summaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0001-PSP-3.0.1.6-kernel-source-patched-with-OCF-Linux.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0001-PSP-3.0.1.6-kernel-source-patched-with-OCF-Linux.patch')
-rw-r--r--extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0001-PSP-3.0.1.6-kernel-source-patched-with-OCF-Linux.patch88333
1 files changed, 88333 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0001-PSP-3.0.1.6-kernel-source-patched-with-OCF-Linux.patch b/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0001-PSP-3.0.1.6-kernel-source-patched-with-OCF-Linux.patch
new file mode 100644
index 00000000..561670e9
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0001-PSP-3.0.1.6-kernel-source-patched-with-OCF-Linux.patch
@@ -0,0 +1,88333 @@
1From 8e1595675e4f2ad795faecb30e0657ac556913d1 Mon Sep 17 00:00:00 2001
2From: Greg Turner <gregturner@ti.com>
3Date: Wed, 19 Jan 2011 16:19:37 +0100
4Subject: [PATCH] PSP 3.0.1.6 kernel source patched with OCF-Linux
5
6---
7 crypto/Kconfig | 3 +
8 crypto/Makefile | 2 +
9 crypto/modules.builtin | 22 +
10 crypto/ocf/Config.in | 36 +
11 crypto/ocf/Kconfig | 119 +
12 crypto/ocf/Makefile | 124 +
13 crypto/ocf/README | 167 ++
14 crypto/ocf/c7108/Makefile | 12 +
15 crypto/ocf/c7108/aes-7108.c | 839 ++++++
16 crypto/ocf/c7108/aes-7108.h | 134 +
17 crypto/ocf/criov.c | 215 ++
18 crypto/ocf/crypto.c | 1784 +++++++++++
19 crypto/ocf/cryptocteon/Makefile | 17 +
20 crypto/ocf/cryptocteon/cavium_crypto.c | 2283 ++++++++++++++
21 crypto/ocf/cryptocteon/cryptocteon.c | 574 ++++
22 crypto/ocf/cryptodev.c | 1061 +++++++
23 crypto/ocf/cryptodev.h | 479 +++
24 crypto/ocf/cryptosoft.c | 1210 ++++++++
25 crypto/ocf/ep80579/Makefile | 119 +
26 crypto/ocf/ep80579/icp_asym.c | 1334 +++++++++
27 crypto/ocf/ep80579/icp_common.c | 773 +++++
28 crypto/ocf/ep80579/icp_ocf.h | 376 +++
29 crypto/ocf/ep80579/icp_sym.c | 1153 ++++++++
30 crypto/ocf/hifn/Makefile | 13 +
31 crypto/ocf/hifn/hifn7751.c | 2976 +++++++++++++++++++
32 crypto/ocf/hifn/hifn7751reg.h | 540 ++++
33 crypto/ocf/hifn/hifn7751var.h | 369 +++
34 crypto/ocf/hifn/hifnHIPP.c | 420 +++
35 crypto/ocf/hifn/hifnHIPPreg.h | 46 +
36 crypto/ocf/hifn/hifnHIPPvar.h | 93 +
37 crypto/ocf/ixp4xx/Makefile | 104 +
38 crypto/ocf/ixp4xx/ixp4xx.c | 1324 +++++++++
39 crypto/ocf/kirkwood/Makefile | 19 +
40 crypto/ocf/kirkwood/cesa/AES/mvAes.h | 62 +
41 crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c | 317 ++
42 crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h | 19 +
43 crypto/ocf/kirkwood/cesa/AES/mvAesApi.c | 312 ++
44 crypto/ocf/kirkwood/cesa/mvCesa.c | 3126 ++++++++++++++++++++
45 crypto/ocf/kirkwood/cesa/mvCesa.h | 412 +++
46 crypto/ocf/kirkwood/cesa/mvCesaDebug.c | 484 +++
47 crypto/ocf/kirkwood/cesa/mvCesaRegs.h | 357 +++
48 crypto/ocf/kirkwood/cesa/mvCesaTest.c | 3096 +++++++++++++++++++
49 crypto/ocf/kirkwood/cesa/mvLru.c | 158 +
50 crypto/ocf/kirkwood/cesa/mvLru.h | 112 +
51 crypto/ocf/kirkwood/cesa/mvMD5.c | 349 +++
52 crypto/ocf/kirkwood/cesa/mvMD5.h | 93 +
53 crypto/ocf/kirkwood/cesa/mvSHA1.c | 239 ++
54 crypto/ocf/kirkwood/cesa/mvSHA1.h | 88 +
55 crypto/ocf/kirkwood/cesa_ocf_drv.c | 1296 ++++++++
56 crypto/ocf/kirkwood/mvHal/common/mv802_3.h | 213 ++
57 crypto/ocf/kirkwood/mvHal/common/mvCommon.c | 277 ++
58 crypto/ocf/kirkwood/mvHal/common/mvCommon.h | 308 ++
59 crypto/ocf/kirkwood/mvHal/common/mvDebug.c | 326 ++
60 crypto/ocf/kirkwood/mvHal/common/mvDebug.h | 178 ++
61 crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h | 225 ++
62 crypto/ocf/kirkwood/mvHal/common/mvHalVer.h | 73 +
63 crypto/ocf/kirkwood/mvHal/common/mvStack.c | 100 +
64 crypto/ocf/kirkwood/mvHal/common/mvStack.h | 140 +
65 crypto/ocf/kirkwood/mvHal/common/mvTypes.h | 245 ++
66 crypto/ocf/kirkwood/mvHal/dbg-trace.c | 110 +
67 crypto/ocf/kirkwood/mvHal/dbg-trace.h | 24 +
68 .../mvHal/kw_family/boardEnv/mvBoardEnvLib.c | 2513 ++++++++++++++++
69 .../mvHal/kw_family/boardEnv/mvBoardEnvLib.h | 376 +++
70 .../mvHal/kw_family/boardEnv/mvBoardEnvSpec.c | 848 ++++++
71 .../mvHal/kw_family/boardEnv/mvBoardEnvSpec.h | 262 ++
72 crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c | 320 ++
73 crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h | 99 +
74 .../mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c | 296 ++
75 .../mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h | 203 ++
76 .../mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h | 98 +
77 .../mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c | 1825 ++++++++++++
78 .../mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h | 185 ++
79 .../mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h | 419 +++
80 .../mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h | 257 ++
81 .../mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c | 1048 +++++++
82 .../mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h | 130 +
83 .../mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h | 143 +
84 .../kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c | 1036 +++++++
85 .../kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h | 120 +
86 .../mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h | 304 ++
87 .../mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c | 324 ++
88 .../mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h | 123 +
89 .../mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c | 382 +++
90 .../mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h | 100 +
91 .../mvHal/kw_family/ctrlEnv/sys/mvSysDram.c | 348 +++
92 .../mvHal/kw_family/ctrlEnv/sys/mvSysDram.h | 80 +
93 .../mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c | 658 ++++
94 .../mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h | 113 +
95 .../mvHal/kw_family/ctrlEnv/sys/mvSysPex.c | 1697 +++++++++++
96 .../mvHal/kw_family/ctrlEnv/sys/mvSysPex.h | 348 +++
97 .../mvHal/kw_family/ctrlEnv/sys/mvSysSata.c | 430 +++
98 .../mvHal/kw_family/ctrlEnv/sys/mvSysSata.h | 128 +
99 .../mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c | 427 +++
100 .../mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h | 125 +
101 .../mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c | 462 +++
102 .../mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h | 106 +
103 .../kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c | 591 ++++
104 .../kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h | 110 +
105 .../mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c | 497 ++++
106 .../mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h | 125 +
107 .../mvHal/kw_family/ctrlEnv/sys/mvSysXor.c | 662 +++++
108 .../mvHal/kw_family/ctrlEnv/sys/mvSysXor.h | 140 +
109 .../ocf/kirkwood/mvHal/kw_family/device/mvDevice.c | 75 +
110 .../ocf/kirkwood/mvHal/kw_family/device/mvDevice.h | 74 +
111 .../kirkwood/mvHal/kw_family/device/mvDeviceRegs.h | 101 +
112 crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c | 211 ++
113 crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h | 423 +++
114 crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h | 158 +
115 crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h | 375 +++
116 crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c | 376 +++
117 crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h | 121 +
118 .../ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h | 121 +
119 crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c | 207 ++
120 crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h | 213 ++
121 .../ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c | 143 +
122 .../ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h | 151 +
123 crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c | 1479 +++++++++
124 crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h | 191 ++
125 crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c | 1599 ++++++++++
126 crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h | 179 ++
127 .../kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h | 192 ++
128 .../kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h | 306 ++
129 crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c | 1855 ++++++++++++
130 crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h | 172 ++
131 .../kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h | 157 +
132 .../ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h | 423 +++
133 .../mvHal/mv_hal/ddr2/mvDramIfStaticInit.h | 179 ++
134 crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c | 1474 +++++++++
135 crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h | 192 ++
136 crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c | 2952 ++++++++++++++++++
137 .../ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c | 748 +++++
138 .../ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h | 146 +
139 .../ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h | 751 +++++
140 .../ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h | 700 +++++
141 crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h | 356 +++
142 crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c | 362 +++
143 crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h | 118 +
144 crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h | 116 +
145 crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c | 669 +++++
146 crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h | 134 +
147 .../ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h | 245 ++
148 .../mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c | 1006 +++++++
149 .../mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h | 323 ++
150 crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c | 1047 +++++++
151 crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h | 185 ++
152 crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h | 411 +++
153 crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c | 1143 +++++++
154 crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h | 168 ++
155 crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h | 751 +++++
156 crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c | 313 ++
157 crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h | 82 +
158 crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c | 1522 ++++++++++
159 crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h | 166 ++
160 .../kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h | 233 ++
161 crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c | 576 ++++
162 crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h | 94 +
163 crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c | 249 ++
164 crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h | 82 +
165 crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h | 98 +
166 crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c | 1023 +++++++
167 crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h | 121 +
168 crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h | 160 +
169 crypto/ocf/ocf-bench.c | 436 +++
170 crypto/ocf/ocf-compat.h | 294 ++
171 crypto/ocf/ocfnull/Makefile | 12 +
172 crypto/ocf/ocfnull/ocfnull.c | 203 ++
173 crypto/ocf/pasemi/Makefile | 12 +
174 crypto/ocf/pasemi/pasemi.c | 1009 +++++++
175 crypto/ocf/pasemi/pasemi_fnu.h | 410 +++
176 crypto/ocf/random.c | 322 ++
177 crypto/ocf/rndtest.c | 300 ++
178 crypto/ocf/rndtest.h | 54 +
179 crypto/ocf/safe/Makefile | 12 +
180 crypto/ocf/safe/md5.c | 308 ++
181 crypto/ocf/safe/md5.h | 76 +
182 crypto/ocf/safe/safe.c | 2288 ++++++++++++++
183 crypto/ocf/safe/safereg.h | 421 +++
184 crypto/ocf/safe/safevar.h | 230 ++
185 crypto/ocf/safe/sha1.c | 279 ++
186 crypto/ocf/safe/sha1.h | 72 +
187 crypto/ocf/talitos/Makefile | 12 +
188 crypto/ocf/talitos/talitos.c | 1359 +++++++++
189 crypto/ocf/talitos/talitos_dev.h | 277 ++
190 crypto/ocf/talitos/talitos_soft.h | 77 +
191 crypto/ocf/uio.h | 54 +
192 drivers/char/random.c | 65 +
193 fs/fcntl.c | 1 +
194 include/linux/miscdevice.h | 1 +
195 include/linux/random.h | 29 +
196 kernel/pid.c | 1 +
197 190 files changed, 86748 insertions(+), 0 deletions(-)
198 create mode 100644 crypto/modules.builtin
199 create mode 100644 crypto/ocf/Config.in
200 create mode 100644 crypto/ocf/Kconfig
201 create mode 100644 crypto/ocf/Makefile
202 create mode 100644 crypto/ocf/README
203 create mode 100644 crypto/ocf/c7108/Makefile
204 create mode 100644 crypto/ocf/c7108/aes-7108.c
205 create mode 100644 crypto/ocf/c7108/aes-7108.h
206 create mode 100644 crypto/ocf/criov.c
207 create mode 100644 crypto/ocf/crypto.c
208 create mode 100644 crypto/ocf/cryptocteon/Makefile
209 create mode 100644 crypto/ocf/cryptocteon/cavium_crypto.c
210 create mode 100644 crypto/ocf/cryptocteon/cryptocteon.c
211 create mode 100644 crypto/ocf/cryptodev.c
212 create mode 100644 crypto/ocf/cryptodev.h
213 create mode 100644 crypto/ocf/cryptosoft.c
214 create mode 100644 crypto/ocf/ep80579/Makefile
215 create mode 100644 crypto/ocf/ep80579/icp_asym.c
216 create mode 100644 crypto/ocf/ep80579/icp_common.c
217 create mode 100644 crypto/ocf/ep80579/icp_ocf.h
218 create mode 100644 crypto/ocf/ep80579/icp_sym.c
219 create mode 100644 crypto/ocf/hifn/Makefile
220 create mode 100644 crypto/ocf/hifn/hifn7751.c
221 create mode 100644 crypto/ocf/hifn/hifn7751reg.h
222 create mode 100644 crypto/ocf/hifn/hifn7751var.h
223 create mode 100644 crypto/ocf/hifn/hifnHIPP.c
224 create mode 100644 crypto/ocf/hifn/hifnHIPPreg.h
225 create mode 100644 crypto/ocf/hifn/hifnHIPPvar.h
226 create mode 100644 crypto/ocf/ixp4xx/Makefile
227 create mode 100644 crypto/ocf/ixp4xx/ixp4xx.c
228 create mode 100644 crypto/ocf/kirkwood/Makefile
229 create mode 100644 crypto/ocf/kirkwood/cesa/AES/mvAes.h
230 create mode 100644 crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c
231 create mode 100644 crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h
232 create mode 100644 crypto/ocf/kirkwood/cesa/AES/mvAesApi.c
233 create mode 100644 crypto/ocf/kirkwood/cesa/mvCesa.c
234 create mode 100644 crypto/ocf/kirkwood/cesa/mvCesa.h
235 create mode 100644 crypto/ocf/kirkwood/cesa/mvCesaDebug.c
236 create mode 100644 crypto/ocf/kirkwood/cesa/mvCesaRegs.h
237 create mode 100644 crypto/ocf/kirkwood/cesa/mvCesaTest.c
238 create mode 100644 crypto/ocf/kirkwood/cesa/mvLru.c
239 create mode 100644 crypto/ocf/kirkwood/cesa/mvLru.h
240 create mode 100644 crypto/ocf/kirkwood/cesa/mvMD5.c
241 create mode 100644 crypto/ocf/kirkwood/cesa/mvMD5.h
242 create mode 100644 crypto/ocf/kirkwood/cesa/mvSHA1.c
243 create mode 100644 crypto/ocf/kirkwood/cesa/mvSHA1.h
244 create mode 100644 crypto/ocf/kirkwood/cesa_ocf_drv.c
245 create mode 100644 crypto/ocf/kirkwood/mvHal/common/mv802_3.h
246 create mode 100644 crypto/ocf/kirkwood/mvHal/common/mvCommon.c
247 create mode 100644 crypto/ocf/kirkwood/mvHal/common/mvCommon.h
248 create mode 100644 crypto/ocf/kirkwood/mvHal/common/mvDebug.c
249 create mode 100644 crypto/ocf/kirkwood/mvHal/common/mvDebug.h
250 create mode 100644 crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h
251 create mode 100644 crypto/ocf/kirkwood/mvHal/common/mvHalVer.h
252 create mode 100644 crypto/ocf/kirkwood/mvHal/common/mvStack.c
253 create mode 100644 crypto/ocf/kirkwood/mvHal/common/mvStack.h
254 create mode 100644 crypto/ocf/kirkwood/mvHal/common/mvTypes.h
255 create mode 100644 crypto/ocf/kirkwood/mvHal/dbg-trace.c
256 create mode 100644 crypto/ocf/kirkwood/mvHal/dbg-trace.h
257 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c
258 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h
259 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c
260 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h
261 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c
262 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h
263 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c
264 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h
265 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h
266 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c
267 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h
268 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h
269 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h
270 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c
271 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h
272 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h
273 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c
274 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h
275 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h
276 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c
277 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h
278 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c
279 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h
280 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c
281 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h
282 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c
283 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h
284 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c
285 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h
286 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c
287 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h
288 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c
289 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h
290 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c
291 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h
292 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c
293 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h
294 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c
295 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h
296 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c
297 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h
298 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c
299 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h
300 create mode 100644 crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h
301 create mode 100644 crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c
302 create mode 100644 crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h
303 create mode 100644 crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h
304 create mode 100644 crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h
305 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c
306 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h
307 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h
308 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c
309 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h
310 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c
311 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h
312 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c
313 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h
314 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c
315 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h
316 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h
317 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h
318 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c
319 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h
320 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h
321 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h
322 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h
323 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c
324 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h
325 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c
326 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c
327 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h
328 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h
329 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h
330 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h
331 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c
332 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h
333 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h
334 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c
335 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h
336 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h
337 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c
338 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h
339 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c
340 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h
341 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h
342 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c
343 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h
344 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h
345 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c
346 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h
347 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c
348 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h
349 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h
350 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c
351 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h
352 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c
353 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h
354 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h
355 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c
356 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h
357 create mode 100644 crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h
358 create mode 100644 crypto/ocf/ocf-bench.c
359 create mode 100644 crypto/ocf/ocf-compat.h
360 create mode 100644 crypto/ocf/ocfnull/Makefile
361 create mode 100644 crypto/ocf/ocfnull/ocfnull.c
362 create mode 100644 crypto/ocf/pasemi/Makefile
363 create mode 100644 crypto/ocf/pasemi/pasemi.c
364 create mode 100644 crypto/ocf/pasemi/pasemi_fnu.h
365 create mode 100644 crypto/ocf/random.c
366 create mode 100644 crypto/ocf/rndtest.c
367 create mode 100644 crypto/ocf/rndtest.h
368 create mode 100644 crypto/ocf/safe/Makefile
369 create mode 100644 crypto/ocf/safe/md5.c
370 create mode 100644 crypto/ocf/safe/md5.h
371 create mode 100644 crypto/ocf/safe/safe.c
372 create mode 100644 crypto/ocf/safe/safereg.h
373 create mode 100644 crypto/ocf/safe/safevar.h
374 create mode 100644 crypto/ocf/safe/sha1.c
375 create mode 100644 crypto/ocf/safe/sha1.h
376 create mode 100644 crypto/ocf/talitos/Makefile
377 create mode 100644 crypto/ocf/talitos/talitos.c
378 create mode 100644 crypto/ocf/talitos/talitos_dev.h
379 create mode 100644 crypto/ocf/talitos/talitos_soft.h
380 create mode 100644 crypto/ocf/uio.h
381
382diff --git a/crypto/Kconfig b/crypto/Kconfig
383index 81c185a..9f1c30f 100644
384--- a/crypto/Kconfig
385+++ b/crypto/Kconfig
386@@ -822,3 +822,6 @@ config CRYPTO_ANSI_CPRNG
387 source "drivers/crypto/Kconfig"
388
389 endif # if CRYPTO
390+
391+source "crypto/ocf/Kconfig"
392+
393diff --git a/crypto/Makefile b/crypto/Makefile
394index 9e8f619..79631fc 100644
395--- a/crypto/Makefile
396+++ b/crypto/Makefile
397@@ -85,6 +85,8 @@ obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o
398 obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
399 obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
400
401+obj-$(CONFIG_OCF_OCF) += ocf/
402+
403 #
404 # generic algorithms and the async_tx api
405 #
406diff --git a/crypto/modules.builtin b/crypto/modules.builtin
407new file mode 100644
408index 0000000..04825d1
409--- /dev/null
410+++ b/crypto/modules.builtin
411@@ -0,0 +1,22 @@
412+kernel/crypto/crypto.ko
413+kernel/crypto/crypto_wq.ko
414+kernel/crypto/crypto_algapi.ko
415+kernel/crypto/aead.ko
416+kernel/crypto/crypto_blkcipher.ko
417+kernel/crypto/chainiv.ko
418+kernel/crypto/eseqiv.ko
419+kernel/crypto/crypto_hash.ko
420+kernel/crypto/pcompress.ko
421+kernel/crypto/cryptomgr.ko
422+kernel/crypto/md5.ko
423+kernel/crypto/ecb.ko
424+kernel/crypto/cbc.ko
425+kernel/crypto/des_generic.ko
426+kernel/crypto/aes_generic.ko
427+kernel/crypto/arc4.ko
428+kernel/crypto/deflate.ko
429+kernel/crypto/michael_mic.ko
430+kernel/crypto/crc32c.ko
431+kernel/crypto/lzo.ko
432+kernel/crypto/rng.ko
433+kernel/crypto/krng.ko
434diff --git a/crypto/ocf/Config.in b/crypto/ocf/Config.in
435new file mode 100644
436index 0000000..d722cba
437--- /dev/null
438+++ b/crypto/ocf/Config.in
439@@ -0,0 +1,36 @@
440+#############################################################################
441+
442+mainmenu_option next_comment
443+comment 'OCF Configuration'
444+tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF
445+dep_mbool ' enable fips RNG checks (fips check on RNG data before use)' \
446+ CONFIG_OCF_FIPS $CONFIG_OCF_OCF
447+dep_mbool ' enable harvesting entropy for /dev/random' \
448+ CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF
449+dep_tristate ' cryptodev (user space support)' \
450+ CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF
451+dep_tristate ' cryptosoft (software crypto engine)' \
452+ CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF
453+dep_tristate ' safenet (HW crypto engine)' \
454+ CONFIG_OCF_SAFE $CONFIG_OCF_OCF
455+dep_tristate ' IXP4xx (HW crypto engine)' \
456+ CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF
457+dep_mbool ' Enable IXP4xx HW to perform SHA1 and MD5 hashing (very slow)' \
458+ CONFIG_OCF_IXP4XX_SHA1_MD5 $CONFIG_OCF_IXP4XX
459+dep_tristate ' hifn (HW crypto engine)' \
460+ CONFIG_OCF_HIFN $CONFIG_OCF_OCF
461+dep_tristate ' talitos (HW crypto engine)' \
462+ CONFIG_OCF_TALITOS $CONFIG_OCF_OCF
463+dep_tristate ' pasemi (HW crypto engine)' \
464+ CONFIG_OCF_PASEMI $CONFIG_OCF_OCF
465+dep_tristate ' ep80579 (HW crypto engine)' \
466+ CONFIG_OCF_EP80579 $CONFIG_OCF_OCF
467+dep_tristate ' Micronas c7108 (HW crypto engine)' \
468+ CONFIG_OCF_C7108 $CONFIG_OCF_OCF
469+dep_tristate ' ocfnull (does no crypto)' \
470+ CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF
471+dep_tristate ' ocf-bench (HW crypto in-kernel benchmark)' \
472+ CONFIG_OCF_BENCH $CONFIG_OCF_OCF
473+endmenu
474+
475+#############################################################################
476diff --git a/crypto/ocf/Kconfig b/crypto/ocf/Kconfig
477new file mode 100644
478index 0000000..b9c24ff
479--- /dev/null
480+++ b/crypto/ocf/Kconfig
481@@ -0,0 +1,119 @@
482+menu "OCF Configuration"
483+
484+config OCF_OCF
485+ tristate "OCF (Open Cryptograhic Framework)"
486+ help
487+ A linux port of the OpenBSD/FreeBSD crypto framework.
488+
489+config OCF_RANDOMHARVEST
490+ bool "crypto random --- harvest entropy for /dev/random"
491+ depends on OCF_OCF
492+ help
493+ Includes code to harvest random numbers from devices that support it.
494+
495+config OCF_FIPS
496+ bool "enable fips RNG checks"
497+ depends on OCF_OCF && OCF_RANDOMHARVEST
498+ help
499+ Run all RNG provided data through a fips check before
500+ adding it /dev/random's entropy pool.
501+
502+config OCF_CRYPTODEV
503+ tristate "cryptodev (user space support)"
504+ depends on OCF_OCF
505+ help
506+ The user space API to access crypto hardware.
507+
508+config OCF_CRYPTOSOFT
509+ tristate "cryptosoft (software crypto engine)"
510+ depends on OCF_OCF
511+ help
512+ A software driver for the OCF framework that uses
513+ the kernel CryptoAPI.
514+
515+config OCF_SAFE
516+ tristate "safenet (HW crypto engine)"
517+ depends on OCF_OCF
518+ help
519+ A driver for a number of the safenet Excel crypto accelerators.
520+ Currently tested and working on the 1141 and 1741.
521+
522+config OCF_IXP4XX
523+ tristate "IXP4xx (HW crypto engine)"
524+ depends on OCF_OCF
525+ help
526+ XScale IXP4xx crypto accelerator driver. Requires the
527+ Intel Access library.
528+
529+config OCF_IXP4XX_SHA1_MD5
530+ bool "IXP4xx SHA1 and MD5 Hashing"
531+ depends on OCF_IXP4XX
532+ help
533+ Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.
534+ Note: this is MUCH slower than using cryptosoft (software crypto engine).
535+
536+config OCF_HIFN
537+ tristate "hifn (HW crypto engine)"
538+ depends on OCF_OCF
539+ help
540+ OCF driver for various HIFN based crypto accelerators.
541+ (7951, 7955, 7956, 7751, 7811)
542+
543+config OCF_HIFNHIPP
544+ tristate "Hifn HIPP (HW packet crypto engine)"
545+ depends on OCF_OCF
546+ help
547+ OCF driver for various HIFN (HIPP) based crypto accelerators
548+ (7855)
549+
550+config OCF_TALITOS
551+ tristate "talitos (HW crypto engine)"
552+ depends on OCF_OCF
553+ help
554+ OCF driver for Freescale's security engine (SEC/talitos).
555+
556+config OCF_PASEMI
557+ tristate "pasemi (HW crypto engine)"
558+ depends on OCF_OCF && PPC_PASEMI
559+ help
560+ OCF driver for the PA Semi PWRficient DMA Engine
561+
562+config OCF_EP80579
563+ tristate "ep80579 (HW crypto engine)"
564+ depends on OCF_OCF
565+ help
566+ OCF driver for the Intel EP80579 Integrated Processor Product Line.
567+
568+config OCF_CRYPTOCTEON
569+ tristate "cryptocteon (HW crypto engine)"
570+ depends on OCF_OCF
571+ help
572+ OCF driver for the Cavium OCTEON Processors.
573+
574+config OCF_KIRKWOOD
575+ tristate "kirkwood (HW crypto engine)"
576+ depends on OCF_OCF
577+ help
578+ OCF driver for the Marvell Kirkwood (88F6xxx) Processors.
579+
580+config OCF_C7108
581+ tristate "Micronas 7108 (HW crypto engine)"
582+ depends on OCF_OCF
583+ help
584+ OCF driver for the Microna 7108 Cipher processors.
585+
586+config OCF_OCFNULL
587+ tristate "ocfnull (fake crypto engine)"
588+ depends on OCF_OCF
589+ help
590+ OCF driver for measuring ipsec overheads (does no crypto)
591+
592+config OCF_BENCH
593+ tristate "ocf-bench (HW crypto in-kernel benchmark)"
594+ depends on OCF_OCF
595+ help
596+ A very simple encryption test for the in-kernel interface
597+ of OCF. Also includes code to benchmark the IXP Access library
598+ for comparison.
599+
600+endmenu
601diff --git a/crypto/ocf/Makefile b/crypto/ocf/Makefile
602new file mode 100644
603index 0000000..fa951f4
604--- /dev/null
605+++ b/crypto/ocf/Makefile
606@@ -0,0 +1,124 @@
607+# for SGlinux builds
608+-include $(ROOTDIR)/modules/.config
609+
610+OCF_OBJS = crypto.o criov.o
611+
612+ifdef CONFIG_OCF_RANDOMHARVEST
613+ OCF_OBJS += random.o
614+endif
615+
616+ifdef CONFIG_OCF_FIPS
617+ OCF_OBJS += rndtest.o
618+endif
619+
620+# Add in autoconf.h to get #defines for CONFIG_xxx
621+AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h
622+ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))
623+ EXTRA_CFLAGS += -include $(AUTOCONF_H)
624+ export EXTRA_CFLAGS
625+endif
626+
627+ifndef obj
628+ obj ?= .
629+ _obj = subdir
630+ mod-subdirs := safe hifn ixp4xx talitos ocfnull
631+ export-objs += crypto.o criov.o random.o
632+ list-multi += ocf.o
633+ _slash :=
634+else
635+ _obj = obj
636+ _slash := /
637+endif
638+
639+EXTRA_CFLAGS += -I$(obj)/.
640+
641+obj-$(CONFIG_OCF_OCF) += ocf.o
642+obj-$(CONFIG_OCF_CRYPTODEV) += cryptodev.o
643+obj-$(CONFIG_OCF_CRYPTOSOFT) += cryptosoft.o
644+obj-$(CONFIG_OCF_BENCH) += ocf-bench.o
645+
646+$(_obj)-$(CONFIG_OCF_SAFE) += safe$(_slash)
647+$(_obj)-$(CONFIG_OCF_HIFN) += hifn$(_slash)
648+$(_obj)-$(CONFIG_OCF_IXP4XX) += ixp4xx$(_slash)
649+$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)
650+$(_obj)-$(CONFIG_OCF_PASEMI) += pasemi$(_slash)
651+$(_obj)-$(CONFIG_OCF_EP80579) += ep80579$(_slash)
652+$(_obj)-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon$(_slash)
653+$(_obj)-$(CONFIG_OCF_KIRKWOOD) += kirkwood$(_slash)
654+$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
655+$(_obj)-$(CONFIG_OCF_C7108) += c7108$(_slash)
656+
657+ocf-objs := $(OCF_OBJS)
658+
659+$(list-multi) dummy1: $(ocf-objs)
660+ $(LD) -r -o $@ $(ocf-objs)
661+
662+.PHONY:
663+clean:
664+ rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c
665+ rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags
666+
667+ifdef TOPDIR
668+-include $(TOPDIR)/Rules.make
669+endif
670+
671+#
672+# release gen targets
673+#
674+
675+.PHONY: patch
676+patch:
677+ REL=`date +%Y%m%d`; \
678+ patch=ocf-linux-$$REL.patch; \
679+ patch24=ocf-linux-24-$$REL.patch; \
680+ patch26=ocf-linux-26-$$REL.patch; \
681+ ( \
682+ find . -name Makefile; \
683+ find . -name Config.in; \
684+ find . -name Kconfig; \
685+ find . -name README; \
686+ find . -name '*.[ch]' | grep -v '.mod.c'; \
687+ ) | while read t; do \
688+ diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \
689+ done > $$patch; \
690+ cat patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
691+ cat patches/linux-2.6.33-ocf.patch $$patch > $$patch26
692+
693+.PHONY: tarball
694+tarball:
695+ REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \
696+ CURDIR=`pwd`; \
697+ rm -rf /tmp/ocf-linux-$$REL*; \
698+ mkdir -p $$RELDIR/tools; \
699+ cp README* $$RELDIR; \
700+ cp patches/openss*.patch $$RELDIR; \
701+ cp patches/crypto-tools.patch $$RELDIR; \
702+ cp tools/[!C]* $$RELDIR/tools; \
703+ cd ..; \
704+ tar cvf $$RELDIR/ocf-linux.tar \
705+ --exclude=CVS \
706+ --exclude=.* \
707+ --exclude=*.o \
708+ --exclude=*.ko \
709+ --exclude=*.mod.* \
710+ --exclude=README* \
711+ --exclude=ocf-*.patch \
712+ --exclude=ocf/patches/openss*.patch \
713+ --exclude=ocf/patches/crypto-tools.patch \
714+ --exclude=ocf/tools \
715+ ocf; \
716+ gzip -9 $$RELDIR/ocf-linux.tar; \
717+ cd /tmp; \
718+ tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \
719+ gzip -9 ocf-linux-$$REL.tar; \
720+ cd $$CURDIR/../../user; \
721+ rm -rf /tmp/crypto-tools-$$REL*; \
722+ tar cvf /tmp/crypto-tools-$$REL.tar \
723+ --exclude=CVS \
724+ --exclude=.* \
725+ --exclude=*.o \
726+ --exclude=cryptotest \
727+ --exclude=cryptokeytest \
728+ crypto-tools; \
729+ gzip -9 /tmp/crypto-tools-$$REL.tar
730+
731diff --git a/crypto/ocf/README b/crypto/ocf/README
732new file mode 100644
733index 0000000..ba0a7de
734--- /dev/null
735+++ b/crypto/ocf/README
736@@ -0,0 +1,167 @@
737+README - ocf-linux-20100325
738+---------------------------
739+
740+This README provides instructions for getting ocf-linux compiled and
741+operating in a generic linux environment. For other information you
742+might like to visit the home page for this project:
743+
744+ http://ocf-linux.sourceforge.net/
745+
746+Adding OCF to linux
747+-------------------
748+
749+ Not much in this file for now, just some notes. I usually build
750+ the ocf support as modules but it can be built into the kernel as
751+ well. To use it:
752+
753+ * mknod /dev/crypto c 10 70
754+
755+ * to add OCF to your kernel source, you have two options. Apply
756+ the kernel specific patch:
757+
758+ cd linux-2.4*; gunzip < ocf-linux-24-XXXXXXXX.patch.gz | patch -p1
759+ cd linux-2.6*; gunzip < ocf-linux-26-XXXXXXXX.patch.gz | patch -p1
760+
761+ if you do one of the above, then you can proceed to the next step,
762+ or you can do the above process by hand with using the patches against
763+ linux-2.4.35 and 2.6.33 to include the ocf code under crypto/ocf.
764+ Here's how to add it:
765+
766+ for 2.4.35 (and later)
767+
768+ cd linux-2.4.35/crypto
769+ tar xvzf ocf-linux.tar.gz
770+ cd ..
771+ patch -p1 < crypto/ocf/patches/linux-2.4.35-ocf.patch
772+
773+ for 2.6.23 (and later), find the kernel patch specific (or nearest)
774+ to your kernel versions and then:
775+
776+ cd linux-2.6.NN/crypto
777+ tar xvzf ocf-linux.tar.gz
778+ cd ..
779+ patch -p1 < crypto/ocf/patches/linux-2.6.NN-ocf.patch
780+
781+ It should be easy to take this patch and apply it to other more
782+ recent versions of the kernels. The same patches should also work
783+ relatively easily on kernels as old as 2.6.11 and 2.4.18.
784+
785+ * under 2.4 if you are on a non-x86 platform, you may need to:
786+
787+ cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY
788+
789+ so that you can build the kernel crypto support needed for the cryptosoft
790+ driver.
791+
792+ * For simplicity you should enable all the crypto support in your kernel
793+ except for the test driver. Likewise for the OCF options. Do not
794+ enable OCF crypto drivers for HW that you do not have (for example
795+ ixp4xx will not compile on non-Xscale systems).
796+
797+ * make sure that cryptodev.h (from ocf-linux.tar.gz) is installed as
798+ crypto/cryptodev.h in an include directory that is used for building
799+ applications for your platform. For example on a host system that
800+ might be:
801+
802+ /usr/include/crypto/cryptodev.h
803+
804+ * patch your openssl-0.9.8n code with the openssl-0.9.8n.patch.
805+ (NOTE: there is no longer a need to patch ssh). The patch is against:
806+ openssl-0_9_8e
807+
808+ If you need a patch for an older version of openssl, you should look
809+ to older OCF releases. This patch is unlikely to work on older
810+ openssl versions.
811+
812+ openssl-0.9.8n.patch
813+ - enables --with-cryptodev for non BSD systems
814+ - adds -cpu option to openssl speed for calculating CPU load
815+ under linux
816+ - fixes null pointer in openssl speed multi thread output.
817+ - fixes test keys to work with linux crypto's more stringent
818+ key checking.
819+ - adds MD5/SHA acceleration (Ronen Shitrit), only enabled
820+ with the --with-cryptodev-digests option
821+ - fixes bug in engine code caching.
822+
823+ * build crypto-tools-XXXXXXXX.tar.gz if you want to try some of the BSD
824+ tools for testing OCF (ie., cryptotest).
825+
826+How to load the OCF drivers
827+---------------------------
828+
829+ First insert the base modules:
830+
831+ insmod ocf
832+ insmod cryptodev
833+
834+ You can then install the software OCF driver with:
835+
836+ insmod cryptosoft
837+
838+ and one or more of the OCF HW drivers with:
839+
840+ insmod safe
841+ insmod hifn7751
842+ insmod ixp4xx
843+ ...
844+
845+ all the drivers take a debug option to enable verbose debug so that
846+ you can see what is going on. For debug you load them as:
847+
848+ insmod ocf crypto_debug=1
849+ insmod cryptodev cryptodev_debug=1
850+ insmod cryptosoft swcr_debug=1
851+
852+ You may load more than one OCF crypto driver but then there is no guarantee
853+ as to which will be used.
854+
855+ You can also enable debug at run time on 2.6 systems with the following:
856+
857+ echo 1 > /sys/module/ocf/parameters/crypto_debug
858+ echo 1 > /sys/module/cryptodev/parameters/cryptodev_debug
859+ echo 1 > /sys/module/cryptosoft/parameters/swcr_debug
860+ echo 1 > /sys/module/hifn7751/parameters/hifn_debug
861+ echo 1 > /sys/module/safe/parameters/safe_debug
862+ echo 1 > /sys/module/ixp4xx/parameters/ixp_debug
863+ ...
864+
865+Testing the OCF support
866+-----------------------
867+
868+ run "cryptotest", it should do a short test for a couple of
869+ des packets. If it does everything is working.
870+
871+ If this works, then ssh will use the driver when invoked as:
872+
873+ ssh -c 3des username@host
874+
875+ to see for sure that it is operating, enable debug as defined above.
876+
877+ To get a better idea of performance run:
878+
879+ cryptotest 100 4096
880+
881+ There are more options to cryptotest, see the help.
882+
883+ It is also possible to use openssl to test the speed of the crypto
884+ drivers.
885+
886+ openssl speed -evp des -engine cryptodev -elapsed
887+ openssl speed -evp des3 -engine cryptodev -elapsed
888+ openssl speed -evp aes128 -engine cryptodev -elapsed
889+
890+ and multiple threads (10) with:
891+
892+ openssl speed -evp des -engine cryptodev -elapsed -multi 10
893+ openssl speed -evp des3 -engine cryptodev -elapsed -multi 10
894+ openssl speed -evp aes128 -engine cryptodev -elapsed -multi 10
895+
896+ for public key testing you can try:
897+
898+ cryptokeytest
899+ openssl speed -engine cryptodev rsa -elapsed
900+ openssl speed -engine cryptodev dsa -elapsed
901+
902+David McCullough
903+david_mccullough@mcafee.com
904diff --git a/crypto/ocf/c7108/Makefile b/crypto/ocf/c7108/Makefile
905new file mode 100644
906index 0000000..e7e634b
907--- /dev/null
908+++ b/crypto/ocf/c7108/Makefile
909@@ -0,0 +1,12 @@
910+# for SGlinux builds
911+-include $(ROOTDIR)/modules/.config
912+
913+obj-$(CONFIG_OCF_C7108) += aes-7108.o
914+
915+obj ?= .
916+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
917+
918+ifdef TOPDIR
919+-include $(TOPDIR)/Rules.make
920+endif
921+
922diff --git a/crypto/ocf/c7108/aes-7108.c b/crypto/ocf/c7108/aes-7108.c
923new file mode 100644
924index 0000000..6dbc515
925--- /dev/null
926+++ b/crypto/ocf/c7108/aes-7108.c
927@@ -0,0 +1,839 @@
928+/*
929+ * Copyright (C) 2006 Micronas USA
930+ *
931+ * 1. Redistributions of source code must retain the above copyright
932+ * notice, this list of conditions and the following disclaimer.
933+ * 2. Redistributions in binary form must reproduce the above copyright
934+ * notice, this list of conditions and the following disclaimer in the
935+ * documentation and/or other materials provided with the distribution.
936+ * 3. The name of the author may not be used to endorse or promote products
937+ * derived from this software without specific prior written permission.
938+ *
939+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
940+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
941+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
942+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
943+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
944+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
945+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
946+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
947+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
948+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
949+ *
950+ * Effort sponsored in part by the Defense Advanced Research Projects
951+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
952+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
953+ *
954+ */
955+
956+//#include <linux/config.h>
957+#include <linux/module.h>
958+#include <linux/init.h>
959+#include <linux/list.h>
960+#include <linux/slab.h>
961+#include <linux/sched.h>
962+#include <linux/wait.h>
963+#include <linux/crypto.h>
964+#include <linux/mm.h>
965+#include <linux/skbuff.h>
966+#include <linux/random.h>
967+#include <asm/io.h>
968+#include <asm/delay.h>
969+//#include <asm/scatterlist.h>
970+#include <linux/scatterlist.h>
971+#include <linux/dma-mapping.h>
972+#include <linux/highmem.h>
973+#include <cryptodev.h>
974+#include <uio.h>
975+#include <aes-7108.h>
976+
977+/* Runtime mode */
978+static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR;
979+//static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC;
980+
981+static int32_t c7108_id = -1;
982+static struct cipher_7108 **c7108_sessions = NULL;
983+static u_int32_t c7108_sesnum = 0;
984+static unsigned long iobar;
985+
986+/* Crypto entry points */
987+static int c7108_process(void *, struct cryptop *, int);
988+static int c7108_newsession(void *, u_int32_t *, struct cryptoini *);
989+static int c7108_freesession(void *, u_int64_t);
990+
991+/* Globals */
992+static int debug = 0;
993+static spinlock_t csr_mutex;
994+
995+/* Generic controller-based lock */
996+#define AES_LOCK()\
997+ spin_lock(&csr_mutex)
998+#define AES_UNLOCK()\
999+ spin_unlock(&csr_mutex)
1000+
1001+/* 7108 AES register access */
1002+#define c7108_reg_wr8(a,d) iowrite8(d, (void*)(iobar+(a)))
1003+#define c7108_reg_wr16(a,d) iowrite16(d, (void*)(iobar+(a)))
1004+#define c7108_reg_wr32(a,d) iowrite32(d, (void*)(iobar+(a)))
1005+#define c7108_reg_rd8(a) ioread8((void*)(iobar+(a)))
1006+#define c7108_reg_rd16(a) ioread16((void*)(iobar+(a)))
1007+#define c7108_reg_rd32(a) ioread32((void*)(iobar+(a)))
1008+
1009+static int
1010+c7108_xlate_key(int klen, u8* k8ptr, u32* k32ptr)
1011+{
1012+ int i, nw=0;
1013+ nw = ((klen >= 256) ? 8 : (klen >= 192) ? 6 : 4);
1014+ for ( i = 0; i < nw; i++) {
1015+ k32ptr[i] = (k8ptr[i+3] << 24) | (k8ptr[i+2] << 16) |
1016+ (k8ptr[i+1] << 8) | k8ptr[i];
1017+
1018+ }
1019+ return 0;
1020+}
1021+
1022+static int
1023+c7108_cache_key(int klen, u32* k32ptr, u8* k8ptr)
1024+{
1025+ int i, nb=0;
1026+ u8* ptr = (u8*)k32ptr;
1027+ nb = ((klen >= 256) ? 32 : (klen >= 192) ? 24 : 16);
1028+ for ( i = 0; i < nb; i++)
1029+ k8ptr[i] = ptr[i];
1030+ return 0;
1031+}
1032+
1033+static int
1034+c7108_aes_setup_dma(u32 src, u32 dst, u32 len)
1035+{
1036+ if (len < 16) {
1037+ printk("len < 16\n");
1038+ return -10;
1039+ }
1040+ if (len % 16) {
1041+ printk("len not multiple of 16\n");
1042+ return -11;
1043+ }
1044+ c7108_reg_wr16(C7108_AES_DMA_SRC0_LO, (u16) src);
1045+ c7108_reg_wr16(C7108_AES_DMA_SRC0_HI, (u16)((src & 0xffff0000) >> 16));
1046+ c7108_reg_wr16(C7108_AES_DMA_DST0_LO, (u16) dst);
1047+ c7108_reg_wr16(C7108_AES_DMA_DST0_HI, (u16)((dst & 0xffff0000) >> 16));
1048+ c7108_reg_wr16(C7108_AES_DMA_LEN, (u16) ((len / 16) - 1));
1049+
1050+ return 0;
1051+}
1052+
1053+static int
1054+c7108_aes_set_hw_iv(u8 iv[16])
1055+{
1056+ c7108_reg_wr16(C7108_AES_IV0_LO, (u16) ((iv[1] << 8) | iv[0]));
1057+ c7108_reg_wr16(C7108_AES_IV0_HI, (u16) ((iv[3] << 8) | iv[2]));
1058+ c7108_reg_wr16(C7108_AES_IV1_LO, (u16) ((iv[5] << 8) | iv[4]));
1059+ c7108_reg_wr16(C7108_AES_IV1_HI, (u16) ((iv[7] << 8) | iv[6]));
1060+ c7108_reg_wr16(C7108_AES_IV2_LO, (u16) ((iv[9] << 8) | iv[8]));
1061+ c7108_reg_wr16(C7108_AES_IV2_HI, (u16) ((iv[11] << 8) | iv[10]));
1062+ c7108_reg_wr16(C7108_AES_IV3_LO, (u16) ((iv[13] << 8) | iv[12]));
1063+ c7108_reg_wr16(C7108_AES_IV3_HI, (u16) ((iv[15] << 8) | iv[14]));
1064+
1065+ return 0;
1066+}
1067+
1068+static void
1069+c7108_aes_read_dkey(u32 * dkey)
1070+{
1071+ dkey[0] = (c7108_reg_rd16(C7108_AES_EKEY0_HI) << 16) |
1072+ c7108_reg_rd16(C7108_AES_EKEY0_LO);
1073+ dkey[1] = (c7108_reg_rd16(C7108_AES_EKEY1_HI) << 16) |
1074+ c7108_reg_rd16(C7108_AES_EKEY1_LO);
1075+ dkey[2] = (c7108_reg_rd16(C7108_AES_EKEY2_HI) << 16) |
1076+ c7108_reg_rd16(C7108_AES_EKEY2_LO);
1077+ dkey[3] = (c7108_reg_rd16(C7108_AES_EKEY3_HI) << 16) |
1078+ c7108_reg_rd16(C7108_AES_EKEY3_LO);
1079+ dkey[4] = (c7108_reg_rd16(C7108_AES_EKEY4_HI) << 16) |
1080+ c7108_reg_rd16(C7108_AES_EKEY4_LO);
1081+ dkey[5] = (c7108_reg_rd16(C7108_AES_EKEY5_HI) << 16) |
1082+ c7108_reg_rd16(C7108_AES_EKEY5_LO);
1083+ dkey[6] = (c7108_reg_rd16(C7108_AES_EKEY6_HI) << 16) |
1084+ c7108_reg_rd16(C7108_AES_EKEY6_LO);
1085+ dkey[7] = (c7108_reg_rd16(C7108_AES_EKEY7_HI) << 16) |
1086+ c7108_reg_rd16(C7108_AES_EKEY7_LO);
1087+}
1088+
1089+static int
1090+c7108_aes_cipher(int op,
1091+ u32 dst,
1092+ u32 src,
1093+ u32 len,
1094+ int klen,
1095+ u16 mode,
1096+ u32 key[8],
1097+ u8 iv[16])
1098+{
1099+ int rv = 0, cnt=0;
1100+ u16 ctrl = 0, stat = 0;
1101+
1102+ AES_LOCK();
1103+
1104+ /* Setup key length */
1105+ if (klen == 128) {
1106+ ctrl |= C7108_AES_KEY_LEN_128;
1107+ } else if (klen == 192) {
1108+ ctrl |= C7108_AES_KEY_LEN_192;
1109+ } else if (klen == 256) {
1110+ ctrl |= C7108_AES_KEY_LEN_256;
1111+ } else {
1112+ AES_UNLOCK();
1113+ return -3;
1114+ }
1115+
1116+ /* Check opcode */
1117+ if (C7108_AES_ENCRYPT == op) {
1118+ ctrl |= C7108_AES_ENCRYPT;
1119+ } else if (C7108_AES_DECRYPT == op) {
1120+ ctrl |= C7108_AES_DECRYPT;
1121+ } else {
1122+ AES_UNLOCK();
1123+ return -4;
1124+ }
1125+
1126+ /* check mode */
1127+ if ( (mode != C7108_AES_CTRL_MODE_CBC) &&
1128+ (mode != C7108_AES_CTRL_MODE_CFB) &&
1129+ (mode != C7108_AES_CTRL_MODE_OFB) &&
1130+ (mode != C7108_AES_CTRL_MODE_CTR) &&
1131+ (mode != C7108_AES_CTRL_MODE_ECB) ) {
1132+ AES_UNLOCK();
1133+ return -5;
1134+ }
1135+
1136+ /* Now set mode */
1137+ ctrl |= mode;
1138+
1139+ /* For CFB, OFB, and CTR, neither backward key
1140+ * expansion nor key inversion is required.
1141+ */
1142+ if ( (C7108_AES_DECRYPT == op) &&
1143+ (C7108_AES_CTRL_MODE_CBC == mode ||
1144+ C7108_AES_CTRL_MODE_ECB == mode ) ){
1145+
1146+ /* Program Key */
1147+ c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[4]);
1148+ c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[4] >> 16));
1149+ c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[5]);
1150+ c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[5] >> 16));
1151+ c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[6]);
1152+ c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[6] >> 16));
1153+ c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[7]);
1154+ c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[7] >> 16));
1155+ c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[2]);
1156+ c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[2] >> 16));
1157+ c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[3]);
1158+ c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[3] >> 16));
1159+
1160+
1161+ if (192 == klen) {
1162+ c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[7]);
1163+ c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[7] >> 16));
1164+ c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[7]);
1165+ c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[7] >> 16));
1166+
1167+ } else if (256 == klen) {
1168+ /* 256 */
1169+ c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[0]);
1170+ c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[0] >> 16));
1171+ c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[1]);
1172+ c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[1] >> 16));
1173+
1174+ }
1175+
1176+ } else {
1177+ /* Program Key */
1178+ c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[0]);
1179+ c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[0] >> 16));
1180+ c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[1]);
1181+ c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[1] >> 16));
1182+ c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[2]);
1183+ c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[2] >> 16));
1184+ c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[3]);
1185+ c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[3] >> 16));
1186+ c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[4]);
1187+ c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[4] >> 16));
1188+ c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[5]);
1189+ c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[5] >> 16));
1190+ c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[6]);
1191+ c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[6] >> 16));
1192+ c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[7]);
1193+ c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[7] >> 16));
1194+
1195+ }
1196+
1197+ /* Set IV always */
1198+ c7108_aes_set_hw_iv(iv);
1199+
1200+ /* Program DMA addresses */
1201+ if ((rv = c7108_aes_setup_dma(src, dst, len)) < 0) {
1202+ AES_UNLOCK();
1203+ return rv;
1204+ }
1205+
1206+
1207+ /* Start AES cipher */
1208+ c7108_reg_wr16(C7108_AES_CTRL, ctrl | C7108_AES_GO);
1209+
1210+ //printk("Ctrl: 0x%x\n", ctrl | C7108_AES_GO);
1211+ do {
1212+ /* TODO: interrupt mode */
1213+ // printk("aes_stat=0x%x\n", stat);
1214+ //udelay(100);
1215+ } while ((cnt++ < 1000000) &&
1216+ !((stat=c7108_reg_rd16(C7108_AES_CTRL))&C7108_AES_OP_DONE));
1217+
1218+
1219+ if ((mode == C7108_AES_CTRL_MODE_ECB)||
1220+ (mode == C7108_AES_CTRL_MODE_CBC)) {
1221+ /* Save out key when the lock is held ... */
1222+ c7108_aes_read_dkey(key);
1223+ }
1224+
1225+ AES_UNLOCK();
1226+ return 0;
1227+
1228+}
1229+
1230+/*
1231+ * Generate a new crypto device session.
1232+ */
1233+static int
1234+c7108_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
1235+{
1236+ struct cipher_7108 **swd;
1237+ u_int32_t i;
1238+ char *algo;
1239+ int mode, xfm_type;
1240+
1241+ dprintk("%s()\n", __FUNCTION__);
1242+ if (sid == NULL || cri == NULL) {
1243+ dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
1244+ return EINVAL;
1245+ }
1246+
1247+ if (c7108_sessions) {
1248+ for (i = 1; i < c7108_sesnum; i++)
1249+ if (c7108_sessions[i] == NULL)
1250+ break;
1251+ } else
1252+ i = 1; /* NB: to silence compiler warning */
1253+
1254+ if (c7108_sessions == NULL || i == c7108_sesnum) {
1255+ if (c7108_sessions == NULL) {
1256+ i = 1; /* We leave c7108_sessions[0] empty */
1257+ c7108_sesnum = CRYPTO_SW_SESSIONS;
1258+ } else
1259+ c7108_sesnum *= 2;
1260+
1261+ swd = kmalloc(c7108_sesnum * sizeof(struct cipher_7108 *),
1262+ GFP_ATOMIC);
1263+ if (swd == NULL) {
1264+ /* Reset session number */
1265+ if (c7108_sesnum == CRYPTO_SW_SESSIONS)
1266+ c7108_sesnum = 0;
1267+ else
1268+ c7108_sesnum /= 2;
1269+ dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
1270+ return ENOBUFS;
1271+ }
1272+ memset(swd, 0, c7108_sesnum * sizeof(struct cipher_7108 *));
1273+
1274+ /* Copy existing sessions */
1275+ if (c7108_sessions) {
1276+ memcpy(swd, c7108_sessions,
1277+ (c7108_sesnum / 2) * sizeof(struct cipher_7108 *));
1278+ kfree(c7108_sessions);
1279+ }
1280+
1281+ c7108_sessions = swd;
1282+
1283+ }
1284+
1285+ swd = &c7108_sessions[i];
1286+ *sid = i;
1287+
1288+ while (cri) {
1289+ *swd = (struct cipher_7108 *)
1290+ kmalloc(sizeof(struct cipher_7108), GFP_ATOMIC);
1291+ if (*swd == NULL) {
1292+ c7108_freesession(NULL, i);
1293+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
1294+ return ENOBUFS;
1295+ }
1296+ memset(*swd, 0, sizeof(struct cipher_7108));
1297+
1298+ algo = NULL;
1299+ mode = 0;
1300+ xfm_type = HW_TYPE_CIPHER;
1301+
1302+ switch (cri->cri_alg) {
1303+
1304+ case CRYPTO_AES_CBC:
1305+ algo = "aes";
1306+ mode = CRYPTO_TFM_MODE_CBC;
1307+ c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC;
1308+ break;
1309+#if 0
1310+ case CRYPTO_AES_CTR:
1311+ algo = "aes_ctr";
1312+ mode = CRYPTO_TFM_MODE_CBC;
1313+ c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR;
1314+ break;
1315+ case CRYPTO_AES_ECB:
1316+ algo = "aes_ecb";
1317+ mode = CRYPTO_TFM_MODE_CBC;
1318+ c7108_crypto_mode = C7108_AES_CTRL_MODE_ECB;
1319+ break;
1320+ case CRYPTO_AES_OFB:
1321+ algo = "aes_ofb";
1322+ mode = CRYPTO_TFM_MODE_CBC;
1323+ c7108_crypto_mode = C7108_AES_CTRL_MODE_OFB;
1324+ break;
1325+ case CRYPTO_AES_CFB:
1326+ algo = "aes_cfb";
1327+ mode = CRYPTO_TFM_MODE_CBC;
1328+ c7108_crypto_mode = C7108_AES_CTRL_MODE_CFB;
1329+ break;
1330+#endif
1331+ default:
1332+ printk("unsupported crypto algorithm: %d\n",
1333+ cri->cri_alg);
1334+ return -EINVAL;
1335+ break;
1336+ }
1337+
1338+
1339+ if (!algo || !*algo) {
1340+ printk("cypher_7108_crypto: Unknown algo 0x%x\n",
1341+ cri->cri_alg);
1342+ c7108_freesession(NULL, i);
1343+ return EINVAL;
1344+ }
1345+
1346+ if (xfm_type == HW_TYPE_CIPHER) {
1347+ if (debug) {
1348+ dprintk("%s key:", __FUNCTION__);
1349+ for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
1350+ dprintk("%s0x%02x", (i % 8) ? " " : "\n ",
1351+ cri->cri_key[i]);
1352+ dprintk("\n");
1353+ }
1354+
1355+ } else if (xfm_type == SW_TYPE_HMAC ||
1356+ xfm_type == SW_TYPE_HASH) {
1357+ printk("cypher_7108_crypto: HMAC unsupported!\n");
1358+ return -EINVAL;
1359+ c7108_freesession(NULL, i);
1360+ } else {
1361+ printk("cypher_7108_crypto: "
1362+ "Unhandled xfm_type %d\n", xfm_type);
1363+ c7108_freesession(NULL, i);
1364+ return EINVAL;
1365+ }
1366+
1367+ (*swd)->cri_alg = cri->cri_alg;
1368+ (*swd)->xfm_type = xfm_type;
1369+
1370+ cri = cri->cri_next;
1371+ swd = &((*swd)->next);
1372+ }
1373+ return 0;
1374+}
1375+
1376+/*
1377+ * Free a session.
1378+ */
1379+static int
1380+c7108_freesession(void *arg, u_int64_t tid)
1381+{
1382+ struct cipher_7108 *swd;
1383+ u_int32_t sid = CRYPTO_SESID2LID(tid);
1384+
1385+ dprintk("%s()\n", __FUNCTION__);
1386+ if (sid > c7108_sesnum || c7108_sessions == NULL ||
1387+ c7108_sessions[sid] == NULL) {
1388+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
1389+ return(EINVAL);
1390+ }
1391+
1392+ /* Silently accept and return */
1393+ if (sid == 0)
1394+ return(0);
1395+
1396+ while ((swd = c7108_sessions[sid]) != NULL) {
1397+ c7108_sessions[sid] = swd->next;
1398+ kfree(swd);
1399+ }
1400+ return 0;
1401+}
1402+
1403+/*
1404+ * Process a hardware request.
1405+ */
1406+static int
1407+c7108_process(void *arg, struct cryptop *crp, int hint)
1408+{
1409+ struct cryptodesc *crd;
1410+ struct cipher_7108 *sw;
1411+ u_int32_t lid;
1412+ int type;
1413+ u32 hwkey[8];
1414+
1415+#define SCATTERLIST_MAX 16
1416+ struct scatterlist sg[SCATTERLIST_MAX];
1417+ int sg_num, sg_len, skip;
1418+ struct sk_buff *skb = NULL;
1419+ struct uio *uiop = NULL;
1420+
1421+ dprintk("%s()\n", __FUNCTION__);
1422+ /* Sanity check */
1423+ if (crp == NULL) {
1424+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
1425+ return EINVAL;
1426+ }
1427+
1428+ crp->crp_etype = 0;
1429+
1430+ if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
1431+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
1432+ crp->crp_etype = EINVAL;
1433+ goto done;
1434+ }
1435+
1436+ lid = crp->crp_sid & 0xffffffff;
1437+ if (lid >= c7108_sesnum || lid == 0 || c7108_sessions == NULL ||
1438+ c7108_sessions[lid] == NULL) {
1439+ crp->crp_etype = ENOENT;
1440+ dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
1441+ goto done;
1442+ }
1443+
1444+ /*
1445+ * do some error checking outside of the loop for SKB and IOV
1446+ * processing this leaves us with valid skb or uiop pointers
1447+ * for later
1448+ */
1449+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
1450+ skb = (struct sk_buff *) crp->crp_buf;
1451+ if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
1452+ printk("%s,%d: %d nr_frags > SCATTERLIST_MAX",
1453+ __FILE__, __LINE__,
1454+ skb_shinfo(skb)->nr_frags);
1455+ goto done;
1456+ }
1457+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
1458+ uiop = (struct uio *) crp->crp_buf;
1459+ if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
1460+ printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX",
1461+ __FILE__, __LINE__,
1462+ uiop->uio_iovcnt);
1463+ goto done;
1464+ }
1465+ }
1466+
1467+ /* Go through crypto descriptors, processing as we go */
1468+ for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
1469+ /*
1470+ * Find the crypto context.
1471+ *
1472+ * XXX Note that the logic here prevents us from having
1473+ * XXX the same algorithm multiple times in a session
1474+ * XXX (or rather, we can but it won't give us the right
1475+ * XXX results). To do that, we'd need some way of differentiating
1476+ * XXX between the various instances of an algorithm (so we can
1477+ * XXX locate the correct crypto context).
1478+ */
1479+ for (sw = c7108_sessions[lid];
1480+ sw && sw->cri_alg != crd->crd_alg;
1481+ sw = sw->next)
1482+ ;
1483+
1484+ /* No such context ? */
1485+ if (sw == NULL) {
1486+ crp->crp_etype = EINVAL;
1487+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
1488+ goto done;
1489+ }
1490+
1491+ skip = crd->crd_skip;
1492+
1493+ /*
1494+ * setup the SG list skip from the start of the buffer
1495+ */
1496+ memset(sg, 0, sizeof(sg));
1497+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
1498+ int i, len;
1499+ type = CRYPTO_BUF_SKBUF;
1500+
1501+ sg_num = 0;
1502+ sg_len = 0;
1503+
1504+ if (skip < skb_headlen(skb)) {
1505+ //sg[sg_num].page = virt_to_page(skb->data + skip);
1506+ //sg[sg_num].offset = offset_in_page(skb->data + skip);
1507+ len = skb_headlen(skb) - skip;
1508+ if (len + sg_len > crd->crd_len)
1509+ len = crd->crd_len - sg_len;
1510+ //sg[sg_num].length = len;
1511+ sg_set_page(&sg[sg_num], virt_to_page(skb->data + skip), len, offset_in_page(skb->data + skip));
1512+ sg_len += sg[sg_num].length;
1513+ sg_num++;
1514+ skip = 0;
1515+ } else
1516+ skip -= skb_headlen(skb);
1517+
1518+ for (i = 0; sg_len < crd->crd_len &&
1519+ i < skb_shinfo(skb)->nr_frags &&
1520+ sg_num < SCATTERLIST_MAX; i++) {
1521+ if (skip < skb_shinfo(skb)->frags[i].size) {
1522+ //sg[sg_num].page = skb_shinfo(skb)->frags[i].page;
1523+ //sg[sg_num].offset = skb_shinfo(skb)->frags[i].page_offset + skip;
1524+ len = skb_shinfo(skb)->frags[i].size - skip;
1525+ if (len + sg_len > crd->crd_len)
1526+ len = crd->crd_len - sg_len;
1527+ //sg[sg_num].length = len;
1528+ sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page, len, skb_shinfo(skb)->frags[i].page_offset + skip);
1529+ sg_len += sg[sg_num].length;
1530+ sg_num++;
1531+ skip = 0;
1532+ } else
1533+ skip -= skb_shinfo(skb)->frags[i].size;
1534+ }
1535+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
1536+ int len;
1537+ type = CRYPTO_BUF_IOV;
1538+ sg_len = 0;
1539+ for (sg_num = 0; sg_len < crd->crd_len &&
1540+ sg_num < uiop->uio_iovcnt &&
1541+ sg_num < SCATTERLIST_MAX; sg_num++) {
1542+ if (skip < uiop->uio_iov[sg_num].iov_len) {
1543+ //sg[sg_num].page = virt_to_page(uiop->uio_iov[sg_num].iov_base+skip);
1544+ //sg[sg_num].offset = offset_in_page(uiop->uio_iov[sg_num].iov_base+skip);
1545+ len = uiop->uio_iov[sg_num].iov_len - skip;
1546+ if (len + sg_len > crd->crd_len)
1547+ len = crd->crd_len - sg_len;
1548+ //sg[sg_num].length = len;
1549+ sg_set_page(&sg[sg_num], virt_to_page(uiop->uio_iov[sg_num].iov_base+skip), len, offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
1550+ sg_len += sg[sg_num].length;
1551+ skip = 0;
1552+ } else
1553+ skip -= uiop->uio_iov[sg_num].iov_len;
1554+ }
1555+ } else {
1556+ type = CRYPTO_BUF_CONTIG;
1557+ //sg[0].page = virt_to_page(crp->crp_buf + skip);
1558+ //sg[0].offset = offset_in_page(crp->crp_buf + skip);
1559+ sg_len = (crp->crp_ilen - skip);
1560+ if (sg_len > crd->crd_len)
1561+ sg_len = crd->crd_len;
1562+ //sg[0].length = sg_len;
1563+ sg_set_page(&sg[0], virt_to_page(crp->crp_buf + skip), sg_len, offset_in_page(crp->crp_buf + skip));
1564+ sg_num = 1;
1565+ }
1566+
1567+
1568+ switch (sw->xfm_type) {
1569+
1570+ case HW_TYPE_CIPHER: {
1571+
1572+ unsigned char iv[64];
1573+ unsigned char *ivp = iv;
1574+ int i;
1575+ int ivsize = 16; /* fixed for AES */
1576+ int blocksize = 16; /* fixed for AES */
1577+
1578+ if (sg_len < blocksize) {
1579+ crp->crp_etype = EINVAL;
1580+ dprintk("%s,%d: EINVAL len %d < %d\n",
1581+ __FILE__, __LINE__,
1582+ sg_len,
1583+ blocksize);
1584+ goto done;
1585+ }
1586+
1587+ if (ivsize > sizeof(iv)) {
1588+ crp->crp_etype = EINVAL;
1589+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
1590+ goto done;
1591+ }
1592+
1593+ if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
1594+
1595+ if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
1596+ ivp = crd->crd_iv;
1597+ } else {
1598+ get_random_bytes(ivp, ivsize);
1599+ }
1600+ /*
1601+ * do we have to copy the IV back to the buffer ?
1602+ */
1603+ if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
1604+ crypto_copyback(crp->crp_buf,
1605+ crd->crd_inject,
1606+ ivsize,
1607+ (caddr_t)ivp);
1608+ }
1609+
1610+ c7108_xlate_key(crd->crd_klen,
1611+ (u8*)crd->crd_key, (u32*)hwkey);
1612+
1613+ /* Encrypt SG list */
1614+ for (i = 0; i < sg_num; i++) {
1615+ sg[i].dma_address =
1616+ dma_map_single(NULL,
1617+ kmap(sg_page(&sg[i])) + sg[i].offset, sg_len, DMA_BIDIRECTIONAL);
1618+#if 0
1619+ printk("sg[%d]:0x%08x, off 0x%08x "
1620+ "kmap 0x%08x phys 0x%08x\n",
1621+ i, sg[i].page, sg[i].offset,
1622+ kmap(sg[i].page) + sg[i].offset,
1623+ sg[i].dma_address);
1624+#endif
1625+ c7108_aes_cipher(C7108_AES_ENCRYPT,
1626+ sg[i].dma_address,
1627+ sg[i].dma_address,
1628+ sg_len,
1629+ crd->crd_klen,
1630+ c7108_crypto_mode,
1631+ hwkey,
1632+ ivp);
1633+
1634+ if ((c7108_crypto_mode == C7108_AES_CTRL_MODE_CBC)||
1635+ (c7108_crypto_mode == C7108_AES_CTRL_MODE_ECB)) {
1636+ /* Read back expanded key and cache it in key
1637+ * context.
1638+ * NOTE: for ECB/CBC modes only (not CTR, CFB, OFB)
1639+ * where you set the key once.
1640+ */
1641+ c7108_cache_key(crd->crd_klen,
1642+ (u32*)hwkey, (u8*)crd->crd_key);
1643+#if 0
1644+ printk("%s expanded key:", __FUNCTION__);
1645+ for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
1646+ printk("%s0x%02x", (i % 8) ? " " : "\n ",
1647+ crd->crd_key[i]);
1648+ printk("\n");
1649+#endif
1650+ }
1651+ }
1652+ }
1653+ else { /*decrypt */
1654+
1655+ if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
1656+ ivp = crd->crd_iv;
1657+ } else {
1658+ crypto_copydata(crp->crp_buf, crd->crd_inject,
1659+ ivsize, (caddr_t)ivp);
1660+ }
1661+
1662+ c7108_xlate_key(crd->crd_klen,
1663+ (u8*)crd->crd_key, (u32*)hwkey);
1664+
1665+ /* Decrypt SG list */
1666+ for (i = 0; i < sg_num; i++) {
1667+ sg[i].dma_address =
1668+ dma_map_single(NULL,
1669+ kmap(sg_page(&sg[i])) + sg[i].offset,
1670+ sg_len, DMA_BIDIRECTIONAL);
1671+
1672+#if 0
1673+ printk("sg[%d]:0x%08x, off 0x%08x "
1674+ "kmap 0x%08x phys 0x%08x\n",
1675+ i, sg[i].page, sg[i].offset,
1676+ kmap(sg[i].page) + sg[i].offset,
1677+ sg[i].dma_address);
1678+#endif
1679+ c7108_aes_cipher(C7108_AES_DECRYPT,
1680+ sg[i].dma_address,
1681+ sg[i].dma_address,
1682+ sg_len,
1683+ crd->crd_klen,
1684+ c7108_crypto_mode,
1685+ hwkey,
1686+ ivp);
1687+ }
1688+ }
1689+ } break;
1690+ case SW_TYPE_HMAC:
1691+ case SW_TYPE_HASH:
1692+ crp->crp_etype = EINVAL;
1693+ goto done;
1694+ break;
1695+
1696+ case SW_TYPE_COMP:
1697+ crp->crp_etype = EINVAL;
1698+ goto done;
1699+ break;
1700+
1701+ default:
1702+ /* Unknown/unsupported algorithm */
1703+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
1704+ crp->crp_etype = EINVAL;
1705+ goto done;
1706+ }
1707+ }
1708+
1709+done:
1710+ crypto_done(crp);
1711+ return 0;
1712+}
1713+
1714+static struct {
1715+ softc_device_decl sc_dev;
1716+} a7108dev;
1717+
1718+static device_method_t a7108_methods = {
1719+/* crypto device methods */
1720+ DEVMETHOD(cryptodev_newsession, c7108_newsession),
1721+ DEVMETHOD(cryptodev_freesession, c7108_freesession),
1722+ DEVMETHOD(cryptodev_process, c7108_process),
1723+ DEVMETHOD(cryptodev_kprocess, NULL)
1724+};
1725+
1726+static int
1727+cypher_7108_crypto_init(void)
1728+{
1729+ dprintk("%s(%p)\n", __FUNCTION__, cypher_7108_crypto_init);
1730+
1731+ iobar = (unsigned long)ioremap(CCU_AES_REG_BASE, 0x4000);
1732+ printk("7108: AES @ 0x%08x (0x%08x phys) %s mode\n",
1733+ iobar, CCU_AES_REG_BASE,
1734+ c7108_crypto_mode & C7108_AES_CTRL_MODE_CBC ? "CBC" :
1735+ c7108_crypto_mode & C7108_AES_CTRL_MODE_ECB ? "ECB" :
1736+ c7108_crypto_mode & C7108_AES_CTRL_MODE_CTR ? "CTR" :
1737+ c7108_crypto_mode & C7108_AES_CTRL_MODE_CFB ? "CFB" :
1738+ c7108_crypto_mode & C7108_AES_CTRL_MODE_OFB ? "OFB" : "???");
1739+ csr_mutex = SPIN_LOCK_UNLOCKED;
1740+
1741+ memset(&a7108dev, 0, sizeof(a7108dev));
1742+ softc_device_init(&a7108dev, "aes7108", 0, a7108_methods);
1743+
1744+ c7108_id = crypto_get_driverid(softc_get_device(&a7108dev), CRYPTOCAP_F_HARDWARE);
1745+ if (c7108_id < 0)
1746+ panic("7108: crypto device cannot initialize!");
1747+
1748+// crypto_register(c7108_id, CRYPTO_AES_CBC, 0, 0, c7108_newsession, c7108_freesession, c7108_process, NULL);
1749+ crypto_register(c7108_id, CRYPTO_AES_CBC, 0, 0);
1750+
1751+ return(0);
1752+}
1753+
1754+static void
1755+cypher_7108_crypto_exit(void)
1756+{
1757+ dprintk("%s()\n", __FUNCTION__);
1758+ crypto_unregister_all(c7108_id);
1759+ c7108_id = -1;
1760+}
1761+
1762+module_init(cypher_7108_crypto_init);
1763+module_exit(cypher_7108_crypto_exit);
1764+
1765+MODULE_LICENSE("Dual BSD/GPL");
1766+MODULE_DESCRIPTION("Cypher 7108 Crypto (OCF module for kernel crypto)");
1767diff --git a/crypto/ocf/c7108/aes-7108.h b/crypto/ocf/c7108/aes-7108.h
1768new file mode 100644
1769index 0000000..48711b4
1770--- /dev/null
1771+++ b/crypto/ocf/c7108/aes-7108.h
1772@@ -0,0 +1,134 @@
1773+/*
1774+ * Copyright (C) 2006 Micronas USA
1775+ *
1776+ * 1. Redistributions of source code must retain the above copyright
1777+ * notice, this list of conditions and the following disclaimer.
1778+ * 2. Redistributions in binary form must reproduce the above copyright
1779+ * notice, this list of conditions and the following disclaimer in the
1780+ * documentation and/or other materials provided with the distribution.
1781+ * 3. The name of the author may not be used to endorse or promote products
1782+ * derived from this software without specific prior written permission.
1783+ *
1784+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1785+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1786+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1787+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1788+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1789+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1790+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1791+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1792+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1793+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1794+ *
1795+ * Effort sponsored in part by the Defense Advanced Research Projects
1796+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
1797+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
1798+ *
1799+ */
1800+
1801+#ifndef __AES_7108_H__
1802+#define __AES_7108_H__
1803+
1804+/* Cypher 7108 AES Controller Hardware */
1805+#define CCU_REG_BASE 0x1b500000
1806+#define CCU_AES_REG_BASE (CCU_REG_BASE + 0x100)
1807+#define C7108_AES_KEY0_LO (0x0000)
1808+#define C7108_AES_KEY0_HI (0x0004)
1809+#define C7108_AES_KEY1_LO (0x0008)
1810+#define C7108_AES_KEY1_HI (0x000c)
1811+#define C7108_AES_KEY2_LO (0x0010)
1812+#define C7108_AES_KEY2_HI (0x0014)
1813+#define C7108_AES_KEY3_LO (0x0018)
1814+#define C7108_AES_KEY3_HI (0x001c)
1815+#define C7108_AES_KEY4_LO (0x0020)
1816+#define C7108_AES_KEY4_HI (0x0024)
1817+#define C7108_AES_KEY5_LO (0x0028)
1818+#define C7108_AES_KEY5_HI (0x002c)
1819+#define C7108_AES_KEY6_LO (0x0030)
1820+#define C7108_AES_KEY6_HI (0x0034)
1821+#define C7108_AES_KEY7_LO (0x0038)
1822+#define C7108_AES_KEY7_HI (0x003c)
1823+#define C7108_AES_IV0_LO (0x0040)
1824+#define C7108_AES_IV0_HI (0x0044)
1825+#define C7108_AES_IV1_LO (0x0048)
1826+#define C7108_AES_IV1_HI (0x004c)
1827+#define C7108_AES_IV2_LO (0x0050)
1828+#define C7108_AES_IV2_HI (0x0054)
1829+#define C7108_AES_IV3_LO (0x0058)
1830+#define C7108_AES_IV3_HI (0x005c)
1831+
1832+#define C7108_AES_DMA_SRC0_LO (0x0068) /* Bits 0:15 */
1833+#define C7108_AES_DMA_SRC0_HI (0x006c) /* Bits 27:16 */
1834+#define C7108_AES_DMA_DST0_LO (0x0070) /* Bits 0:15 */
1835+#define C7108_AES_DMA_DST0_HI (0x0074) /* Bits 27:16 */
1836+#define C7108_AES_DMA_LEN (0x0078) /*Bytes:(Count+1)x16 */
1837+
1838+/* AES/Copy engine control register */
1839+#define C7108_AES_CTRL (0x007c) /* AES control */
1840+#define C7108_AES_CTRL_RS (1<<0) /* Which set of src/dst to use */
1841+
1842+/* AES Cipher mode, controlled by setting Bits 2:0 */
1843+#define C7108_AES_CTRL_MODE_CBC 0
1844+#define C7108_AES_CTRL_MODE_CFB (1<<0)
1845+#define C7108_AES_CTRL_MODE_OFB (1<<1)
1846+#define C7108_AES_CTRL_MODE_CTR ((1<<0)|(1<<1))
1847+#define C7108_AES_CTRL_MODE_ECB (1<<2)
1848+
1849+/* AES Key length , Bits 5:4 */
1850+#define C7108_AES_KEY_LEN_128 0 /* 00 */
1851+#define C7108_AES_KEY_LEN_192 (1<<4) /* 01 */
1852+#define C7108_AES_KEY_LEN_256 (1<<5) /* 10 */
1853+
1854+/* AES Operation (crypt/decrypt), Bit 3 */
1855+#define C7108_AES_DECRYPT (1<<3) /* Clear for encrypt */
1856+#define C7108_AES_ENCRYPT 0
1857+#define C7108_AES_INTR (1<<13) /* Set on done trans from 0->1*/
1858+#define C7108_AES_GO (1<<14) /* Run */
1859+#define C7108_AES_OP_DONE (1<<15) /* Set when complete */
1860+
1861+
1862+/* Expanded key registers */
1863+#define C7108_AES_EKEY0_LO (0x0080)
1864+#define C7108_AES_EKEY0_HI (0x0084)
1865+#define C7108_AES_EKEY1_LO (0x0088)
1866+#define C7108_AES_EKEY1_HI (0x008c)
1867+#define C7108_AES_EKEY2_LO (0x0090)
1868+#define C7108_AES_EKEY2_HI (0x0094)
1869+#define C7108_AES_EKEY3_LO (0x0098)
1870+#define C7108_AES_EKEY3_HI (0x009c)
1871+#define C7108_AES_EKEY4_LO (0x00a0)
1872+#define C7108_AES_EKEY4_HI (0x00a4)
1873+#define C7108_AES_EKEY5_LO (0x00a8)
1874+#define C7108_AES_EKEY5_HI (0x00ac)
1875+#define C7108_AES_EKEY6_LO (0x00b0)
1876+#define C7108_AES_EKEY6_HI (0x00b4)
1877+#define C7108_AES_EKEY7_LO (0x00b8)
1878+#define C7108_AES_EKEY7_HI (0x00bc)
1879+#define C7108_AES_OK (0x00fc) /* Reset: "OK" */
1880+
1881+#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
1882+
1883+/* Software session entry */
1884+
1885+#define HW_TYPE_CIPHER 0
1886+#define SW_TYPE_HMAC 1
1887+#define SW_TYPE_AUTH2 2
1888+#define SW_TYPE_HASH 3
1889+#define SW_TYPE_COMP 4
1890+
1891+struct cipher_7108 {
1892+ int xfm_type;
1893+ int cri_alg;
1894+ union {
1895+ struct {
1896+ char sw_key[HMAC_BLOCK_LEN];
1897+ int sw_klen;
1898+ int sw_authlen;
1899+ } hmac;
1900+ } u;
1901+ struct cipher_7108 *next;
1902+};
1903+
1904+
1905+
1906+#endif /* __C7108_AES_7108_H__ */
1907diff --git a/crypto/ocf/criov.c b/crypto/ocf/criov.c
1908new file mode 100644
1909index 0000000..d04b984
1910--- /dev/null
1911+++ b/crypto/ocf/criov.c
1912@@ -0,0 +1,215 @@
1913+/* $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $ */
1914+
1915+/*
1916+ * Linux port done by David McCullough <david_mccullough@mcafee.com>
1917+ * Copyright (C) 2006-2010 David McCullough
1918+ * Copyright (C) 2004-2005 Intel Corporation.
1919+ * The license and original author are listed below.
1920+ *
1921+ * Copyright (c) 1999 Theo de Raadt
1922+ *
1923+ * Redistribution and use in source and binary forms, with or without
1924+ * modification, are permitted provided that the following conditions
1925+ * are met:
1926+ *
1927+ * 1. Redistributions of source code must retain the above copyright
1928+ * notice, this list of conditions and the following disclaimer.
1929+ * 2. Redistributions in binary form must reproduce the above copyright
1930+ * notice, this list of conditions and the following disclaimer in the
1931+ * documentation and/or other materials provided with the distribution.
1932+ * 3. The name of the author may not be used to endorse or promote products
1933+ * derived from this software without specific prior written permission.
1934+ *
1935+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1936+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1937+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1938+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1939+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1940+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1941+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1942+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1943+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1944+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1945+ *
1946+__FBSDID("$FreeBSD: src/sys/opencrypto/criov.c,v 1.5 2006/06/04 22:15:13 pjd Exp $");
1947+ */
1948+
1949+#ifndef AUTOCONF_INCLUDED
1950+#include <linux/config.h>
1951+#endif
1952+#include <linux/module.h>
1953+#include <linux/init.h>
1954+#include <linux/slab.h>
1955+#include <linux/uio.h>
1956+#include <linux/skbuff.h>
1957+#include <linux/kernel.h>
1958+#include <linux/mm.h>
1959+#include <asm/io.h>
1960+
1961+#include <uio.h>
1962+#include <cryptodev.h>
1963+
1964+/*
1965+ * This macro is only for avoiding code duplication, as we need to skip
1966+ * given number of bytes in the same way in three functions below.
1967+ */
1968+#define CUIO_SKIP() do { \
1969+ KASSERT(off >= 0, ("%s: off %d < 0", __func__, off)); \
1970+ KASSERT(len >= 0, ("%s: len %d < 0", __func__, len)); \
1971+ while (off > 0) { \
1972+ KASSERT(iol >= 0, ("%s: empty in skip", __func__)); \
1973+ if (off < iov->iov_len) \
1974+ break; \
1975+ off -= iov->iov_len; \
1976+ iol--; \
1977+ iov++; \
1978+ } \
1979+} while (0)
1980+
1981+void
1982+cuio_copydata(struct uio* uio, int off, int len, caddr_t cp)
1983+{
1984+ struct iovec *iov = uio->uio_iov;
1985+ int iol = uio->uio_iovcnt;
1986+ unsigned count;
1987+
1988+ CUIO_SKIP();
1989+ while (len > 0) {
1990+ KASSERT(iol >= 0, ("%s: empty", __func__));
1991+ count = min((int)(iov->iov_len - off), len);
1992+ memcpy(cp, ((caddr_t)iov->iov_base) + off, count);
1993+ len -= count;
1994+ cp += count;
1995+ off = 0;
1996+ iol--;
1997+ iov++;
1998+ }
1999+}
2000+
2001+void
2002+cuio_copyback(struct uio* uio, int off, int len, caddr_t cp)
2003+{
2004+ struct iovec *iov = uio->uio_iov;
2005+ int iol = uio->uio_iovcnt;
2006+ unsigned count;
2007+
2008+ CUIO_SKIP();
2009+ while (len > 0) {
2010+ KASSERT(iol >= 0, ("%s: empty", __func__));
2011+ count = min((int)(iov->iov_len - off), len);
2012+ memcpy(((caddr_t)iov->iov_base) + off, cp, count);
2013+ len -= count;
2014+ cp += count;
2015+ off = 0;
2016+ iol--;
2017+ iov++;
2018+ }
2019+}
2020+
2021+/*
2022+ * Return a pointer to iov/offset of location in iovec list.
2023+ */
2024+struct iovec *
2025+cuio_getptr(struct uio *uio, int loc, int *off)
2026+{
2027+ struct iovec *iov = uio->uio_iov;
2028+ int iol = uio->uio_iovcnt;
2029+
2030+ while (loc >= 0) {
2031+ /* Normal end of search */
2032+ if (loc < iov->iov_len) {
2033+ *off = loc;
2034+ return (iov);
2035+ }
2036+
2037+ loc -= iov->iov_len;
2038+ if (iol == 0) {
2039+ if (loc == 0) {
2040+ /* Point at the end of valid data */
2041+ *off = iov->iov_len;
2042+ return (iov);
2043+ } else
2044+ return (NULL);
2045+ } else {
2046+ iov++, iol--;
2047+ }
2048+ }
2049+
2050+ return (NULL);
2051+}
2052+
2053+EXPORT_SYMBOL(cuio_copyback);
2054+EXPORT_SYMBOL(cuio_copydata);
2055+EXPORT_SYMBOL(cuio_getptr);
2056+
2057+
2058+static void
2059+skb_copy_bits_back(struct sk_buff *skb, int offset, caddr_t cp, int len)
2060+{
2061+ int i;
2062+ if (offset < skb_headlen(skb)) {
2063+ memcpy(skb->data + offset, cp, min_t(int, skb_headlen(skb), len));
2064+ len -= skb_headlen(skb);
2065+ cp += skb_headlen(skb);
2066+ }
2067+ offset -= skb_headlen(skb);
2068+ for (i = 0; len > 0 && i < skb_shinfo(skb)->nr_frags; i++) {
2069+ if (offset < skb_shinfo(skb)->frags[i].size) {
2070+ memcpy(page_address(skb_shinfo(skb)->frags[i].page) +
2071+ skb_shinfo(skb)->frags[i].page_offset,
2072+ cp, min_t(int, skb_shinfo(skb)->frags[i].size, len));
2073+ len -= skb_shinfo(skb)->frags[i].size;
2074+ cp += skb_shinfo(skb)->frags[i].size;
2075+ }
2076+ offset -= skb_shinfo(skb)->frags[i].size;
2077+ }
2078+}
2079+
2080+void
2081+crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in)
2082+{
2083+
2084+ if ((flags & CRYPTO_F_SKBUF) != 0)
2085+ skb_copy_bits_back((struct sk_buff *)buf, off, in, size);
2086+ else if ((flags & CRYPTO_F_IOV) != 0)
2087+ cuio_copyback((struct uio *)buf, off, size, in);
2088+ else
2089+ bcopy(in, buf + off, size);
2090+}
2091+
2092+void
2093+crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out)
2094+{
2095+
2096+ if ((flags & CRYPTO_F_SKBUF) != 0)
2097+ skb_copy_bits((struct sk_buff *)buf, off, out, size);
2098+ else if ((flags & CRYPTO_F_IOV) != 0)
2099+ cuio_copydata((struct uio *)buf, off, size, out);
2100+ else
2101+ bcopy(buf + off, out, size);
2102+}
2103+
2104+int
2105+crypto_apply(int flags, caddr_t buf, int off, int len,
2106+ int (*f)(void *, void *, u_int), void *arg)
2107+{
2108+#if 0
2109+ int error;
2110+
2111+ if ((flags & CRYPTO_F_SKBUF) != 0)
2112+ error = XXXXXX((struct mbuf *)buf, off, len, f, arg);
2113+ else if ((flags & CRYPTO_F_IOV) != 0)
2114+ error = cuio_apply((struct uio *)buf, off, len, f, arg);
2115+ else
2116+ error = (*f)(arg, buf + off, len);
2117+ return (error);
2118+#else
2119+ KASSERT(0, ("crypto_apply not implemented!\n"));
2120+#endif
2121+ return 0;
2122+}
2123+
2124+EXPORT_SYMBOL(crypto_copyback);
2125+EXPORT_SYMBOL(crypto_copydata);
2126+EXPORT_SYMBOL(crypto_apply);
2127+
2128diff --git a/crypto/ocf/crypto.c b/crypto/ocf/crypto.c
2129new file mode 100644
2130index 0000000..1adbaa7
2131--- /dev/null
2132+++ b/crypto/ocf/crypto.c
2133@@ -0,0 +1,1784 @@
2134+/*-
2135+ * Linux port done by David McCullough <david_mccullough@mcafee.com>
2136+ * Copyright (C) 2006-2010 David McCullough
2137+ * Copyright (C) 2004-2005 Intel Corporation.
2138+ * The license and original author are listed below.
2139+ *
2140+ * Redistribution and use in source and binary forms, with or without
2141+ * Copyright (c) 2002-2006 Sam Leffler. All rights reserved.
2142+ *
2143+ * modification, are permitted provided that the following conditions
2144+ * are met:
2145+ * 1. Redistributions of source code must retain the above copyright
2146+ * notice, this list of conditions and the following disclaimer.
2147+ * 2. Redistributions in binary form must reproduce the above copyright
2148+ * notice, this list of conditions and the following disclaimer in the
2149+ * documentation and/or other materials provided with the distribution.
2150+ *
2151+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2152+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2153+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2154+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2155+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2156+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2157+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2158+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2159+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2160+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2161+ */
2162+
2163+#if 0
2164+#include <sys/cdefs.h>
2165+__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.27 2007/03/21 03:42:51 sam Exp $");
2166+#endif
2167+
2168+/*
2169+ * Cryptographic Subsystem.
2170+ *
2171+ * This code is derived from the Openbsd Cryptographic Framework (OCF)
2172+ * that has the copyright shown below. Very little of the original
2173+ * code remains.
2174+ */
2175+/*-
2176+ * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
2177+ *
2178+ * This code was written by Angelos D. Keromytis in Athens, Greece, in
2179+ * February 2000. Network Security Technologies Inc. (NSTI) kindly
2180+ * supported the development of this code.
2181+ *
2182+ * Copyright (c) 2000, 2001 Angelos D. Keromytis
2183+ *
2184+ * Permission to use, copy, and modify this software with or without fee
2185+ * is hereby granted, provided that this entire notice is included in
2186+ * all source code copies of any software which is or includes a copy or
2187+ * modification of this software.
2188+ *
2189+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
2190+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
2191+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
2192+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
2193+ * PURPOSE.
2194+ *
2195+__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp Exp $");
2196+ */
2197+
2198+
2199+#ifndef AUTOCONF_INCLUDED
2200+#include <linux/config.h>
2201+#endif
2202+#include <linux/module.h>
2203+#include <linux/init.h>
2204+#include <linux/list.h>
2205+#include <linux/slab.h>
2206+#include <linux/wait.h>
2207+#include <linux/sched.h>
2208+#include <linux/spinlock.h>
2209+#include <linux/version.h>
2210+#include <cryptodev.h>
2211+
2212+/*
2213+ * keep track of whether or not we have been initialised, a big
2214+ * issue if we are linked into the kernel and a driver gets started before
2215+ * us
2216+ */
2217+static int crypto_initted = 0;
2218+
2219+/*
2220+ * Crypto drivers register themselves by allocating a slot in the
2221+ * crypto_drivers table with crypto_get_driverid() and then registering
2222+ * each algorithm they support with crypto_register() and crypto_kregister().
2223+ */
2224+
2225+/*
2226+ * lock on driver table
2227+ * we track its state as spin_is_locked does not do anything on non-SMP boxes
2228+ */
2229+static spinlock_t crypto_drivers_lock;
2230+static int crypto_drivers_locked; /* for non-SMP boxes */
2231+
2232+#define CRYPTO_DRIVER_LOCK() \
2233+ ({ \
2234+ spin_lock_irqsave(&crypto_drivers_lock, d_flags); \
2235+ crypto_drivers_locked = 1; \
2236+ dprintk("%s,%d: DRIVER_LOCK()\n", __FILE__, __LINE__); \
2237+ })
2238+#define CRYPTO_DRIVER_UNLOCK() \
2239+ ({ \
2240+ dprintk("%s,%d: DRIVER_UNLOCK()\n", __FILE__, __LINE__); \
2241+ crypto_drivers_locked = 0; \
2242+ spin_unlock_irqrestore(&crypto_drivers_lock, d_flags); \
2243+ })
2244+#define CRYPTO_DRIVER_ASSERT() \
2245+ ({ \
2246+ if (!crypto_drivers_locked) { \
2247+ dprintk("%s,%d: DRIVER_ASSERT!\n", __FILE__, __LINE__); \
2248+ } \
2249+ })
2250+
2251+/*
2252+ * Crypto device/driver capabilities structure.
2253+ *
2254+ * Synchronization:
2255+ * (d) - protected by CRYPTO_DRIVER_LOCK()
2256+ * (q) - protected by CRYPTO_Q_LOCK()
2257+ * Not tagged fields are read-only.
2258+ */
2259+struct cryptocap {
2260+ device_t cc_dev; /* (d) device/driver */
2261+ u_int32_t cc_sessions; /* (d) # of sessions */
2262+ u_int32_t cc_koperations; /* (d) # os asym operations */
2263+ /*
2264+ * Largest possible operator length (in bits) for each type of
2265+ * encryption algorithm. XXX not used
2266+ */
2267+ u_int16_t cc_max_op_len[CRYPTO_ALGORITHM_MAX + 1];
2268+ u_int8_t cc_alg[CRYPTO_ALGORITHM_MAX + 1];
2269+ u_int8_t cc_kalg[CRK_ALGORITHM_MAX + 1];
2270+
2271+ int cc_flags; /* (d) flags */
2272+#define CRYPTOCAP_F_CLEANUP 0x80000000 /* needs resource cleanup */
2273+ int cc_qblocked; /* (q) symmetric q blocked */
2274+ int cc_kqblocked; /* (q) asymmetric q blocked */
2275+
2276+ int cc_unqblocked; /* (q) symmetric q blocked */
2277+ int cc_unkqblocked; /* (q) asymmetric q blocked */
2278+};
2279+static struct cryptocap *crypto_drivers = NULL;
2280+static int crypto_drivers_num = 0;
2281+
2282+/*
2283+ * There are two queues for crypto requests; one for symmetric (e.g.
2284+ * cipher) operations and one for asymmetric (e.g. MOD)operations.
2285+ * A single mutex is used to lock access to both queues. We could
2286+ * have one per-queue but having one simplifies handling of block/unblock
2287+ * operations.
2288+ */
2289+static int crp_sleep = 0;
2290+static LIST_HEAD(crp_q); /* request queues */
2291+static LIST_HEAD(crp_kq);
2292+
2293+static spinlock_t crypto_q_lock;
2294+
2295+int crypto_all_qblocked = 0; /* protect with Q_LOCK */
2296+module_param(crypto_all_qblocked, int, 0444);
2297+MODULE_PARM_DESC(crypto_all_qblocked, "Are all crypto queues blocked");
2298+
2299+int crypto_all_kqblocked = 0; /* protect with Q_LOCK */
2300+module_param(crypto_all_kqblocked, int, 0444);
2301+MODULE_PARM_DESC(crypto_all_kqblocked, "Are all asym crypto queues blocked");
2302+
2303+#define CRYPTO_Q_LOCK() \
2304+ ({ \
2305+ spin_lock_irqsave(&crypto_q_lock, q_flags); \
2306+ dprintk("%s,%d: Q_LOCK()\n", __FILE__, __LINE__); \
2307+ })
2308+#define CRYPTO_Q_UNLOCK() \
2309+ ({ \
2310+ dprintk("%s,%d: Q_UNLOCK()\n", __FILE__, __LINE__); \
2311+ spin_unlock_irqrestore(&crypto_q_lock, q_flags); \
2312+ })
2313+
2314+/*
2315+ * There are two queues for processing completed crypto requests; one
2316+ * for the symmetric and one for the asymmetric ops. We only need one
2317+ * but have two to avoid type futzing (cryptop vs. cryptkop). A single
2318+ * mutex is used to lock access to both queues. Note that this lock
2319+ * must be separate from the lock on request queues to insure driver
2320+ * callbacks don't generate lock order reversals.
2321+ */
2322+static LIST_HEAD(crp_ret_q); /* callback queues */
2323+static LIST_HEAD(crp_ret_kq);
2324+
2325+static spinlock_t crypto_ret_q_lock;
2326+#define CRYPTO_RETQ_LOCK() \
2327+ ({ \
2328+ spin_lock_irqsave(&crypto_ret_q_lock, r_flags); \
2329+ dprintk("%s,%d: RETQ_LOCK\n", __FILE__, __LINE__); \
2330+ })
2331+#define CRYPTO_RETQ_UNLOCK() \
2332+ ({ \
2333+ dprintk("%s,%d: RETQ_UNLOCK\n", __FILE__, __LINE__); \
2334+ spin_unlock_irqrestore(&crypto_ret_q_lock, r_flags); \
2335+ })
2336+#define CRYPTO_RETQ_EMPTY() (list_empty(&crp_ret_q) && list_empty(&crp_ret_kq))
2337+
2338+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
2339+static kmem_cache_t *cryptop_zone;
2340+static kmem_cache_t *cryptodesc_zone;
2341+#else
2342+static struct kmem_cache *cryptop_zone;
2343+static struct kmem_cache *cryptodesc_zone;
2344+#endif
2345+
2346+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
2347+#include <linux/sched.h>
2348+#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
2349+#endif
2350+
2351+#define debug crypto_debug
2352+int crypto_debug = 0;
2353+module_param(crypto_debug, int, 0644);
2354+MODULE_PARM_DESC(crypto_debug, "Enable debug");
2355+EXPORT_SYMBOL(crypto_debug);
2356+
2357+/*
2358+ * Maximum number of outstanding crypto requests before we start
2359+ * failing requests. We need this to prevent DOS when too many
2360+ * requests are arriving for us to keep up. Otherwise we will
2361+ * run the system out of memory. Since crypto is slow, we are
2362+ * usually the bottleneck that needs to say, enough is enough.
2363+ *
2364+ * We cannot print errors when this condition occurs, we are already too
2365+ * slow, printing anything will just kill us
2366+ */
2367+
2368+static int crypto_q_cnt = 0;
2369+module_param(crypto_q_cnt, int, 0444);
2370+MODULE_PARM_DESC(crypto_q_cnt,
2371+ "Current number of outstanding crypto requests");
2372+
2373+static int crypto_q_max = 1000;
2374+module_param(crypto_q_max, int, 0644);
2375+MODULE_PARM_DESC(crypto_q_max,
2376+ "Maximum number of outstanding crypto requests");
2377+
2378+#define bootverbose crypto_verbose
2379+static int crypto_verbose = 0;
2380+module_param(crypto_verbose, int, 0644);
2381+MODULE_PARM_DESC(crypto_verbose,
2382+ "Enable verbose crypto startup");
2383+
2384+int crypto_usercrypto = 1; /* userland may do crypto reqs */
2385+module_param(crypto_usercrypto, int, 0644);
2386+MODULE_PARM_DESC(crypto_usercrypto,
2387+ "Enable/disable user-mode access to crypto support");
2388+
2389+int crypto_userasymcrypto = 1; /* userland may do asym crypto reqs */
2390+module_param(crypto_userasymcrypto, int, 0644);
2391+MODULE_PARM_DESC(crypto_userasymcrypto,
2392+ "Enable/disable user-mode access to asymmetric crypto support");
2393+
2394+int crypto_devallowsoft = 0; /* only use hardware crypto */
2395+module_param(crypto_devallowsoft, int, 0644);
2396+MODULE_PARM_DESC(crypto_devallowsoft,
2397+ "Enable/disable use of software crypto support");
2398+
2399+/*
2400+ * This parameter controls the maximum number of crypto operations to
2401+ * do consecutively in the crypto kernel thread before scheduling to allow
2402+ * other processes to run. Without it, it is possible to get into a
2403+ * situation where the crypto thread never allows any other processes to run.
2404+ * Default to 1000 which should be less than one second.
2405+ */
2406+static int crypto_max_loopcount = 1000;
2407+module_param(crypto_max_loopcount, int, 0644);
2408+MODULE_PARM_DESC(crypto_max_loopcount,
2409+ "Maximum number of crypto ops to do before yielding to other processes");
2410+
2411+static pid_t cryptoproc = (pid_t) -1;
2412+static struct completion cryptoproc_exited;
2413+static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait);
2414+static pid_t cryptoretproc = (pid_t) -1;
2415+static struct completion cryptoretproc_exited;
2416+static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait);
2417+
2418+static int crypto_proc(void *arg);
2419+static int crypto_ret_proc(void *arg);
2420+static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);
2421+static int crypto_kinvoke(struct cryptkop *krp, int flags);
2422+static void crypto_exit(void);
2423+static int crypto_init(void);
2424+
2425+static struct cryptostats cryptostats;
2426+
2427+static struct cryptocap *
2428+crypto_checkdriver(u_int32_t hid)
2429+{
2430+ if (crypto_drivers == NULL)
2431+ return NULL;
2432+ return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]);
2433+}
2434+
2435+/*
2436+ * Compare a driver's list of supported algorithms against another
2437+ * list; return non-zero if all algorithms are supported.
2438+ */
2439+static int
2440+driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri)
2441+{
2442+ const struct cryptoini *cr;
2443+
2444+ /* See if all the algorithms are supported. */
2445+ for (cr = cri; cr; cr = cr->cri_next)
2446+ if (cap->cc_alg[cr->cri_alg] == 0)
2447+ return 0;
2448+ return 1;
2449+}
2450+
2451+/*
2452+ * Select a driver for a new session that supports the specified
2453+ * algorithms and, optionally, is constrained according to the flags.
2454+ * The algorithm we use here is pretty stupid; just use the
2455+ * first driver that supports all the algorithms we need. If there
2456+ * are multiple drivers we choose the driver with the fewest active
2457+ * sessions. We prefer hardware-backed drivers to software ones.
2458+ *
2459+ * XXX We need more smarts here (in real life too, but that's
2460+ * XXX another story altogether).
2461+ */
2462+static struct cryptocap *
2463+crypto_select_driver(const struct cryptoini *cri, int flags)
2464+{
2465+ struct cryptocap *cap, *best;
2466+ int match, hid;
2467+
2468+ CRYPTO_DRIVER_ASSERT();
2469+
2470+ /*
2471+ * Look first for hardware crypto devices if permitted.
2472+ */
2473+ if (flags & CRYPTOCAP_F_HARDWARE)
2474+ match = CRYPTOCAP_F_HARDWARE;
2475+ else
2476+ match = CRYPTOCAP_F_SOFTWARE;
2477+ best = NULL;
2478+again:
2479+ for (hid = 0; hid < crypto_drivers_num; hid++) {
2480+ cap = &crypto_drivers[hid];
2481+ /*
2482+ * If it's not initialized, is in the process of
2483+ * going away, or is not appropriate (hardware
2484+ * or software based on match), then skip.
2485+ */
2486+ if (cap->cc_dev == NULL ||
2487+ (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
2488+ (cap->cc_flags & match) == 0)
2489+ continue;
2490+
2491+ /* verify all the algorithms are supported. */
2492+ if (driver_suitable(cap, cri)) {
2493+ if (best == NULL ||
2494+ cap->cc_sessions < best->cc_sessions)
2495+ best = cap;
2496+ }
2497+ }
2498+ if (best != NULL)
2499+ return best;
2500+ if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
2501+ /* sort of an Algol 68-style for loop */
2502+ match = CRYPTOCAP_F_SOFTWARE;
2503+ goto again;
2504+ }
2505+ return best;
2506+}
2507+
2508+/*
2509+ * Create a new session. The crid argument specifies a crypto
2510+ * driver to use or constraints on a driver to select (hardware
2511+ * only, software only, either). Whatever driver is selected
2512+ * must be capable of the requested crypto algorithms.
2513+ */
2514+int
2515+crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid)
2516+{
2517+ struct cryptocap *cap;
2518+ u_int32_t hid, lid;
2519+ int err;
2520+ unsigned long d_flags;
2521+
2522+ CRYPTO_DRIVER_LOCK();
2523+ if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
2524+ /*
2525+ * Use specified driver; verify it is capable.
2526+ */
2527+ cap = crypto_checkdriver(crid);
2528+ if (cap != NULL && !driver_suitable(cap, cri))
2529+ cap = NULL;
2530+ } else {
2531+ /*
2532+ * No requested driver; select based on crid flags.
2533+ */
2534+ cap = crypto_select_driver(cri, crid);
2535+ /*
2536+ * if NULL then can't do everything in one session.
2537+ * XXX Fix this. We need to inject a "virtual" session
2538+ * XXX layer right about here.
2539+ */
2540+ }
2541+ if (cap != NULL) {
2542+ /* Call the driver initialization routine. */
2543+ hid = cap - crypto_drivers;
2544+ lid = hid; /* Pass the driver ID. */
2545+ cap->cc_sessions++;
2546+ CRYPTO_DRIVER_UNLOCK();
2547+ err = CRYPTODEV_NEWSESSION(cap->cc_dev, &lid, cri);
2548+ CRYPTO_DRIVER_LOCK();
2549+ if (err == 0) {
2550+ (*sid) = (cap->cc_flags & 0xff000000)
2551+ | (hid & 0x00ffffff);
2552+ (*sid) <<= 32;
2553+ (*sid) |= (lid & 0xffffffff);
2554+ } else
2555+ cap->cc_sessions--;
2556+ } else
2557+ err = EINVAL;
2558+ CRYPTO_DRIVER_UNLOCK();
2559+ return err;
2560+}
2561+
2562+static void
2563+crypto_remove(struct cryptocap *cap)
2564+{
2565+ CRYPTO_DRIVER_ASSERT();
2566+ if (cap->cc_sessions == 0 && cap->cc_koperations == 0)
2567+ bzero(cap, sizeof(*cap));
2568+}
2569+
2570+/*
2571+ * Delete an existing session (or a reserved session on an unregistered
2572+ * driver).
2573+ */
2574+int
2575+crypto_freesession(u_int64_t sid)
2576+{
2577+ struct cryptocap *cap;
2578+ u_int32_t hid;
2579+ int err = 0;
2580+ unsigned long d_flags;
2581+
2582+ dprintk("%s()\n", __FUNCTION__);
2583+ CRYPTO_DRIVER_LOCK();
2584+
2585+ if (crypto_drivers == NULL) {
2586+ err = EINVAL;
2587+ goto done;
2588+ }
2589+
2590+ /* Determine two IDs. */
2591+ hid = CRYPTO_SESID2HID(sid);
2592+
2593+ if (hid >= crypto_drivers_num) {
2594+ dprintk("%s - INVALID DRIVER NUM %d\n", __FUNCTION__, hid);
2595+ err = ENOENT;
2596+ goto done;
2597+ }
2598+ cap = &crypto_drivers[hid];
2599+
2600+ if (cap->cc_dev) {
2601+ CRYPTO_DRIVER_UNLOCK();
2602+ /* Call the driver cleanup routine, if available, unlocked. */
2603+ err = CRYPTODEV_FREESESSION(cap->cc_dev, sid);
2604+ CRYPTO_DRIVER_LOCK();
2605+ }
2606+
2607+ if (cap->cc_sessions)
2608+ cap->cc_sessions--;
2609+
2610+ if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
2611+ crypto_remove(cap);
2612+
2613+done:
2614+ CRYPTO_DRIVER_UNLOCK();
2615+ return err;
2616+}
2617+
2618+/*
2619+ * Return an unused driver id. Used by drivers prior to registering
2620+ * support for the algorithms they handle.
2621+ */
2622+int32_t
2623+crypto_get_driverid(device_t dev, int flags)
2624+{
2625+ struct cryptocap *newdrv;
2626+ int i;
2627+ unsigned long d_flags;
2628+
2629+ if ((flags & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
2630+ printf("%s: no flags specified when registering driver\n",
2631+ device_get_nameunit(dev));
2632+ return -1;
2633+ }
2634+
2635+ CRYPTO_DRIVER_LOCK();
2636+
2637+ for (i = 0; i < crypto_drivers_num; i++) {
2638+ if (crypto_drivers[i].cc_dev == NULL &&
2639+ (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0) {
2640+ break;
2641+ }
2642+ }
2643+
2644+ /* Out of entries, allocate some more. */
2645+ if (i == crypto_drivers_num) {
2646+ /* Be careful about wrap-around. */
2647+ if (2 * crypto_drivers_num <= crypto_drivers_num) {
2648+ CRYPTO_DRIVER_UNLOCK();
2649+ printk("crypto: driver count wraparound!\n");
2650+ return -1;
2651+ }
2652+
2653+ newdrv = kmalloc(2 * crypto_drivers_num * sizeof(struct cryptocap),
2654+ GFP_KERNEL);
2655+ if (newdrv == NULL) {
2656+ CRYPTO_DRIVER_UNLOCK();
2657+ printk("crypto: no space to expand driver table!\n");
2658+ return -1;
2659+ }
2660+
2661+ memcpy(newdrv, crypto_drivers,
2662+ crypto_drivers_num * sizeof(struct cryptocap));
2663+ memset(&newdrv[crypto_drivers_num], 0,
2664+ crypto_drivers_num * sizeof(struct cryptocap));
2665+
2666+ crypto_drivers_num *= 2;
2667+
2668+ kfree(crypto_drivers);
2669+ crypto_drivers = newdrv;
2670+ }
2671+
2672+ /* NB: state is zero'd on free */
2673+ crypto_drivers[i].cc_sessions = 1; /* Mark */
2674+ crypto_drivers[i].cc_dev = dev;
2675+ crypto_drivers[i].cc_flags = flags;
2676+ if (bootverbose)
2677+ printf("crypto: assign %s driver id %u, flags %u\n",
2678+ device_get_nameunit(dev), i, flags);
2679+
2680+ CRYPTO_DRIVER_UNLOCK();
2681+
2682+ return i;
2683+}
2684+
2685+/*
2686+ * Lookup a driver by name. We match against the full device
2687+ * name and unit, and against just the name. The latter gives
2688+ * us a simple widlcarding by device name. On success return the
2689+ * driver/hardware identifier; otherwise return -1.
2690+ */
2691+int
2692+crypto_find_driver(const char *match)
2693+{
2694+ int i, len = strlen(match);
2695+ unsigned long d_flags;
2696+
2697+ CRYPTO_DRIVER_LOCK();
2698+ for (i = 0; i < crypto_drivers_num; i++) {
2699+ device_t dev = crypto_drivers[i].cc_dev;
2700+ if (dev == NULL ||
2701+ (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP))
2702+ continue;
2703+ if (strncmp(match, device_get_nameunit(dev), len) == 0 ||
2704+ strncmp(match, device_get_name(dev), len) == 0)
2705+ break;
2706+ }
2707+ CRYPTO_DRIVER_UNLOCK();
2708+ return i < crypto_drivers_num ? i : -1;
2709+}
2710+
2711+/*
2712+ * Return the device_t for the specified driver or NULL
2713+ * if the driver identifier is invalid.
2714+ */
2715+device_t
2716+crypto_find_device_byhid(int hid)
2717+{
2718+ struct cryptocap *cap = crypto_checkdriver(hid);
2719+ return cap != NULL ? cap->cc_dev : NULL;
2720+}
2721+
2722+/*
2723+ * Return the device/driver capabilities.
2724+ */
2725+int
2726+crypto_getcaps(int hid)
2727+{
2728+ struct cryptocap *cap = crypto_checkdriver(hid);
2729+ return cap != NULL ? cap->cc_flags : 0;
2730+}
2731+
2732+/*
2733+ * Register support for a key-related algorithm. This routine
2734+ * is called once for each algorithm supported a driver.
2735+ */
2736+int
2737+crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags)
2738+{
2739+ struct cryptocap *cap;
2740+ int err;
2741+ unsigned long d_flags;
2742+
2743+ dprintk("%s()\n", __FUNCTION__);
2744+ CRYPTO_DRIVER_LOCK();
2745+
2746+ cap = crypto_checkdriver(driverid);
2747+ if (cap != NULL &&
2748+ (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {
2749+ /*
2750+ * XXX Do some performance testing to determine placing.
2751+ * XXX We probably need an auxiliary data structure that
2752+ * XXX describes relative performances.
2753+ */
2754+
2755+ cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
2756+ if (bootverbose)
2757+ printf("crypto: %s registers key alg %u flags %u\n"
2758+ , device_get_nameunit(cap->cc_dev)
2759+ , kalg
2760+ , flags
2761+ );
2762+ err = 0;
2763+ } else
2764+ err = EINVAL;
2765+
2766+ CRYPTO_DRIVER_UNLOCK();
2767+ return err;
2768+}
2769+
2770+/*
2771+ * Register support for a non-key-related algorithm. This routine
2772+ * is called once for each such algorithm supported by a driver.
2773+ */
2774+int
2775+crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
2776+ u_int32_t flags)
2777+{
2778+ struct cryptocap *cap;
2779+ int err;
2780+ unsigned long d_flags;
2781+
2782+ dprintk("%s(id=0x%x, alg=%d, maxoplen=%d, flags=0x%x)\n", __FUNCTION__,
2783+ driverid, alg, maxoplen, flags);
2784+
2785+ CRYPTO_DRIVER_LOCK();
2786+
2787+ cap = crypto_checkdriver(driverid);
2788+ /* NB: algorithms are in the range [1..max] */
2789+ if (cap != NULL &&
2790+ (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) {
2791+ /*
2792+ * XXX Do some performance testing to determine placing.
2793+ * XXX We probably need an auxiliary data structure that
2794+ * XXX describes relative performances.
2795+ */
2796+
2797+ cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
2798+ cap->cc_max_op_len[alg] = maxoplen;
2799+ if (bootverbose)
2800+ printf("crypto: %s registers alg %u flags %u maxoplen %u\n"
2801+ , device_get_nameunit(cap->cc_dev)
2802+ , alg
2803+ , flags
2804+ , maxoplen
2805+ );
2806+ cap->cc_sessions = 0; /* Unmark */
2807+ err = 0;
2808+ } else
2809+ err = EINVAL;
2810+
2811+ CRYPTO_DRIVER_UNLOCK();
2812+ return err;
2813+}
2814+
2815+static void
2816+driver_finis(struct cryptocap *cap)
2817+{
2818+ u_int32_t ses, kops;
2819+
2820+ CRYPTO_DRIVER_ASSERT();
2821+
2822+ ses = cap->cc_sessions;
2823+ kops = cap->cc_koperations;
2824+ bzero(cap, sizeof(*cap));
2825+ if (ses != 0 || kops != 0) {
2826+ /*
2827+ * If there are pending sessions,
2828+ * just mark as invalid.
2829+ */
2830+ cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
2831+ cap->cc_sessions = ses;
2832+ cap->cc_koperations = kops;
2833+ }
2834+}
2835+
2836+/*
2837+ * Unregister a crypto driver. If there are pending sessions using it,
2838+ * leave enough information around so that subsequent calls using those
2839+ * sessions will correctly detect the driver has been unregistered and
2840+ * reroute requests.
2841+ */
2842+int
2843+crypto_unregister(u_int32_t driverid, int alg)
2844+{
2845+ struct cryptocap *cap;
2846+ int i, err;
2847+ unsigned long d_flags;
2848+
2849+ dprintk("%s()\n", __FUNCTION__);
2850+ CRYPTO_DRIVER_LOCK();
2851+
2852+ cap = crypto_checkdriver(driverid);
2853+ if (cap != NULL &&
2854+ (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) &&
2855+ cap->cc_alg[alg] != 0) {
2856+ cap->cc_alg[alg] = 0;
2857+ cap->cc_max_op_len[alg] = 0;
2858+
2859+ /* Was this the last algorithm ? */
2860+ for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
2861+ if (cap->cc_alg[i] != 0)
2862+ break;
2863+
2864+ if (i == CRYPTO_ALGORITHM_MAX + 1)
2865+ driver_finis(cap);
2866+ err = 0;
2867+ } else
2868+ err = EINVAL;
2869+ CRYPTO_DRIVER_UNLOCK();
2870+ return err;
2871+}
2872+
2873+/*
2874+ * Unregister all algorithms associated with a crypto driver.
2875+ * If there are pending sessions using it, leave enough information
2876+ * around so that subsequent calls using those sessions will
2877+ * correctly detect the driver has been unregistered and reroute
2878+ * requests.
2879+ */
2880+int
2881+crypto_unregister_all(u_int32_t driverid)
2882+{
2883+ struct cryptocap *cap;
2884+ int err;
2885+ unsigned long d_flags;
2886+
2887+ dprintk("%s()\n", __FUNCTION__);
2888+ CRYPTO_DRIVER_LOCK();
2889+ cap = crypto_checkdriver(driverid);
2890+ if (cap != NULL) {
2891+ driver_finis(cap);
2892+ err = 0;
2893+ } else
2894+ err = EINVAL;
2895+ CRYPTO_DRIVER_UNLOCK();
2896+
2897+ return err;
2898+}
2899+
2900+/*
2901+ * Clear blockage on a driver. The what parameter indicates whether
2902+ * the driver is now ready for cryptop's and/or cryptokop's.
2903+ */
2904+int
2905+crypto_unblock(u_int32_t driverid, int what)
2906+{
2907+ struct cryptocap *cap;
2908+ int err;
2909+ unsigned long q_flags;
2910+
2911+ CRYPTO_Q_LOCK();
2912+ cap = crypto_checkdriver(driverid);
2913+ if (cap != NULL) {
2914+ if (what & CRYPTO_SYMQ) {
2915+ cap->cc_qblocked = 0;
2916+ cap->cc_unqblocked = 0;
2917+ crypto_all_qblocked = 0;
2918+ }
2919+ if (what & CRYPTO_ASYMQ) {
2920+ cap->cc_kqblocked = 0;
2921+ cap->cc_unkqblocked = 0;
2922+ crypto_all_kqblocked = 0;
2923+ }
2924+ if (crp_sleep)
2925+ wake_up_interruptible(&cryptoproc_wait);
2926+ err = 0;
2927+ } else
2928+ err = EINVAL;
2929+ CRYPTO_Q_UNLOCK(); //DAVIDM should this be a driver lock
2930+
2931+ return err;
2932+}
2933+
2934+/*
2935+ * Add a crypto request to a queue, to be processed by the kernel thread.
2936+ */
2937+int
2938+crypto_dispatch(struct cryptop *crp)
2939+{
2940+ struct cryptocap *cap;
2941+ int result = -1;
2942+ unsigned long q_flags;
2943+
2944+ dprintk("%s()\n", __FUNCTION__);
2945+
2946+ cryptostats.cs_ops++;
2947+
2948+ CRYPTO_Q_LOCK();
2949+ if (crypto_q_cnt >= crypto_q_max) {
2950+ CRYPTO_Q_UNLOCK();
2951+ cryptostats.cs_drops++;
2952+ return ENOMEM;
2953+ }
2954+ crypto_q_cnt++;
2955+
2956+ /* make sure we are starting a fresh run on this crp. */
2957+ crp->crp_flags &= ~CRYPTO_F_DONE;
2958+ crp->crp_etype = 0;
2959+
2960+ /*
2961+ * Caller marked the request to be processed immediately; dispatch
2962+ * it directly to the driver unless the driver is currently blocked.
2963+ */
2964+ if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
2965+ int hid = CRYPTO_SESID2HID(crp->crp_sid);
2966+ cap = crypto_checkdriver(hid);
2967+ /* Driver cannot disappear when there is an active session. */
2968+ KASSERT(cap != NULL, ("%s: Driver disappeared.", __func__));
2969+ if (!cap->cc_qblocked) {
2970+ crypto_all_qblocked = 0;
2971+ crypto_drivers[hid].cc_unqblocked = 1;
2972+ CRYPTO_Q_UNLOCK();
2973+ result = crypto_invoke(cap, crp, 0);
2974+ CRYPTO_Q_LOCK();
2975+ if (result == ERESTART)
2976+ if (crypto_drivers[hid].cc_unqblocked)
2977+ crypto_drivers[hid].cc_qblocked = 1;
2978+ crypto_drivers[hid].cc_unqblocked = 0;
2979+ }
2980+ }
2981+ if (result == ERESTART) {
2982+ /*
2983+ * The driver ran out of resources, mark the
2984+ * driver ``blocked'' for cryptop's and put
2985+ * the request back in the queue. It would
2986+ * best to put the request back where we got
2987+ * it but that's hard so for now we put it
2988+ * at the front. This should be ok; putting
2989+ * it at the end does not work.
2990+ */
2991+ list_add(&crp->crp_next, &crp_q);
2992+ cryptostats.cs_blocks++;
2993+ result = 0;
2994+ } else if (result == -1) {
2995+ TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
2996+ result = 0;
2997+ }
2998+ if (crp_sleep)
2999+ wake_up_interruptible(&cryptoproc_wait);
3000+ CRYPTO_Q_UNLOCK();
3001+ return result;
3002+}
3003+
3004+/*
3005+ * Add an asymetric crypto request to a queue,
3006+ * to be processed by the kernel thread.
3007+ */
3008+int
3009+crypto_kdispatch(struct cryptkop *krp)
3010+{
3011+ int error;
3012+ unsigned long q_flags;
3013+
3014+ cryptostats.cs_kops++;
3015+
3016+ error = crypto_kinvoke(krp, krp->krp_crid);
3017+ if (error == ERESTART) {
3018+ CRYPTO_Q_LOCK();
3019+ TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
3020+ if (crp_sleep)
3021+ wake_up_interruptible(&cryptoproc_wait);
3022+ CRYPTO_Q_UNLOCK();
3023+ error = 0;
3024+ }
3025+ return error;
3026+}
3027+
3028+/*
3029+ * Verify a driver is suitable for the specified operation.
3030+ */
3031+static __inline int
3032+kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp)
3033+{
3034+ return (cap->cc_kalg[krp->krp_op] & CRYPTO_ALG_FLAG_SUPPORTED) != 0;
3035+}
3036+
3037+/*
3038+ * Select a driver for an asym operation. The driver must
3039+ * support the necessary algorithm. The caller can constrain
3040+ * which device is selected with the flags parameter. The
3041+ * algorithm we use here is pretty stupid; just use the first
3042+ * driver that supports the algorithms we need. If there are
3043+ * multiple suitable drivers we choose the driver with the
3044+ * fewest active operations. We prefer hardware-backed
3045+ * drivers to software ones when either may be used.
3046+ */
3047+static struct cryptocap *
3048+crypto_select_kdriver(const struct cryptkop *krp, int flags)
3049+{
3050+ struct cryptocap *cap, *best, *blocked;
3051+ int match, hid;
3052+
3053+ CRYPTO_DRIVER_ASSERT();
3054+
3055+ /*
3056+ * Look first for hardware crypto devices if permitted.
3057+ */
3058+ if (flags & CRYPTOCAP_F_HARDWARE)
3059+ match = CRYPTOCAP_F_HARDWARE;
3060+ else
3061+ match = CRYPTOCAP_F_SOFTWARE;
3062+ best = NULL;
3063+ blocked = NULL;
3064+again:
3065+ for (hid = 0; hid < crypto_drivers_num; hid++) {
3066+ cap = &crypto_drivers[hid];
3067+ /*
3068+ * If it's not initialized, is in the process of
3069+ * going away, or is not appropriate (hardware
3070+ * or software based on match), then skip.
3071+ */
3072+ if (cap->cc_dev == NULL ||
3073+ (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
3074+ (cap->cc_flags & match) == 0)
3075+ continue;
3076+
3077+ /* verify all the algorithms are supported. */
3078+ if (kdriver_suitable(cap, krp)) {
3079+ if (best == NULL ||
3080+ cap->cc_koperations < best->cc_koperations)
3081+ best = cap;
3082+ }
3083+ }
3084+ if (best != NULL)
3085+ return best;
3086+ if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
3087+ /* sort of an Algol 68-style for loop */
3088+ match = CRYPTOCAP_F_SOFTWARE;
3089+ goto again;
3090+ }
3091+ return best;
3092+}
3093+
3094+/*
3095+ * Dispatch an assymetric crypto request.
3096+ */
3097+static int
3098+crypto_kinvoke(struct cryptkop *krp, int crid)
3099+{
3100+ struct cryptocap *cap = NULL;
3101+ int error;
3102+ unsigned long d_flags;
3103+
3104+ KASSERT(krp != NULL, ("%s: krp == NULL", __func__));
3105+ KASSERT(krp->krp_callback != NULL,
3106+ ("%s: krp->crp_callback == NULL", __func__));
3107+
3108+ CRYPTO_DRIVER_LOCK();
3109+ if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
3110+ cap = crypto_checkdriver(crid);
3111+ if (cap != NULL) {
3112+ /*
3113+ * Driver present, it must support the necessary
3114+ * algorithm and, if s/w drivers are excluded,
3115+ * it must be registered as hardware-backed.
3116+ */
3117+ if (!kdriver_suitable(cap, krp) ||
3118+ (!crypto_devallowsoft &&
3119+ (cap->cc_flags & CRYPTOCAP_F_HARDWARE) == 0))
3120+ cap = NULL;
3121+ }
3122+ } else {
3123+ /*
3124+ * No requested driver; select based on crid flags.
3125+ */
3126+ if (!crypto_devallowsoft) /* NB: disallow s/w drivers */
3127+ crid &= ~CRYPTOCAP_F_SOFTWARE;
3128+ cap = crypto_select_kdriver(krp, crid);
3129+ }
3130+ if (cap != NULL && !cap->cc_kqblocked) {
3131+ krp->krp_hid = cap - crypto_drivers;
3132+ cap->cc_koperations++;
3133+ CRYPTO_DRIVER_UNLOCK();
3134+ error = CRYPTODEV_KPROCESS(cap->cc_dev, krp, 0);
3135+ CRYPTO_DRIVER_LOCK();
3136+ if (error == ERESTART) {
3137+ cap->cc_koperations--;
3138+ CRYPTO_DRIVER_UNLOCK();
3139+ return (error);
3140+ }
3141+ /* return the actual device used */
3142+ krp->krp_crid = krp->krp_hid;
3143+ } else {
3144+ /*
3145+ * NB: cap is !NULL if device is blocked; in
3146+ * that case return ERESTART so the operation
3147+ * is resubmitted if possible.
3148+ */
3149+ error = (cap == NULL) ? ENODEV : ERESTART;
3150+ }
3151+ CRYPTO_DRIVER_UNLOCK();
3152+
3153+ if (error) {
3154+ krp->krp_status = error;
3155+ crypto_kdone(krp);
3156+ }
3157+ return 0;
3158+}
3159+
3160+
3161+/*
3162+ * Dispatch a crypto request to the appropriate crypto devices.
3163+ */
3164+static int
3165+crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint)
3166+{
3167+ KASSERT(crp != NULL, ("%s: crp == NULL", __func__));
3168+ KASSERT(crp->crp_callback != NULL,
3169+ ("%s: crp->crp_callback == NULL", __func__));
3170+ KASSERT(crp->crp_desc != NULL, ("%s: crp->crp_desc == NULL", __func__));
3171+
3172+ dprintk("%s()\n", __FUNCTION__);
3173+
3174+#ifdef CRYPTO_TIMING
3175+ if (crypto_timing)
3176+ crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);
3177+#endif
3178+ if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) {
3179+ struct cryptodesc *crd;
3180+ u_int64_t nid;
3181+
3182+ /*
3183+ * Driver has unregistered; migrate the session and return
3184+ * an error to the caller so they'll resubmit the op.
3185+ *
3186+ * XXX: What if there are more already queued requests for this
3187+ * session?
3188+ */
3189+ crypto_freesession(crp->crp_sid);
3190+
3191+ for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
3192+ crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
3193+
3194+ /* XXX propagate flags from initial session? */
3195+ if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI),
3196+ CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE) == 0)
3197+ crp->crp_sid = nid;
3198+
3199+ crp->crp_etype = EAGAIN;
3200+ crypto_done(crp);
3201+ return 0;
3202+ } else {
3203+ /*
3204+ * Invoke the driver to process the request.
3205+ */
3206+ return CRYPTODEV_PROCESS(cap->cc_dev, crp, hint);
3207+ }
3208+}
3209+
3210+/*
3211+ * Release a set of crypto descriptors.
3212+ */
3213+void
3214+crypto_freereq(struct cryptop *crp)
3215+{
3216+ struct cryptodesc *crd;
3217+
3218+ if (crp == NULL)
3219+ return;
3220+
3221+#ifdef DIAGNOSTIC
3222+ {
3223+ struct cryptop *crp2;
3224+ unsigned long q_flags;
3225+
3226+ CRYPTO_Q_LOCK();
3227+ TAILQ_FOREACH(crp2, &crp_q, crp_next) {
3228+ KASSERT(crp2 != crp,
3229+ ("Freeing cryptop from the crypto queue (%p).",
3230+ crp));
3231+ }
3232+ CRYPTO_Q_UNLOCK();
3233+ CRYPTO_RETQ_LOCK();
3234+ TAILQ_FOREACH(crp2, &crp_ret_q, crp_next) {
3235+ KASSERT(crp2 != crp,
3236+ ("Freeing cryptop from the return queue (%p).",
3237+ crp));
3238+ }
3239+ CRYPTO_RETQ_UNLOCK();
3240+ }
3241+#endif
3242+
3243+ while ((crd = crp->crp_desc) != NULL) {
3244+ crp->crp_desc = crd->crd_next;
3245+ kmem_cache_free(cryptodesc_zone, crd);
3246+ }
3247+ kmem_cache_free(cryptop_zone, crp);
3248+}
3249+
3250+/*
3251+ * Acquire a set of crypto descriptors.
3252+ */
3253+struct cryptop *
3254+crypto_getreq(int num)
3255+{
3256+ struct cryptodesc *crd;
3257+ struct cryptop *crp;
3258+
3259+ crp = kmem_cache_alloc(cryptop_zone, SLAB_ATOMIC);
3260+ if (crp != NULL) {
3261+ memset(crp, 0, sizeof(*crp));
3262+ INIT_LIST_HEAD(&crp->crp_next);
3263+ init_waitqueue_head(&crp->crp_waitq);
3264+ while (num--) {
3265+ crd = kmem_cache_alloc(cryptodesc_zone, SLAB_ATOMIC);
3266+ if (crd == NULL) {
3267+ crypto_freereq(crp);
3268+ return NULL;
3269+ }
3270+ memset(crd, 0, sizeof(*crd));
3271+ crd->crd_next = crp->crp_desc;
3272+ crp->crp_desc = crd;
3273+ }
3274+ }
3275+ return crp;
3276+}
3277+
3278+/*
3279+ * Invoke the callback on behalf of the driver.
3280+ */
3281+void
3282+crypto_done(struct cryptop *crp)
3283+{
3284+ unsigned long q_flags;
3285+
3286+ dprintk("%s()\n", __FUNCTION__);
3287+ if ((crp->crp_flags & CRYPTO_F_DONE) == 0) {
3288+ crp->crp_flags |= CRYPTO_F_DONE;
3289+ CRYPTO_Q_LOCK();
3290+ crypto_q_cnt--;
3291+ CRYPTO_Q_UNLOCK();
3292+ } else
3293+ printk("crypto: crypto_done op already done, flags 0x%x",
3294+ crp->crp_flags);
3295+ if (crp->crp_etype != 0)
3296+ cryptostats.cs_errs++;
3297+ /*
3298+ * CBIMM means unconditionally do the callback immediately;
3299+ * CBIFSYNC means do the callback immediately only if the
3300+ * operation was done synchronously. Both are used to avoid
3301+ * doing extraneous context switches; the latter is mostly
3302+ * used with the software crypto driver.
3303+ */
3304+ if ((crp->crp_flags & CRYPTO_F_CBIMM) ||
3305+ ((crp->crp_flags & CRYPTO_F_CBIFSYNC) &&
3306+ (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC))) {
3307+ /*
3308+ * Do the callback directly. This is ok when the
3309+ * callback routine does very little (e.g. the
3310+ * /dev/crypto callback method just does a wakeup).
3311+ */
3312+ crp->crp_callback(crp);
3313+ } else {
3314+ unsigned long r_flags;
3315+ /*
3316+ * Normal case; queue the callback for the thread.
3317+ */
3318+ CRYPTO_RETQ_LOCK();
3319+ if (CRYPTO_RETQ_EMPTY())
3320+ wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
3321+ TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
3322+ CRYPTO_RETQ_UNLOCK();
3323+ }
3324+}
3325+
3326+/*
3327+ * Invoke the callback on behalf of the driver.
3328+ */
3329+void
3330+crypto_kdone(struct cryptkop *krp)
3331+{
3332+ struct cryptocap *cap;
3333+ unsigned long d_flags;
3334+
3335+ if ((krp->krp_flags & CRYPTO_KF_DONE) != 0)
3336+ printk("crypto: crypto_kdone op already done, flags 0x%x",
3337+ krp->krp_flags);
3338+ krp->krp_flags |= CRYPTO_KF_DONE;
3339+ if (krp->krp_status != 0)
3340+ cryptostats.cs_kerrs++;
3341+
3342+ CRYPTO_DRIVER_LOCK();
3343+ /* XXX: What if driver is loaded in the meantime? */
3344+ if (krp->krp_hid < crypto_drivers_num) {
3345+ cap = &crypto_drivers[krp->krp_hid];
3346+ cap->cc_koperations--;
3347+ KASSERT(cap->cc_koperations >= 0, ("cc_koperations < 0"));
3348+ if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
3349+ crypto_remove(cap);
3350+ }
3351+ CRYPTO_DRIVER_UNLOCK();
3352+
3353+ /*
3354+ * CBIMM means unconditionally do the callback immediately;
3355+ * This is used to avoid doing extraneous context switches
3356+ */
3357+ if ((krp->krp_flags & CRYPTO_KF_CBIMM)) {
3358+ /*
3359+ * Do the callback directly. This is ok when the
3360+ * callback routine does very little (e.g. the
3361+ * /dev/crypto callback method just does a wakeup).
3362+ */
3363+ krp->krp_callback(krp);
3364+ } else {
3365+ unsigned long r_flags;
3366+ /*
3367+ * Normal case; queue the callback for the thread.
3368+ */
3369+ CRYPTO_RETQ_LOCK();
3370+ if (CRYPTO_RETQ_EMPTY())
3371+ wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
3372+ TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
3373+ CRYPTO_RETQ_UNLOCK();
3374+ }
3375+}
3376+
3377+int
3378+crypto_getfeat(int *featp)
3379+{
3380+ int hid, kalg, feat = 0;
3381+ unsigned long d_flags;
3382+
3383+ CRYPTO_DRIVER_LOCK();
3384+ for (hid = 0; hid < crypto_drivers_num; hid++) {
3385+ const struct cryptocap *cap = &crypto_drivers[hid];
3386+
3387+ if ((cap->cc_flags & CRYPTOCAP_F_SOFTWARE) &&
3388+ !crypto_devallowsoft) {
3389+ continue;
3390+ }
3391+ for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
3392+ if (cap->cc_kalg[kalg] & CRYPTO_ALG_FLAG_SUPPORTED)
3393+ feat |= 1 << kalg;
3394+ }
3395+ CRYPTO_DRIVER_UNLOCK();
3396+ *featp = feat;
3397+ return (0);
3398+}
3399+
3400+/*
3401+ * Crypto thread, dispatches crypto requests.
3402+ */
3403+static int
3404+crypto_proc(void *arg)
3405+{
3406+ struct cryptop *crp, *submit;
3407+ struct cryptkop *krp, *krpp;
3408+ struct cryptocap *cap;
3409+ u_int32_t hid;
3410+ int result, hint;
3411+ unsigned long q_flags;
3412+ int loopcount = 0;
3413+
3414+ ocf_daemonize("crypto");
3415+
3416+ CRYPTO_Q_LOCK();
3417+ for (;;) {
3418+ /*
3419+ * we need to make sure we don't get into a busy loop with nothing
3420+ * to do, the two crypto_all_*blocked vars help us find out when
3421+ * we are all full and can do nothing on any driver or Q. If so we
3422+ * wait for an unblock.
3423+ */
3424+ crypto_all_qblocked = !list_empty(&crp_q);
3425+
3426+ /*
3427+ * Find the first element in the queue that can be
3428+ * processed and look-ahead to see if multiple ops
3429+ * are ready for the same driver.
3430+ */
3431+ submit = NULL;
3432+ hint = 0;
3433+ list_for_each_entry(crp, &crp_q, crp_next) {
3434+ hid = CRYPTO_SESID2HID(crp->crp_sid);
3435+ cap = crypto_checkdriver(hid);
3436+ /*
3437+ * Driver cannot disappear when there is an active
3438+ * session.
3439+ */
3440+ KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
3441+ __func__, __LINE__));
3442+ if (cap == NULL || cap->cc_dev == NULL) {
3443+ /* Op needs to be migrated, process it. */
3444+ if (submit == NULL)
3445+ submit = crp;
3446+ break;
3447+ }
3448+ if (!cap->cc_qblocked) {
3449+ if (submit != NULL) {
3450+ /*
3451+ * We stop on finding another op,
3452+ * regardless whether its for the same
3453+ * driver or not. We could keep
3454+ * searching the queue but it might be
3455+ * better to just use a per-driver
3456+ * queue instead.
3457+ */
3458+ if (CRYPTO_SESID2HID(submit->crp_sid) == hid)
3459+ hint = CRYPTO_HINT_MORE;
3460+ break;
3461+ } else {
3462+ submit = crp;
3463+ if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)
3464+ break;
3465+ /* keep scanning for more are q'd */
3466+ }
3467+ }
3468+ }
3469+ if (submit != NULL) {
3470+ hid = CRYPTO_SESID2HID(submit->crp_sid);
3471+ crypto_all_qblocked = 0;
3472+ list_del(&submit->crp_next);
3473+ crypto_drivers[hid].cc_unqblocked = 1;
3474+ cap = crypto_checkdriver(hid);
3475+ CRYPTO_Q_UNLOCK();
3476+ KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
3477+ __func__, __LINE__));
3478+ result = crypto_invoke(cap, submit, hint);
3479+ CRYPTO_Q_LOCK();
3480+ if (result == ERESTART) {
3481+ /*
3482+ * The driver ran out of resources, mark the
3483+ * driver ``blocked'' for cryptop's and put
3484+ * the request back in the queue. It would
3485+ * best to put the request back where we got
3486+ * it but that's hard so for now we put it
3487+ * at the front. This should be ok; putting
3488+ * it at the end does not work.
3489+ */
3490+ /* XXX validate sid again? */
3491+ list_add(&submit->crp_next, &crp_q);
3492+ cryptostats.cs_blocks++;
3493+ if (crypto_drivers[hid].cc_unqblocked)
3494+ crypto_drivers[hid].cc_qblocked=0;
3495+ crypto_drivers[hid].cc_unqblocked=0;
3496+ }
3497+ crypto_drivers[hid].cc_unqblocked = 0;
3498+ }
3499+
3500+ crypto_all_kqblocked = !list_empty(&crp_kq);
3501+
3502+ /* As above, but for key ops */
3503+ krp = NULL;
3504+ list_for_each_entry(krpp, &crp_kq, krp_next) {
3505+ cap = crypto_checkdriver(krpp->krp_hid);
3506+ if (cap == NULL || cap->cc_dev == NULL) {
3507+ /*
3508+ * Operation needs to be migrated, invalidate
3509+ * the assigned device so it will reselect a
3510+ * new one below. Propagate the original
3511+ * crid selection flags if supplied.
3512+ */
3513+ krp->krp_hid = krp->krp_crid &
3514+ (CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE);
3515+ if (krp->krp_hid == 0)
3516+ krp->krp_hid =
3517+ CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE;
3518+ break;
3519+ }
3520+ if (!cap->cc_kqblocked) {
3521+ krp = krpp;
3522+ break;
3523+ }
3524+ }
3525+ if (krp != NULL) {
3526+ crypto_all_kqblocked = 0;
3527+ list_del(&krp->krp_next);
3528+ crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
3529+ CRYPTO_Q_UNLOCK();
3530+ result = crypto_kinvoke(krp, krp->krp_hid);
3531+ CRYPTO_Q_LOCK();
3532+ if (result == ERESTART) {
3533+ /*
3534+ * The driver ran out of resources, mark the
3535+ * driver ``blocked'' for cryptkop's and put
3536+ * the request back in the queue. It would
3537+ * best to put the request back where we got
3538+ * it but that's hard so for now we put it
3539+ * at the front. This should be ok; putting
3540+ * it at the end does not work.
3541+ */
3542+ /* XXX validate sid again? */
3543+ list_add(&krp->krp_next, &crp_kq);
3544+ cryptostats.cs_kblocks++;
3545+ } else
3546+ crypto_drivers[krp->krp_hid].cc_kqblocked = 0;
3547+ }
3548+
3549+ if (submit == NULL && krp == NULL) {
3550+ /*
3551+ * Nothing more to be processed. Sleep until we're
3552+ * woken because there are more ops to process.
3553+ * This happens either by submission or by a driver
3554+ * becoming unblocked and notifying us through
3555+ * crypto_unblock. Note that when we wakeup we
3556+ * start processing each queue again from the
3557+ * front. It's not clear that it's important to
3558+ * preserve this ordering since ops may finish
3559+ * out of order if dispatched to different devices
3560+ * and some become blocked while others do not.
3561+ */
3562+ dprintk("%s - sleeping (qe=%d qb=%d kqe=%d kqb=%d)\n",
3563+ __FUNCTION__,
3564+ list_empty(&crp_q), crypto_all_qblocked,
3565+ list_empty(&crp_kq), crypto_all_kqblocked);
3566+ loopcount = 0;
3567+ CRYPTO_Q_UNLOCK();
3568+ crp_sleep = 1;
3569+ wait_event_interruptible(cryptoproc_wait,
3570+ !(list_empty(&crp_q) || crypto_all_qblocked) ||
3571+ !(list_empty(&crp_kq) || crypto_all_kqblocked) ||
3572+ cryptoproc == (pid_t) -1);
3573+ crp_sleep = 0;
3574+ if (signal_pending (current)) {
3575+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
3576+ spin_lock_irq(&current->sigmask_lock);
3577+#endif
3578+ flush_signals(current);
3579+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
3580+ spin_unlock_irq(&current->sigmask_lock);
3581+#endif
3582+ }
3583+ CRYPTO_Q_LOCK();
3584+ dprintk("%s - awake\n", __FUNCTION__);
3585+ if (cryptoproc == (pid_t) -1)
3586+ break;
3587+ cryptostats.cs_intrs++;
3588+ } else if (loopcount > crypto_max_loopcount) {
3589+ /*
3590+ * Give other processes a chance to run if we've
3591+ * been using the CPU exclusively for a while.
3592+ */
3593+ loopcount = 0;
3594+ schedule();
3595+ }
3596+ loopcount++;
3597+ }
3598+ CRYPTO_Q_UNLOCK();
3599+ complete_and_exit(&cryptoproc_exited, 0);
3600+}
3601+
3602+/*
3603+ * Crypto returns thread, does callbacks for processed crypto requests.
3604+ * Callbacks are done here, rather than in the crypto drivers, because
3605+ * callbacks typically are expensive and would slow interrupt handling.
3606+ */
3607+static int
3608+crypto_ret_proc(void *arg)
3609+{
3610+ struct cryptop *crpt;
3611+ struct cryptkop *krpt;
3612+ unsigned long r_flags;
3613+
3614+ ocf_daemonize("crypto_ret");
3615+
3616+ CRYPTO_RETQ_LOCK();
3617+ for (;;) {
3618+ /* Harvest return q's for completed ops */
3619+ crpt = NULL;
3620+ if (!list_empty(&crp_ret_q))
3621+ crpt = list_entry(crp_ret_q.next, typeof(*crpt), crp_next);
3622+ if (crpt != NULL)
3623+ list_del(&crpt->crp_next);
3624+
3625+ krpt = NULL;
3626+ if (!list_empty(&crp_ret_kq))
3627+ krpt = list_entry(crp_ret_kq.next, typeof(*krpt), krp_next);
3628+ if (krpt != NULL)
3629+ list_del(&krpt->krp_next);
3630+
3631+ if (crpt != NULL || krpt != NULL) {
3632+ CRYPTO_RETQ_UNLOCK();
3633+ /*
3634+ * Run callbacks unlocked.
3635+ */
3636+ if (crpt != NULL)
3637+ crpt->crp_callback(crpt);
3638+ if (krpt != NULL)
3639+ krpt->krp_callback(krpt);
3640+ CRYPTO_RETQ_LOCK();
3641+ } else {
3642+ /*
3643+ * Nothing more to be processed. Sleep until we're
3644+ * woken because there are more returns to process.
3645+ */
3646+ dprintk("%s - sleeping\n", __FUNCTION__);
3647+ CRYPTO_RETQ_UNLOCK();
3648+ wait_event_interruptible(cryptoretproc_wait,
3649+ cryptoretproc == (pid_t) -1 ||
3650+ !list_empty(&crp_ret_q) ||
3651+ !list_empty(&crp_ret_kq));
3652+ if (signal_pending (current)) {
3653+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
3654+ spin_lock_irq(&current->sigmask_lock);
3655+#endif
3656+ flush_signals(current);
3657+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
3658+ spin_unlock_irq(&current->sigmask_lock);
3659+#endif
3660+ }
3661+ CRYPTO_RETQ_LOCK();
3662+ dprintk("%s - awake\n", __FUNCTION__);
3663+ if (cryptoretproc == (pid_t) -1) {
3664+ dprintk("%s - EXITING!\n", __FUNCTION__);
3665+ break;
3666+ }
3667+ cryptostats.cs_rets++;
3668+ }
3669+ }
3670+ CRYPTO_RETQ_UNLOCK();
3671+ complete_and_exit(&cryptoretproc_exited, 0);
3672+}
3673+
3674+
3675+#if 0 /* should put this into /proc or something */
3676+static void
3677+db_show_drivers(void)
3678+{
3679+ int hid;
3680+
3681+ db_printf("%12s %4s %4s %8s %2s %2s\n"
3682+ , "Device"
3683+ , "Ses"
3684+ , "Kops"
3685+ , "Flags"
3686+ , "QB"
3687+ , "KB"
3688+ );
3689+ for (hid = 0; hid < crypto_drivers_num; hid++) {
3690+ const struct cryptocap *cap = &crypto_drivers[hid];
3691+ if (cap->cc_dev == NULL)
3692+ continue;
3693+ db_printf("%-12s %4u %4u %08x %2u %2u\n"
3694+ , device_get_nameunit(cap->cc_dev)
3695+ , cap->cc_sessions
3696+ , cap->cc_koperations
3697+ , cap->cc_flags
3698+ , cap->cc_qblocked
3699+ , cap->cc_kqblocked
3700+ );
3701+ }
3702+}
3703+
3704+DB_SHOW_COMMAND(crypto, db_show_crypto)
3705+{
3706+ struct cryptop *crp;
3707+
3708+ db_show_drivers();
3709+ db_printf("\n");
3710+
3711+ db_printf("%4s %8s %4s %4s %4s %4s %8s %8s\n",
3712+ "HID", "Caps", "Ilen", "Olen", "Etype", "Flags",
3713+ "Desc", "Callback");
3714+ TAILQ_FOREACH(crp, &crp_q, crp_next) {
3715+ db_printf("%4u %08x %4u %4u %4u %04x %8p %8p\n"
3716+ , (int) CRYPTO_SESID2HID(crp->crp_sid)
3717+ , (int) CRYPTO_SESID2CAPS(crp->crp_sid)
3718+ , crp->crp_ilen, crp->crp_olen
3719+ , crp->crp_etype
3720+ , crp->crp_flags
3721+ , crp->crp_desc
3722+ , crp->crp_callback
3723+ );
3724+ }
3725+ if (!TAILQ_EMPTY(&crp_ret_q)) {
3726+ db_printf("\n%4s %4s %4s %8s\n",
3727+ "HID", "Etype", "Flags", "Callback");
3728+ TAILQ_FOREACH(crp, &crp_ret_q, crp_next) {
3729+ db_printf("%4u %4u %04x %8p\n"
3730+ , (int) CRYPTO_SESID2HID(crp->crp_sid)
3731+ , crp->crp_etype
3732+ , crp->crp_flags
3733+ , crp->crp_callback
3734+ );
3735+ }
3736+ }
3737+}
3738+
3739+DB_SHOW_COMMAND(kcrypto, db_show_kcrypto)
3740+{
3741+ struct cryptkop *krp;
3742+
3743+ db_show_drivers();
3744+ db_printf("\n");
3745+
3746+ db_printf("%4s %5s %4s %4s %8s %4s %8s\n",
3747+ "Op", "Status", "#IP", "#OP", "CRID", "HID", "Callback");
3748+ TAILQ_FOREACH(krp, &crp_kq, krp_next) {
3749+ db_printf("%4u %5u %4u %4u %08x %4u %8p\n"
3750+ , krp->krp_op
3751+ , krp->krp_status
3752+ , krp->krp_iparams, krp->krp_oparams
3753+ , krp->krp_crid, krp->krp_hid
3754+ , krp->krp_callback
3755+ );
3756+ }
3757+ if (!TAILQ_EMPTY(&crp_ret_q)) {
3758+ db_printf("%4s %5s %8s %4s %8s\n",
3759+ "Op", "Status", "CRID", "HID", "Callback");
3760+ TAILQ_FOREACH(krp, &crp_ret_kq, krp_next) {
3761+ db_printf("%4u %5u %08x %4u %8p\n"
3762+ , krp->krp_op
3763+ , krp->krp_status
3764+ , krp->krp_crid, krp->krp_hid
3765+ , krp->krp_callback
3766+ );
3767+ }
3768+ }
3769+}
3770+#endif
3771+
3772+
3773+static int
3774+crypto_init(void)
3775+{
3776+ int error;
3777+
3778+ dprintk("%s(%p)\n", __FUNCTION__, (void *) crypto_init);
3779+
3780+ if (crypto_initted)
3781+ return 0;
3782+ crypto_initted = 1;
3783+
3784+ spin_lock_init(&crypto_drivers_lock);
3785+ spin_lock_init(&crypto_q_lock);
3786+ spin_lock_init(&crypto_ret_q_lock);
3787+
3788+ cryptop_zone = kmem_cache_create("cryptop", sizeof(struct cryptop),
3789+ 0, SLAB_HWCACHE_ALIGN, NULL
3790+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
3791+ , NULL
3792+#endif
3793+ );
3794+
3795+ cryptodesc_zone = kmem_cache_create("cryptodesc", sizeof(struct cryptodesc),
3796+ 0, SLAB_HWCACHE_ALIGN, NULL
3797+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
3798+ , NULL
3799+#endif
3800+ );
3801+
3802+ if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
3803+ printk("crypto: crypto_init cannot setup crypto zones\n");
3804+ error = ENOMEM;
3805+ goto bad;
3806+ }
3807+
3808+ crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
3809+ crypto_drivers = kmalloc(crypto_drivers_num * sizeof(struct cryptocap),
3810+ GFP_KERNEL);
3811+ if (crypto_drivers == NULL) {
3812+ printk("crypto: crypto_init cannot setup crypto drivers\n");
3813+ error = ENOMEM;
3814+ goto bad;
3815+ }
3816+
3817+ memset(crypto_drivers, 0, crypto_drivers_num * sizeof(struct cryptocap));
3818+
3819+ init_completion(&cryptoproc_exited);
3820+ init_completion(&cryptoretproc_exited);
3821+
3822+ cryptoproc = 0; /* to avoid race condition where proc runs first */
3823+ cryptoproc = kernel_thread(crypto_proc, NULL, CLONE_FS|CLONE_FILES);
3824+ if (cryptoproc < 0) {
3825+ error = cryptoproc;
3826+ printk("crypto: crypto_init cannot start crypto thread; error %d",
3827+ error);
3828+ goto bad;
3829+ }
3830+
3831+ cryptoretproc = 0; /* to avoid race condition where proc runs first */
3832+ cryptoretproc = kernel_thread(crypto_ret_proc, NULL, CLONE_FS|CLONE_FILES);
3833+ if (cryptoretproc < 0) {
3834+ error = cryptoretproc;
3835+ printk("crypto: crypto_init cannot start cryptoret thread; error %d",
3836+ error);
3837+ goto bad;
3838+ }
3839+
3840+ return 0;
3841+bad:
3842+ crypto_exit();
3843+ return error;
3844+}
3845+
3846+
3847+static void
3848+crypto_exit(void)
3849+{
3850+ pid_t p;
3851+ unsigned long d_flags;
3852+
3853+ dprintk("%s()\n", __FUNCTION__);
3854+
3855+ /*
3856+ * Terminate any crypto threads.
3857+ */
3858+
3859+ CRYPTO_DRIVER_LOCK();
3860+ p = cryptoproc;
3861+ cryptoproc = (pid_t) -1;
3862+ kill_proc(p, SIGTERM, 1);
3863+ wake_up_interruptible(&cryptoproc_wait);
3864+ CRYPTO_DRIVER_UNLOCK();
3865+
3866+ wait_for_completion(&cryptoproc_exited);
3867+
3868+ CRYPTO_DRIVER_LOCK();
3869+ p = cryptoretproc;
3870+ cryptoretproc = (pid_t) -1;
3871+ kill_proc(p, SIGTERM, 1);
3872+ wake_up_interruptible(&cryptoretproc_wait);
3873+ CRYPTO_DRIVER_UNLOCK();
3874+
3875+ wait_for_completion(&cryptoretproc_exited);
3876+
3877+ /* XXX flush queues??? */
3878+
3879+ /*
3880+ * Reclaim dynamically allocated resources.
3881+ */
3882+ if (crypto_drivers != NULL)
3883+ kfree(crypto_drivers);
3884+
3885+ if (cryptodesc_zone != NULL)
3886+ kmem_cache_destroy(cryptodesc_zone);
3887+ if (cryptop_zone != NULL)
3888+ kmem_cache_destroy(cryptop_zone);
3889+}
3890+
3891+
3892+EXPORT_SYMBOL(crypto_newsession);
3893+EXPORT_SYMBOL(crypto_freesession);
3894+EXPORT_SYMBOL(crypto_get_driverid);
3895+EXPORT_SYMBOL(crypto_kregister);
3896+EXPORT_SYMBOL(crypto_register);
3897+EXPORT_SYMBOL(crypto_unregister);
3898+EXPORT_SYMBOL(crypto_unregister_all);
3899+EXPORT_SYMBOL(crypto_unblock);
3900+EXPORT_SYMBOL(crypto_dispatch);
3901+EXPORT_SYMBOL(crypto_kdispatch);
3902+EXPORT_SYMBOL(crypto_freereq);
3903+EXPORT_SYMBOL(crypto_getreq);
3904+EXPORT_SYMBOL(crypto_done);
3905+EXPORT_SYMBOL(crypto_kdone);
3906+EXPORT_SYMBOL(crypto_getfeat);
3907+EXPORT_SYMBOL(crypto_userasymcrypto);
3908+EXPORT_SYMBOL(crypto_getcaps);
3909+EXPORT_SYMBOL(crypto_find_driver);
3910+EXPORT_SYMBOL(crypto_find_device_byhid);
3911+
3912+module_init(crypto_init);
3913+module_exit(crypto_exit);
3914+
3915+MODULE_LICENSE("BSD");
3916+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
3917+MODULE_DESCRIPTION("OCF (OpenBSD Cryptographic Framework)");
3918diff --git a/crypto/ocf/cryptocteon/Makefile b/crypto/ocf/cryptocteon/Makefile
3919new file mode 100644
3920index 0000000..eeed0d6
3921--- /dev/null
3922+++ b/crypto/ocf/cryptocteon/Makefile
3923@@ -0,0 +1,17 @@
3924+# for SGlinux builds
3925+-include $(ROOTDIR)/modules/.config
3926+
3927+obj-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon.o
3928+
3929+obj ?= .
3930+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
3931+
3932+ifdef CONFIG_OCF_CRYPTOCTEON
3933+# you need the cavium crypto component installed
3934+EXTRA_CFLAGS += -I$(ROOTDIR)/prop/include
3935+endif
3936+
3937+ifdef TOPDIR
3938+-include $(TOPDIR)/Rules.make
3939+endif
3940+
3941diff --git a/crypto/ocf/cryptocteon/cavium_crypto.c b/crypto/ocf/cryptocteon/cavium_crypto.c
3942new file mode 100644
3943index 0000000..0254b9b
3944--- /dev/null
3945+++ b/crypto/ocf/cryptocteon/cavium_crypto.c
3946@@ -0,0 +1,2283 @@
3947+/*
3948+ * Copyright (c) 2009 David McCullough <david.mccullough@securecomputing.com>
3949+ *
3950+ * Copyright (c) 2003-2007 Cavium Networks (support@cavium.com). All rights
3951+ * reserved.
3952+ *
3953+ * Redistribution and use in source and binary forms, with or without
3954+ * modification, are permitted provided that the following conditions are met:
3955+ * 1. Redistributions of source code must retain the above copyright notice,
3956+ * this list of conditions and the following disclaimer.
3957+ * 2. Redistributions in binary form must reproduce the above copyright notice,
3958+ * this list of conditions and the following disclaimer in the documentation
3959+ * and/or other materials provided with the distribution.
3960+ * 3. All advertising materials mentioning features or use of this software
3961+ * must display the following acknowledgement:
3962+ * This product includes software developed by Cavium Networks
3963+ * 4. Cavium Networks' name may not be used to endorse or promote products
3964+ * derived from this software without specific prior written permission.
3965+ *
3966+ * This Software, including technical data, may be subject to U.S. export
3967+ * control laws, including the U.S. Export Administration Act and its
3968+ * associated regulations, and may be subject to export or import regulations
3969+ * in other countries. You warrant that You will comply strictly in all
3970+ * respects with all such regulations and acknowledge that you have the
3971+ * responsibility to obtain licenses to export, re-export or import the
3972+ * Software.
3973+ *
3974+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" AND
3975+ * WITH ALL FAULTS AND CAVIUM MAKES NO PROMISES, REPRESENTATIONS OR WARRANTIES,
3976+ * EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE
3977+ * SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
3978+ * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
3979+ * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
3980+ * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
3981+ * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
3982+ * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
3983+ * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
3984+*/
3985+/****************************************************************************/
3986+
3987+#include <linux/scatterlist.h>
3988+#include <asm/octeon/octeon.h>
3989+#include "octeon-asm.h"
3990+
3991+/****************************************************************************/
3992+
3993+extern unsigned long octeon_crypto_enable(struct octeon_cop2_state *);
3994+extern void octeon_crypto_disable(struct octeon_cop2_state *, unsigned long);
3995+
3996+#define SG_INIT(s, p, i, l) \
3997+ { \
3998+ (i) = 0; \
3999+ (l) = (s)[0].length; \
4000+ (p) = (typeof(p)) sg_virt((s)); \
4001+ CVMX_PREFETCH0((p)); \
4002+ }
4003+
4004+#define SG_CONSUME(s, p, i, l) \
4005+ { \
4006+ (p)++; \
4007+ (l) -= sizeof(*(p)); \
4008+ if ((l) < 0) { \
4009+ dprintk("%s, %d: l = %d\n", __FILE__, __LINE__, l); \
4010+ } else if ((l) == 0) { \
4011+ (i)++; \
4012+ (l) = (s)[0].length; \
4013+ (p) = (typeof(p)) sg_virt(s); \
4014+ CVMX_PREFETCH0((p)); \
4015+ } \
4016+ }
4017+
4018+#define ESP_HEADER_LENGTH 8
4019+#define DES_CBC_IV_LENGTH 8
4020+#define AES_CBC_IV_LENGTH 16
4021+#define ESP_HMAC_LEN 12
4022+
4023+#define ESP_HEADER_LENGTH 8
4024+#define DES_CBC_IV_LENGTH 8
4025+
4026+/****************************************************************************/
4027+
4028+#define CVM_LOAD_SHA_UNIT(dat, next) { \
4029+ if (next == 0) { \
4030+ next = 1; \
4031+ CVMX_MT_HSH_DAT (dat, 0); \
4032+ } else if (next == 1) { \
4033+ next = 2; \
4034+ CVMX_MT_HSH_DAT (dat, 1); \
4035+ } else if (next == 2) { \
4036+ next = 3; \
4037+ CVMX_MT_HSH_DAT (dat, 2); \
4038+ } else if (next == 3) { \
4039+ next = 4; \
4040+ CVMX_MT_HSH_DAT (dat, 3); \
4041+ } else if (next == 4) { \
4042+ next = 5; \
4043+ CVMX_MT_HSH_DAT (dat, 4); \
4044+ } else if (next == 5) { \
4045+ next = 6; \
4046+ CVMX_MT_HSH_DAT (dat, 5); \
4047+ } else if (next == 6) { \
4048+ next = 7; \
4049+ CVMX_MT_HSH_DAT (dat, 6); \
4050+ } else { \
4051+ CVMX_MT_HSH_STARTSHA (dat); \
4052+ next = 0; \
4053+ } \
4054+}
4055+
4056+#define CVM_LOAD2_SHA_UNIT(dat1, dat2, next) { \
4057+ if (next == 0) { \
4058+ CVMX_MT_HSH_DAT (dat1, 0); \
4059+ CVMX_MT_HSH_DAT (dat2, 1); \
4060+ next = 2; \
4061+ } else if (next == 1) { \
4062+ CVMX_MT_HSH_DAT (dat1, 1); \
4063+ CVMX_MT_HSH_DAT (dat2, 2); \
4064+ next = 3; \
4065+ } else if (next == 2) { \
4066+ CVMX_MT_HSH_DAT (dat1, 2); \
4067+ CVMX_MT_HSH_DAT (dat2, 3); \
4068+ next = 4; \
4069+ } else if (next == 3) { \
4070+ CVMX_MT_HSH_DAT (dat1, 3); \
4071+ CVMX_MT_HSH_DAT (dat2, 4); \
4072+ next = 5; \
4073+ } else if (next == 4) { \
4074+ CVMX_MT_HSH_DAT (dat1, 4); \
4075+ CVMX_MT_HSH_DAT (dat2, 5); \
4076+ next = 6; \
4077+ } else if (next == 5) { \
4078+ CVMX_MT_HSH_DAT (dat1, 5); \
4079+ CVMX_MT_HSH_DAT (dat2, 6); \
4080+ next = 7; \
4081+ } else if (next == 6) { \
4082+ CVMX_MT_HSH_DAT (dat1, 6); \
4083+ CVMX_MT_HSH_STARTSHA (dat2); \
4084+ next = 0; \
4085+ } else { \
4086+ CVMX_MT_HSH_STARTSHA (dat1); \
4087+ CVMX_MT_HSH_DAT (dat2, 0); \
4088+ next = 1; \
4089+ } \
4090+}
4091+
4092+/****************************************************************************/
4093+
4094+#define CVM_LOAD_MD5_UNIT(dat, next) { \
4095+ if (next == 0) { \
4096+ next = 1; \
4097+ CVMX_MT_HSH_DAT (dat, 0); \
4098+ } else if (next == 1) { \
4099+ next = 2; \
4100+ CVMX_MT_HSH_DAT (dat, 1); \
4101+ } else if (next == 2) { \
4102+ next = 3; \
4103+ CVMX_MT_HSH_DAT (dat, 2); \
4104+ } else if (next == 3) { \
4105+ next = 4; \
4106+ CVMX_MT_HSH_DAT (dat, 3); \
4107+ } else if (next == 4) { \
4108+ next = 5; \
4109+ CVMX_MT_HSH_DAT (dat, 4); \
4110+ } else if (next == 5) { \
4111+ next = 6; \
4112+ CVMX_MT_HSH_DAT (dat, 5); \
4113+ } else if (next == 6) { \
4114+ next = 7; \
4115+ CVMX_MT_HSH_DAT (dat, 6); \
4116+ } else { \
4117+ CVMX_MT_HSH_STARTMD5 (dat); \
4118+ next = 0; \
4119+ } \
4120+}
4121+
4122+#define CVM_LOAD2_MD5_UNIT(dat1, dat2, next) { \
4123+ if (next == 0) { \
4124+ CVMX_MT_HSH_DAT (dat1, 0); \
4125+ CVMX_MT_HSH_DAT (dat2, 1); \
4126+ next = 2; \
4127+ } else if (next == 1) { \
4128+ CVMX_MT_HSH_DAT (dat1, 1); \
4129+ CVMX_MT_HSH_DAT (dat2, 2); \
4130+ next = 3; \
4131+ } else if (next == 2) { \
4132+ CVMX_MT_HSH_DAT (dat1, 2); \
4133+ CVMX_MT_HSH_DAT (dat2, 3); \
4134+ next = 4; \
4135+ } else if (next == 3) { \
4136+ CVMX_MT_HSH_DAT (dat1, 3); \
4137+ CVMX_MT_HSH_DAT (dat2, 4); \
4138+ next = 5; \
4139+ } else if (next == 4) { \
4140+ CVMX_MT_HSH_DAT (dat1, 4); \
4141+ CVMX_MT_HSH_DAT (dat2, 5); \
4142+ next = 6; \
4143+ } else if (next == 5) { \
4144+ CVMX_MT_HSH_DAT (dat1, 5); \
4145+ CVMX_MT_HSH_DAT (dat2, 6); \
4146+ next = 7; \
4147+ } else if (next == 6) { \
4148+ CVMX_MT_HSH_DAT (dat1, 6); \
4149+ CVMX_MT_HSH_STARTMD5 (dat2); \
4150+ next = 0; \
4151+ } else { \
4152+ CVMX_MT_HSH_STARTMD5 (dat1); \
4153+ CVMX_MT_HSH_DAT (dat2, 0); \
4154+ next = 1; \
4155+ } \
4156+}
4157+
4158+/****************************************************************************/
4159+
4160+static inline uint64_t
4161+swap64(uint64_t a)
4162+{
4163+ return ((a >> 56) |
4164+ (((a >> 48) & 0xfful) << 8) |
4165+ (((a >> 40) & 0xfful) << 16) |
4166+ (((a >> 32) & 0xfful) << 24) |
4167+ (((a >> 24) & 0xfful) << 32) |
4168+ (((a >> 16) & 0xfful) << 40) |
4169+ (((a >> 8) & 0xfful) << 48) | (((a >> 0) & 0xfful) << 56));
4170+}
4171+
4172+/****************************************************************************/
4173+
4174+void
4175+octo_calc_hash(__u8 auth, unsigned char *key, uint64_t *inner, uint64_t *outer)
4176+{
4177+ uint8_t hash_key[64];
4178+ uint64_t *key1;
4179+ register uint64_t xor1 = 0x3636363636363636ULL;
4180+ register uint64_t xor2 = 0x5c5c5c5c5c5c5c5cULL;
4181+ struct octeon_cop2_state state;
4182+ unsigned long flags;
4183+
4184+ dprintk("%s()\n", __FUNCTION__);
4185+
4186+ memset(hash_key, 0, sizeof(hash_key));
4187+ memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));
4188+ key1 = (uint64_t *) hash_key;
4189+ flags = octeon_crypto_enable(&state);
4190+ if (auth) {
4191+ CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);
4192+ CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);
4193+ CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);
4194+ } else {
4195+ CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);
4196+ CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);
4197+ }
4198+
4199+ CVMX_MT_HSH_DAT((*key1 ^ xor1), 0);
4200+ key1++;
4201+ CVMX_MT_HSH_DAT((*key1 ^ xor1), 1);
4202+ key1++;
4203+ CVMX_MT_HSH_DAT((*key1 ^ xor1), 2);
4204+ key1++;
4205+ CVMX_MT_HSH_DAT((*key1 ^ xor1), 3);
4206+ key1++;
4207+ CVMX_MT_HSH_DAT((*key1 ^ xor1), 4);
4208+ key1++;
4209+ CVMX_MT_HSH_DAT((*key1 ^ xor1), 5);
4210+ key1++;
4211+ CVMX_MT_HSH_DAT((*key1 ^ xor1), 6);
4212+ key1++;
4213+ if (auth)
4214+ CVMX_MT_HSH_STARTSHA((*key1 ^ xor1));
4215+ else
4216+ CVMX_MT_HSH_STARTMD5((*key1 ^ xor1));
4217+
4218+ CVMX_MF_HSH_IV(inner[0], 0);
4219+ CVMX_MF_HSH_IV(inner[1], 1);
4220+ if (auth) {
4221+ inner[2] = 0;
4222+ CVMX_MF_HSH_IV(((uint64_t *) inner)[2], 2);
4223+ }
4224+
4225+ memset(hash_key, 0, sizeof(hash_key));
4226+ memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));
4227+ key1 = (uint64_t *) hash_key;
4228+ if (auth) {
4229+ CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);
4230+ CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);
4231+ CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);
4232+ } else {
4233+ CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);
4234+ CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);
4235+ }
4236+
4237+ CVMX_MT_HSH_DAT((*key1 ^ xor2), 0);
4238+ key1++;
4239+ CVMX_MT_HSH_DAT((*key1 ^ xor2), 1);
4240+ key1++;
4241+ CVMX_MT_HSH_DAT((*key1 ^ xor2), 2);
4242+ key1++;
4243+ CVMX_MT_HSH_DAT((*key1 ^ xor2), 3);
4244+ key1++;
4245+ CVMX_MT_HSH_DAT((*key1 ^ xor2), 4);
4246+ key1++;
4247+ CVMX_MT_HSH_DAT((*key1 ^ xor2), 5);
4248+ key1++;
4249+ CVMX_MT_HSH_DAT((*key1 ^ xor2), 6);
4250+ key1++;
4251+ if (auth)
4252+ CVMX_MT_HSH_STARTSHA((*key1 ^ xor2));
4253+ else
4254+ CVMX_MT_HSH_STARTMD5((*key1 ^ xor2));
4255+
4256+ CVMX_MF_HSH_IV(outer[0], 0);
4257+ CVMX_MF_HSH_IV(outer[1], 1);
4258+ if (auth) {
4259+ outer[2] = 0;
4260+ CVMX_MF_HSH_IV(outer[2], 2);
4261+ }
4262+ octeon_crypto_disable(&state, flags);
4263+ return;
4264+}
4265+
4266+/****************************************************************************/
4267+/* DES functions */
4268+
4269+int
4270+octo_des_cbc_encrypt(
4271+ struct octo_sess *od,
4272+ struct scatterlist *sg, int sg_len,
4273+ int auth_off, int auth_len,
4274+ int crypt_off, int crypt_len,
4275+ int icv_off, uint8_t *ivp)
4276+{
4277+ uint64_t *data;
4278+ int data_i, data_l;
4279+ struct octeon_cop2_state state;
4280+ unsigned long flags;
4281+
4282+ dprintk("%s()\n", __FUNCTION__);
4283+
4284+ if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
4285+ (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
4286+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
4287+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
4288+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
4289+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
4290+ return -EINVAL;
4291+ }
4292+
4293+ SG_INIT(sg, data, data_i, data_l);
4294+
4295+ CVMX_PREFETCH0(ivp);
4296+ CVMX_PREFETCH0(od->octo_enckey);
4297+
4298+ flags = octeon_crypto_enable(&state);
4299+
4300+ /* load 3DES Key */
4301+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
4302+ if (od->octo_encklen == 24) {
4303+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
4304+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
4305+ } else if (od->octo_encklen == 8) {
4306+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
4307+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
4308+ } else {
4309+ octeon_crypto_disable(&state, flags);
4310+ dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
4311+ return -EINVAL;
4312+ }
4313+
4314+ CVMX_MT_3DES_IV(* (uint64_t *) ivp);
4315+
4316+ while (crypt_off > 0) {
4317+ SG_CONSUME(sg, data, data_i, data_l);
4318+ crypt_off -= 8;
4319+ }
4320+
4321+ while (crypt_len > 0) {
4322+ CVMX_MT_3DES_ENC_CBC(*data);
4323+ CVMX_MF_3DES_RESULT(*data);
4324+ SG_CONSUME(sg, data, data_i, data_l);
4325+ crypt_len -= 8;
4326+ }
4327+
4328+ octeon_crypto_disable(&state, flags);
4329+ return 0;
4330+}
4331+
4332+
4333+int
4334+octo_des_cbc_decrypt(
4335+ struct octo_sess *od,
4336+ struct scatterlist *sg, int sg_len,
4337+ int auth_off, int auth_len,
4338+ int crypt_off, int crypt_len,
4339+ int icv_off, uint8_t *ivp)
4340+{
4341+ uint64_t *data;
4342+ int data_i, data_l;
4343+ struct octeon_cop2_state state;
4344+ unsigned long flags;
4345+
4346+ dprintk("%s()\n", __FUNCTION__);
4347+
4348+ if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
4349+ (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
4350+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
4351+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
4352+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
4353+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
4354+ return -EINVAL;
4355+ }
4356+
4357+ SG_INIT(sg, data, data_i, data_l);
4358+
4359+ CVMX_PREFETCH0(ivp);
4360+ CVMX_PREFETCH0(od->octo_enckey);
4361+
4362+ flags = octeon_crypto_enable(&state);
4363+
4364+ /* load 3DES Key */
4365+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
4366+ if (od->octo_encklen == 24) {
4367+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
4368+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
4369+ } else if (od->octo_encklen == 8) {
4370+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
4371+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
4372+ } else {
4373+ octeon_crypto_disable(&state, flags);
4374+ dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
4375+ return -EINVAL;
4376+ }
4377+
4378+ CVMX_MT_3DES_IV(* (uint64_t *) ivp);
4379+
4380+ while (crypt_off > 0) {
4381+ SG_CONSUME(sg, data, data_i, data_l);
4382+ crypt_off -= 8;
4383+ }
4384+
4385+ while (crypt_len > 0) {
4386+ CVMX_MT_3DES_DEC_CBC(*data);
4387+ CVMX_MF_3DES_RESULT(*data);
4388+ SG_CONSUME(sg, data, data_i, data_l);
4389+ crypt_len -= 8;
4390+ }
4391+
4392+ octeon_crypto_disable(&state, flags);
4393+ return 0;
4394+}
4395+
4396+/****************************************************************************/
4397+/* AES functions */
4398+
4399+int
4400+octo_aes_cbc_encrypt(
4401+ struct octo_sess *od,
4402+ struct scatterlist *sg, int sg_len,
4403+ int auth_off, int auth_len,
4404+ int crypt_off, int crypt_len,
4405+ int icv_off, uint8_t *ivp)
4406+{
4407+ uint64_t *data, *pdata;
4408+ int data_i, data_l;
4409+ struct octeon_cop2_state state;
4410+ unsigned long flags;
4411+
4412+ dprintk("%s()\n", __FUNCTION__);
4413+
4414+ if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
4415+ (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
4416+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
4417+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
4418+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
4419+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
4420+ return -EINVAL;
4421+ }
4422+
4423+ SG_INIT(sg, data, data_i, data_l);
4424+
4425+ CVMX_PREFETCH0(ivp);
4426+ CVMX_PREFETCH0(od->octo_enckey);
4427+
4428+ flags = octeon_crypto_enable(&state);
4429+
4430+ /* load AES Key */
4431+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
4432+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
4433+
4434+ if (od->octo_encklen == 16) {
4435+ CVMX_MT_AES_KEY(0x0, 2);
4436+ CVMX_MT_AES_KEY(0x0, 3);
4437+ } else if (od->octo_encklen == 24) {
4438+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
4439+ CVMX_MT_AES_KEY(0x0, 3);
4440+ } else if (od->octo_encklen == 32) {
4441+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
4442+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
4443+ } else {
4444+ octeon_crypto_disable(&state, flags);
4445+ dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
4446+ return -EINVAL;
4447+ }
4448+ CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
4449+
4450+ CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
4451+ CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
4452+
4453+ while (crypt_off > 0) {
4454+ SG_CONSUME(sg, data, data_i, data_l);
4455+ crypt_off -= 8;
4456+ }
4457+
4458+ while (crypt_len > 0) {
4459+ pdata = data;
4460+ CVMX_MT_AES_ENC_CBC0(*data);
4461+ SG_CONSUME(sg, data, data_i, data_l);
4462+ CVMX_MT_AES_ENC_CBC1(*data);
4463+ CVMX_MF_AES_RESULT(*pdata, 0);
4464+ CVMX_MF_AES_RESULT(*data, 1);
4465+ SG_CONSUME(sg, data, data_i, data_l);
4466+ crypt_len -= 16;
4467+ }
4468+
4469+ octeon_crypto_disable(&state, flags);
4470+ return 0;
4471+}
4472+
4473+
4474+int
4475+octo_aes_cbc_decrypt(
4476+ struct octo_sess *od,
4477+ struct scatterlist *sg, int sg_len,
4478+ int auth_off, int auth_len,
4479+ int crypt_off, int crypt_len,
4480+ int icv_off, uint8_t *ivp)
4481+{
4482+ uint64_t *data, *pdata;
4483+ int data_i, data_l;
4484+ struct octeon_cop2_state state;
4485+ unsigned long flags;
4486+
4487+ dprintk("%s()\n", __FUNCTION__);
4488+
4489+ if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
4490+ (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
4491+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
4492+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
4493+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
4494+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
4495+ return -EINVAL;
4496+ }
4497+
4498+ SG_INIT(sg, data, data_i, data_l);
4499+
4500+ CVMX_PREFETCH0(ivp);
4501+ CVMX_PREFETCH0(od->octo_enckey);
4502+
4503+ flags = octeon_crypto_enable(&state);
4504+
4505+ /* load AES Key */
4506+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
4507+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
4508+
4509+ if (od->octo_encklen == 16) {
4510+ CVMX_MT_AES_KEY(0x0, 2);
4511+ CVMX_MT_AES_KEY(0x0, 3);
4512+ } else if (od->octo_encklen == 24) {
4513+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
4514+ CVMX_MT_AES_KEY(0x0, 3);
4515+ } else if (od->octo_encklen == 32) {
4516+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
4517+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
4518+ } else {
4519+ octeon_crypto_disable(&state, flags);
4520+ dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
4521+ return -EINVAL;
4522+ }
4523+ CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
4524+
4525+ CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
4526+ CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
4527+
4528+ while (crypt_off > 0) {
4529+ SG_CONSUME(sg, data, data_i, data_l);
4530+ crypt_off -= 8;
4531+ }
4532+
4533+ while (crypt_len > 0) {
4534+ pdata = data;
4535+ CVMX_MT_AES_DEC_CBC0(*data);
4536+ SG_CONSUME(sg, data, data_i, data_l);
4537+ CVMX_MT_AES_DEC_CBC1(*data);
4538+ CVMX_MF_AES_RESULT(*pdata, 0);
4539+ CVMX_MF_AES_RESULT(*data, 1);
4540+ SG_CONSUME(sg, data, data_i, data_l);
4541+ crypt_len -= 16;
4542+ }
4543+
4544+ octeon_crypto_disable(&state, flags);
4545+ return 0;
4546+}
4547+
4548+/****************************************************************************/
4549+/* MD5 */
4550+
4551+int
4552+octo_null_md5_encrypt(
4553+ struct octo_sess *od,
4554+ struct scatterlist *sg, int sg_len,
4555+ int auth_off, int auth_len,
4556+ int crypt_off, int crypt_len,
4557+ int icv_off, uint8_t *ivp)
4558+{
4559+ register int next = 0;
4560+ uint64_t *data;
4561+ uint64_t tmp1, tmp2;
4562+ int data_i, data_l, alen = auth_len;
4563+ struct octeon_cop2_state state;
4564+ unsigned long flags;
4565+
4566+ dprintk("%s()\n", __FUNCTION__);
4567+
4568+ if (unlikely(od == NULL || sg==NULL || sg_len==0 ||
4569+ (auth_off & 0x7) || (auth_off + auth_len > sg_len))) {
4570+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
4571+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
4572+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
4573+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
4574+ return -EINVAL;
4575+ }
4576+
4577+ SG_INIT(sg, data, data_i, data_l);
4578+
4579+ flags = octeon_crypto_enable(&state);
4580+
4581+ /* Load MD5 IV */
4582+ CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
4583+ CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
4584+
4585+ while (auth_off > 0) {
4586+ SG_CONSUME(sg, data, data_i, data_l);
4587+ auth_off -= 8;
4588+ }
4589+
4590+ while (auth_len > 0) {
4591+ CVM_LOAD_MD5_UNIT(*data, next);
4592+ auth_len -= 8;
4593+ SG_CONSUME(sg, data, data_i, data_l);
4594+ }
4595+
4596+ /* finish the hash */
4597+ CVMX_PREFETCH0(od->octo_hmouter);
4598+#if 0
4599+ if (unlikely(inplen)) {
4600+ uint64_t tmp = 0;
4601+ uint8_t *p = (uint8_t *) & tmp;
4602+ p[inplen] = 0x80;
4603+ do {
4604+ inplen--;
4605+ p[inplen] = ((uint8_t *) data)[inplen];
4606+ } while (inplen);
4607+ CVM_LOAD_MD5_UNIT(tmp, next);
4608+ } else {
4609+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
4610+ }
4611+#else
4612+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
4613+#endif
4614+
4615+ /* Finish Inner hash */
4616+ while (next != 7) {
4617+ CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
4618+ }
4619+ CVMX_ES64(tmp1, ((alen + 64) << 3));
4620+ CVM_LOAD_MD5_UNIT(tmp1, next);
4621+
4622+ /* Get the inner hash of HMAC */
4623+ CVMX_MF_HSH_IV(tmp1, 0);
4624+ CVMX_MF_HSH_IV(tmp2, 1);
4625+
4626+ /* Initialize hash unit */
4627+ CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
4628+ CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
4629+
4630+ CVMX_MT_HSH_DAT(tmp1, 0);
4631+ CVMX_MT_HSH_DAT(tmp2, 1);
4632+ CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
4633+ CVMX_MT_HSH_DATZ(3);
4634+ CVMX_MT_HSH_DATZ(4);
4635+ CVMX_MT_HSH_DATZ(5);
4636+ CVMX_MT_HSH_DATZ(6);
4637+ CVMX_ES64(tmp1, ((64 + 16) << 3));
4638+ CVMX_MT_HSH_STARTMD5(tmp1);
4639+
4640+ /* save the HMAC */
4641+ SG_INIT(sg, data, data_i, data_l);
4642+ while (icv_off > 0) {
4643+ SG_CONSUME(sg, data, data_i, data_l);
4644+ icv_off -= 8;
4645+ }
4646+ CVMX_MF_HSH_IV(*data, 0);
4647+ SG_CONSUME(sg, data, data_i, data_l);
4648+ CVMX_MF_HSH_IV(tmp1, 1);
4649+ *(uint32_t *)data = (uint32_t) (tmp1 >> 32);
4650+
4651+ octeon_crypto_disable(&state, flags);
4652+ return 0;
4653+}
4654+
4655+/****************************************************************************/
4656+/* SHA1 */
4657+
4658+int
4659+octo_null_sha1_encrypt(
4660+ struct octo_sess *od,
4661+ struct scatterlist *sg, int sg_len,
4662+ int auth_off, int auth_len,
4663+ int crypt_off, int crypt_len,
4664+ int icv_off, uint8_t *ivp)
4665+{
4666+ register int next = 0;
4667+ uint64_t *data;
4668+ uint64_t tmp1, tmp2, tmp3;
4669+ int data_i, data_l, alen = auth_len;
4670+ struct octeon_cop2_state state;
4671+ unsigned long flags;
4672+
4673+ dprintk("%s()\n", __FUNCTION__);
4674+
4675+ if (unlikely(od == NULL || sg==NULL || sg_len==0 ||
4676+ (auth_off & 0x7) || (auth_off + auth_len > sg_len))) {
4677+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
4678+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
4679+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
4680+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
4681+ return -EINVAL;
4682+ }
4683+
4684+ SG_INIT(sg, data, data_i, data_l);
4685+
4686+ flags = octeon_crypto_enable(&state);
4687+
4688+ /* Load SHA1 IV */
4689+ CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
4690+ CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
4691+ CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
4692+
4693+ while (auth_off > 0) {
4694+ SG_CONSUME(sg, data, data_i, data_l);
4695+ auth_off -= 8;
4696+ }
4697+
4698+ while (auth_len > 0) {
4699+ CVM_LOAD_SHA_UNIT(*data, next);
4700+ auth_len -= 8;
4701+ SG_CONSUME(sg, data, data_i, data_l);
4702+ }
4703+
4704+ /* finish the hash */
4705+ CVMX_PREFETCH0(od->octo_hmouter);
4706+#if 0
4707+ if (unlikely(inplen)) {
4708+ uint64_t tmp = 0;
4709+ uint8_t *p = (uint8_t *) & tmp;
4710+ p[inplen] = 0x80;
4711+ do {
4712+ inplen--;
4713+ p[inplen] = ((uint8_t *) data)[inplen];
4714+ } while (inplen);
4715+ CVM_LOAD_MD5_UNIT(tmp, next);
4716+ } else {
4717+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
4718+ }
4719+#else
4720+ CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
4721+#endif
4722+
4723+ /* Finish Inner hash */
4724+ while (next != 7) {
4725+ CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
4726+ }
4727+ CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
4728+
4729+ /* Get the inner hash of HMAC */
4730+ CVMX_MF_HSH_IV(tmp1, 0);
4731+ CVMX_MF_HSH_IV(tmp2, 1);
4732+ tmp3 = 0;
4733+ CVMX_MF_HSH_IV(tmp3, 2);
4734+
4735+ /* Initialize hash unit */
4736+ CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
4737+ CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
4738+ CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
4739+
4740+ CVMX_MT_HSH_DAT(tmp1, 0);
4741+ CVMX_MT_HSH_DAT(tmp2, 1);
4742+ tmp3 |= 0x0000000080000000;
4743+ CVMX_MT_HSH_DAT(tmp3, 2);
4744+ CVMX_MT_HSH_DATZ(3);
4745+ CVMX_MT_HSH_DATZ(4);
4746+ CVMX_MT_HSH_DATZ(5);
4747+ CVMX_MT_HSH_DATZ(6);
4748+ CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
4749+
4750+ /* save the HMAC */
4751+ SG_INIT(sg, data, data_i, data_l);
4752+ while (icv_off > 0) {
4753+ SG_CONSUME(sg, data, data_i, data_l);
4754+ icv_off -= 8;
4755+ }
4756+ CVMX_MF_HSH_IV(*data, 0);
4757+ SG_CONSUME(sg, data, data_i, data_l);
4758+ CVMX_MF_HSH_IV(tmp1, 1);
4759+ *(uint32_t *)data = (uint32_t) (tmp1 >> 32);
4760+
4761+ octeon_crypto_disable(&state, flags);
4762+ return 0;
4763+}
4764+
4765+/****************************************************************************/
4766+/* DES MD5 */
4767+
4768+int
4769+octo_des_cbc_md5_encrypt(
4770+ struct octo_sess *od,
4771+ struct scatterlist *sg, int sg_len,
4772+ int auth_off, int auth_len,
4773+ int crypt_off, int crypt_len,
4774+ int icv_off, uint8_t *ivp)
4775+{
4776+ register int next = 0;
4777+ union {
4778+ uint32_t data32[2];
4779+ uint64_t data64[1];
4780+ } mydata;
4781+ uint64_t *data = &mydata.data64[0];
4782+ uint32_t *data32;
4783+ uint64_t tmp1, tmp2;
4784+ int data_i, data_l, alen = auth_len;
4785+ struct octeon_cop2_state state;
4786+ unsigned long flags;
4787+
4788+ dprintk("%s()\n", __FUNCTION__);
4789+
4790+ if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
4791+ (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
4792+ (crypt_len & 0x7) ||
4793+ (auth_len & 0x7) ||
4794+ (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
4795+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
4796+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
4797+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
4798+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
4799+ return -EINVAL;
4800+ }
4801+
4802+ SG_INIT(sg, data32, data_i, data_l);
4803+
4804+ CVMX_PREFETCH0(ivp);
4805+ CVMX_PREFETCH0(od->octo_enckey);
4806+
4807+ flags = octeon_crypto_enable(&state);
4808+
4809+ /* load 3DES Key */
4810+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
4811+ if (od->octo_encklen == 24) {
4812+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
4813+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
4814+ } else if (od->octo_encklen == 8) {
4815+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
4816+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
4817+ } else {
4818+ octeon_crypto_disable(&state, flags);
4819+ dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
4820+ return -EINVAL;
4821+ }
4822+
4823+ CVMX_MT_3DES_IV(* (uint64_t *) ivp);
4824+
4825+ /* Load MD5 IV */
4826+ CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
4827+ CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
4828+
4829+ while (crypt_off > 0 && auth_off > 0) {
4830+ SG_CONSUME(sg, data32, data_i, data_l);
4831+ crypt_off -= 4;
4832+ auth_off -= 4;
4833+ }
4834+
4835+ while (crypt_len > 0 || auth_len > 0) {
4836+ uint32_t *first = data32;
4837+ mydata.data32[0] = *first;
4838+ SG_CONSUME(sg, data32, data_i, data_l);
4839+ mydata.data32[1] = *data32;
4840+ if (crypt_off <= 0) {
4841+ if (crypt_len > 0) {
4842+ CVMX_MT_3DES_ENC_CBC(*data);
4843+ CVMX_MF_3DES_RESULT(*data);
4844+ crypt_len -= 8;
4845+ }
4846+ } else
4847+ crypt_off -= 8;
4848+ if (auth_off <= 0) {
4849+ if (auth_len > 0) {
4850+ CVM_LOAD_MD5_UNIT(*data, next);
4851+ auth_len -= 8;
4852+ }
4853+ } else
4854+ auth_off -= 8;
4855+ *first = mydata.data32[0];
4856+ *data32 = mydata.data32[1];
4857+ SG_CONSUME(sg, data32, data_i, data_l);
4858+ }
4859+
4860+ /* finish the hash */
4861+ CVMX_PREFETCH0(od->octo_hmouter);
4862+#if 0
4863+ if (unlikely(inplen)) {
4864+ uint64_t tmp = 0;
4865+ uint8_t *p = (uint8_t *) & tmp;
4866+ p[inplen] = 0x80;
4867+ do {
4868+ inplen--;
4869+ p[inplen] = ((uint8_t *) data)[inplen];
4870+ } while (inplen);
4871+ CVM_LOAD_MD5_UNIT(tmp, next);
4872+ } else {
4873+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
4874+ }
4875+#else
4876+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
4877+#endif
4878+
4879+ /* Finish Inner hash */
4880+ while (next != 7) {
4881+ CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
4882+ }
4883+ CVMX_ES64(tmp1, ((alen + 64) << 3));
4884+ CVM_LOAD_MD5_UNIT(tmp1, next);
4885+
4886+ /* Get the inner hash of HMAC */
4887+ CVMX_MF_HSH_IV(tmp1, 0);
4888+ CVMX_MF_HSH_IV(tmp2, 1);
4889+
4890+ /* Initialize hash unit */
4891+ CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
4892+ CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
4893+
4894+ CVMX_MT_HSH_DAT(tmp1, 0);
4895+ CVMX_MT_HSH_DAT(tmp2, 1);
4896+ CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
4897+ CVMX_MT_HSH_DATZ(3);
4898+ CVMX_MT_HSH_DATZ(4);
4899+ CVMX_MT_HSH_DATZ(5);
4900+ CVMX_MT_HSH_DATZ(6);
4901+ CVMX_ES64(tmp1, ((64 + 16) << 3));
4902+ CVMX_MT_HSH_STARTMD5(tmp1);
4903+
4904+ /* save the HMAC */
4905+ SG_INIT(sg, data32, data_i, data_l);
4906+ while (icv_off > 0) {
4907+ SG_CONSUME(sg, data32, data_i, data_l);
4908+ icv_off -= 4;
4909+ }
4910+ CVMX_MF_HSH_IV(tmp1, 0);
4911+ *data32 = (uint32_t) (tmp1 >> 32);
4912+ SG_CONSUME(sg, data32, data_i, data_l);
4913+ *data32 = (uint32_t) tmp1;
4914+ SG_CONSUME(sg, data32, data_i, data_l);
4915+ CVMX_MF_HSH_IV(tmp1, 1);
4916+ *data32 = (uint32_t) (tmp1 >> 32);
4917+
4918+ octeon_crypto_disable(&state, flags);
4919+ return 0;
4920+}
4921+
4922+int
4923+octo_des_cbc_md5_decrypt(
4924+ struct octo_sess *od,
4925+ struct scatterlist *sg, int sg_len,
4926+ int auth_off, int auth_len,
4927+ int crypt_off, int crypt_len,
4928+ int icv_off, uint8_t *ivp)
4929+{
4930+ register int next = 0;
4931+ union {
4932+ uint32_t data32[2];
4933+ uint64_t data64[1];
4934+ } mydata;
4935+ uint64_t *data = &mydata.data64[0];
4936+ uint32_t *data32;
4937+ uint64_t tmp1, tmp2;
4938+ int data_i, data_l, alen = auth_len;
4939+ struct octeon_cop2_state state;
4940+ unsigned long flags;
4941+
4942+ dprintk("%s()\n", __FUNCTION__);
4943+
4944+ if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
4945+ (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
4946+ (crypt_len & 0x7) ||
4947+ (auth_len & 0x7) ||
4948+ (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
4949+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
4950+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
4951+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
4952+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
4953+ return -EINVAL;
4954+ }
4955+
4956+ SG_INIT(sg, data32, data_i, data_l);
4957+
4958+ CVMX_PREFETCH0(ivp);
4959+ CVMX_PREFETCH0(od->octo_enckey);
4960+
4961+ flags = octeon_crypto_enable(&state);
4962+
4963+ /* load 3DES Key */
4964+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
4965+ if (od->octo_encklen == 24) {
4966+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
4967+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
4968+ } else if (od->octo_encklen == 8) {
4969+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
4970+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
4971+ } else {
4972+ octeon_crypto_disable(&state, flags);
4973+ dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
4974+ return -EINVAL;
4975+ }
4976+
4977+ CVMX_MT_3DES_IV(* (uint64_t *) ivp);
4978+
4979+ /* Load MD5 IV */
4980+ CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
4981+ CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
4982+
4983+ while (crypt_off > 0 && auth_off > 0) {
4984+ SG_CONSUME(sg, data32, data_i, data_l);
4985+ crypt_off -= 4;
4986+ auth_off -= 4;
4987+ }
4988+
4989+ while (crypt_len > 0 || auth_len > 0) {
4990+ uint32_t *first = data32;
4991+ mydata.data32[0] = *first;
4992+ SG_CONSUME(sg, data32, data_i, data_l);
4993+ mydata.data32[1] = *data32;
4994+ if (auth_off <= 0) {
4995+ if (auth_len > 0) {
4996+ CVM_LOAD_MD5_UNIT(*data, next);
4997+ auth_len -= 8;
4998+ }
4999+ } else
5000+ auth_off -= 8;
5001+ if (crypt_off <= 0) {
5002+ if (crypt_len > 0) {
5003+ CVMX_MT_3DES_DEC_CBC(*data);
5004+ CVMX_MF_3DES_RESULT(*data);
5005+ crypt_len -= 8;
5006+ }
5007+ } else
5008+ crypt_off -= 8;
5009+ *first = mydata.data32[0];
5010+ *data32 = mydata.data32[1];
5011+ SG_CONSUME(sg, data32, data_i, data_l);
5012+ }
5013+
5014+ /* finish the hash */
5015+ CVMX_PREFETCH0(od->octo_hmouter);
5016+#if 0
5017+ if (unlikely(inplen)) {
5018+ uint64_t tmp = 0;
5019+ uint8_t *p = (uint8_t *) & tmp;
5020+ p[inplen] = 0x80;
5021+ do {
5022+ inplen--;
5023+ p[inplen] = ((uint8_t *) data)[inplen];
5024+ } while (inplen);
5025+ CVM_LOAD_MD5_UNIT(tmp, next);
5026+ } else {
5027+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
5028+ }
5029+#else
5030+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
5031+#endif
5032+
5033+ /* Finish Inner hash */
5034+ while (next != 7) {
5035+ CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
5036+ }
5037+ CVMX_ES64(tmp1, ((alen + 64) << 3));
5038+ CVM_LOAD_MD5_UNIT(tmp1, next);
5039+
5040+ /* Get the inner hash of HMAC */
5041+ CVMX_MF_HSH_IV(tmp1, 0);
5042+ CVMX_MF_HSH_IV(tmp2, 1);
5043+
5044+ /* Initialize hash unit */
5045+ CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
5046+ CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
5047+
5048+ CVMX_MT_HSH_DAT(tmp1, 0);
5049+ CVMX_MT_HSH_DAT(tmp2, 1);
5050+ CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
5051+ CVMX_MT_HSH_DATZ(3);
5052+ CVMX_MT_HSH_DATZ(4);
5053+ CVMX_MT_HSH_DATZ(5);
5054+ CVMX_MT_HSH_DATZ(6);
5055+ CVMX_ES64(tmp1, ((64 + 16) << 3));
5056+ CVMX_MT_HSH_STARTMD5(tmp1);
5057+
5058+ /* save the HMAC */
5059+ SG_INIT(sg, data32, data_i, data_l);
5060+ while (icv_off > 0) {
5061+ SG_CONSUME(sg, data32, data_i, data_l);
5062+ icv_off -= 4;
5063+ }
5064+ CVMX_MF_HSH_IV(tmp1, 0);
5065+ *data32 = (uint32_t) (tmp1 >> 32);
5066+ SG_CONSUME(sg, data32, data_i, data_l);
5067+ *data32 = (uint32_t) tmp1;
5068+ SG_CONSUME(sg, data32, data_i, data_l);
5069+ CVMX_MF_HSH_IV(tmp1, 1);
5070+ *data32 = (uint32_t) (tmp1 >> 32);
5071+
5072+ octeon_crypto_disable(&state, flags);
5073+ return 0;
5074+}
5075+
5076+/****************************************************************************/
5077+/* DES SHA */
5078+
5079+int
5080+octo_des_cbc_sha1_encrypt(
5081+ struct octo_sess *od,
5082+ struct scatterlist *sg, int sg_len,
5083+ int auth_off, int auth_len,
5084+ int crypt_off, int crypt_len,
5085+ int icv_off, uint8_t *ivp)
5086+{
5087+ register int next = 0;
5088+ union {
5089+ uint32_t data32[2];
5090+ uint64_t data64[1];
5091+ } mydata;
5092+ uint64_t *data = &mydata.data64[0];
5093+ uint32_t *data32;
5094+ uint64_t tmp1, tmp2, tmp3;
5095+ int data_i, data_l, alen = auth_len;
5096+ struct octeon_cop2_state state;
5097+ unsigned long flags;
5098+
5099+ dprintk("%s()\n", __FUNCTION__);
5100+
5101+ if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
5102+ (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
5103+ (crypt_len & 0x7) ||
5104+ (auth_len & 0x7) ||
5105+ (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
5106+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
5107+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
5108+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
5109+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
5110+ return -EINVAL;
5111+ }
5112+
5113+ SG_INIT(sg, data32, data_i, data_l);
5114+
5115+ CVMX_PREFETCH0(ivp);
5116+ CVMX_PREFETCH0(od->octo_enckey);
5117+
5118+ flags = octeon_crypto_enable(&state);
5119+
5120+ /* load 3DES Key */
5121+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
5122+ if (od->octo_encklen == 24) {
5123+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
5124+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
5125+ } else if (od->octo_encklen == 8) {
5126+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
5127+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
5128+ } else {
5129+ octeon_crypto_disable(&state, flags);
5130+ dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
5131+ return -EINVAL;
5132+ }
5133+
5134+ CVMX_MT_3DES_IV(* (uint64_t *) ivp);
5135+
5136+ /* Load SHA1 IV */
5137+ CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
5138+ CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
5139+ CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
5140+
5141+ while (crypt_off > 0 && auth_off > 0) {
5142+ SG_CONSUME(sg, data32, data_i, data_l);
5143+ crypt_off -= 4;
5144+ auth_off -= 4;
5145+ }
5146+
5147+ while (crypt_len > 0 || auth_len > 0) {
5148+ uint32_t *first = data32;
5149+ mydata.data32[0] = *first;
5150+ SG_CONSUME(sg, data32, data_i, data_l);
5151+ mydata.data32[1] = *data32;
5152+ if (crypt_off <= 0) {
5153+ if (crypt_len > 0) {
5154+ CVMX_MT_3DES_ENC_CBC(*data);
5155+ CVMX_MF_3DES_RESULT(*data);
5156+ crypt_len -= 8;
5157+ }
5158+ } else
5159+ crypt_off -= 8;
5160+ if (auth_off <= 0) {
5161+ if (auth_len > 0) {
5162+ CVM_LOAD_SHA_UNIT(*data, next);
5163+ auth_len -= 8;
5164+ }
5165+ } else
5166+ auth_off -= 8;
5167+ *first = mydata.data32[0];
5168+ *data32 = mydata.data32[1];
5169+ SG_CONSUME(sg, data32, data_i, data_l);
5170+ }
5171+
5172+ /* finish the hash */
5173+ CVMX_PREFETCH0(od->octo_hmouter);
5174+#if 0
5175+ if (unlikely(inplen)) {
5176+ uint64_t tmp = 0;
5177+ uint8_t *p = (uint8_t *) & tmp;
5178+ p[inplen] = 0x80;
5179+ do {
5180+ inplen--;
5181+ p[inplen] = ((uint8_t *) data)[inplen];
5182+ } while (inplen);
5183+ CVM_LOAD_SHA_UNIT(tmp, next);
5184+ } else {
5185+ CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
5186+ }
5187+#else
5188+ CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
5189+#endif
5190+
5191+ /* Finish Inner hash */
5192+ while (next != 7) {
5193+ CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
5194+ }
5195+ CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
5196+
5197+ /* Get the inner hash of HMAC */
5198+ CVMX_MF_HSH_IV(tmp1, 0);
5199+ CVMX_MF_HSH_IV(tmp2, 1);
5200+ tmp3 = 0;
5201+ CVMX_MF_HSH_IV(tmp3, 2);
5202+
5203+ /* Initialize hash unit */
5204+ CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
5205+ CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
5206+ CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
5207+
5208+ CVMX_MT_HSH_DAT(tmp1, 0);
5209+ CVMX_MT_HSH_DAT(tmp2, 1);
5210+ tmp3 |= 0x0000000080000000;
5211+ CVMX_MT_HSH_DAT(tmp3, 2);
5212+ CVMX_MT_HSH_DATZ(3);
5213+ CVMX_MT_HSH_DATZ(4);
5214+ CVMX_MT_HSH_DATZ(5);
5215+ CVMX_MT_HSH_DATZ(6);
5216+ CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
5217+
5218+ /* save the HMAC */
5219+ SG_INIT(sg, data32, data_i, data_l);
5220+ while (icv_off > 0) {
5221+ SG_CONSUME(sg, data32, data_i, data_l);
5222+ icv_off -= 4;
5223+ }
5224+ CVMX_MF_HSH_IV(tmp1, 0);
5225+ *data32 = (uint32_t) (tmp1 >> 32);
5226+ SG_CONSUME(sg, data32, data_i, data_l);
5227+ *data32 = (uint32_t) tmp1;
5228+ SG_CONSUME(sg, data32, data_i, data_l);
5229+ CVMX_MF_HSH_IV(tmp1, 1);
5230+ *data32 = (uint32_t) (tmp1 >> 32);
5231+
5232+ octeon_crypto_disable(&state, flags);
5233+ return 0;
5234+}
5235+
5236+int
5237+octo_des_cbc_sha1_decrypt(
5238+ struct octo_sess *od,
5239+ struct scatterlist *sg, int sg_len,
5240+ int auth_off, int auth_len,
5241+ int crypt_off, int crypt_len,
5242+ int icv_off, uint8_t *ivp)
5243+{
5244+ register int next = 0;
5245+ union {
5246+ uint32_t data32[2];
5247+ uint64_t data64[1];
5248+ } mydata;
5249+ uint64_t *data = &mydata.data64[0];
5250+ uint32_t *data32;
5251+ uint64_t tmp1, tmp2, tmp3;
5252+ int data_i, data_l, alen = auth_len;
5253+ struct octeon_cop2_state state;
5254+ unsigned long flags;
5255+
5256+ dprintk("%s()\n", __FUNCTION__);
5257+
5258+ if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
5259+ (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
5260+ (crypt_len & 0x7) ||
5261+ (auth_len & 0x7) ||
5262+ (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
5263+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
5264+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
5265+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
5266+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
5267+ return -EINVAL;
5268+ }
5269+
5270+ SG_INIT(sg, data32, data_i, data_l);
5271+
5272+ CVMX_PREFETCH0(ivp);
5273+ CVMX_PREFETCH0(od->octo_enckey);
5274+
5275+ flags = octeon_crypto_enable(&state);
5276+
5277+ /* load 3DES Key */
5278+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
5279+ if (od->octo_encklen == 24) {
5280+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
5281+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
5282+ } else if (od->octo_encklen == 8) {
5283+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
5284+ CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
5285+ } else {
5286+ octeon_crypto_disable(&state, flags);
5287+ dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
5288+ return -EINVAL;
5289+ }
5290+
5291+ CVMX_MT_3DES_IV(* (uint64_t *) ivp);
5292+
5293+ /* Load SHA1 IV */
5294+ CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
5295+ CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
5296+ CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
5297+
5298+ while (crypt_off > 0 && auth_off > 0) {
5299+ SG_CONSUME(sg, data32, data_i, data_l);
5300+ crypt_off -= 4;
5301+ auth_off -= 4;
5302+ }
5303+
5304+ while (crypt_len > 0 || auth_len > 0) {
5305+ uint32_t *first = data32;
5306+ mydata.data32[0] = *first;
5307+ SG_CONSUME(sg, data32, data_i, data_l);
5308+ mydata.data32[1] = *data32;
5309+ if (auth_off <= 0) {
5310+ if (auth_len > 0) {
5311+ CVM_LOAD_SHA_UNIT(*data, next);
5312+ auth_len -= 8;
5313+ }
5314+ } else
5315+ auth_off -= 8;
5316+ if (crypt_off <= 0) {
5317+ if (crypt_len > 0) {
5318+ CVMX_MT_3DES_DEC_CBC(*data);
5319+ CVMX_MF_3DES_RESULT(*data);
5320+ crypt_len -= 8;
5321+ }
5322+ } else
5323+ crypt_off -= 8;
5324+ *first = mydata.data32[0];
5325+ *data32 = mydata.data32[1];
5326+ SG_CONSUME(sg, data32, data_i, data_l);
5327+ }
5328+
5329+ /* finish the hash */
5330+ CVMX_PREFETCH0(od->octo_hmouter);
5331+#if 0
5332+ if (unlikely(inplen)) {
5333+ uint64_t tmp = 0;
5334+ uint8_t *p = (uint8_t *) & tmp;
5335+ p[inplen] = 0x80;
5336+ do {
5337+ inplen--;
5338+ p[inplen] = ((uint8_t *) data)[inplen];
5339+ } while (inplen);
5340+ CVM_LOAD_SHA_UNIT(tmp, next);
5341+ } else {
5342+ CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
5343+ }
5344+#else
5345+ CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
5346+#endif
5347+
5348+ /* Finish Inner hash */
5349+ while (next != 7) {
5350+ CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
5351+ }
5352+ CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
5353+
5354+ /* Get the inner hash of HMAC */
5355+ CVMX_MF_HSH_IV(tmp1, 0);
5356+ CVMX_MF_HSH_IV(tmp2, 1);
5357+ tmp3 = 0;
5358+ CVMX_MF_HSH_IV(tmp3, 2);
5359+
5360+ /* Initialize hash unit */
5361+ CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
5362+ CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
5363+ CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
5364+
5365+ CVMX_MT_HSH_DAT(tmp1, 0);
5366+ CVMX_MT_HSH_DAT(tmp2, 1);
5367+ tmp3 |= 0x0000000080000000;
5368+ CVMX_MT_HSH_DAT(tmp3, 2);
5369+ CVMX_MT_HSH_DATZ(3);
5370+ CVMX_MT_HSH_DATZ(4);
5371+ CVMX_MT_HSH_DATZ(5);
5372+ CVMX_MT_HSH_DATZ(6);
5373+ CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
5374+ /* save the HMAC */
5375+ SG_INIT(sg, data32, data_i, data_l);
5376+ while (icv_off > 0) {
5377+ SG_CONSUME(sg, data32, data_i, data_l);
5378+ icv_off -= 4;
5379+ }
5380+ CVMX_MF_HSH_IV(tmp1, 0);
5381+ *data32 = (uint32_t) (tmp1 >> 32);
5382+ SG_CONSUME(sg, data32, data_i, data_l);
5383+ *data32 = (uint32_t) tmp1;
5384+ SG_CONSUME(sg, data32, data_i, data_l);
5385+ CVMX_MF_HSH_IV(tmp1, 1);
5386+ *data32 = (uint32_t) (tmp1 >> 32);
5387+
5388+ octeon_crypto_disable(&state, flags);
5389+ return 0;
5390+}
5391+
5392+/****************************************************************************/
5393+/* AES MD5 */
5394+
5395+int
5396+octo_aes_cbc_md5_encrypt(
5397+ struct octo_sess *od,
5398+ struct scatterlist *sg, int sg_len,
5399+ int auth_off, int auth_len,
5400+ int crypt_off, int crypt_len,
5401+ int icv_off, uint8_t *ivp)
5402+{
5403+ register int next = 0;
5404+ union {
5405+ uint32_t data32[2];
5406+ uint64_t data64[1];
5407+ } mydata[2];
5408+ uint64_t *pdata = &mydata[0].data64[0];
5409+ uint64_t *data = &mydata[1].data64[0];
5410+ uint32_t *data32;
5411+ uint64_t tmp1, tmp2;
5412+ int data_i, data_l, alen = auth_len;
5413+ struct octeon_cop2_state state;
5414+ unsigned long flags;
5415+
5416+ dprintk("%s()\n", __FUNCTION__);
5417+
5418+ if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
5419+ (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
5420+ (crypt_len & 0x7) ||
5421+ (auth_len & 0x7) ||
5422+ (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
5423+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
5424+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
5425+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
5426+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
5427+ return -EINVAL;
5428+ }
5429+
5430+ SG_INIT(sg, data32, data_i, data_l);
5431+
5432+ CVMX_PREFETCH0(ivp);
5433+ CVMX_PREFETCH0(od->octo_enckey);
5434+
5435+ flags = octeon_crypto_enable(&state);
5436+
5437+ /* load AES Key */
5438+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
5439+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
5440+
5441+ if (od->octo_encklen == 16) {
5442+ CVMX_MT_AES_KEY(0x0, 2);
5443+ CVMX_MT_AES_KEY(0x0, 3);
5444+ } else if (od->octo_encklen == 24) {
5445+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
5446+ CVMX_MT_AES_KEY(0x0, 3);
5447+ } else if (od->octo_encklen == 32) {
5448+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
5449+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
5450+ } else {
5451+ octeon_crypto_disable(&state, flags);
5452+ dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
5453+ return -EINVAL;
5454+ }
5455+ CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
5456+
5457+ CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
5458+ CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
5459+
5460+ /* Load MD5 IV */
5461+ CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
5462+ CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
5463+
5464+ while (crypt_off > 0 && auth_off > 0) {
5465+ SG_CONSUME(sg, data32, data_i, data_l);
5466+ crypt_off -= 4;
5467+ auth_off -= 4;
5468+ }
5469+
5470+ /* align auth and crypt */
5471+ while (crypt_off > 0 && auth_len > 0) {
5472+ mydata[0].data32[0] = *data32;
5473+ SG_CONSUME(sg, data32, data_i, data_l);
5474+ mydata[0].data32[1] = *data32;
5475+ SG_CONSUME(sg, data32, data_i, data_l);
5476+ CVM_LOAD_MD5_UNIT(*pdata, next);
5477+ crypt_off -= 8;
5478+ auth_len -= 8;
5479+ }
5480+
5481+ while (crypt_len > 0) {
5482+ uint32_t *pdata32[3];
5483+
5484+ pdata32[0] = data32;
5485+ mydata[0].data32[0] = *data32;
5486+ SG_CONSUME(sg, data32, data_i, data_l);
5487+
5488+ pdata32[1] = data32;
5489+ mydata[0].data32[1] = *data32;
5490+ SG_CONSUME(sg, data32, data_i, data_l);
5491+
5492+ pdata32[2] = data32;
5493+ mydata[1].data32[0] = *data32;
5494+ SG_CONSUME(sg, data32, data_i, data_l);
5495+
5496+ mydata[1].data32[1] = *data32;
5497+
5498+ CVMX_MT_AES_ENC_CBC0(*pdata);
5499+ CVMX_MT_AES_ENC_CBC1(*data);
5500+ CVMX_MF_AES_RESULT(*pdata, 0);
5501+ CVMX_MF_AES_RESULT(*data, 1);
5502+ crypt_len -= 16;
5503+
5504+ if (auth_len > 0) {
5505+ CVM_LOAD_MD5_UNIT(*pdata, next);
5506+ auth_len -= 8;
5507+ }
5508+ if (auth_len > 0) {
5509+ CVM_LOAD_MD5_UNIT(*data, next);
5510+ auth_len -= 8;
5511+ }
5512+
5513+ *pdata32[0] = mydata[0].data32[0];
5514+ *pdata32[1] = mydata[0].data32[1];
5515+ *pdata32[2] = mydata[1].data32[0];
5516+ *data32 = mydata[1].data32[1];
5517+
5518+ SG_CONSUME(sg, data32, data_i, data_l);
5519+ }
5520+
5521+ /* finish any left over hashing */
5522+ while (auth_len > 0) {
5523+ mydata[0].data32[0] = *data32;
5524+ SG_CONSUME(sg, data32, data_i, data_l);
5525+ mydata[0].data32[1] = *data32;
5526+ SG_CONSUME(sg, data32, data_i, data_l);
5527+ CVM_LOAD_MD5_UNIT(*pdata, next);
5528+ auth_len -= 8;
5529+ }
5530+
5531+ /* finish the hash */
5532+ CVMX_PREFETCH0(od->octo_hmouter);
5533+#if 0
5534+ if (unlikely(inplen)) {
5535+ uint64_t tmp = 0;
5536+ uint8_t *p = (uint8_t *) & tmp;
5537+ p[inplen] = 0x80;
5538+ do {
5539+ inplen--;
5540+ p[inplen] = ((uint8_t *) data)[inplen];
5541+ } while (inplen);
5542+ CVM_LOAD_MD5_UNIT(tmp, next);
5543+ } else {
5544+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
5545+ }
5546+#else
5547+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
5548+#endif
5549+
5550+ /* Finish Inner hash */
5551+ while (next != 7) {
5552+ CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
5553+ }
5554+ CVMX_ES64(tmp1, ((alen + 64) << 3));
5555+ CVM_LOAD_MD5_UNIT(tmp1, next);
5556+
5557+ /* Get the inner hash of HMAC */
5558+ CVMX_MF_HSH_IV(tmp1, 0);
5559+ CVMX_MF_HSH_IV(tmp2, 1);
5560+
5561+ /* Initialize hash unit */
5562+ CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
5563+ CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
5564+
5565+ CVMX_MT_HSH_DAT(tmp1, 0);
5566+ CVMX_MT_HSH_DAT(tmp2, 1);
5567+ CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
5568+ CVMX_MT_HSH_DATZ(3);
5569+ CVMX_MT_HSH_DATZ(4);
5570+ CVMX_MT_HSH_DATZ(5);
5571+ CVMX_MT_HSH_DATZ(6);
5572+ CVMX_ES64(tmp1, ((64 + 16) << 3));
5573+ CVMX_MT_HSH_STARTMD5(tmp1);
5574+
5575+ /* save the HMAC */
5576+ SG_INIT(sg, data32, data_i, data_l);
5577+ while (icv_off > 0) {
5578+ SG_CONSUME(sg, data32, data_i, data_l);
5579+ icv_off -= 4;
5580+ }
5581+ CVMX_MF_HSH_IV(tmp1, 0);
5582+ *data32 = (uint32_t) (tmp1 >> 32);
5583+ SG_CONSUME(sg, data32, data_i, data_l);
5584+ *data32 = (uint32_t) tmp1;
5585+ SG_CONSUME(sg, data32, data_i, data_l);
5586+ CVMX_MF_HSH_IV(tmp1, 1);
5587+ *data32 = (uint32_t) (tmp1 >> 32);
5588+
5589+ octeon_crypto_disable(&state, flags);
5590+ return 0;
5591+}
5592+
5593+int
5594+octo_aes_cbc_md5_decrypt(
5595+ struct octo_sess *od,
5596+ struct scatterlist *sg, int sg_len,
5597+ int auth_off, int auth_len,
5598+ int crypt_off, int crypt_len,
5599+ int icv_off, uint8_t *ivp)
5600+{
5601+ register int next = 0;
5602+ union {
5603+ uint32_t data32[2];
5604+ uint64_t data64[1];
5605+ } mydata[2];
5606+ uint64_t *pdata = &mydata[0].data64[0];
5607+ uint64_t *data = &mydata[1].data64[0];
5608+ uint32_t *data32;
5609+ uint64_t tmp1, tmp2;
5610+ int data_i, data_l, alen = auth_len;
5611+ struct octeon_cop2_state state;
5612+ unsigned long flags;
5613+
5614+ dprintk("%s()\n", __FUNCTION__);
5615+
5616+ if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
5617+ (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
5618+ (crypt_len & 0x7) ||
5619+ (auth_len & 0x7) ||
5620+ (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
5621+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
5622+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
5623+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
5624+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
5625+ return -EINVAL;
5626+ }
5627+
5628+ SG_INIT(sg, data32, data_i, data_l);
5629+
5630+ CVMX_PREFETCH0(ivp);
5631+ CVMX_PREFETCH0(od->octo_enckey);
5632+
5633+ flags = octeon_crypto_enable(&state);
5634+
5635+ /* load AES Key */
5636+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
5637+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
5638+
5639+ if (od->octo_encklen == 16) {
5640+ CVMX_MT_AES_KEY(0x0, 2);
5641+ CVMX_MT_AES_KEY(0x0, 3);
5642+ } else if (od->octo_encklen == 24) {
5643+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
5644+ CVMX_MT_AES_KEY(0x0, 3);
5645+ } else if (od->octo_encklen == 32) {
5646+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
5647+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
5648+ } else {
5649+ octeon_crypto_disable(&state, flags);
5650+ dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
5651+ return -EINVAL;
5652+ }
5653+ CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
5654+
5655+ CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
5656+ CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
5657+
5658+ /* Load MD5 IV */
5659+ CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
5660+ CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
5661+
5662+ while (crypt_off > 0 && auth_off > 0) {
5663+ SG_CONSUME(sg, data32, data_i, data_l);
5664+ crypt_off -= 4;
5665+ auth_off -= 4;
5666+ }
5667+
5668+ /* align auth and crypt */
5669+ while (crypt_off > 0 && auth_len > 0) {
5670+ mydata[0].data32[0] = *data32;
5671+ SG_CONSUME(sg, data32, data_i, data_l);
5672+ mydata[0].data32[1] = *data32;
5673+ SG_CONSUME(sg, data32, data_i, data_l);
5674+ CVM_LOAD_MD5_UNIT(*pdata, next);
5675+ crypt_off -= 8;
5676+ auth_len -= 8;
5677+ }
5678+
5679+ while (crypt_len > 0) {
5680+ uint32_t *pdata32[3];
5681+
5682+ pdata32[0] = data32;
5683+ mydata[0].data32[0] = *data32;
5684+ SG_CONSUME(sg, data32, data_i, data_l);
5685+ pdata32[1] = data32;
5686+ mydata[0].data32[1] = *data32;
5687+ SG_CONSUME(sg, data32, data_i, data_l);
5688+ pdata32[2] = data32;
5689+ mydata[1].data32[0] = *data32;
5690+ SG_CONSUME(sg, data32, data_i, data_l);
5691+ mydata[1].data32[1] = *data32;
5692+
5693+ if (auth_len > 0) {
5694+ CVM_LOAD_MD5_UNIT(*pdata, next);
5695+ auth_len -= 8;
5696+ }
5697+
5698+ if (auth_len > 0) {
5699+ CVM_LOAD_MD5_UNIT(*data, next);
5700+ auth_len -= 8;
5701+ }
5702+
5703+ CVMX_MT_AES_DEC_CBC0(*pdata);
5704+ CVMX_MT_AES_DEC_CBC1(*data);
5705+ CVMX_MF_AES_RESULT(*pdata, 0);
5706+ CVMX_MF_AES_RESULT(*data, 1);
5707+ crypt_len -= 16;
5708+
5709+ *pdata32[0] = mydata[0].data32[0];
5710+ *pdata32[1] = mydata[0].data32[1];
5711+ *pdata32[2] = mydata[1].data32[0];
5712+ *data32 = mydata[1].data32[1];
5713+
5714+ SG_CONSUME(sg, data32, data_i, data_l);
5715+ }
5716+
5717+ /* finish left over hash if any */
5718+ while (auth_len > 0) {
5719+ mydata[0].data32[0] = *data32;
5720+ SG_CONSUME(sg, data32, data_i, data_l);
5721+ mydata[0].data32[1] = *data32;
5722+ SG_CONSUME(sg, data32, data_i, data_l);
5723+ CVM_LOAD_MD5_UNIT(*pdata, next);
5724+ auth_len -= 8;
5725+ }
5726+
5727+
5728+ /* finish the hash */
5729+ CVMX_PREFETCH0(od->octo_hmouter);
5730+#if 0
5731+ if (unlikely(inplen)) {
5732+ uint64_t tmp = 0;
5733+ uint8_t *p = (uint8_t *) & tmp;
5734+ p[inplen] = 0x80;
5735+ do {
5736+ inplen--;
5737+ p[inplen] = ((uint8_t *) data)[inplen];
5738+ } while (inplen);
5739+ CVM_LOAD_MD5_UNIT(tmp, next);
5740+ } else {
5741+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
5742+ }
5743+#else
5744+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
5745+#endif
5746+
5747+ /* Finish Inner hash */
5748+ while (next != 7) {
5749+ CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
5750+ }
5751+ CVMX_ES64(tmp1, ((alen + 64) << 3));
5752+ CVM_LOAD_MD5_UNIT(tmp1, next);
5753+
5754+ /* Get the inner hash of HMAC */
5755+ CVMX_MF_HSH_IV(tmp1, 0);
5756+ CVMX_MF_HSH_IV(tmp2, 1);
5757+
5758+ /* Initialize hash unit */
5759+ CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
5760+ CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
5761+
5762+ CVMX_MT_HSH_DAT(tmp1, 0);
5763+ CVMX_MT_HSH_DAT(tmp2, 1);
5764+ CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
5765+ CVMX_MT_HSH_DATZ(3);
5766+ CVMX_MT_HSH_DATZ(4);
5767+ CVMX_MT_HSH_DATZ(5);
5768+ CVMX_MT_HSH_DATZ(6);
5769+ CVMX_ES64(tmp1, ((64 + 16) << 3));
5770+ CVMX_MT_HSH_STARTMD5(tmp1);
5771+
5772+ /* save the HMAC */
5773+ SG_INIT(sg, data32, data_i, data_l);
5774+ while (icv_off > 0) {
5775+ SG_CONSUME(sg, data32, data_i, data_l);
5776+ icv_off -= 4;
5777+ }
5778+ CVMX_MF_HSH_IV(tmp1, 0);
5779+ *data32 = (uint32_t) (tmp1 >> 32);
5780+ SG_CONSUME(sg, data32, data_i, data_l);
5781+ *data32 = (uint32_t) tmp1;
5782+ SG_CONSUME(sg, data32, data_i, data_l);
5783+ CVMX_MF_HSH_IV(tmp1, 1);
5784+ *data32 = (uint32_t) (tmp1 >> 32);
5785+
5786+ octeon_crypto_disable(&state, flags);
5787+ return 0;
5788+}
5789+
5790+/****************************************************************************/
5791+/* AES SHA1 */
5792+
5793+int
5794+octo_aes_cbc_sha1_encrypt(
5795+ struct octo_sess *od,
5796+ struct scatterlist *sg, int sg_len,
5797+ int auth_off, int auth_len,
5798+ int crypt_off, int crypt_len,
5799+ int icv_off, uint8_t *ivp)
5800+{
5801+ register int next = 0;
5802+ union {
5803+ uint32_t data32[2];
5804+ uint64_t data64[1];
5805+ } mydata[2];
5806+ uint64_t *pdata = &mydata[0].data64[0];
5807+ uint64_t *data = &mydata[1].data64[0];
5808+ uint32_t *data32;
5809+ uint64_t tmp1, tmp2, tmp3;
5810+ int data_i, data_l, alen = auth_len;
5811+ struct octeon_cop2_state state;
5812+ unsigned long flags;
5813+
5814+ dprintk("%s(a_off=%d a_len=%d c_off=%d c_len=%d icv_off=%d)\n",
5815+ __FUNCTION__, auth_off, auth_len, crypt_off, crypt_len, icv_off);
5816+
5817+ if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
5818+ (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
5819+ (crypt_len & 0x7) ||
5820+ (auth_len & 0x7) ||
5821+ (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
5822+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
5823+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
5824+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
5825+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
5826+ return -EINVAL;
5827+ }
5828+
5829+ SG_INIT(sg, data32, data_i, data_l);
5830+
5831+ CVMX_PREFETCH0(ivp);
5832+ CVMX_PREFETCH0(od->octo_enckey);
5833+
5834+ flags = octeon_crypto_enable(&state);
5835+
5836+ /* load AES Key */
5837+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
5838+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
5839+
5840+ if (od->octo_encklen == 16) {
5841+ CVMX_MT_AES_KEY(0x0, 2);
5842+ CVMX_MT_AES_KEY(0x0, 3);
5843+ } else if (od->octo_encklen == 24) {
5844+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
5845+ CVMX_MT_AES_KEY(0x0, 3);
5846+ } else if (od->octo_encklen == 32) {
5847+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
5848+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
5849+ } else {
5850+ octeon_crypto_disable(&state, flags);
5851+ dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
5852+ return -EINVAL;
5853+ }
5854+ CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
5855+
5856+ CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
5857+ CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
5858+
5859+ /* Load SHA IV */
5860+ CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
5861+ CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
5862+ CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
5863+
5864+ while (crypt_off > 0 && auth_off > 0) {
5865+ SG_CONSUME(sg, data32, data_i, data_l);
5866+ crypt_off -= 4;
5867+ auth_off -= 4;
5868+ }
5869+
5870+ /* align auth and crypt */
5871+ while (crypt_off > 0 && auth_len > 0) {
5872+ mydata[0].data32[0] = *data32;
5873+ SG_CONSUME(sg, data32, data_i, data_l);
5874+ mydata[0].data32[1] = *data32;
5875+ SG_CONSUME(sg, data32, data_i, data_l);
5876+ CVM_LOAD_SHA_UNIT(*pdata, next);
5877+ crypt_off -= 8;
5878+ auth_len -= 8;
5879+ }
5880+
5881+ while (crypt_len > 0) {
5882+ uint32_t *pdata32[3];
5883+
5884+ pdata32[0] = data32;
5885+ mydata[0].data32[0] = *data32;
5886+ SG_CONSUME(sg, data32, data_i, data_l);
5887+ pdata32[1] = data32;
5888+ mydata[0].data32[1] = *data32;
5889+ SG_CONSUME(sg, data32, data_i, data_l);
5890+ pdata32[2] = data32;
5891+ mydata[1].data32[0] = *data32;
5892+ SG_CONSUME(sg, data32, data_i, data_l);
5893+ mydata[1].data32[1] = *data32;
5894+
5895+ CVMX_MT_AES_ENC_CBC0(*pdata);
5896+ CVMX_MT_AES_ENC_CBC1(*data);
5897+ CVMX_MF_AES_RESULT(*pdata, 0);
5898+ CVMX_MF_AES_RESULT(*data, 1);
5899+ crypt_len -= 16;
5900+
5901+ if (auth_len > 0) {
5902+ CVM_LOAD_SHA_UNIT(*pdata, next);
5903+ auth_len -= 8;
5904+ }
5905+ if (auth_len > 0) {
5906+ CVM_LOAD_SHA_UNIT(*data, next);
5907+ auth_len -= 8;
5908+ }
5909+
5910+ *pdata32[0] = mydata[0].data32[0];
5911+ *pdata32[1] = mydata[0].data32[1];
5912+ *pdata32[2] = mydata[1].data32[0];
5913+ *data32 = mydata[1].data32[1];
5914+
5915+ SG_CONSUME(sg, data32, data_i, data_l);
5916+ }
5917+
5918+ /* finish and hashing */
5919+ while (auth_len > 0) {
5920+ mydata[0].data32[0] = *data32;
5921+ SG_CONSUME(sg, data32, data_i, data_l);
5922+ mydata[0].data32[1] = *data32;
5923+ SG_CONSUME(sg, data32, data_i, data_l);
5924+ CVM_LOAD_SHA_UNIT(*pdata, next);
5925+ auth_len -= 8;
5926+ }
5927+
5928+ /* finish the hash */
5929+ CVMX_PREFETCH0(od->octo_hmouter);
5930+#if 0
5931+ if (unlikely(inplen)) {
5932+ uint64_t tmp = 0;
5933+ uint8_t *p = (uint8_t *) & tmp;
5934+ p[inplen] = 0x80;
5935+ do {
5936+ inplen--;
5937+ p[inplen] = ((uint8_t *) data)[inplen];
5938+ } while (inplen);
5939+ CVM_LOAD_SHA_UNIT(tmp, next);
5940+ } else {
5941+ CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
5942+ }
5943+#else
5944+ CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
5945+#endif
5946+
5947+ /* Finish Inner hash */
5948+ while (next != 7) {
5949+ CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
5950+ }
5951+ CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
5952+
5953+ /* Get the inner hash of HMAC */
5954+ CVMX_MF_HSH_IV(tmp1, 0);
5955+ CVMX_MF_HSH_IV(tmp2, 1);
5956+ tmp3 = 0;
5957+ CVMX_MF_HSH_IV(tmp3, 2);
5958+
5959+ /* Initialize hash unit */
5960+ CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
5961+ CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
5962+ CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
5963+
5964+ CVMX_MT_HSH_DAT(tmp1, 0);
5965+ CVMX_MT_HSH_DAT(tmp2, 1);
5966+ tmp3 |= 0x0000000080000000;
5967+ CVMX_MT_HSH_DAT(tmp3, 2);
5968+ CVMX_MT_HSH_DATZ(3);
5969+ CVMX_MT_HSH_DATZ(4);
5970+ CVMX_MT_HSH_DATZ(5);
5971+ CVMX_MT_HSH_DATZ(6);
5972+ CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
5973+
5974+ /* finish the hash */
5975+ CVMX_PREFETCH0(od->octo_hmouter);
5976+#if 0
5977+ if (unlikely(inplen)) {
5978+ uint64_t tmp = 0;
5979+ uint8_t *p = (uint8_t *) & tmp;
5980+ p[inplen] = 0x80;
5981+ do {
5982+ inplen--;
5983+ p[inplen] = ((uint8_t *) data)[inplen];
5984+ } while (inplen);
5985+ CVM_LOAD_MD5_UNIT(tmp, next);
5986+ } else {
5987+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
5988+ }
5989+#else
5990+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
5991+#endif
5992+
5993+ /* save the HMAC */
5994+ SG_INIT(sg, data32, data_i, data_l);
5995+ while (icv_off > 0) {
5996+ SG_CONSUME(sg, data32, data_i, data_l);
5997+ icv_off -= 4;
5998+ }
5999+ CVMX_MF_HSH_IV(tmp1, 0);
6000+ *data32 = (uint32_t) (tmp1 >> 32);
6001+ SG_CONSUME(sg, data32, data_i, data_l);
6002+ *data32 = (uint32_t) tmp1;
6003+ SG_CONSUME(sg, data32, data_i, data_l);
6004+ CVMX_MF_HSH_IV(tmp1, 1);
6005+ *data32 = (uint32_t) (tmp1 >> 32);
6006+
6007+ octeon_crypto_disable(&state, flags);
6008+ return 0;
6009+}
6010+
6011+int
6012+octo_aes_cbc_sha1_decrypt(
6013+ struct octo_sess *od,
6014+ struct scatterlist *sg, int sg_len,
6015+ int auth_off, int auth_len,
6016+ int crypt_off, int crypt_len,
6017+ int icv_off, uint8_t *ivp)
6018+{
6019+ register int next = 0;
6020+ union {
6021+ uint32_t data32[2];
6022+ uint64_t data64[1];
6023+ } mydata[2];
6024+ uint64_t *pdata = &mydata[0].data64[0];
6025+ uint64_t *data = &mydata[1].data64[0];
6026+ uint32_t *data32;
6027+ uint64_t tmp1, tmp2, tmp3;
6028+ int data_i, data_l, alen = auth_len;
6029+ struct octeon_cop2_state state;
6030+ unsigned long flags;
6031+
6032+ dprintk("%s(a_off=%d a_len=%d c_off=%d c_len=%d icv_off=%d)\n",
6033+ __FUNCTION__, auth_off, auth_len, crypt_off, crypt_len, icv_off);
6034+
6035+ if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
6036+ (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
6037+ (crypt_len & 0x7) ||
6038+ (auth_len & 0x7) ||
6039+ (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
6040+ dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
6041+ "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
6042+ "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
6043+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
6044+ return -EINVAL;
6045+ }
6046+
6047+ SG_INIT(sg, data32, data_i, data_l);
6048+
6049+ CVMX_PREFETCH0(ivp);
6050+ CVMX_PREFETCH0(od->octo_enckey);
6051+
6052+ flags = octeon_crypto_enable(&state);
6053+
6054+ /* load AES Key */
6055+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
6056+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
6057+
6058+ if (od->octo_encklen == 16) {
6059+ CVMX_MT_AES_KEY(0x0, 2);
6060+ CVMX_MT_AES_KEY(0x0, 3);
6061+ } else if (od->octo_encklen == 24) {
6062+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
6063+ CVMX_MT_AES_KEY(0x0, 3);
6064+ } else if (od->octo_encklen == 32) {
6065+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
6066+ CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
6067+ } else {
6068+ octeon_crypto_disable(&state, flags);
6069+ dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
6070+ return -EINVAL;
6071+ }
6072+ CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
6073+
6074+ CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
6075+ CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
6076+
6077+ /* Load SHA1 IV */
6078+ CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
6079+ CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
6080+ CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
6081+
6082+ while (crypt_off > 0 && auth_off > 0) {
6083+ SG_CONSUME(sg, data32, data_i, data_l);
6084+ crypt_off -= 4;
6085+ auth_off -= 4;
6086+ }
6087+
6088+ /* align auth and crypt */
6089+ while (crypt_off > 0 && auth_len > 0) {
6090+ mydata[0].data32[0] = *data32;
6091+ SG_CONSUME(sg, data32, data_i, data_l);
6092+ mydata[0].data32[1] = *data32;
6093+ SG_CONSUME(sg, data32, data_i, data_l);
6094+ CVM_LOAD_SHA_UNIT(*pdata, next);
6095+ crypt_off -= 8;
6096+ auth_len -= 8;
6097+ }
6098+
6099+ while (crypt_len > 0) {
6100+ uint32_t *pdata32[3];
6101+
6102+ pdata32[0] = data32;
6103+ mydata[0].data32[0] = *data32;
6104+ SG_CONSUME(sg, data32, data_i, data_l);
6105+ pdata32[1] = data32;
6106+ mydata[0].data32[1] = *data32;
6107+ SG_CONSUME(sg, data32, data_i, data_l);
6108+ pdata32[2] = data32;
6109+ mydata[1].data32[0] = *data32;
6110+ SG_CONSUME(sg, data32, data_i, data_l);
6111+ mydata[1].data32[1] = *data32;
6112+
6113+ if (auth_len > 0) {
6114+ CVM_LOAD_SHA_UNIT(*pdata, next);
6115+ auth_len -= 8;
6116+ }
6117+ if (auth_len > 0) {
6118+ CVM_LOAD_SHA_UNIT(*data, next);
6119+ auth_len -= 8;
6120+ }
6121+
6122+ CVMX_MT_AES_DEC_CBC0(*pdata);
6123+ CVMX_MT_AES_DEC_CBC1(*data);
6124+ CVMX_MF_AES_RESULT(*pdata, 0);
6125+ CVMX_MF_AES_RESULT(*data, 1);
6126+ crypt_len -= 16;
6127+
6128+ *pdata32[0] = mydata[0].data32[0];
6129+ *pdata32[1] = mydata[0].data32[1];
6130+ *pdata32[2] = mydata[1].data32[0];
6131+ *data32 = mydata[1].data32[1];
6132+
6133+ SG_CONSUME(sg, data32, data_i, data_l);
6134+ }
6135+
6136+ /* finish and leftover hashing */
6137+ while (auth_len > 0) {
6138+ mydata[0].data32[0] = *data32;
6139+ SG_CONSUME(sg, data32, data_i, data_l);
6140+ mydata[0].data32[1] = *data32;
6141+ SG_CONSUME(sg, data32, data_i, data_l);
6142+ CVM_LOAD_SHA_UNIT(*pdata, next);
6143+ auth_len -= 8;
6144+ }
6145+
6146+ /* finish the hash */
6147+ CVMX_PREFETCH0(od->octo_hmouter);
6148+#if 0
6149+ if (unlikely(inplen)) {
6150+ uint64_t tmp = 0;
6151+ uint8_t *p = (uint8_t *) & tmp;
6152+ p[inplen] = 0x80;
6153+ do {
6154+ inplen--;
6155+ p[inplen] = ((uint8_t *) data)[inplen];
6156+ } while (inplen);
6157+ CVM_LOAD_SHA_UNIT(tmp, next);
6158+ } else {
6159+ CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
6160+ }
6161+#else
6162+ CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
6163+#endif
6164+
6165+ /* Finish Inner hash */
6166+ while (next != 7) {
6167+ CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
6168+ }
6169+ CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
6170+
6171+ /* Get the inner hash of HMAC */
6172+ CVMX_MF_HSH_IV(tmp1, 0);
6173+ CVMX_MF_HSH_IV(tmp2, 1);
6174+ tmp3 = 0;
6175+ CVMX_MF_HSH_IV(tmp3, 2);
6176+
6177+ /* Initialize hash unit */
6178+ CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
6179+ CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
6180+ CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
6181+
6182+ CVMX_MT_HSH_DAT(tmp1, 0);
6183+ CVMX_MT_HSH_DAT(tmp2, 1);
6184+ tmp3 |= 0x0000000080000000;
6185+ CVMX_MT_HSH_DAT(tmp3, 2);
6186+ CVMX_MT_HSH_DATZ(3);
6187+ CVMX_MT_HSH_DATZ(4);
6188+ CVMX_MT_HSH_DATZ(5);
6189+ CVMX_MT_HSH_DATZ(6);
6190+ CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
6191+
6192+ /* finish the hash */
6193+ CVMX_PREFETCH0(od->octo_hmouter);
6194+#if 0
6195+ if (unlikely(inplen)) {
6196+ uint64_t tmp = 0;
6197+ uint8_t *p = (uint8_t *) & tmp;
6198+ p[inplen] = 0x80;
6199+ do {
6200+ inplen--;
6201+ p[inplen] = ((uint8_t *) data)[inplen];
6202+ } while (inplen);
6203+ CVM_LOAD_MD5_UNIT(tmp, next);
6204+ } else {
6205+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
6206+ }
6207+#else
6208+ CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
6209+#endif
6210+
6211+ /* save the HMAC */
6212+ SG_INIT(sg, data32, data_i, data_l);
6213+ while (icv_off > 0) {
6214+ SG_CONSUME(sg, data32, data_i, data_l);
6215+ icv_off -= 4;
6216+ }
6217+ CVMX_MF_HSH_IV(tmp1, 0);
6218+ *data32 = (uint32_t) (tmp1 >> 32);
6219+ SG_CONSUME(sg, data32, data_i, data_l);
6220+ *data32 = (uint32_t) tmp1;
6221+ SG_CONSUME(sg, data32, data_i, data_l);
6222+ CVMX_MF_HSH_IV(tmp1, 1);
6223+ *data32 = (uint32_t) (tmp1 >> 32);
6224+
6225+ octeon_crypto_disable(&state, flags);
6226+ return 0;
6227+}
6228+
6229+/****************************************************************************/
6230diff --git a/crypto/ocf/cryptocteon/cryptocteon.c b/crypto/ocf/cryptocteon/cryptocteon.c
6231new file mode 100644
6232index 0000000..9940f59
6233--- /dev/null
6234+++ b/crypto/ocf/cryptocteon/cryptocteon.c
6235@@ -0,0 +1,574 @@
6236+/*
6237+ * Octeon Crypto for OCF
6238+ *
6239+ * Written by David McCullough <david_mccullough@mcafee.com>
6240+ * Copyright (C) 2009-2010 David McCullough
6241+ *
6242+ * LICENSE TERMS
6243+ *
6244+ * The free distribution and use of this software in both source and binary
6245+ * form is allowed (with or without changes) provided that:
6246+ *
6247+ * 1. distributions of this source code include the above copyright
6248+ * notice, this list of conditions and the following disclaimer;
6249+ *
6250+ * 2. distributions in binary form include the above copyright
6251+ * notice, this list of conditions and the following disclaimer
6252+ * in the documentation and/or other associated materials;
6253+ *
6254+ * 3. the copyright holder's name is not used to endorse products
6255+ * built using this software without specific written permission.
6256+ *
6257+ * DISCLAIMER
6258+ *
6259+ * This software is provided 'as is' with no explicit or implied warranties
6260+ * in respect of its properties, including, but not limited to, correctness
6261+ * and/or fitness for purpose.
6262+ * ---------------------------------------------------------------------------
6263+ */
6264+
6265+#ifndef AUTOCONF_INCLUDED
6266+#include <linux/config.h>
6267+#endif
6268+#include <linux/module.h>
6269+#include <linux/init.h>
6270+#include <linux/list.h>
6271+#include <linux/slab.h>
6272+#include <linux/sched.h>
6273+#include <linux/wait.h>
6274+#include <linux/crypto.h>
6275+#include <linux/mm.h>
6276+#include <linux/skbuff.h>
6277+#include <linux/random.h>
6278+#include <linux/scatterlist.h>
6279+
6280+#include <cryptodev.h>
6281+#include <uio.h>
6282+
6283+struct {
6284+ softc_device_decl sc_dev;
6285+} octo_softc;
6286+
6287+#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
6288+
6289+struct octo_sess {
6290+ int octo_encalg;
6291+ #define MAX_CIPHER_KEYLEN 64
6292+ char octo_enckey[MAX_CIPHER_KEYLEN];
6293+ int octo_encklen;
6294+
6295+ int octo_macalg;
6296+ #define MAX_HASH_KEYLEN 64
6297+ char octo_mackey[MAX_HASH_KEYLEN];
6298+ int octo_macklen;
6299+ int octo_mackey_set;
6300+
6301+ int octo_mlen;
6302+ int octo_ivsize;
6303+
6304+#if 0
6305+ int (*octo_decrypt)(struct scatterlist *sg, int sg_len,
6306+ uint8_t *key, int key_len, uint8_t * iv,
6307+ uint64_t *hminner, uint64_t *hmouter);
6308+
6309+ int (*octo_encrypt)(struct scatterlist *sg, int sg_len,
6310+ uint8_t *key, int key_len, uint8_t * iv,
6311+ uint64_t *hminner, uint64_t *hmouter);
6312+#else
6313+ int (*octo_encrypt)(struct octo_sess *od,
6314+ struct scatterlist *sg, int sg_len,
6315+ int auth_off, int auth_len,
6316+ int crypt_off, int crypt_len,
6317+ int icv_off, uint8_t *ivp);
6318+ int (*octo_decrypt)(struct octo_sess *od,
6319+ struct scatterlist *sg, int sg_len,
6320+ int auth_off, int auth_len,
6321+ int crypt_off, int crypt_len,
6322+ int icv_off, uint8_t *ivp);
6323+#endif
6324+
6325+ uint64_t octo_hminner[3];
6326+ uint64_t octo_hmouter[3];
6327+};
6328+
6329+int32_t octo_id = -1;
6330+module_param(octo_id, int, 0444);
6331+MODULE_PARM_DESC(octo_id, "Read-Only OCF ID for cryptocteon driver");
6332+
6333+static struct octo_sess **octo_sessions = NULL;
6334+static u_int32_t octo_sesnum = 0;
6335+
6336+static int octo_process(device_t, struct cryptop *, int);
6337+static int octo_newsession(device_t, u_int32_t *, struct cryptoini *);
6338+static int octo_freesession(device_t, u_int64_t);
6339+
6340+static device_method_t octo_methods = {
6341+ /* crypto device methods */
6342+ DEVMETHOD(cryptodev_newsession, octo_newsession),
6343+ DEVMETHOD(cryptodev_freesession,octo_freesession),
6344+ DEVMETHOD(cryptodev_process, octo_process),
6345+};
6346+
6347+#define debug octo_debug
6348+int octo_debug = 0;
6349+module_param(octo_debug, int, 0644);
6350+MODULE_PARM_DESC(octo_debug, "Enable debug");
6351+
6352+
6353+#include "cavium_crypto.c"
6354+
6355+
6356+/*
6357+ * Generate a new octo session. We artifically limit it to a single
6358+ * hash/cipher or hash-cipher combo just to make it easier, most callers
6359+ * do not expect more than this anyway.
6360+ */
6361+static int
6362+octo_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
6363+{
6364+ struct cryptoini *c, *encini = NULL, *macini = NULL;
6365+ struct octo_sess **ocd;
6366+ int i;
6367+
6368+ dprintk("%s()\n", __FUNCTION__);
6369+ if (sid == NULL || cri == NULL) {
6370+ dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
6371+ return EINVAL;
6372+ }
6373+
6374+ /*
6375+ * To keep it simple, we only handle hash, cipher or hash/cipher in a
6376+ * session, you cannot currently do multiple ciphers/hashes in one
6377+ * session even though it would be possibel to code this driver to
6378+ * handle it.
6379+ */
6380+ for (i = 0, c = cri; c && i < 2; i++) {
6381+ if (c->cri_alg == CRYPTO_MD5_HMAC ||
6382+ c->cri_alg == CRYPTO_SHA1_HMAC ||
6383+ c->cri_alg == CRYPTO_NULL_HMAC) {
6384+ if (macini) {
6385+ break;
6386+ }
6387+ macini = c;
6388+ }
6389+ if (c->cri_alg == CRYPTO_DES_CBC ||
6390+ c->cri_alg == CRYPTO_3DES_CBC ||
6391+ c->cri_alg == CRYPTO_AES_CBC ||
6392+ c->cri_alg == CRYPTO_NULL_CBC) {
6393+ if (encini) {
6394+ break;
6395+ }
6396+ encini = c;
6397+ }
6398+ c = c->cri_next;
6399+ }
6400+ if (!macini && !encini) {
6401+ dprintk("%s,%d - EINVAL bad cipher/hash or combination\n",
6402+ __FILE__, __LINE__);
6403+ return EINVAL;
6404+ }
6405+ if (c) {
6406+ dprintk("%s,%d - EINVAL cannot handle chained cipher/hash combos\n",
6407+ __FILE__, __LINE__);
6408+ return EINVAL;
6409+ }
6410+
6411+ /*
6412+ * So we have something we can do, lets setup the session
6413+ */
6414+
6415+ if (octo_sessions) {
6416+ for (i = 1; i < octo_sesnum; i++)
6417+ if (octo_sessions[i] == NULL)
6418+ break;
6419+ } else
6420+ i = 1; /* NB: to silence compiler warning */
6421+
6422+ if (octo_sessions == NULL || i == octo_sesnum) {
6423+ if (octo_sessions == NULL) {
6424+ i = 1; /* We leave octo_sessions[0] empty */
6425+ octo_sesnum = CRYPTO_SW_SESSIONS;
6426+ } else
6427+ octo_sesnum *= 2;
6428+
6429+ ocd = kmalloc(octo_sesnum * sizeof(struct octo_sess *), SLAB_ATOMIC);
6430+ if (ocd == NULL) {
6431+ /* Reset session number */
6432+ if (octo_sesnum == CRYPTO_SW_SESSIONS)
6433+ octo_sesnum = 0;
6434+ else
6435+ octo_sesnum /= 2;
6436+ dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
6437+ return ENOBUFS;
6438+ }
6439+ memset(ocd, 0, octo_sesnum * sizeof(struct octo_sess *));
6440+
6441+ /* Copy existing sessions */
6442+ if (octo_sessions) {
6443+ memcpy(ocd, octo_sessions,
6444+ (octo_sesnum / 2) * sizeof(struct octo_sess *));
6445+ kfree(octo_sessions);
6446+ }
6447+
6448+ octo_sessions = ocd;
6449+ }
6450+
6451+ ocd = &octo_sessions[i];
6452+ *sid = i;
6453+
6454+
6455+ *ocd = (struct octo_sess *) kmalloc(sizeof(struct octo_sess), SLAB_ATOMIC);
6456+ if (*ocd == NULL) {
6457+ octo_freesession(NULL, i);
6458+ dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
6459+ return ENOBUFS;
6460+ }
6461+ memset(*ocd, 0, sizeof(struct octo_sess));
6462+
6463+ if (encini && encini->cri_key) {
6464+ (*ocd)->octo_encklen = (encini->cri_klen + 7) / 8;
6465+ memcpy((*ocd)->octo_enckey, encini->cri_key, (*ocd)->octo_encklen);
6466+ }
6467+
6468+ if (macini && macini->cri_key) {
6469+ (*ocd)->octo_macklen = (macini->cri_klen + 7) / 8;
6470+ memcpy((*ocd)->octo_mackey, macini->cri_key, (*ocd)->octo_macklen);
6471+ }
6472+
6473+ (*ocd)->octo_mlen = 0;
6474+ if (encini && encini->cri_mlen)
6475+ (*ocd)->octo_mlen = encini->cri_mlen;
6476+ else if (macini && macini->cri_mlen)
6477+ (*ocd)->octo_mlen = macini->cri_mlen;
6478+ else
6479+ (*ocd)->octo_mlen = 12;
6480+
6481+ /*
6482+ * point c at the enc if it exists, otherwise the mac
6483+ */
6484+ c = encini ? encini : macini;
6485+
6486+ switch (c->cri_alg) {
6487+ case CRYPTO_DES_CBC:
6488+ case CRYPTO_3DES_CBC:
6489+ (*ocd)->octo_ivsize = 8;
6490+ switch (macini ? macini->cri_alg : -1) {
6491+ case CRYPTO_MD5_HMAC:
6492+ (*ocd)->octo_encrypt = octo_des_cbc_md5_encrypt;
6493+ (*ocd)->octo_decrypt = octo_des_cbc_md5_decrypt;
6494+ octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
6495+ (*ocd)->octo_hmouter);
6496+ break;
6497+ case CRYPTO_SHA1_HMAC:
6498+ (*ocd)->octo_encrypt = octo_des_cbc_sha1_encrypt;
6499+ (*ocd)->octo_decrypt = octo_des_cbc_sha1_encrypt;
6500+ octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
6501+ (*ocd)->octo_hmouter);
6502+ break;
6503+ case -1:
6504+ (*ocd)->octo_encrypt = octo_des_cbc_encrypt;
6505+ (*ocd)->octo_decrypt = octo_des_cbc_decrypt;
6506+ break;
6507+ default:
6508+ octo_freesession(NULL, i);
6509+ dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
6510+ return EINVAL;
6511+ }
6512+ break;
6513+ case CRYPTO_AES_CBC:
6514+ (*ocd)->octo_ivsize = 16;
6515+ switch (macini ? macini->cri_alg : -1) {
6516+ case CRYPTO_MD5_HMAC:
6517+ (*ocd)->octo_encrypt = octo_aes_cbc_md5_encrypt;
6518+ (*ocd)->octo_decrypt = octo_aes_cbc_md5_decrypt;
6519+ octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
6520+ (*ocd)->octo_hmouter);
6521+ break;
6522+ case CRYPTO_SHA1_HMAC:
6523+ (*ocd)->octo_encrypt = octo_aes_cbc_sha1_encrypt;
6524+ (*ocd)->octo_decrypt = octo_aes_cbc_sha1_decrypt;
6525+ octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
6526+ (*ocd)->octo_hmouter);
6527+ break;
6528+ case -1:
6529+ (*ocd)->octo_encrypt = octo_aes_cbc_encrypt;
6530+ (*ocd)->octo_decrypt = octo_aes_cbc_decrypt;
6531+ break;
6532+ default:
6533+ octo_freesession(NULL, i);
6534+ dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
6535+ return EINVAL;
6536+ }
6537+ break;
6538+ case CRYPTO_MD5_HMAC:
6539+ (*ocd)->octo_encrypt = octo_null_md5_encrypt;
6540+ (*ocd)->octo_decrypt = octo_null_md5_encrypt;
6541+ octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
6542+ (*ocd)->octo_hmouter);
6543+ break;
6544+ case CRYPTO_SHA1_HMAC:
6545+ (*ocd)->octo_encrypt = octo_null_sha1_encrypt;
6546+ (*ocd)->octo_decrypt = octo_null_sha1_encrypt;
6547+ octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
6548+ (*ocd)->octo_hmouter);
6549+ break;
6550+ default:
6551+ octo_freesession(NULL, i);
6552+ dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
6553+ return EINVAL;
6554+ }
6555+
6556+ (*ocd)->octo_encalg = encini ? encini->cri_alg : -1;
6557+ (*ocd)->octo_macalg = macini ? macini->cri_alg : -1;
6558+
6559+ return 0;
6560+}
6561+
6562+/*
6563+ * Free a session.
6564+ */
6565+static int
6566+octo_freesession(device_t dev, u_int64_t tid)
6567+{
6568+ u_int32_t sid = CRYPTO_SESID2LID(tid);
6569+
6570+ dprintk("%s()\n", __FUNCTION__);
6571+ if (sid > octo_sesnum || octo_sessions == NULL ||
6572+ octo_sessions[sid] == NULL) {
6573+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
6574+ return(EINVAL);
6575+ }
6576+
6577+ /* Silently accept and return */
6578+ if (sid == 0)
6579+ return(0);
6580+
6581+ if (octo_sessions[sid])
6582+ kfree(octo_sessions[sid]);
6583+ octo_sessions[sid] = NULL;
6584+ return 0;
6585+}
6586+
6587+/*
6588+ * Process a request.
6589+ */
6590+static int
6591+octo_process(device_t dev, struct cryptop *crp, int hint)
6592+{
6593+ struct cryptodesc *crd;
6594+ struct octo_sess *od;
6595+ u_int32_t lid;
6596+#define SCATTERLIST_MAX 16
6597+ struct scatterlist sg[SCATTERLIST_MAX];
6598+ int sg_num, sg_len;
6599+ struct sk_buff *skb = NULL;
6600+ struct uio *uiop = NULL;
6601+ struct cryptodesc *enccrd = NULL, *maccrd = NULL;
6602+ unsigned char *ivp = NULL;
6603+ unsigned char iv_data[HASH_MAX_LEN];
6604+ int auth_off = 0, auth_len = 0, crypt_off = 0, crypt_len = 0, icv_off = 0;
6605+
6606+ dprintk("%s()\n", __FUNCTION__);
6607+ /* Sanity check */
6608+ if (crp == NULL) {
6609+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
6610+ return EINVAL;
6611+ }
6612+
6613+ crp->crp_etype = 0;
6614+
6615+ if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
6616+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
6617+ crp->crp_etype = EINVAL;
6618+ goto done;
6619+ }
6620+
6621+ lid = crp->crp_sid & 0xffffffff;
6622+ if (lid >= octo_sesnum || lid == 0 || octo_sessions == NULL ||
6623+ octo_sessions[lid] == NULL) {
6624+ crp->crp_etype = ENOENT;
6625+ dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
6626+ goto done;
6627+ }
6628+ od = octo_sessions[lid];
6629+
6630+ /*
6631+ * do some error checking outside of the loop for SKB and IOV processing
6632+ * this leaves us with valid skb or uiop pointers for later
6633+ */
6634+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
6635+ skb = (struct sk_buff *) crp->crp_buf;
6636+ if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
6637+ printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
6638+ skb_shinfo(skb)->nr_frags);
6639+ goto done;
6640+ }
6641+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
6642+ uiop = (struct uio *) crp->crp_buf;
6643+ if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
6644+ printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
6645+ uiop->uio_iovcnt);
6646+ goto done;
6647+ }
6648+ }
6649+
6650+ /* point our enccrd and maccrd appropriately */
6651+ crd = crp->crp_desc;
6652+ if (crd->crd_alg == od->octo_encalg) enccrd = crd;
6653+ if (crd->crd_alg == od->octo_macalg) maccrd = crd;
6654+ crd = crd->crd_next;
6655+ if (crd) {
6656+ if (crd->crd_alg == od->octo_encalg) enccrd = crd;
6657+ if (crd->crd_alg == od->octo_macalg) maccrd = crd;
6658+ crd = crd->crd_next;
6659+ }
6660+ if (crd) {
6661+ crp->crp_etype = EINVAL;
6662+ dprintk("%s,%d: ENOENT - descriptors do not match session\n",
6663+ __FILE__, __LINE__);
6664+ goto done;
6665+ }
6666+
6667+ if (enccrd) {
6668+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
6669+ ivp = enccrd->crd_iv;
6670+ } else {
6671+ ivp = iv_data;
6672+ crypto_copydata(crp->crp_flags, crp->crp_buf,
6673+ enccrd->crd_inject, od->octo_ivsize, (caddr_t) ivp);
6674+ }
6675+
6676+ if (maccrd) {
6677+ auth_off = maccrd->crd_skip;
6678+ auth_len = maccrd->crd_len;
6679+ icv_off = maccrd->crd_inject;
6680+ }
6681+
6682+ crypt_off = enccrd->crd_skip;
6683+ crypt_len = enccrd->crd_len;
6684+ } else { /* if (maccrd) */
6685+ auth_off = maccrd->crd_skip;
6686+ auth_len = maccrd->crd_len;
6687+ icv_off = maccrd->crd_inject;
6688+ }
6689+
6690+
6691+ /*
6692+ * setup the SG list to cover the buffer
6693+ */
6694+ memset(sg, 0, sizeof(sg));
6695+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
6696+ int i, len;
6697+
6698+ sg_num = 0;
6699+ sg_len = 0;
6700+
6701+ len = skb_headlen(skb);
6702+ sg_set_page(&sg[sg_num], virt_to_page(skb->data), len,
6703+ offset_in_page(skb->data));
6704+ sg_len += len;
6705+ sg_num++;
6706+
6707+ for (i = 0; i < skb_shinfo(skb)->nr_frags && sg_num < SCATTERLIST_MAX;
6708+ i++) {
6709+ len = skb_shinfo(skb)->frags[i].size;
6710+ sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page,
6711+ len, skb_shinfo(skb)->frags[i].page_offset);
6712+ sg_len += len;
6713+ sg_num++;
6714+ }
6715+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
6716+ int len;
6717+
6718+ sg_len = 0;
6719+ for (sg_num = 0; sg_len < crp->crp_ilen &&
6720+ sg_num < uiop->uio_iovcnt &&
6721+ sg_num < SCATTERLIST_MAX; sg_num++) {
6722+ len = uiop->uio_iov[sg_num].iov_len;
6723+ sg_set_page(&sg[sg_num],
6724+ virt_to_page(uiop->uio_iov[sg_num].iov_base), len,
6725+ offset_in_page(uiop->uio_iov[sg_num].iov_base));
6726+ sg_len += len;
6727+ }
6728+ } else {
6729+ sg_len = crp->crp_ilen;
6730+ sg_set_page(&sg[0], virt_to_page(crp->crp_buf), sg_len,
6731+ offset_in_page(crp->crp_buf));
6732+ sg_num = 1;
6733+ }
6734+
6735+
6736+ /*
6737+ * setup a new explicit key
6738+ */
6739+ if (enccrd) {
6740+ if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
6741+ od->octo_encklen = (enccrd->crd_klen + 7) / 8;
6742+ memcpy(od->octo_enckey, enccrd->crd_key, od->octo_encklen);
6743+ }
6744+ }
6745+ if (maccrd) {
6746+ if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
6747+ od->octo_macklen = (maccrd->crd_klen + 7) / 8;
6748+ memcpy(od->octo_mackey, maccrd->crd_key, od->octo_macklen);
6749+ od->octo_mackey_set = 0;
6750+ }
6751+ if (!od->octo_mackey_set) {
6752+ octo_calc_hash(maccrd->crd_alg == CRYPTO_MD5_HMAC ? 0 : 1,
6753+ maccrd->crd_key, od->octo_hminner, od->octo_hmouter);
6754+ od->octo_mackey_set = 1;
6755+ }
6756+ }
6757+
6758+
6759+ if (!enccrd || (enccrd->crd_flags & CRD_F_ENCRYPT))
6760+ (*od->octo_encrypt)(od, sg, sg_len,
6761+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
6762+ else
6763+ (*od->octo_decrypt)(od, sg, sg_len,
6764+ auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
6765+
6766+done:
6767+ crypto_done(crp);
6768+ return 0;
6769+}
6770+
6771+static int
6772+cryptocteon_init(void)
6773+{
6774+ dprintk("%s(%p)\n", __FUNCTION__, cryptocteon_init);
6775+
6776+ softc_device_init(&octo_softc, "cryptocteon", 0, octo_methods);
6777+
6778+ octo_id = crypto_get_driverid(softc_get_device(&octo_softc),
6779+ CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SYNC);
6780+ if (octo_id < 0) {
6781+ printk("Cryptocteon device cannot initialize!");
6782+ return -ENODEV;
6783+ }
6784+
6785+ crypto_register(octo_id, CRYPTO_MD5_HMAC, 0,0);
6786+ crypto_register(octo_id, CRYPTO_SHA1_HMAC, 0,0);
6787+ //crypto_register(octo_id, CRYPTO_MD5, 0,0);
6788+ //crypto_register(octo_id, CRYPTO_SHA1, 0,0);
6789+ crypto_register(octo_id, CRYPTO_DES_CBC, 0,0);
6790+ crypto_register(octo_id, CRYPTO_3DES_CBC, 0,0);
6791+ crypto_register(octo_id, CRYPTO_AES_CBC, 0,0);
6792+
6793+ return(0);
6794+}
6795+
6796+static void
6797+cryptocteon_exit(void)
6798+{
6799+ dprintk("%s()\n", __FUNCTION__);
6800+ crypto_unregister_all(octo_id);
6801+ octo_id = -1;
6802+}
6803+
6804+module_init(cryptocteon_init);
6805+module_exit(cryptocteon_exit);
6806+
6807+MODULE_LICENSE("BSD");
6808+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
6809+MODULE_DESCRIPTION("Cryptocteon (OCF module for Cavium OCTEON crypto)");
6810diff --git a/crypto/ocf/cryptodev.c b/crypto/ocf/cryptodev.c
6811new file mode 100644
6812index 0000000..d20da17
6813--- /dev/null
6814+++ b/crypto/ocf/cryptodev.c
6815@@ -0,0 +1,1061 @@
6816+/* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */
6817+
6818+/*-
6819+ * Linux port done by David McCullough <david_mccullough@mcafee.com>
6820+ * Copyright (C) 2006-2010 David McCullough
6821+ * Copyright (C) 2004-2005 Intel Corporation.
6822+ * The license and original author are listed below.
6823+ *
6824+ * Copyright (c) 2001 Theo de Raadt
6825+ * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
6826+ *
6827+ * Redistribution and use in source and binary forms, with or without
6828+ * modification, are permitted provided that the following conditions
6829+ * are met:
6830+ *
6831+ * 1. Redistributions of source code must retain the above copyright
6832+ * notice, this list of conditions and the following disclaimer.
6833+ * 2. Redistributions in binary form must reproduce the above copyright
6834+ * notice, this list of conditions and the following disclaimer in the
6835+ * documentation and/or other materials provided with the distribution.
6836+ * 3. The name of the author may not be used to endorse or promote products
6837+ * derived from this software without specific prior written permission.
6838+ *
6839+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
6840+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
6841+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
6842+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
6843+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
6844+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
6845+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
6846+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6847+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
6848+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6849+ *
6850+ * Effort sponsored in part by the Defense Advanced Research Projects
6851+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
6852+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
6853+ *
6854+__FBSDID("$FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.34 2007/05/09 19:37:02 gnn Exp $");
6855+ */
6856+
6857+#ifndef AUTOCONF_INCLUDED
6858+#include <linux/config.h>
6859+#endif
6860+#include <linux/types.h>
6861+#include <linux/time.h>
6862+#include <linux/delay.h>
6863+#include <linux/list.h>
6864+#include <linux/init.h>
6865+#include <linux/sched.h>
6866+#include <linux/unistd.h>
6867+#include <linux/module.h>
6868+#include <linux/wait.h>
6869+#include <linux/slab.h>
6870+#include <linux/fs.h>
6871+#include <linux/dcache.h>
6872+#include <linux/file.h>
6873+#include <linux/mount.h>
6874+#include <linux/miscdevice.h>
6875+#include <linux/version.h>
6876+#include <asm/uaccess.h>
6877+
6878+#include <cryptodev.h>
6879+#include <uio.h>
6880+
6881+extern asmlinkage long sys_dup(unsigned int fildes);
6882+
6883+#define debug cryptodev_debug
6884+int cryptodev_debug = 0;
6885+module_param(cryptodev_debug, int, 0644);
6886+MODULE_PARM_DESC(cryptodev_debug, "Enable cryptodev debug");
6887+
6888+struct csession_info {
6889+ u_int16_t blocksize;
6890+ u_int16_t minkey, maxkey;
6891+
6892+ u_int16_t keysize;
6893+ /* u_int16_t hashsize; */
6894+ u_int16_t authsize;
6895+ u_int16_t authkey;
6896+ /* u_int16_t ctxsize; */
6897+};
6898+
6899+struct csession {
6900+ struct list_head list;
6901+ u_int64_t sid;
6902+ u_int32_t ses;
6903+
6904+ wait_queue_head_t waitq;
6905+
6906+ u_int32_t cipher;
6907+
6908+ u_int32_t mac;
6909+
6910+ caddr_t key;
6911+ int keylen;
6912+ u_char tmp_iv[EALG_MAX_BLOCK_LEN];
6913+
6914+ caddr_t mackey;
6915+ int mackeylen;
6916+
6917+ struct csession_info info;
6918+
6919+ struct iovec iovec;
6920+ struct uio uio;
6921+ int error;
6922+};
6923+
6924+struct fcrypt {
6925+ struct list_head csessions;
6926+ int sesn;
6927+};
6928+
6929+static struct csession *csefind(struct fcrypt *, u_int);
6930+static int csedelete(struct fcrypt *, struct csession *);
6931+static struct csession *cseadd(struct fcrypt *, struct csession *);
6932+static struct csession *csecreate(struct fcrypt *, u_int64_t,
6933+ struct cryptoini *crie, struct cryptoini *cria, struct csession_info *);
6934+static int csefree(struct csession *);
6935+
6936+static int cryptodev_op(struct csession *, struct crypt_op *);
6937+static int cryptodev_key(struct crypt_kop *);
6938+static int cryptodev_find(struct crypt_find_op *);
6939+
6940+static int cryptodev_cb(void *);
6941+static int cryptodev_open(struct inode *inode, struct file *filp);
6942+
6943+/*
6944+ * Check a crypto identifier to see if it requested
6945+ * a valid crid and it's capabilities match.
6946+ */
6947+static int
6948+checkcrid(int crid)
6949+{
6950+ int hid = crid & ~(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
6951+ int typ = crid & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
6952+ int caps = 0;
6953+
6954+ /* if the user hasn't selected a driver, then just call newsession */
6955+ if (hid == 0 && typ != 0)
6956+ return 0;
6957+
6958+ caps = crypto_getcaps(hid);
6959+
6960+ /* didn't find anything with capabilities */
6961+ if (caps == 0) {
6962+ dprintk("%s: hid=%x typ=%x not matched\n", __FUNCTION__, hid, typ);
6963+ return EINVAL;
6964+ }
6965+
6966+ /* the user didn't specify SW or HW, so the driver is ok */
6967+ if (typ == 0)
6968+ return 0;
6969+
6970+ /* if the type specified didn't match */
6971+ if (typ != (caps & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE))) {
6972+ dprintk("%s: hid=%x typ=%x caps=%x not matched\n", __FUNCTION__,
6973+ hid, typ, caps);
6974+ return EINVAL;
6975+ }
6976+
6977+ return 0;
6978+}
6979+
6980+static int
6981+cryptodev_op(struct csession *cse, struct crypt_op *cop)
6982+{
6983+ struct cryptop *crp = NULL;
6984+ struct cryptodesc *crde = NULL, *crda = NULL;
6985+ int error = 0;
6986+
6987+ dprintk("%s()\n", __FUNCTION__);
6988+ if (cop->len > CRYPTO_MAX_DATA_LEN) {
6989+ dprintk("%s: %d > %d\n", __FUNCTION__, cop->len, CRYPTO_MAX_DATA_LEN);
6990+ return (E2BIG);
6991+ }
6992+
6993+ if (cse->info.blocksize && (cop->len % cse->info.blocksize) != 0) {
6994+ dprintk("%s: blocksize=%d len=%d\n", __FUNCTION__, cse->info.blocksize,
6995+ cop->len);
6996+ return (EINVAL);
6997+ }
6998+
6999+ cse->uio.uio_iov = &cse->iovec;
7000+ cse->uio.uio_iovcnt = 1;
7001+ cse->uio.uio_offset = 0;
7002+#if 0
7003+ cse->uio.uio_resid = cop->len;
7004+ cse->uio.uio_segflg = UIO_SYSSPACE;
7005+ cse->uio.uio_rw = UIO_WRITE;
7006+ cse->uio.uio_td = td;
7007+#endif
7008+ cse->uio.uio_iov[0].iov_len = cop->len;
7009+ if (cse->info.authsize)
7010+ cse->uio.uio_iov[0].iov_len += cse->info.authsize;
7011+ cse->uio.uio_iov[0].iov_base = kmalloc(cse->uio.uio_iov[0].iov_len,
7012+ GFP_KERNEL);
7013+
7014+ if (cse->uio.uio_iov[0].iov_base == NULL) {
7015+ dprintk("%s: iov_base kmalloc(%d) failed\n", __FUNCTION__,
7016+ (int)cse->uio.uio_iov[0].iov_len);
7017+ return (ENOMEM);
7018+ }
7019+
7020+ crp = crypto_getreq((cse->info.blocksize != 0) + (cse->info.authsize != 0));
7021+ if (crp == NULL) {
7022+ dprintk("%s: ENOMEM\n", __FUNCTION__);
7023+ error = ENOMEM;
7024+ goto bail;
7025+ }
7026+
7027+ if (cse->info.authsize && cse->info.blocksize) {
7028+ if (cop->op == COP_ENCRYPT) {
7029+ crde = crp->crp_desc;
7030+ crda = crde->crd_next;
7031+ } else {
7032+ crda = crp->crp_desc;
7033+ crde = crda->crd_next;
7034+ }
7035+ } else if (cse->info.authsize) {
7036+ crda = crp->crp_desc;
7037+ } else if (cse->info.blocksize) {
7038+ crde = crp->crp_desc;
7039+ } else {
7040+ dprintk("%s: bad request\n", __FUNCTION__);
7041+ error = EINVAL;
7042+ goto bail;
7043+ }
7044+
7045+ if ((error = copy_from_user(cse->uio.uio_iov[0].iov_base, cop->src,
7046+ cop->len))) {
7047+ dprintk("%s: bad copy\n", __FUNCTION__);
7048+ goto bail;
7049+ }
7050+
7051+ if (crda) {
7052+ crda->crd_skip = 0;
7053+ crda->crd_len = cop->len;
7054+ crda->crd_inject = cop->len;
7055+
7056+ crda->crd_alg = cse->mac;
7057+ crda->crd_key = cse->mackey;
7058+ crda->crd_klen = cse->mackeylen * 8;
7059+ }
7060+
7061+ if (crde) {
7062+ if (cop->op == COP_ENCRYPT)
7063+ crde->crd_flags |= CRD_F_ENCRYPT;
7064+ else
7065+ crde->crd_flags &= ~CRD_F_ENCRYPT;
7066+ crde->crd_len = cop->len;
7067+ crde->crd_inject = 0;
7068+
7069+ crde->crd_alg = cse->cipher;
7070+ crde->crd_key = cse->key;
7071+ crde->crd_klen = cse->keylen * 8;
7072+ }
7073+
7074+ crp->crp_ilen = cse->uio.uio_iov[0].iov_len;
7075+ crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
7076+ | (cop->flags & COP_F_BATCH);
7077+ crp->crp_buf = (caddr_t)&cse->uio;
7078+ crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;
7079+ crp->crp_sid = cse->sid;
7080+ crp->crp_opaque = (void *)cse;
7081+
7082+ if (cop->iv) {
7083+ if (crde == NULL) {
7084+ error = EINVAL;
7085+ dprintk("%s no crde\n", __FUNCTION__);
7086+ goto bail;
7087+ }
7088+ if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
7089+ error = EINVAL;
7090+ dprintk("%s arc4 with IV\n", __FUNCTION__);
7091+ goto bail;
7092+ }
7093+ if ((error = copy_from_user(cse->tmp_iv, cop->iv,
7094+ cse->info.blocksize))) {
7095+ dprintk("%s bad iv copy\n", __FUNCTION__);
7096+ goto bail;
7097+ }
7098+ memcpy(crde->crd_iv, cse->tmp_iv, cse->info.blocksize);
7099+ crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
7100+ crde->crd_skip = 0;
7101+ } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
7102+ crde->crd_skip = 0;
7103+ } else if (crde) {
7104+ crde->crd_flags |= CRD_F_IV_PRESENT;
7105+ crde->crd_skip = cse->info.blocksize;
7106+ crde->crd_len -= cse->info.blocksize;
7107+ }
7108+
7109+ if (cop->mac && crda == NULL) {
7110+ error = EINVAL;
7111+ dprintk("%s no crda\n", __FUNCTION__);
7112+ goto bail;
7113+ }
7114+
7115+ /*
7116+ * Let the dispatch run unlocked, then, interlock against the
7117+ * callback before checking if the operation completed and going
7118+ * to sleep. This insures drivers don't inherit our lock which
7119+ * results in a lock order reversal between crypto_dispatch forced
7120+ * entry and the crypto_done callback into us.
7121+ */
7122+ error = crypto_dispatch(crp);
7123+ if (error) {
7124+ dprintk("%s error in crypto_dispatch\n", __FUNCTION__);
7125+ goto bail;
7126+ }
7127+
7128+ dprintk("%s about to WAIT\n", __FUNCTION__);
7129+ /*
7130+ * we really need to wait for driver to complete to maintain
7131+ * state, luckily interrupts will be remembered
7132+ */
7133+ do {
7134+ error = wait_event_interruptible(crp->crp_waitq,
7135+ ((crp->crp_flags & CRYPTO_F_DONE) != 0));
7136+ /*
7137+ * we can't break out of this loop or we will leave behind
7138+ * a huge mess, however, staying here means if your driver
7139+ * is broken user applications can hang and not be killed.
7140+ * The solution, fix your driver :-)
7141+ */
7142+ if (error) {
7143+ schedule();
7144+ error = 0;
7145+ }
7146+ } while ((crp->crp_flags & CRYPTO_F_DONE) == 0);
7147+ dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
7148+
7149+ if (crp->crp_etype != 0) {
7150+ error = crp->crp_etype;
7151+ dprintk("%s error in crp processing\n", __FUNCTION__);
7152+ goto bail;
7153+ }
7154+
7155+ if (cse->error) {
7156+ error = cse->error;
7157+ dprintk("%s error in cse processing\n", __FUNCTION__);
7158+ goto bail;
7159+ }
7160+
7161+ if (cop->dst && (error = copy_to_user(cop->dst,
7162+ cse->uio.uio_iov[0].iov_base, cop->len))) {
7163+ dprintk("%s bad dst copy\n", __FUNCTION__);
7164+ goto bail;
7165+ }
7166+
7167+ if (cop->mac &&
7168+ (error=copy_to_user(cop->mac,
7169+ (caddr_t)cse->uio.uio_iov[0].iov_base + cop->len,
7170+ cse->info.authsize))) {
7171+ dprintk("%s bad mac copy\n", __FUNCTION__);
7172+ goto bail;
7173+ }
7174+
7175+bail:
7176+ if (crp)
7177+ crypto_freereq(crp);
7178+ if (cse->uio.uio_iov[0].iov_base)
7179+ kfree(cse->uio.uio_iov[0].iov_base);
7180+
7181+ return (error);
7182+}
7183+
7184+static int
7185+cryptodev_cb(void *op)
7186+{
7187+ struct cryptop *crp = (struct cryptop *) op;
7188+ struct csession *cse = (struct csession *)crp->crp_opaque;
7189+ int error;
7190+
7191+ dprintk("%s()\n", __FUNCTION__);
7192+ error = crp->crp_etype;
7193+ if (error == EAGAIN) {
7194+ crp->crp_flags &= ~CRYPTO_F_DONE;
7195+#ifdef NOTYET
7196+ /*
7197+ * DAVIDM I am fairly sure that we should turn this into a batch
7198+ * request to stop bad karma/lockup, revisit
7199+ */
7200+ crp->crp_flags |= CRYPTO_F_BATCH;
7201+#endif
7202+ return crypto_dispatch(crp);
7203+ }
7204+ if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
7205+ cse->error = error;
7206+ wake_up_interruptible(&crp->crp_waitq);
7207+ }
7208+ return (0);
7209+}
7210+
7211+static int
7212+cryptodevkey_cb(void *op)
7213+{
7214+ struct cryptkop *krp = (struct cryptkop *) op;
7215+ dprintk("%s()\n", __FUNCTION__);
7216+ wake_up_interruptible(&krp->krp_waitq);
7217+ return (0);
7218+}
7219+
7220+static int
7221+cryptodev_key(struct crypt_kop *kop)
7222+{
7223+ struct cryptkop *krp = NULL;
7224+ int error = EINVAL;
7225+ int in, out, size, i;
7226+
7227+ dprintk("%s()\n", __FUNCTION__);
7228+ if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
7229+ dprintk("%s params too big\n", __FUNCTION__);
7230+ return (EFBIG);
7231+ }
7232+
7233+ in = kop->crk_iparams;
7234+ out = kop->crk_oparams;
7235+ switch (kop->crk_op) {
7236+ case CRK_MOD_EXP:
7237+ if (in == 3 && out == 1)
7238+ break;
7239+ return (EINVAL);
7240+ case CRK_MOD_EXP_CRT:
7241+ if (in == 6 && out == 1)
7242+ break;
7243+ return (EINVAL);
7244+ case CRK_DSA_SIGN:
7245+ if (in == 5 && out == 2)
7246+ break;
7247+ return (EINVAL);
7248+ case CRK_DSA_VERIFY:
7249+ if (in == 7 && out == 0)
7250+ break;
7251+ return (EINVAL);
7252+ case CRK_DH_COMPUTE_KEY:
7253+ if (in == 3 && out == 1)
7254+ break;
7255+ return (EINVAL);
7256+ default:
7257+ return (EINVAL);
7258+ }
7259+
7260+ krp = (struct cryptkop *)kmalloc(sizeof *krp, GFP_KERNEL);
7261+ if (!krp)
7262+ return (ENOMEM);
7263+ bzero(krp, sizeof *krp);
7264+ krp->krp_op = kop->crk_op;
7265+ krp->krp_status = kop->crk_status;
7266+ krp->krp_iparams = kop->crk_iparams;
7267+ krp->krp_oparams = kop->crk_oparams;
7268+ krp->krp_crid = kop->crk_crid;
7269+ krp->krp_status = 0;
7270+ krp->krp_flags = CRYPTO_KF_CBIMM;
7271+ krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
7272+ init_waitqueue_head(&krp->krp_waitq);
7273+
7274+ for (i = 0; i < CRK_MAXPARAM; i++)
7275+ krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
7276+ for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
7277+ size = (krp->krp_param[i].crp_nbits + 7) / 8;
7278+ if (size == 0)
7279+ continue;
7280+ krp->krp_param[i].crp_p = (caddr_t) kmalloc(size, GFP_KERNEL);
7281+ if (i >= krp->krp_iparams)
7282+ continue;
7283+ error = copy_from_user(krp->krp_param[i].crp_p,
7284+ kop->crk_param[i].crp_p, size);
7285+ if (error)
7286+ goto fail;
7287+ }
7288+
7289+ error = crypto_kdispatch(krp);
7290+ if (error)
7291+ goto fail;
7292+
7293+ do {
7294+ error = wait_event_interruptible(krp->krp_waitq,
7295+ ((krp->krp_flags & CRYPTO_KF_DONE) != 0));
7296+ /*
7297+ * we can't break out of this loop or we will leave behind
7298+ * a huge mess, however, staying here means if your driver
7299+ * is broken user applications can hang and not be killed.
7300+ * The solution, fix your driver :-)
7301+ */
7302+ if (error) {
7303+ schedule();
7304+ error = 0;
7305+ }
7306+ } while ((krp->krp_flags & CRYPTO_KF_DONE) == 0);
7307+
7308+ dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
7309+
7310+ kop->crk_crid = krp->krp_crid; /* device that did the work */
7311+ if (krp->krp_status != 0) {
7312+ error = krp->krp_status;
7313+ goto fail;
7314+ }
7315+
7316+ for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
7317+ size = (krp->krp_param[i].crp_nbits + 7) / 8;
7318+ if (size == 0)
7319+ continue;
7320+ error = copy_to_user(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p,
7321+ size);
7322+ if (error)
7323+ goto fail;
7324+ }
7325+
7326+fail:
7327+ if (krp) {
7328+ kop->crk_status = krp->krp_status;
7329+ for (i = 0; i < CRK_MAXPARAM; i++) {
7330+ if (krp->krp_param[i].crp_p)
7331+ kfree(krp->krp_param[i].crp_p);
7332+ }
7333+ kfree(krp);
7334+ }
7335+ return (error);
7336+}
7337+
7338+static int
7339+cryptodev_find(struct crypt_find_op *find)
7340+{
7341+ device_t dev;
7342+
7343+ if (find->crid != -1) {
7344+ dev = crypto_find_device_byhid(find->crid);
7345+ if (dev == NULL)
7346+ return (ENOENT);
7347+ strlcpy(find->name, device_get_nameunit(dev),
7348+ sizeof(find->name));
7349+ } else {
7350+ find->crid = crypto_find_driver(find->name);
7351+ if (find->crid == -1)
7352+ return (ENOENT);
7353+ }
7354+ return (0);
7355+}
7356+
7357+static struct csession *
7358+csefind(struct fcrypt *fcr, u_int ses)
7359+{
7360+ struct csession *cse;
7361+
7362+ dprintk("%s()\n", __FUNCTION__);
7363+ list_for_each_entry(cse, &fcr->csessions, list)
7364+ if (cse->ses == ses)
7365+ return (cse);
7366+ return (NULL);
7367+}
7368+
7369+static int
7370+csedelete(struct fcrypt *fcr, struct csession *cse_del)
7371+{
7372+ struct csession *cse;
7373+
7374+ dprintk("%s()\n", __FUNCTION__);
7375+ list_for_each_entry(cse, &fcr->csessions, list) {
7376+ if (cse == cse_del) {
7377+ list_del(&cse->list);
7378+ return (1);
7379+ }
7380+ }
7381+ return (0);
7382+}
7383+
7384+static struct csession *
7385+cseadd(struct fcrypt *fcr, struct csession *cse)
7386+{
7387+ dprintk("%s()\n", __FUNCTION__);
7388+ list_add_tail(&cse->list, &fcr->csessions);
7389+ cse->ses = fcr->sesn++;
7390+ return (cse);
7391+}
7392+
7393+static struct csession *
7394+csecreate(struct fcrypt *fcr, u_int64_t sid, struct cryptoini *crie,
7395+ struct cryptoini *cria, struct csession_info *info)
7396+{
7397+ struct csession *cse;
7398+
7399+ dprintk("%s()\n", __FUNCTION__);
7400+ cse = (struct csession *) kmalloc(sizeof(struct csession), GFP_KERNEL);
7401+ if (cse == NULL)
7402+ return NULL;
7403+ memset(cse, 0, sizeof(struct csession));
7404+
7405+ INIT_LIST_HEAD(&cse->list);
7406+ init_waitqueue_head(&cse->waitq);
7407+
7408+ cse->key = crie->cri_key;
7409+ cse->keylen = crie->cri_klen/8;
7410+ cse->mackey = cria->cri_key;
7411+ cse->mackeylen = cria->cri_klen/8;
7412+ cse->sid = sid;
7413+ cse->cipher = crie->cri_alg;
7414+ cse->mac = cria->cri_alg;
7415+ cse->info = *info;
7416+ cseadd(fcr, cse);
7417+ return (cse);
7418+}
7419+
7420+static int
7421+csefree(struct csession *cse)
7422+{
7423+ int error;
7424+
7425+ dprintk("%s()\n", __FUNCTION__);
7426+ error = crypto_freesession(cse->sid);
7427+ if (cse->key)
7428+ kfree(cse->key);
7429+ if (cse->mackey)
7430+ kfree(cse->mackey);
7431+ kfree(cse);
7432+ return(error);
7433+}
7434+
7435+static int
7436+cryptodev_ioctl(
7437+ struct inode *inode,
7438+ struct file *filp,
7439+ unsigned int cmd,
7440+ unsigned long arg)
7441+{
7442+ struct cryptoini cria, crie;
7443+ struct fcrypt *fcr = filp->private_data;
7444+ struct csession *cse;
7445+ struct csession_info info;
7446+ struct session2_op sop;
7447+ struct crypt_op cop;
7448+ struct crypt_kop kop;
7449+ struct crypt_find_op fop;
7450+ u_int64_t sid;
7451+ u_int32_t ses = 0;
7452+ int feat, fd, error = 0, crid;
7453+ mm_segment_t fs;
7454+
7455+ dprintk("%s(cmd=%x arg=%lx)\n", __FUNCTION__, cmd, arg);
7456+
7457+ switch (cmd) {
7458+
7459+ case CRIOGET: {
7460+ dprintk("%s(CRIOGET)\n", __FUNCTION__);
7461+ fs = get_fs();
7462+ set_fs(get_ds());
7463+ for (fd = 0; fd < files_fdtable(current->files)->max_fds; fd++)
7464+ if (files_fdtable(current->files)->fd[fd] == filp)
7465+ break;
7466+ fd = sys_dup(fd);
7467+ set_fs(fs);
7468+ put_user(fd, (int *) arg);
7469+ return IS_ERR_VALUE(fd) ? fd : 0;
7470+ }
7471+
7472+#define CIOCGSESSSTR (cmd == CIOCGSESSION ? "CIOCGSESSION" : "CIOCGSESSION2")
7473+ case CIOCGSESSION:
7474+ case CIOCGSESSION2:
7475+ dprintk("%s(%s)\n", __FUNCTION__, CIOCGSESSSTR);
7476+ memset(&crie, 0, sizeof(crie));
7477+ memset(&cria, 0, sizeof(cria));
7478+ memset(&info, 0, sizeof(info));
7479+ memset(&sop, 0, sizeof(sop));
7480+
7481+ if (copy_from_user(&sop, (void*)arg, (cmd == CIOCGSESSION) ?
7482+ sizeof(struct session_op) : sizeof(sop))) {
7483+ dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
7484+ error = EFAULT;
7485+ goto bail;
7486+ }
7487+
7488+ switch (sop.cipher) {
7489+ case 0:
7490+ dprintk("%s(%s) - no cipher\n", __FUNCTION__, CIOCGSESSSTR);
7491+ break;
7492+ case CRYPTO_NULL_CBC:
7493+ info.blocksize = NULL_BLOCK_LEN;
7494+ info.minkey = NULL_MIN_KEY_LEN;
7495+ info.maxkey = NULL_MAX_KEY_LEN;
7496+ break;
7497+ case CRYPTO_DES_CBC:
7498+ info.blocksize = DES_BLOCK_LEN;
7499+ info.minkey = DES_MIN_KEY_LEN;
7500+ info.maxkey = DES_MAX_KEY_LEN;
7501+ break;
7502+ case CRYPTO_3DES_CBC:
7503+ info.blocksize = DES3_BLOCK_LEN;
7504+ info.minkey = DES3_MIN_KEY_LEN;
7505+ info.maxkey = DES3_MAX_KEY_LEN;
7506+ break;
7507+ case CRYPTO_BLF_CBC:
7508+ info.blocksize = BLOWFISH_BLOCK_LEN;
7509+ info.minkey = BLOWFISH_MIN_KEY_LEN;
7510+ info.maxkey = BLOWFISH_MAX_KEY_LEN;
7511+ break;
7512+ case CRYPTO_CAST_CBC:
7513+ info.blocksize = CAST128_BLOCK_LEN;
7514+ info.minkey = CAST128_MIN_KEY_LEN;
7515+ info.maxkey = CAST128_MAX_KEY_LEN;
7516+ break;
7517+ case CRYPTO_SKIPJACK_CBC:
7518+ info.blocksize = SKIPJACK_BLOCK_LEN;
7519+ info.minkey = SKIPJACK_MIN_KEY_LEN;
7520+ info.maxkey = SKIPJACK_MAX_KEY_LEN;
7521+ break;
7522+ case CRYPTO_AES_CBC:
7523+ info.blocksize = AES_BLOCK_LEN;
7524+ info.minkey = AES_MIN_KEY_LEN;
7525+ info.maxkey = AES_MAX_KEY_LEN;
7526+ break;
7527+ case CRYPTO_ARC4:
7528+ info.blocksize = ARC4_BLOCK_LEN;
7529+ info.minkey = ARC4_MIN_KEY_LEN;
7530+ info.maxkey = ARC4_MAX_KEY_LEN;
7531+ break;
7532+ case CRYPTO_CAMELLIA_CBC:
7533+ info.blocksize = CAMELLIA_BLOCK_LEN;
7534+ info.minkey = CAMELLIA_MIN_KEY_LEN;
7535+ info.maxkey = CAMELLIA_MAX_KEY_LEN;
7536+ break;
7537+ default:
7538+ dprintk("%s(%s) - bad cipher\n", __FUNCTION__, CIOCGSESSSTR);
7539+ error = EINVAL;
7540+ goto bail;
7541+ }
7542+
7543+ switch (sop.mac) {
7544+ case 0:
7545+ dprintk("%s(%s) - no mac\n", __FUNCTION__, CIOCGSESSSTR);
7546+ break;
7547+ case CRYPTO_NULL_HMAC:
7548+ info.authsize = NULL_HASH_LEN;
7549+ break;
7550+ case CRYPTO_MD5:
7551+ info.authsize = MD5_HASH_LEN;
7552+ break;
7553+ case CRYPTO_SHA1:
7554+ info.authsize = SHA1_HASH_LEN;
7555+ break;
7556+ case CRYPTO_SHA2_256:
7557+ info.authsize = SHA2_256_HASH_LEN;
7558+ break;
7559+ case CRYPTO_SHA2_384:
7560+ info.authsize = SHA2_384_HASH_LEN;
7561+ break;
7562+ case CRYPTO_SHA2_512:
7563+ info.authsize = SHA2_512_HASH_LEN;
7564+ break;
7565+ case CRYPTO_RIPEMD160:
7566+ info.authsize = RIPEMD160_HASH_LEN;
7567+ break;
7568+ case CRYPTO_MD5_HMAC:
7569+ info.authsize = MD5_HASH_LEN;
7570+ info.authkey = 16;
7571+ break;
7572+ case CRYPTO_SHA1_HMAC:
7573+ info.authsize = SHA1_HASH_LEN;
7574+ info.authkey = 20;
7575+ break;
7576+ case CRYPTO_SHA2_256_HMAC:
7577+ info.authsize = SHA2_256_HASH_LEN;
7578+ info.authkey = 32;
7579+ break;
7580+ case CRYPTO_SHA2_384_HMAC:
7581+ info.authsize = SHA2_384_HASH_LEN;
7582+ info.authkey = 48;
7583+ break;
7584+ case CRYPTO_SHA2_512_HMAC:
7585+ info.authsize = SHA2_512_HASH_LEN;
7586+ info.authkey = 64;
7587+ break;
7588+ case CRYPTO_RIPEMD160_HMAC:
7589+ info.authsize = RIPEMD160_HASH_LEN;
7590+ info.authkey = 20;
7591+ break;
7592+ default:
7593+ dprintk("%s(%s) - bad mac\n", __FUNCTION__, CIOCGSESSSTR);
7594+ error = EINVAL;
7595+ goto bail;
7596+ }
7597+
7598+ if (info.blocksize) {
7599+ crie.cri_alg = sop.cipher;
7600+ crie.cri_klen = sop.keylen * 8;
7601+ if ((info.maxkey && sop.keylen > info.maxkey) ||
7602+ sop.keylen < info.minkey) {
7603+ dprintk("%s(%s) - bad key\n", __FUNCTION__, CIOCGSESSSTR);
7604+ error = EINVAL;
7605+ goto bail;
7606+ }
7607+
7608+ crie.cri_key = (u_int8_t *) kmalloc(crie.cri_klen/8+1, GFP_KERNEL);
7609+ if (copy_from_user(crie.cri_key, sop.key,
7610+ crie.cri_klen/8)) {
7611+ dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
7612+ error = EFAULT;
7613+ goto bail;
7614+ }
7615+ if (info.authsize)
7616+ crie.cri_next = &cria;
7617+ }
7618+
7619+ if (info.authsize) {
7620+ cria.cri_alg = sop.mac;
7621+ cria.cri_klen = sop.mackeylen * 8;
7622+ if (info.authkey && sop.mackeylen != info.authkey) {
7623+ dprintk("%s(%s) - mackeylen %d != %d\n", __FUNCTION__,
7624+ CIOCGSESSSTR, sop.mackeylen, info.authkey);
7625+ error = EINVAL;
7626+ goto bail;
7627+ }
7628+
7629+ if (cria.cri_klen) {
7630+ cria.cri_key = (u_int8_t *) kmalloc(cria.cri_klen/8,GFP_KERNEL);
7631+ if (copy_from_user(cria.cri_key, sop.mackey,
7632+ cria.cri_klen / 8)) {
7633+ dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
7634+ error = EFAULT;
7635+ goto bail;
7636+ }
7637+ }
7638+ }
7639+
7640+ /* NB: CIOGSESSION2 has the crid */
7641+ if (cmd == CIOCGSESSION2) {
7642+ crid = sop.crid;
7643+ error = checkcrid(crid);
7644+ if (error) {
7645+ dprintk("%s(%s) - checkcrid %x\n", __FUNCTION__,
7646+ CIOCGSESSSTR, error);
7647+ goto bail;
7648+ }
7649+ } else {
7650+ /* allow either HW or SW to be used */
7651+ crid = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
7652+ }
7653+ error = crypto_newsession(&sid, (info.blocksize ? &crie : &cria), crid);
7654+ if (error) {
7655+ dprintk("%s(%s) - newsession %d\n",__FUNCTION__,CIOCGSESSSTR,error);
7656+ goto bail;
7657+ }
7658+
7659+ cse = csecreate(fcr, sid, &crie, &cria, &info);
7660+ if (cse == NULL) {
7661+ crypto_freesession(sid);
7662+ error = EINVAL;
7663+ dprintk("%s(%s) - csecreate failed\n", __FUNCTION__, CIOCGSESSSTR);
7664+ goto bail;
7665+ }
7666+ sop.ses = cse->ses;
7667+
7668+ if (cmd == CIOCGSESSION2) {
7669+ /* return hardware/driver id */
7670+ sop.crid = CRYPTO_SESID2HID(cse->sid);
7671+ }
7672+
7673+ if (copy_to_user((void*)arg, &sop, (cmd == CIOCGSESSION) ?
7674+ sizeof(struct session_op) : sizeof(sop))) {
7675+ dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
7676+ error = EFAULT;
7677+ }
7678+bail:
7679+ if (error) {
7680+ dprintk("%s(%s) - bail %d\n", __FUNCTION__, CIOCGSESSSTR, error);
7681+ if (crie.cri_key)
7682+ kfree(crie.cri_key);
7683+ if (cria.cri_key)
7684+ kfree(cria.cri_key);
7685+ }
7686+ break;
7687+ case CIOCFSESSION:
7688+ dprintk("%s(CIOCFSESSION)\n", __FUNCTION__);
7689+ get_user(ses, (uint32_t*)arg);
7690+ cse = csefind(fcr, ses);
7691+ if (cse == NULL) {
7692+ error = EINVAL;
7693+ dprintk("%s(CIOCFSESSION) - Fail %d\n", __FUNCTION__, error);
7694+ break;
7695+ }
7696+ csedelete(fcr, cse);
7697+ error = csefree(cse);
7698+ break;
7699+ case CIOCCRYPT:
7700+ dprintk("%s(CIOCCRYPT)\n", __FUNCTION__);
7701+ if(copy_from_user(&cop, (void*)arg, sizeof(cop))) {
7702+ dprintk("%s(CIOCCRYPT) - bad copy\n", __FUNCTION__);
7703+ error = EFAULT;
7704+ goto bail;
7705+ }
7706+ cse = csefind(fcr, cop.ses);
7707+ if (cse == NULL) {
7708+ error = EINVAL;
7709+ dprintk("%s(CIOCCRYPT) - Fail %d\n", __FUNCTION__, error);
7710+ break;
7711+ }
7712+ error = cryptodev_op(cse, &cop);
7713+ if(copy_to_user((void*)arg, &cop, sizeof(cop))) {
7714+ dprintk("%s(CIOCCRYPT) - bad return copy\n", __FUNCTION__);
7715+ error = EFAULT;
7716+ goto bail;
7717+ }
7718+ break;
7719+ case CIOCKEY:
7720+ case CIOCKEY2:
7721+ dprintk("%s(CIOCKEY)\n", __FUNCTION__);
7722+ if (!crypto_userasymcrypto)
7723+ return (EPERM); /* XXX compat? */
7724+ if(copy_from_user(&kop, (void*)arg, sizeof(kop))) {
7725+ dprintk("%s(CIOCKEY) - bad copy\n", __FUNCTION__);
7726+ error = EFAULT;
7727+ goto bail;
7728+ }
7729+ if (cmd == CIOCKEY) {
7730+ /* NB: crypto core enforces s/w driver use */
7731+ kop.crk_crid =
7732+ CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
7733+ }
7734+ error = cryptodev_key(&kop);
7735+ if(copy_to_user((void*)arg, &kop, sizeof(kop))) {
7736+ dprintk("%s(CIOCGKEY) - bad return copy\n", __FUNCTION__);
7737+ error = EFAULT;
7738+ goto bail;
7739+ }
7740+ break;
7741+ case CIOCASYMFEAT:
7742+ dprintk("%s(CIOCASYMFEAT)\n", __FUNCTION__);
7743+ if (!crypto_userasymcrypto) {
7744+ /*
7745+ * NB: if user asym crypto operations are
7746+ * not permitted return "no algorithms"
7747+ * so well-behaved applications will just
7748+ * fallback to doing them in software.
7749+ */
7750+ feat = 0;
7751+ } else
7752+ error = crypto_getfeat(&feat);
7753+ if (!error) {
7754+ error = copy_to_user((void*)arg, &feat, sizeof(feat));
7755+ }
7756+ break;
7757+ case CIOCFINDDEV:
7758+ if (copy_from_user(&fop, (void*)arg, sizeof(fop))) {
7759+ dprintk("%s(CIOCFINDDEV) - bad copy\n", __FUNCTION__);
7760+ error = EFAULT;
7761+ goto bail;
7762+ }
7763+ error = cryptodev_find(&fop);
7764+ if (copy_to_user((void*)arg, &fop, sizeof(fop))) {
7765+ dprintk("%s(CIOCFINDDEV) - bad return copy\n", __FUNCTION__);
7766+ error = EFAULT;
7767+ goto bail;
7768+ }
7769+ break;
7770+ default:
7771+ dprintk("%s(unknown ioctl 0x%x)\n", __FUNCTION__, cmd);
7772+ error = EINVAL;
7773+ break;
7774+ }
7775+ return(-error);
7776+}
7777+
7778+#ifdef HAVE_UNLOCKED_IOCTL
7779+static long
7780+cryptodev_unlocked_ioctl(
7781+ struct file *filp,
7782+ unsigned int cmd,
7783+ unsigned long arg)
7784+{
7785+ return cryptodev_ioctl(NULL, filp, cmd, arg);
7786+}
7787+#endif
7788+
7789+static int
7790+cryptodev_open(struct inode *inode, struct file *filp)
7791+{
7792+ struct fcrypt *fcr;
7793+
7794+ dprintk("%s()\n", __FUNCTION__);
7795+ if (filp->private_data) {
7796+ printk("cryptodev: Private data already exists !\n");
7797+ return(0);
7798+ }
7799+
7800+ fcr = kmalloc(sizeof(*fcr), GFP_KERNEL);
7801+ if (!fcr) {
7802+ dprintk("%s() - malloc failed\n", __FUNCTION__);
7803+ return(-ENOMEM);
7804+ }
7805+ memset(fcr, 0, sizeof(*fcr));
7806+
7807+ INIT_LIST_HEAD(&fcr->csessions);
7808+ filp->private_data = fcr;
7809+ return(0);
7810+}
7811+
7812+static int
7813+cryptodev_release(struct inode *inode, struct file *filp)
7814+{
7815+ struct fcrypt *fcr = filp->private_data;
7816+ struct csession *cse, *tmp;
7817+
7818+ dprintk("%s()\n", __FUNCTION__);
7819+ if (!filp) {
7820+ printk("cryptodev: No private data on release\n");
7821+ return(0);
7822+ }
7823+
7824+ list_for_each_entry_safe(cse, tmp, &fcr->csessions, list) {
7825+ list_del(&cse->list);
7826+ (void)csefree(cse);
7827+ }
7828+ filp->private_data = NULL;
7829+ kfree(fcr);
7830+ return(0);
7831+}
7832+
7833+static struct file_operations cryptodev_fops = {
7834+ .owner = THIS_MODULE,
7835+ .open = cryptodev_open,
7836+ .release = cryptodev_release,
7837+ .ioctl = cryptodev_ioctl,
7838+#ifdef HAVE_UNLOCKED_IOCTL
7839+ .unlocked_ioctl = cryptodev_unlocked_ioctl,
7840+#endif
7841+};
7842+
7843+static struct miscdevice cryptodev = {
7844+ .minor = CRYPTODEV_MINOR,
7845+ .name = "crypto",
7846+ .fops = &cryptodev_fops,
7847+};
7848+
7849+static int __init
7850+cryptodev_init(void)
7851+{
7852+ int rc;
7853+
7854+ dprintk("%s(%p)\n", __FUNCTION__, cryptodev_init);
7855+ rc = misc_register(&cryptodev);
7856+ if (rc) {
7857+ printk(KERN_ERR "cryptodev: registration of /dev/crypto failed\n");
7858+ return(rc);
7859+ }
7860+
7861+ return(0);
7862+}
7863+
7864+static void __exit
7865+cryptodev_exit(void)
7866+{
7867+ dprintk("%s()\n", __FUNCTION__);
7868+ misc_deregister(&cryptodev);
7869+}
7870+
7871+module_init(cryptodev_init);
7872+module_exit(cryptodev_exit);
7873+
7874+MODULE_LICENSE("BSD");
7875+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
7876+MODULE_DESCRIPTION("Cryptodev (user interface to OCF)");
7877diff --git a/crypto/ocf/cryptodev.h b/crypto/ocf/cryptodev.h
7878new file mode 100644
7879index 0000000..bb11a56
7880--- /dev/null
7881+++ b/crypto/ocf/cryptodev.h
7882@@ -0,0 +1,479 @@
7883+/* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.25 2007/05/09 19:37:02 gnn Exp $ */
7884+/* $OpenBSD: cryptodev.h,v 1.31 2002/06/11 11:14:29 beck Exp $ */
7885+
7886+/*-
7887+ * Linux port done by David McCullough <david_mccullough@mcafee.com>
7888+ * Copyright (C) 2006-2010 David McCullough
7889+ * Copyright (C) 2004-2005 Intel Corporation.
7890+ * The license and original author are listed below.
7891+ *
7892+ * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
7893+ * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
7894+ *
7895+ * This code was written by Angelos D. Keromytis in Athens, Greece, in
7896+ * February 2000. Network Security Technologies Inc. (NSTI) kindly
7897+ * supported the development of this code.
7898+ *
7899+ * Copyright (c) 2000 Angelos D. Keromytis
7900+ *
7901+ * Permission to use, copy, and modify this software with or without fee
7902+ * is hereby granted, provided that this entire notice is included in
7903+ * all source code copies of any software which is or includes a copy or
7904+ * modification of this software.
7905+ *
7906+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
7907+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
7908+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
7909+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
7910+ * PURPOSE.
7911+ *
7912+ * Copyright (c) 2001 Theo de Raadt
7913+ *
7914+ * Redistribution and use in source and binary forms, with or without
7915+ * modification, are permitted provided that the following conditions
7916+ * are met:
7917+ *
7918+ * 1. Redistributions of source code must retain the above copyright
7919+ * notice, this list of conditions and the following disclaimer.
7920+ * 2. Redistributions in binary form must reproduce the above copyright
7921+ * notice, this list of conditions and the following disclaimer in the
7922+ * documentation and/or other materials provided with the distribution.
7923+ * 3. The name of the author may not be used to endorse or promote products
7924+ * derived from this software without specific prior written permission.
7925+ *
7926+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
7927+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
7928+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
7929+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
7930+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
7931+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
7932+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
7933+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7934+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
7935+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7936+ *
7937+ * Effort sponsored in part by the Defense Advanced Research Projects
7938+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
7939+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
7940+ *
7941+ */
7942+
7943+#ifndef _CRYPTO_CRYPTO_H_
7944+#define _CRYPTO_CRYPTO_H_
7945+
7946+/* Some initial values */
7947+#define CRYPTO_DRIVERS_INITIAL 4
7948+#define CRYPTO_SW_SESSIONS 32
7949+
7950+/* Hash values */
7951+#define NULL_HASH_LEN 0
7952+#define MD5_HASH_LEN 16
7953+#define SHA1_HASH_LEN 20
7954+#define RIPEMD160_HASH_LEN 20
7955+#define SHA2_256_HASH_LEN 32
7956+#define SHA2_384_HASH_LEN 48
7957+#define SHA2_512_HASH_LEN 64
7958+#define MD5_KPDK_HASH_LEN 16
7959+#define SHA1_KPDK_HASH_LEN 20
7960+/* Maximum hash algorithm result length */
7961+#define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */
7962+
7963+/* HMAC values */
7964+#define NULL_HMAC_BLOCK_LEN 1
7965+#define MD5_HMAC_BLOCK_LEN 64
7966+#define SHA1_HMAC_BLOCK_LEN 64
7967+#define RIPEMD160_HMAC_BLOCK_LEN 64
7968+#define SHA2_256_HMAC_BLOCK_LEN 64
7969+#define SHA2_384_HMAC_BLOCK_LEN 128
7970+#define SHA2_512_HMAC_BLOCK_LEN 128
7971+/* Maximum HMAC block length */
7972+#define HMAC_MAX_BLOCK_LEN SHA2_512_HMAC_BLOCK_LEN /* Keep this updated */
7973+#define HMAC_IPAD_VAL 0x36
7974+#define HMAC_OPAD_VAL 0x5C
7975+
7976+/* Encryption algorithm block sizes */
7977+#define NULL_BLOCK_LEN 1
7978+#define DES_BLOCK_LEN 8
7979+#define DES3_BLOCK_LEN 8
7980+#define BLOWFISH_BLOCK_LEN 8
7981+#define SKIPJACK_BLOCK_LEN 8
7982+#define CAST128_BLOCK_LEN 8
7983+#define RIJNDAEL128_BLOCK_LEN 16
7984+#define AES_BLOCK_LEN RIJNDAEL128_BLOCK_LEN
7985+#define CAMELLIA_BLOCK_LEN 16
7986+#define ARC4_BLOCK_LEN 1
7987+#define EALG_MAX_BLOCK_LEN AES_BLOCK_LEN /* Keep this updated */
7988+
7989+/* Encryption algorithm min and max key sizes */
7990+#define NULL_MIN_KEY_LEN 0
7991+#define NULL_MAX_KEY_LEN 0
7992+#define DES_MIN_KEY_LEN 8
7993+#define DES_MAX_KEY_LEN 8
7994+#define DES3_MIN_KEY_LEN 24
7995+#define DES3_MAX_KEY_LEN 24
7996+#define BLOWFISH_MIN_KEY_LEN 4
7997+#define BLOWFISH_MAX_KEY_LEN 56
7998+#define SKIPJACK_MIN_KEY_LEN 10
7999+#define SKIPJACK_MAX_KEY_LEN 10
8000+#define CAST128_MIN_KEY_LEN 5
8001+#define CAST128_MAX_KEY_LEN 16
8002+#define RIJNDAEL128_MIN_KEY_LEN 16
8003+#define RIJNDAEL128_MAX_KEY_LEN 32
8004+#define AES_MIN_KEY_LEN RIJNDAEL128_MIN_KEY_LEN
8005+#define AES_MAX_KEY_LEN RIJNDAEL128_MAX_KEY_LEN
8006+#define CAMELLIA_MIN_KEY_LEN 16
8007+#define CAMELLIA_MAX_KEY_LEN 32
8008+#define ARC4_MIN_KEY_LEN 1
8009+#define ARC4_MAX_KEY_LEN 256
8010+
8011+/* Max size of data that can be processed */
8012+#define CRYPTO_MAX_DATA_LEN 64*1024 - 1
8013+
8014+#define CRYPTO_ALGORITHM_MIN 1
8015+#define CRYPTO_DES_CBC 1
8016+#define CRYPTO_3DES_CBC 2
8017+#define CRYPTO_BLF_CBC 3
8018+#define CRYPTO_CAST_CBC 4
8019+#define CRYPTO_SKIPJACK_CBC 5
8020+#define CRYPTO_MD5_HMAC 6
8021+#define CRYPTO_SHA1_HMAC 7
8022+#define CRYPTO_RIPEMD160_HMAC 8
8023+#define CRYPTO_MD5_KPDK 9
8024+#define CRYPTO_SHA1_KPDK 10
8025+#define CRYPTO_RIJNDAEL128_CBC 11 /* 128 bit blocksize */
8026+#define CRYPTO_AES_CBC 11 /* 128 bit blocksize -- the same as above */
8027+#define CRYPTO_ARC4 12
8028+#define CRYPTO_MD5 13
8029+#define CRYPTO_SHA1 14
8030+#define CRYPTO_NULL_HMAC 15
8031+#define CRYPTO_NULL_CBC 16
8032+#define CRYPTO_DEFLATE_COMP 17 /* Deflate compression algorithm */
8033+#define CRYPTO_SHA2_256_HMAC 18
8034+#define CRYPTO_SHA2_384_HMAC 19
8035+#define CRYPTO_SHA2_512_HMAC 20
8036+#define CRYPTO_CAMELLIA_CBC 21
8037+#define CRYPTO_SHA2_256 22
8038+#define CRYPTO_SHA2_384 23
8039+#define CRYPTO_SHA2_512 24
8040+#define CRYPTO_RIPEMD160 25
8041+#define CRYPTO_ALGORITHM_MAX 25 /* Keep updated - see below */
8042+
8043+/* Algorithm flags */
8044+#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
8045+#define CRYPTO_ALG_FLAG_RNG_ENABLE 0x02 /* Has HW RNG for DH/DSA */
8046+#define CRYPTO_ALG_FLAG_DSA_SHA 0x04 /* Can do SHA on msg */
8047+
8048+/*
8049+ * Crypto driver/device flags. They can set in the crid
8050+ * parameter when creating a session or submitting a key
8051+ * op to affect the device/driver assigned. If neither
8052+ * of these are specified then the crid is assumed to hold
8053+ * the driver id of an existing (and suitable) device that
8054+ * must be used to satisfy the request.
8055+ */
8056+#define CRYPTO_FLAG_HARDWARE 0x01000000 /* hardware accelerated */
8057+#define CRYPTO_FLAG_SOFTWARE 0x02000000 /* software implementation */
8058+
8059+/* NB: deprecated */
8060+struct session_op {
8061+ u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
8062+ u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
8063+
8064+ u_int32_t keylen; /* cipher key */
8065+ caddr_t key;
8066+ int mackeylen; /* mac key */
8067+ caddr_t mackey;
8068+
8069+ u_int32_t ses; /* returns: session # */
8070+};
8071+
8072+struct session2_op {
8073+ u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
8074+ u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
8075+
8076+ u_int32_t keylen; /* cipher key */
8077+ caddr_t key;
8078+ int mackeylen; /* mac key */
8079+ caddr_t mackey;
8080+
8081+ u_int32_t ses; /* returns: session # */
8082+ int crid; /* driver id + flags (rw) */
8083+ int pad[4]; /* for future expansion */
8084+};
8085+
8086+struct crypt_op {
8087+ u_int32_t ses;
8088+ u_int16_t op; /* i.e. COP_ENCRYPT */
8089+#define COP_NONE 0
8090+#define COP_ENCRYPT 1
8091+#define COP_DECRYPT 2
8092+ u_int16_t flags;
8093+#define COP_F_BATCH 0x0008 /* Batch op if possible */
8094+ u_int len;
8095+ caddr_t src, dst; /* become iov[] inside kernel */
8096+ caddr_t mac; /* must be big enough for chosen MAC */
8097+ caddr_t iv;
8098+};
8099+
8100+/*
8101+ * Parameters for looking up a crypto driver/device by
8102+ * device name or by id. The latter are returned for
8103+ * created sessions (crid) and completed key operations.
8104+ */
8105+struct crypt_find_op {
8106+ int crid; /* driver id + flags */
8107+ char name[32]; /* device/driver name */
8108+};
8109+
8110+/* bignum parameter, in packed bytes, ... */
8111+struct crparam {
8112+ caddr_t crp_p;
8113+ u_int crp_nbits;
8114+};
8115+
8116+#define CRK_MAXPARAM 8
8117+
8118+struct crypt_kop {
8119+ u_int crk_op; /* ie. CRK_MOD_EXP or other */
8120+ u_int crk_status; /* return status */
8121+ u_short crk_iparams; /* # of input parameters */
8122+ u_short crk_oparams; /* # of output parameters */
8123+ u_int crk_crid; /* NB: only used by CIOCKEY2 (rw) */
8124+ struct crparam crk_param[CRK_MAXPARAM];
8125+};
8126+#define CRK_ALGORITM_MIN 0
8127+#define CRK_MOD_EXP 0
8128+#define CRK_MOD_EXP_CRT 1
8129+#define CRK_DSA_SIGN 2
8130+#define CRK_DSA_VERIFY 3
8131+#define CRK_DH_COMPUTE_KEY 4
8132+#define CRK_ALGORITHM_MAX 4 /* Keep updated - see below */
8133+
8134+#define CRF_MOD_EXP (1 << CRK_MOD_EXP)
8135+#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT)
8136+#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN)
8137+#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY)
8138+#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
8139+
8140+/*
8141+ * done against open of /dev/crypto, to get a cloned descriptor.
8142+ * Please use F_SETFD against the cloned descriptor.
8143+ */
8144+#define CRIOGET _IOWR('c', 100, u_int32_t)
8145+#define CRIOASYMFEAT CIOCASYMFEAT
8146+#define CRIOFINDDEV CIOCFINDDEV
8147+
8148+/* the following are done against the cloned descriptor */
8149+#define CIOCGSESSION _IOWR('c', 101, struct session_op)
8150+#define CIOCFSESSION _IOW('c', 102, u_int32_t)
8151+#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
8152+#define CIOCKEY _IOWR('c', 104, struct crypt_kop)
8153+#define CIOCASYMFEAT _IOR('c', 105, u_int32_t)
8154+#define CIOCGSESSION2 _IOWR('c', 106, struct session2_op)
8155+#define CIOCKEY2 _IOWR('c', 107, struct crypt_kop)
8156+#define CIOCFINDDEV _IOWR('c', 108, struct crypt_find_op)
8157+
8158+struct cryptotstat {
8159+ struct timespec acc; /* total accumulated time */
8160+ struct timespec min; /* min time */
8161+ struct timespec max; /* max time */
8162+ u_int32_t count; /* number of observations */
8163+};
8164+
8165+struct cryptostats {
8166+ u_int32_t cs_ops; /* symmetric crypto ops submitted */
8167+ u_int32_t cs_errs; /* symmetric crypto ops that failed */
8168+ u_int32_t cs_kops; /* asymetric/key ops submitted */
8169+ u_int32_t cs_kerrs; /* asymetric/key ops that failed */
8170+ u_int32_t cs_intrs; /* crypto swi thread activations */
8171+ u_int32_t cs_rets; /* crypto return thread activations */
8172+ u_int32_t cs_blocks; /* symmetric op driver block */
8173+ u_int32_t cs_kblocks; /* symmetric op driver block */
8174+ /*
8175+ * When CRYPTO_TIMING is defined at compile time and the
8176+ * sysctl debug.crypto is set to 1, the crypto system will
8177+ * accumulate statistics about how long it takes to process
8178+ * crypto requests at various points during processing.
8179+ */
8180+ struct cryptotstat cs_invoke; /* crypto_dipsatch -> crypto_invoke */
8181+ struct cryptotstat cs_done; /* crypto_invoke -> crypto_done */
8182+ struct cryptotstat cs_cb; /* crypto_done -> callback */
8183+ struct cryptotstat cs_finis; /* callback -> callback return */
8184+
8185+ u_int32_t cs_drops; /* crypto ops dropped due to congestion */
8186+};
8187+
8188+#ifdef __KERNEL__
8189+
8190+/* Standard initialization structure beginning */
8191+struct cryptoini {
8192+ int cri_alg; /* Algorithm to use */
8193+ int cri_klen; /* Key length, in bits */
8194+ int cri_mlen; /* Number of bytes we want from the
8195+ entire hash. 0 means all. */
8196+ caddr_t cri_key; /* key to use */
8197+ u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */
8198+ struct cryptoini *cri_next;
8199+};
8200+
8201+/* Describe boundaries of a single crypto operation */
8202+struct cryptodesc {
8203+ int crd_skip; /* How many bytes to ignore from start */
8204+ int crd_len; /* How many bytes to process */
8205+ int crd_inject; /* Where to inject results, if applicable */
8206+ int crd_flags;
8207+
8208+#define CRD_F_ENCRYPT 0x01 /* Set when doing encryption */
8209+#define CRD_F_IV_PRESENT 0x02 /* When encrypting, IV is already in
8210+ place, so don't copy. */
8211+#define CRD_F_IV_EXPLICIT 0x04 /* IV explicitly provided */
8212+#define CRD_F_DSA_SHA_NEEDED 0x08 /* Compute SHA-1 of buffer for DSA */
8213+#define CRD_F_KEY_EXPLICIT 0x10 /* Key explicitly provided */
8214+#define CRD_F_COMP 0x0f /* Set when doing compression */
8215+
8216+ struct cryptoini CRD_INI; /* Initialization/context data */
8217+#define crd_iv CRD_INI.cri_iv
8218+#define crd_key CRD_INI.cri_key
8219+#define crd_alg CRD_INI.cri_alg
8220+#define crd_klen CRD_INI.cri_klen
8221+#define crd_mlen CRD_INI.cri_mlen
8222+
8223+ struct cryptodesc *crd_next;
8224+};
8225+
8226+/* Structure describing complete operation */
8227+struct cryptop {
8228+ struct list_head crp_next;
8229+ wait_queue_head_t crp_waitq;
8230+
8231+ u_int64_t crp_sid; /* Session ID */
8232+ int crp_ilen; /* Input data total length */
8233+ int crp_olen; /* Result total length */
8234+
8235+ int crp_etype; /*
8236+ * Error type (zero means no error).
8237+ * All error codes except EAGAIN
8238+ * indicate possible data corruption (as in,
8239+ * the data have been touched). On all
8240+ * errors, the crp_sid may have changed
8241+ * (reset to a new one), so the caller
8242+ * should always check and use the new
8243+ * value on future requests.
8244+ */
8245+ int crp_flags;
8246+
8247+#define CRYPTO_F_SKBUF 0x0001 /* Input/output are skbuf chains */
8248+#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
8249+#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
8250+#define CRYPTO_F_BATCH 0x0008 /* Batch op if possible */
8251+#define CRYPTO_F_CBIMM 0x0010 /* Do callback immediately */
8252+#define CRYPTO_F_DONE 0x0020 /* Operation completed */
8253+#define CRYPTO_F_CBIFSYNC 0x0040 /* Do CBIMM if op is synchronous */
8254+
8255+ caddr_t crp_buf; /* Data to be processed */
8256+ caddr_t crp_opaque; /* Opaque pointer, passed along */
8257+ struct cryptodesc *crp_desc; /* Linked list of processing descriptors */
8258+
8259+ int (*crp_callback)(struct cryptop *); /* Callback function */
8260+};
8261+
8262+#define CRYPTO_BUF_CONTIG 0x0
8263+#define CRYPTO_BUF_IOV 0x1
8264+#define CRYPTO_BUF_SKBUF 0x2
8265+
8266+#define CRYPTO_OP_DECRYPT 0x0
8267+#define CRYPTO_OP_ENCRYPT 0x1
8268+
8269+/*
8270+ * Hints passed to process methods.
8271+ */
8272+#define CRYPTO_HINT_MORE 0x1 /* more ops coming shortly */
8273+
8274+struct cryptkop {
8275+ struct list_head krp_next;
8276+ wait_queue_head_t krp_waitq;
8277+
8278+ int krp_flags;
8279+#define CRYPTO_KF_DONE 0x0001 /* Operation completed */
8280+#define CRYPTO_KF_CBIMM 0x0002 /* Do callback immediately */
8281+
8282+ u_int krp_op; /* ie. CRK_MOD_EXP or other */
8283+ u_int krp_status; /* return status */
8284+ u_short krp_iparams; /* # of input parameters */
8285+ u_short krp_oparams; /* # of output parameters */
8286+ u_int krp_crid; /* desired device, etc. */
8287+ u_int32_t krp_hid;
8288+ struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
8289+ int (*krp_callback)(struct cryptkop *);
8290+};
8291+
8292+#include <ocf-compat.h>
8293+
8294+/*
8295+ * Session ids are 64 bits. The lower 32 bits contain a "local id" which
8296+ * is a driver-private session identifier. The upper 32 bits contain a
8297+ * "hardware id" used by the core crypto code to identify the driver and
8298+ * a copy of the driver's capabilities that can be used by client code to
8299+ * optimize operation.
8300+ */
8301+#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0x00ffffff)
8302+#define CRYPTO_SESID2CAPS(_sid) (((_sid) >> 32) & 0xff000000)
8303+#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
8304+
8305+extern int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard);
8306+extern int crypto_freesession(u_int64_t sid);
8307+#define CRYPTOCAP_F_HARDWARE CRYPTO_FLAG_HARDWARE
8308+#define CRYPTOCAP_F_SOFTWARE CRYPTO_FLAG_SOFTWARE
8309+#define CRYPTOCAP_F_SYNC 0x04000000 /* operates synchronously */
8310+extern int32_t crypto_get_driverid(device_t dev, int flags);
8311+extern int crypto_find_driver(const char *);
8312+extern device_t crypto_find_device_byhid(int hid);
8313+extern int crypto_getcaps(int hid);
8314+extern int crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
8315+ u_int32_t flags);
8316+extern int crypto_kregister(u_int32_t, int, u_int32_t);
8317+extern int crypto_unregister(u_int32_t driverid, int alg);
8318+extern int crypto_unregister_all(u_int32_t driverid);
8319+extern int crypto_dispatch(struct cryptop *crp);
8320+extern int crypto_kdispatch(struct cryptkop *);
8321+#define CRYPTO_SYMQ 0x1
8322+#define CRYPTO_ASYMQ 0x2
8323+extern int crypto_unblock(u_int32_t, int);
8324+extern void crypto_done(struct cryptop *crp);
8325+extern void crypto_kdone(struct cryptkop *);
8326+extern int crypto_getfeat(int *);
8327+
8328+extern void crypto_freereq(struct cryptop *crp);
8329+extern struct cryptop *crypto_getreq(int num);
8330+
8331+extern int crypto_usercrypto; /* userland may do crypto requests */
8332+extern int crypto_userasymcrypto; /* userland may do asym crypto reqs */
8333+extern int crypto_devallowsoft; /* only use hardware crypto */
8334+
8335+/*
8336+ * random number support, crypto_unregister_all will unregister
8337+ */
8338+extern int crypto_rregister(u_int32_t driverid,
8339+ int (*read_random)(void *arg, u_int32_t *buf, int len), void *arg);
8340+extern int crypto_runregister_all(u_int32_t driverid);
8341+
8342+/*
8343+ * Crypto-related utility routines used mainly by drivers.
8344+ *
8345+ * XXX these don't really belong here; but for now they're
8346+ * kept apart from the rest of the system.
8347+ */
8348+struct uio;
8349+extern void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp);
8350+extern void cuio_copyback(struct uio* uio, int off, int len, caddr_t cp);
8351+extern struct iovec *cuio_getptr(struct uio *uio, int loc, int *off);
8352+
8353+extern void crypto_copyback(int flags, caddr_t buf, int off, int size,
8354+ caddr_t in);
8355+extern void crypto_copydata(int flags, caddr_t buf, int off, int size,
8356+ caddr_t out);
8357+extern int crypto_apply(int flags, caddr_t buf, int off, int len,
8358+ int (*f)(void *, void *, u_int), void *arg);
8359+
8360+#endif /* __KERNEL__ */
8361+#endif /* _CRYPTO_CRYPTO_H_ */
8362diff --git a/crypto/ocf/cryptosoft.c b/crypto/ocf/cryptosoft.c
8363new file mode 100644
8364index 0000000..fa8838e
8365--- /dev/null
8366+++ b/crypto/ocf/cryptosoft.c
8367@@ -0,0 +1,1210 @@
8368+/*
8369+ * An OCF module that uses the linux kernel cryptoapi, based on the
8370+ * original cryptosoft for BSD by Angelos D. Keromytis (angelos@cis.upenn.edu)
8371+ * but is mostly unrecognisable,
8372+ *
8373+ * Written by David McCullough <david_mccullough@mcafee.com>
8374+ * Copyright (C) 2004-2010 David McCullough
8375+ * Copyright (C) 2004-2005 Intel Corporation.
8376+ *
8377+ * LICENSE TERMS
8378+ *
8379+ * The free distribution and use of this software in both source and binary
8380+ * form is allowed (with or without changes) provided that:
8381+ *
8382+ * 1. distributions of this source code include the above copyright
8383+ * notice, this list of conditions and the following disclaimer;
8384+ *
8385+ * 2. distributions in binary form include the above copyright
8386+ * notice, this list of conditions and the following disclaimer
8387+ * in the documentation and/or other associated materials;
8388+ *
8389+ * 3. the copyright holder's name is not used to endorse products
8390+ * built using this software without specific written permission.
8391+ *
8392+ * ALTERNATIVELY, provided that this notice is retained in full, this product
8393+ * may be distributed under the terms of the GNU General Public License (GPL),
8394+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
8395+ *
8396+ * DISCLAIMER
8397+ *
8398+ * This software is provided 'as is' with no explicit or implied warranties
8399+ * in respect of its properties, including, but not limited to, correctness
8400+ * and/or fitness for purpose.
8401+ * ---------------------------------------------------------------------------
8402+ */
8403+
8404+#ifndef AUTOCONF_INCLUDED
8405+#include <linux/config.h>
8406+#endif
8407+#include <linux/module.h>
8408+#include <linux/init.h>
8409+#include <linux/list.h>
8410+#include <linux/slab.h>
8411+#include <linux/sched.h>
8412+#include <linux/wait.h>
8413+#include <linux/crypto.h>
8414+#include <linux/mm.h>
8415+#include <linux/skbuff.h>
8416+#include <linux/random.h>
8417+#include <linux/version.h>
8418+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
8419+#include <linux/scatterlist.h>
8420+#endif
8421+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
8422+#include <crypto/hash.h>
8423+#endif
8424+
8425+#include <cryptodev.h>
8426+#include <uio.h>
8427+
8428+struct {
8429+ softc_device_decl sc_dev;
8430+} swcr_softc;
8431+
8432+#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
8433+
8434+#define SW_TYPE_CIPHER 0x01
8435+#define SW_TYPE_HMAC 0x02
8436+#define SW_TYPE_HASH 0x04
8437+#define SW_TYPE_COMP 0x08
8438+#define SW_TYPE_BLKCIPHER 0x10
8439+#define SW_TYPE_ALG_MASK 0x1f
8440+
8441+#define SW_TYPE_ASYNC 0x8000
8442+
8443+/* We change some of the above if we have an async interface */
8444+
8445+#define SW_TYPE_ALG_AMASK (SW_TYPE_ALG_MASK | SW_TYPE_ASYNC)
8446+
8447+#define SW_TYPE_ABLKCIPHER (SW_TYPE_BLKCIPHER | SW_TYPE_ASYNC)
8448+#define SW_TYPE_AHASH (SW_TYPE_HASH | SW_TYPE_ASYNC)
8449+#define SW_TYPE_AHMAC (SW_TYPE_HMAC | SW_TYPE_ASYNC)
8450+
8451+#define SCATTERLIST_MAX 16
8452+
8453+struct swcr_data {
8454+ int sw_type;
8455+ int sw_alg;
8456+ struct crypto_tfm *sw_tfm;
8457+ union {
8458+ struct {
8459+ char *sw_key;
8460+ int sw_klen;
8461+ int sw_mlen;
8462+ } hmac;
8463+ void *sw_comp_buf;
8464+ } u;
8465+ struct swcr_data *sw_next;
8466+};
8467+
8468+struct swcr_req {
8469+ struct swcr_data *sw_head;
8470+ struct swcr_data *sw;
8471+ struct cryptop *crp;
8472+ struct cryptodesc *crd;
8473+ struct scatterlist sg[SCATTERLIST_MAX];
8474+ unsigned char iv[EALG_MAX_BLOCK_LEN];
8475+ char result[HASH_MAX_LEN];
8476+ void *crypto_req;
8477+};
8478+
8479+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
8480+static kmem_cache_t *swcr_req_cache;
8481+#else
8482+static struct kmem_cache *swcr_req_cache;
8483+#endif
8484+
8485+#ifndef CRYPTO_TFM_MODE_CBC
8486+/*
8487+ * As of linux-2.6.21 this is no longer defined, and presumably no longer
8488+ * needed to be passed into the crypto core code.
8489+ */
8490+#define CRYPTO_TFM_MODE_CBC 0
8491+#define CRYPTO_TFM_MODE_ECB 0
8492+#endif
8493+
8494+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
8495+ /*
8496+ * Linux 2.6.19 introduced a new Crypto API, setup macro's to convert new
8497+ * API into old API.
8498+ */
8499+
8500+ /* Symmetric/Block Cipher */
8501+ struct blkcipher_desc
8502+ {
8503+ struct crypto_tfm *tfm;
8504+ void *info;
8505+ };
8506+ #define ecb(X) #X , CRYPTO_TFM_MODE_ECB
8507+ #define cbc(X) #X , CRYPTO_TFM_MODE_CBC
8508+ #define crypto_has_blkcipher(X, Y, Z) crypto_alg_available(X, 0)
8509+ #define crypto_blkcipher_cast(X) X
8510+ #define crypto_blkcipher_tfm(X) X
8511+ #define crypto_alloc_blkcipher(X, Y, Z) crypto_alloc_tfm(X, mode)
8512+ #define crypto_blkcipher_ivsize(X) crypto_tfm_alg_ivsize(X)
8513+ #define crypto_blkcipher_blocksize(X) crypto_tfm_alg_blocksize(X)
8514+ #define crypto_blkcipher_setkey(X, Y, Z) crypto_cipher_setkey(X, Y, Z)
8515+ #define crypto_blkcipher_encrypt_iv(W, X, Y, Z) \
8516+ crypto_cipher_encrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
8517+ #define crypto_blkcipher_decrypt_iv(W, X, Y, Z) \
8518+ crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
8519+ #define crypto_blkcipher_set_flags(x, y) /* nop */
8520+
8521+ /* Hash/HMAC/Digest */
8522+ struct hash_desc
8523+ {
8524+ struct crypto_tfm *tfm;
8525+ };
8526+ #define hmac(X) #X , 0
8527+ #define crypto_has_hash(X, Y, Z) crypto_alg_available(X, 0)
8528+ #define crypto_hash_cast(X) X
8529+ #define crypto_hash_tfm(X) X
8530+ #define crypto_alloc_hash(X, Y, Z) crypto_alloc_tfm(X, mode)
8531+ #define crypto_hash_digestsize(X) crypto_tfm_alg_digestsize(X)
8532+ #define crypto_hash_digest(W, X, Y, Z) \
8533+ crypto_digest_digest((W)->tfm, X, sg_num, Z)
8534+
8535+ /* Asymmetric Cipher */
8536+ #define crypto_has_cipher(X, Y, Z) crypto_alg_available(X, 0)
8537+
8538+ /* Compression */
8539+ #define crypto_has_comp(X, Y, Z) crypto_alg_available(X, 0)
8540+ #define crypto_comp_tfm(X) X
8541+ #define crypto_comp_cast(X) X
8542+ #define crypto_alloc_comp(X, Y, Z) crypto_alloc_tfm(X, mode)
8543+ #define plain(X) #X , 0
8544+#else
8545+ #define ecb(X) "ecb(" #X ")" , 0
8546+ #define cbc(X) "cbc(" #X ")" , 0
8547+ #define hmac(X) "hmac(" #X ")" , 0
8548+ #define plain(X) #X , 0
8549+#endif /* if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
8550+
8551+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
8552+/* no ablkcipher in older kernels */
8553+#define crypto_alloc_ablkcipher(a,b,c) (NULL)
8554+#define crypto_ablkcipher_tfm(x) ((struct crypto_tfm *)(x))
8555+#define crypto_ablkcipher_set_flags(a, b) /* nop */
8556+#define crypto_ablkcipher_setkey(x, y, z) (-EINVAL)
8557+#define crypto_has_ablkcipher(a,b,c) (0)
8558+#else
8559+#define HAVE_ABLKCIPHER
8560+#endif
8561+
8562+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
8563+/* no ahash in older kernels */
8564+#define crypto_ahash_tfm(x) ((struct crypto_tfm *)(x))
8565+#define crypto_alloc_ahash(a,b,c) (NULL)
8566+#define crypto_ahash_digestsize(x) 0
8567+#else
8568+#define HAVE_AHASH
8569+#endif
8570+
8571+struct crypto_details {
8572+ char *alg_name;
8573+ int mode;
8574+ int sw_type;
8575+};
8576+
8577+static struct crypto_details crypto_details[] = {
8578+ [CRYPTO_DES_CBC] = { cbc(des), SW_TYPE_BLKCIPHER, },
8579+ [CRYPTO_3DES_CBC] = { cbc(des3_ede), SW_TYPE_BLKCIPHER, },
8580+ [CRYPTO_BLF_CBC] = { cbc(blowfish), SW_TYPE_BLKCIPHER, },
8581+ [CRYPTO_CAST_CBC] = { cbc(cast5), SW_TYPE_BLKCIPHER, },
8582+ [CRYPTO_SKIPJACK_CBC] = { cbc(skipjack), SW_TYPE_BLKCIPHER, },
8583+ [CRYPTO_MD5_HMAC] = { hmac(md5), SW_TYPE_HMAC, },
8584+ [CRYPTO_SHA1_HMAC] = { hmac(sha1), SW_TYPE_HMAC, },
8585+ [CRYPTO_RIPEMD160_HMAC] = { hmac(ripemd160), SW_TYPE_HMAC, },
8586+ [CRYPTO_MD5_KPDK] = { plain(md5-kpdk), SW_TYPE_HASH, },
8587+ [CRYPTO_SHA1_KPDK] = { plain(sha1-kpdk), SW_TYPE_HASH, },
8588+ [CRYPTO_AES_CBC] = { cbc(aes), SW_TYPE_BLKCIPHER, },
8589+ [CRYPTO_ARC4] = { ecb(arc4), SW_TYPE_BLKCIPHER, },
8590+ [CRYPTO_MD5] = { plain(md5), SW_TYPE_HASH, },
8591+ [CRYPTO_SHA1] = { plain(sha1), SW_TYPE_HASH, },
8592+ [CRYPTO_NULL_HMAC] = { hmac(digest_null), SW_TYPE_HMAC, },
8593+ [CRYPTO_NULL_CBC] = { cbc(cipher_null), SW_TYPE_BLKCIPHER, },
8594+ [CRYPTO_DEFLATE_COMP] = { plain(deflate), SW_TYPE_COMP, },
8595+ [CRYPTO_SHA2_256_HMAC] = { hmac(sha256), SW_TYPE_HMAC, },
8596+ [CRYPTO_SHA2_384_HMAC] = { hmac(sha384), SW_TYPE_HMAC, },
8597+ [CRYPTO_SHA2_512_HMAC] = { hmac(sha512), SW_TYPE_HMAC, },
8598+ [CRYPTO_CAMELLIA_CBC] = { cbc(camellia), SW_TYPE_BLKCIPHER, },
8599+ [CRYPTO_SHA2_256] = { plain(sha256), SW_TYPE_HASH, },
8600+ [CRYPTO_SHA2_384] = { plain(sha384), SW_TYPE_HASH, },
8601+ [CRYPTO_SHA2_512] = { plain(sha512), SW_TYPE_HASH, },
8602+ [CRYPTO_RIPEMD160] = { plain(ripemd160), SW_TYPE_HASH, },
8603+};
8604+
8605+int32_t swcr_id = -1;
8606+module_param(swcr_id, int, 0444);
8607+MODULE_PARM_DESC(swcr_id, "Read-Only OCF ID for cryptosoft driver");
8608+
8609+int swcr_fail_if_compression_grows = 1;
8610+module_param(swcr_fail_if_compression_grows, int, 0644);
8611+MODULE_PARM_DESC(swcr_fail_if_compression_grows,
8612+ "Treat compression that results in more data as a failure");
8613+
8614+int swcr_no_ahash = 0;
8615+module_param(swcr_no_ahash, int, 0644);
8616+MODULE_PARM_DESC(swcr_no_ahash,
8617+ "Do not use async hash/hmac even if available");
8618+
8619+int swcr_no_ablk = 0;
8620+module_param(swcr_no_ablk, int, 0644);
8621+MODULE_PARM_DESC(swcr_no_ablk,
8622+ "Do not use async blk ciphers even if available");
8623+
8624+static struct swcr_data **swcr_sessions = NULL;
8625+static u_int32_t swcr_sesnum = 0;
8626+
8627+static int swcr_process(device_t, struct cryptop *, int);
8628+static int swcr_newsession(device_t, u_int32_t *, struct cryptoini *);
8629+static int swcr_freesession(device_t, u_int64_t);
8630+
8631+static device_method_t swcr_methods = {
8632+ /* crypto device methods */
8633+ DEVMETHOD(cryptodev_newsession, swcr_newsession),
8634+ DEVMETHOD(cryptodev_freesession,swcr_freesession),
8635+ DEVMETHOD(cryptodev_process, swcr_process),
8636+};
8637+
8638+#define debug swcr_debug
8639+int swcr_debug = 0;
8640+module_param(swcr_debug, int, 0644);
8641+MODULE_PARM_DESC(swcr_debug, "Enable debug");
8642+
8643+static void swcr_process_req(struct swcr_req *req);
8644+
8645+/*
8646+ * Generate a new software session.
8647+ */
8648+static int
8649+swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
8650+{
8651+ struct swcr_data **swd;
8652+ u_int32_t i;
8653+ int error;
8654+ char *algo;
8655+ int mode;
8656+
8657+ dprintk("%s()\n", __FUNCTION__);
8658+ if (sid == NULL || cri == NULL) {
8659+ dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
8660+ return EINVAL;
8661+ }
8662+
8663+ if (swcr_sessions) {
8664+ for (i = 1; i < swcr_sesnum; i++)
8665+ if (swcr_sessions[i] == NULL)
8666+ break;
8667+ } else
8668+ i = 1; /* NB: to silence compiler warning */
8669+
8670+ if (swcr_sessions == NULL || i == swcr_sesnum) {
8671+ if (swcr_sessions == NULL) {
8672+ i = 1; /* We leave swcr_sessions[0] empty */
8673+ swcr_sesnum = CRYPTO_SW_SESSIONS;
8674+ } else
8675+ swcr_sesnum *= 2;
8676+
8677+ swd = kmalloc(swcr_sesnum * sizeof(struct swcr_data *), SLAB_ATOMIC);
8678+ if (swd == NULL) {
8679+ /* Reset session number */
8680+ if (swcr_sesnum == CRYPTO_SW_SESSIONS)
8681+ swcr_sesnum = 0;
8682+ else
8683+ swcr_sesnum /= 2;
8684+ dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
8685+ return ENOBUFS;
8686+ }
8687+ memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *));
8688+
8689+ /* Copy existing sessions */
8690+ if (swcr_sessions) {
8691+ memcpy(swd, swcr_sessions,
8692+ (swcr_sesnum / 2) * sizeof(struct swcr_data *));
8693+ kfree(swcr_sessions);
8694+ }
8695+
8696+ swcr_sessions = swd;
8697+ }
8698+
8699+ swd = &swcr_sessions[i];
8700+ *sid = i;
8701+
8702+ while (cri) {
8703+ *swd = (struct swcr_data *) kmalloc(sizeof(struct swcr_data),
8704+ SLAB_ATOMIC);
8705+ if (*swd == NULL) {
8706+ swcr_freesession(NULL, i);
8707+ dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
8708+ return ENOBUFS;
8709+ }
8710+ memset(*swd, 0, sizeof(struct swcr_data));
8711+
8712+ if (cri->cri_alg < 0 ||
8713+ cri->cri_alg>=sizeof(crypto_details)/sizeof(crypto_details[0])){
8714+ printk("cryptosoft: Unknown algorithm 0x%x\n", cri->cri_alg);
8715+ swcr_freesession(NULL, i);
8716+ return EINVAL;
8717+ }
8718+
8719+ algo = crypto_details[cri->cri_alg].alg_name;
8720+ if (!algo || !*algo) {
8721+ printk("cryptosoft: Unsupported algorithm 0x%x\n", cri->cri_alg);
8722+ swcr_freesession(NULL, i);
8723+ return EINVAL;
8724+ }
8725+
8726+ mode = crypto_details[cri->cri_alg].mode;
8727+ (*swd)->sw_type = crypto_details[cri->cri_alg].sw_type;
8728+ (*swd)->sw_alg = cri->cri_alg;
8729+
8730+ /* Algorithm specific configuration */
8731+ switch (cri->cri_alg) {
8732+ case CRYPTO_NULL_CBC:
8733+ cri->cri_klen = 0; /* make it work with crypto API */
8734+ break;
8735+ default:
8736+ break;
8737+ }
8738+
8739+ if ((*swd)->sw_type & SW_TYPE_BLKCIPHER) {
8740+ dprintk("%s crypto_alloc_*blkcipher(%s, 0x%x)\n", __FUNCTION__,
8741+ algo, mode);
8742+
8743+ /* try async first */
8744+ (*swd)->sw_tfm = swcr_no_ablk ? NULL :
8745+ crypto_ablkcipher_tfm(crypto_alloc_ablkcipher(algo, 0, 0));
8746+ if ((*swd)->sw_tfm) {
8747+ dprintk("%s %s cipher is async\n", __FUNCTION__, algo);
8748+ (*swd)->sw_type |= SW_TYPE_ASYNC;
8749+ } else {
8750+ dprintk("%s %s cipher is sync\n", __FUNCTION__, algo);
8751+ (*swd)->sw_tfm = crypto_blkcipher_tfm(
8752+ crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC));
8753+ }
8754+ if (!(*swd)->sw_tfm) {
8755+ dprintk("cryptosoft: crypto_alloc_blkcipher failed(%s, 0x%x)\n",
8756+ algo,mode);
8757+ swcr_freesession(NULL, i);
8758+ return EINVAL;
8759+ }
8760+
8761+ if (debug) {
8762+ dprintk("%s key:cri->cri_klen=%d,(cri->cri_klen + 7)/8=%d",
8763+ __FUNCTION__, cri->cri_klen, (cri->cri_klen + 7) / 8);
8764+ for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
8765+ dprintk("%s0x%x", (i % 8) ? " " : "\n ",
8766+ cri->cri_key[i] & 0xff);
8767+ dprintk("\n");
8768+ }
8769+ if ((*swd)->sw_type & SW_TYPE_ASYNC) {
8770+ /* OCF doesn't enforce keys */
8771+ crypto_ablkcipher_set_flags(
8772+ __crypto_ablkcipher_cast((*swd)->sw_tfm),
8773+ CRYPTO_TFM_REQ_WEAK_KEY);
8774+ error = crypto_ablkcipher_setkey(
8775+ __crypto_ablkcipher_cast((*swd)->sw_tfm),
8776+ cri->cri_key, (cri->cri_klen + 7) / 8);
8777+ } else {
8778+ /* OCF doesn't enforce keys */
8779+ crypto_blkcipher_set_flags(
8780+ crypto_blkcipher_cast((*swd)->sw_tfm),
8781+ CRYPTO_TFM_REQ_WEAK_KEY);
8782+ error = crypto_blkcipher_setkey(
8783+ crypto_blkcipher_cast((*swd)->sw_tfm),
8784+ cri->cri_key, (cri->cri_klen + 7) / 8);
8785+ }
8786+ if (error) {
8787+ printk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n", error,
8788+ (*swd)->sw_tfm->crt_flags);
8789+ swcr_freesession(NULL, i);
8790+ return error;
8791+ }
8792+ } else if ((*swd)->sw_type & (SW_TYPE_HMAC | SW_TYPE_HASH)) {
8793+ dprintk("%s crypto_alloc_*hash(%s, 0x%x)\n", __FUNCTION__,
8794+ algo, mode);
8795+
8796+ /* try async first */
8797+ (*swd)->sw_tfm = swcr_no_ahash ? NULL :
8798+ crypto_ahash_tfm(crypto_alloc_ahash(algo, 0, 0));
8799+ if ((*swd)->sw_tfm) {
8800+ dprintk("%s %s hash is async\n", __FUNCTION__, algo);
8801+ (*swd)->sw_type |= SW_TYPE_ASYNC;
8802+ } else {
8803+ dprintk("%s %s hash is sync\n", __FUNCTION__, algo);
8804+ (*swd)->sw_tfm = crypto_hash_tfm(
8805+ crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC));
8806+ }
8807+
8808+ if (!(*swd)->sw_tfm) {
8809+ dprintk("cryptosoft: crypto_alloc_hash failed(%s,0x%x)\n",
8810+ algo, mode);
8811+ swcr_freesession(NULL, i);
8812+ return EINVAL;
8813+ }
8814+
8815+ (*swd)->u.hmac.sw_klen = (cri->cri_klen + 7) / 8;
8816+ (*swd)->u.hmac.sw_key = (char *)kmalloc((*swd)->u.hmac.sw_klen,
8817+ SLAB_ATOMIC);
8818+ if ((*swd)->u.hmac.sw_key == NULL) {
8819+ swcr_freesession(NULL, i);
8820+ dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
8821+ return ENOBUFS;
8822+ }
8823+ memcpy((*swd)->u.hmac.sw_key, cri->cri_key, (*swd)->u.hmac.sw_klen);
8824+ if (cri->cri_mlen) {
8825+ (*swd)->u.hmac.sw_mlen = cri->cri_mlen;
8826+ } else if ((*swd)->sw_type & SW_TYPE_ASYNC) {
8827+ (*swd)->u.hmac.sw_mlen = crypto_ahash_digestsize(
8828+ __crypto_ahash_cast((*swd)->sw_tfm));
8829+ } else {
8830+ (*swd)->u.hmac.sw_mlen = crypto_hash_digestsize(
8831+ crypto_hash_cast((*swd)->sw_tfm));
8832+ }
8833+ } else if ((*swd)->sw_type & SW_TYPE_COMP) {
8834+ (*swd)->sw_tfm = crypto_comp_tfm(
8835+ crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC));
8836+ if (!(*swd)->sw_tfm) {
8837+ dprintk("cryptosoft: crypto_alloc_comp failed(%s,0x%x)\n",
8838+ algo, mode);
8839+ swcr_freesession(NULL, i);
8840+ return EINVAL;
8841+ }
8842+ (*swd)->u.sw_comp_buf = kmalloc(CRYPTO_MAX_DATA_LEN, SLAB_ATOMIC);
8843+ if ((*swd)->u.sw_comp_buf == NULL) {
8844+ swcr_freesession(NULL, i);
8845+ dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
8846+ return ENOBUFS;
8847+ }
8848+ } else {
8849+ printk("cryptosoft: Unhandled sw_type %d\n", (*swd)->sw_type);
8850+ swcr_freesession(NULL, i);
8851+ return EINVAL;
8852+ }
8853+
8854+ cri = cri->cri_next;
8855+ swd = &((*swd)->sw_next);
8856+ }
8857+ return 0;
8858+}
8859+
8860+/*
8861+ * Free a session.
8862+ */
8863+static int
8864+swcr_freesession(device_t dev, u_int64_t tid)
8865+{
8866+ struct swcr_data *swd;
8867+ u_int32_t sid = CRYPTO_SESID2LID(tid);
8868+
8869+ dprintk("%s()\n", __FUNCTION__);
8870+ if (sid > swcr_sesnum || swcr_sessions == NULL ||
8871+ swcr_sessions[sid] == NULL) {
8872+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
8873+ return(EINVAL);
8874+ }
8875+
8876+ /* Silently accept and return */
8877+ if (sid == 0)
8878+ return(0);
8879+
8880+ while ((swd = swcr_sessions[sid]) != NULL) {
8881+ swcr_sessions[sid] = swd->sw_next;
8882+ if (swd->sw_tfm) {
8883+ switch (swd->sw_type & SW_TYPE_ALG_AMASK) {
8884+#ifdef HAVE_AHASH
8885+ case SW_TYPE_AHMAC:
8886+ case SW_TYPE_AHASH:
8887+ crypto_free_ahash(__crypto_ahash_cast(swd->sw_tfm));
8888+ break;
8889+#endif
8890+#ifdef HAVE_ABLKCIPHER
8891+ case SW_TYPE_ABLKCIPHER:
8892+ crypto_free_ablkcipher(__crypto_ablkcipher_cast(swd->sw_tfm));
8893+ break;
8894+#endif
8895+ case SW_TYPE_BLKCIPHER:
8896+ crypto_free_blkcipher(crypto_blkcipher_cast(swd->sw_tfm));
8897+ break;
8898+ case SW_TYPE_HMAC:
8899+ case SW_TYPE_HASH:
8900+ crypto_free_hash(crypto_hash_cast(swd->sw_tfm));
8901+ break;
8902+ case SW_TYPE_COMP:
8903+ crypto_free_comp(crypto_comp_cast(swd->sw_tfm));
8904+ default:
8905+ crypto_free_tfm(swd->sw_tfm);
8906+ break;
8907+ }
8908+ swd->sw_tfm = NULL;
8909+ }
8910+ if (swd->sw_type & SW_TYPE_COMP) {
8911+ if (swd->u.sw_comp_buf)
8912+ kfree(swd->u.sw_comp_buf);
8913+ } else {
8914+ if (swd->u.hmac.sw_key)
8915+ kfree(swd->u.hmac.sw_key);
8916+ }
8917+ kfree(swd);
8918+ }
8919+ return 0;
8920+}
8921+
8922+#if defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH)
8923+/* older kernels had no async interface */
8924+
8925+static void swcr_process_callback(struct crypto_async_request *creq, int err)
8926+{
8927+ struct swcr_req *req = creq->data;
8928+
8929+ dprintk("%s()\n", __FUNCTION__);
8930+ if (err) {
8931+ if (err == -EINPROGRESS)
8932+ return;
8933+ dprintk("%s() fail %d\n", __FUNCTION__, -err);
8934+ req->crp->crp_etype = -err;
8935+ goto done;
8936+ }
8937+
8938+ switch (req->sw->sw_type & SW_TYPE_ALG_AMASK) {
8939+ case SW_TYPE_AHMAC:
8940+ case SW_TYPE_AHASH:
8941+ crypto_copyback(req->crp->crp_flags, req->crp->crp_buf,
8942+ req->crd->crd_inject, req->sw->u.hmac.sw_mlen, req->result);
8943+ ahash_request_free(req->crypto_req);
8944+ break;
8945+ case SW_TYPE_ABLKCIPHER:
8946+ ablkcipher_request_free(req->crypto_req);
8947+ break;
8948+ default:
8949+ req->crp->crp_etype = EINVAL;
8950+ goto done;
8951+ }
8952+
8953+ req->crd = req->crd->crd_next;
8954+ if (req->crd) {
8955+ swcr_process_req(req);
8956+ return;
8957+ }
8958+
8959+done:
8960+ dprintk("%s crypto_done %p\n", __FUNCTION__, req);
8961+ crypto_done(req->crp);
8962+ kmem_cache_free(swcr_req_cache, req);
8963+}
8964+#endif /* defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH) */
8965+
8966+
8967+static void swcr_process_req(struct swcr_req *req)
8968+{
8969+ struct swcr_data *sw;
8970+ struct cryptop *crp = req->crp;
8971+ struct cryptodesc *crd = req->crd;
8972+ struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
8973+ struct uio *uiop = (struct uio *) crp->crp_buf;
8974+ int sg_num, sg_len, skip;
8975+
8976+ dprintk("%s()\n", __FUNCTION__);
8977+
8978+ /*
8979+ * Find the crypto context.
8980+ *
8981+ * XXX Note that the logic here prevents us from having
8982+ * XXX the same algorithm multiple times in a session
8983+ * XXX (or rather, we can but it won't give us the right
8984+ * XXX results). To do that, we'd need some way of differentiating
8985+ * XXX between the various instances of an algorithm (so we can
8986+ * XXX locate the correct crypto context).
8987+ */
8988+ for (sw = req->sw_head; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next)
8989+ ;
8990+
8991+ /* No such context ? */
8992+ if (sw == NULL) {
8993+ crp->crp_etype = EINVAL;
8994+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
8995+ goto done;
8996+ }
8997+
8998+ req->sw = sw;
8999+ skip = crd->crd_skip;
9000+
9001+ /*
9002+ * setup the SG list skip from the start of the buffer
9003+ */
9004+ memset(req->sg, 0, sizeof(req->sg));
9005+ sg_init_table(req->sg, SCATTERLIST_MAX);
9006+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
9007+ int i, len;
9008+
9009+ sg_num = 0;
9010+ sg_len = 0;
9011+
9012+ if (skip < skb_headlen(skb)) {
9013+ len = skb_headlen(skb) - skip;
9014+ if (len + sg_len > crd->crd_len)
9015+ len = crd->crd_len - sg_len;
9016+ sg_set_page(&req->sg[sg_num],
9017+ virt_to_page(skb->data + skip), len,
9018+ offset_in_page(skb->data + skip));
9019+ sg_len += len;
9020+ sg_num++;
9021+ skip = 0;
9022+ } else
9023+ skip -= skb_headlen(skb);
9024+
9025+ for (i = 0; sg_len < crd->crd_len &&
9026+ i < skb_shinfo(skb)->nr_frags &&
9027+ sg_num < SCATTERLIST_MAX; i++) {
9028+ if (skip < skb_shinfo(skb)->frags[i].size) {
9029+ len = skb_shinfo(skb)->frags[i].size - skip;
9030+ if (len + sg_len > crd->crd_len)
9031+ len = crd->crd_len - sg_len;
9032+ sg_set_page(&req->sg[sg_num],
9033+ skb_shinfo(skb)->frags[i].page,
9034+ len,
9035+ skb_shinfo(skb)->frags[i].page_offset + skip);
9036+ sg_len += len;
9037+ sg_num++;
9038+ skip = 0;
9039+ } else
9040+ skip -= skb_shinfo(skb)->frags[i].size;
9041+ }
9042+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
9043+ int len;
9044+
9045+ sg_len = 0;
9046+ for (sg_num = 0; sg_len < crd->crd_len &&
9047+ sg_num < uiop->uio_iovcnt &&
9048+ sg_num < SCATTERLIST_MAX; sg_num++) {
9049+ if (skip <= uiop->uio_iov[sg_num].iov_len) {
9050+ len = uiop->uio_iov[sg_num].iov_len - skip;
9051+ if (len + sg_len > crd->crd_len)
9052+ len = crd->crd_len - sg_len;
9053+ sg_set_page(&req->sg[sg_num],
9054+ virt_to_page(uiop->uio_iov[sg_num].iov_base+skip),
9055+ len,
9056+ offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
9057+ sg_len += len;
9058+ skip = 0;
9059+ } else
9060+ skip -= uiop->uio_iov[sg_num].iov_len;
9061+ }
9062+ } else {
9063+ sg_len = (crp->crp_ilen - skip);
9064+ if (sg_len > crd->crd_len)
9065+ sg_len = crd->crd_len;
9066+ sg_set_page(&req->sg[0], virt_to_page(crp->crp_buf + skip),
9067+ sg_len, offset_in_page(crp->crp_buf + skip));
9068+ sg_num = 1;
9069+ }
9070+
9071+ switch (sw->sw_type & SW_TYPE_ALG_AMASK) {
9072+
9073+#ifdef HAVE_AHASH
9074+ case SW_TYPE_AHMAC:
9075+ case SW_TYPE_AHASH:
9076+ {
9077+ int ret;
9078+
9079+ /* check we have room for the result */
9080+ if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
9081+ dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
9082+ "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
9083+ crd->crd_inject, sw->u.hmac.sw_mlen);
9084+ crp->crp_etype = EINVAL;
9085+ goto done;
9086+ }
9087+
9088+ req->crypto_req =
9089+ ahash_request_alloc(__crypto_ahash_cast(sw->sw_tfm),GFP_KERNEL);
9090+ if (!req->crypto_req) {
9091+ crp->crp_etype = ENOMEM;
9092+ dprintk("%s,%d: ENOMEM ahash_request_alloc", __FILE__, __LINE__);
9093+ goto done;
9094+ }
9095+
9096+ ahash_request_set_callback(req->crypto_req,
9097+ CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
9098+
9099+ memset(req->result, 0, sizeof(req->result));
9100+
9101+ if (sw->sw_type & SW_TYPE_AHMAC)
9102+ crypto_ahash_setkey(__crypto_ahash_cast(sw->sw_tfm),
9103+ sw->u.hmac.sw_key, sw->u.hmac.sw_klen);
9104+ ahash_request_set_crypt(req->crypto_req, req->sg, req->result, sg_len);
9105+ ret = crypto_ahash_digest(req->crypto_req);
9106+ switch (ret) {
9107+ case -EINPROGRESS:
9108+ case -EBUSY:
9109+ return;
9110+ default:
9111+ case 0:
9112+ dprintk("hash OP %s %d\n", ret ? "failed" : "success", ret);
9113+ crp->crp_etype = ret;
9114+ ahash_request_free(req->crypto_req);
9115+ goto done;
9116+ }
9117+ } break;
9118+#endif /* HAVE_AHASH */
9119+
9120+#ifdef HAVE_ABLKCIPHER
9121+ case SW_TYPE_ABLKCIPHER: {
9122+ int ret;
9123+ unsigned char *ivp = req->iv;
9124+ int ivsize =
9125+ crypto_ablkcipher_ivsize(__crypto_ablkcipher_cast(sw->sw_tfm));
9126+
9127+ if (sg_len < crypto_ablkcipher_blocksize(
9128+ __crypto_ablkcipher_cast(sw->sw_tfm))) {
9129+ crp->crp_etype = EINVAL;
9130+ dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
9131+ sg_len, crypto_ablkcipher_blocksize(
9132+ __crypto_ablkcipher_cast(sw->sw_tfm)));
9133+ goto done;
9134+ }
9135+
9136+ if (ivsize > sizeof(req->iv)) {
9137+ crp->crp_etype = EINVAL;
9138+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
9139+ goto done;
9140+ }
9141+
9142+ req->crypto_req = ablkcipher_request_alloc(
9143+ __crypto_ablkcipher_cast(sw->sw_tfm), GFP_KERNEL);
9144+ if (!req->crypto_req) {
9145+ crp->crp_etype = ENOMEM;
9146+ dprintk("%s,%d: ENOMEM ablkcipher_request_alloc",
9147+ __FILE__, __LINE__);
9148+ goto done;
9149+ }
9150+
9151+ ablkcipher_request_set_callback(req->crypto_req,
9152+ CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
9153+
9154+ if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
9155+ int i, error;
9156+
9157+ if (debug) {
9158+ dprintk("%s key:", __FUNCTION__);
9159+ for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
9160+ dprintk("%s0x%x", (i % 8) ? " " : "\n ",
9161+ crd->crd_key[i] & 0xff);
9162+ dprintk("\n");
9163+ }
9164+ /* OCF doesn't enforce keys */
9165+ crypto_ablkcipher_set_flags(__crypto_ablkcipher_cast(sw->sw_tfm),
9166+ CRYPTO_TFM_REQ_WEAK_KEY);
9167+ error = crypto_ablkcipher_setkey(
9168+ __crypto_ablkcipher_cast(sw->sw_tfm), crd->crd_key,
9169+ (crd->crd_klen + 7) / 8);
9170+ if (error) {
9171+ dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
9172+ error, sw->sw_tfm->crt_flags);
9173+ crp->crp_etype = -error;
9174+ }
9175+ }
9176+
9177+ if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
9178+
9179+ if (crd->crd_flags & CRD_F_IV_EXPLICIT)
9180+ ivp = crd->crd_iv;
9181+ else
9182+ get_random_bytes(ivp, ivsize);
9183+ /*
9184+ * do we have to copy the IV back to the buffer ?
9185+ */
9186+ if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
9187+ crypto_copyback(crp->crp_flags, crp->crp_buf,
9188+ crd->crd_inject, ivsize, (caddr_t)ivp);
9189+ }
9190+ ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
9191+ sg_len, ivp);
9192+ ret = crypto_ablkcipher_encrypt(req->crypto_req);
9193+
9194+ } else { /*decrypt */
9195+
9196+ if (crd->crd_flags & CRD_F_IV_EXPLICIT)
9197+ ivp = crd->crd_iv;
9198+ else
9199+ crypto_copydata(crp->crp_flags, crp->crp_buf,
9200+ crd->crd_inject, ivsize, (caddr_t)ivp);
9201+ ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
9202+ sg_len, ivp);
9203+ ret = crypto_ablkcipher_decrypt(req->crypto_req);
9204+ }
9205+
9206+ switch (ret) {
9207+ case -EINPROGRESS:
9208+ case -EBUSY:
9209+ return;
9210+ default:
9211+ case 0:
9212+ dprintk("crypto OP %s %d\n", ret ? "failed" : "success", ret);
9213+ crp->crp_etype = ret;
9214+ goto done;
9215+ }
9216+ } break;
9217+#endif /* HAVE_ABLKCIPHER */
9218+
9219+ case SW_TYPE_BLKCIPHER: {
9220+ unsigned char iv[EALG_MAX_BLOCK_LEN];
9221+ unsigned char *ivp = iv;
9222+ struct blkcipher_desc desc;
9223+ int ivsize = crypto_blkcipher_ivsize(crypto_blkcipher_cast(sw->sw_tfm));
9224+
9225+ if (sg_len < crypto_blkcipher_blocksize(
9226+ crypto_blkcipher_cast(sw->sw_tfm))) {
9227+ crp->crp_etype = EINVAL;
9228+ dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
9229+ sg_len, crypto_blkcipher_blocksize(
9230+ crypto_blkcipher_cast(sw->sw_tfm)));
9231+ goto done;
9232+ }
9233+
9234+ if (ivsize > sizeof(iv)) {
9235+ crp->crp_etype = EINVAL;
9236+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
9237+ goto done;
9238+ }
9239+
9240+ if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
9241+ int i, error;
9242+
9243+ if (debug) {
9244+ dprintk("%s key:", __FUNCTION__);
9245+ for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
9246+ dprintk("%s0x%x", (i % 8) ? " " : "\n ",
9247+ crd->crd_key[i] & 0xff);
9248+ dprintk("\n");
9249+ }
9250+ /* OCF doesn't enforce keys */
9251+ crypto_blkcipher_set_flags(crypto_blkcipher_cast(sw->sw_tfm),
9252+ CRYPTO_TFM_REQ_WEAK_KEY);
9253+ error = crypto_blkcipher_setkey(
9254+ crypto_blkcipher_cast(sw->sw_tfm), crd->crd_key,
9255+ (crd->crd_klen + 7) / 8);
9256+ if (error) {
9257+ dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
9258+ error, sw->sw_tfm->crt_flags);
9259+ crp->crp_etype = -error;
9260+ }
9261+ }
9262+
9263+ memset(&desc, 0, sizeof(desc));
9264+ desc.tfm = crypto_blkcipher_cast(sw->sw_tfm);
9265+
9266+ if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
9267+
9268+ if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
9269+ ivp = crd->crd_iv;
9270+ } else {
9271+ get_random_bytes(ivp, ivsize);
9272+ }
9273+ /*
9274+ * do we have to copy the IV back to the buffer ?
9275+ */
9276+ if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
9277+ crypto_copyback(crp->crp_flags, crp->crp_buf,
9278+ crd->crd_inject, ivsize, (caddr_t)ivp);
9279+ }
9280+ desc.info = ivp;
9281+ crypto_blkcipher_encrypt_iv(&desc, req->sg, req->sg, sg_len);
9282+
9283+ } else { /*decrypt */
9284+
9285+ if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
9286+ ivp = crd->crd_iv;
9287+ } else {
9288+ crypto_copydata(crp->crp_flags, crp->crp_buf,
9289+ crd->crd_inject, ivsize, (caddr_t)ivp);
9290+ }
9291+ desc.info = ivp;
9292+ crypto_blkcipher_decrypt_iv(&desc, req->sg, req->sg, sg_len);
9293+ }
9294+ } break;
9295+
9296+ case SW_TYPE_HMAC:
9297+ case SW_TYPE_HASH:
9298+ {
9299+ char result[HASH_MAX_LEN];
9300+ struct hash_desc desc;
9301+
9302+ /* check we have room for the result */
9303+ if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
9304+ dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
9305+ "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
9306+ crd->crd_inject, sw->u.hmac.sw_mlen);
9307+ crp->crp_etype = EINVAL;
9308+ goto done;
9309+ }
9310+
9311+ memset(&desc, 0, sizeof(desc));
9312+ desc.tfm = crypto_hash_cast(sw->sw_tfm);
9313+
9314+ memset(result, 0, sizeof(result));
9315+
9316+ if (sw->sw_type & SW_TYPE_HMAC) {
9317+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
9318+ crypto_hmac(sw->sw_tfm, sw->u.hmac.sw_key, &sw->u.hmac.sw_klen,
9319+ req->sg, sg_num, result);
9320+#else
9321+ crypto_hash_setkey(desc.tfm, sw->u.hmac.sw_key,
9322+ sw->u.hmac.sw_klen);
9323+ crypto_hash_digest(&desc, req->sg, sg_len, result);
9324+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
9325+
9326+ } else { /* SW_TYPE_HASH */
9327+ crypto_hash_digest(&desc, req->sg, sg_len, result);
9328+ }
9329+
9330+ crypto_copyback(crp->crp_flags, crp->crp_buf,
9331+ crd->crd_inject, sw->u.hmac.sw_mlen, result);
9332+ }
9333+ break;
9334+
9335+ case SW_TYPE_COMP: {
9336+ void *ibuf = NULL;
9337+ void *obuf = sw->u.sw_comp_buf;
9338+ int ilen = sg_len, olen = CRYPTO_MAX_DATA_LEN;
9339+ int ret = 0;
9340+
9341+ /*
9342+ * we need to use an additional copy if there is more than one
9343+ * input chunk since the kernel comp routines do not handle
9344+ * SG yet. Otherwise we just use the input buffer as is.
9345+ * Rather than allocate another buffer we just split the tmp
9346+ * buffer we already have.
9347+ * Perhaps we should just use zlib directly ?
9348+ */
9349+ if (sg_num > 1) {
9350+ int blk;
9351+
9352+ ibuf = obuf;
9353+ for (blk = 0; blk < sg_num; blk++) {
9354+ memcpy(obuf, sg_virt(&req->sg[blk]),
9355+ req->sg[blk].length);
9356+ obuf += req->sg[blk].length;
9357+ }
9358+ olen -= sg_len;
9359+ } else
9360+ ibuf = sg_virt(&req->sg[0]);
9361+
9362+ if (crd->crd_flags & CRD_F_ENCRYPT) { /* compress */
9363+ ret = crypto_comp_compress(crypto_comp_cast(sw->sw_tfm),
9364+ ibuf, ilen, obuf, &olen);
9365+ if (!ret && olen > crd->crd_len) {
9366+ dprintk("cryptosoft: ERANGE compress %d into %d\n",
9367+ crd->crd_len, olen);
9368+ if (swcr_fail_if_compression_grows)
9369+ ret = ERANGE;
9370+ }
9371+ } else { /* decompress */
9372+ ret = crypto_comp_decompress(crypto_comp_cast(sw->sw_tfm),
9373+ ibuf, ilen, obuf, &olen);
9374+ if (!ret && (olen + crd->crd_inject) > crp->crp_olen) {
9375+ dprintk("cryptosoft: ETOOSMALL decompress %d into %d, "
9376+ "space for %d,at offset %d\n",
9377+ crd->crd_len, olen, crp->crp_olen, crd->crd_inject);
9378+ ret = ETOOSMALL;
9379+ }
9380+ }
9381+ if (ret)
9382+ dprintk("%s,%d: ret = %d\n", __FILE__, __LINE__, ret);
9383+
9384+ /*
9385+ * on success copy result back,
9386+ * linux crpyto API returns -errno, we need to fix that
9387+ */
9388+ crp->crp_etype = ret < 0 ? -ret : ret;
9389+ if (ret == 0) {
9390+ /* copy back the result and return it's size */
9391+ crypto_copyback(crp->crp_flags, crp->crp_buf,
9392+ crd->crd_inject, olen, obuf);
9393+ crp->crp_olen = olen;
9394+ }
9395+
9396+
9397+ } break;
9398+
9399+ default:
9400+ /* Unknown/unsupported algorithm */
9401+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
9402+ crp->crp_etype = EINVAL;
9403+ goto done;
9404+ }
9405+
9406+done:
9407+ crypto_done(crp);
9408+ kmem_cache_free(swcr_req_cache, req);
9409+}
9410+
9411+
9412+/*
9413+ * Process a crypto request.
9414+ */
9415+static int
9416+swcr_process(device_t dev, struct cryptop *crp, int hint)
9417+{
9418+ struct swcr_req *req = NULL;
9419+ u_int32_t lid;
9420+
9421+ dprintk("%s()\n", __FUNCTION__);
9422+ /* Sanity check */
9423+ if (crp == NULL) {
9424+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
9425+ return EINVAL;
9426+ }
9427+
9428+ crp->crp_etype = 0;
9429+
9430+ if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
9431+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
9432+ crp->crp_etype = EINVAL;
9433+ goto done;
9434+ }
9435+
9436+ lid = crp->crp_sid & 0xffffffff;
9437+ if (lid >= swcr_sesnum || lid == 0 || swcr_sessions == NULL ||
9438+ swcr_sessions[lid] == NULL) {
9439+ crp->crp_etype = ENOENT;
9440+ dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
9441+ goto done;
9442+ }
9443+
9444+ /*
9445+ * do some error checking outside of the loop for SKB and IOV processing
9446+ * this leaves us with valid skb or uiop pointers for later
9447+ */
9448+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
9449+ struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
9450+ if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
9451+ printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
9452+ skb_shinfo(skb)->nr_frags);
9453+ goto done;
9454+ }
9455+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
9456+ struct uio *uiop = (struct uio *) crp->crp_buf;
9457+ if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
9458+ printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
9459+ uiop->uio_iovcnt);
9460+ goto done;
9461+ }
9462+ }
9463+
9464+ /*
9465+ * setup a new request ready for queuing
9466+ */
9467+ req = kmem_cache_alloc(swcr_req_cache, SLAB_ATOMIC);
9468+ if (req == NULL) {
9469+ dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
9470+ crp->crp_etype = ENOMEM;
9471+ goto done;
9472+ }
9473+ memset(req, 0, sizeof(*req));
9474+
9475+ req->sw_head = swcr_sessions[lid];
9476+ req->crp = crp;
9477+ req->crd = crp->crp_desc;
9478+
9479+ swcr_process_req(req);
9480+ return 0;
9481+
9482+done:
9483+ crypto_done(crp);
9484+ if (req)
9485+ kmem_cache_free(swcr_req_cache, req);
9486+ return 0;
9487+}
9488+
9489+
9490+static int
9491+cryptosoft_init(void)
9492+{
9493+ int i, sw_type, mode;
9494+ char *algo;
9495+
9496+ dprintk("%s(%p)\n", __FUNCTION__, cryptosoft_init);
9497+
9498+ swcr_req_cache = kmem_cache_create("cryptosoft_req",
9499+ sizeof(struct swcr_req), 0, SLAB_HWCACHE_ALIGN, NULL
9500+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
9501+ , NULL
9502+#endif
9503+ );
9504+ if (!swcr_req_cache) {
9505+ printk("cryptosoft: failed to create request cache\n");
9506+ return -ENOENT;
9507+ }
9508+
9509+ softc_device_init(&swcr_softc, "cryptosoft", 0, swcr_methods);
9510+
9511+ swcr_id = crypto_get_driverid(softc_get_device(&swcr_softc),
9512+ CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
9513+ if (swcr_id < 0) {
9514+ printk("cryptosoft: Software crypto device cannot initialize!");
9515+ return -ENODEV;
9516+ }
9517+
9518+#define REGISTER(alg) \
9519+ crypto_register(swcr_id, alg, 0,0)
9520+
9521+ for (i = 0; i < sizeof(crypto_details)/sizeof(crypto_details[0]); i++) {
9522+ int found;
9523+
9524+ algo = crypto_details[i].alg_name;
9525+ if (!algo || !*algo) {
9526+ dprintk("%s:Algorithm %d not supported\n", __FUNCTION__, i);
9527+ continue;
9528+ }
9529+
9530+ mode = crypto_details[i].mode;
9531+ sw_type = crypto_details[i].sw_type;
9532+
9533+ found = 0;
9534+ switch (sw_type & SW_TYPE_ALG_MASK) {
9535+ case SW_TYPE_CIPHER:
9536+ found = crypto_has_cipher(algo, 0, CRYPTO_ALG_ASYNC);
9537+ break;
9538+ case SW_TYPE_HMAC:
9539+ found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
9540+ break;
9541+ case SW_TYPE_HASH:
9542+ found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
9543+ break;
9544+ case SW_TYPE_COMP:
9545+ found = crypto_has_comp(algo, 0, CRYPTO_ALG_ASYNC);
9546+ break;
9547+ case SW_TYPE_BLKCIPHER:
9548+ found = crypto_has_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);
9549+ if (!found && !swcr_no_ablk)
9550+ found = crypto_has_ablkcipher(algo, 0, 0);
9551+ break;
9552+ }
9553+ if (found) {
9554+ REGISTER(i);
9555+ } else {
9556+ dprintk("%s:Algorithm Type %d not supported (algorithm %d:'%s')\n",
9557+ __FUNCTION__, sw_type, i, algo);
9558+ }
9559+ }
9560+ return 0;
9561+}
9562+
9563+static void
9564+cryptosoft_exit(void)
9565+{
9566+ dprintk("%s()\n", __FUNCTION__);
9567+ crypto_unregister_all(swcr_id);
9568+ swcr_id = -1;
9569+ kmem_cache_destroy(swcr_req_cache);
9570+}
9571+
9572+late_initcall(cryptosoft_init);
9573+module_exit(cryptosoft_exit);
9574+
9575+MODULE_LICENSE("Dual BSD/GPL");
9576+MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
9577+MODULE_DESCRIPTION("Cryptosoft (OCF module for kernel crypto)");
9578diff --git a/crypto/ocf/ep80579/Makefile b/crypto/ocf/ep80579/Makefile
9579new file mode 100644
9580index 0000000..e488374
9581--- /dev/null
9582+++ b/crypto/ocf/ep80579/Makefile
9583@@ -0,0 +1,119 @@
9584+#########################################################################
9585+#
9586+# Targets supported
9587+# all - builds everything and installs
9588+# install - identical to all
9589+# depend - build dependencies
9590+# clean - clears derived objects except the .depend files
9591+# distclean- clears all derived objects and the .depend file
9592+#
9593+# @par
9594+# This file is provided under a dual BSD/GPLv2 license. When using or
9595+# redistributing this file, you may do so under either license.
9596+#
9597+# GPL LICENSE SUMMARY
9598+#
9599+# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
9600+#
9601+# This program is free software; you can redistribute it and/or modify
9602+# it under the terms of version 2 of the GNU General Public License as
9603+# published by the Free Software Foundation.
9604+#
9605+# This program is distributed in the hope that it will be useful, but
9606+# WITHOUT ANY WARRANTY; without even the implied warranty of
9607+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9608+# General Public License for more details.
9609+#
9610+# You should have received a copy of the GNU General Public License
9611+# along with this program; if not, write to the Free Software
9612+# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
9613+# The full GNU General Public License is included in this distribution
9614+# in the file called LICENSE.GPL.
9615+#
9616+# Contact Information:
9617+# Intel Corporation
9618+#
9619+# BSD LICENSE
9620+#
9621+# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
9622+# All rights reserved.
9623+#
9624+# Redistribution and use in source and binary forms, with or without
9625+# modification, are permitted provided that the following conditions
9626+# are met:
9627+#
9628+# * Redistributions of source code must retain the above copyright
9629+# notice, this list of conditions and the following disclaimer.
9630+# * Redistributions in binary form must reproduce the above copyright
9631+# notice, this list of conditions and the following disclaimer in
9632+# the documentation and/or other materials provided with the
9633+# distribution.
9634+# * Neither the name of Intel Corporation nor the names of its
9635+# contributors may be used to endorse or promote products derived
9636+# from this software without specific prior written permission.
9637+#
9638+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
9639+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
9640+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
9641+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9642+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9643+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9644+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
9645+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
9646+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9647+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
9648+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9649+#
9650+#
9651+# version: Security.L.1.0.2-229
9652+############################################################################
9653+
9654+
9655+####################Common variables and definitions########################
9656+
9657+ifndef ICP_ROOT
9658+$(warning ICP_ROOT is undefined. Please set the path to EP80579 release package directory \
9659+ "-> setenv ICP_ROOT <path>")
9660+all fastdep:
9661+ :
9662+else
9663+
9664+ifndef KERNEL_SOURCE_ROOT
9665+$(error KERNEL_SOURCE_ROOT is undefined. Please set the path to the kernel source directory \
9666+ "-> setenv KERNEL_SOURCE_ROOT <path>")
9667+endif
9668+
9669+# Ensure The ENV_DIR environmental var is defined.
9670+ifndef ICP_ENV_DIR
9671+$(error ICP_ENV_DIR is undefined. Please set the path to EP80579 driver environment.mk file \
9672+ "-> setenv ICP_ENV_DIR <path>")
9673+endif
9674+
9675+#Add your project environment Makefile
9676+include ${ICP_ENV_DIR}/environment.mk
9677+
9678+#include the makefile with all the default and common Make variable definitions
9679+include ${ICP_BUILDSYSTEM_PATH}/build_files/common.mk
9680+
9681+#Add the name for the executable, Library or Module output definitions
9682+OUTPUT_NAME= icp_ocf
9683+
9684+# List of Source Files to be compiled
9685+SOURCES= icp_common.c icp_sym.c icp_asym.c icp_ocf_linux.c
9686+
9687+#common includes between all supported OSes
9688+INCLUDES= -I ${ICP_API_DIR} -I${ICP_LAC_API} \
9689+-I${ICP_OCF_SRC_DIR}
9690+
9691+# The location of the os level makefile needs to be changed.
9692+include ${ICP_ENV_DIR}/${ICP_OS}_${ICP_OS_LEVEL}.mk
9693+
9694+# On the line directly below list the outputs you wish to build for,
9695+# e.g "lib_static lib_shared exe module" as shown below
9696+install: module
9697+
9698+###################Include rules makefiles########################
9699+include ${ICP_BUILDSYSTEM_PATH}/build_files/rules.mk
9700+###################End of Rules inclusion#########################
9701+
9702+endif
9703diff --git a/crypto/ocf/ep80579/icp_asym.c b/crypto/ocf/ep80579/icp_asym.c
9704new file mode 100644
9705index 0000000..ebdddc1
9706--- /dev/null
9707+++ b/crypto/ocf/ep80579/icp_asym.c
9708@@ -0,0 +1,1334 @@
9709+/***************************************************************************
9710+ *
9711+ * This file is provided under a dual BSD/GPLv2 license. When using or
9712+ * redistributing this file, you may do so under either license.
9713+ *
9714+ * GPL LICENSE SUMMARY
9715+ *
9716+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
9717+ *
9718+ * This program is free software; you can redistribute it and/or modify
9719+ * it under the terms of version 2 of the GNU General Public License as
9720+ * published by the Free Software Foundation.
9721+ *
9722+ * This program is distributed in the hope that it will be useful, but
9723+ * WITHOUT ANY WARRANTY; without even the implied warranty of
9724+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9725+ * General Public License for more details.
9726+ *
9727+ * You should have received a copy of the GNU General Public License
9728+ * along with this program; if not, write to the Free Software
9729+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
9730+ * The full GNU General Public License is included in this distribution
9731+ * in the file called LICENSE.GPL.
9732+ *
9733+ * Contact Information:
9734+ * Intel Corporation
9735+ *
9736+ * BSD LICENSE
9737+ *
9738+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
9739+ * All rights reserved.
9740+ *
9741+ * Redistribution and use in source and binary forms, with or without
9742+ * modification, are permitted provided that the following conditions
9743+ * are met:
9744+ *
9745+ * * Redistributions of source code must retain the above copyright
9746+ * notice, this list of conditions and the following disclaimer.
9747+ * * Redistributions in binary form must reproduce the above copyright
9748+ * notice, this list of conditions and the following disclaimer in
9749+ * the documentation and/or other materials provided with the
9750+ * distribution.
9751+ * * Neither the name of Intel Corporation nor the names of its
9752+ * contributors may be used to endorse or promote products derived
9753+ * from this software without specific prior written permission.
9754+ *
9755+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
9756+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
9757+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
9758+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9759+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9760+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9761+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
9762+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
9763+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9764+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
9765+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9766+ *
9767+ *
9768+ * version: Security.L.1.0.2-229
9769+ *
9770+ ***************************************************************************/
9771+
9772+#include "icp_ocf.h"
9773+
9774+/*The following define values (containing the word 'INDEX') are used to find
9775+the index of each input buffer of the crypto_kop struct (see OCF cryptodev.h).
9776+These values were found through analysis of the OCF OpenSSL patch. If the
9777+calling program uses different input buffer positions, these defines will have
9778+to be changed.*/
9779+
9780+/*DIFFIE HELLMAN buffer index values*/
9781+#define ICP_DH_KRP_PARAM_PRIME_INDEX (0)
9782+#define ICP_DH_KRP_PARAM_BASE_INDEX (1)
9783+#define ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX (2)
9784+#define ICP_DH_KRP_PARAM_RESULT_INDEX (3)
9785+
9786+/*MOD EXP buffer index values*/
9787+#define ICP_MOD_EXP_KRP_PARAM_BASE_INDEX (0)
9788+#define ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX (1)
9789+#define ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX (2)
9790+#define ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX (3)
9791+
9792+/*MOD EXP CRT buffer index values*/
9793+#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX (0)
9794+#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX (1)
9795+#define ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX (2)
9796+#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX (3)
9797+#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX (4)
9798+#define ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX (5)
9799+#define ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX (6)
9800+
9801+/*DSA sign buffer index values*/
9802+#define ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX (0)
9803+#define ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX (1)
9804+#define ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX (2)
9805+#define ICP_DSA_SIGN_KRP_PARAM_G_INDEX (3)
9806+#define ICP_DSA_SIGN_KRP_PARAM_X_INDEX (4)
9807+#define ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX (5)
9808+#define ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX (6)
9809+
9810+/*DSA verify buffer index values*/
9811+#define ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX (0)
9812+#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX (1)
9813+#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX (2)
9814+#define ICP_DSA_VERIFY_KRP_PARAM_G_INDEX (3)
9815+#define ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX (4)
9816+#define ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX (5)
9817+#define ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX (6)
9818+
9819+/*DSA sign prime Q vs random number K size check values*/
9820+#define DONT_RUN_LESS_THAN_CHECK (0)
9821+#define FAIL_A_IS_GREATER_THAN_B (1)
9822+#define FAIL_A_IS_EQUAL_TO_B (1)
9823+#define SUCCESS_A_IS_LESS_THAN_B (0)
9824+#define DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS (500)
9825+
9826+/* We need to set a cryptokp success value just in case it is set or allocated
9827+ and not set to zero outside of this module */
9828+#define CRYPTO_OP_SUCCESS (0)
9829+
9830+/*Function to compute Diffie Hellman (DH) phase 1 or phase 2 key values*/
9831+static int icp_ocfDrvDHComputeKey(struct cryptkop *krp);
9832+
9833+/*Function to compute a Modular Exponentiation (Mod Exp)*/
9834+static int icp_ocfDrvModExp(struct cryptkop *krp);
9835+
9836+/*Function to compute a Mod Exp using the Chinease Remainder Theorem*/
9837+static int icp_ocfDrvModExpCRT(struct cryptkop *krp);
9838+
9839+/*Helper function to compute whether the first big number argument is less than
9840+ the second big number argument */
9841+static int
9842+icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck);
9843+
9844+/*Function to sign an input with DSA R and S keys*/
9845+static int icp_ocfDrvDsaSign(struct cryptkop *krp);
9846+
9847+/*Function to Verify a DSA buffer signature*/
9848+static int icp_ocfDrvDsaVerify(struct cryptkop *krp);
9849+
9850+/*Callback function for DH operation*/
9851+static void
9852+icp_ocfDrvDhP1CallBack(void *callbackTag,
9853+ CpaStatus status,
9854+ void *pOpData, CpaFlatBuffer * pLocalOctetStringPV);
9855+
9856+/*Callback function for ME operation*/
9857+static void
9858+icp_ocfDrvModExpCallBack(void *callbackTag,
9859+ CpaStatus status,
9860+ void *pOpData, CpaFlatBuffer * pResult);
9861+
9862+/*Callback function for ME CRT operation*/
9863+static void
9864+icp_ocfDrvModExpCRTCallBack(void *callbackTag,
9865+ CpaStatus status,
9866+ void *pOpData, CpaFlatBuffer * pOutputData);
9867+
9868+/*Callback function for DSA sign operation*/
9869+static void
9870+icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
9871+ CpaStatus status,
9872+ void *pOpData,
9873+ CpaBoolean protocolStatus,
9874+ CpaFlatBuffer * pR, CpaFlatBuffer * pS);
9875+
9876+/*Callback function for DSA Verify operation*/
9877+static void
9878+icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
9879+ CpaStatus status,
9880+ void *pOpData, CpaBoolean verifyStatus);
9881+
9882+/* Name : icp_ocfDrvPkeProcess
9883+ *
9884+ * Description : This function will choose which PKE process to follow
9885+ * based on the input arguments
9886+ */
9887+int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint)
9888+{
9889+ CpaStatus lacStatus = CPA_STATUS_SUCCESS;
9890+
9891+ if (NULL == krp) {
9892+ DPRINTK("%s(): Invalid input parameters, cryptkop = %p\n",
9893+ __FUNCTION__, krp);
9894+ return EINVAL;
9895+ }
9896+
9897+ if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
9898+ krp->krp_status = ECANCELED;
9899+ return ECANCELED;
9900+ }
9901+
9902+ switch (krp->krp_op) {
9903+ case CRK_DH_COMPUTE_KEY:
9904+ DPRINTK("%s() doing DH_COMPUTE_KEY\n", __FUNCTION__);
9905+ lacStatus = icp_ocfDrvDHComputeKey(krp);
9906+ if (CPA_STATUS_SUCCESS != lacStatus) {
9907+ EPRINTK("%s(): icp_ocfDrvDHComputeKey failed "
9908+ "(%d).\n", __FUNCTION__, lacStatus);
9909+ krp->krp_status = ECANCELED;
9910+ return ECANCELED;
9911+ }
9912+
9913+ break;
9914+
9915+ case CRK_MOD_EXP:
9916+ DPRINTK("%s() doing MOD_EXP \n", __FUNCTION__);
9917+ lacStatus = icp_ocfDrvModExp(krp);
9918+ if (CPA_STATUS_SUCCESS != lacStatus) {
9919+ EPRINTK("%s(): icp_ocfDrvModExp failed (%d).\n",
9920+ __FUNCTION__, lacStatus);
9921+ krp->krp_status = ECANCELED;
9922+ return ECANCELED;
9923+ }
9924+
9925+ break;
9926+
9927+ case CRK_MOD_EXP_CRT:
9928+ DPRINTK("%s() doing MOD_EXP_CRT \n", __FUNCTION__);
9929+ lacStatus = icp_ocfDrvModExpCRT(krp);
9930+ if (CPA_STATUS_SUCCESS != lacStatus) {
9931+ EPRINTK("%s(): icp_ocfDrvModExpCRT "
9932+ "failed (%d).\n", __FUNCTION__, lacStatus);
9933+ krp->krp_status = ECANCELED;
9934+ return ECANCELED;
9935+ }
9936+
9937+ break;
9938+
9939+ case CRK_DSA_SIGN:
9940+ DPRINTK("%s() doing DSA_SIGN \n", __FUNCTION__);
9941+ lacStatus = icp_ocfDrvDsaSign(krp);
9942+ if (CPA_STATUS_SUCCESS != lacStatus) {
9943+ EPRINTK("%s(): icp_ocfDrvDsaSign "
9944+ "failed (%d).\n", __FUNCTION__, lacStatus);
9945+ krp->krp_status = ECANCELED;
9946+ return ECANCELED;
9947+ }
9948+
9949+ break;
9950+
9951+ case CRK_DSA_VERIFY:
9952+ DPRINTK("%s() doing DSA_VERIFY \n", __FUNCTION__);
9953+ lacStatus = icp_ocfDrvDsaVerify(krp);
9954+ if (CPA_STATUS_SUCCESS != lacStatus) {
9955+ EPRINTK("%s(): icp_ocfDrvDsaVerify "
9956+ "failed (%d).\n", __FUNCTION__, lacStatus);
9957+ krp->krp_status = ECANCELED;
9958+ return ECANCELED;
9959+ }
9960+
9961+ break;
9962+
9963+ default:
9964+ EPRINTK("%s(): Asymettric function not "
9965+ "supported (%d).\n", __FUNCTION__, krp->krp_op);
9966+ krp->krp_status = EOPNOTSUPP;
9967+ return EOPNOTSUPP;
9968+ }
9969+
9970+ return ICP_OCF_DRV_STATUS_SUCCESS;
9971+}
9972+
9973+/* Name : icp_ocfDrvSwapBytes
9974+ *
9975+ * Description : This function is used to swap the byte order of a buffer.
9976+ * It has been seen that in general we are passed little endian byte order
9977+ * buffers, but LAC only accepts big endian byte order buffers.
9978+ */
9979+static void inline icp_ocfDrvSwapBytes(u_int8_t * num, u_int32_t buff_len_bytes)
9980+{
9981+
9982+ int i;
9983+ u_int8_t *end_ptr;
9984+ u_int8_t hold_val;
9985+
9986+ end_ptr = num + (buff_len_bytes - 1);
9987+ buff_len_bytes = buff_len_bytes >> 1;
9988+ for (i = 0; i < buff_len_bytes; i++) {
9989+ hold_val = *num;
9990+ *num = *end_ptr;
9991+ num++;
9992+ *end_ptr = hold_val;
9993+ end_ptr--;
9994+ }
9995+}
9996+
9997+/* Name : icp_ocfDrvDHComputeKey
9998+ *
9999+ * Description : This function will map Diffie Hellman calls from OCF
10000+ * to the LAC API. OCF uses this function for Diffie Hellman Phase1 and
10001+ * Phase2. LAC has a separate Diffie Hellman Phase2 call, however both phases
10002+ * break down to a modular exponentiation.
10003+ */
10004+static int icp_ocfDrvDHComputeKey(struct cryptkop *krp)
10005+{
10006+ CpaStatus lacStatus = CPA_STATUS_SUCCESS;
10007+ void *callbackTag = NULL;
10008+ CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
10009+ CpaFlatBuffer *pLocalOctetStringPV = NULL;
10010+ uint32_t dh_prime_len_bytes = 0, dh_prime_len_bits = 0;
10011+
10012+ /* Input checks - check prime is a multiple of 8 bits to allow for
10013+ allocation later */
10014+ dh_prime_len_bits =
10015+ (krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_nbits);
10016+
10017+ /* LAC can reject prime lengths based on prime key sizes, we just
10018+ need to make sure we can allocate space for the base and
10019+ exponent buffers correctly */
10020+ if ((dh_prime_len_bits % NUM_BITS_IN_BYTE) != 0) {
10021+ APRINTK("%s(): Warning Prime number buffer size is not a "
10022+ "multiple of 8 bits\n", __FUNCTION__);
10023+ }
10024+
10025+ /* Result storage space should be the same size as the prime as this
10026+ value can take up the same amount of storage space */
10027+ if (dh_prime_len_bits !=
10028+ krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits) {
10029+ DPRINTK("%s(): Return Buffer must be the same size "
10030+ "as the Prime buffer\n", __FUNCTION__);
10031+ krp->krp_status = EINVAL;
10032+ return EINVAL;
10033+ }
10034+ /* Switch to size in bytes */
10035+ BITS_TO_BYTES(dh_prime_len_bytes, dh_prime_len_bits);
10036+
10037+ callbackTag = krp;
10038+
10039+/*All allocations are set to ICP_M_NOWAIT due to the possibility of getting
10040+called in interrupt context*/
10041+ pPhase1OpData = icp_kmem_cache_zalloc(drvDH_zone, ICP_M_NOWAIT);
10042+ if (NULL == pPhase1OpData) {
10043+ APRINTK("%s():Failed to get memory for key gen data\n",
10044+ __FUNCTION__);
10045+ krp->krp_status = ENOMEM;
10046+ return ENOMEM;
10047+ }
10048+
10049+ pLocalOctetStringPV =
10050+ icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
10051+ if (NULL == pLocalOctetStringPV) {
10052+ APRINTK("%s():Failed to get memory for pLocalOctetStringPV\n",
10053+ __FUNCTION__);
10054+ ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
10055+ krp->krp_status = ENOMEM;
10056+ return ENOMEM;
10057+ }
10058+
10059+ /* Link parameters */
10060+ pPhase1OpData->primeP.pData =
10061+ krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_p;
10062+
10063+ pPhase1OpData->primeP.dataLenInBytes = dh_prime_len_bytes;
10064+
10065+ icp_ocfDrvSwapBytes(pPhase1OpData->primeP.pData, dh_prime_len_bytes);
10066+
10067+ pPhase1OpData->baseG.pData =
10068+ krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_p;
10069+
10070+ BITS_TO_BYTES(pPhase1OpData->baseG.dataLenInBytes,
10071+ krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_nbits);
10072+
10073+ icp_ocfDrvSwapBytes(pPhase1OpData->baseG.pData,
10074+ pPhase1OpData->baseG.dataLenInBytes);
10075+
10076+ pPhase1OpData->privateValueX.pData =
10077+ krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].crp_p;
10078+
10079+ BITS_TO_BYTES(pPhase1OpData->privateValueX.dataLenInBytes,
10080+ krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].
10081+ crp_nbits);
10082+
10083+ icp_ocfDrvSwapBytes(pPhase1OpData->privateValueX.pData,
10084+ pPhase1OpData->privateValueX.dataLenInBytes);
10085+
10086+ /* Output parameters */
10087+ pLocalOctetStringPV->pData =
10088+ krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_p;
10089+
10090+ BITS_TO_BYTES(pLocalOctetStringPV->dataLenInBytes,
10091+ krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits);
10092+
10093+ lacStatus = cpaCyDhKeyGenPhase1(CPA_INSTANCE_HANDLE_SINGLE,
10094+ icp_ocfDrvDhP1CallBack,
10095+ callbackTag, pPhase1OpData,
10096+ pLocalOctetStringPV);
10097+
10098+ if (CPA_STATUS_SUCCESS != lacStatus) {
10099+ EPRINTK("%s(): DH Phase 1 Key Gen failed (%d).\n",
10100+ __FUNCTION__, lacStatus);
10101+ icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
10102+ ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
10103+ }
10104+
10105+ return lacStatus;
10106+}
10107+
10108+/* Name : icp_ocfDrvModExp
10109+ *
10110+ * Description : This function will map ordinary Modular Exponentiation calls
10111+ * from OCF to the LAC API.
10112+ *
10113+ */
10114+static int icp_ocfDrvModExp(struct cryptkop *krp)
10115+{
10116+ CpaStatus lacStatus = CPA_STATUS_SUCCESS;
10117+ void *callbackTag = NULL;
10118+ CpaCyLnModExpOpData *pModExpOpData = NULL;
10119+ CpaFlatBuffer *pResult = NULL;
10120+
10121+ if ((krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits %
10122+ NUM_BITS_IN_BYTE) != 0) {
10123+ DPRINTK("%s(): Warning - modulus buffer size (%d) is not a "
10124+ "multiple of 8 bits\n", __FUNCTION__,
10125+ krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
10126+ crp_nbits);
10127+ }
10128+
10129+ /* Result storage space should be the same size as the prime as this
10130+ value can take up the same amount of storage space */
10131+ if (krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits >
10132+ krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_nbits) {
10133+ APRINTK("%s(): Return Buffer size must be the same or"
10134+ " greater than the Modulus buffer\n", __FUNCTION__);
10135+ krp->krp_status = EINVAL;
10136+ return EINVAL;
10137+ }
10138+
10139+ callbackTag = krp;
10140+
10141+ pModExpOpData = icp_kmem_cache_zalloc(drvLnModExp_zone, ICP_M_NOWAIT);
10142+ if (NULL == pModExpOpData) {
10143+ APRINTK("%s():Failed to get memory for key gen data\n",
10144+ __FUNCTION__);
10145+ krp->krp_status = ENOMEM;
10146+ return ENOMEM;
10147+ }
10148+
10149+ pResult = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
10150+ if (NULL == pResult) {
10151+ APRINTK("%s():Failed to get memory for ModExp result\n",
10152+ __FUNCTION__);
10153+ ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);
10154+ krp->krp_status = ENOMEM;
10155+ return ENOMEM;
10156+ }
10157+
10158+ /* Link parameters */
10159+ pModExpOpData->modulus.pData =
10160+ krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_p;
10161+ BITS_TO_BYTES(pModExpOpData->modulus.dataLenInBytes,
10162+ krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
10163+ crp_nbits);
10164+
10165+ icp_ocfDrvSwapBytes(pModExpOpData->modulus.pData,
10166+ pModExpOpData->modulus.dataLenInBytes);
10167+
10168+ DPRINTK("%s : base (%d)\n", __FUNCTION__, krp->
10169+ krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits);
10170+ pModExpOpData->base.pData =
10171+ krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_p;
10172+ BITS_TO_BYTES(pModExpOpData->base.dataLenInBytes,
10173+ krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
10174+ crp_nbits);
10175+ icp_ocfDrvSwapBytes(pModExpOpData->base.pData,
10176+ pModExpOpData->base.dataLenInBytes);
10177+
10178+ pModExpOpData->exponent.pData =
10179+ krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].crp_p;
10180+ BITS_TO_BYTES(pModExpOpData->exponent.dataLenInBytes,
10181+ krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].
10182+ crp_nbits);
10183+
10184+ icp_ocfDrvSwapBytes(pModExpOpData->exponent.pData,
10185+ pModExpOpData->exponent.dataLenInBytes);
10186+ /* Output parameters */
10187+ pResult->pData =
10188+ krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_p,
10189+ BITS_TO_BYTES(pResult->dataLenInBytes,
10190+ krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].
10191+ crp_nbits);
10192+
10193+ lacStatus = cpaCyLnModExp(CPA_INSTANCE_HANDLE_SINGLE,
10194+ icp_ocfDrvModExpCallBack,
10195+ callbackTag, pModExpOpData, pResult);
10196+
10197+ if (CPA_STATUS_SUCCESS != lacStatus) {
10198+ EPRINTK("%s(): Mod Exp Operation failed (%d).\n",
10199+ __FUNCTION__, lacStatus);
10200+ krp->krp_status = ECANCELED;
10201+ icp_ocfDrvFreeFlatBuffer(pResult);
10202+ ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);
10203+ }
10204+
10205+ return lacStatus;
10206+}
10207+
10208+/* Name : icp_ocfDrvModExpCRT
10209+ *
10210+ * Description : This function will map ordinary Modular Exponentiation Chinese
10211+ * Remainder Theorem implementaion calls from OCF to the LAC API.
10212+ *
10213+ * Note : Mod Exp CRT for this driver is accelerated through LAC RSA type 2
10214+ * decrypt operation. Therefore P and Q input values must always be prime
10215+ * numbers. Although basic primality checks are done in LAC, it is up to the
10216+ * user to do any correct prime number checking before passing the inputs.
10217+ */
10218+static int icp_ocfDrvModExpCRT(struct cryptkop *krp)
10219+{
10220+ CpaStatus lacStatus = CPA_STATUS_SUCCESS;
10221+ CpaCyRsaDecryptOpData *rsaDecryptOpData = NULL;
10222+ void *callbackTag = NULL;
10223+ CpaFlatBuffer *pOutputData = NULL;
10224+
10225+ /*Parameter input checks are all done by LAC, no need to repeat
10226+ them here. */
10227+ callbackTag = krp;
10228+
10229+ rsaDecryptOpData =
10230+ icp_kmem_cache_zalloc(drvRSADecrypt_zone, ICP_M_NOWAIT);
10231+ if (NULL == rsaDecryptOpData) {
10232+ APRINTK("%s():Failed to get memory"
10233+ " for MOD EXP CRT Op data struct\n", __FUNCTION__);
10234+ krp->krp_status = ENOMEM;
10235+ return ENOMEM;
10236+ }
10237+
10238+ rsaDecryptOpData->pRecipientPrivateKey
10239+ = icp_kmem_cache_zalloc(drvRSAPrivateKey_zone, ICP_M_NOWAIT);
10240+ if (NULL == rsaDecryptOpData->pRecipientPrivateKey) {
10241+ APRINTK("%s():Failed to get memory for MOD EXP CRT"
10242+ " private key values struct\n", __FUNCTION__);
10243+ ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
10244+ krp->krp_status = ENOMEM;
10245+ return ENOMEM;
10246+ }
10247+
10248+ rsaDecryptOpData->pRecipientPrivateKey->
10249+ version = CPA_CY_RSA_VERSION_TWO_PRIME;
10250+ rsaDecryptOpData->pRecipientPrivateKey->
10251+ privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
10252+
10253+ pOutputData = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
10254+ if (NULL == pOutputData) {
10255+ APRINTK("%s():Failed to get memory"
10256+ " for MOD EXP CRT output data\n", __FUNCTION__);
10257+ ICP_CACHE_FREE(drvRSAPrivateKey_zone,
10258+ rsaDecryptOpData->pRecipientPrivateKey);
10259+ ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
10260+ krp->krp_status = ENOMEM;
10261+ return ENOMEM;
10262+ }
10263+
10264+ rsaDecryptOpData->pRecipientPrivateKey->
10265+ version = CPA_CY_RSA_VERSION_TWO_PRIME;
10266+ rsaDecryptOpData->pRecipientPrivateKey->
10267+ privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
10268+
10269+ /* Link parameters */
10270+ rsaDecryptOpData->inputData.pData =
10271+ krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].crp_p;
10272+ BITS_TO_BYTES(rsaDecryptOpData->inputData.dataLenInBytes,
10273+ krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].
10274+ crp_nbits);
10275+
10276+ icp_ocfDrvSwapBytes(rsaDecryptOpData->inputData.pData,
10277+ rsaDecryptOpData->inputData.dataLenInBytes);
10278+
10279+ rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime1P.pData =
10280+ krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].crp_p;
10281+ BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
10282+ prime1P.dataLenInBytes,
10283+ krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].
10284+ crp_nbits);
10285+
10286+ icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
10287+ privateKeyRep2.prime1P.pData,
10288+ rsaDecryptOpData->pRecipientPrivateKey->
10289+ privateKeyRep2.prime1P.dataLenInBytes);
10290+
10291+ rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime2Q.pData =
10292+ krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].crp_p;
10293+ BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
10294+ prime2Q.dataLenInBytes,
10295+ krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].
10296+ crp_nbits);
10297+
10298+ icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
10299+ privateKeyRep2.prime2Q.pData,
10300+ rsaDecryptOpData->pRecipientPrivateKey->
10301+ privateKeyRep2.prime2Q.dataLenInBytes);
10302+
10303+ rsaDecryptOpData->pRecipientPrivateKey->
10304+ privateKeyRep2.exponent1Dp.pData =
10305+ krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].crp_p;
10306+ BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
10307+ exponent1Dp.dataLenInBytes,
10308+ krp->
10309+ krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].
10310+ crp_nbits);
10311+
10312+ icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
10313+ privateKeyRep2.exponent1Dp.pData,
10314+ rsaDecryptOpData->pRecipientPrivateKey->
10315+ privateKeyRep2.exponent1Dp.dataLenInBytes);
10316+
10317+ rsaDecryptOpData->pRecipientPrivateKey->
10318+ privateKeyRep2.exponent2Dq.pData =
10319+ krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].crp_p;
10320+ BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
10321+ privateKeyRep2.exponent2Dq.dataLenInBytes,
10322+ krp->
10323+ krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].
10324+ crp_nbits);
10325+
10326+ icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
10327+ privateKeyRep2.exponent2Dq.pData,
10328+ rsaDecryptOpData->pRecipientPrivateKey->
10329+ privateKeyRep2.exponent2Dq.dataLenInBytes);
10330+
10331+ rsaDecryptOpData->pRecipientPrivateKey->
10332+ privateKeyRep2.coefficientQInv.pData =
10333+ krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].crp_p;
10334+ BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
10335+ privateKeyRep2.coefficientQInv.dataLenInBytes,
10336+ krp->
10337+ krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].
10338+ crp_nbits);
10339+
10340+ icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
10341+ privateKeyRep2.coefficientQInv.pData,
10342+ rsaDecryptOpData->pRecipientPrivateKey->
10343+ privateKeyRep2.coefficientQInv.dataLenInBytes);
10344+
10345+ /* Output Parameter */
10346+ pOutputData->pData =
10347+ krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].crp_p;
10348+ BITS_TO_BYTES(pOutputData->dataLenInBytes,
10349+ krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].
10350+ crp_nbits);
10351+
10352+ lacStatus = cpaCyRsaDecrypt(CPA_INSTANCE_HANDLE_SINGLE,
10353+ icp_ocfDrvModExpCRTCallBack,
10354+ callbackTag, rsaDecryptOpData, pOutputData);
10355+
10356+ if (CPA_STATUS_SUCCESS != lacStatus) {
10357+ EPRINTK("%s(): Mod Exp CRT Operation failed (%d).\n",
10358+ __FUNCTION__, lacStatus);
10359+ krp->krp_status = ECANCELED;
10360+ icp_ocfDrvFreeFlatBuffer(pOutputData);
10361+ ICP_CACHE_FREE(drvRSAPrivateKey_zone,
10362+ rsaDecryptOpData->pRecipientPrivateKey);
10363+ ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
10364+ }
10365+
10366+ return lacStatus;
10367+}
10368+
10369+/* Name : icp_ocfDrvCheckALessThanB
10370+ *
10371+ * Description : This function will check whether the first argument is less
10372+ * than the second. It is used to check whether the DSA RS sign Random K
10373+ * value is less than the Prime Q value (as defined in the specification)
10374+ *
10375+ */
10376+static int
10377+icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck)
10378+{
10379+
10380+ uint8_t *MSB_K = pK->pData;
10381+ uint8_t *MSB_Q = pQ->pData;
10382+ uint32_t buffer_lengths_in_bytes = pQ->dataLenInBytes;
10383+
10384+ if (DONT_RUN_LESS_THAN_CHECK == *doCheck) {
10385+ return FAIL_A_IS_GREATER_THAN_B;
10386+ }
10387+
10388+/*Check MSBs
10389+if A == B, check next MSB
10390+if A > B, return A_IS_GREATER_THAN_B
10391+if A < B, return A_IS_LESS_THAN_B (success)
10392+*/
10393+ while (*MSB_K == *MSB_Q) {
10394+ MSB_K++;
10395+ MSB_Q++;
10396+
10397+ buffer_lengths_in_bytes--;
10398+ if (0 == buffer_lengths_in_bytes) {
10399+ DPRINTK("%s() Buffers have equal value!!\n",
10400+ __FUNCTION__);
10401+ return FAIL_A_IS_EQUAL_TO_B;
10402+ }
10403+
10404+ }
10405+
10406+ if (*MSB_K < *MSB_Q) {
10407+ return SUCCESS_A_IS_LESS_THAN_B;
10408+ } else {
10409+ return FAIL_A_IS_GREATER_THAN_B;
10410+ }
10411+
10412+}
10413+
10414+/* Name : icp_ocfDrvDsaSign
10415+ *
10416+ * Description : This function will map DSA RS Sign from OCF to the LAC API.
10417+ *
10418+ * NOTE: From looking at OCF patch to OpenSSL and even the number of input
10419+ * parameters, OCF expects us to generate the random seed value. This value
10420+ * is generated and passed to LAC, however the number is discared in the
10421+ * callback and not returned to the user.
10422+ */
10423+static int icp_ocfDrvDsaSign(struct cryptkop *krp)
10424+{
10425+ CpaStatus lacStatus = CPA_STATUS_SUCCESS;
10426+ CpaCyDsaRSSignOpData *dsaRsSignOpData = NULL;
10427+ void *callbackTag = NULL;
10428+ CpaCyRandGenOpData randGenOpData;
10429+ int primeQSizeInBytes = 0;
10430+ int doCheck = 0;
10431+ CpaFlatBuffer randData;
10432+ CpaBoolean protocolStatus = CPA_FALSE;
10433+ CpaFlatBuffer *pR = NULL;
10434+ CpaFlatBuffer *pS = NULL;
10435+
10436+ callbackTag = krp;
10437+
10438+ BITS_TO_BYTES(primeQSizeInBytes,
10439+ krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
10440+ crp_nbits);
10441+
10442+ if (DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES != primeQSizeInBytes) {
10443+ APRINTK("%s(): DSA PRIME Q size not equal to the "
10444+ "FIPS defined 20bytes, = %d\n",
10445+ __FUNCTION__, primeQSizeInBytes);
10446+ krp->krp_status = EDOM;
10447+ return EDOM;
10448+ }
10449+
10450+ dsaRsSignOpData =
10451+ icp_kmem_cache_zalloc(drvDSARSSign_zone, ICP_M_NOWAIT);
10452+ if (NULL == dsaRsSignOpData) {
10453+ APRINTK("%s():Failed to get memory"
10454+ " for DSA RS Sign Op data struct\n", __FUNCTION__);
10455+ krp->krp_status = ENOMEM;
10456+ return ENOMEM;
10457+ }
10458+
10459+ dsaRsSignOpData->K.pData =
10460+ icp_kmem_cache_alloc(drvDSARSSignKValue_zone, ICP_M_NOWAIT);
10461+
10462+ if (NULL == dsaRsSignOpData->K.pData) {
10463+ APRINTK("%s():Failed to get memory"
10464+ " for DSA RS Sign Op Random value\n", __FUNCTION__);
10465+ ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
10466+ krp->krp_status = ENOMEM;
10467+ return ENOMEM;
10468+ }
10469+
10470+ pR = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
10471+ if (NULL == pR) {
10472+ APRINTK("%s():Failed to get memory"
10473+ " for DSA signature R\n", __FUNCTION__);
10474+ ICP_CACHE_FREE(drvDSARSSignKValue_zone,
10475+ dsaRsSignOpData->K.pData);
10476+ ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
10477+ krp->krp_status = ENOMEM;
10478+ return ENOMEM;
10479+ }
10480+
10481+ pS = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
10482+ if (NULL == pS) {
10483+ APRINTK("%s():Failed to get memory"
10484+ " for DSA signature S\n", __FUNCTION__);
10485+ icp_ocfDrvFreeFlatBuffer(pR);
10486+ ICP_CACHE_FREE(drvDSARSSignKValue_zone,
10487+ dsaRsSignOpData->K.pData);
10488+ ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
10489+ krp->krp_status = ENOMEM;
10490+ return ENOMEM;
10491+ }
10492+
10493+ /*link prime number parameter for ease of processing */
10494+ dsaRsSignOpData->P.pData =
10495+ krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].crp_p;
10496+ BITS_TO_BYTES(dsaRsSignOpData->P.dataLenInBytes,
10497+ krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].
10498+ crp_nbits);
10499+
10500+ icp_ocfDrvSwapBytes(dsaRsSignOpData->P.pData,
10501+ dsaRsSignOpData->P.dataLenInBytes);
10502+
10503+ dsaRsSignOpData->Q.pData =
10504+ krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].crp_p;
10505+ BITS_TO_BYTES(dsaRsSignOpData->Q.dataLenInBytes,
10506+ krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
10507+ crp_nbits);
10508+
10509+ icp_ocfDrvSwapBytes(dsaRsSignOpData->Q.pData,
10510+ dsaRsSignOpData->Q.dataLenInBytes);
10511+
10512+ /*generate random number with equal buffer size to Prime value Q,
10513+ but value less than Q */
10514+ dsaRsSignOpData->K.dataLenInBytes = dsaRsSignOpData->Q.dataLenInBytes;
10515+
10516+ randGenOpData.generateBits = CPA_TRUE;
10517+ randGenOpData.lenInBytes = dsaRsSignOpData->K.dataLenInBytes;
10518+
10519+ icp_ocfDrvPtrAndLenToFlatBuffer(dsaRsSignOpData->K.pData,
10520+ dsaRsSignOpData->K.dataLenInBytes,
10521+ &randData);
10522+
10523+ doCheck = 0;
10524+ while (icp_ocfDrvCheckALessThanB(&(dsaRsSignOpData->K),
10525+ &(dsaRsSignOpData->Q), &doCheck)) {
10526+
10527+ if (CPA_STATUS_SUCCESS
10528+ != cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
10529+ NULL, NULL, &randGenOpData, &randData)) {
10530+ APRINTK("%s(): ERROR - Failed to generate DSA RS Sign K"
10531+ "value\n", __FUNCTION__);
10532+ icp_ocfDrvFreeFlatBuffer(pS);
10533+ icp_ocfDrvFreeFlatBuffer(pR);
10534+ ICP_CACHE_FREE(drvDSARSSignKValue_zone,
10535+ dsaRsSignOpData->K.pData);
10536+ ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
10537+ krp->krp_status = EAGAIN;
10538+ return EAGAIN;
10539+ }
10540+
10541+ doCheck++;
10542+ if (DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS == doCheck) {
10543+ APRINTK("%s(): ERROR - Failed to find DSA RS Sign K "
10544+ "value less than Q value\n", __FUNCTION__);
10545+ icp_ocfDrvFreeFlatBuffer(pS);
10546+ icp_ocfDrvFreeFlatBuffer(pR);
10547+ ICP_CACHE_FREE(drvDSARSSignKValue_zone,
10548+ dsaRsSignOpData->K.pData);
10549+ ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
10550+ krp->krp_status = EAGAIN;
10551+ return EAGAIN;
10552+ }
10553+
10554+ }
10555+ /*Rand Data - no need to swap bytes for pK */
10556+
10557+ /* Link parameters */
10558+ dsaRsSignOpData->G.pData =
10559+ krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_p;
10560+ BITS_TO_BYTES(dsaRsSignOpData->G.dataLenInBytes,
10561+ krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_nbits);
10562+
10563+ icp_ocfDrvSwapBytes(dsaRsSignOpData->G.pData,
10564+ dsaRsSignOpData->G.dataLenInBytes);
10565+
10566+ dsaRsSignOpData->X.pData =
10567+ krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_p;
10568+ BITS_TO_BYTES(dsaRsSignOpData->X.dataLenInBytes,
10569+ krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_nbits);
10570+ icp_ocfDrvSwapBytes(dsaRsSignOpData->X.pData,
10571+ dsaRsSignOpData->X.dataLenInBytes);
10572+
10573+ /*OpenSSL dgst parameter is left in big endian byte order,
10574+ therefore no byte swap is required */
10575+ dsaRsSignOpData->M.pData =
10576+ krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].crp_p;
10577+ BITS_TO_BYTES(dsaRsSignOpData->M.dataLenInBytes,
10578+ krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].
10579+ crp_nbits);
10580+
10581+ /* Output Parameters */
10582+ pS->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].crp_p;
10583+ BITS_TO_BYTES(pS->dataLenInBytes,
10584+ krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].
10585+ crp_nbits);
10586+
10587+ pR->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].crp_p;
10588+ BITS_TO_BYTES(pR->dataLenInBytes,
10589+ krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].
10590+ crp_nbits);
10591+
10592+ lacStatus = cpaCyDsaSignRS(CPA_INSTANCE_HANDLE_SINGLE,
10593+ icp_ocfDrvDsaRSSignCallBack,
10594+ callbackTag, dsaRsSignOpData,
10595+ &protocolStatus, pR, pS);
10596+
10597+ if (CPA_STATUS_SUCCESS != lacStatus) {
10598+ EPRINTK("%s(): DSA RS Sign Operation failed (%d).\n",
10599+ __FUNCTION__, lacStatus);
10600+ krp->krp_status = ECANCELED;
10601+ icp_ocfDrvFreeFlatBuffer(pS);
10602+ icp_ocfDrvFreeFlatBuffer(pR);
10603+ ICP_CACHE_FREE(drvDSARSSignKValue_zone,
10604+ dsaRsSignOpData->K.pData);
10605+ ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
10606+ }
10607+
10608+ return lacStatus;
10609+}
10610+
10611+/* Name : icp_ocfDrvDsaVerify
10612+ *
10613+ * Description : This function will map DSA RS Verify from OCF to the LAC API.
10614+ *
10615+ */
10616+static int icp_ocfDrvDsaVerify(struct cryptkop *krp)
10617+{
10618+ CpaStatus lacStatus = CPA_STATUS_SUCCESS;
10619+ CpaCyDsaVerifyOpData *dsaVerifyOpData = NULL;
10620+ void *callbackTag = NULL;
10621+ CpaBoolean verifyStatus = CPA_FALSE;
10622+
10623+ callbackTag = krp;
10624+
10625+ dsaVerifyOpData =
10626+ icp_kmem_cache_zalloc(drvDSAVerify_zone, ICP_M_NOWAIT);
10627+ if (NULL == dsaVerifyOpData) {
10628+ APRINTK("%s():Failed to get memory"
10629+ " for DSA Verify Op data struct\n", __FUNCTION__);
10630+ krp->krp_status = ENOMEM;
10631+ return ENOMEM;
10632+ }
10633+
10634+ /* Link parameters */
10635+ dsaVerifyOpData->P.pData =
10636+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].crp_p;
10637+ BITS_TO_BYTES(dsaVerifyOpData->P.dataLenInBytes,
10638+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].
10639+ crp_nbits);
10640+ icp_ocfDrvSwapBytes(dsaVerifyOpData->P.pData,
10641+ dsaVerifyOpData->P.dataLenInBytes);
10642+
10643+ dsaVerifyOpData->Q.pData =
10644+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].crp_p;
10645+ BITS_TO_BYTES(dsaVerifyOpData->Q.dataLenInBytes,
10646+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].
10647+ crp_nbits);
10648+ icp_ocfDrvSwapBytes(dsaVerifyOpData->Q.pData,
10649+ dsaVerifyOpData->Q.dataLenInBytes);
10650+
10651+ dsaVerifyOpData->G.pData =
10652+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].crp_p;
10653+ BITS_TO_BYTES(dsaVerifyOpData->G.dataLenInBytes,
10654+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].
10655+ crp_nbits);
10656+ icp_ocfDrvSwapBytes(dsaVerifyOpData->G.pData,
10657+ dsaVerifyOpData->G.dataLenInBytes);
10658+
10659+ dsaVerifyOpData->Y.pData =
10660+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].crp_p;
10661+ BITS_TO_BYTES(dsaVerifyOpData->Y.dataLenInBytes,
10662+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].
10663+ crp_nbits);
10664+ icp_ocfDrvSwapBytes(dsaVerifyOpData->Y.pData,
10665+ dsaVerifyOpData->Y.dataLenInBytes);
10666+
10667+ /*OpenSSL dgst parameter is left in big endian byte order,
10668+ therefore no byte swap is required */
10669+ dsaVerifyOpData->M.pData =
10670+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].crp_p;
10671+ BITS_TO_BYTES(dsaVerifyOpData->M.dataLenInBytes,
10672+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].
10673+ crp_nbits);
10674+
10675+ dsaVerifyOpData->R.pData =
10676+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].crp_p;
10677+ BITS_TO_BYTES(dsaVerifyOpData->R.dataLenInBytes,
10678+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].
10679+ crp_nbits);
10680+ icp_ocfDrvSwapBytes(dsaVerifyOpData->R.pData,
10681+ dsaVerifyOpData->R.dataLenInBytes);
10682+
10683+ dsaVerifyOpData->S.pData =
10684+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].crp_p;
10685+ BITS_TO_BYTES(dsaVerifyOpData->S.dataLenInBytes,
10686+ krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].
10687+ crp_nbits);
10688+ icp_ocfDrvSwapBytes(dsaVerifyOpData->S.pData,
10689+ dsaVerifyOpData->S.dataLenInBytes);
10690+
10691+ lacStatus = cpaCyDsaVerify(CPA_INSTANCE_HANDLE_SINGLE,
10692+ icp_ocfDrvDsaVerifyCallBack,
10693+ callbackTag, dsaVerifyOpData, &verifyStatus);
10694+
10695+ if (CPA_STATUS_SUCCESS != lacStatus) {
10696+ EPRINTK("%s(): DSA Verify Operation failed (%d).\n",
10697+ __FUNCTION__, lacStatus);
10698+ ICP_CACHE_FREE(drvDSAVerify_zone, dsaVerifyOpData);
10699+ krp->krp_status = ECANCELED;
10700+ }
10701+
10702+ return lacStatus;
10703+}
10704+
10705+/* Name : icp_ocfDrvDhP1Callback
10706+ *
10707+ * Description : When this function returns it signifies that the LAC
10708+ * component has completed the DH operation.
10709+ */
10710+static void
10711+icp_ocfDrvDhP1CallBack(void *callbackTag,
10712+ CpaStatus status,
10713+ void *pOpData, CpaFlatBuffer * pLocalOctetStringPV)
10714+{
10715+ struct cryptkop *krp = NULL;
10716+ CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
10717+
10718+ if (NULL == callbackTag) {
10719+ DPRINTK("%s(): Invalid input parameters - "
10720+ "callbackTag data is NULL\n", __FUNCTION__);
10721+ return;
10722+ }
10723+ krp = (struct cryptkop *)callbackTag;
10724+
10725+ if (NULL == pOpData) {
10726+ DPRINTK("%s(): Invalid input parameters - "
10727+ "Operation Data is NULL\n", __FUNCTION__);
10728+ krp->krp_status = ECANCELED;
10729+ crypto_kdone(krp);
10730+ return;
10731+ }
10732+ pPhase1OpData = (CpaCyDhPhase1KeyGenOpData *) pOpData;
10733+
10734+ if (NULL == pLocalOctetStringPV) {
10735+ DPRINTK("%s(): Invalid input parameters - "
10736+ "pLocalOctetStringPV Data is NULL\n", __FUNCTION__);
10737+ memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
10738+ ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
10739+ krp->krp_status = ECANCELED;
10740+ crypto_kdone(krp);
10741+ return;
10742+ }
10743+
10744+ if (CPA_STATUS_SUCCESS == status) {
10745+ krp->krp_status = CRYPTO_OP_SUCCESS;
10746+ } else {
10747+ APRINTK("%s(): Diffie Hellman Phase1 Key Gen failed - "
10748+ "Operation Status = %d\n", __FUNCTION__, status);
10749+ krp->krp_status = ECANCELED;
10750+ }
10751+
10752+ icp_ocfDrvSwapBytes(pLocalOctetStringPV->pData,
10753+ pLocalOctetStringPV->dataLenInBytes);
10754+
10755+ icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
10756+ memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
10757+ ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
10758+
10759+ crypto_kdone(krp);
10760+
10761+ return;
10762+}
10763+
10764+/* Name : icp_ocfDrvModExpCallBack
10765+ *
10766+ * Description : When this function returns it signifies that the LAC
10767+ * component has completed the Mod Exp operation.
10768+ */
10769+static void
10770+icp_ocfDrvModExpCallBack(void *callbackTag,
10771+ CpaStatus status,
10772+ void *pOpdata, CpaFlatBuffer * pResult)
10773+{
10774+ struct cryptkop *krp = NULL;
10775+ CpaCyLnModExpOpData *pLnModExpOpData = NULL;
10776+
10777+ if (NULL == callbackTag) {
10778+ DPRINTK("%s(): Invalid input parameters - "
10779+ "callbackTag data is NULL\n", __FUNCTION__);
10780+ return;
10781+ }
10782+ krp = (struct cryptkop *)callbackTag;
10783+
10784+ if (NULL == pOpdata) {
10785+ DPRINTK("%s(): Invalid Mod Exp input parameters - "
10786+ "Operation Data is NULL\n", __FUNCTION__);
10787+ krp->krp_status = ECANCELED;
10788+ crypto_kdone(krp);
10789+ return;
10790+ }
10791+ pLnModExpOpData = (CpaCyLnModExpOpData *) pOpdata;
10792+
10793+ if (NULL == pResult) {
10794+ DPRINTK("%s(): Invalid input parameters - "
10795+ "pResult data is NULL\n", __FUNCTION__);
10796+ krp->krp_status = ECANCELED;
10797+ memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
10798+ ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);
10799+ crypto_kdone(krp);
10800+ return;
10801+ }
10802+
10803+ if (CPA_STATUS_SUCCESS == status) {
10804+ krp->krp_status = CRYPTO_OP_SUCCESS;
10805+ } else {
10806+ APRINTK("%s(): LAC Mod Exp Operation failed - "
10807+ "Operation Status = %d\n", __FUNCTION__, status);
10808+ krp->krp_status = ECANCELED;
10809+ }
10810+
10811+ icp_ocfDrvSwapBytes(pResult->pData, pResult->dataLenInBytes);
10812+
10813+ /*switch base size value back to original */
10814+ if (pLnModExpOpData->base.pData ==
10815+ (uint8_t *) & (krp->
10816+ krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
10817+ crp_nbits)) {
10818+ *((uint32_t *) pLnModExpOpData->base.pData) =
10819+ ntohl(*((uint32_t *) pLnModExpOpData->base.pData));
10820+ }
10821+ icp_ocfDrvFreeFlatBuffer(pResult);
10822+ memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
10823+ ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);
10824+
10825+ crypto_kdone(krp);
10826+
10827+ return;
10828+
10829+}
10830+
10831+/* Name : icp_ocfDrvModExpCRTCallBack
10832+ *
10833+ * Description : When this function returns it signifies that the LAC
10834+ * component has completed the Mod Exp CRT operation.
10835+ */
10836+static void
10837+icp_ocfDrvModExpCRTCallBack(void *callbackTag,
10838+ CpaStatus status,
10839+ void *pOpData, CpaFlatBuffer * pOutputData)
10840+{
10841+ struct cryptkop *krp = NULL;
10842+ CpaCyRsaDecryptOpData *pDecryptData = NULL;
10843+
10844+ if (NULL == callbackTag) {
10845+ DPRINTK("%s(): Invalid input parameters - "
10846+ "callbackTag data is NULL\n", __FUNCTION__);
10847+ return;
10848+ }
10849+
10850+ krp = (struct cryptkop *)callbackTag;
10851+
10852+ if (NULL == pOpData) {
10853+ DPRINTK("%s(): Invalid input parameters - "
10854+ "Operation Data is NULL\n", __FUNCTION__);
10855+ krp->krp_status = ECANCELED;
10856+ crypto_kdone(krp);
10857+ return;
10858+ }
10859+ pDecryptData = (CpaCyRsaDecryptOpData *) pOpData;
10860+
10861+ if (NULL == pOutputData) {
10862+ DPRINTK("%s(): Invalid input parameter - "
10863+ "pOutputData is NULL\n", __FUNCTION__);
10864+ memset(pDecryptData->pRecipientPrivateKey, 0,
10865+ sizeof(CpaCyRsaPrivateKey));
10866+ ICP_CACHE_FREE(drvRSAPrivateKey_zone,
10867+ pDecryptData->pRecipientPrivateKey);
10868+ memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
10869+ ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);
10870+ krp->krp_status = ECANCELED;
10871+ crypto_kdone(krp);
10872+ return;
10873+ }
10874+
10875+ if (CPA_STATUS_SUCCESS == status) {
10876+ krp->krp_status = CRYPTO_OP_SUCCESS;
10877+ } else {
10878+ APRINTK("%s(): LAC Mod Exp CRT operation failed - "
10879+ "Operation Status = %d\n", __FUNCTION__, status);
10880+ krp->krp_status = ECANCELED;
10881+ }
10882+
10883+ icp_ocfDrvSwapBytes(pOutputData->pData, pOutputData->dataLenInBytes);
10884+
10885+ icp_ocfDrvFreeFlatBuffer(pOutputData);
10886+ memset(pDecryptData->pRecipientPrivateKey, 0,
10887+ sizeof(CpaCyRsaPrivateKey));
10888+ ICP_CACHE_FREE(drvRSAPrivateKey_zone,
10889+ pDecryptData->pRecipientPrivateKey);
10890+ memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
10891+ ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);
10892+
10893+ crypto_kdone(krp);
10894+
10895+ return;
10896+}
10897+
10898+/* Name : icp_ocfDrvDsaRSSignCallBack
10899+ *
10900+ * Description : When this function returns it signifies that the LAC
10901+ * component has completed the DSA RS sign operation.
10902+ */
10903+static void
10904+icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
10905+ CpaStatus status,
10906+ void *pOpData,
10907+ CpaBoolean protocolStatus,
10908+ CpaFlatBuffer * pR, CpaFlatBuffer * pS)
10909+{
10910+ struct cryptkop *krp = NULL;
10911+ CpaCyDsaRSSignOpData *pSignData = NULL;
10912+
10913+ if (NULL == callbackTag) {
10914+ DPRINTK("%s(): Invalid input parameters - "
10915+ "callbackTag data is NULL\n", __FUNCTION__);
10916+ return;
10917+ }
10918+
10919+ krp = (struct cryptkop *)callbackTag;
10920+
10921+ if (NULL == pOpData) {
10922+ DPRINTK("%s(): Invalid input parameters - "
10923+ "Operation Data is NULL\n", __FUNCTION__);
10924+ krp->krp_status = ECANCELED;
10925+ crypto_kdone(krp);
10926+ return;
10927+ }
10928+ pSignData = (CpaCyDsaRSSignOpData *) pOpData;
10929+
10930+ if (NULL == pR) {
10931+ DPRINTK("%s(): Invalid input parameter - "
10932+ "pR sign is NULL\n", __FUNCTION__);
10933+ icp_ocfDrvFreeFlatBuffer(pS);
10934+ ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
10935+ krp->krp_status = ECANCELED;
10936+ crypto_kdone(krp);
10937+ return;
10938+ }
10939+
10940+ if (NULL == pS) {
10941+ DPRINTK("%s(): Invalid input parameter - "
10942+ "pS sign is NULL\n", __FUNCTION__);
10943+ icp_ocfDrvFreeFlatBuffer(pR);
10944+ ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
10945+ krp->krp_status = ECANCELED;
10946+ crypto_kdone(krp);
10947+ return;
10948+ }
10949+
10950+ if (CPA_STATUS_SUCCESS != status) {
10951+ APRINTK("%s(): LAC DSA RS Sign operation failed - "
10952+ "Operation Status = %d\n", __FUNCTION__, status);
10953+ krp->krp_status = ECANCELED;
10954+ } else {
10955+ krp->krp_status = CRYPTO_OP_SUCCESS;
10956+
10957+ if (CPA_TRUE != protocolStatus) {
10958+ DPRINTK("%s(): LAC DSA RS Sign operation failed due "
10959+ "to protocol error\n", __FUNCTION__);
10960+ krp->krp_status = EIO;
10961+ }
10962+ }
10963+
10964+ /* Swap bytes only when the callback status is successful and
10965+ protocolStatus is set to true */
10966+ if (CPA_STATUS_SUCCESS == status && CPA_TRUE == protocolStatus) {
10967+ icp_ocfDrvSwapBytes(pR->pData, pR->dataLenInBytes);
10968+ icp_ocfDrvSwapBytes(pS->pData, pS->dataLenInBytes);
10969+ }
10970+
10971+ icp_ocfDrvFreeFlatBuffer(pR);
10972+ icp_ocfDrvFreeFlatBuffer(pS);
10973+ memset(pSignData->K.pData, 0, pSignData->K.dataLenInBytes);
10974+ ICP_CACHE_FREE(drvDSARSSignKValue_zone, pSignData->K.pData);
10975+ memset(pSignData, 0, sizeof(CpaCyDsaRSSignOpData));
10976+ ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
10977+ crypto_kdone(krp);
10978+
10979+ return;
10980+}
10981+
10982+/* Name : icp_ocfDrvDsaVerifyCallback
10983+ *
10984+ * Description : When this function returns it signifies that the LAC
10985+ * component has completed the DSA Verify operation.
10986+ */
10987+static void
10988+icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
10989+ CpaStatus status,
10990+ void *pOpData, CpaBoolean verifyStatus)
10991+{
10992+
10993+ struct cryptkop *krp = NULL;
10994+ CpaCyDsaVerifyOpData *pVerData = NULL;
10995+
10996+ if (NULL == callbackTag) {
10997+ DPRINTK("%s(): Invalid input parameters - "
10998+ "callbackTag data is NULL\n", __FUNCTION__);
10999+ return;
11000+ }
11001+
11002+ krp = (struct cryptkop *)callbackTag;
11003+
11004+ if (NULL == pOpData) {
11005+ DPRINTK("%s(): Invalid input parameters - "
11006+ "Operation Data is NULL\n", __FUNCTION__);
11007+ krp->krp_status = ECANCELED;
11008+ crypto_kdone(krp);
11009+ return;
11010+ }
11011+ pVerData = (CpaCyDsaVerifyOpData *) pOpData;
11012+
11013+ if (CPA_STATUS_SUCCESS != status) {
11014+ APRINTK("%s(): LAC DSA Verify operation failed - "
11015+ "Operation Status = %d\n", __FUNCTION__, status);
11016+ krp->krp_status = ECANCELED;
11017+ } else {
11018+ krp->krp_status = CRYPTO_OP_SUCCESS;
11019+
11020+ if (CPA_TRUE != verifyStatus) {
11021+ DPRINTK("%s(): DSA signature invalid\n", __FUNCTION__);
11022+ krp->krp_status = EIO;
11023+ }
11024+ }
11025+
11026+ /* Swap bytes only when the callback status is successful and
11027+ verifyStatus is set to true */
11028+ /*Just swapping back the key values for now. Possibly all
11029+ swapped buffers need to be reverted */
11030+ if (CPA_STATUS_SUCCESS == status && CPA_TRUE == verifyStatus) {
11031+ icp_ocfDrvSwapBytes(pVerData->R.pData,
11032+ pVerData->R.dataLenInBytes);
11033+ icp_ocfDrvSwapBytes(pVerData->S.pData,
11034+ pVerData->S.dataLenInBytes);
11035+ }
11036+
11037+ memset(pVerData, 0, sizeof(CpaCyDsaVerifyOpData));
11038+ ICP_CACHE_FREE(drvDSAVerify_zone, pVerData);
11039+ crypto_kdone(krp);
11040+
11041+ return;
11042+}
11043diff --git a/crypto/ocf/ep80579/icp_common.c b/crypto/ocf/ep80579/icp_common.c
11044new file mode 100644
11045index 0000000..06a4cf2
11046--- /dev/null
11047+++ b/crypto/ocf/ep80579/icp_common.c
11048@@ -0,0 +1,773 @@
11049+/*************************************************************************
11050+ *
11051+ * This file is provided under a dual BSD/GPLv2 license. When using or
11052+ * redistributing this file, you may do so under either license.
11053+ *
11054+ * GPL LICENSE SUMMARY
11055+ *
11056+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
11057+ *
11058+ * This program is free software; you can redistribute it and/or modify
11059+ * it under the terms of version 2 of the GNU General Public License as
11060+ * published by the Free Software Foundation.
11061+ *
11062+ * This program is distributed in the hope that it will be useful, but
11063+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11064+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11065+ * General Public License for more details.
11066+ *
11067+ * You should have received a copy of the GNU General Public License
11068+ * along with this program; if not, write to the Free Software
11069+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
11070+ * The full GNU General Public License is included in this distribution
11071+ * in the file called LICENSE.GPL.
11072+ *
11073+ * Contact Information:
11074+ * Intel Corporation
11075+ *
11076+ * BSD LICENSE
11077+ *
11078+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
11079+ * All rights reserved.
11080+ *
11081+ * Redistribution and use in source and binary forms, with or without
11082+ * modification, are permitted provided that the following conditions
11083+ * are met:
11084+ *
11085+ * * Redistributions of source code must retain the above copyright
11086+ * notice, this list of conditions and the following disclaimer.
11087+ * * Redistributions in binary form must reproduce the above copyright
11088+ * notice, this list of conditions and the following disclaimer in
11089+ * the documentation and/or other materials provided with the
11090+ * distribution.
11091+ * * Neither the name of Intel Corporation nor the names of its
11092+ * contributors may be used to endorse or promote products derived
11093+ * from this software without specific prior written permission.
11094+ *
11095+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
11096+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11097+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
11098+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
11099+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
11100+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11101+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11102+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11103+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11104+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
11105+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11106+ *
11107+ *
11108+ * version: Security.L.1.0.2-229
11109+ *
11110+ ***************************************************************************/
11111+
11112+/*
11113+ * An OCF module that uses Intel® QuickAssist Integrated Accelerator to do the
11114+ * crypto.
11115+ *
11116+ * This driver requires the ICP Access Library that is available from Intel in
11117+ * order to operate.
11118+ */
11119+
11120+#include "icp_ocf.h"
11121+
11122+#define ICP_OCF_COMP_NAME "ICP_OCF"
11123+#define ICP_OCF_VER_MAIN (2)
11124+#define ICP_OCF_VER_MJR (1)
11125+#define ICP_OCF_VER_MNR (0)
11126+
11127+#define MAX_DEREG_RETRIES (100)
11128+#define DEFAULT_DEREG_RETRIES (10)
11129+#define DEFAULT_DEREG_DELAY_IN_JIFFIES (10)
11130+
11131+/* This defines the maximum number of sessions possible between OCF
11132+ and the OCF EP80579 Driver. If set to zero, there is no limit. */
11133+#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT (0)
11134+#define NUM_SUPPORTED_CAPABILITIES (21)
11135+
11136+/*Slab zone names*/
11137+#define ICP_SESSION_DATA_NAME "icp_ocf.SesDat"
11138+#define ICP_OP_DATA_NAME "icp_ocf.OpDat"
11139+#define ICP_DH_NAME "icp_ocf.DH"
11140+#define ICP_MODEXP_NAME "icp_ocf.ModExp"
11141+#define ICP_RSA_DECRYPT_NAME "icp_ocf.RSAdec"
11142+#define ICP_RSA_PKEY_NAME "icp_ocf.RSApk"
11143+#define ICP_DSA_SIGN_NAME "icp_ocf.DSAsg"
11144+#define ICP_DSA_VER_NAME "icp_ocf.DSAver"
11145+#define ICP_RAND_VAL_NAME "icp_ocf.DSArnd"
11146+#define ICP_FLAT_BUFF_NAME "icp_ocf.FB"
11147+
11148+/*Slabs zones*/
11149+icp_kmem_cache drvSessionData_zone = NULL;
11150+icp_kmem_cache drvOpData_zone = NULL;
11151+icp_kmem_cache drvDH_zone = NULL;
11152+icp_kmem_cache drvLnModExp_zone = NULL;
11153+icp_kmem_cache drvRSADecrypt_zone = NULL;
11154+icp_kmem_cache drvRSAPrivateKey_zone = NULL;
11155+icp_kmem_cache drvDSARSSign_zone = NULL;
11156+icp_kmem_cache drvDSARSSignKValue_zone = NULL;
11157+icp_kmem_cache drvDSAVerify_zone = NULL;
11158+
11159+/*Slab zones for flatbuffers and bufferlist*/
11160+icp_kmem_cache drvFlatBuffer_zone = NULL;
11161+
11162+static inline int icp_cache_null_check(void)
11163+{
11164+ return (drvSessionData_zone && drvOpData_zone
11165+ && drvDH_zone && drvLnModExp_zone && drvRSADecrypt_zone
11166+ && drvRSAPrivateKey_zone && drvDSARSSign_zone
11167+ && drvDSARSSign_zone && drvDSARSSignKValue_zone
11168+ && drvDSAVerify_zone && drvFlatBuffer_zone);
11169+}
11170+
11171+/*Function to free all allocated slab caches before exiting the module*/
11172+static void icp_ocfDrvFreeCaches(void);
11173+
11174+int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID;
11175+
11176+/* Module parameter - gives the number of times LAC deregistration shall be
11177+ re-tried */
11178+int num_dereg_retries = DEFAULT_DEREG_RETRIES;
11179+
11180+/* Module parameter - gives the delay time in jiffies before a LAC session
11181+ shall be attempted to be deregistered again */
11182+int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES;
11183+
11184+/* Module parameter - gives the maximum number of sessions possible between
11185+ OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
11186+int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT;
11187+
11188+/* This is set when the module is removed from the system, no further
11189+ processing can take place if this is set */
11190+icp_atomic_t icp_ocfDrvIsExiting = ICP_ATOMIC_INIT(0);
11191+
11192+/* This is used to show how many lac sessions were not deregistered*/
11193+icp_atomic_t lac_session_failed_dereg_count = ICP_ATOMIC_INIT(0);
11194+
11195+/* This is used to track the number of registered sessions between OCF and
11196+ * and the OCF EP80579 driver, when max_session is set to value other than
11197+ * zero. This ensures that the max_session set for the OCF and the driver
11198+ * is equal to the LAC registered sessions */
11199+icp_atomic_t num_ocf_to_drv_registered_sessions = ICP_ATOMIC_INIT(0);
11200+
11201+/* Head of linked list used to store session data */
11202+icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
11203+icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
11204+
11205+icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
11206+
11207+/*Below pointer is only used in linux, FreeBSD uses the name to
11208+create its own variable name*/
11209+icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ = NULL;
11210+ICP_WORKQUEUE_DEFINE_THREAD(icp_ocfDrvFreeLacSessionWorkQ);
11211+
11212+struct icp_drvBuffListInfo defBuffListInfo;
11213+
11214+/* Name : icp_ocfDrvInit
11215+ *
11216+ * Description : This function will register all the symmetric and asymmetric
11217+ * functionality that will be accelerated by the hardware. It will also
11218+ * get a unique driver ID from the OCF and initialise all slab caches
11219+ */
11220+ICP_MODULE_INIT_FUNC(icp_ocfDrvInit)
11221+{
11222+ int ocfStatus = 0;
11223+
11224+ IPRINTK("=== %s ver %d.%d.%d ===\n", ICP_OCF_COMP_NAME,
11225+ ICP_OCF_VER_MAIN, ICP_OCF_VER_MJR, ICP_OCF_VER_MNR);
11226+
11227+ if (MAX_DEREG_RETRIES < num_dereg_retries) {
11228+ EPRINTK("Session deregistration retry count set to greater "
11229+ "than %d", MAX_DEREG_RETRIES);
11230+ icp_module_return_code(EINVAL);
11231+ }
11232+
11233+ /* Initialize and Start the Cryptographic component */
11234+ if (CPA_STATUS_SUCCESS !=
11235+ cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) {
11236+ EPRINTK("Failed to initialize and start the instance "
11237+ "of the Cryptographic component.\n");
11238+ return icp_module_return_code(EINVAL);
11239+ }
11240+
11241+ icp_spin_lock_init(&icp_ocfDrvSymSessInfoListSpinlock);
11242+
11243+ /* Set the default size of BufferList to allocate */
11244+ memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo));
11245+ if (ICP_OCF_DRV_STATUS_SUCCESS !=
11246+ icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS,
11247+ &defBuffListInfo)) {
11248+ EPRINTK("Failed to get bufferlist memory info.\n");
11249+ return icp_module_return_code(ENOMEM);
11250+ }
11251+
11252+ /*Register OCF EP80579 Driver with OCF */
11253+ icp_ocfDrvDriverId = ICP_CRYPTO_GET_DRIVERID();
11254+
11255+ if (icp_ocfDrvDriverId < 0) {
11256+ EPRINTK("%s : ICP driver failed to register with OCF!\n",
11257+ __FUNCTION__);
11258+ return icp_module_return_code(ENODEV);
11259+ }
11260+
11261+ /*Create all the slab caches used by the OCF EP80579 Driver */
11262+ drvSessionData_zone =
11263+ ICP_CACHE_CREATE(ICP_SESSION_DATA_NAME, struct icp_drvSessionData);
11264+
11265+ /*
11266+ * Allocation of the OpData includes the allocation space for meta data.
11267+ * The memory after the opData structure is reserved for this meta data.
11268+ */
11269+ drvOpData_zone =
11270+ icp_kmem_cache_create(ICP_OP_DATA_NAME,
11271+ sizeof(struct icp_drvOpData) +
11272+ defBuffListInfo.metaSize,
11273+ ICP_KERNEL_CACHE_ALIGN,
11274+ ICP_KERNEL_CACHE_NOINIT);
11275+
11276+ drvDH_zone = ICP_CACHE_CREATE(ICP_DH_NAME, CpaCyDhPhase1KeyGenOpData);
11277+
11278+ drvLnModExp_zone =
11279+ ICP_CACHE_CREATE(ICP_MODEXP_NAME, CpaCyLnModExpOpData);
11280+
11281+ drvRSADecrypt_zone =
11282+ ICP_CACHE_CREATE(ICP_RSA_DECRYPT_NAME, CpaCyRsaDecryptOpData);
11283+
11284+ drvRSAPrivateKey_zone =
11285+ ICP_CACHE_CREATE(ICP_RSA_PKEY_NAME, CpaCyRsaPrivateKey);
11286+
11287+ drvDSARSSign_zone =
11288+ ICP_CACHE_CREATE(ICP_DSA_SIGN_NAME, CpaCyDsaRSSignOpData);
11289+
11290+ /*too awkward to use a macro here */
11291+ drvDSARSSignKValue_zone =
11292+ ICP_CACHE_CREATE(ICP_RAND_VAL_NAME,
11293+ DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES);
11294+
11295+ drvDSAVerify_zone =
11296+ ICP_CACHE_CREATE(ICP_DSA_VER_NAME, CpaCyDsaVerifyOpData);
11297+
11298+ drvFlatBuffer_zone =
11299+ ICP_CACHE_CREATE(ICP_FLAT_BUFF_NAME, CpaFlatBuffer);
11300+
11301+ if (0 == icp_cache_null_check()) {
11302+ icp_ocfDrvFreeCaches();
11303+ EPRINTK("%s() line %d: Not enough memory!\n",
11304+ __FUNCTION__, __LINE__);
11305+ return ENOMEM;
11306+ }
11307+
11308+ /* Register the ICP symmetric crypto support. */
11309+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_NULL_CBC, ocfStatus);
11310+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_DES_CBC, ocfStatus);
11311+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_3DES_CBC, ocfStatus);
11312+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_AES_CBC, ocfStatus);
11313+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_ARC4, ocfStatus);
11314+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5, ocfStatus);
11315+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5_HMAC, ocfStatus);
11316+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1, ocfStatus);
11317+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1_HMAC, ocfStatus);
11318+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256, ocfStatus);
11319+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256_HMAC,
11320+ ocfStatus);
11321+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384, ocfStatus);
11322+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384_HMAC,
11323+ ocfStatus);
11324+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512, ocfStatus);
11325+ ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512_HMAC,
11326+ ocfStatus);
11327+
11328+ /* Register the ICP asymmetric algorithm support */
11329+ ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DH_COMPUTE_KEY,
11330+ ocfStatus);
11331+ ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP, ocfStatus);
11332+ ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP_CRT, ocfStatus);
11333+ ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_SIGN, ocfStatus);
11334+ ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_VERIFY, ocfStatus);
11335+
11336+ /* Register the ICP random number generator support */
11337+ ICP_REG_RAND_WITH_OCF(icp_ocfDrvDriverId,
11338+ icp_ocfDrvReadRandom, NULL, ocfStatus);
11339+
11340+ if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) {
11341+ DPRINTK("%s: Failed to register any device capabilities\n",
11342+ __FUNCTION__);
11343+ icp_ocfDrvFreeCaches();
11344+ icp_ocfDrvDriverId = INVALID_DRIVER_ID;
11345+ return icp_module_return_code(ECANCELED);
11346+ }
11347+
11348+ DPRINTK("%s: Registered %d of %d device capabilities\n",
11349+ __FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES);
11350+
11351+ /*Session data linked list used during module exit */
11352+ ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);
11353+ ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);
11354+
11355+ ICP_WORKQUEUE_CREATE(icp_ocfDrvFreeLacSessionWorkQ, "icpwq");
11356+ if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
11357+ EPRINTK("%s: Failed to create single "
11358+ "thread workqueue\n", __FUNCTION__);
11359+ icp_ocfDrvFreeCaches();
11360+ icp_ocfDrvDriverId = INVALID_DRIVER_ID;
11361+ return icp_module_return_code(ENOMEM);
11362+ }
11363+
11364+ return icp_module_return_code(0);
11365+}
11366+
11367+/* Name : icp_ocfDrvExit
11368+ *
11369+ * Description : This function will deregister all the symmetric sessions
11370+ * registered with the LAC component. It will also deregister all symmetric
11371+ * and asymmetric functionality that can be accelerated by the hardware via OCF
11372+ * and random number generation if it is enabled.
11373+ */
11374+ICP_MODULE_EXIT_FUNC(icp_ocfDrvExit)
11375+{
11376+ CpaStatus lacStatus = CPA_STATUS_SUCCESS;
11377+ struct icp_drvSessionData *sessionData = NULL;
11378+ struct icp_drvSessionData *tempSessionData = NULL;
11379+ int i, remaining_delay_time_in_jiffies = 0;
11380+
11381+ /* For FreeBSD the invariant macro below makes function to return */
11382+ /* with EBUSY value in the case of any session which has been regi- */
11383+ /* stered with LAC not being deregistered. */
11384+ /* The Linux implementation is empty since it is purely to compensate */
11385+ /* for a limitation of the FreeBSD 7.1 Opencrypto framework. */
11386+
11387+ ICP_MODULE_EXIT_INV();
11388+
11389+ /* There is a possibility of a process or new session command being */
11390+ /* sent before this variable is incremented. The aim of this variable */
11391+ /* is to stop a loop of calls creating a deadlock situation which */
11392+ /* would prevent the driver from exiting. */
11393+ icp_atomic_set(&icp_ocfDrvIsExiting, 1);
11394+
11395+ /*Existing sessions will be routed to another driver after these calls */
11396+ crypto_unregister_all(icp_ocfDrvDriverId);
11397+ crypto_runregister_all(icp_ocfDrvDriverId);
11398+
11399+ if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
11400+ DPRINTK("%s: workqueue already "
11401+ "destroyed, therefore module exit "
11402+ " function already called. Exiting.\n", __FUNCTION__);
11403+ return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
11404+ }
11405+ /*If any sessions are waiting to be deregistered, do that. This also
11406+ flushes the work queue */
11407+ ICP_WORKQUEUE_DESTROY(icp_ocfDrvFreeLacSessionWorkQ);
11408+
11409+ /*ENTER CRITICAL SECTION */
11410+ icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
11411+
11412+ ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
11413+ &icp_ocfDrvGlobalSymListHead, listNode) {
11414+ for (i = 0; i < num_dereg_retries; i++) {
11415+ /*No harm if bad input - LAC will handle error cases */
11416+ if (ICP_SESSION_RUNNING == tempSessionData->inUse) {
11417+ lacStatus =
11418+ cpaCySymRemoveSession
11419+ (CPA_INSTANCE_HANDLE_SINGLE,
11420+ tempSessionData->sessHandle);
11421+ if (CPA_STATUS_SUCCESS == lacStatus) {
11422+ /* Succesfully deregistered */
11423+ break;
11424+ } else if (CPA_STATUS_RETRY != lacStatus) {
11425+ icp_atomic_inc
11426+ (&lac_session_failed_dereg_count);
11427+ break;
11428+ }
11429+
11430+ /*schedule_timout returns the time left for completion if
11431+ * this task is set to TASK_INTERRUPTIBLE */
11432+ remaining_delay_time_in_jiffies =
11433+ dereg_retry_delay_in_jiffies;
11434+ while (0 > remaining_delay_time_in_jiffies) {
11435+ remaining_delay_time_in_jiffies =
11436+ icp_schedule_timeout
11437+ (&icp_ocfDrvSymSessInfoListSpinlock,
11438+ remaining_delay_time_in_jiffies);
11439+ }
11440+
11441+ DPRINTK
11442+ ("%s(): Retry %d to deregistrate the session\n",
11443+ __FUNCTION__, i);
11444+ }
11445+ }
11446+
11447+ /*remove from current list */
11448+ ICP_LIST_DEL(tempSessionData, listNode);
11449+ /*add to free mem linked list */
11450+ ICP_LIST_ADD(tempSessionData,
11451+ &icp_ocfDrvGlobalSymListHead_FreeMemList,
11452+ listNode);
11453+
11454+ }
11455+
11456+ /*EXIT CRITICAL SECTION */
11457+ icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
11458+
11459+ /*set back to initial values */
11460+ sessionData = NULL;
11461+ /*still have a reference in our list! */
11462+ tempSessionData = NULL;
11463+ /*free memory */
11464+
11465+ ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
11466+ &icp_ocfDrvGlobalSymListHead_FreeMemList,
11467+ listNode) {
11468+
11469+ ICP_LIST_DEL(tempSessionData, listNode);
11470+ /* Free allocated CpaCySymSessionCtx */
11471+ if (NULL != tempSessionData->sessHandle) {
11472+ icp_kfree(tempSessionData->sessHandle);
11473+ }
11474+ memset(tempSessionData, 0, sizeof(struct icp_drvSessionData));
11475+ ICP_CACHE_FREE(drvSessionData_zone, tempSessionData);
11476+ }
11477+
11478+ if (0 != icp_atomic_read(&lac_session_failed_dereg_count)) {
11479+ DPRINTK("%s(): %d LAC sessions were not deregistered "
11480+ "correctly. This is not a clean exit! \n",
11481+ __FUNCTION__,
11482+ icp_atomic_read(&lac_session_failed_dereg_count));
11483+ }
11484+
11485+ icp_ocfDrvFreeCaches();
11486+ icp_ocfDrvDriverId = INVALID_DRIVER_ID;
11487+
11488+ icp_spin_lock_destroy(&icp_ocfDrvSymSessInfoListSpinlock);
11489+
11490+ /* Shutdown the Cryptographic component */
11491+ lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE);
11492+ if (CPA_STATUS_SUCCESS != lacStatus) {
11493+ DPRINTK("%s(): Failed to stop instance of the "
11494+ "Cryptographic component.(status == %d)\n",
11495+ __FUNCTION__, lacStatus);
11496+ }
11497+
11498+ return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
11499+}
11500+
11501+/* Name : icp_ocfDrvFreeCaches
11502+ *
11503+ * Description : This function deregisters all slab caches
11504+ */
11505+static void icp_ocfDrvFreeCaches(void)
11506+{
11507+ icp_atomic_set(&icp_ocfDrvIsExiting, 1);
11508+
11509+ /*Sym Zones */
11510+ ICP_CACHE_DESTROY(drvSessionData_zone);
11511+ ICP_CACHE_DESTROY(drvOpData_zone);
11512+
11513+ /*Asym zones */
11514+ ICP_CACHE_DESTROY(drvDH_zone);
11515+ ICP_CACHE_DESTROY(drvLnModExp_zone);
11516+ ICP_CACHE_DESTROY(drvRSADecrypt_zone);
11517+ ICP_CACHE_DESTROY(drvRSAPrivateKey_zone);
11518+ ICP_CACHE_DESTROY(drvDSARSSignKValue_zone);
11519+ ICP_CACHE_DESTROY(drvDSARSSign_zone);
11520+ ICP_CACHE_DESTROY(drvDSAVerify_zone);
11521+
11522+ /*FlatBuffer and BufferList Zones */
11523+ ICP_CACHE_DESTROY(drvFlatBuffer_zone);
11524+
11525+}
11526+
11527+/* Name : icp_ocfDrvDeregRetry
11528+ *
11529+ * Description : This function will try to farm the session deregistration
11530+ * off to a work queue. If it fails, nothing more can be done and it
11531+ * returns an error
11532+ */
11533+int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
11534+{
11535+ struct icp_ocfDrvFreeLacSession *workstore = NULL;
11536+
11537+ DPRINTK("%s(): Retry - Deregistering session (%p)\n",
11538+ __FUNCTION__, sessionToDeregister);
11539+
11540+ /*make sure the session is not available to be allocated during this
11541+ process */
11542+ icp_atomic_inc(&lac_session_failed_dereg_count);
11543+
11544+ /*Farm off to work queue */
11545+ workstore =
11546+ icp_kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), ICP_M_NOWAIT);
11547+ if (NULL == workstore) {
11548+ DPRINTK("%s(): unable to free session - no memory available "
11549+ "for work queue\n", __FUNCTION__);
11550+ return ENOMEM;
11551+ }
11552+
11553+ workstore->sessionToDeregister = sessionToDeregister;
11554+
11555+ icp_init_work(&(workstore->work),
11556+ icp_ocfDrvDeferedFreeLacSessionTaskFn, workstore);
11557+
11558+ ICP_WORKQUEUE_ENQUEUE(icp_ocfDrvFreeLacSessionWorkQ,
11559+ &(workstore->work));
11560+
11561+ return ICP_OCF_DRV_STATUS_SUCCESS;
11562+
11563+}
11564+
11565+/* Name : icp_ocfDrvDeferedFreeLacSessionProcess
11566+ *
11567+ * Description : This function will retry (module input parameter)
11568+ * 'num_dereg_retries' times to deregister any symmetric session that recieves a
11569+ * CPA_STATUS_RETRY message from the LAC component. This function is run in
11570+ * Thread context because it is called from a worker thread
11571+ */
11572+void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
11573+{
11574+ struct icp_ocfDrvFreeLacSession *workstore = NULL;
11575+ CpaCySymSessionCtx sessionToDeregister = NULL;
11576+ int i = 0;
11577+ int remaining_delay_time_in_jiffies = 0;
11578+ CpaStatus lacStatus = CPA_STATUS_SUCCESS;
11579+
11580+ workstore = (struct icp_ocfDrvFreeLacSession *)arg;
11581+ if (NULL == workstore) {
11582+ DPRINTK("%s() function called with null parameter \n",
11583+ __FUNCTION__);
11584+ return;
11585+ }
11586+
11587+ sessionToDeregister = workstore->sessionToDeregister;
11588+ icp_kfree(workstore);
11589+
11590+ /*if exiting, give deregistration one more blast only */
11591+ if (icp_atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {
11592+ lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
11593+ sessionToDeregister);
11594+
11595+ if (lacStatus != CPA_STATUS_SUCCESS) {
11596+ DPRINTK("%s() Failed to Dereg LAC session %p "
11597+ "during module exit\n", __FUNCTION__,
11598+ sessionToDeregister);
11599+ return;
11600+ }
11601+
11602+ icp_atomic_dec(&lac_session_failed_dereg_count);
11603+ return;
11604+ }
11605+
11606+ for (i = 0; i <= num_dereg_retries; i++) {
11607+ lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
11608+ sessionToDeregister);
11609+
11610+ if (lacStatus == CPA_STATUS_SUCCESS) {
11611+ icp_atomic_dec(&lac_session_failed_dereg_count);
11612+ return;
11613+ }
11614+ if (lacStatus != CPA_STATUS_RETRY) {
11615+ DPRINTK("%s() Failed to deregister session - lacStatus "
11616+ " = %d", __FUNCTION__, lacStatus);
11617+ break;
11618+ }
11619+
11620+ /*schedule_timout returns the time left for completion if this
11621+ task is set to TASK_INTERRUPTIBLE */
11622+ remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies;
11623+ while (0 < remaining_delay_time_in_jiffies) {
11624+ remaining_delay_time_in_jiffies =
11625+ icp_schedule_timeout(NULL,
11626+ remaining_delay_time_in_jiffies);
11627+ }
11628+
11629+ }
11630+
11631+ DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__);
11632+ DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__,
11633+ icp_atomic_read(&lac_session_failed_dereg_count));
11634+}
11635+
11636+/* Name : icp_ocfDrvPtrAndLenToFlatBuffer
11637+ *
11638+ * Description : This function converts a "pointer and length" buffer
11639+ * structure to Fredericksburg Flat Buffer (CpaFlatBuffer) format.
11640+ *
11641+ * This function assumes that the data passed in are valid.
11642+ */
11643+inline void
11644+icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
11645+ CpaFlatBuffer * pFlatBuffer)
11646+{
11647+ pFlatBuffer->pData = pData;
11648+ pFlatBuffer->dataLenInBytes = len;
11649+}
11650+
11651+/* Name : icp_ocfDrvPtrAndLenToBufferList
11652+ *
11653+ * Description : This function converts a "pointer and length" buffer
11654+ * structure to Fredericksburg Scatter/Gather Buffer (CpaBufferList) format.
11655+ *
11656+ * This function assumes that the data passed in are valid.
11657+ */
11658+inline void
11659+icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
11660+ CpaBufferList * pBufferList)
11661+{
11662+ pBufferList->numBuffers = 1;
11663+ pBufferList->pBuffers->pData = pDataIn;
11664+ pBufferList->pBuffers->dataLenInBytes = length;
11665+}
11666+
11667+/* Name : icp_ocfDrvBufferListToPtrAndLen
11668+ *
11669+ * Description : This function converts Fredericksburg Scatter/Gather Buffer
11670+ * (CpaBufferList) format to a "pointer and length" buffer structure.
11671+ *
11672+ * This function assumes that the data passed in are valid.
11673+ */
11674+inline void
11675+icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
11676+ void **ppDataOut, uint32_t * pLength)
11677+{
11678+ *ppDataOut = pBufferList->pBuffers->pData;
11679+ *pLength = pBufferList->pBuffers->dataLenInBytes;
11680+}
11681+
11682+/* Name : icp_ocfDrvBufferListMemInfo
11683+ *
11684+ * Description : This function will set the number of flat buffers in
11685+ * bufferlist, the size of memory to allocate for the pPrivateMetaData
11686+ * member of the CpaBufferList.
11687+ */
11688+int
11689+icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
11690+ struct icp_drvBuffListInfo *buffListInfo)
11691+{
11692+ buffListInfo->numBuffers = numBuffers;
11693+
11694+ if (CPA_STATUS_SUCCESS !=
11695+ cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
11696+ buffListInfo->numBuffers,
11697+ &(buffListInfo->metaSize))) {
11698+ EPRINTK("%s() Failed to get buffer list meta size.\n",
11699+ __FUNCTION__);
11700+ return ICP_OCF_DRV_STATUS_FAIL;
11701+ }
11702+
11703+ return ICP_OCF_DRV_STATUS_SUCCESS;
11704+}
11705+
11706+/* Name : icp_ocfDrvFreeFlatBuffer
11707+ *
11708+ * Description : This function will deallocate flat buffer.
11709+ */
11710+inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)
11711+{
11712+ if (pFlatBuffer != NULL) {
11713+ memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer));
11714+ ICP_CACHE_FREE(drvFlatBuffer_zone, pFlatBuffer);
11715+ }
11716+}
11717+
11718+/* Name : icp_ocfDrvAllocMetaData
11719+ *
11720+ * Description : This function will allocate memory for the
11721+ * pPrivateMetaData member of CpaBufferList.
11722+ */
11723+inline int
11724+icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
11725+ struct icp_drvOpData *pOpData)
11726+{
11727+ Cpa32U metaSize = 0;
11728+
11729+ if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
11730+ uint8_t *pOpDataStartAddr = (uint8_t *) pOpData;
11731+
11732+ if (0 == defBuffListInfo.metaSize) {
11733+ pBufferList->pPrivateMetaData = NULL;
11734+ return ICP_OCF_DRV_STATUS_SUCCESS;
11735+ }
11736+ /*
11737+ * The meta data allocation has been included as part of the
11738+ * op data. It has been pre-allocated in memory just after the
11739+ * icp_drvOpData structure.
11740+ */
11741+ pBufferList->pPrivateMetaData = (void *)(pOpDataStartAddr +
11742+ sizeof(struct
11743+ icp_drvOpData));
11744+ } else {
11745+ if (CPA_STATUS_SUCCESS !=
11746+ cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
11747+ pBufferList->numBuffers,
11748+ &metaSize)) {
11749+ EPRINTK("%s() Failed to get buffer list meta size.\n",
11750+ __FUNCTION__);
11751+ return ICP_OCF_DRV_STATUS_FAIL;
11752+ }
11753+
11754+ if (0 == metaSize) {
11755+ pBufferList->pPrivateMetaData = NULL;
11756+ return ICP_OCF_DRV_STATUS_SUCCESS;
11757+ }
11758+
11759+ pBufferList->pPrivateMetaData =
11760+ icp_kmalloc(metaSize, ICP_M_NOWAIT);
11761+ }
11762+ if (NULL == pBufferList->pPrivateMetaData) {
11763+ EPRINTK("%s() Failed to allocate pPrivateMetaData.\n",
11764+ __FUNCTION__);
11765+ return ICP_OCF_DRV_STATUS_FAIL;
11766+ }
11767+
11768+ return ICP_OCF_DRV_STATUS_SUCCESS;
11769+}
11770+
11771+/* Name : icp_ocfDrvFreeMetaData
11772+ *
11773+ * Description : This function will deallocate pPrivateMetaData memory.
11774+ */
11775+inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList)
11776+{
11777+ if (NULL == pBufferList->pPrivateMetaData) {
11778+ return;
11779+ }
11780+
11781+ /*
11782+ * Only free the meta data if the BufferList has more than
11783+ * ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS number of buffers.
11784+ * Otherwise, the meta data shall be freed when the icp_drvOpData is
11785+ * freed.
11786+ */
11787+ if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers) {
11788+ icp_kfree(pBufferList->pPrivateMetaData);
11789+ }
11790+}
11791+
11792+/* Module declaration, init and exit functions */
11793+ICP_DECLARE_MODULE(icp_ocf, icp_ocfDrvInit, icp_ocfDrvExit);
11794+ICP_MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");
11795+ICP_MODULE_VERSION(icp_ocf, ICP_OCF_VER_MJR);
11796+ICP_MODULE_LICENSE("Dual BSD/GPL");
11797+ICP_MODULE_AUTHOR("Intel");
11798+
11799+/* Module parameters */
11800+ICP_MODULE_PARAM_INT(icp_ocf, num_dereg_retries,
11801+ "Number of times to retry LAC Sym Session Deregistration. "
11802+ "Default 10, Max 100");
11803+ICP_MODULE_PARAM_INT(icp_ocf, dereg_retry_delay_in_jiffies, "Delay in jiffies "
11804+ "(added to a schedule() function call) before a LAC Sym "
11805+ "Session Dereg is retried. Default 10");
11806+ICP_MODULE_PARAM_INT(icp_ocf, max_sessions,
11807+ "This sets the maximum number of sessions "
11808+ "between OCF and this driver. If this value is set to zero,"
11809+ "max session count checking is disabled. Default is zero(0)");
11810+
11811+/* Module dependencies */
11812+#define MODULE_MIN_VER 1
11813+#define CRYPTO_MAX_VER 3
11814+#define LAC_MAX_VER 2
11815+
11816+ICP_MODULE_DEPEND(icp_ocf, crypto, MODULE_MIN_VER, MODULE_MIN_VER,
11817+ CRYPTO_MAX_VER);
11818+ICP_MODULE_DEPEND(icp_ocf, cryptodev, MODULE_MIN_VER, MODULE_MIN_VER,
11819+ CRYPTO_MAX_VER);
11820+ICP_MODULE_DEPEND(icp_ocf, icp_crypto, MODULE_MIN_VER, MODULE_MIN_VER,
11821+ LAC_MAX_VER);
11822diff --git a/crypto/ocf/ep80579/icp_ocf.h b/crypto/ocf/ep80579/icp_ocf.h
11823new file mode 100644
11824index 0000000..854b306
11825--- /dev/null
11826+++ b/crypto/ocf/ep80579/icp_ocf.h
11827@@ -0,0 +1,376 @@
11828+/***************************************************************************
11829+ *
11830+ * This file is provided under a dual BSD/GPLv2 license. When using or
11831+ * redistributing this file, you may do so under either license.
11832+ *
11833+ * GPL LICENSE SUMMARY
11834+ *
11835+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
11836+ *
11837+ * This program is free software; you can redistribute it and/or modify
11838+ * it under the terms of version 2 of the GNU General Public License as
11839+ * published by the Free Software Foundation.
11840+ *
11841+ * This program is distributed in the hope that it will be useful, but
11842+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11843+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11844+ * General Public License for more details.
11845+ *
11846+ * You should have received a copy of the GNU General Public License
11847+ * along with this program; if not, write to the Free Software
11848+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
11849+ * The full GNU General Public License is included in this distribution
11850+ * in the file called LICENSE.GPL.
11851+ *
11852+ * Contact Information:
11853+ * Intel Corporation
11854+ *
11855+ * BSD LICENSE
11856+ *
11857+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
11858+ * All rights reserved.
11859+ *
11860+ * Redistribution and use in source and binary forms, with or without
11861+ * modification, are permitted provided that the following conditions
11862+ * are met:
11863+ *
11864+ * * Redistributions of source code must retain the above copyright
11865+ * notice, this list of conditions and the following disclaimer.
11866+ * * Redistributions in binary form must reproduce the above copyright
11867+ * notice, this list of conditions and the following disclaimer in
11868+ * the documentation and/or other materials provided with the
11869+ * distribution.
11870+ * * Neither the name of Intel Corporation nor the names of its
11871+ * contributors may be used to endorse or promote products derived
11872+ * from this software without specific prior written permission.
11873+ *
11874+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
11875+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11876+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
11877+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
11878+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
11879+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11880+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11881+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11882+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11883+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
11884+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11885+ *
11886+ *
11887+ * version: Security.L.1.0.2-229
11888+ *
11889+ ***************************************************************************/
11890+
11891+/*
11892+ * OCF driver header file for the Intel ICP processor.
11893+ */
11894+
11895+#ifndef ICP_OCF_H_
11896+#define ICP_OCF_H_
11897+
11898+#include <cpa.h>
11899+#include <cpa_cy_im.h>
11900+#include <cpa_cy_sym.h>
11901+#include <cpa_cy_rand.h>
11902+#include <cpa_cy_dh.h>
11903+#include <cpa_cy_rsa.h>
11904+#include <cpa_cy_ln.h>
11905+#include <cpa_cy_common.h>
11906+#include <cpa_cy_dsa.h>
11907+
11908+#include "icp_os.h"
11909+
11910+#define NUM_BITS_IN_BYTE (8)
11911+#define NUM_BITS_IN_BYTE_MINUS_ONE (NUM_BITS_IN_BYTE -1)
11912+#define INVALID_DRIVER_ID (-1)
11913+#define RETURN_RAND_NUM_GEN_FAILED (-1)
11914+
11915+/*This is the max block cipher initialisation vector*/
11916+#define MAX_IV_LEN_IN_BYTES (20)
11917+/*This is used to check whether the OCF to this driver session limit has
11918+ been disabled*/
11919+#define NO_OCF_TO_DRV_MAX_SESSIONS (0)
11920+
11921+/*OCF values mapped here*/
11922+#define ICP_SHA1_DIGEST_SIZE_IN_BYTES (SHA1_HASH_LEN)
11923+#define ICP_SHA256_DIGEST_SIZE_IN_BYTES (SHA2_256_HASH_LEN)
11924+#define ICP_SHA384_DIGEST_SIZE_IN_BYTES (SHA2_384_HASH_LEN)
11925+#define ICP_SHA512_DIGEST_SIZE_IN_BYTES (SHA2_512_HASH_LEN)
11926+#define ICP_MD5_DIGEST_SIZE_IN_BYTES (MD5_HASH_LEN)
11927+#define ARC4_COUNTER_LEN (ARC4_BLOCK_LEN)
11928+
11929+#define OCF_REGISTRATION_STATUS_SUCCESS (0)
11930+#define OCF_ZERO_FUNCTIONALITY_REGISTERED (0)
11931+#define ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR (0)
11932+#define ICP_OCF_DRV_STATUS_SUCCESS (0)
11933+#define ICP_OCF_DRV_STATUS_FAIL (1)
11934+
11935+/*Turn on/off debug options*/
11936+#define ICP_OCF_PRINT_DEBUG_MESSAGES (0)
11937+#define ICP_OCF_PRINT_KERN_ALERT (1)
11938+#define ICP_OCF_PRINT_KERN_ERRS (1)
11939+
11940+#if ICP_OCF_PRINT_DEBUG_MESSAGES == 1
11941+#define DPRINTK(args...) \
11942+{ \
11943+ ICP_IPRINTK(args); \
11944+}
11945+
11946+#else //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
11947+
11948+#define DPRINTK(args...)
11949+
11950+#endif //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
11951+
11952+#if ICP_OCF_PRINT_KERN_ALERT == 1
11953+#define APRINTK(args...) \
11954+{ \
11955+ ICP_APRINTK(args); \
11956+}
11957+
11958+#else //ICP_OCF_PRINT_KERN_ALERT == 1
11959+
11960+#define APRINTK(args...)
11961+
11962+#endif //ICP_OCF_PRINT_KERN_ALERT == 1
11963+
11964+#if ICP_OCF_PRINT_KERN_ERRS == 1
11965+#define EPRINTK(args...) \
11966+{ \
11967+ ICP_EPRINTK(args); \
11968+}
11969+
11970+#else //ICP_OCF_PRINT_KERN_ERRS == 1
11971+
11972+#define EPRINTK(args...)
11973+
11974+#endif //ICP_OCF_PRINT_KERN_ERRS == 1
11975+
11976+#define IPRINTK(args...) \
11977+{ \
11978+ ICP_IPRINTK(args); \
11979+}
11980+
11981+/*DSA Prime Q size in bytes (as defined in the standard) */
11982+#define DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES (20)
11983+
11984+#define BITS_TO_BYTES(bytes, bits) \
11985+ bytes = (bits + NUM_BITS_IN_BYTE_MINUS_ONE) / NUM_BITS_IN_BYTE
11986+
11987+typedef enum {
11988+ ICP_OCF_DRV_ALG_CIPHER = 0,
11989+ ICP_OCF_DRV_ALG_HASH
11990+} icp_ocf_drv_alg_type_t;
11991+
11992+typedef ICP_LIST_HEAD(icp_drvSessionListHead_s,
11993+ icp_drvSessionData) icp_drvSessionListHead_t;
11994+
11995+/*Values used to derisk chances of performs being called against
11996+deregistered sessions (for which the slab page has been reclaimed)
11997+This is not a fix - since page frames are reclaimed from a slab, one cannot
11998+rely on that memory not being re-used by another app.*/
11999+typedef enum {
12000+ ICP_SESSION_INITIALISED = 0x5C5C5C,
12001+ ICP_SESSION_RUNNING = 0x005C00,
12002+ ICP_SESSION_DEREGISTERED = 0xC5C5C5
12003+} usage_derisk;
12004+
12005+/* This struct is required for deferred session
12006+ deregistration as a work queue function can
12007+ only have one argument*/
12008+struct icp_ocfDrvFreeLacSession {
12009+ CpaCySymSessionCtx sessionToDeregister;
12010+ icp_workstruct work;
12011+};
12012+
12013+/*
12014+This is the OCF<->OCF_DRV session object:
12015+
12016+1.listNode
12017+ The first member is a listNode. These session objects are added to a linked
12018+ list in order to make it easier to remove them all at session exit time.
12019+
12020+2.inUse
12021+ The second member is used to give the session object state and derisk the
12022+ possibility of OCF batch calls executing against a deregistered session (as
12023+ described above).
12024+
12025+3.sessHandle
12026+ The third member is a LAC<->OCF_DRV session handle (initialised with the first
12027+ perform request for that session).
12028+
12029+4.lacSessCtx
12030+ The fourth is the LAC session context. All the parameters for this structure
12031+ are only known when the first perform request for this session occurs. That is
12032+ why the OCF EP80579 Driver only registers a new LAC session at perform time
12033+*/
12034+struct icp_drvSessionData {
12035+ ICP_LIST_ENTRY(icp_drvSessionData) listNode;
12036+ usage_derisk inUse;
12037+ CpaCySymSessionCtx sessHandle;
12038+ CpaCySymSessionSetupData lacSessCtx;
12039+};
12040+
12041+/* These are all defined in icp_common.c */
12042+extern icp_atomic_t lac_session_failed_dereg_count;
12043+extern icp_atomic_t icp_ocfDrvIsExiting;
12044+extern icp_atomic_t num_ocf_to_drv_registered_sessions;
12045+
12046+extern int32_t icp_ocfDrvDriverId;
12047+
12048+extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
12049+extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
12050+extern icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ;
12051+extern icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
12052+
12053+/*Slab zones for symettric functionality, instantiated in icp_common.c*/
12054+extern icp_kmem_cache drvSessionData_zone;
12055+extern icp_kmem_cache drvOpData_zone;
12056+
12057+/*Slabs zones for asymettric functionality, instantiated in icp_common.c*/
12058+extern icp_kmem_cache drvDH_zone;
12059+extern icp_kmem_cache drvLnModExp_zone;
12060+extern icp_kmem_cache drvRSADecrypt_zone;
12061+extern icp_kmem_cache drvRSAPrivateKey_zone;
12062+extern icp_kmem_cache drvDSARSSign_zone;
12063+extern icp_kmem_cache drvDSARSSignKValue_zone;
12064+extern icp_kmem_cache drvDSAVerify_zone;
12065+
12066+/* Module parameters defined in icp_cpmmon.c*/
12067+
12068+/* Module parameters - gives the number of times LAC deregistration shall be
12069+ re-tried */
12070+extern int num_dereg_retries;
12071+
12072+/* Module parameter - gives the delay time in jiffies before a LAC session
12073+ shall be attempted to be deregistered again */
12074+extern int dereg_retry_delay_in_jiffies;
12075+
12076+/* Module parameter - gives the maximum number of sessions possible between
12077+ OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
12078+extern int max_sessions;
12079+
12080+/*Slab zones for flatbuffers and bufferlist*/
12081+extern icp_kmem_cache drvFlatBuffer_zone;
12082+
12083+#define ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS (16)
12084+
12085+struct icp_drvBuffListInfo {
12086+ Cpa16U numBuffers;
12087+ Cpa32U metaSize;
12088+ Cpa32U metaOffset;
12089+ Cpa32U buffListSize;
12090+};
12091+
12092+extern struct icp_drvBuffListInfo defBuffListInfo;
12093+
12094+/* This struct is used to keep a reference to the relevant node in the list
12095+ of sessionData structs, to the buffer type required by OCF and to the OCF
12096+ provided crp struct that needs to be returned. All this info is needed in
12097+ the callback function.*/
12098+struct icp_drvOpData {
12099+ CpaCySymOpData lacOpData;
12100+ uint32_t digestSizeInBytes;
12101+ struct cryptop *crp;
12102+ uint8_t bufferType;
12103+ uint8_t ivData[MAX_IV_LEN_IN_BYTES];
12104+ uint16_t numBufferListArray;
12105+ CpaBufferList srcBuffer;
12106+ CpaFlatBuffer bufferListArray[ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS];
12107+ CpaBoolean verifyResult;
12108+};
12109+
12110+/* Create a new session between OCF and this driver*/
12111+int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sild,
12112+ struct cryptoini *cri);
12113+
12114+/* Free a session between this driver and the Quick Assist Framework*/
12115+int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid);
12116+
12117+/* Defer freeing a Quick Assist session*/
12118+void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg);
12119+
12120+/* Process OCF cryptographic request for a symmetric algorithm*/
12121+int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint);
12122+
12123+/* Process OCF cryptographic request for an asymmetric algorithm*/
12124+int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint);
12125+
12126+/* Populate a buffer with random data*/
12127+int icp_ocfDrvReadRandom(void *arg, uint32_t * buf, int maxwords);
12128+
12129+/* Retry Quick Assist session deregistration*/
12130+int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister);
12131+
12132+/* Convert an OS scatter gather list to a CPA buffer list*/
12133+int icp_ocfDrvPacketBuffToBufferList(icp_packet_buffer_t * pPacketBuffer,
12134+ CpaBufferList * bufferList);
12135+
12136+/* Convert a CPA buffer list to an OS scatter gather list*/
12137+int icp_ocfDrvBufferListToPacketBuff(CpaBufferList * bufferList,
12138+ icp_packet_buffer_t ** pPacketBuffer);
12139+
12140+/* Get the number of buffers in an OS scatter gather list*/
12141+uint16_t icp_ocfDrvGetPacketBuffFrags(icp_packet_buffer_t * pPacketBuffer);
12142+
12143+/* Convert a single OS buffer to a CPA Flat Buffer*/
12144+void icp_ocfDrvSinglePacketBuffToFlatBuffer(icp_packet_buffer_t * pPacketBuffer,
12145+ CpaFlatBuffer * pFlatBuffer);
12146+
12147+/* Add pointer and length to a CPA Flat Buffer structure*/
12148+void icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
12149+ CpaFlatBuffer * pFlatBuffer);
12150+
12151+/* Convert pointer and length values to a CPA buffer list*/
12152+void icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
12153+ CpaBufferList * pBufferList);
12154+
12155+/* Convert a CPA buffer list to pointer and length values*/
12156+void icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
12157+ void **ppDataOut, uint32_t * pLength);
12158+
12159+/* Set the number of flat buffers in bufferlist and the size of memory
12160+ to allocate for the pPrivateMetaData member of the CpaBufferList.*/
12161+int icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
12162+ struct icp_drvBuffListInfo *buffListInfo);
12163+
12164+/* Find pointer position of the digest within an OS scatter gather list*/
12165+uint8_t *icp_ocfDrvPacketBufferDigestPointerFind(struct icp_drvOpData
12166+ *drvOpData,
12167+ int offsetInBytes,
12168+ uint32_t digestSizeInBytes);
12169+
12170+/*This top level function is used to find a pointer to where a digest is
12171+ stored/needs to be inserted. */
12172+uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData *drvOpData,
12173+ struct cryptodesc *crp_desc);
12174+
12175+/* Free a CPA flat buffer*/
12176+void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer);
12177+
12178+/* This function will allocate memory for the pPrivateMetaData
12179+ member of CpaBufferList. */
12180+int icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
12181+ struct icp_drvOpData *pOpData);
12182+
12183+/* Free data allocated for the pPrivateMetaData
12184+ member of CpaBufferList.*/
12185+void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList);
12186+
12187+#define ICP_CACHE_CREATE(cache_ID, cache_name) \
12188+ icp_kmem_cache_create(cache_ID, sizeof(cache_name),ICP_KERNEL_CACHE_ALIGN,\
12189+ ICP_KERNEL_CACHE_NOINIT)
12190+
12191+#define ICP_CACHE_FREE(args...) \
12192+ icp_kmem_cache_free (args)
12193+
12194+#define ICP_CACHE_DESTROY(slab_zone)\
12195+{\
12196+ if(NULL != slab_zone){\
12197+ icp_kmem_cache_destroy(slab_zone);\
12198+ slab_zone = NULL;\
12199+ }\
12200+}
12201+
12202+#endif
12203+/* ICP_OCF_H_ */
12204diff --git a/crypto/ocf/ep80579/icp_sym.c b/crypto/ocf/ep80579/icp_sym.c
12205new file mode 100644
12206index 0000000..a3edc43
12207--- /dev/null
12208+++ b/crypto/ocf/ep80579/icp_sym.c
12209@@ -0,0 +1,1153 @@
12210+/***************************************************************************
12211+ *
12212+ * This file is provided under a dual BSD/GPLv2 license. When using or
12213+ * redistributing this file, you may do so under either license.
12214+ *
12215+ * GPL LICENSE SUMMARY
12216+ *
12217+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
12218+ *
12219+ * This program is free software; you can redistribute it and/or modify
12220+ * it under the terms of version 2 of the GNU General Public License as
12221+ * published by the Free Software Foundation.
12222+ *
12223+ * This program is distributed in the hope that it will be useful, but
12224+ * WITHOUT ANY WARRANTY; without even the implied warranty of
12225+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12226+ * General Public License for more details.
12227+ *
12228+ * You should have received a copy of the GNU General Public License
12229+ * along with this program; if not, write to the Free Software
12230+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
12231+ * The full GNU General Public License is included in this distribution
12232+ * in the file called LICENSE.GPL.
12233+ *
12234+ * Contact Information:
12235+ * Intel Corporation
12236+ *
12237+ * BSD LICENSE
12238+ *
12239+ * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
12240+ * All rights reserved.
12241+ *
12242+ * Redistribution and use in source and binary forms, with or without
12243+ * modification, are permitted provided that the following conditions
12244+ * are met:
12245+ *
12246+ * * Redistributions of source code must retain the above copyright
12247+ * notice, this list of conditions and the following disclaimer.
12248+ * * Redistributions in binary form must reproduce the above copyright
12249+ * notice, this list of conditions and the following disclaimer in
12250+ * the documentation and/or other materials provided with the
12251+ * distribution.
12252+ * * Neither the name of Intel Corporation nor the names of its
12253+ * contributors may be used to endorse or promote products derived
12254+ * from this software without specific prior written permission.
12255+ *
12256+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
12257+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
12258+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
12259+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
12260+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
12261+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
12262+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12263+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12264+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12265+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
12266+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12267+ *
12268+ *
12269+ * version: Security.L.1.0.2-229
12270+ *
12271+ ***************************************************************************/
12272+/*
12273+ * An OCF module that uses the API for Intel® QuickAssist Technology to do the
12274+ * cryptography.
12275+ *
12276+ * This driver requires the ICP Access Library that is available from Intel in
12277+ * order to operate.
12278+ */
12279+
12280+#include "icp_ocf.h"
12281+
12282+/*This is the call back function for all symmetric cryptographic processes.
12283+ Its main functionality is to free driver crypto operation structure and to
12284+ call back to OCF*/
12285+static void
12286+icp_ocfDrvSymCallBack(void *callbackTag,
12287+ CpaStatus status,
12288+ const CpaCySymOp operationType,
12289+ void *pOpData,
12290+ CpaBufferList * pDstBuffer, CpaBoolean verifyResult);
12291+
12292+/*This function is used to extract crypto processing information from the OCF
12293+ inputs, so as that it may be passed onto LAC*/
12294+static int
12295+icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
12296+ struct cryptodesc *crp_desc);
12297+
12298+/*This function checks whether the crp_desc argument pertains to a digest or a
12299+ cipher operation*/
12300+static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc);
12301+
12302+/*This function copies all the passed in session context information and stores
12303+ it in a LAC context structure*/
12304+static int
12305+icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
12306+ CpaCySymSessionSetupData * lacSessCtx);
12307+
12308+/*This function is used to free an OCF->OCF_DRV session object*/
12309+static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData);
12310+
12311+/*max IOV buffs supported in a UIO structure*/
12312+#define NUM_IOV_SUPPORTED (1)
12313+
12314+/* Name : icp_ocfDrvSymCallBack
12315+ *
12316+ * Description : When this function returns it signifies that the LAC
12317+ * component has completed the relevant symmetric operation.
12318+ *
12319+ * Notes : The callbackTag is a pointer to an icp_drvOpData. This memory
12320+ * object was passed to LAC for the cryptographic processing and contains all
12321+ * the relevant information for cleaning up buffer handles etc. so that the
12322+ * OCF EP80579 Driver portion of this crypto operation can be fully completed.
12323+ */
12324+static void
12325+icp_ocfDrvSymCallBack(void *callbackTag,
12326+ CpaStatus status,
12327+ const CpaCySymOp operationType,
12328+ void *pOpData,
12329+ CpaBufferList * pDstBuffer, CpaBoolean verifyResult)
12330+{
12331+ struct cryptop *crp = NULL;
12332+ struct icp_drvOpData *temp_drvOpData =
12333+ (struct icp_drvOpData *)callbackTag;
12334+ uint64_t *tempBasePtr = NULL;
12335+ uint32_t tempLen = 0;
12336+
12337+ if (NULL == temp_drvOpData) {
12338+ DPRINTK("%s(): The callback from the LAC component"
12339+ " has failed due to Null userOpaque data"
12340+ "(status == %d).\n", __FUNCTION__, status);
12341+ DPRINTK("%s(): Unable to call OCF back! \n", __FUNCTION__);
12342+ return;
12343+ }
12344+
12345+ crp = temp_drvOpData->crp;
12346+ crp->crp_etype = ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR;
12347+
12348+ if (NULL == pOpData) {
12349+ DPRINTK("%s(): The callback from the LAC component"
12350+ " has failed due to Null Symmetric Op data"
12351+ "(status == %d).\n", __FUNCTION__, status);
12352+ crp->crp_etype = ECANCELED;
12353+ crypto_done(crp);
12354+ return;
12355+ }
12356+
12357+ if (NULL == pDstBuffer) {
12358+ DPRINTK("%s(): The callback from the LAC component"
12359+ " has failed due to Null Dst Bufferlist data"
12360+ "(status == %d).\n", __FUNCTION__, status);
12361+ crp->crp_etype = ECANCELED;
12362+ crypto_done(crp);
12363+ return;
12364+ }
12365+
12366+ if (CPA_STATUS_SUCCESS == status) {
12367+
12368+ if (temp_drvOpData->bufferType == ICP_CRYPTO_F_PACKET_BUF) {
12369+ if (ICP_OCF_DRV_STATUS_SUCCESS !=
12370+ icp_ocfDrvBufferListToPacketBuff(pDstBuffer,
12371+ (icp_packet_buffer_t
12372+ **)
12373+ & (crp->crp_buf))) {
12374+ EPRINTK("%s(): BufferList to SkBuff "
12375+ "conversion error.\n", __FUNCTION__);
12376+ crp->crp_etype = EPERM;
12377+ }
12378+ } else {
12379+ icp_ocfDrvBufferListToPtrAndLen(pDstBuffer,
12380+ (void **)&tempBasePtr,
12381+ &tempLen);
12382+ crp->crp_olen = (int)tempLen;
12383+ }
12384+
12385+ } else {
12386+ DPRINTK("%s(): The callback from the LAC component has failed"
12387+ "(status == %d).\n", __FUNCTION__, status);
12388+
12389+ crp->crp_etype = ECANCELED;
12390+ }
12391+
12392+ if (temp_drvOpData->numBufferListArray >
12393+ ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
12394+ icp_kfree(pDstBuffer->pBuffers);
12395+ }
12396+ icp_ocfDrvFreeMetaData(pDstBuffer);
12397+ ICP_CACHE_FREE(drvOpData_zone, temp_drvOpData);
12398+
12399+ /* Invoke the OCF callback function */
12400+ crypto_done(crp);
12401+
12402+ return;
12403+}
12404+
12405+/* Name : icp_ocfDrvNewSession
12406+ *
12407+ * Description : This function will create a new Driver<->OCF session
12408+ *
12409+ * Notes : LAC session registration happens during the first perform call.
12410+ * That is the first time we know all information about a given session.
12411+ */
12412+int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sid,
12413+ struct cryptoini *cri)
12414+{
12415+ struct icp_drvSessionData *sessionData = NULL;
12416+ uint32_t delete_session = 0;
12417+
12418+ /* The SID passed in should be our driver ID. We can return the */
12419+ /* local ID (LID) which is a unique identifier which we can use */
12420+ /* to differentiate between the encrypt/decrypt LAC session handles */
12421+ if (NULL == sid) {
12422+ EPRINTK("%s(): Invalid input parameters - NULL sid.\n",
12423+ __FUNCTION__);
12424+ return EINVAL;
12425+ }
12426+
12427+ if (NULL == cri) {
12428+ EPRINTK("%s(): Invalid input parameters - NULL cryptoini.\n",
12429+ __FUNCTION__);
12430+ return EINVAL;
12431+ }
12432+
12433+ if (icp_ocfDrvDriverId != *sid) {
12434+ EPRINTK("%s(): Invalid input parameters - bad driver ID\n",
12435+ __FUNCTION__);
12436+ EPRINTK("\t sid = 0x08%p \n \t cri = 0x08%p \n", sid, cri);
12437+ return EINVAL;
12438+ }
12439+
12440+ sessionData = icp_kmem_cache_zalloc(drvSessionData_zone, ICP_M_NOWAIT);
12441+ if (NULL == sessionData) {
12442+ DPRINTK("%s():No memory for Session Data\n", __FUNCTION__);
12443+ return ENOMEM;
12444+ }
12445+
12446+ /*ENTER CRITICAL SECTION */
12447+ icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
12448+ /*put this check in the spinlock so no new sessions can be added to the
12449+ linked list when we are exiting */
12450+ if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
12451+ delete_session++;
12452+
12453+ } else if (NO_OCF_TO_DRV_MAX_SESSIONS != max_sessions) {
12454+ if (icp_atomic_read(&num_ocf_to_drv_registered_sessions) >=
12455+ (max_sessions -
12456+ icp_atomic_read(&lac_session_failed_dereg_count))) {
12457+ delete_session++;
12458+ } else {
12459+ icp_atomic_inc(&num_ocf_to_drv_registered_sessions);
12460+ /* Add to session data linked list */
12461+ ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
12462+ listNode);
12463+ }
12464+
12465+ } else if (NO_OCF_TO_DRV_MAX_SESSIONS == max_sessions) {
12466+ ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
12467+ listNode);
12468+ }
12469+
12470+ sessionData->inUse = ICP_SESSION_INITIALISED;
12471+
12472+ /*EXIT CRITICAL SECTION */
12473+ icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
12474+
12475+ if (delete_session) {
12476+ DPRINTK("%s():No Session handles available\n", __FUNCTION__);
12477+ ICP_CACHE_FREE(drvSessionData_zone, sessionData);
12478+ return EPERM;
12479+ }
12480+
12481+ if (ICP_OCF_DRV_STATUS_SUCCESS !=
12482+ icp_ocfDrvAlgorithmSetup(cri, &(sessionData->lacSessCtx))) {
12483+ DPRINTK("%s():algorithm not supported\n", __FUNCTION__);
12484+ icp_ocfDrvFreeOCFSession(sessionData);
12485+ return EINVAL;
12486+ }
12487+
12488+ if (cri->cri_next) {
12489+ if (cri->cri_next->cri_next != NULL) {
12490+ DPRINTK("%s():only two chained algorithms supported\n",
12491+ __FUNCTION__);
12492+ icp_ocfDrvFreeOCFSession(sessionData);
12493+ return EPERM;
12494+ }
12495+
12496+ if (ICP_OCF_DRV_STATUS_SUCCESS !=
12497+ icp_ocfDrvAlgorithmSetup(cri->cri_next,
12498+ &(sessionData->lacSessCtx))) {
12499+ DPRINTK("%s():second algorithm not supported\n",
12500+ __FUNCTION__);
12501+ icp_ocfDrvFreeOCFSession(sessionData);
12502+ return EINVAL;
12503+ }
12504+
12505+ sessionData->lacSessCtx.symOperation =
12506+ CPA_CY_SYM_OP_ALGORITHM_CHAINING;
12507+ }
12508+
12509+ *sid = (uint32_t) sessionData;
12510+
12511+ return ICP_OCF_DRV_STATUS_SUCCESS;
12512+}
12513+
12514+/* Name : icp_ocfDrvAlgorithmSetup
12515+ *
12516+ * Description : This function builds the session context data from the
12517+ * information supplied through OCF. Algorithm chain order and whether the
12518+ * session is Encrypt/Decrypt can only be found out at perform time however, so
12519+ * the session is registered with LAC at that time.
12520+ */
12521+static int
12522+icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
12523+ CpaCySymSessionSetupData * lacSessCtx)
12524+{
12525+
12526+ lacSessCtx->sessionPriority = CPA_CY_PRIORITY_NORMAL;
12527+
12528+ switch (cri->cri_alg) {
12529+
12530+ case CRYPTO_NULL_CBC:
12531+ DPRINTK("%s(): NULL CBC\n", __FUNCTION__);
12532+ lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
12533+ lacSessCtx->cipherSetupData.cipherAlgorithm =
12534+ CPA_CY_SYM_CIPHER_NULL;
12535+ lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
12536+ cri->cri_klen / NUM_BITS_IN_BYTE;
12537+ lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
12538+ break;
12539+
12540+ case CRYPTO_DES_CBC:
12541+ DPRINTK("%s(): DES CBC\n", __FUNCTION__);
12542+ lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
12543+ lacSessCtx->cipherSetupData.cipherAlgorithm =
12544+ CPA_CY_SYM_CIPHER_DES_CBC;
12545+ lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
12546+ cri->cri_klen / NUM_BITS_IN_BYTE;
12547+ lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
12548+ break;
12549+
12550+ case CRYPTO_3DES_CBC:
12551+ DPRINTK("%s(): 3DES CBC\n", __FUNCTION__);
12552+ lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
12553+ lacSessCtx->cipherSetupData.cipherAlgorithm =
12554+ CPA_CY_SYM_CIPHER_3DES_CBC;
12555+ lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
12556+ cri->cri_klen / NUM_BITS_IN_BYTE;
12557+ lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
12558+ break;
12559+
12560+ case CRYPTO_AES_CBC:
12561+ DPRINTK("%s(): AES CBC\n", __FUNCTION__);
12562+ lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
12563+ lacSessCtx->cipherSetupData.cipherAlgorithm =
12564+ CPA_CY_SYM_CIPHER_AES_CBC;
12565+ lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
12566+ cri->cri_klen / NUM_BITS_IN_BYTE;
12567+ lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
12568+ break;
12569+
12570+ case CRYPTO_ARC4:
12571+ DPRINTK("%s(): ARC4\n", __FUNCTION__);
12572+ lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
12573+ lacSessCtx->cipherSetupData.cipherAlgorithm =
12574+ CPA_CY_SYM_CIPHER_ARC4;
12575+ lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
12576+ cri->cri_klen / NUM_BITS_IN_BYTE;
12577+ lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
12578+ break;
12579+
12580+ case CRYPTO_SHA1:
12581+ DPRINTK("%s(): SHA1\n", __FUNCTION__);
12582+ lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
12583+ lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
12584+ lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
12585+ lacSessCtx->hashSetupData.digestResultLenInBytes =
12586+ (cri->cri_mlen ?
12587+ cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
12588+
12589+ break;
12590+
12591+ case CRYPTO_SHA1_HMAC:
12592+ DPRINTK("%s(): SHA1_HMAC\n", __FUNCTION__);
12593+ lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
12594+ lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
12595+ lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
12596+ lacSessCtx->hashSetupData.digestResultLenInBytes =
12597+ (cri->cri_mlen ?
12598+ cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
12599+ lacSessCtx->hashSetupData.authModeSetupData.authKey =
12600+ cri->cri_key;
12601+ lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
12602+ cri->cri_klen / NUM_BITS_IN_BYTE;
12603+ lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
12604+
12605+ break;
12606+
12607+ case CRYPTO_SHA2_256:
12608+ DPRINTK("%s(): SHA256\n", __FUNCTION__);
12609+ lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
12610+ lacSessCtx->hashSetupData.hashAlgorithm =
12611+ CPA_CY_SYM_HASH_SHA256;
12612+ lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
12613+ lacSessCtx->hashSetupData.digestResultLenInBytes =
12614+ (cri->cri_mlen ?
12615+ cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
12616+
12617+ break;
12618+
12619+ case CRYPTO_SHA2_256_HMAC:
12620+ DPRINTK("%s(): SHA256_HMAC\n", __FUNCTION__);
12621+ lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
12622+ lacSessCtx->hashSetupData.hashAlgorithm =
12623+ CPA_CY_SYM_HASH_SHA256;
12624+ lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
12625+ lacSessCtx->hashSetupData.digestResultLenInBytes =
12626+ (cri->cri_mlen ?
12627+ cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
12628+ lacSessCtx->hashSetupData.authModeSetupData.authKey =
12629+ cri->cri_key;
12630+ lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
12631+ cri->cri_klen / NUM_BITS_IN_BYTE;
12632+ lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
12633+
12634+ break;
12635+
12636+ case CRYPTO_SHA2_384:
12637+ DPRINTK("%s(): SHA384\n", __FUNCTION__);
12638+ lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
12639+ lacSessCtx->hashSetupData.hashAlgorithm =
12640+ CPA_CY_SYM_HASH_SHA384;
12641+ lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
12642+ lacSessCtx->hashSetupData.digestResultLenInBytes =
12643+ (cri->cri_mlen ?
12644+ cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
12645+
12646+ break;
12647+
12648+ case CRYPTO_SHA2_384_HMAC:
12649+ DPRINTK("%s(): SHA384_HMAC\n", __FUNCTION__);
12650+ lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
12651+ lacSessCtx->hashSetupData.hashAlgorithm =
12652+ CPA_CY_SYM_HASH_SHA384;
12653+ lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
12654+ lacSessCtx->hashSetupData.digestResultLenInBytes =
12655+ (cri->cri_mlen ?
12656+ cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
12657+ lacSessCtx->hashSetupData.authModeSetupData.authKey =
12658+ cri->cri_key;
12659+ lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
12660+ cri->cri_klen / NUM_BITS_IN_BYTE;
12661+ lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
12662+
12663+ break;
12664+
12665+ case CRYPTO_SHA2_512:
12666+ DPRINTK("%s(): SHA512\n", __FUNCTION__);
12667+ lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
12668+ lacSessCtx->hashSetupData.hashAlgorithm =
12669+ CPA_CY_SYM_HASH_SHA512;
12670+ lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
12671+ lacSessCtx->hashSetupData.digestResultLenInBytes =
12672+ (cri->cri_mlen ?
12673+ cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
12674+
12675+ break;
12676+
12677+ case CRYPTO_SHA2_512_HMAC:
12678+ DPRINTK("%s(): SHA512_HMAC\n", __FUNCTION__);
12679+ lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
12680+ lacSessCtx->hashSetupData.hashAlgorithm =
12681+ CPA_CY_SYM_HASH_SHA512;
12682+ lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
12683+ lacSessCtx->hashSetupData.digestResultLenInBytes =
12684+ (cri->cri_mlen ?
12685+ cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
12686+ lacSessCtx->hashSetupData.authModeSetupData.authKey =
12687+ cri->cri_key;
12688+ lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
12689+ cri->cri_klen / NUM_BITS_IN_BYTE;
12690+ lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
12691+
12692+ break;
12693+
12694+ case CRYPTO_MD5:
12695+ DPRINTK("%s(): MD5\n", __FUNCTION__);
12696+ lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
12697+ lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
12698+ lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
12699+ lacSessCtx->hashSetupData.digestResultLenInBytes =
12700+ (cri->cri_mlen ?
12701+ cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
12702+
12703+ break;
12704+
12705+ case CRYPTO_MD5_HMAC:
12706+ DPRINTK("%s(): MD5_HMAC\n", __FUNCTION__);
12707+ lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
12708+ lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
12709+ lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
12710+ lacSessCtx->hashSetupData.digestResultLenInBytes =
12711+ (cri->cri_mlen ?
12712+ cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
12713+ lacSessCtx->hashSetupData.authModeSetupData.authKey =
12714+ cri->cri_key;
12715+ lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
12716+ cri->cri_klen / NUM_BITS_IN_BYTE;
12717+ lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
12718+
12719+ break;
12720+
12721+ default:
12722+ DPRINTK("%s(): ALG Setup FAIL\n", __FUNCTION__);
12723+ return ICP_OCF_DRV_STATUS_FAIL;
12724+ }
12725+
12726+ return ICP_OCF_DRV_STATUS_SUCCESS;
12727+}
12728+
12729+/* Name : icp_ocfDrvFreeOCFSession
12730+ *
12731+ * Description : This function deletes all existing Session data representing
12732+ * the Cryptographic session established between OCF and this driver. This
12733+ * also includes freeing the memory allocated for the session context. The
12734+ * session object is also removed from the session linked list.
12735+ */
12736+static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData)
12737+{
12738+
12739+ sessionData->inUse = ICP_SESSION_DEREGISTERED;
12740+
12741+ /*ENTER CRITICAL SECTION */
12742+ icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
12743+
12744+ if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
12745+ /*If the Driver is exiting, allow that process to
12746+ handle any deletions */
12747+ /*EXIT CRITICAL SECTION */
12748+ icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
12749+ return;
12750+ }
12751+
12752+ icp_atomic_dec(&num_ocf_to_drv_registered_sessions);
12753+
12754+ ICP_LIST_DEL(sessionData, listNode);
12755+
12756+ /*EXIT CRITICAL SECTION */
12757+ icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
12758+
12759+ if (NULL != sessionData->sessHandle) {
12760+ icp_kfree(sessionData->sessHandle);
12761+ }
12762+ ICP_CACHE_FREE(drvSessionData_zone, sessionData);
12763+}
12764+
12765+/* Name : icp_ocfDrvFreeLACSession
12766+ *
12767+ * Description : This attempts to deregister a LAC session. If it fails, the
12768+ * deregistation retry function is called.
12769+ */
12770+int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid)
12771+{
12772+ CpaCySymSessionCtx sessionToDeregister = NULL;
12773+ struct icp_drvSessionData *sessionData = NULL;
12774+ CpaStatus lacStatus = CPA_STATUS_SUCCESS;
12775+ int retval = 0;
12776+
12777+ sessionData = (struct icp_drvSessionData *)CRYPTO_SESID2LID(sid);
12778+ if (NULL == sessionData) {
12779+ EPRINTK("%s(): OCF Free session called with Null Session ID.\n",
12780+ __FUNCTION__);
12781+ return EINVAL;
12782+ }
12783+
12784+ sessionToDeregister = sessionData->sessHandle;
12785+
12786+ if ((ICP_SESSION_INITIALISED != sessionData->inUse) &&
12787+ (ICP_SESSION_RUNNING != sessionData->inUse) &&
12788+ (ICP_SESSION_DEREGISTERED != sessionData->inUse)) {
12789+ DPRINTK("%s() Session not initialised.\n", __FUNCTION__);
12790+ return EINVAL;
12791+ }
12792+
12793+ if (ICP_SESSION_RUNNING == sessionData->inUse) {
12794+ lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
12795+ sessionToDeregister);
12796+ if (CPA_STATUS_RETRY == lacStatus) {
12797+ if (ICP_OCF_DRV_STATUS_SUCCESS !=
12798+ icp_ocfDrvDeregRetry(&sessionToDeregister)) {
12799+ /* the retry function increments the
12800+ dereg failed count */
12801+ DPRINTK("%s(): LAC failed to deregister the "
12802+ "session. (localSessionId= %p)\n",
12803+ __FUNCTION__, sessionToDeregister);
12804+ retval = EPERM;
12805+ }
12806+
12807+ } else if (CPA_STATUS_SUCCESS != lacStatus) {
12808+ DPRINTK("%s(): LAC failed to deregister the session. "
12809+ "localSessionId= %p, lacStatus = %d\n",
12810+ __FUNCTION__, sessionToDeregister, lacStatus);
12811+ icp_atomic_inc(&lac_session_failed_dereg_count);
12812+ retval = EPERM;
12813+ }
12814+ } else {
12815+ DPRINTK("%s() Session not registered with LAC.\n",
12816+ __FUNCTION__);
12817+ }
12818+
12819+ icp_ocfDrvFreeOCFSession(sessionData);
12820+ return retval;
12821+
12822+}
12823+
12824+/* Name : icp_ocfDrvAlgCheck
12825+ *
12826+ * Description : This function checks whether the cryptodesc argument pertains
12827+ * to a sym or hash function
12828+ */
12829+static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc)
12830+{
12831+
12832+ if (crp_desc->crd_alg == CRYPTO_3DES_CBC ||
12833+ crp_desc->crd_alg == CRYPTO_AES_CBC ||
12834+ crp_desc->crd_alg == CRYPTO_DES_CBC ||
12835+ crp_desc->crd_alg == CRYPTO_NULL_CBC ||
12836+ crp_desc->crd_alg == CRYPTO_ARC4) {
12837+ return ICP_OCF_DRV_ALG_CIPHER;
12838+ }
12839+
12840+ return ICP_OCF_DRV_ALG_HASH;
12841+}
12842+
12843+/* Name : icp_ocfDrvSymProcess
12844+ *
12845+ * Description : This function will map symmetric functionality calls from OCF
12846+ * to the LAC API. It will also allocate memory to store the session context.
12847+ *
12848+ * Notes: If it is the first perform call for a given session, then a LAC
12849+ * session is registered. After the session is registered, no checks as
12850+ * to whether session paramaters have changed (e.g. alg chain order) are
12851+ * done.
12852+ */
12853+int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint)
12854+{
12855+ struct icp_drvSessionData *sessionData = NULL;
12856+ struct icp_drvOpData *drvOpData = NULL;
12857+ CpaStatus lacStatus = CPA_STATUS_SUCCESS;
12858+ Cpa32U sessionCtxSizeInBytes = 0;
12859+
12860+ if (NULL == crp) {
12861+ DPRINTK("%s(): Invalid input parameters, cryptop is NULL\n",
12862+ __FUNCTION__);
12863+ return EINVAL;
12864+ }
12865+
12866+ if (NULL == crp->crp_desc) {
12867+ DPRINTK("%s(): Invalid input parameters, no crp_desc attached "
12868+ "to crp\n", __FUNCTION__);
12869+ crp->crp_etype = EINVAL;
12870+ return EINVAL;
12871+ }
12872+
12873+ if (NULL == crp->crp_buf) {
12874+ DPRINTK("%s(): Invalid input parameters, no buffer attached "
12875+ "to crp\n", __FUNCTION__);
12876+ crp->crp_etype = EINVAL;
12877+ return EINVAL;
12878+ }
12879+
12880+ if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
12881+ crp->crp_etype = EFAULT;
12882+ return EFAULT;
12883+ }
12884+
12885+ sessionData = (struct icp_drvSessionData *)
12886+ (CRYPTO_SESID2LID(crp->crp_sid));
12887+ if (NULL == sessionData) {
12888+ DPRINTK("%s(): Invalid input parameters, Null Session ID \n",
12889+ __FUNCTION__);
12890+ crp->crp_etype = EINVAL;
12891+ return EINVAL;
12892+ }
12893+
12894+/*If we get a request against a deregisted session, cancel operation*/
12895+ if (ICP_SESSION_DEREGISTERED == sessionData->inUse) {
12896+ DPRINTK("%s(): Session ID %d was deregistered \n",
12897+ __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
12898+ crp->crp_etype = EFAULT;
12899+ return EFAULT;
12900+ }
12901+
12902+/*If none of the session states are set, then the session structure was either
12903+ not initialised properly or we are reading from a freed memory area (possible
12904+ due to OCF batch mode not removing queued requests against deregistered
12905+ sessions*/
12906+ if (ICP_SESSION_INITIALISED != sessionData->inUse &&
12907+ ICP_SESSION_RUNNING != sessionData->inUse) {
12908+ DPRINTK("%s(): Session - ID %d - not properly initialised or "
12909+ "memory freed back to the kernel \n",
12910+ __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
12911+ crp->crp_etype = EINVAL;
12912+ return EINVAL;
12913+ }
12914+
12915+ /*For the below checks, remember error checking is already done in LAC.
12916+ We're not validating inputs subsequent to registration */
12917+ if (sessionData->inUse == ICP_SESSION_INITIALISED) {
12918+ DPRINTK("%s(): Initialising session\n", __FUNCTION__);
12919+
12920+ if (NULL != crp->crp_desc->crd_next) {
12921+ if (ICP_OCF_DRV_ALG_CIPHER ==
12922+ icp_ocfDrvAlgCheck(crp->crp_desc)) {
12923+
12924+ sessionData->lacSessCtx.algChainOrder =
12925+ CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
12926+
12927+ if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
12928+ sessionData->lacSessCtx.cipherSetupData.
12929+ cipherDirection =
12930+ CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
12931+ } else {
12932+ sessionData->lacSessCtx.cipherSetupData.
12933+ cipherDirection =
12934+ CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
12935+ }
12936+ } else {
12937+ sessionData->lacSessCtx.algChainOrder =
12938+ CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
12939+
12940+ if (crp->crp_desc->crd_next->crd_flags &
12941+ CRD_F_ENCRYPT) {
12942+ sessionData->lacSessCtx.cipherSetupData.
12943+ cipherDirection =
12944+ CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
12945+ } else {
12946+ sessionData->lacSessCtx.cipherSetupData.
12947+ cipherDirection =
12948+ CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
12949+ }
12950+
12951+ }
12952+
12953+ } else if (ICP_OCF_DRV_ALG_CIPHER ==
12954+ icp_ocfDrvAlgCheck(crp->crp_desc)) {
12955+ if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
12956+ sessionData->lacSessCtx.cipherSetupData.
12957+ cipherDirection =
12958+ CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
12959+ } else {
12960+ sessionData->lacSessCtx.cipherSetupData.
12961+ cipherDirection =
12962+ CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
12963+ }
12964+
12965+ }
12966+
12967+ /*No action required for standalone Auth here */
12968+
12969+ /* Allocate memory for SymSessionCtx before the Session Registration */
12970+ lacStatus =
12971+ cpaCySymSessionCtxGetSize(CPA_INSTANCE_HANDLE_SINGLE,
12972+ &(sessionData->lacSessCtx),
12973+ &sessionCtxSizeInBytes);
12974+ if (CPA_STATUS_SUCCESS != lacStatus) {
12975+ EPRINTK("%s(): cpaCySymSessionCtxGetSize failed - %d\n",
12976+ __FUNCTION__, lacStatus);
12977+ crp->crp_etype = EINVAL;
12978+ return EINVAL;
12979+ }
12980+ sessionData->sessHandle =
12981+ icp_kmalloc(sessionCtxSizeInBytes, ICP_M_NOWAIT);
12982+ if (NULL == sessionData->sessHandle) {
12983+ EPRINTK
12984+ ("%s(): Failed to get memory for SymSessionCtx\n",
12985+ __FUNCTION__);
12986+ crp->crp_etype = ENOMEM;
12987+ return ENOMEM;
12988+ }
12989+
12990+ lacStatus = cpaCySymInitSession(CPA_INSTANCE_HANDLE_SINGLE,
12991+ icp_ocfDrvSymCallBack,
12992+ &(sessionData->lacSessCtx),
12993+ sessionData->sessHandle);
12994+
12995+ if (CPA_STATUS_SUCCESS != lacStatus) {
12996+ EPRINTK("%s(): cpaCySymInitSession failed -%d \n",
12997+ __FUNCTION__, lacStatus);
12998+ crp->crp_etype = EFAULT;
12999+ return EFAULT;
13000+ }
13001+
13002+ sessionData->inUse = ICP_SESSION_RUNNING;
13003+ }
13004+
13005+ drvOpData = icp_kmem_cache_zalloc(drvOpData_zone, ICP_M_NOWAIT);
13006+ if (NULL == drvOpData) {
13007+ EPRINTK("%s():Failed to get memory for drvOpData\n",
13008+ __FUNCTION__);
13009+ crp->crp_etype = ENOMEM;
13010+ return ENOMEM;
13011+ }
13012+
13013+ drvOpData->lacOpData.pSessionCtx = sessionData->sessHandle;
13014+ drvOpData->digestSizeInBytes = sessionData->lacSessCtx.hashSetupData.
13015+ digestResultLenInBytes;
13016+ drvOpData->crp = crp;
13017+
13018+ /* Set the default buffer list array memory allocation */
13019+ drvOpData->srcBuffer.pBuffers = drvOpData->bufferListArray;
13020+ drvOpData->numBufferListArray = ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS;
13021+
13022+ if (ICP_OCF_DRV_STATUS_SUCCESS !=
13023+ icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->crp_desc)) {
13024+ crp->crp_etype = EINVAL;
13025+ goto err;
13026+ }
13027+
13028+ if (drvOpData->crp->crp_desc->crd_next != NULL) {
13029+ if (icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->
13030+ crp_desc->crd_next)) {
13031+ crp->crp_etype = EINVAL;
13032+ goto err;
13033+ }
13034+
13035+ }
13036+
13037+ /*
13038+ * Allocate buffer list array memory if the data fragment is more than
13039+ * the default number (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) and not
13040+ * calculated already
13041+ */
13042+ if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
13043+ if (NULL == drvOpData->lacOpData.pDigestResult) {
13044+ drvOpData->numBufferListArray =
13045+ icp_ocfDrvGetPacketBuffFrags((icp_packet_buffer_t *)
13046+ crp->crp_buf);
13047+ }
13048+
13049+ if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS <
13050+ drvOpData->numBufferListArray) {
13051+ DPRINTK("%s() numBufferListArray more than default\n",
13052+ __FUNCTION__);
13053+ drvOpData->srcBuffer.pBuffers = NULL;
13054+ drvOpData->srcBuffer.pBuffers =
13055+ icp_kmalloc(drvOpData->numBufferListArray *
13056+ sizeof(CpaFlatBuffer), ICP_M_NOWAIT);
13057+ if (NULL == drvOpData->srcBuffer.pBuffers) {
13058+ EPRINTK("%s() Failed to get memory for "
13059+ "pBuffers\n", __FUNCTION__);
13060+ ICP_CACHE_FREE(drvOpData_zone, drvOpData);
13061+ crp->crp_etype = ENOMEM;
13062+ return ENOMEM;
13063+ }
13064+ }
13065+ }
13066+
13067+ /*
13068+ * Check the type of buffer structure we got and convert it into
13069+ * CpaBufferList format.
13070+ */
13071+ if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
13072+ if (ICP_OCF_DRV_STATUS_SUCCESS !=
13073+ icp_ocfDrvPacketBuffToBufferList((icp_packet_buffer_t *)
13074+ crp->crp_buf,
13075+ &(drvOpData->srcBuffer))) {
13076+ EPRINTK("%s():Failed to translate from packet buffer "
13077+ "to bufferlist\n", __FUNCTION__);
13078+ crp->crp_etype = EINVAL;
13079+ goto err;
13080+ }
13081+
13082+ drvOpData->bufferType = ICP_CRYPTO_F_PACKET_BUF;
13083+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
13084+ /* OCF only supports IOV of one entry. */
13085+ if (NUM_IOV_SUPPORTED ==
13086+ ((struct uio *)(crp->crp_buf))->uio_iovcnt) {
13087+
13088+ icp_ocfDrvPtrAndLenToBufferList(((struct uio *)(crp->
13089+ crp_buf))->
13090+ uio_iov[0].iov_base,
13091+ ((struct uio *)(crp->
13092+ crp_buf))->
13093+ uio_iov[0].iov_len,
13094+ &(drvOpData->
13095+ srcBuffer));
13096+
13097+ drvOpData->bufferType = CRYPTO_F_IOV;
13098+
13099+ } else {
13100+ DPRINTK("%s():Unable to handle IOVs with lengths of "
13101+ "greater than one!\n", __FUNCTION__);
13102+ crp->crp_etype = EINVAL;
13103+ goto err;
13104+ }
13105+
13106+ } else {
13107+ icp_ocfDrvPtrAndLenToBufferList(crp->crp_buf,
13108+ crp->crp_ilen,
13109+ &(drvOpData->srcBuffer));
13110+
13111+ drvOpData->bufferType = CRYPTO_BUF_CONTIG;
13112+ }
13113+
13114+ /* Allocate srcBuffer's private meta data */
13115+ if (ICP_OCF_DRV_STATUS_SUCCESS !=
13116+ icp_ocfDrvAllocMetaData(&(drvOpData->srcBuffer), drvOpData)) {
13117+ EPRINTK("%s() icp_ocfDrvAllocMetaData failed\n", __FUNCTION__);
13118+ memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
13119+ crp->crp_etype = EINVAL;
13120+ goto err;
13121+ }
13122+
13123+ /* Perform "in-place" crypto operation */
13124+ lacStatus = cpaCySymPerformOp(CPA_INSTANCE_HANDLE_SINGLE,
13125+ (void *)drvOpData,
13126+ &(drvOpData->lacOpData),
13127+ &(drvOpData->srcBuffer),
13128+ &(drvOpData->srcBuffer),
13129+ &(drvOpData->verifyResult));
13130+ if (CPA_STATUS_RETRY == lacStatus) {
13131+ DPRINTK("%s(): cpaCySymPerformOp retry, lacStatus = %d\n",
13132+ __FUNCTION__, lacStatus);
13133+ memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
13134+ crp->crp_etype = ERESTART;
13135+ goto err;
13136+ }
13137+ if (CPA_STATUS_SUCCESS != lacStatus) {
13138+ EPRINTK("%s(): cpaCySymPerformOp failed, lacStatus = %d\n",
13139+ __FUNCTION__, lacStatus);
13140+ memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
13141+ crp->crp_etype = EINVAL;
13142+ goto err;
13143+ }
13144+
13145+ return 0; //OCF success status value
13146+
13147+ err:
13148+ if (drvOpData->numBufferListArray > ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
13149+ icp_kfree(drvOpData->srcBuffer.pBuffers);
13150+ }
13151+ icp_ocfDrvFreeMetaData(&(drvOpData->srcBuffer));
13152+ ICP_CACHE_FREE(drvOpData_zone, drvOpData);
13153+
13154+ return crp->crp_etype;
13155+}
13156+
13157+/* Name : icp_ocfDrvProcessDataSetup
13158+ *
13159+ * Description : This function will setup all the cryptographic operation data
13160+ * that is required by LAC to execute the operation.
13161+ */
13162+static int icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
13163+ struct cryptodesc *crp_desc)
13164+{
13165+ CpaCyRandGenOpData randGenOpData;
13166+ CpaFlatBuffer randData;
13167+
13168+ drvOpData->lacOpData.packetType = CPA_CY_SYM_PACKET_TYPE_FULL;
13169+
13170+ /* Convert from the cryptop to the ICP LAC crypto parameters */
13171+ switch (crp_desc->crd_alg) {
13172+ case CRYPTO_NULL_CBC:
13173+ drvOpData->lacOpData.
13174+ cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
13175+ drvOpData->lacOpData.
13176+ messageLenToCipherInBytes = crp_desc->crd_len;
13177+ drvOpData->verifyResult = CPA_FALSE;
13178+ drvOpData->lacOpData.ivLenInBytes = NULL_BLOCK_LEN;
13179+ break;
13180+ case CRYPTO_DES_CBC:
13181+ drvOpData->lacOpData.
13182+ cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
13183+ drvOpData->lacOpData.
13184+ messageLenToCipherInBytes = crp_desc->crd_len;
13185+ drvOpData->verifyResult = CPA_FALSE;
13186+ drvOpData->lacOpData.ivLenInBytes = DES_BLOCK_LEN;
13187+ break;
13188+ case CRYPTO_3DES_CBC:
13189+ drvOpData->lacOpData.
13190+ cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
13191+ drvOpData->lacOpData.
13192+ messageLenToCipherInBytes = crp_desc->crd_len;
13193+ drvOpData->verifyResult = CPA_FALSE;
13194+ drvOpData->lacOpData.ivLenInBytes = DES3_BLOCK_LEN;
13195+ break;
13196+ case CRYPTO_ARC4:
13197+ drvOpData->lacOpData.
13198+ cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
13199+ drvOpData->lacOpData.
13200+ messageLenToCipherInBytes = crp_desc->crd_len;
13201+ drvOpData->verifyResult = CPA_FALSE;
13202+ drvOpData->lacOpData.ivLenInBytes = ARC4_COUNTER_LEN;
13203+ break;
13204+ case CRYPTO_AES_CBC:
13205+ drvOpData->lacOpData.
13206+ cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
13207+ drvOpData->lacOpData.
13208+ messageLenToCipherInBytes = crp_desc->crd_len;
13209+ drvOpData->verifyResult = CPA_FALSE;
13210+ drvOpData->lacOpData.ivLenInBytes = RIJNDAEL128_BLOCK_LEN;
13211+ break;
13212+ case CRYPTO_SHA1:
13213+ case CRYPTO_SHA1_HMAC:
13214+ case CRYPTO_SHA2_256:
13215+ case CRYPTO_SHA2_256_HMAC:
13216+ case CRYPTO_SHA2_384:
13217+ case CRYPTO_SHA2_384_HMAC:
13218+ case CRYPTO_SHA2_512:
13219+ case CRYPTO_SHA2_512_HMAC:
13220+ case CRYPTO_MD5:
13221+ case CRYPTO_MD5_HMAC:
13222+ drvOpData->lacOpData.
13223+ hashStartSrcOffsetInBytes = crp_desc->crd_skip;
13224+ drvOpData->lacOpData.
13225+ messageLenToHashInBytes = crp_desc->crd_len;
13226+ drvOpData->lacOpData.
13227+ pDigestResult =
13228+ icp_ocfDrvDigestPointerFind(drvOpData, crp_desc);
13229+
13230+ if (NULL == drvOpData->lacOpData.pDigestResult) {
13231+ DPRINTK("%s(): ERROR - could not calculate "
13232+ "Digest Result memory address\n", __FUNCTION__);
13233+ return ICP_OCF_DRV_STATUS_FAIL;
13234+ }
13235+
13236+ drvOpData->lacOpData.digestVerify = CPA_FALSE;
13237+ break;
13238+ default:
13239+ DPRINTK("%s(): Crypto process error - algorithm not "
13240+ "found \n", __FUNCTION__);
13241+ return ICP_OCF_DRV_STATUS_FAIL;
13242+ }
13243+
13244+ /* Figure out what the IV is supposed to be */
13245+ if ((crp_desc->crd_alg == CRYPTO_DES_CBC) ||
13246+ (crp_desc->crd_alg == CRYPTO_3DES_CBC) ||
13247+ (crp_desc->crd_alg == CRYPTO_AES_CBC)) {
13248+ /*ARC4 doesn't use an IV */
13249+ if (crp_desc->crd_flags & CRD_F_IV_EXPLICIT) {
13250+ /* Explicit IV provided to OCF */
13251+ drvOpData->lacOpData.pIv = crp_desc->crd_iv;
13252+ } else {
13253+ /* IV is not explicitly provided to OCF */
13254+
13255+ /* Point the LAC OP Data IV pointer to our allocated
13256+ storage location for this session. */
13257+ drvOpData->lacOpData.pIv = drvOpData->ivData;
13258+
13259+ if ((crp_desc->crd_flags & CRD_F_ENCRYPT) &&
13260+ ((crp_desc->crd_flags & CRD_F_IV_PRESENT) == 0)) {
13261+
13262+ /* Encrypting - need to create IV */
13263+ randGenOpData.generateBits = CPA_TRUE;
13264+ randGenOpData.lenInBytes = MAX_IV_LEN_IN_BYTES;
13265+
13266+ icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *)
13267+ drvOpData->
13268+ ivData,
13269+ MAX_IV_LEN_IN_BYTES,
13270+ &randData);
13271+
13272+ if (CPA_STATUS_SUCCESS !=
13273+ cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
13274+ NULL, NULL,
13275+ &randGenOpData, &randData)) {
13276+ DPRINTK("%s(): ERROR - Failed to"
13277+ " generate"
13278+ " Initialisation Vector\n",
13279+ __FUNCTION__);
13280+ return ICP_OCF_DRV_STATUS_FAIL;
13281+ }
13282+
13283+ crypto_copyback(drvOpData->crp->
13284+ crp_flags,
13285+ drvOpData->crp->crp_buf,
13286+ crp_desc->crd_inject,
13287+ drvOpData->lacOpData.
13288+ ivLenInBytes,
13289+ (caddr_t) (drvOpData->lacOpData.
13290+ pIv));
13291+ } else {
13292+ /* Reading IV from buffer */
13293+ crypto_copydata(drvOpData->crp->
13294+ crp_flags,
13295+ drvOpData->crp->crp_buf,
13296+ crp_desc->crd_inject,
13297+ drvOpData->lacOpData.
13298+ ivLenInBytes,
13299+ (caddr_t) (drvOpData->lacOpData.
13300+ pIv));
13301+ }
13302+
13303+ }
13304+
13305+ }
13306+
13307+ return ICP_OCF_DRV_STATUS_SUCCESS;
13308+}
13309+
13310+/* Name : icp_ocfDrvDigestPointerFind
13311+ *
13312+ * Description : This function is used to find the memory address of where the
13313+ * digest information shall be stored in. Input buffer types are an skbuff, iov
13314+ * or flat buffer. The address is found using the buffer data start address and
13315+ * an offset.
13316+ *
13317+ * Note: In the case of a linux skbuff, the digest address may exist within
13318+ * a memory space linked to from the start buffer. These linked memory spaces
13319+ * must be traversed by the data length offset in order to find the digest start
13320+ * address. Whether there is enough space for the digest must also be checked.
13321+ */
13322+uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData * drvOpData,
13323+ struct cryptodesc * crp_desc)
13324+{
13325+
13326+ int offsetInBytes = crp_desc->crd_inject;
13327+ uint32_t digestSizeInBytes = drvOpData->digestSizeInBytes;
13328+ uint8_t *flat_buffer_base = NULL;
13329+ int flat_buffer_length = 0;
13330+
13331+ if (drvOpData->crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
13332+
13333+ return icp_ocfDrvPacketBufferDigestPointerFind(drvOpData,
13334+ offsetInBytes,
13335+ digestSizeInBytes);
13336+
13337+ } else {
13338+ /* IOV or flat buffer */
13339+ if (drvOpData->crp->crp_flags & CRYPTO_F_IOV) {
13340+ /*single IOV check has already been done */
13341+ flat_buffer_base = ((struct uio *)
13342+ (drvOpData->crp->crp_buf))->
13343+ uio_iov[0].iov_base;
13344+ flat_buffer_length = ((struct uio *)
13345+ (drvOpData->crp->crp_buf))->
13346+ uio_iov[0].iov_len;
13347+ } else {
13348+ flat_buffer_base = (uint8_t *) drvOpData->crp->crp_buf;
13349+ flat_buffer_length = drvOpData->crp->crp_ilen;
13350+ }
13351+
13352+ if (flat_buffer_length < (offsetInBytes + digestSizeInBytes)) {
13353+ DPRINTK("%s() Not enough space for Digest "
13354+ "(IOV/Flat Buffer) \n", __FUNCTION__);
13355+ return NULL;
13356+ } else {
13357+ return (uint8_t *) (flat_buffer_base + offsetInBytes);
13358+ }
13359+ }
13360+ DPRINTK("%s() Should not reach this point\n", __FUNCTION__);
13361+ return NULL;
13362+}
13363diff --git a/crypto/ocf/hifn/Makefile b/crypto/ocf/hifn/Makefile
13364new file mode 100644
13365index 0000000..163fed0
13366--- /dev/null
13367+++ b/crypto/ocf/hifn/Makefile
13368@@ -0,0 +1,13 @@
13369+# for SGlinux builds
13370+-include $(ROOTDIR)/modules/.config
13371+
13372+obj-$(CONFIG_OCF_HIFN) += hifn7751.o
13373+obj-$(CONFIG_OCF_HIFNHIPP) += hifnHIPP.o
13374+
13375+obj ?= .
13376+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
13377+
13378+ifdef TOPDIR
13379+-include $(TOPDIR)/Rules.make
13380+endif
13381+
13382diff --git a/crypto/ocf/hifn/hifn7751.c b/crypto/ocf/hifn/hifn7751.c
13383new file mode 100644
13384index 0000000..e7a5958
13385--- /dev/null
13386+++ b/crypto/ocf/hifn/hifn7751.c
13387@@ -0,0 +1,2976 @@
13388+/* $OpenBSD: hifn7751.c,v 1.120 2002/05/17 00:33:34 deraadt Exp $ */
13389+
13390+/*-
13391+ * Invertex AEON / Hifn 7751 driver
13392+ * Copyright (c) 1999 Invertex Inc. All rights reserved.
13393+ * Copyright (c) 1999 Theo de Raadt
13394+ * Copyright (c) 2000-2001 Network Security Technologies, Inc.
13395+ * http://www.netsec.net
13396+ * Copyright (c) 2003 Hifn Inc.
13397+ *
13398+ * This driver is based on a previous driver by Invertex, for which they
13399+ * requested: Please send any comments, feedback, bug-fixes, or feature
13400+ * requests to software@invertex.com.
13401+ *
13402+ * Redistribution and use in source and binary forms, with or without
13403+ * modification, are permitted provided that the following conditions
13404+ * are met:
13405+ *
13406+ * 1. Redistributions of source code must retain the above copyright
13407+ * notice, this list of conditions and the following disclaimer.
13408+ * 2. Redistributions in binary form must reproduce the above copyright
13409+ * notice, this list of conditions and the following disclaimer in the
13410+ * documentation and/or other materials provided with the distribution.
13411+ * 3. The name of the author may not be used to endorse or promote products
13412+ * derived from this software without specific prior written permission.
13413+ *
13414+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
13415+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
13416+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
13417+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
13418+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
13419+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
13420+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13421+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13422+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
13423+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13424+ *
13425+ * Effort sponsored in part by the Defense Advanced Research Projects
13426+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
13427+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
13428+ *
13429+ *
13430+__FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam Exp $");
13431+ */
13432+
13433+/*
13434+ * Driver for various Hifn encryption processors.
13435+ */
13436+#ifndef AUTOCONF_INCLUDED
13437+#include <linux/config.h>
13438+#endif
13439+#include <linux/module.h>
13440+#include <linux/init.h>
13441+#include <linux/list.h>
13442+#include <linux/slab.h>
13443+#include <linux/wait.h>
13444+#include <linux/sched.h>
13445+#include <linux/pci.h>
13446+#include <linux/delay.h>
13447+#include <linux/interrupt.h>
13448+#include <linux/spinlock.h>
13449+#include <linux/random.h>
13450+#include <linux/version.h>
13451+#include <linux/skbuff.h>
13452+#include <asm/io.h>
13453+
13454+#include <cryptodev.h>
13455+#include <uio.h>
13456+#include <hifn/hifn7751reg.h>
13457+#include <hifn/hifn7751var.h>
13458+
13459+#if 1
13460+#define DPRINTF(a...) if (hifn_debug) { \
13461+ printk("%s: ", sc ? \
13462+ device_get_nameunit(sc->sc_dev) : "hifn"); \
13463+ printk(a); \
13464+ } else
13465+#else
13466+#define DPRINTF(a...)
13467+#endif
13468+
13469+static inline int
13470+pci_get_revid(struct pci_dev *dev)
13471+{
13472+ u8 rid = 0;
13473+ pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
13474+ return rid;
13475+}
13476+
13477+static struct hifn_stats hifnstats;
13478+
13479+#define debug hifn_debug
13480+int hifn_debug = 0;
13481+module_param(hifn_debug, int, 0644);
13482+MODULE_PARM_DESC(hifn_debug, "Enable debug");
13483+
13484+int hifn_maxbatch = 1;
13485+module_param(hifn_maxbatch, int, 0644);
13486+MODULE_PARM_DESC(hifn_maxbatch, "max ops to batch w/o interrupt");
13487+
13488+int hifn_cache_linesize = 0x10;
13489+module_param(hifn_cache_linesize, int, 0444);
13490+MODULE_PARM_DESC(hifn_cache_linesize, "PCI config cache line size");
13491+
13492+#ifdef MODULE_PARM
13493+char *hifn_pllconfig = NULL;
13494+MODULE_PARM(hifn_pllconfig, "s");
13495+#else
13496+char hifn_pllconfig[32]; /* This setting is RO after loading */
13497+module_param_string(hifn_pllconfig, hifn_pllconfig, 32, 0444);
13498+#endif
13499+MODULE_PARM_DESC(hifn_pllconfig, "PLL config, ie., pci66, ext33, ...");
13500+
13501+#ifdef HIFN_VULCANDEV
13502+#include <sys/conf.h>
13503+#include <sys/uio.h>
13504+
13505+static struct cdevsw vulcanpk_cdevsw; /* forward declaration */
13506+#endif
13507+
13508+/*
13509+ * Prototypes and count for the pci_device structure
13510+ */
13511+static int hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent);
13512+static void hifn_remove(struct pci_dev *dev);
13513+
13514+static int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);
13515+static int hifn_freesession(device_t, u_int64_t);
13516+static int hifn_process(device_t, struct cryptop *, int);
13517+
13518+static device_method_t hifn_methods = {
13519+ /* crypto device methods */
13520+ DEVMETHOD(cryptodev_newsession, hifn_newsession),
13521+ DEVMETHOD(cryptodev_freesession,hifn_freesession),
13522+ DEVMETHOD(cryptodev_process, hifn_process),
13523+};
13524+
13525+static void hifn_reset_board(struct hifn_softc *, int);
13526+static void hifn_reset_puc(struct hifn_softc *);
13527+static void hifn_puc_wait(struct hifn_softc *);
13528+static int hifn_enable_crypto(struct hifn_softc *);
13529+static void hifn_set_retry(struct hifn_softc *sc);
13530+static void hifn_init_dma(struct hifn_softc *);
13531+static void hifn_init_pci_registers(struct hifn_softc *);
13532+static int hifn_sramsize(struct hifn_softc *);
13533+static int hifn_dramsize(struct hifn_softc *);
13534+static int hifn_ramtype(struct hifn_softc *);
13535+static void hifn_sessions(struct hifn_softc *);
13536+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
13537+static irqreturn_t hifn_intr(int irq, void *arg);
13538+#else
13539+static irqreturn_t hifn_intr(int irq, void *arg, struct pt_regs *regs);
13540+#endif
13541+static u_int hifn_write_command(struct hifn_command *, u_int8_t *);
13542+static u_int32_t hifn_next_signature(u_int32_t a, u_int cnt);
13543+static void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *);
13544+static int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int);
13545+static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);
13546+static int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *);
13547+static int hifn_dmamap_load_src(struct hifn_softc *, struct hifn_command *);
13548+static int hifn_dmamap_load_dst(struct hifn_softc *, struct hifn_command *);
13549+static int hifn_init_pubrng(struct hifn_softc *);
13550+static void hifn_tick(unsigned long arg);
13551+static void hifn_abort(struct hifn_softc *);
13552+static void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *);
13553+
13554+static void hifn_write_reg_0(struct hifn_softc *, bus_size_t, u_int32_t);
13555+static void hifn_write_reg_1(struct hifn_softc *, bus_size_t, u_int32_t);
13556+
13557+#ifdef CONFIG_OCF_RANDOMHARVEST
13558+static int hifn_read_random(void *arg, u_int32_t *buf, int len);
13559+#endif
13560+
13561+#define HIFN_MAX_CHIPS 8
13562+static struct hifn_softc *hifn_chip_idx[HIFN_MAX_CHIPS];
13563+
13564+static __inline u_int32_t
13565+READ_REG_0(struct hifn_softc *sc, bus_size_t reg)
13566+{
13567+ u_int32_t v = readl(sc->sc_bar0 + reg);
13568+ sc->sc_bar0_lastreg = (bus_size_t) -1;
13569+ return (v);
13570+}
13571+#define WRITE_REG_0(sc, reg, val) hifn_write_reg_0(sc, reg, val)
13572+
13573+static __inline u_int32_t
13574+READ_REG_1(struct hifn_softc *sc, bus_size_t reg)
13575+{
13576+ u_int32_t v = readl(sc->sc_bar1 + reg);
13577+ sc->sc_bar1_lastreg = (bus_size_t) -1;
13578+ return (v);
13579+}
13580+#define WRITE_REG_1(sc, reg, val) hifn_write_reg_1(sc, reg, val)
13581+
13582+/*
13583+ * map in a given buffer (great on some arches :-)
13584+ */
13585+
13586+static int
13587+pci_map_uio(struct hifn_softc *sc, struct hifn_operand *buf, struct uio *uio)
13588+{
13589+ struct iovec *iov = uio->uio_iov;
13590+
13591+ DPRINTF("%s()\n", __FUNCTION__);
13592+
13593+ buf->mapsize = 0;
13594+ for (buf->nsegs = 0; buf->nsegs < uio->uio_iovcnt; ) {
13595+ buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
13596+ iov->iov_base, iov->iov_len,
13597+ PCI_DMA_BIDIRECTIONAL);
13598+ buf->segs[buf->nsegs].ds_len = iov->iov_len;
13599+ buf->mapsize += iov->iov_len;
13600+ iov++;
13601+ buf->nsegs++;
13602+ }
13603+ /* identify this buffer by the first segment */
13604+ buf->map = (void *) buf->segs[0].ds_addr;
13605+ return(0);
13606+}
13607+
13608+/*
13609+ * map in a given sk_buff
13610+ */
13611+
13612+static int
13613+pci_map_skb(struct hifn_softc *sc,struct hifn_operand *buf,struct sk_buff *skb)
13614+{
13615+ int i;
13616+
13617+ DPRINTF("%s()\n", __FUNCTION__);
13618+
13619+ buf->mapsize = 0;
13620+
13621+ buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
13622+ skb->data, skb_headlen(skb), PCI_DMA_BIDIRECTIONAL);
13623+ buf->segs[0].ds_len = skb_headlen(skb);
13624+ buf->mapsize += buf->segs[0].ds_len;
13625+
13626+ buf->nsegs = 1;
13627+
13628+ for (i = 0; i < skb_shinfo(skb)->nr_frags; ) {
13629+ buf->segs[buf->nsegs].ds_len = skb_shinfo(skb)->frags[i].size;
13630+ buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
13631+ page_address(skb_shinfo(skb)->frags[i].page) +
13632+ skb_shinfo(skb)->frags[i].page_offset,
13633+ buf->segs[buf->nsegs].ds_len, PCI_DMA_BIDIRECTIONAL);
13634+ buf->mapsize += buf->segs[buf->nsegs].ds_len;
13635+ buf->nsegs++;
13636+ }
13637+
13638+ /* identify this buffer by the first segment */
13639+ buf->map = (void *) buf->segs[0].ds_addr;
13640+ return(0);
13641+}
13642+
13643+/*
13644+ * map in a given contiguous buffer
13645+ */
13646+
13647+static int
13648+pci_map_buf(struct hifn_softc *sc,struct hifn_operand *buf, void *b, int len)
13649+{
13650+ DPRINTF("%s()\n", __FUNCTION__);
13651+
13652+ buf->mapsize = 0;
13653+ buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
13654+ b, len, PCI_DMA_BIDIRECTIONAL);
13655+ buf->segs[0].ds_len = len;
13656+ buf->mapsize += buf->segs[0].ds_len;
13657+ buf->nsegs = 1;
13658+
13659+ /* identify this buffer by the first segment */
13660+ buf->map = (void *) buf->segs[0].ds_addr;
13661+ return(0);
13662+}
13663+
13664+#if 0 /* not needed at this time */
13665+static void
13666+pci_sync_iov(struct hifn_softc *sc, struct hifn_operand *buf)
13667+{
13668+ int i;
13669+
13670+ DPRINTF("%s()\n", __FUNCTION__);
13671+ for (i = 0; i < buf->nsegs; i++)
13672+ pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
13673+ buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
13674+}
13675+#endif
13676+
13677+static void
13678+pci_unmap_buf(struct hifn_softc *sc, struct hifn_operand *buf)
13679+{
13680+ int i;
13681+ DPRINTF("%s()\n", __FUNCTION__);
13682+ for (i = 0; i < buf->nsegs; i++) {
13683+ pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
13684+ buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
13685+ buf->segs[i].ds_addr = 0;
13686+ buf->segs[i].ds_len = 0;
13687+ }
13688+ buf->nsegs = 0;
13689+ buf->mapsize = 0;
13690+ buf->map = 0;
13691+}
13692+
13693+static const char*
13694+hifn_partname(struct hifn_softc *sc)
13695+{
13696+ /* XXX sprintf numbers when not decoded */
13697+ switch (pci_get_vendor(sc->sc_pcidev)) {
13698+ case PCI_VENDOR_HIFN:
13699+ switch (pci_get_device(sc->sc_pcidev)) {
13700+ case PCI_PRODUCT_HIFN_6500: return "Hifn 6500";
13701+ case PCI_PRODUCT_HIFN_7751: return "Hifn 7751";
13702+ case PCI_PRODUCT_HIFN_7811: return "Hifn 7811";
13703+ case PCI_PRODUCT_HIFN_7951: return "Hifn 7951";
13704+ case PCI_PRODUCT_HIFN_7955: return "Hifn 7955";
13705+ case PCI_PRODUCT_HIFN_7956: return "Hifn 7956";
13706+ }
13707+ return "Hifn unknown-part";
13708+ case PCI_VENDOR_INVERTEX:
13709+ switch (pci_get_device(sc->sc_pcidev)) {
13710+ case PCI_PRODUCT_INVERTEX_AEON: return "Invertex AEON";
13711+ }
13712+ return "Invertex unknown-part";
13713+ case PCI_VENDOR_NETSEC:
13714+ switch (pci_get_device(sc->sc_pcidev)) {
13715+ case PCI_PRODUCT_NETSEC_7751: return "NetSec 7751";
13716+ }
13717+ return "NetSec unknown-part";
13718+ }
13719+ return "Unknown-vendor unknown-part";
13720+}
13721+
13722+static u_int
13723+checkmaxmin(struct pci_dev *dev, const char *what, u_int v, u_int min, u_int max)
13724+{
13725+ struct hifn_softc *sc = pci_get_drvdata(dev);
13726+ if (v > max) {
13727+ device_printf(sc->sc_dev, "Warning, %s %u out of range, "
13728+ "using max %u\n", what, v, max);
13729+ v = max;
13730+ } else if (v < min) {
13731+ device_printf(sc->sc_dev, "Warning, %s %u out of range, "
13732+ "using min %u\n", what, v, min);
13733+ v = min;
13734+ }
13735+ return v;
13736+}
13737+
13738+/*
13739+ * Select PLL configuration for 795x parts. This is complicated in
13740+ * that we cannot determine the optimal parameters without user input.
13741+ * The reference clock is derived from an external clock through a
13742+ * multiplier. The external clock is either the host bus (i.e. PCI)
13743+ * or an external clock generator. When using the PCI bus we assume
13744+ * the clock is either 33 or 66 MHz; for an external source we cannot
13745+ * tell the speed.
13746+ *
13747+ * PLL configuration is done with a string: "pci" for PCI bus, or "ext"
13748+ * for an external source, followed by the frequency. We calculate
13749+ * the appropriate multiplier and PLL register contents accordingly.
13750+ * When no configuration is given we default to "pci66" since that
13751+ * always will allow the card to work. If a card is using the PCI
13752+ * bus clock and in a 33MHz slot then it will be operating at half
13753+ * speed until the correct information is provided.
13754+ *
13755+ * We use a default setting of "ext66" because according to Mike Ham
13756+ * of HiFn, almost every board in existence has an external crystal
13757+ * populated at 66Mhz. Using PCI can be a problem on modern motherboards,
13758+ * because PCI33 can have clocks from 0 to 33Mhz, and some have
13759+ * non-PCI-compliant spread-spectrum clocks, which can confuse the pll.
13760+ */
13761+static void
13762+hifn_getpllconfig(struct pci_dev *dev, u_int *pll)
13763+{
13764+ const char *pllspec = hifn_pllconfig;
13765+ u_int freq, mul, fl, fh;
13766+ u_int32_t pllconfig;
13767+ char *nxt;
13768+
13769+ if (pllspec == NULL)
13770+ pllspec = "ext66";
13771+ fl = 33, fh = 66;
13772+ pllconfig = 0;
13773+ if (strncmp(pllspec, "ext", 3) == 0) {
13774+ pllspec += 3;
13775+ pllconfig |= HIFN_PLL_REF_SEL;
13776+ switch (pci_get_device(dev)) {
13777+ case PCI_PRODUCT_HIFN_7955:
13778+ case PCI_PRODUCT_HIFN_7956:
13779+ fl = 20, fh = 100;
13780+ break;
13781+#ifdef notyet
13782+ case PCI_PRODUCT_HIFN_7954:
13783+ fl = 20, fh = 66;
13784+ break;
13785+#endif
13786+ }
13787+ } else if (strncmp(pllspec, "pci", 3) == 0)
13788+ pllspec += 3;
13789+ freq = strtoul(pllspec, &nxt, 10);
13790+ if (nxt == pllspec)
13791+ freq = 66;
13792+ else
13793+ freq = checkmaxmin(dev, "frequency", freq, fl, fh);
13794+ /*
13795+ * Calculate multiplier. We target a Fck of 266 MHz,
13796+ * allowing only even values, possibly rounded down.
13797+ * Multipliers > 8 must set the charge pump current.
13798+ */
13799+ mul = checkmaxmin(dev, "PLL divisor", (266 / freq) &~ 1, 2, 12);
13800+ pllconfig |= (mul / 2 - 1) << HIFN_PLL_ND_SHIFT;
13801+ if (mul > 8)
13802+ pllconfig |= HIFN_PLL_IS;
13803+ *pll = pllconfig;
13804+}
13805+
13806+/*
13807+ * Attach an interface that successfully probed.
13808+ */
13809+static int
13810+hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent)
13811+{
13812+ struct hifn_softc *sc = NULL;
13813+ char rbase;
13814+ u_int16_t ena, rev;
13815+ int rseg, rc;
13816+ unsigned long mem_start, mem_len;
13817+ static int num_chips = 0;
13818+
13819+ DPRINTF("%s()\n", __FUNCTION__);
13820+
13821+ if (pci_enable_device(dev) < 0)
13822+ return(-ENODEV);
13823+
13824+ if (pci_set_mwi(dev))
13825+ return(-ENODEV);
13826+
13827+ if (!dev->irq) {
13828+ printk("hifn: found device with no IRQ assigned. check BIOS settings!");
13829+ pci_disable_device(dev);
13830+ return(-ENODEV);
13831+ }
13832+
13833+ sc = (struct hifn_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
13834+ if (!sc)
13835+ return(-ENOMEM);
13836+ memset(sc, 0, sizeof(*sc));
13837+
13838+ softc_device_init(sc, "hifn", num_chips, hifn_methods);
13839+
13840+ sc->sc_pcidev = dev;
13841+ sc->sc_irq = -1;
13842+ sc->sc_cid = -1;
13843+ sc->sc_num = num_chips++;
13844+ if (sc->sc_num < HIFN_MAX_CHIPS)
13845+ hifn_chip_idx[sc->sc_num] = sc;
13846+
13847+ pci_set_drvdata(sc->sc_pcidev, sc);
13848+
13849+ spin_lock_init(&sc->sc_mtx);
13850+
13851+ /* XXX handle power management */
13852+
13853+ /*
13854+ * The 7951 and 795x have a random number generator and
13855+ * public key support; note this.
13856+ */
13857+ if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
13858+ (pci_get_device(dev) == PCI_PRODUCT_HIFN_7951 ||
13859+ pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
13860+ pci_get_device(dev) == PCI_PRODUCT_HIFN_7956))
13861+ sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC;
13862+ /*
13863+ * The 7811 has a random number generator and
13864+ * we also note it's identity 'cuz of some quirks.
13865+ */
13866+ if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
13867+ pci_get_device(dev) == PCI_PRODUCT_HIFN_7811)
13868+ sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG;
13869+
13870+ /*
13871+ * The 795x parts support AES.
13872+ */
13873+ if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
13874+ (pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
13875+ pci_get_device(dev) == PCI_PRODUCT_HIFN_7956)) {
13876+ sc->sc_flags |= HIFN_IS_7956 | HIFN_HAS_AES;
13877+ /*
13878+ * Select PLL configuration. This depends on the
13879+ * bus and board design and must be manually configured
13880+ * if the default setting is unacceptable.
13881+ */
13882+ hifn_getpllconfig(dev, &sc->sc_pllconfig);
13883+ }
13884+
13885+ /*
13886+ * Setup PCI resources. Note that we record the bus
13887+ * tag and handle for each register mapping, this is
13888+ * used by the READ_REG_0, WRITE_REG_0, READ_REG_1,
13889+ * and WRITE_REG_1 macros throughout the driver.
13890+ */
13891+ mem_start = pci_resource_start(sc->sc_pcidev, 0);
13892+ mem_len = pci_resource_len(sc->sc_pcidev, 0);
13893+ sc->sc_bar0 = (ocf_iomem_t) ioremap(mem_start, mem_len);
13894+ if (!sc->sc_bar0) {
13895+ device_printf(sc->sc_dev, "cannot map bar%d register space\n", 0);
13896+ goto fail;
13897+ }
13898+ sc->sc_bar0_lastreg = (bus_size_t) -1;
13899+
13900+ mem_start = pci_resource_start(sc->sc_pcidev, 1);
13901+ mem_len = pci_resource_len(sc->sc_pcidev, 1);
13902+ sc->sc_bar1 = (ocf_iomem_t) ioremap(mem_start, mem_len);
13903+ if (!sc->sc_bar1) {
13904+ device_printf(sc->sc_dev, "cannot map bar%d register space\n", 1);
13905+ goto fail;
13906+ }
13907+ sc->sc_bar1_lastreg = (bus_size_t) -1;
13908+
13909+ /* fix up the bus size */
13910+ if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
13911+ device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
13912+ goto fail;
13913+ }
13914+ if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
13915+ device_printf(sc->sc_dev,
13916+ "No usable consistent DMA configuration, aborting.\n");
13917+ goto fail;
13918+ }
13919+
13920+ hifn_set_retry(sc);
13921+
13922+ /*
13923+ * Setup the area where the Hifn DMA's descriptors
13924+ * and associated data structures.
13925+ */
13926+ sc->sc_dma = (struct hifn_dma *) pci_alloc_consistent(dev,
13927+ sizeof(*sc->sc_dma),
13928+ &sc->sc_dma_physaddr);
13929+ if (!sc->sc_dma) {
13930+ device_printf(sc->sc_dev, "cannot alloc sc_dma\n");
13931+ goto fail;
13932+ }
13933+ bzero(sc->sc_dma, sizeof(*sc->sc_dma));
13934+
13935+ /*
13936+ * Reset the board and do the ``secret handshake''
13937+ * to enable the crypto support. Then complete the
13938+ * initialization procedure by setting up the interrupt
13939+ * and hooking in to the system crypto support so we'll
13940+ * get used for system services like the crypto device,
13941+ * IPsec, RNG device, etc.
13942+ */
13943+ hifn_reset_board(sc, 0);
13944+
13945+ if (hifn_enable_crypto(sc) != 0) {
13946+ device_printf(sc->sc_dev, "crypto enabling failed\n");
13947+ goto fail;
13948+ }
13949+ hifn_reset_puc(sc);
13950+
13951+ hifn_init_dma(sc);
13952+ hifn_init_pci_registers(sc);
13953+
13954+ pci_set_master(sc->sc_pcidev);
13955+
13956+ /* XXX can't dynamically determine ram type for 795x; force dram */
13957+ if (sc->sc_flags & HIFN_IS_7956)
13958+ sc->sc_drammodel = 1;
13959+ else if (hifn_ramtype(sc))
13960+ goto fail;
13961+
13962+ if (sc->sc_drammodel == 0)
13963+ hifn_sramsize(sc);
13964+ else
13965+ hifn_dramsize(sc);
13966+
13967+ /*
13968+ * Workaround for NetSec 7751 rev A: half ram size because two
13969+ * of the address lines were left floating
13970+ */
13971+ if (pci_get_vendor(dev) == PCI_VENDOR_NETSEC &&
13972+ pci_get_device(dev) == PCI_PRODUCT_NETSEC_7751 &&
13973+ pci_get_revid(dev) == 0x61) /*XXX???*/
13974+ sc->sc_ramsize >>= 1;
13975+
13976+ /*
13977+ * Arrange the interrupt line.
13978+ */
13979+ rc = request_irq(dev->irq, hifn_intr, IRQF_SHARED, "hifn", sc);
13980+ if (rc) {
13981+ device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
13982+ goto fail;
13983+ }
13984+ sc->sc_irq = dev->irq;
13985+
13986+ hifn_sessions(sc);
13987+
13988+ /*
13989+ * NB: Keep only the low 16 bits; this masks the chip id
13990+ * from the 7951.
13991+ */
13992+ rev = READ_REG_1(sc, HIFN_1_REVID) & 0xffff;
13993+
13994+ rseg = sc->sc_ramsize / 1024;
13995+ rbase = 'K';
13996+ if (sc->sc_ramsize >= (1024 * 1024)) {
13997+ rbase = 'M';
13998+ rseg /= 1024;
13999+ }
14000+ device_printf(sc->sc_dev, "%s, rev %u, %d%cB %cram",
14001+ hifn_partname(sc), rev,
14002+ rseg, rbase, sc->sc_drammodel ? 'd' : 's');
14003+ if (sc->sc_flags & HIFN_IS_7956)
14004+ printf(", pll=0x%x<%s clk, %ux mult>",
14005+ sc->sc_pllconfig,
14006+ sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
14007+ 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
14008+ printf("\n");
14009+
14010+ sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
14011+ if (sc->sc_cid < 0) {
14012+ device_printf(sc->sc_dev, "could not get crypto driver id\n");
14013+ goto fail;
14014+ }
14015+
14016+ WRITE_REG_0(sc, HIFN_0_PUCNFG,
14017+ READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID);
14018+ ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
14019+
14020+ switch (ena) {
14021+ case HIFN_PUSTAT_ENA_2:
14022+ crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
14023+ crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
14024+ if (sc->sc_flags & HIFN_HAS_AES)
14025+ crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
14026+ /*FALLTHROUGH*/
14027+ case HIFN_PUSTAT_ENA_1:
14028+ crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
14029+ crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
14030+ crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
14031+ crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
14032+ crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
14033+ break;
14034+ }
14035+
14036+ if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG))
14037+ hifn_init_pubrng(sc);
14038+
14039+ init_timer(&sc->sc_tickto);
14040+ sc->sc_tickto.function = hifn_tick;
14041+ sc->sc_tickto.data = (unsigned long) sc->sc_num;
14042+ mod_timer(&sc->sc_tickto, jiffies + HZ);
14043+
14044+ return (0);
14045+
14046+fail:
14047+ if (sc->sc_cid >= 0)
14048+ crypto_unregister_all(sc->sc_cid);
14049+ if (sc->sc_irq != -1)
14050+ free_irq(sc->sc_irq, sc);
14051+ if (sc->sc_dma) {
14052+ /* Turn off DMA polling */
14053+ WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
14054+ HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
14055+
14056+ pci_free_consistent(sc->sc_pcidev,
14057+ sizeof(*sc->sc_dma),
14058+ sc->sc_dma, sc->sc_dma_physaddr);
14059+ }
14060+ kfree(sc);
14061+ return (-ENXIO);
14062+}
14063+
14064+/*
14065+ * Detach an interface that successfully probed.
14066+ */
14067+static void
14068+hifn_remove(struct pci_dev *dev)
14069+{
14070+ struct hifn_softc *sc = pci_get_drvdata(dev);
14071+ unsigned long l_flags;
14072+
14073+ DPRINTF("%s()\n", __FUNCTION__);
14074+
14075+ KASSERT(sc != NULL, ("hifn_detach: null software carrier!"));
14076+
14077+ /* disable interrupts */
14078+ HIFN_LOCK(sc);
14079+ WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
14080+ HIFN_UNLOCK(sc);
14081+
14082+ /*XXX other resources */
14083+ del_timer_sync(&sc->sc_tickto);
14084+
14085+ /* Turn off DMA polling */
14086+ WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
14087+ HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
14088+
14089+ crypto_unregister_all(sc->sc_cid);
14090+
14091+ free_irq(sc->sc_irq, sc);
14092+
14093+ pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
14094+ sc->sc_dma, sc->sc_dma_physaddr);
14095+}
14096+
14097+
14098+static int
14099+hifn_init_pubrng(struct hifn_softc *sc)
14100+{
14101+ int i;
14102+
14103+ DPRINTF("%s()\n", __FUNCTION__);
14104+
14105+ if ((sc->sc_flags & HIFN_IS_7811) == 0) {
14106+ /* Reset 7951 public key/rng engine */
14107+ WRITE_REG_1(sc, HIFN_1_PUB_RESET,
14108+ READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET);
14109+
14110+ for (i = 0; i < 100; i++) {
14111+ DELAY(1000);
14112+ if ((READ_REG_1(sc, HIFN_1_PUB_RESET) &
14113+ HIFN_PUBRST_RESET) == 0)
14114+ break;
14115+ }
14116+
14117+ if (i == 100) {
14118+ device_printf(sc->sc_dev, "public key init failed\n");
14119+ return (1);
14120+ }
14121+ }
14122+
14123+ /* Enable the rng, if available */
14124+#ifdef CONFIG_OCF_RANDOMHARVEST
14125+ if (sc->sc_flags & HIFN_HAS_RNG) {
14126+ if (sc->sc_flags & HIFN_IS_7811) {
14127+ u_int32_t r;
14128+ r = READ_REG_1(sc, HIFN_1_7811_RNGENA);
14129+ if (r & HIFN_7811_RNGENA_ENA) {
14130+ r &= ~HIFN_7811_RNGENA_ENA;
14131+ WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
14132+ }
14133+ WRITE_REG_1(sc, HIFN_1_7811_RNGCFG,
14134+ HIFN_7811_RNGCFG_DEFL);
14135+ r |= HIFN_7811_RNGENA_ENA;
14136+ WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
14137+ } else
14138+ WRITE_REG_1(sc, HIFN_1_RNG_CONFIG,
14139+ READ_REG_1(sc, HIFN_1_RNG_CONFIG) |
14140+ HIFN_RNGCFG_ENA);
14141+
14142+ sc->sc_rngfirst = 1;
14143+ crypto_rregister(sc->sc_cid, hifn_read_random, sc);
14144+ }
14145+#endif
14146+
14147+ /* Enable public key engine, if available */
14148+ if (sc->sc_flags & HIFN_HAS_PUBLIC) {
14149+ WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE);
14150+ sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;
14151+ WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
14152+#ifdef HIFN_VULCANDEV
14153+ sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0,
14154+ UID_ROOT, GID_WHEEL, 0666,
14155+ "vulcanpk");
14156+ sc->sc_pkdev->si_drv1 = sc;
14157+#endif
14158+ }
14159+
14160+ return (0);
14161+}
14162+
14163+#ifdef CONFIG_OCF_RANDOMHARVEST
14164+static int
14165+hifn_read_random(void *arg, u_int32_t *buf, int len)
14166+{
14167+ struct hifn_softc *sc = (struct hifn_softc *) arg;
14168+ u_int32_t sts;
14169+ int i, rc = 0;
14170+
14171+ if (len <= 0)
14172+ return rc;
14173+
14174+ if (sc->sc_flags & HIFN_IS_7811) {
14175+ /* ONLY VALID ON 7811!!!! */
14176+ for (i = 0; i < 5; i++) {
14177+ sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS);
14178+ if (sts & HIFN_7811_RNGSTS_UFL) {
14179+ device_printf(sc->sc_dev,
14180+ "RNG underflow: disabling\n");
14181+ /* DAVIDM perhaps return -1 */
14182+ break;
14183+ }
14184+ if ((sts & HIFN_7811_RNGSTS_RDY) == 0)
14185+ break;
14186+
14187+ /*
14188+ * There are at least two words in the RNG FIFO
14189+ * at this point.
14190+ */
14191+ if (rc < len)
14192+ buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
14193+ if (rc < len)
14194+ buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
14195+ }
14196+ } else
14197+ buf[rc++] = READ_REG_1(sc, HIFN_1_RNG_DATA);
14198+
14199+ /* NB: discard first data read */
14200+ if (sc->sc_rngfirst) {
14201+ sc->sc_rngfirst = 0;
14202+ rc = 0;
14203+ }
14204+
14205+ return(rc);
14206+}
14207+#endif /* CONFIG_OCF_RANDOMHARVEST */
14208+
14209+static void
14210+hifn_puc_wait(struct hifn_softc *sc)
14211+{
14212+ int i;
14213+ int reg = HIFN_0_PUCTRL;
14214+
14215+ if (sc->sc_flags & HIFN_IS_7956) {
14216+ reg = HIFN_0_PUCTRL2;
14217+ }
14218+
14219+ for (i = 5000; i > 0; i--) {
14220+ DELAY(1);
14221+ if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET))
14222+ break;
14223+ }
14224+ if (!i)
14225+ device_printf(sc->sc_dev, "proc unit did not reset(0x%x)\n",
14226+ READ_REG_0(sc, HIFN_0_PUCTRL));
14227+}
14228+
14229+/*
14230+ * Reset the processing unit.
14231+ */
14232+static void
14233+hifn_reset_puc(struct hifn_softc *sc)
14234+{
14235+ /* Reset processing unit */
14236+ int reg = HIFN_0_PUCTRL;
14237+
14238+ if (sc->sc_flags & HIFN_IS_7956) {
14239+ reg = HIFN_0_PUCTRL2;
14240+ }
14241+ WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA);
14242+
14243+ hifn_puc_wait(sc);
14244+}
14245+
14246+/*
14247+ * Set the Retry and TRDY registers; note that we set them to
14248+ * zero because the 7811 locks up when forced to retry (section
14249+ * 3.6 of "Specification Update SU-0014-04". Not clear if we
14250+ * should do this for all Hifn parts, but it doesn't seem to hurt.
14251+ */
14252+static void
14253+hifn_set_retry(struct hifn_softc *sc)
14254+{
14255+ DPRINTF("%s()\n", __FUNCTION__);
14256+ /* NB: RETRY only responds to 8-bit reads/writes */
14257+ pci_write_config_byte(sc->sc_pcidev, HIFN_RETRY_TIMEOUT, 0);
14258+ pci_write_config_dword(sc->sc_pcidev, HIFN_TRDY_TIMEOUT, 0);
14259+ /* piggy back the cache line setting here */
14260+ pci_write_config_byte(sc->sc_pcidev, PCI_CACHE_LINE_SIZE, hifn_cache_linesize);
14261+}
14262+
14263+/*
14264+ * Resets the board. Values in the regesters are left as is
14265+ * from the reset (i.e. initial values are assigned elsewhere).
14266+ */
14267+static void
14268+hifn_reset_board(struct hifn_softc *sc, int full)
14269+{
14270+ u_int32_t reg;
14271+
14272+ DPRINTF("%s()\n", __FUNCTION__);
14273+ /*
14274+ * Set polling in the DMA configuration register to zero. 0x7 avoids
14275+ * resetting the board and zeros out the other fields.
14276+ */
14277+ WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
14278+ HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
14279+
14280+ /*
14281+ * Now that polling has been disabled, we have to wait 1 ms
14282+ * before resetting the board.
14283+ */
14284+ DELAY(1000);
14285+
14286+ /* Reset the DMA unit */
14287+ if (full) {
14288+ WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MODE);
14289+ DELAY(1000);
14290+ } else {
14291+ WRITE_REG_1(sc, HIFN_1_DMA_CNFG,
14292+ HIFN_DMACNFG_MODE | HIFN_DMACNFG_MSTRESET);
14293+ hifn_reset_puc(sc);
14294+ }
14295+
14296+ KASSERT(sc->sc_dma != NULL, ("hifn_reset_board: null DMA tag!"));
14297+ bzero(sc->sc_dma, sizeof(*sc->sc_dma));
14298+
14299+ /* Bring dma unit out of reset */
14300+ WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
14301+ HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
14302+
14303+ hifn_puc_wait(sc);
14304+ hifn_set_retry(sc);
14305+
14306+ if (sc->sc_flags & HIFN_IS_7811) {
14307+ for (reg = 0; reg < 1000; reg++) {
14308+ if (READ_REG_1(sc, HIFN_1_7811_MIPSRST) &
14309+ HIFN_MIPSRST_CRAMINIT)
14310+ break;
14311+ DELAY(1000);
14312+ }
14313+ if (reg == 1000)
14314+ device_printf(sc->sc_dev, ": cram init timeout\n");
14315+ } else {
14316+ /* set up DMA configuration register #2 */
14317+ /* turn off all PK and BAR0 swaps */
14318+ WRITE_REG_1(sc, HIFN_1_DMA_CNFG2,
14319+ (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)|
14320+ (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)|
14321+ (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)|
14322+ (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT));
14323+ }
14324+}
14325+
14326+static u_int32_t
14327+hifn_next_signature(u_int32_t a, u_int cnt)
14328+{
14329+ int i;
14330+ u_int32_t v;
14331+
14332+ for (i = 0; i < cnt; i++) {
14333+
14334+ /* get the parity */
14335+ v = a & 0x80080125;
14336+ v ^= v >> 16;
14337+ v ^= v >> 8;
14338+ v ^= v >> 4;
14339+ v ^= v >> 2;
14340+ v ^= v >> 1;
14341+
14342+ a = (v & 1) ^ (a << 1);
14343+ }
14344+
14345+ return a;
14346+}
14347+
14348+
14349+/*
14350+ * Checks to see if crypto is already enabled. If crypto isn't enable,
14351+ * "hifn_enable_crypto" is called to enable it. The check is important,
14352+ * as enabling crypto twice will lock the board.
14353+ */
14354+static int
14355+hifn_enable_crypto(struct hifn_softc *sc)
14356+{
14357+ u_int32_t dmacfg, ramcfg, encl, addr, i;
14358+ char offtbl[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
14359+ 0x00, 0x00, 0x00, 0x00 };
14360+
14361+ DPRINTF("%s()\n", __FUNCTION__);
14362+
14363+ ramcfg = READ_REG_0(sc, HIFN_0_PUCNFG);
14364+ dmacfg = READ_REG_1(sc, HIFN_1_DMA_CNFG);
14365+
14366+ /*
14367+ * The RAM config register's encrypt level bit needs to be set before
14368+ * every read performed on the encryption level register.
14369+ */
14370+ WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
14371+
14372+ encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
14373+
14374+ /*
14375+ * Make sure we don't re-unlock. Two unlocks kills chip until the
14376+ * next reboot.
14377+ */
14378+ if (encl == HIFN_PUSTAT_ENA_1 || encl == HIFN_PUSTAT_ENA_2) {
14379+#ifdef HIFN_DEBUG
14380+ if (hifn_debug)
14381+ device_printf(sc->sc_dev,
14382+ "Strong crypto already enabled!\n");
14383+#endif
14384+ goto report;
14385+ }
14386+
14387+ if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) {
14388+#ifdef HIFN_DEBUG
14389+ if (hifn_debug)
14390+ device_printf(sc->sc_dev,
14391+ "Unknown encryption level 0x%x\n", encl);
14392+#endif
14393+ return 1;
14394+ }
14395+
14396+ WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_UNLOCK |
14397+ HIFN_DMACNFG_MSTRESET | HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
14398+ DELAY(1000);
14399+ addr = READ_REG_1(sc, HIFN_UNLOCK_SECRET1);
14400+ DELAY(1000);
14401+ WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, 0);
14402+ DELAY(1000);
14403+
14404+ for (i = 0; i <= 12; i++) {
14405+ addr = hifn_next_signature(addr, offtbl[i] + 0x101);
14406+ WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, addr);
14407+
14408+ DELAY(1000);
14409+ }
14410+
14411+ WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
14412+ encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
14413+
14414+#ifdef HIFN_DEBUG
14415+ if (hifn_debug) {
14416+ if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2)
14417+ device_printf(sc->sc_dev, "Engine is permanently "
14418+ "locked until next system reset!\n");
14419+ else
14420+ device_printf(sc->sc_dev, "Engine enabled "
14421+ "successfully!\n");
14422+ }
14423+#endif
14424+
14425+report:
14426+ WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg);
14427+ WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg);
14428+
14429+ switch (encl) {
14430+ case HIFN_PUSTAT_ENA_1:
14431+ case HIFN_PUSTAT_ENA_2:
14432+ break;
14433+ case HIFN_PUSTAT_ENA_0:
14434+ default:
14435+ device_printf(sc->sc_dev, "disabled\n");
14436+ break;
14437+ }
14438+
14439+ return 0;
14440+}
14441+
14442+/*
14443+ * Give initial values to the registers listed in the "Register Space"
14444+ * section of the HIFN Software Development reference manual.
14445+ */
14446+static void
14447+hifn_init_pci_registers(struct hifn_softc *sc)
14448+{
14449+ DPRINTF("%s()\n", __FUNCTION__);
14450+
14451+ /* write fixed values needed by the Initialization registers */
14452+ WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);
14453+ WRITE_REG_0(sc, HIFN_0_FIFOCNFG, HIFN_FIFOCNFG_THRESHOLD);
14454+ WRITE_REG_0(sc, HIFN_0_PUIER, HIFN_PUIER_DSTOVER);
14455+
14456+ /* write all 4 ring address registers */
14457+ WRITE_REG_1(sc, HIFN_1_DMA_CRAR, sc->sc_dma_physaddr +
14458+ offsetof(struct hifn_dma, cmdr[0]));
14459+ WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dma_physaddr +
14460+ offsetof(struct hifn_dma, srcr[0]));
14461+ WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dma_physaddr +
14462+ offsetof(struct hifn_dma, dstr[0]));
14463+ WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dma_physaddr +
14464+ offsetof(struct hifn_dma, resr[0]));
14465+
14466+ DELAY(2000);
14467+
14468+ /* write status register */
14469+ WRITE_REG_1(sc, HIFN_1_DMA_CSR,
14470+ HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS |
14471+ HIFN_DMACSR_S_CTRL_DIS | HIFN_DMACSR_C_CTRL_DIS |
14472+ HIFN_DMACSR_D_ABORT | HIFN_DMACSR_D_DONE | HIFN_DMACSR_D_LAST |
14473+ HIFN_DMACSR_D_WAIT | HIFN_DMACSR_D_OVER |
14474+ HIFN_DMACSR_R_ABORT | HIFN_DMACSR_R_DONE | HIFN_DMACSR_R_LAST |
14475+ HIFN_DMACSR_R_WAIT | HIFN_DMACSR_R_OVER |
14476+ HIFN_DMACSR_S_ABORT | HIFN_DMACSR_S_DONE | HIFN_DMACSR_S_LAST |
14477+ HIFN_DMACSR_S_WAIT |
14478+ HIFN_DMACSR_C_ABORT | HIFN_DMACSR_C_DONE | HIFN_DMACSR_C_LAST |
14479+ HIFN_DMACSR_C_WAIT |
14480+ HIFN_DMACSR_ENGINE |
14481+ ((sc->sc_flags & HIFN_HAS_PUBLIC) ?
14482+ HIFN_DMACSR_PUBDONE : 0) |
14483+ ((sc->sc_flags & HIFN_IS_7811) ?
14484+ HIFN_DMACSR_ILLW | HIFN_DMACSR_ILLR : 0));
14485+
14486+ sc->sc_d_busy = sc->sc_r_busy = sc->sc_s_busy = sc->sc_c_busy = 0;
14487+ sc->sc_dmaier |= HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_ABORT |
14488+ HIFN_DMAIER_D_OVER | HIFN_DMAIER_R_OVER |
14489+ HIFN_DMAIER_S_ABORT | HIFN_DMAIER_D_ABORT | HIFN_DMAIER_R_ABORT |
14490+ ((sc->sc_flags & HIFN_IS_7811) ?
14491+ HIFN_DMAIER_ILLW | HIFN_DMAIER_ILLR : 0);
14492+ sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
14493+ WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
14494+
14495+
14496+ if (sc->sc_flags & HIFN_IS_7956) {
14497+ u_int32_t pll;
14498+
14499+ WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
14500+ HIFN_PUCNFG_TCALLPHASES |
14501+ HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32);
14502+
14503+ /* turn off the clocks and insure bypass is set */
14504+ pll = READ_REG_1(sc, HIFN_1_PLL);
14505+ pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL))
14506+ | HIFN_PLL_BP | HIFN_PLL_MBSET;
14507+ WRITE_REG_1(sc, HIFN_1_PLL, pll);
14508+ DELAY(10*1000); /* 10ms */
14509+
14510+ /* change configuration */
14511+ pll = (pll &~ HIFN_PLL_CONFIG) | sc->sc_pllconfig;
14512+ WRITE_REG_1(sc, HIFN_1_PLL, pll);
14513+ DELAY(10*1000); /* 10ms */
14514+
14515+ /* disable bypass */
14516+ pll &= ~HIFN_PLL_BP;
14517+ WRITE_REG_1(sc, HIFN_1_PLL, pll);
14518+ /* enable clocks with new configuration */
14519+ pll |= HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL;
14520+ WRITE_REG_1(sc, HIFN_1_PLL, pll);
14521+ } else {
14522+ WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
14523+ HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES |
14524+ HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 |
14525+ (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM));
14526+ }
14527+
14528+ WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER);
14529+ WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
14530+ HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST |
14531+ ((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) |
14532+ ((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL));
14533+}
14534+
14535+/*
14536+ * The maximum number of sessions supported by the card
14537+ * is dependent on the amount of context ram, which
14538+ * encryption algorithms are enabled, and how compression
14539+ * is configured. This should be configured before this
14540+ * routine is called.
14541+ */
14542+static void
14543+hifn_sessions(struct hifn_softc *sc)
14544+{
14545+ u_int32_t pucnfg;
14546+ int ctxsize;
14547+
14548+ DPRINTF("%s()\n", __FUNCTION__);
14549+
14550+ pucnfg = READ_REG_0(sc, HIFN_0_PUCNFG);
14551+
14552+ if (pucnfg & HIFN_PUCNFG_COMPSING) {
14553+ if (pucnfg & HIFN_PUCNFG_ENCCNFG)
14554+ ctxsize = 128;
14555+ else
14556+ ctxsize = 512;
14557+ /*
14558+ * 7955/7956 has internal context memory of 32K
14559+ */
14560+ if (sc->sc_flags & HIFN_IS_7956)
14561+ sc->sc_maxses = 32768 / ctxsize;
14562+ else
14563+ sc->sc_maxses = 1 +
14564+ ((sc->sc_ramsize - 32768) / ctxsize);
14565+ } else
14566+ sc->sc_maxses = sc->sc_ramsize / 16384;
14567+
14568+ if (sc->sc_maxses > 2048)
14569+ sc->sc_maxses = 2048;
14570+}
14571+
14572+/*
14573+ * Determine ram type (sram or dram). Board should be just out of a reset
14574+ * state when this is called.
14575+ */
14576+static int
14577+hifn_ramtype(struct hifn_softc *sc)
14578+{
14579+ u_int8_t data[8], dataexpect[8];
14580+ int i;
14581+
14582+ for (i = 0; i < sizeof(data); i++)
14583+ data[i] = dataexpect[i] = 0x55;
14584+ if (hifn_writeramaddr(sc, 0, data))
14585+ return (-1);
14586+ if (hifn_readramaddr(sc, 0, data))
14587+ return (-1);
14588+ if (bcmp(data, dataexpect, sizeof(data)) != 0) {
14589+ sc->sc_drammodel = 1;
14590+ return (0);
14591+ }
14592+
14593+ for (i = 0; i < sizeof(data); i++)
14594+ data[i] = dataexpect[i] = 0xaa;
14595+ if (hifn_writeramaddr(sc, 0, data))
14596+ return (-1);
14597+ if (hifn_readramaddr(sc, 0, data))
14598+ return (-1);
14599+ if (bcmp(data, dataexpect, sizeof(data)) != 0) {
14600+ sc->sc_drammodel = 1;
14601+ return (0);
14602+ }
14603+
14604+ return (0);
14605+}
14606+
14607+#define HIFN_SRAM_MAX (32 << 20)
14608+#define HIFN_SRAM_STEP_SIZE 16384
14609+#define HIFN_SRAM_GRANULARITY (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)
14610+
14611+static int
14612+hifn_sramsize(struct hifn_softc *sc)
14613+{
14614+ u_int32_t a;
14615+ u_int8_t data[8];
14616+ u_int8_t dataexpect[sizeof(data)];
14617+ int32_t i;
14618+
14619+ for (i = 0; i < sizeof(data); i++)
14620+ data[i] = dataexpect[i] = i ^ 0x5a;
14621+
14622+ for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) {
14623+ a = i * HIFN_SRAM_STEP_SIZE;
14624+ bcopy(&i, data, sizeof(i));
14625+ hifn_writeramaddr(sc, a, data);
14626+ }
14627+
14628+ for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) {
14629+ a = i * HIFN_SRAM_STEP_SIZE;
14630+ bcopy(&i, dataexpect, sizeof(i));
14631+ if (hifn_readramaddr(sc, a, data) < 0)
14632+ return (0);
14633+ if (bcmp(data, dataexpect, sizeof(data)) != 0)
14634+ return (0);
14635+ sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE;
14636+ }
14637+
14638+ return (0);
14639+}
14640+
14641+/*
14642+ * XXX For dram boards, one should really try all of the
14643+ * HIFN_PUCNFG_DSZ_*'s. This just assumes that PUCNFG
14644+ * is already set up correctly.
14645+ */
14646+static int
14647+hifn_dramsize(struct hifn_softc *sc)
14648+{
14649+ u_int32_t cnfg;
14650+
14651+ if (sc->sc_flags & HIFN_IS_7956) {
14652+ /*
14653+ * 7955/7956 have a fixed internal ram of only 32K.
14654+ */
14655+ sc->sc_ramsize = 32768;
14656+ } else {
14657+ cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) &
14658+ HIFN_PUCNFG_DRAMMASK;
14659+ sc->sc_ramsize = 1 << ((cnfg >> 13) + 18);
14660+ }
14661+ return (0);
14662+}
14663+
14664+static void
14665+hifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, int *dstp, int *resp)
14666+{
14667+ struct hifn_dma *dma = sc->sc_dma;
14668+
14669+ DPRINTF("%s()\n", __FUNCTION__);
14670+
14671+ if (dma->cmdi == HIFN_D_CMD_RSIZE) {
14672+ dma->cmdi = 0;
14673+ dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
14674+ wmb();
14675+ dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
14676+ HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
14677+ BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
14678+ }
14679+ *cmdp = dma->cmdi++;
14680+ dma->cmdk = dma->cmdi;
14681+
14682+ if (dma->srci == HIFN_D_SRC_RSIZE) {
14683+ dma->srci = 0;
14684+ dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
14685+ wmb();
14686+ dma->srcr[HIFN_D_SRC_RSIZE].l |= htole32(HIFN_D_VALID);
14687+ HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
14688+ BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
14689+ }
14690+ *srcp = dma->srci++;
14691+ dma->srck = dma->srci;
14692+
14693+ if (dma->dsti == HIFN_D_DST_RSIZE) {
14694+ dma->dsti = 0;
14695+ dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
14696+ wmb();
14697+ dma->dstr[HIFN_D_DST_RSIZE].l |= htole32(HIFN_D_VALID);
14698+ HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE,
14699+ BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
14700+ }
14701+ *dstp = dma->dsti++;
14702+ dma->dstk = dma->dsti;
14703+
14704+ if (dma->resi == HIFN_D_RES_RSIZE) {
14705+ dma->resi = 0;
14706+ dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
14707+ wmb();
14708+ dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
14709+ HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
14710+ BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
14711+ }
14712+ *resp = dma->resi++;
14713+ dma->resk = dma->resi;
14714+}
14715+
14716+static int
14717+hifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
14718+{
14719+ struct hifn_dma *dma = sc->sc_dma;
14720+ hifn_base_command_t wc;
14721+ const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
14722+ int r, cmdi, resi, srci, dsti;
14723+
14724+ DPRINTF("%s()\n", __FUNCTION__);
14725+
14726+ wc.masks = htole16(3 << 13);
14727+ wc.session_num = htole16(addr >> 14);
14728+ wc.total_source_count = htole16(8);
14729+ wc.total_dest_count = htole16(addr & 0x3fff);
14730+
14731+ hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
14732+
14733+ WRITE_REG_1(sc, HIFN_1_DMA_CSR,
14734+ HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
14735+ HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
14736+
14737+ /* build write command */
14738+ bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
14739+ *(hifn_base_command_t *)dma->command_bufs[cmdi] = wc;
14740+ bcopy(data, &dma->test_src, sizeof(dma->test_src));
14741+
14742+ dma->srcr[srci].p = htole32(sc->sc_dma_physaddr
14743+ + offsetof(struct hifn_dma, test_src));
14744+ dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr
14745+ + offsetof(struct hifn_dma, test_dst));
14746+
14747+ dma->cmdr[cmdi].l = htole32(16 | masks);
14748+ dma->srcr[srci].l = htole32(8 | masks);
14749+ dma->dstr[dsti].l = htole32(4 | masks);
14750+ dma->resr[resi].l = htole32(4 | masks);
14751+
14752+ for (r = 10000; r >= 0; r--) {
14753+ DELAY(10);
14754+ if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
14755+ break;
14756+ }
14757+ if (r == 0) {
14758+ device_printf(sc->sc_dev, "writeramaddr -- "
14759+ "result[%d](addr %d) still valid\n", resi, addr);
14760+ r = -1;
14761+ return (-1);
14762+ } else
14763+ r = 0;
14764+
14765+ WRITE_REG_1(sc, HIFN_1_DMA_CSR,
14766+ HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
14767+ HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
14768+
14769+ return (r);
14770+}
14771+
14772+static int
14773+hifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
14774+{
14775+ struct hifn_dma *dma = sc->sc_dma;
14776+ hifn_base_command_t rc;
14777+ const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
14778+ int r, cmdi, srci, dsti, resi;
14779+
14780+ DPRINTF("%s()\n", __FUNCTION__);
14781+
14782+ rc.masks = htole16(2 << 13);
14783+ rc.session_num = htole16(addr >> 14);
14784+ rc.total_source_count = htole16(addr & 0x3fff);
14785+ rc.total_dest_count = htole16(8);
14786+
14787+ hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
14788+
14789+ WRITE_REG_1(sc, HIFN_1_DMA_CSR,
14790+ HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
14791+ HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
14792+
14793+ bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
14794+ *(hifn_base_command_t *)dma->command_bufs[cmdi] = rc;
14795+
14796+ dma->srcr[srci].p = htole32(sc->sc_dma_physaddr +
14797+ offsetof(struct hifn_dma, test_src));
14798+ dma->test_src = 0;
14799+ dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr +
14800+ offsetof(struct hifn_dma, test_dst));
14801+ dma->test_dst = 0;
14802+ dma->cmdr[cmdi].l = htole32(8 | masks);
14803+ dma->srcr[srci].l = htole32(8 | masks);
14804+ dma->dstr[dsti].l = htole32(8 | masks);
14805+ dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks);
14806+
14807+ for (r = 10000; r >= 0; r--) {
14808+ DELAY(10);
14809+ if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
14810+ break;
14811+ }
14812+ if (r == 0) {
14813+ device_printf(sc->sc_dev, "readramaddr -- "
14814+ "result[%d](addr %d) still valid\n", resi, addr);
14815+ r = -1;
14816+ } else {
14817+ r = 0;
14818+ bcopy(&dma->test_dst, data, sizeof(dma->test_dst));
14819+ }
14820+
14821+ WRITE_REG_1(sc, HIFN_1_DMA_CSR,
14822+ HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
14823+ HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
14824+
14825+ return (r);
14826+}
14827+
14828+/*
14829+ * Initialize the descriptor rings.
14830+ */
14831+static void
14832+hifn_init_dma(struct hifn_softc *sc)
14833+{
14834+ struct hifn_dma *dma = sc->sc_dma;
14835+ int i;
14836+
14837+ DPRINTF("%s()\n", __FUNCTION__);
14838+
14839+ hifn_set_retry(sc);
14840+
14841+ /* initialize static pointer values */
14842+ for (i = 0; i < HIFN_D_CMD_RSIZE; i++)
14843+ dma->cmdr[i].p = htole32(sc->sc_dma_physaddr +
14844+ offsetof(struct hifn_dma, command_bufs[i][0]));
14845+ for (i = 0; i < HIFN_D_RES_RSIZE; i++)
14846+ dma->resr[i].p = htole32(sc->sc_dma_physaddr +
14847+ offsetof(struct hifn_dma, result_bufs[i][0]));
14848+
14849+ dma->cmdr[HIFN_D_CMD_RSIZE].p =
14850+ htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, cmdr[0]));
14851+ dma->srcr[HIFN_D_SRC_RSIZE].p =
14852+ htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, srcr[0]));
14853+ dma->dstr[HIFN_D_DST_RSIZE].p =
14854+ htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, dstr[0]));
14855+ dma->resr[HIFN_D_RES_RSIZE].p =
14856+ htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, resr[0]));
14857+
14858+ dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0;
14859+ dma->cmdi = dma->srci = dma->dsti = dma->resi = 0;
14860+ dma->cmdk = dma->srck = dma->dstk = dma->resk = 0;
14861+}
14862+
14863+/*
14864+ * Writes out the raw command buffer space. Returns the
14865+ * command buffer size.
14866+ */
14867+static u_int
14868+hifn_write_command(struct hifn_command *cmd, u_int8_t *buf)
14869+{
14870+ struct hifn_softc *sc = NULL;
14871+ u_int8_t *buf_pos;
14872+ hifn_base_command_t *base_cmd;
14873+ hifn_mac_command_t *mac_cmd;
14874+ hifn_crypt_command_t *cry_cmd;
14875+ int using_mac, using_crypt, len, ivlen;
14876+ u_int32_t dlen, slen;
14877+
14878+ DPRINTF("%s()\n", __FUNCTION__);
14879+
14880+ buf_pos = buf;
14881+ using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC;
14882+ using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT;
14883+
14884+ base_cmd = (hifn_base_command_t *)buf_pos;
14885+ base_cmd->masks = htole16(cmd->base_masks);
14886+ slen = cmd->src_mapsize;
14887+ if (cmd->sloplen)
14888+ dlen = cmd->dst_mapsize - cmd->sloplen + sizeof(u_int32_t);
14889+ else
14890+ dlen = cmd->dst_mapsize;
14891+ base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO);
14892+ base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);
14893+ dlen >>= 16;
14894+ slen >>= 16;
14895+ base_cmd->session_num = htole16(
14896+ ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |
14897+ ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));
14898+ buf_pos += sizeof(hifn_base_command_t);
14899+
14900+ if (using_mac) {
14901+ mac_cmd = (hifn_mac_command_t *)buf_pos;
14902+ dlen = cmd->maccrd->crd_len;
14903+ mac_cmd->source_count = htole16(dlen & 0xffff);
14904+ dlen >>= 16;
14905+ mac_cmd->masks = htole16(cmd->mac_masks |
14906+ ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M));
14907+ mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip);
14908+ mac_cmd->reserved = 0;
14909+ buf_pos += sizeof(hifn_mac_command_t);
14910+ }
14911+
14912+ if (using_crypt) {
14913+ cry_cmd = (hifn_crypt_command_t *)buf_pos;
14914+ dlen = cmd->enccrd->crd_len;
14915+ cry_cmd->source_count = htole16(dlen & 0xffff);
14916+ dlen >>= 16;
14917+ cry_cmd->masks = htole16(cmd->cry_masks |
14918+ ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M));
14919+ cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip);
14920+ cry_cmd->reserved = 0;
14921+ buf_pos += sizeof(hifn_crypt_command_t);
14922+ }
14923+
14924+ if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) {
14925+ bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH);
14926+ buf_pos += HIFN_MAC_KEY_LENGTH;
14927+ }
14928+
14929+ if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) {
14930+ switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
14931+ case HIFN_CRYPT_CMD_ALG_3DES:
14932+ bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH);
14933+ buf_pos += HIFN_3DES_KEY_LENGTH;
14934+ break;
14935+ case HIFN_CRYPT_CMD_ALG_DES:
14936+ bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH);
14937+ buf_pos += HIFN_DES_KEY_LENGTH;
14938+ break;
14939+ case HIFN_CRYPT_CMD_ALG_RC4:
14940+ len = 256;
14941+ do {
14942+ int clen;
14943+
14944+ clen = MIN(cmd->cklen, len);
14945+ bcopy(cmd->ck, buf_pos, clen);
14946+ len -= clen;
14947+ buf_pos += clen;
14948+ } while (len > 0);
14949+ bzero(buf_pos, 4);
14950+ buf_pos += 4;
14951+ break;
14952+ case HIFN_CRYPT_CMD_ALG_AES:
14953+ /*
14954+ * AES keys are variable 128, 192 and
14955+ * 256 bits (16, 24 and 32 bytes).
14956+ */
14957+ bcopy(cmd->ck, buf_pos, cmd->cklen);
14958+ buf_pos += cmd->cklen;
14959+ break;
14960+ }
14961+ }
14962+
14963+ if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) {
14964+ switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
14965+ case HIFN_CRYPT_CMD_ALG_AES:
14966+ ivlen = HIFN_AES_IV_LENGTH;
14967+ break;
14968+ default:
14969+ ivlen = HIFN_IV_LENGTH;
14970+ break;
14971+ }
14972+ bcopy(cmd->iv, buf_pos, ivlen);
14973+ buf_pos += ivlen;
14974+ }
14975+
14976+ if ((cmd->base_masks & (HIFN_BASE_CMD_MAC|HIFN_BASE_CMD_CRYPT)) == 0) {
14977+ bzero(buf_pos, 8);
14978+ buf_pos += 8;
14979+ }
14980+
14981+ return (buf_pos - buf);
14982+}
14983+
14984+static int
14985+hifn_dmamap_aligned(struct hifn_operand *op)
14986+{
14987+ struct hifn_softc *sc = NULL;
14988+ int i;
14989+
14990+ DPRINTF("%s()\n", __FUNCTION__);
14991+
14992+ for (i = 0; i < op->nsegs; i++) {
14993+ if (op->segs[i].ds_addr & 3)
14994+ return (0);
14995+ if ((i != (op->nsegs - 1)) && (op->segs[i].ds_len & 3))
14996+ return (0);
14997+ }
14998+ return (1);
14999+}
15000+
15001+static __inline int
15002+hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx)
15003+{
15004+ struct hifn_dma *dma = sc->sc_dma;
15005+
15006+ if (++idx == HIFN_D_DST_RSIZE) {
15007+ dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
15008+ HIFN_D_MASKDONEIRQ);
15009+ HIFN_DSTR_SYNC(sc, idx,
15010+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
15011+ idx = 0;
15012+ }
15013+ return (idx);
15014+}
15015+
15016+static int
15017+hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
15018+{
15019+ struct hifn_dma *dma = sc->sc_dma;
15020+ struct hifn_operand *dst = &cmd->dst;
15021+ u_int32_t p, l;
15022+ int idx, used = 0, i;
15023+
15024+ DPRINTF("%s()\n", __FUNCTION__);
15025+
15026+ idx = dma->dsti;
15027+ for (i = 0; i < dst->nsegs - 1; i++) {
15028+ dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
15029+ dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ | dst->segs[i].ds_len);
15030+ wmb();
15031+ dma->dstr[idx].l |= htole32(HIFN_D_VALID);
15032+ HIFN_DSTR_SYNC(sc, idx,
15033+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
15034+ used++;
15035+
15036+ idx = hifn_dmamap_dstwrap(sc, idx);
15037+ }
15038+
15039+ if (cmd->sloplen == 0) {
15040+ p = dst->segs[i].ds_addr;
15041+ l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
15042+ dst->segs[i].ds_len;
15043+ } else {
15044+ p = sc->sc_dma_physaddr +
15045+ offsetof(struct hifn_dma, slop[cmd->slopidx]);
15046+ l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
15047+ sizeof(u_int32_t);
15048+
15049+ if ((dst->segs[i].ds_len - cmd->sloplen) != 0) {
15050+ dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
15051+ dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ |
15052+ (dst->segs[i].ds_len - cmd->sloplen));
15053+ wmb();
15054+ dma->dstr[idx].l |= htole32(HIFN_D_VALID);
15055+ HIFN_DSTR_SYNC(sc, idx,
15056+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
15057+ used++;
15058+
15059+ idx = hifn_dmamap_dstwrap(sc, idx);
15060+ }
15061+ }
15062+ dma->dstr[idx].p = htole32(p);
15063+ dma->dstr[idx].l = htole32(l);
15064+ wmb();
15065+ dma->dstr[idx].l |= htole32(HIFN_D_VALID);
15066+ HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
15067+ used++;
15068+
15069+ idx = hifn_dmamap_dstwrap(sc, idx);
15070+
15071+ dma->dsti = idx;
15072+ dma->dstu += used;
15073+ return (idx);
15074+}
15075+
15076+static __inline int
15077+hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx)
15078+{
15079+ struct hifn_dma *dma = sc->sc_dma;
15080+
15081+ if (++idx == HIFN_D_SRC_RSIZE) {
15082+ dma->srcr[idx].l = htole32(HIFN_D_VALID |
15083+ HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
15084+ HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
15085+ BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
15086+ idx = 0;
15087+ }
15088+ return (idx);
15089+}
15090+
15091+static int
15092+hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)
15093+{
15094+ struct hifn_dma *dma = sc->sc_dma;
15095+ struct hifn_operand *src = &cmd->src;
15096+ int idx, i;
15097+ u_int32_t last = 0;
15098+
15099+ DPRINTF("%s()\n", __FUNCTION__);
15100+
15101+ idx = dma->srci;
15102+ for (i = 0; i < src->nsegs; i++) {
15103+ if (i == src->nsegs - 1)
15104+ last = HIFN_D_LAST;
15105+
15106+ dma->srcr[idx].p = htole32(src->segs[i].ds_addr);
15107+ dma->srcr[idx].l = htole32(src->segs[i].ds_len |
15108+ HIFN_D_MASKDONEIRQ | last);
15109+ wmb();
15110+ dma->srcr[idx].l |= htole32(HIFN_D_VALID);
15111+ HIFN_SRCR_SYNC(sc, idx,
15112+ BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
15113+
15114+ idx = hifn_dmamap_srcwrap(sc, idx);
15115+ }
15116+ dma->srci = idx;
15117+ dma->srcu += src->nsegs;
15118+ return (idx);
15119+}
15120+
15121+
15122+static int
15123+hifn_crypto(
15124+ struct hifn_softc *sc,
15125+ struct hifn_command *cmd,
15126+ struct cryptop *crp,
15127+ int hint)
15128+{
15129+ struct hifn_dma *dma = sc->sc_dma;
15130+ u_int32_t cmdlen, csr;
15131+ int cmdi, resi, err = 0;
15132+ unsigned long l_flags;
15133+
15134+ DPRINTF("%s()\n", __FUNCTION__);
15135+
15136+ /*
15137+ * need 1 cmd, and 1 res
15138+ *
15139+ * NB: check this first since it's easy.
15140+ */
15141+ HIFN_LOCK(sc);
15142+ if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE ||
15143+ (dma->resu + 1) > HIFN_D_RES_RSIZE) {
15144+#ifdef HIFN_DEBUG
15145+ if (hifn_debug) {
15146+ device_printf(sc->sc_dev,
15147+ "cmd/result exhaustion, cmdu %u resu %u\n",
15148+ dma->cmdu, dma->resu);
15149+ }
15150+#endif
15151+ hifnstats.hst_nomem_cr++;
15152+ sc->sc_needwakeup |= CRYPTO_SYMQ;
15153+ HIFN_UNLOCK(sc);
15154+ return (ERESTART);
15155+ }
15156+
15157+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
15158+ if (pci_map_skb(sc, &cmd->src, cmd->src_skb)) {
15159+ hifnstats.hst_nomem_load++;
15160+ err = ENOMEM;
15161+ goto err_srcmap1;
15162+ }
15163+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
15164+ if (pci_map_uio(sc, &cmd->src, cmd->src_io)) {
15165+ hifnstats.hst_nomem_load++;
15166+ err = ENOMEM;
15167+ goto err_srcmap1;
15168+ }
15169+ } else {
15170+ if (pci_map_buf(sc, &cmd->src, cmd->src_buf, crp->crp_ilen)) {
15171+ hifnstats.hst_nomem_load++;
15172+ err = ENOMEM;
15173+ goto err_srcmap1;
15174+ }
15175+ }
15176+
15177+ if (hifn_dmamap_aligned(&cmd->src)) {
15178+ cmd->sloplen = cmd->src_mapsize & 3;
15179+ cmd->dst = cmd->src;
15180+ } else {
15181+ if (crp->crp_flags & CRYPTO_F_IOV) {
15182+ DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
15183+ err = EINVAL;
15184+ goto err_srcmap;
15185+ } else if (crp->crp_flags & CRYPTO_F_SKBUF) {
15186+#ifdef NOTYET
15187+ int totlen, len;
15188+ struct mbuf *m, *m0, *mlast;
15189+
15190+ KASSERT(cmd->dst_m == cmd->src_m,
15191+ ("hifn_crypto: dst_m initialized improperly"));
15192+ hifnstats.hst_unaligned++;
15193+ /*
15194+ * Source is not aligned on a longword boundary.
15195+ * Copy the data to insure alignment. If we fail
15196+ * to allocate mbufs or clusters while doing this
15197+ * we return ERESTART so the operation is requeued
15198+ * at the crypto later, but only if there are
15199+ * ops already posted to the hardware; otherwise we
15200+ * have no guarantee that we'll be re-entered.
15201+ */
15202+ totlen = cmd->src_mapsize;
15203+ if (cmd->src_m->m_flags & M_PKTHDR) {
15204+ len = MHLEN;
15205+ MGETHDR(m0, M_DONTWAIT, MT_DATA);
15206+ if (m0 && !m_dup_pkthdr(m0, cmd->src_m, M_DONTWAIT)) {
15207+ m_free(m0);
15208+ m0 = NULL;
15209+ }
15210+ } else {
15211+ len = MLEN;
15212+ MGET(m0, M_DONTWAIT, MT_DATA);
15213+ }
15214+ if (m0 == NULL) {
15215+ hifnstats.hst_nomem_mbuf++;
15216+ err = dma->cmdu ? ERESTART : ENOMEM;
15217+ goto err_srcmap;
15218+ }
15219+ if (totlen >= MINCLSIZE) {
15220+ MCLGET(m0, M_DONTWAIT);
15221+ if ((m0->m_flags & M_EXT) == 0) {
15222+ hifnstats.hst_nomem_mcl++;
15223+ err = dma->cmdu ? ERESTART : ENOMEM;
15224+ m_freem(m0);
15225+ goto err_srcmap;
15226+ }
15227+ len = MCLBYTES;
15228+ }
15229+ totlen -= len;
15230+ m0->m_pkthdr.len = m0->m_len = len;
15231+ mlast = m0;
15232+
15233+ while (totlen > 0) {
15234+ MGET(m, M_DONTWAIT, MT_DATA);
15235+ if (m == NULL) {
15236+ hifnstats.hst_nomem_mbuf++;
15237+ err = dma->cmdu ? ERESTART : ENOMEM;
15238+ m_freem(m0);
15239+ goto err_srcmap;
15240+ }
15241+ len = MLEN;
15242+ if (totlen >= MINCLSIZE) {
15243+ MCLGET(m, M_DONTWAIT);
15244+ if ((m->m_flags & M_EXT) == 0) {
15245+ hifnstats.hst_nomem_mcl++;
15246+ err = dma->cmdu ? ERESTART : ENOMEM;
15247+ mlast->m_next = m;
15248+ m_freem(m0);
15249+ goto err_srcmap;
15250+ }
15251+ len = MCLBYTES;
15252+ }
15253+
15254+ m->m_len = len;
15255+ m0->m_pkthdr.len += len;
15256+ totlen -= len;
15257+
15258+ mlast->m_next = m;
15259+ mlast = m;
15260+ }
15261+ cmd->dst_m = m0;
15262+#else
15263+ device_printf(sc->sc_dev,
15264+ "%s,%d: CRYPTO_F_SKBUF unaligned not implemented\n",
15265+ __FILE__, __LINE__);
15266+ err = EINVAL;
15267+ goto err_srcmap;
15268+#endif
15269+ } else {
15270+ device_printf(sc->sc_dev,
15271+ "%s,%d: unaligned contig buffers not implemented\n",
15272+ __FILE__, __LINE__);
15273+ err = EINVAL;
15274+ goto err_srcmap;
15275+ }
15276+ }
15277+
15278+ if (cmd->dst_map == NULL) {
15279+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
15280+ if (pci_map_skb(sc, &cmd->dst, cmd->dst_skb)) {
15281+ hifnstats.hst_nomem_map++;
15282+ err = ENOMEM;
15283+ goto err_dstmap1;
15284+ }
15285+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
15286+ if (pci_map_uio(sc, &cmd->dst, cmd->dst_io)) {
15287+ hifnstats.hst_nomem_load++;
15288+ err = ENOMEM;
15289+ goto err_dstmap1;
15290+ }
15291+ } else {
15292+ if (pci_map_buf(sc, &cmd->dst, cmd->dst_buf, crp->crp_ilen)) {
15293+ hifnstats.hst_nomem_load++;
15294+ err = ENOMEM;
15295+ goto err_dstmap1;
15296+ }
15297+ }
15298+ }
15299+
15300+#ifdef HIFN_DEBUG
15301+ if (hifn_debug) {
15302+ device_printf(sc->sc_dev,
15303+ "Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",
15304+ READ_REG_1(sc, HIFN_1_DMA_CSR),
15305+ READ_REG_1(sc, HIFN_1_DMA_IER),
15306+ dma->cmdu, dma->srcu, dma->dstu, dma->resu,
15307+ cmd->src_nsegs, cmd->dst_nsegs);
15308+ }
15309+#endif
15310+
15311+#if 0
15312+ if (cmd->src_map == cmd->dst_map) {
15313+ bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
15314+ BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
15315+ } else {
15316+ bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
15317+ BUS_DMASYNC_PREWRITE);
15318+ bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
15319+ BUS_DMASYNC_PREREAD);
15320+ }
15321+#endif
15322+
15323+ /*
15324+ * need N src, and N dst
15325+ */
15326+ if ((dma->srcu + cmd->src_nsegs) > HIFN_D_SRC_RSIZE ||
15327+ (dma->dstu + cmd->dst_nsegs + 1) > HIFN_D_DST_RSIZE) {
15328+#ifdef HIFN_DEBUG
15329+ if (hifn_debug) {
15330+ device_printf(sc->sc_dev,
15331+ "src/dst exhaustion, srcu %u+%u dstu %u+%u\n",
15332+ dma->srcu, cmd->src_nsegs,
15333+ dma->dstu, cmd->dst_nsegs);
15334+ }
15335+#endif
15336+ hifnstats.hst_nomem_sd++;
15337+ err = ERESTART;
15338+ goto err_dstmap;
15339+ }
15340+
15341+ if (dma->cmdi == HIFN_D_CMD_RSIZE) {
15342+ dma->cmdi = 0;
15343+ dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
15344+ wmb();
15345+ dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
15346+ HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
15347+ BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
15348+ }
15349+ cmdi = dma->cmdi++;
15350+ cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]);
15351+ HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE);
15352+
15353+ /* .p for command/result already set */
15354+ dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_LAST |
15355+ HIFN_D_MASKDONEIRQ);
15356+ wmb();
15357+ dma->cmdr[cmdi].l |= htole32(HIFN_D_VALID);
15358+ HIFN_CMDR_SYNC(sc, cmdi,
15359+ BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
15360+ dma->cmdu++;
15361+
15362+ /*
15363+ * We don't worry about missing an interrupt (which a "command wait"
15364+ * interrupt salvages us from), unless there is more than one command
15365+ * in the queue.
15366+ */
15367+ if (dma->cmdu > 1) {
15368+ sc->sc_dmaier |= HIFN_DMAIER_C_WAIT;
15369+ WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
15370+ }
15371+
15372+ hifnstats.hst_ipackets++;
15373+ hifnstats.hst_ibytes += cmd->src_mapsize;
15374+
15375+ hifn_dmamap_load_src(sc, cmd);
15376+
15377+ /*
15378+ * Unlike other descriptors, we don't mask done interrupt from
15379+ * result descriptor.
15380+ */
15381+#ifdef HIFN_DEBUG
15382+ if (hifn_debug)
15383+ device_printf(sc->sc_dev, "load res\n");
15384+#endif
15385+ if (dma->resi == HIFN_D_RES_RSIZE) {
15386+ dma->resi = 0;
15387+ dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
15388+ wmb();
15389+ dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
15390+ HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
15391+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
15392+ }
15393+ resi = dma->resi++;
15394+ KASSERT(dma->hifn_commands[resi] == NULL,
15395+ ("hifn_crypto: command slot %u busy", resi));
15396+ dma->hifn_commands[resi] = cmd;
15397+ HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD);
15398+ if ((hint & CRYPTO_HINT_MORE) && sc->sc_curbatch < hifn_maxbatch) {
15399+ dma->resr[resi].l = htole32(HIFN_MAX_RESULT |
15400+ HIFN_D_LAST | HIFN_D_MASKDONEIRQ);
15401+ wmb();
15402+ dma->resr[resi].l |= htole32(HIFN_D_VALID);
15403+ sc->sc_curbatch++;
15404+ if (sc->sc_curbatch > hifnstats.hst_maxbatch)
15405+ hifnstats.hst_maxbatch = sc->sc_curbatch;
15406+ hifnstats.hst_totbatch++;
15407+ } else {
15408+ dma->resr[resi].l = htole32(HIFN_MAX_RESULT | HIFN_D_LAST);
15409+ wmb();
15410+ dma->resr[resi].l |= htole32(HIFN_D_VALID);
15411+ sc->sc_curbatch = 0;
15412+ }
15413+ HIFN_RESR_SYNC(sc, resi,
15414+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
15415+ dma->resu++;
15416+
15417+ if (cmd->sloplen)
15418+ cmd->slopidx = resi;
15419+
15420+ hifn_dmamap_load_dst(sc, cmd);
15421+
15422+ csr = 0;
15423+ if (sc->sc_c_busy == 0) {
15424+ csr |= HIFN_DMACSR_C_CTRL_ENA;
15425+ sc->sc_c_busy = 1;
15426+ }
15427+ if (sc->sc_s_busy == 0) {
15428+ csr |= HIFN_DMACSR_S_CTRL_ENA;
15429+ sc->sc_s_busy = 1;
15430+ }
15431+ if (sc->sc_r_busy == 0) {
15432+ csr |= HIFN_DMACSR_R_CTRL_ENA;
15433+ sc->sc_r_busy = 1;
15434+ }
15435+ if (sc->sc_d_busy == 0) {
15436+ csr |= HIFN_DMACSR_D_CTRL_ENA;
15437+ sc->sc_d_busy = 1;
15438+ }
15439+ if (csr)
15440+ WRITE_REG_1(sc, HIFN_1_DMA_CSR, csr);
15441+
15442+#ifdef HIFN_DEBUG
15443+ if (hifn_debug) {
15444+ device_printf(sc->sc_dev, "command: stat %8x ier %8x\n",
15445+ READ_REG_1(sc, HIFN_1_DMA_CSR),
15446+ READ_REG_1(sc, HIFN_1_DMA_IER));
15447+ }
15448+#endif
15449+
15450+ sc->sc_active = 5;
15451+ HIFN_UNLOCK(sc);
15452+ KASSERT(err == 0, ("hifn_crypto: success with error %u", err));
15453+ return (err); /* success */
15454+
15455+err_dstmap:
15456+ if (cmd->src_map != cmd->dst_map)
15457+ pci_unmap_buf(sc, &cmd->dst);
15458+err_dstmap1:
15459+err_srcmap:
15460+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
15461+ if (cmd->src_skb != cmd->dst_skb)
15462+#ifdef NOTYET
15463+ m_freem(cmd->dst_m);
15464+#else
15465+ device_printf(sc->sc_dev,
15466+ "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
15467+ __FILE__, __LINE__);
15468+#endif
15469+ }
15470+ pci_unmap_buf(sc, &cmd->src);
15471+err_srcmap1:
15472+ HIFN_UNLOCK(sc);
15473+ return (err);
15474+}
15475+
15476+static void
15477+hifn_tick(unsigned long arg)
15478+{
15479+ struct hifn_softc *sc;
15480+ unsigned long l_flags;
15481+
15482+ if (arg >= HIFN_MAX_CHIPS)
15483+ return;
15484+ sc = hifn_chip_idx[arg];
15485+ if (!sc)
15486+ return;
15487+
15488+ HIFN_LOCK(sc);
15489+ if (sc->sc_active == 0) {
15490+ struct hifn_dma *dma = sc->sc_dma;
15491+ u_int32_t r = 0;
15492+
15493+ if (dma->cmdu == 0 && sc->sc_c_busy) {
15494+ sc->sc_c_busy = 0;
15495+ r |= HIFN_DMACSR_C_CTRL_DIS;
15496+ }
15497+ if (dma->srcu == 0 && sc->sc_s_busy) {
15498+ sc->sc_s_busy = 0;
15499+ r |= HIFN_DMACSR_S_CTRL_DIS;
15500+ }
15501+ if (dma->dstu == 0 && sc->sc_d_busy) {
15502+ sc->sc_d_busy = 0;
15503+ r |= HIFN_DMACSR_D_CTRL_DIS;
15504+ }
15505+ if (dma->resu == 0 && sc->sc_r_busy) {
15506+ sc->sc_r_busy = 0;
15507+ r |= HIFN_DMACSR_R_CTRL_DIS;
15508+ }
15509+ if (r)
15510+ WRITE_REG_1(sc, HIFN_1_DMA_CSR, r);
15511+ } else
15512+ sc->sc_active--;
15513+ HIFN_UNLOCK(sc);
15514+ mod_timer(&sc->sc_tickto, jiffies + HZ);
15515+}
15516+
15517+static irqreturn_t
15518+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
15519+hifn_intr(int irq, void *arg)
15520+#else
15521+hifn_intr(int irq, void *arg, struct pt_regs *regs)
15522+#endif
15523+{
15524+ struct hifn_softc *sc = arg;
15525+ struct hifn_dma *dma;
15526+ u_int32_t dmacsr, restart;
15527+ int i, u;
15528+ unsigned long l_flags;
15529+
15530+ dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);
15531+
15532+ /* Nothing in the DMA unit interrupted */
15533+ if ((dmacsr & sc->sc_dmaier) == 0)
15534+ return IRQ_NONE;
15535+
15536+ HIFN_LOCK(sc);
15537+
15538+ dma = sc->sc_dma;
15539+
15540+#ifdef HIFN_DEBUG
15541+ if (hifn_debug) {
15542+ device_printf(sc->sc_dev,
15543+ "irq: stat %08x ien %08x damier %08x i %d/%d/%d/%d k %d/%d/%d/%d u %d/%d/%d/%d\n",
15544+ dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER), sc->sc_dmaier,
15545+ dma->cmdi, dma->srci, dma->dsti, dma->resi,
15546+ dma->cmdk, dma->srck, dma->dstk, dma->resk,
15547+ dma->cmdu, dma->srcu, dma->dstu, dma->resu);
15548+ }
15549+#endif
15550+
15551+ WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier);
15552+
15553+ if ((sc->sc_flags & HIFN_HAS_PUBLIC) &&
15554+ (dmacsr & HIFN_DMACSR_PUBDONE))
15555+ WRITE_REG_1(sc, HIFN_1_PUB_STATUS,
15556+ READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE);
15557+
15558+ restart = dmacsr & (HIFN_DMACSR_D_OVER | HIFN_DMACSR_R_OVER);
15559+ if (restart)
15560+ device_printf(sc->sc_dev, "overrun %x\n", dmacsr);
15561+
15562+ if (sc->sc_flags & HIFN_IS_7811) {
15563+ if (dmacsr & HIFN_DMACSR_ILLR)
15564+ device_printf(sc->sc_dev, "illegal read\n");
15565+ if (dmacsr & HIFN_DMACSR_ILLW)
15566+ device_printf(sc->sc_dev, "illegal write\n");
15567+ }
15568+
15569+ restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT |
15570+ HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT);
15571+ if (restart) {
15572+ device_printf(sc->sc_dev, "abort, resetting.\n");
15573+ hifnstats.hst_abort++;
15574+ hifn_abort(sc);
15575+ HIFN_UNLOCK(sc);
15576+ return IRQ_HANDLED;
15577+ }
15578+
15579+ if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->cmdu == 0)) {
15580+ /*
15581+ * If no slots to process and we receive a "waiting on
15582+ * command" interrupt, we disable the "waiting on command"
15583+ * (by clearing it).
15584+ */
15585+ sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
15586+ WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
15587+ }
15588+
15589+ /* clear the rings */
15590+ i = dma->resk; u = dma->resu;
15591+ while (u != 0) {
15592+ HIFN_RESR_SYNC(sc, i,
15593+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
15594+ if (dma->resr[i].l & htole32(HIFN_D_VALID)) {
15595+ HIFN_RESR_SYNC(sc, i,
15596+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
15597+ break;
15598+ }
15599+
15600+ if (i != HIFN_D_RES_RSIZE) {
15601+ struct hifn_command *cmd;
15602+ u_int8_t *macbuf = NULL;
15603+
15604+ HIFN_RES_SYNC(sc, i, BUS_DMASYNC_POSTREAD);
15605+ cmd = dma->hifn_commands[i];
15606+ KASSERT(cmd != NULL,
15607+ ("hifn_intr: null command slot %u", i));
15608+ dma->hifn_commands[i] = NULL;
15609+
15610+ if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
15611+ macbuf = dma->result_bufs[i];
15612+ macbuf += 12;
15613+ }
15614+
15615+ hifn_callback(sc, cmd, macbuf);
15616+ hifnstats.hst_opackets++;
15617+ u--;
15618+ }
15619+
15620+ if (++i == (HIFN_D_RES_RSIZE + 1))
15621+ i = 0;
15622+ }
15623+ dma->resk = i; dma->resu = u;
15624+
15625+ i = dma->srck; u = dma->srcu;
15626+ while (u != 0) {
15627+ if (i == HIFN_D_SRC_RSIZE)
15628+ i = 0;
15629+ HIFN_SRCR_SYNC(sc, i,
15630+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
15631+ if (dma->srcr[i].l & htole32(HIFN_D_VALID)) {
15632+ HIFN_SRCR_SYNC(sc, i,
15633+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
15634+ break;
15635+ }
15636+ i++, u--;
15637+ }
15638+ dma->srck = i; dma->srcu = u;
15639+
15640+ i = dma->cmdk; u = dma->cmdu;
15641+ while (u != 0) {
15642+ HIFN_CMDR_SYNC(sc, i,
15643+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
15644+ if (dma->cmdr[i].l & htole32(HIFN_D_VALID)) {
15645+ HIFN_CMDR_SYNC(sc, i,
15646+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
15647+ break;
15648+ }
15649+ if (i != HIFN_D_CMD_RSIZE) {
15650+ u--;
15651+ HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE);
15652+ }
15653+ if (++i == (HIFN_D_CMD_RSIZE + 1))
15654+ i = 0;
15655+ }
15656+ dma->cmdk = i; dma->cmdu = u;
15657+
15658+ HIFN_UNLOCK(sc);
15659+
15660+ if (sc->sc_needwakeup) { /* XXX check high watermark */
15661+ int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
15662+#ifdef HIFN_DEBUG
15663+ if (hifn_debug)
15664+ device_printf(sc->sc_dev,
15665+ "wakeup crypto (%x) u %d/%d/%d/%d\n",
15666+ sc->sc_needwakeup,
15667+ dma->cmdu, dma->srcu, dma->dstu, dma->resu);
15668+#endif
15669+ sc->sc_needwakeup &= ~wakeup;
15670+ crypto_unblock(sc->sc_cid, wakeup);
15671+ }
15672+
15673+ return IRQ_HANDLED;
15674+}
15675+
15676+/*
15677+ * Allocate a new 'session' and return an encoded session id. 'sidp'
15678+ * contains our registration id, and should contain an encoded session
15679+ * id on successful allocation.
15680+ */
15681+static int
15682+hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
15683+{
15684+ struct hifn_softc *sc = device_get_softc(dev);
15685+ struct cryptoini *c;
15686+ int mac = 0, cry = 0, sesn;
15687+ struct hifn_session *ses = NULL;
15688+ unsigned long l_flags;
15689+
15690+ DPRINTF("%s()\n", __FUNCTION__);
15691+
15692+ KASSERT(sc != NULL, ("hifn_newsession: null softc"));
15693+ if (sidp == NULL || cri == NULL || sc == NULL) {
15694+ DPRINTF("%s,%d: %s - EINVAL\n", __FILE__, __LINE__, __FUNCTION__);
15695+ return (EINVAL);
15696+ }
15697+
15698+ HIFN_LOCK(sc);
15699+ if (sc->sc_sessions == NULL) {
15700+ ses = sc->sc_sessions = (struct hifn_session *)kmalloc(sizeof(*ses),
15701+ SLAB_ATOMIC);
15702+ if (ses == NULL) {
15703+ HIFN_UNLOCK(sc);
15704+ return (ENOMEM);
15705+ }
15706+ sesn = 0;
15707+ sc->sc_nsessions = 1;
15708+ } else {
15709+ for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
15710+ if (!sc->sc_sessions[sesn].hs_used) {
15711+ ses = &sc->sc_sessions[sesn];
15712+ break;
15713+ }
15714+ }
15715+
15716+ if (ses == NULL) {
15717+ sesn = sc->sc_nsessions;
15718+ ses = (struct hifn_session *)kmalloc((sesn + 1) * sizeof(*ses),
15719+ SLAB_ATOMIC);
15720+ if (ses == NULL) {
15721+ HIFN_UNLOCK(sc);
15722+ return (ENOMEM);
15723+ }
15724+ bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
15725+ bzero(sc->sc_sessions, sesn * sizeof(*ses));
15726+ kfree(sc->sc_sessions);
15727+ sc->sc_sessions = ses;
15728+ ses = &sc->sc_sessions[sesn];
15729+ sc->sc_nsessions++;
15730+ }
15731+ }
15732+ HIFN_UNLOCK(sc);
15733+
15734+ bzero(ses, sizeof(*ses));
15735+ ses->hs_used = 1;
15736+
15737+ for (c = cri; c != NULL; c = c->cri_next) {
15738+ switch (c->cri_alg) {
15739+ case CRYPTO_MD5:
15740+ case CRYPTO_SHA1:
15741+ case CRYPTO_MD5_HMAC:
15742+ case CRYPTO_SHA1_HMAC:
15743+ if (mac) {
15744+ DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
15745+ return (EINVAL);
15746+ }
15747+ mac = 1;
15748+ ses->hs_mlen = c->cri_mlen;
15749+ if (ses->hs_mlen == 0) {
15750+ switch (c->cri_alg) {
15751+ case CRYPTO_MD5:
15752+ case CRYPTO_MD5_HMAC:
15753+ ses->hs_mlen = 16;
15754+ break;
15755+ case CRYPTO_SHA1:
15756+ case CRYPTO_SHA1_HMAC:
15757+ ses->hs_mlen = 20;
15758+ break;
15759+ }
15760+ }
15761+ break;
15762+ case CRYPTO_DES_CBC:
15763+ case CRYPTO_3DES_CBC:
15764+ case CRYPTO_AES_CBC:
15765+ /* XXX this may read fewer, does it matter? */
15766+ read_random(ses->hs_iv,
15767+ c->cri_alg == CRYPTO_AES_CBC ?
15768+ HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
15769+ /*FALLTHROUGH*/
15770+ case CRYPTO_ARC4:
15771+ if (cry) {
15772+ DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
15773+ return (EINVAL);
15774+ }
15775+ cry = 1;
15776+ break;
15777+ default:
15778+ DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
15779+ return (EINVAL);
15780+ }
15781+ }
15782+ if (mac == 0 && cry == 0) {
15783+ DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
15784+ return (EINVAL);
15785+ }
15786+
15787+ *sidp = HIFN_SID(device_get_unit(sc->sc_dev), sesn);
15788+
15789+ return (0);
15790+}
15791+
15792+/*
15793+ * Deallocate a session.
15794+ * XXX this routine should run a zero'd mac/encrypt key into context ram.
15795+ * XXX to blow away any keys already stored there.
15796+ */
15797+static int
15798+hifn_freesession(device_t dev, u_int64_t tid)
15799+{
15800+ struct hifn_softc *sc = device_get_softc(dev);
15801+ int session, error;
15802+ u_int32_t sid = CRYPTO_SESID2LID(tid);
15803+ unsigned long l_flags;
15804+
15805+ DPRINTF("%s()\n", __FUNCTION__);
15806+
15807+ KASSERT(sc != NULL, ("hifn_freesession: null softc"));
15808+ if (sc == NULL) {
15809+ DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
15810+ return (EINVAL);
15811+ }
15812+
15813+ HIFN_LOCK(sc);
15814+ session = HIFN_SESSION(sid);
15815+ if (session < sc->sc_nsessions) {
15816+ bzero(&sc->sc_sessions[session], sizeof(struct hifn_session));
15817+ error = 0;
15818+ } else {
15819+ DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
15820+ error = EINVAL;
15821+ }
15822+ HIFN_UNLOCK(sc);
15823+
15824+ return (error);
15825+}
15826+
15827+static int
15828+hifn_process(device_t dev, struct cryptop *crp, int hint)
15829+{
15830+ struct hifn_softc *sc = device_get_softc(dev);
15831+ struct hifn_command *cmd = NULL;
15832+ int session, err, ivlen;
15833+ struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
15834+
15835+ DPRINTF("%s()\n", __FUNCTION__);
15836+
15837+ if (crp == NULL || crp->crp_callback == NULL) {
15838+ hifnstats.hst_invalid++;
15839+ DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
15840+ return (EINVAL);
15841+ }
15842+ session = HIFN_SESSION(crp->crp_sid);
15843+
15844+ if (sc == NULL || session >= sc->sc_nsessions) {
15845+ DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
15846+ err = EINVAL;
15847+ goto errout;
15848+ }
15849+
15850+ cmd = kmalloc(sizeof(struct hifn_command), SLAB_ATOMIC);
15851+ if (cmd == NULL) {
15852+ hifnstats.hst_nomem++;
15853+ err = ENOMEM;
15854+ goto errout;
15855+ }
15856+ memset(cmd, 0, sizeof(*cmd));
15857+
15858+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
15859+ cmd->src_skb = (struct sk_buff *)crp->crp_buf;
15860+ cmd->dst_skb = (struct sk_buff *)crp->crp_buf;
15861+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
15862+ cmd->src_io = (struct uio *)crp->crp_buf;
15863+ cmd->dst_io = (struct uio *)crp->crp_buf;
15864+ } else {
15865+ cmd->src_buf = crp->crp_buf;
15866+ cmd->dst_buf = crp->crp_buf;
15867+ }
15868+
15869+ crd1 = crp->crp_desc;
15870+ if (crd1 == NULL) {
15871+ DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
15872+ err = EINVAL;
15873+ goto errout;
15874+ }
15875+ crd2 = crd1->crd_next;
15876+
15877+ if (crd2 == NULL) {
15878+ if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
15879+ crd1->crd_alg == CRYPTO_SHA1_HMAC ||
15880+ crd1->crd_alg == CRYPTO_SHA1 ||
15881+ crd1->crd_alg == CRYPTO_MD5) {
15882+ maccrd = crd1;
15883+ enccrd = NULL;
15884+ } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
15885+ crd1->crd_alg == CRYPTO_3DES_CBC ||
15886+ crd1->crd_alg == CRYPTO_AES_CBC ||
15887+ crd1->crd_alg == CRYPTO_ARC4) {
15888+ if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0)
15889+ cmd->base_masks |= HIFN_BASE_CMD_DECODE;
15890+ maccrd = NULL;
15891+ enccrd = crd1;
15892+ } else {
15893+ DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
15894+ err = EINVAL;
15895+ goto errout;
15896+ }
15897+ } else {
15898+ if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
15899+ crd1->crd_alg == CRYPTO_SHA1_HMAC ||
15900+ crd1->crd_alg == CRYPTO_MD5 ||
15901+ crd1->crd_alg == CRYPTO_SHA1) &&
15902+ (crd2->crd_alg == CRYPTO_DES_CBC ||
15903+ crd2->crd_alg == CRYPTO_3DES_CBC ||
15904+ crd2->crd_alg == CRYPTO_AES_CBC ||
15905+ crd2->crd_alg == CRYPTO_ARC4) &&
15906+ ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
15907+ cmd->base_masks = HIFN_BASE_CMD_DECODE;
15908+ maccrd = crd1;
15909+ enccrd = crd2;
15910+ } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
15911+ crd1->crd_alg == CRYPTO_ARC4 ||
15912+ crd1->crd_alg == CRYPTO_3DES_CBC ||
15913+ crd1->crd_alg == CRYPTO_AES_CBC) &&
15914+ (crd2->crd_alg == CRYPTO_MD5_HMAC ||
15915+ crd2->crd_alg == CRYPTO_SHA1_HMAC ||
15916+ crd2->crd_alg == CRYPTO_MD5 ||
15917+ crd2->crd_alg == CRYPTO_SHA1) &&
15918+ (crd1->crd_flags & CRD_F_ENCRYPT)) {
15919+ enccrd = crd1;
15920+ maccrd = crd2;
15921+ } else {
15922+ /*
15923+ * We cannot order the 7751 as requested
15924+ */
15925+ DPRINTF("%s,%d: %s %d,%d,%d - EINVAL\n",__FILE__,__LINE__,__FUNCTION__, crd1->crd_alg, crd2->crd_alg, crd1->crd_flags & CRD_F_ENCRYPT);
15926+ err = EINVAL;
15927+ goto errout;
15928+ }
15929+ }
15930+
15931+ if (enccrd) {
15932+ cmd->enccrd = enccrd;
15933+ cmd->base_masks |= HIFN_BASE_CMD_CRYPT;
15934+ switch (enccrd->crd_alg) {
15935+ case CRYPTO_ARC4:
15936+ cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4;
15937+ break;
15938+ case CRYPTO_DES_CBC:
15939+ cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES |
15940+ HIFN_CRYPT_CMD_MODE_CBC |
15941+ HIFN_CRYPT_CMD_NEW_IV;
15942+ break;
15943+ case CRYPTO_3DES_CBC:
15944+ cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES |
15945+ HIFN_CRYPT_CMD_MODE_CBC |
15946+ HIFN_CRYPT_CMD_NEW_IV;
15947+ break;
15948+ case CRYPTO_AES_CBC:
15949+ cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES |
15950+ HIFN_CRYPT_CMD_MODE_CBC |
15951+ HIFN_CRYPT_CMD_NEW_IV;
15952+ break;
15953+ default:
15954+ DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
15955+ err = EINVAL;
15956+ goto errout;
15957+ }
15958+ if (enccrd->crd_alg != CRYPTO_ARC4) {
15959+ ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ?
15960+ HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
15961+ if (enccrd->crd_flags & CRD_F_ENCRYPT) {
15962+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
15963+ bcopy(enccrd->crd_iv, cmd->iv, ivlen);
15964+ else
15965+ bcopy(sc->sc_sessions[session].hs_iv,
15966+ cmd->iv, ivlen);
15967+
15968+ if ((enccrd->crd_flags & CRD_F_IV_PRESENT)
15969+ == 0) {
15970+ crypto_copyback(crp->crp_flags,
15971+ crp->crp_buf, enccrd->crd_inject,
15972+ ivlen, cmd->iv);
15973+ }
15974+ } else {
15975+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
15976+ bcopy(enccrd->crd_iv, cmd->iv, ivlen);
15977+ else {
15978+ crypto_copydata(crp->crp_flags,
15979+ crp->crp_buf, enccrd->crd_inject,
15980+ ivlen, cmd->iv);
15981+ }
15982+ }
15983+ }
15984+
15985+ if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
15986+ cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
15987+ cmd->ck = enccrd->crd_key;
15988+ cmd->cklen = enccrd->crd_klen >> 3;
15989+ cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
15990+
15991+ /*
15992+ * Need to specify the size for the AES key in the masks.
15993+ */
15994+ if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) ==
15995+ HIFN_CRYPT_CMD_ALG_AES) {
15996+ switch (cmd->cklen) {
15997+ case 16:
15998+ cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128;
15999+ break;
16000+ case 24:
16001+ cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192;
16002+ break;
16003+ case 32:
16004+ cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256;
16005+ break;
16006+ default:
16007+ DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
16008+ err = EINVAL;
16009+ goto errout;
16010+ }
16011+ }
16012+ }
16013+
16014+ if (maccrd) {
16015+ cmd->maccrd = maccrd;
16016+ cmd->base_masks |= HIFN_BASE_CMD_MAC;
16017+
16018+ switch (maccrd->crd_alg) {
16019+ case CRYPTO_MD5:
16020+ cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
16021+ HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
16022+ HIFN_MAC_CMD_POS_IPSEC;
16023+ break;
16024+ case CRYPTO_MD5_HMAC:
16025+ cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
16026+ HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
16027+ HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
16028+ break;
16029+ case CRYPTO_SHA1:
16030+ cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
16031+ HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
16032+ HIFN_MAC_CMD_POS_IPSEC;
16033+ break;
16034+ case CRYPTO_SHA1_HMAC:
16035+ cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
16036+ HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
16037+ HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
16038+ break;
16039+ }
16040+
16041+ if (maccrd->crd_alg == CRYPTO_SHA1_HMAC ||
16042+ maccrd->crd_alg == CRYPTO_MD5_HMAC) {
16043+ cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY;
16044+ bcopy(maccrd->crd_key, cmd->mac, maccrd->crd_klen >> 3);
16045+ bzero(cmd->mac + (maccrd->crd_klen >> 3),
16046+ HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3));
16047+ }
16048+ }
16049+
16050+ cmd->crp = crp;
16051+ cmd->session_num = session;
16052+ cmd->softc = sc;
16053+
16054+ err = hifn_crypto(sc, cmd, crp, hint);
16055+ if (!err) {
16056+ return 0;
16057+ } else if (err == ERESTART) {
16058+ /*
16059+ * There weren't enough resources to dispatch the request
16060+ * to the part. Notify the caller so they'll requeue this
16061+ * request and resubmit it again soon.
16062+ */
16063+#ifdef HIFN_DEBUG
16064+ if (hifn_debug)
16065+ device_printf(sc->sc_dev, "requeue request\n");
16066+#endif
16067+ kfree(cmd);
16068+ sc->sc_needwakeup |= CRYPTO_SYMQ;
16069+ return (err);
16070+ }
16071+
16072+errout:
16073+ if (cmd != NULL)
16074+ kfree(cmd);
16075+ if (err == EINVAL)
16076+ hifnstats.hst_invalid++;
16077+ else
16078+ hifnstats.hst_nomem++;
16079+ crp->crp_etype = err;
16080+ crypto_done(crp);
16081+ return (err);
16082+}
16083+
16084+static void
16085+hifn_abort(struct hifn_softc *sc)
16086+{
16087+ struct hifn_dma *dma = sc->sc_dma;
16088+ struct hifn_command *cmd;
16089+ struct cryptop *crp;
16090+ int i, u;
16091+
16092+ DPRINTF("%s()\n", __FUNCTION__);
16093+
16094+ i = dma->resk; u = dma->resu;
16095+ while (u != 0) {
16096+ cmd = dma->hifn_commands[i];
16097+ KASSERT(cmd != NULL, ("hifn_abort: null command slot %u", i));
16098+ dma->hifn_commands[i] = NULL;
16099+ crp = cmd->crp;
16100+
16101+ if ((dma->resr[i].l & htole32(HIFN_D_VALID)) == 0) {
16102+ /* Salvage what we can. */
16103+ u_int8_t *macbuf;
16104+
16105+ if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
16106+ macbuf = dma->result_bufs[i];
16107+ macbuf += 12;
16108+ } else
16109+ macbuf = NULL;
16110+ hifnstats.hst_opackets++;
16111+ hifn_callback(sc, cmd, macbuf);
16112+ } else {
16113+#if 0
16114+ if (cmd->src_map == cmd->dst_map) {
16115+ bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
16116+ BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
16117+ } else {
16118+ bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
16119+ BUS_DMASYNC_POSTWRITE);
16120+ bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
16121+ BUS_DMASYNC_POSTREAD);
16122+ }
16123+#endif
16124+
16125+ if (cmd->src_skb != cmd->dst_skb) {
16126+#ifdef NOTYET
16127+ m_freem(cmd->src_m);
16128+ crp->crp_buf = (caddr_t)cmd->dst_m;
16129+#else
16130+ device_printf(sc->sc_dev,
16131+ "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
16132+ __FILE__, __LINE__);
16133+#endif
16134+ }
16135+
16136+ /* non-shared buffers cannot be restarted */
16137+ if (cmd->src_map != cmd->dst_map) {
16138+ /*
16139+ * XXX should be EAGAIN, delayed until
16140+ * after the reset.
16141+ */
16142+ crp->crp_etype = ENOMEM;
16143+ pci_unmap_buf(sc, &cmd->dst);
16144+ } else
16145+ crp->crp_etype = ENOMEM;
16146+
16147+ pci_unmap_buf(sc, &cmd->src);
16148+
16149+ kfree(cmd);
16150+ if (crp->crp_etype != EAGAIN)
16151+ crypto_done(crp);
16152+ }
16153+
16154+ if (++i == HIFN_D_RES_RSIZE)
16155+ i = 0;
16156+ u--;
16157+ }
16158+ dma->resk = i; dma->resu = u;
16159+
16160+ hifn_reset_board(sc, 1);
16161+ hifn_init_dma(sc);
16162+ hifn_init_pci_registers(sc);
16163+}
16164+
16165+static void
16166+hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)
16167+{
16168+ struct hifn_dma *dma = sc->sc_dma;
16169+ struct cryptop *crp = cmd->crp;
16170+ struct cryptodesc *crd;
16171+ int i, u, ivlen;
16172+
16173+ DPRINTF("%s()\n", __FUNCTION__);
16174+
16175+#if 0
16176+ if (cmd->src_map == cmd->dst_map) {
16177+ bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
16178+ BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
16179+ } else {
16180+ bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
16181+ BUS_DMASYNC_POSTWRITE);
16182+ bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
16183+ BUS_DMASYNC_POSTREAD);
16184+ }
16185+#endif
16186+
16187+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
16188+ if (cmd->src_skb != cmd->dst_skb) {
16189+#ifdef NOTYET
16190+ crp->crp_buf = (caddr_t)cmd->dst_m;
16191+ totlen = cmd->src_mapsize;
16192+ for (m = cmd->dst_m; m != NULL; m = m->m_next) {
16193+ if (totlen < m->m_len) {
16194+ m->m_len = totlen;
16195+ totlen = 0;
16196+ } else
16197+ totlen -= m->m_len;
16198+ }
16199+ cmd->dst_m->m_pkthdr.len = cmd->src_m->m_pkthdr.len;
16200+ m_freem(cmd->src_m);
16201+#else
16202+ device_printf(sc->sc_dev,
16203+ "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
16204+ __FILE__, __LINE__);
16205+#endif
16206+ }
16207+ }
16208+
16209+ if (cmd->sloplen != 0) {
16210+ crypto_copyback(crp->crp_flags, crp->crp_buf,
16211+ cmd->src_mapsize - cmd->sloplen, cmd->sloplen,
16212+ (caddr_t)&dma->slop[cmd->slopidx]);
16213+ }
16214+
16215+ i = dma->dstk; u = dma->dstu;
16216+ while (u != 0) {
16217+ if (i == HIFN_D_DST_RSIZE)
16218+ i = 0;
16219+#if 0
16220+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
16221+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
16222+#endif
16223+ if (dma->dstr[i].l & htole32(HIFN_D_VALID)) {
16224+#if 0
16225+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
16226+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
16227+#endif
16228+ break;
16229+ }
16230+ i++, u--;
16231+ }
16232+ dma->dstk = i; dma->dstu = u;
16233+
16234+ hifnstats.hst_obytes += cmd->dst_mapsize;
16235+
16236+ if ((cmd->base_masks & (HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE)) ==
16237+ HIFN_BASE_CMD_CRYPT) {
16238+ for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
16239+ if (crd->crd_alg != CRYPTO_DES_CBC &&
16240+ crd->crd_alg != CRYPTO_3DES_CBC &&
16241+ crd->crd_alg != CRYPTO_AES_CBC)
16242+ continue;
16243+ ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?
16244+ HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
16245+ crypto_copydata(crp->crp_flags, crp->crp_buf,
16246+ crd->crd_skip + crd->crd_len - ivlen, ivlen,
16247+ cmd->softc->sc_sessions[cmd->session_num].hs_iv);
16248+ break;
16249+ }
16250+ }
16251+
16252+ if (macbuf != NULL) {
16253+ for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
16254+ int len;
16255+
16256+ if (crd->crd_alg != CRYPTO_MD5 &&
16257+ crd->crd_alg != CRYPTO_SHA1 &&
16258+ crd->crd_alg != CRYPTO_MD5_HMAC &&
16259+ crd->crd_alg != CRYPTO_SHA1_HMAC) {
16260+ continue;
16261+ }
16262+ len = cmd->softc->sc_sessions[cmd->session_num].hs_mlen;
16263+ crypto_copyback(crp->crp_flags, crp->crp_buf,
16264+ crd->crd_inject, len, macbuf);
16265+ break;
16266+ }
16267+ }
16268+
16269+ if (cmd->src_map != cmd->dst_map)
16270+ pci_unmap_buf(sc, &cmd->dst);
16271+ pci_unmap_buf(sc, &cmd->src);
16272+ kfree(cmd);
16273+ crypto_done(crp);
16274+}
16275+
16276+/*
16277+ * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0
16278+ * and Group 1 registers; avoid conditions that could create
16279+ * burst writes by doing a read in between the writes.
16280+ *
16281+ * NB: The read we interpose is always to the same register;
16282+ * we do this because reading from an arbitrary (e.g. last)
16283+ * register may not always work.
16284+ */
16285+static void
16286+hifn_write_reg_0(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
16287+{
16288+ if (sc->sc_flags & HIFN_IS_7811) {
16289+ if (sc->sc_bar0_lastreg == reg - 4)
16290+ readl(sc->sc_bar0 + HIFN_0_PUCNFG);
16291+ sc->sc_bar0_lastreg = reg;
16292+ }
16293+ writel(val, sc->sc_bar0 + reg);
16294+}
16295+
16296+static void
16297+hifn_write_reg_1(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
16298+{
16299+ if (sc->sc_flags & HIFN_IS_7811) {
16300+ if (sc->sc_bar1_lastreg == reg - 4)
16301+ readl(sc->sc_bar1 + HIFN_1_REVID);
16302+ sc->sc_bar1_lastreg = reg;
16303+ }
16304+ writel(val, sc->sc_bar1 + reg);
16305+}
16306+
16307+
16308+static struct pci_device_id hifn_pci_tbl[] = {
16309+ { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7951,
16310+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
16311+ { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955,
16312+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
16313+ { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956,
16314+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
16315+ { PCI_VENDOR_NETSEC, PCI_PRODUCT_NETSEC_7751,
16316+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
16317+ { PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON,
16318+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
16319+ { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7811,
16320+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
16321+ /*
16322+ * Other vendors share this PCI ID as well, such as
16323+ * http://www.powercrypt.com, and obviously they also
16324+ * use the same key.
16325+ */
16326+ { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7751,
16327+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
16328+ { 0, 0, 0, 0, 0, 0, }
16329+};
16330+MODULE_DEVICE_TABLE(pci, hifn_pci_tbl);
16331+
16332+static struct pci_driver hifn_driver = {
16333+ .name = "hifn",
16334+ .id_table = hifn_pci_tbl,
16335+ .probe = hifn_probe,
16336+ .remove = hifn_remove,
16337+ /* add PM stuff here one day */
16338+};
16339+
16340+static int __init hifn_init (void)
16341+{
16342+ struct hifn_softc *sc = NULL;
16343+ int rc;
16344+
16345+ DPRINTF("%s(%p)\n", __FUNCTION__, hifn_init);
16346+
16347+ rc = pci_register_driver(&hifn_driver);
16348+ pci_register_driver_compat(&hifn_driver, rc);
16349+
16350+ return rc;
16351+}
16352+
16353+static void __exit hifn_exit (void)
16354+{
16355+ pci_unregister_driver(&hifn_driver);
16356+}
16357+
16358+module_init(hifn_init);
16359+module_exit(hifn_exit);
16360+
16361+MODULE_LICENSE("BSD");
16362+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
16363+MODULE_DESCRIPTION("OCF driver for hifn PCI crypto devices");
16364diff --git a/crypto/ocf/hifn/hifn7751reg.h b/crypto/ocf/hifn/hifn7751reg.h
16365new file mode 100644
16366index 0000000..23d70c5
16367--- /dev/null
16368+++ b/crypto/ocf/hifn/hifn7751reg.h
16369@@ -0,0 +1,540 @@
16370+/* $FreeBSD: src/sys/dev/hifn/hifn7751reg.h,v 1.7 2007/03/21 03:42:49 sam Exp $ */
16371+/* $OpenBSD: hifn7751reg.h,v 1.35 2002/04/08 17:49:42 jason Exp $ */
16372+
16373+/*-
16374+ * Invertex AEON / Hifn 7751 driver
16375+ * Copyright (c) 1999 Invertex Inc. All rights reserved.
16376+ * Copyright (c) 1999 Theo de Raadt
16377+ * Copyright (c) 2000-2001 Network Security Technologies, Inc.
16378+ * http://www.netsec.net
16379+ *
16380+ * Please send any comments, feedback, bug-fixes, or feature requests to
16381+ * software@invertex.com.
16382+ *
16383+ * Redistribution and use in source and binary forms, with or without
16384+ * modification, are permitted provided that the following conditions
16385+ * are met:
16386+ *
16387+ * 1. Redistributions of source code must retain the above copyright
16388+ * notice, this list of conditions and the following disclaimer.
16389+ * 2. Redistributions in binary form must reproduce the above copyright
16390+ * notice, this list of conditions and the following disclaimer in the
16391+ * documentation and/or other materials provided with the distribution.
16392+ * 3. The name of the author may not be used to endorse or promote products
16393+ * derived from this software without specific prior written permission.
16394+ *
16395+ *
16396+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16397+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16398+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16399+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16400+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16401+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
16402+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
16403+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16404+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
16405+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16406+ *
16407+ * Effort sponsored in part by the Defense Advanced Research Projects
16408+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
16409+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
16410+ *
16411+ */
16412+#ifndef __HIFN_H__
16413+#define __HIFN_H__
16414+
16415+/*
16416+ * Some PCI configuration space offset defines. The names were made
16417+ * identical to the names used by the Linux kernel.
16418+ */
16419+#define HIFN_BAR0 PCIR_BAR(0) /* PUC register map */
16420+#define HIFN_BAR1 PCIR_BAR(1) /* DMA register map */
16421+#define HIFN_TRDY_TIMEOUT 0x40
16422+#define HIFN_RETRY_TIMEOUT 0x41
16423+
16424+/*
16425+ * PCI vendor and device identifiers
16426+ * (the names are preserved from their OpenBSD source).
16427+ */
16428+#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
16429+#define PCI_PRODUCT_HIFN_7751 0x0005 /* 7751 */
16430+#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
16431+#define PCI_PRODUCT_HIFN_7811 0x0007 /* 7811 */
16432+#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
16433+#define PCI_PRODUCT_HIFN_7951 0x0012 /* 7951 */
16434+#define PCI_PRODUCT_HIFN_7955 0x0020 /* 7954/7955 */
16435+#define PCI_PRODUCT_HIFN_7956 0x001d /* 7956 */
16436+
16437+#define PCI_VENDOR_INVERTEX 0x14e1 /* Invertex */
16438+#define PCI_PRODUCT_INVERTEX_AEON 0x0005 /* AEON */
16439+
16440+#define PCI_VENDOR_NETSEC 0x1660 /* NetSec */
16441+#define PCI_PRODUCT_NETSEC_7751 0x7751 /* 7751 */
16442+
16443+/*
16444+ * The values below should multiple of 4 -- and be large enough to handle
16445+ * any command the driver implements.
16446+ *
16447+ * MAX_COMMAND = base command + mac command + encrypt command +
16448+ * mac-key + rc4-key
16449+ * MAX_RESULT = base result + mac result + mac + encrypt result
16450+ *
16451+ *
16452+ */
16453+#define HIFN_MAX_COMMAND (8 + 8 + 8 + 64 + 260)
16454+#define HIFN_MAX_RESULT (8 + 4 + 20 + 4)
16455+
16456+/*
16457+ * hifn_desc_t
16458+ *
16459+ * Holds an individual descriptor for any of the rings.
16460+ */
16461+typedef struct hifn_desc {
16462+ volatile u_int32_t l; /* length and status bits */
16463+ volatile u_int32_t p;
16464+} hifn_desc_t;
16465+
16466+/*
16467+ * Masks for the "length" field of struct hifn_desc.
16468+ */
16469+#define HIFN_D_LENGTH 0x0000ffff /* length bit mask */
16470+#define HIFN_D_MASKDONEIRQ 0x02000000 /* mask the done interrupt */
16471+#define HIFN_D_DESTOVER 0x04000000 /* destination overflow */
16472+#define HIFN_D_OVER 0x08000000 /* overflow */
16473+#define HIFN_D_LAST 0x20000000 /* last descriptor in chain */
16474+#define HIFN_D_JUMP 0x40000000 /* jump descriptor */
16475+#define HIFN_D_VALID 0x80000000 /* valid bit */
16476+
16477+
16478+/*
16479+ * Processing Unit Registers (offset from BASEREG0)
16480+ */
16481+#define HIFN_0_PUDATA 0x00 /* Processing Unit Data */
16482+#define HIFN_0_PUCTRL 0x04 /* Processing Unit Control */
16483+#define HIFN_0_PUISR 0x08 /* Processing Unit Interrupt Status */
16484+#define HIFN_0_PUCNFG 0x0c /* Processing Unit Configuration */
16485+#define HIFN_0_PUIER 0x10 /* Processing Unit Interrupt Enable */
16486+#define HIFN_0_PUSTAT 0x14 /* Processing Unit Status/Chip ID */
16487+#define HIFN_0_FIFOSTAT 0x18 /* FIFO Status */
16488+#define HIFN_0_FIFOCNFG 0x1c /* FIFO Configuration */
16489+#define HIFN_0_PUCTRL2 0x28 /* Processing Unit Control (2nd map) */
16490+#define HIFN_0_MUTE1 0x80
16491+#define HIFN_0_MUTE2 0x90
16492+#define HIFN_0_SPACESIZE 0x100 /* Register space size */
16493+
16494+/* Processing Unit Control Register (HIFN_0_PUCTRL) */
16495+#define HIFN_PUCTRL_CLRSRCFIFO 0x0010 /* clear source fifo */
16496+#define HIFN_PUCTRL_STOP 0x0008 /* stop pu */
16497+#define HIFN_PUCTRL_LOCKRAM 0x0004 /* lock ram */
16498+#define HIFN_PUCTRL_DMAENA 0x0002 /* enable dma */
16499+#define HIFN_PUCTRL_RESET 0x0001 /* Reset processing unit */
16500+
16501+/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */
16502+#define HIFN_PUISR_CMDINVAL 0x8000 /* Invalid command interrupt */
16503+#define HIFN_PUISR_DATAERR 0x4000 /* Data error interrupt */
16504+#define HIFN_PUISR_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
16505+#define HIFN_PUISR_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
16506+#define HIFN_PUISR_DSTOVER 0x0200 /* Destination overrun interrupt */
16507+#define HIFN_PUISR_SRCCMD 0x0080 /* Source command interrupt */
16508+#define HIFN_PUISR_SRCCTX 0x0040 /* Source context interrupt */
16509+#define HIFN_PUISR_SRCDATA 0x0020 /* Source data interrupt */
16510+#define HIFN_PUISR_DSTDATA 0x0010 /* Destination data interrupt */
16511+#define HIFN_PUISR_DSTRESULT 0x0004 /* Destination result interrupt */
16512+
16513+/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */
16514+#define HIFN_PUCNFG_DRAMMASK 0xe000 /* DRAM size mask */
16515+#define HIFN_PUCNFG_DSZ_256K 0x0000 /* 256k dram */
16516+#define HIFN_PUCNFG_DSZ_512K 0x2000 /* 512k dram */
16517+#define HIFN_PUCNFG_DSZ_1M 0x4000 /* 1m dram */
16518+#define HIFN_PUCNFG_DSZ_2M 0x6000 /* 2m dram */
16519+#define HIFN_PUCNFG_DSZ_4M 0x8000 /* 4m dram */
16520+#define HIFN_PUCNFG_DSZ_8M 0xa000 /* 8m dram */
16521+#define HIFN_PUNCFG_DSZ_16M 0xc000 /* 16m dram */
16522+#define HIFN_PUCNFG_DSZ_32M 0xe000 /* 32m dram */
16523+#define HIFN_PUCNFG_DRAMREFRESH 0x1800 /* DRAM refresh rate mask */
16524+#define HIFN_PUCNFG_DRFR_512 0x0000 /* 512 divisor of ECLK */
16525+#define HIFN_PUCNFG_DRFR_256 0x0800 /* 256 divisor of ECLK */
16526+#define HIFN_PUCNFG_DRFR_128 0x1000 /* 128 divisor of ECLK */
16527+#define HIFN_PUCNFG_TCALLPHASES 0x0200 /* your guess is as good as mine... */
16528+#define HIFN_PUCNFG_TCDRVTOTEM 0x0100 /* your guess is as good as mine... */
16529+#define HIFN_PUCNFG_BIGENDIAN 0x0080 /* DMA big endian mode */
16530+#define HIFN_PUCNFG_BUS32 0x0040 /* Bus width 32bits */
16531+#define HIFN_PUCNFG_BUS16 0x0000 /* Bus width 16 bits */
16532+#define HIFN_PUCNFG_CHIPID 0x0020 /* Allow chipid from PUSTAT */
16533+#define HIFN_PUCNFG_DRAM 0x0010 /* Context RAM is DRAM */
16534+#define HIFN_PUCNFG_SRAM 0x0000 /* Context RAM is SRAM */
16535+#define HIFN_PUCNFG_COMPSING 0x0004 /* Enable single compression context */
16536+#define HIFN_PUCNFG_ENCCNFG 0x0002 /* Encryption configuration */
16537+
16538+/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */
16539+#define HIFN_PUIER_CMDINVAL 0x8000 /* Invalid command interrupt */
16540+#define HIFN_PUIER_DATAERR 0x4000 /* Data error interrupt */
16541+#define HIFN_PUIER_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
16542+#define HIFN_PUIER_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
16543+#define HIFN_PUIER_DSTOVER 0x0200 /* Destination overrun interrupt */
16544+#define HIFN_PUIER_SRCCMD 0x0080 /* Source command interrupt */
16545+#define HIFN_PUIER_SRCCTX 0x0040 /* Source context interrupt */
16546+#define HIFN_PUIER_SRCDATA 0x0020 /* Source data interrupt */
16547+#define HIFN_PUIER_DSTDATA 0x0010 /* Destination data interrupt */
16548+#define HIFN_PUIER_DSTRESULT 0x0004 /* Destination result interrupt */
16549+
16550+/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */
16551+#define HIFN_PUSTAT_CMDINVAL 0x8000 /* Invalid command interrupt */
16552+#define HIFN_PUSTAT_DATAERR 0x4000 /* Data error interrupt */
16553+#define HIFN_PUSTAT_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
16554+#define HIFN_PUSTAT_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
16555+#define HIFN_PUSTAT_DSTOVER 0x0200 /* Destination overrun interrupt */
16556+#define HIFN_PUSTAT_SRCCMD 0x0080 /* Source command interrupt */
16557+#define HIFN_PUSTAT_SRCCTX 0x0040 /* Source context interrupt */
16558+#define HIFN_PUSTAT_SRCDATA 0x0020 /* Source data interrupt */
16559+#define HIFN_PUSTAT_DSTDATA 0x0010 /* Destination data interrupt */
16560+#define HIFN_PUSTAT_DSTRESULT 0x0004 /* Destination result interrupt */
16561+#define HIFN_PUSTAT_CHIPREV 0x00ff /* Chip revision mask */
16562+#define HIFN_PUSTAT_CHIPENA 0xff00 /* Chip enabled mask */
16563+#define HIFN_PUSTAT_ENA_2 0x1100 /* Level 2 enabled */
16564+#define HIFN_PUSTAT_ENA_1 0x1000 /* Level 1 enabled */
16565+#define HIFN_PUSTAT_ENA_0 0x3000 /* Level 0 enabled */
16566+#define HIFN_PUSTAT_REV_2 0x0020 /* 7751 PT6/2 */
16567+#define HIFN_PUSTAT_REV_3 0x0030 /* 7751 PT6/3 */
16568+
16569+/* FIFO Status Register (HIFN_0_FIFOSTAT) */
16570+#define HIFN_FIFOSTAT_SRC 0x7f00 /* Source FIFO available */
16571+#define HIFN_FIFOSTAT_DST 0x007f /* Destination FIFO available */
16572+
16573+/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */
16574+#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as this value */
16575+
16576+/*
16577+ * DMA Interface Registers (offset from BASEREG1)
16578+ */
16579+#define HIFN_1_DMA_CRAR 0x0c /* DMA Command Ring Address */
16580+#define HIFN_1_DMA_SRAR 0x1c /* DMA Source Ring Address */
16581+#define HIFN_1_DMA_RRAR 0x2c /* DMA Result Ring Address */
16582+#define HIFN_1_DMA_DRAR 0x3c /* DMA Destination Ring Address */
16583+#define HIFN_1_DMA_CSR 0x40 /* DMA Status and Control */
16584+#define HIFN_1_DMA_IER 0x44 /* DMA Interrupt Enable */
16585+#define HIFN_1_DMA_CNFG 0x48 /* DMA Configuration */
16586+#define HIFN_1_PLL 0x4c /* 7955/7956: PLL config */
16587+#define HIFN_1_7811_RNGENA 0x60 /* 7811: rng enable */
16588+#define HIFN_1_7811_RNGCFG 0x64 /* 7811: rng config */
16589+#define HIFN_1_7811_RNGDAT 0x68 /* 7811: rng data */
16590+#define HIFN_1_7811_RNGSTS 0x6c /* 7811: rng status */
16591+#define HIFN_1_DMA_CNFG2 0x6c /* 7955/7956: dma config #2 */
16592+#define HIFN_1_7811_MIPSRST 0x94 /* 7811: MIPS reset */
16593+#define HIFN_1_REVID 0x98 /* Revision ID */
16594+
16595+#define HIFN_1_PUB_RESET 0x204 /* Public/RNG Reset */
16596+#define HIFN_1_PUB_BASE 0x300 /* Public Base Address */
16597+#define HIFN_1_PUB_OPLEN 0x304 /* 7951-compat Public Operand Length */
16598+#define HIFN_1_PUB_OP 0x308 /* 7951-compat Public Operand */
16599+#define HIFN_1_PUB_STATUS 0x30c /* 7951-compat Public Status */
16600+#define HIFN_1_PUB_IEN 0x310 /* Public Interrupt enable */
16601+#define HIFN_1_RNG_CONFIG 0x314 /* RNG config */
16602+#define HIFN_1_RNG_DATA 0x318 /* RNG data */
16603+#define HIFN_1_PUB_MODE 0x320 /* PK mode */
16604+#define HIFN_1_PUB_FIFO_OPLEN 0x380 /* first element of oplen fifo */
16605+#define HIFN_1_PUB_FIFO_OP 0x384 /* first element of op fifo */
16606+#define HIFN_1_PUB_MEM 0x400 /* start of Public key memory */
16607+#define HIFN_1_PUB_MEMEND 0xbff /* end of Public key memory */
16608+
16609+/* DMA Status and Control Register (HIFN_1_DMA_CSR) */
16610+#define HIFN_DMACSR_D_CTRLMASK 0xc0000000 /* Destinition Ring Control */
16611+#define HIFN_DMACSR_D_CTRL_NOP 0x00000000 /* Dest. Control: no-op */
16612+#define HIFN_DMACSR_D_CTRL_DIS 0x40000000 /* Dest. Control: disable */
16613+#define HIFN_DMACSR_D_CTRL_ENA 0x80000000 /* Dest. Control: enable */
16614+#define HIFN_DMACSR_D_ABORT 0x20000000 /* Destinition Ring PCIAbort */
16615+#define HIFN_DMACSR_D_DONE 0x10000000 /* Destinition Ring Done */
16616+#define HIFN_DMACSR_D_LAST 0x08000000 /* Destinition Ring Last */
16617+#define HIFN_DMACSR_D_WAIT 0x04000000 /* Destinition Ring Waiting */
16618+#define HIFN_DMACSR_D_OVER 0x02000000 /* Destinition Ring Overflow */
16619+#define HIFN_DMACSR_R_CTRL 0x00c00000 /* Result Ring Control */
16620+#define HIFN_DMACSR_R_CTRL_NOP 0x00000000 /* Result Control: no-op */
16621+#define HIFN_DMACSR_R_CTRL_DIS 0x00400000 /* Result Control: disable */
16622+#define HIFN_DMACSR_R_CTRL_ENA 0x00800000 /* Result Control: enable */
16623+#define HIFN_DMACSR_R_ABORT 0x00200000 /* Result Ring PCI Abort */
16624+#define HIFN_DMACSR_R_DONE 0x00100000 /* Result Ring Done */
16625+#define HIFN_DMACSR_R_LAST 0x00080000 /* Result Ring Last */
16626+#define HIFN_DMACSR_R_WAIT 0x00040000 /* Result Ring Waiting */
16627+#define HIFN_DMACSR_R_OVER 0x00020000 /* Result Ring Overflow */
16628+#define HIFN_DMACSR_S_CTRL 0x0000c000 /* Source Ring Control */
16629+#define HIFN_DMACSR_S_CTRL_NOP 0x00000000 /* Source Control: no-op */
16630+#define HIFN_DMACSR_S_CTRL_DIS 0x00004000 /* Source Control: disable */
16631+#define HIFN_DMACSR_S_CTRL_ENA 0x00008000 /* Source Control: enable */
16632+#define HIFN_DMACSR_S_ABORT 0x00002000 /* Source Ring PCI Abort */
16633+#define HIFN_DMACSR_S_DONE 0x00001000 /* Source Ring Done */
16634+#define HIFN_DMACSR_S_LAST 0x00000800 /* Source Ring Last */
16635+#define HIFN_DMACSR_S_WAIT 0x00000400 /* Source Ring Waiting */
16636+#define HIFN_DMACSR_ILLW 0x00000200 /* Illegal write (7811 only) */
16637+#define HIFN_DMACSR_ILLR 0x00000100 /* Illegal read (7811 only) */
16638+#define HIFN_DMACSR_C_CTRL 0x000000c0 /* Command Ring Control */
16639+#define HIFN_DMACSR_C_CTRL_NOP 0x00000000 /* Command Control: no-op */
16640+#define HIFN_DMACSR_C_CTRL_DIS 0x00000040 /* Command Control: disable */
16641+#define HIFN_DMACSR_C_CTRL_ENA 0x00000080 /* Command Control: enable */
16642+#define HIFN_DMACSR_C_ABORT 0x00000020 /* Command Ring PCI Abort */
16643+#define HIFN_DMACSR_C_DONE 0x00000010 /* Command Ring Done */
16644+#define HIFN_DMACSR_C_LAST 0x00000008 /* Command Ring Last */
16645+#define HIFN_DMACSR_C_WAIT 0x00000004 /* Command Ring Waiting */
16646+#define HIFN_DMACSR_PUBDONE 0x00000002 /* Public op done (7951 only) */
16647+#define HIFN_DMACSR_ENGINE 0x00000001 /* Command Ring Engine IRQ */
16648+
16649+/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */
16650+#define HIFN_DMAIER_D_ABORT 0x20000000 /* Destination Ring PCIAbort */
16651+#define HIFN_DMAIER_D_DONE 0x10000000 /* Destination Ring Done */
16652+#define HIFN_DMAIER_D_LAST 0x08000000 /* Destination Ring Last */
16653+#define HIFN_DMAIER_D_WAIT 0x04000000 /* Destination Ring Waiting */
16654+#define HIFN_DMAIER_D_OVER 0x02000000 /* Destination Ring Overflow */
16655+#define HIFN_DMAIER_R_ABORT 0x00200000 /* Result Ring PCI Abort */
16656+#define HIFN_DMAIER_R_DONE 0x00100000 /* Result Ring Done */
16657+#define HIFN_DMAIER_R_LAST 0x00080000 /* Result Ring Last */
16658+#define HIFN_DMAIER_R_WAIT 0x00040000 /* Result Ring Waiting */
16659+#define HIFN_DMAIER_R_OVER 0x00020000 /* Result Ring Overflow */
16660+#define HIFN_DMAIER_S_ABORT 0x00002000 /* Source Ring PCI Abort */
16661+#define HIFN_DMAIER_S_DONE 0x00001000 /* Source Ring Done */
16662+#define HIFN_DMAIER_S_LAST 0x00000800 /* Source Ring Last */
16663+#define HIFN_DMAIER_S_WAIT 0x00000400 /* Source Ring Waiting */
16664+#define HIFN_DMAIER_ILLW 0x00000200 /* Illegal write (7811 only) */
16665+#define HIFN_DMAIER_ILLR 0x00000100 /* Illegal read (7811 only) */
16666+#define HIFN_DMAIER_C_ABORT 0x00000020 /* Command Ring PCI Abort */
16667+#define HIFN_DMAIER_C_DONE 0x00000010 /* Command Ring Done */
16668+#define HIFN_DMAIER_C_LAST 0x00000008 /* Command Ring Last */
16669+#define HIFN_DMAIER_C_WAIT 0x00000004 /* Command Ring Waiting */
16670+#define HIFN_DMAIER_PUBDONE 0x00000002 /* public op done (7951 only) */
16671+#define HIFN_DMAIER_ENGINE 0x00000001 /* Engine IRQ */
16672+
16673+/* DMA Configuration Register (HIFN_1_DMA_CNFG) */
16674+#define HIFN_DMACNFG_BIGENDIAN 0x10000000 /* big endian mode */
16675+#define HIFN_DMACNFG_POLLFREQ 0x00ff0000 /* Poll frequency mask */
16676+#define HIFN_DMACNFG_UNLOCK 0x00000800
16677+#define HIFN_DMACNFG_POLLINVAL 0x00000700 /* Invalid Poll Scalar */
16678+#define HIFN_DMACNFG_LAST 0x00000010 /* Host control LAST bit */
16679+#define HIFN_DMACNFG_MODE 0x00000004 /* DMA mode */
16680+#define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */
16681+#define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */
16682+
16683+/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */
16684+#define HIFN_DMACNFG2_PKSWAP32 (1 << 19) /* swap the OPLEN/OP reg */
16685+#define HIFN_DMACNFG2_PKSWAP8 (1 << 18) /* swap the bits of OPLEN/OP */
16686+#define HIFN_DMACNFG2_BAR0_SWAP32 (1<<17) /* swap the bytes of BAR0 */
16687+#define HIFN_DMACNFG2_BAR1_SWAP8 (1<<16) /* swap the bits of BAR0 */
16688+#define HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12
16689+#define HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8
16690+#define HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4
16691+#define HIFN_DMACNFG2_TGT_READ_BURST_SHIFT 0
16692+
16693+/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */
16694+#define HIFN_7811_RNGENA_ENA 0x00000001 /* enable RNG */
16695+
16696+/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */
16697+#define HIFN_7811_RNGCFG_PRE1 0x00000f00 /* first prescalar */
16698+#define HIFN_7811_RNGCFG_OPRE 0x00000080 /* output prescalar */
16699+#define HIFN_7811_RNGCFG_DEFL 0x00000f80 /* 2 words/ 1/100 sec */
16700+
16701+/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */
16702+#define HIFN_7811_RNGSTS_RDY 0x00004000 /* two numbers in FIFO */
16703+#define HIFN_7811_RNGSTS_UFL 0x00001000 /* rng underflow */
16704+
16705+/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */
16706+#define HIFN_MIPSRST_BAR2SIZE 0xffff0000 /* sdram size */
16707+#define HIFN_MIPSRST_GPRAMINIT 0x00008000 /* gpram can be accessed */
16708+#define HIFN_MIPSRST_CRAMINIT 0x00004000 /* ctxram can be accessed */
16709+#define HIFN_MIPSRST_LED2 0x00000400 /* external LED2 */
16710+#define HIFN_MIPSRST_LED1 0x00000200 /* external LED1 */
16711+#define HIFN_MIPSRST_LED0 0x00000100 /* external LED0 */
16712+#define HIFN_MIPSRST_MIPSDIS 0x00000004 /* disable MIPS */
16713+#define HIFN_MIPSRST_MIPSRST 0x00000002 /* warm reset MIPS */
16714+#define HIFN_MIPSRST_MIPSCOLD 0x00000001 /* cold reset MIPS */
16715+
16716+/* Public key reset register (HIFN_1_PUB_RESET) */
16717+#define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */
16718+
16719+/* Public operation register (HIFN_1_PUB_OP) */
16720+#define HIFN_PUBOP_AOFFSET 0x0000003e /* A offset */
16721+#define HIFN_PUBOP_BOFFSET 0x00000fc0 /* B offset */
16722+#define HIFN_PUBOP_MOFFSET 0x0003f000 /* M offset */
16723+#define HIFN_PUBOP_OP_MASK 0x003c0000 /* Opcode: */
16724+#define HIFN_PUBOP_OP_NOP 0x00000000 /* NOP */
16725+#define HIFN_PUBOP_OP_ADD 0x00040000 /* ADD */
16726+#define HIFN_PUBOP_OP_ADDC 0x00080000 /* ADD w/carry */
16727+#define HIFN_PUBOP_OP_SUB 0x000c0000 /* SUB */
16728+#define HIFN_PUBOP_OP_SUBC 0x00100000 /* SUB w/carry */
16729+#define HIFN_PUBOP_OP_MODADD 0x00140000 /* Modular ADD */
16730+#define HIFN_PUBOP_OP_MODSUB 0x00180000 /* Modular SUB */
16731+#define HIFN_PUBOP_OP_INCA 0x001c0000 /* INC A */
16732+#define HIFN_PUBOP_OP_DECA 0x00200000 /* DEC A */
16733+#define HIFN_PUBOP_OP_MULT 0x00240000 /* MULT */
16734+#define HIFN_PUBOP_OP_MODMULT 0x00280000 /* Modular MULT */
16735+#define HIFN_PUBOP_OP_MODRED 0x002c0000 /* Modular Red */
16736+#define HIFN_PUBOP_OP_MODEXP 0x00300000 /* Modular Exp */
16737+
16738+/* Public operand length register (HIFN_1_PUB_OPLEN) */
16739+#define HIFN_PUBOPLEN_MODLEN 0x0000007f
16740+#define HIFN_PUBOPLEN_EXPLEN 0x0003ff80
16741+#define HIFN_PUBOPLEN_REDLEN 0x003c0000
16742+
16743+/* Public status register (HIFN_1_PUB_STATUS) */
16744+#define HIFN_PUBSTS_DONE 0x00000001 /* operation done */
16745+#define HIFN_PUBSTS_CARRY 0x00000002 /* carry */
16746+#define HIFN_PUBSTS_FIFO_EMPTY 0x00000100 /* fifo empty */
16747+#define HIFN_PUBSTS_FIFO_FULL 0x00000200 /* fifo full */
16748+#define HIFN_PUBSTS_FIFO_OVFL 0x00000400 /* fifo overflow */
16749+#define HIFN_PUBSTS_FIFO_WRITE 0x000f0000 /* fifo write */
16750+#define HIFN_PUBSTS_FIFO_READ 0x0f000000 /* fifo read */
16751+
16752+/* Public interrupt enable register (HIFN_1_PUB_IEN) */
16753+#define HIFN_PUBIEN_DONE 0x00000001 /* operation done interrupt */
16754+
16755+/* Random number generator config register (HIFN_1_RNG_CONFIG) */
16756+#define HIFN_RNGCFG_ENA 0x00000001 /* enable rng */
16757+
16758+/*
16759+ * Register offsets in register set 1
16760+ */
16761+
16762+#define HIFN_UNLOCK_SECRET1 0xf4
16763+#define HIFN_UNLOCK_SECRET2 0xfc
16764+
16765+/*
16766+ * PLL config register
16767+ *
16768+ * This register is present only on 7954/7955/7956 parts. It must be
16769+ * programmed according to the bus interface method used by the h/w.
16770+ * Note that the parts require a stable clock. Since the PCI clock
16771+ * may vary the reference clock must usually be used. To avoid
16772+ * overclocking the core logic, setup must be done carefully, refer
16773+ * to the driver for details. The exact multiplier required varies
16774+ * by part and system configuration; refer to the Hifn documentation.
16775+ */
16776+#define HIFN_PLL_REF_SEL 0x00000001 /* REF/HBI clk selection */
16777+#define HIFN_PLL_BP 0x00000002 /* bypass (used during setup) */
16778+/* bit 2 reserved */
16779+#define HIFN_PLL_PK_CLK_SEL 0x00000008 /* public key clk select */
16780+#define HIFN_PLL_PE_CLK_SEL 0x00000010 /* packet engine clk select */
16781+/* bits 5-9 reserved */
16782+#define HIFN_PLL_MBSET 0x00000400 /* must be set to 1 */
16783+#define HIFN_PLL_ND 0x00003800 /* Fpll_ref multiplier select */
16784+#define HIFN_PLL_ND_SHIFT 11
16785+#define HIFN_PLL_ND_2 0x00000000 /* 2x */
16786+#define HIFN_PLL_ND_4 0x00000800 /* 4x */
16787+#define HIFN_PLL_ND_6 0x00001000 /* 6x */
16788+#define HIFN_PLL_ND_8 0x00001800 /* 8x */
16789+#define HIFN_PLL_ND_10 0x00002000 /* 10x */
16790+#define HIFN_PLL_ND_12 0x00002800 /* 12x */
16791+/* bits 14-15 reserved */
16792+#define HIFN_PLL_IS 0x00010000 /* charge pump current select */
16793+/* bits 17-31 reserved */
16794+
16795+/*
16796+ * Board configuration specifies only these bits.
16797+ */
16798+#define HIFN_PLL_CONFIG (HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL)
16799+
16800+/*
16801+ * Public Key Engine Mode Register
16802+ */
16803+#define HIFN_PKMODE_HOSTINVERT (1 << 0) /* HOST INVERT */
16804+#define HIFN_PKMODE_ENHANCED (1 << 1) /* Enable enhanced mode */
16805+
16806+
16807+/*********************************************************************
16808+ * Structs for board commands
16809+ *
16810+ *********************************************************************/
16811+
16812+/*
16813+ * Structure to help build up the command data structure.
16814+ */
16815+typedef struct hifn_base_command {
16816+ volatile u_int16_t masks;
16817+ volatile u_int16_t session_num;
16818+ volatile u_int16_t total_source_count;
16819+ volatile u_int16_t total_dest_count;
16820+} hifn_base_command_t;
16821+
16822+#define HIFN_BASE_CMD_MAC 0x0400
16823+#define HIFN_BASE_CMD_CRYPT 0x0800
16824+#define HIFN_BASE_CMD_DECODE 0x2000
16825+#define HIFN_BASE_CMD_SRCLEN_M 0xc000
16826+#define HIFN_BASE_CMD_SRCLEN_S 14
16827+#define HIFN_BASE_CMD_DSTLEN_M 0x3000
16828+#define HIFN_BASE_CMD_DSTLEN_S 12
16829+#define HIFN_BASE_CMD_LENMASK_HI 0x30000
16830+#define HIFN_BASE_CMD_LENMASK_LO 0x0ffff
16831+
16832+/*
16833+ * Structure to help build up the command data structure.
16834+ */
16835+typedef struct hifn_crypt_command {
16836+ volatile u_int16_t masks;
16837+ volatile u_int16_t header_skip;
16838+ volatile u_int16_t source_count;
16839+ volatile u_int16_t reserved;
16840+} hifn_crypt_command_t;
16841+
16842+#define HIFN_CRYPT_CMD_ALG_MASK 0x0003 /* algorithm: */
16843+#define HIFN_CRYPT_CMD_ALG_DES 0x0000 /* DES */
16844+#define HIFN_CRYPT_CMD_ALG_3DES 0x0001 /* 3DES */
16845+#define HIFN_CRYPT_CMD_ALG_RC4 0x0002 /* RC4 */
16846+#define HIFN_CRYPT_CMD_ALG_AES 0x0003 /* AES */
16847+#define HIFN_CRYPT_CMD_MODE_MASK 0x0018 /* Encrypt mode: */
16848+#define HIFN_CRYPT_CMD_MODE_ECB 0x0000 /* ECB */
16849+#define HIFN_CRYPT_CMD_MODE_CBC 0x0008 /* CBC */
16850+#define HIFN_CRYPT_CMD_MODE_CFB 0x0010 /* CFB */
16851+#define HIFN_CRYPT_CMD_MODE_OFB 0x0018 /* OFB */
16852+#define HIFN_CRYPT_CMD_CLR_CTX 0x0040 /* clear context */
16853+#define HIFN_CRYPT_CMD_NEW_KEY 0x0800 /* expect new key */
16854+#define HIFN_CRYPT_CMD_NEW_IV 0x1000 /* expect new iv */
16855+
16856+#define HIFN_CRYPT_CMD_SRCLEN_M 0xc000
16857+#define HIFN_CRYPT_CMD_SRCLEN_S 14
16858+
16859+#define HIFN_CRYPT_CMD_KSZ_MASK 0x0600 /* AES key size: */
16860+#define HIFN_CRYPT_CMD_KSZ_128 0x0000 /* 128 bit */
16861+#define HIFN_CRYPT_CMD_KSZ_192 0x0200 /* 192 bit */
16862+#define HIFN_CRYPT_CMD_KSZ_256 0x0400 /* 256 bit */
16863+
16864+/*
16865+ * Structure to help build up the command data structure.
16866+ */
16867+typedef struct hifn_mac_command {
16868+ volatile u_int16_t masks;
16869+ volatile u_int16_t header_skip;
16870+ volatile u_int16_t source_count;
16871+ volatile u_int16_t reserved;
16872+} hifn_mac_command_t;
16873+
16874+#define HIFN_MAC_CMD_ALG_MASK 0x0001
16875+#define HIFN_MAC_CMD_ALG_SHA1 0x0000
16876+#define HIFN_MAC_CMD_ALG_MD5 0x0001
16877+#define HIFN_MAC_CMD_MODE_MASK 0x000c
16878+#define HIFN_MAC_CMD_MODE_HMAC 0x0000
16879+#define HIFN_MAC_CMD_MODE_SSL_MAC 0x0004
16880+#define HIFN_MAC_CMD_MODE_HASH 0x0008
16881+#define HIFN_MAC_CMD_MODE_FULL 0x0004
16882+#define HIFN_MAC_CMD_TRUNC 0x0010
16883+#define HIFN_MAC_CMD_RESULT 0x0020
16884+#define HIFN_MAC_CMD_APPEND 0x0040
16885+#define HIFN_MAC_CMD_SRCLEN_M 0xc000
16886+#define HIFN_MAC_CMD_SRCLEN_S 14
16887+
16888+/*
16889+ * MAC POS IPsec initiates authentication after encryption on encodes
16890+ * and before decryption on decodes.
16891+ */
16892+#define HIFN_MAC_CMD_POS_IPSEC 0x0200
16893+#define HIFN_MAC_CMD_NEW_KEY 0x0800
16894+
16895+/*
16896+ * The poll frequency and poll scalar defines are unshifted values used
16897+ * to set fields in the DMA Configuration Register.
16898+ */
16899+#ifndef HIFN_POLL_FREQUENCY
16900+#define HIFN_POLL_FREQUENCY 0x1
16901+#endif
16902+
16903+#ifndef HIFN_POLL_SCALAR
16904+#define HIFN_POLL_SCALAR 0x0
16905+#endif
16906+
16907+#define HIFN_MAX_SEGLEN 0xffff /* maximum dma segment len */
16908+#define HIFN_MAX_DMALEN 0x3ffff /* maximum dma length */
16909+#endif /* __HIFN_H__ */
16910diff --git a/crypto/ocf/hifn/hifn7751var.h b/crypto/ocf/hifn/hifn7751var.h
16911new file mode 100644
16912index 0000000..6146bfb
16913--- /dev/null
16914+++ b/crypto/ocf/hifn/hifn7751var.h
16915@@ -0,0 +1,369 @@
16916+/* $FreeBSD: src/sys/dev/hifn/hifn7751var.h,v 1.9 2007/03/21 03:42:49 sam Exp $ */
16917+/* $OpenBSD: hifn7751var.h,v 1.42 2002/04/08 17:49:42 jason Exp $ */
16918+
16919+/*-
16920+ * Invertex AEON / Hifn 7751 driver
16921+ * Copyright (c) 1999 Invertex Inc. All rights reserved.
16922+ * Copyright (c) 1999 Theo de Raadt
16923+ * Copyright (c) 2000-2001 Network Security Technologies, Inc.
16924+ * http://www.netsec.net
16925+ *
16926+ * Please send any comments, feedback, bug-fixes, or feature requests to
16927+ * software@invertex.com.
16928+ *
16929+ * Redistribution and use in source and binary forms, with or without
16930+ * modification, are permitted provided that the following conditions
16931+ * are met:
16932+ *
16933+ * 1. Redistributions of source code must retain the above copyright
16934+ * notice, this list of conditions and the following disclaimer.
16935+ * 2. Redistributions in binary form must reproduce the above copyright
16936+ * notice, this list of conditions and the following disclaimer in the
16937+ * documentation and/or other materials provided with the distribution.
16938+ * 3. The name of the author may not be used to endorse or promote products
16939+ * derived from this software without specific prior written permission.
16940+ *
16941+ *
16942+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16943+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16944+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16945+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16946+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16947+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
16948+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
16949+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16950+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
16951+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16952+ *
16953+ * Effort sponsored in part by the Defense Advanced Research Projects
16954+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
16955+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
16956+ *
16957+ */
16958+
16959+#ifndef __HIFN7751VAR_H__
16960+#define __HIFN7751VAR_H__
16961+
16962+#ifdef __KERNEL__
16963+
16964+/*
16965+ * Some configurable values for the driver. By default command+result
16966+ * descriptor rings are the same size. The src+dst descriptor rings
16967+ * are sized at 3.5x the number of potential commands. Slower parts
16968+ * (e.g. 7951) tend to run out of src descriptors; faster parts (7811)
16969+ * src+cmd/result descriptors. It's not clear that increasing the size
16970+ * of the descriptor rings helps performance significantly as other
16971+ * factors tend to come into play (e.g. copying misaligned packets).
16972+ */
16973+#define HIFN_D_CMD_RSIZE 24 /* command descriptors */
16974+#define HIFN_D_SRC_RSIZE ((HIFN_D_CMD_RSIZE * 7) / 2) /* source descriptors */
16975+#define HIFN_D_RES_RSIZE HIFN_D_CMD_RSIZE /* result descriptors */
16976+#define HIFN_D_DST_RSIZE HIFN_D_SRC_RSIZE /* destination descriptors */
16977+
16978+/*
16979+ * Length values for cryptography
16980+ */
16981+#define HIFN_DES_KEY_LENGTH 8
16982+#define HIFN_3DES_KEY_LENGTH 24
16983+#define HIFN_MAX_CRYPT_KEY_LENGTH HIFN_3DES_KEY_LENGTH
16984+#define HIFN_IV_LENGTH 8
16985+#define HIFN_AES_IV_LENGTH 16
16986+#define HIFN_MAX_IV_LENGTH HIFN_AES_IV_LENGTH
16987+
16988+/*
16989+ * Length values for authentication
16990+ */
16991+#define HIFN_MAC_KEY_LENGTH 64
16992+#define HIFN_MD5_LENGTH 16
16993+#define HIFN_SHA1_LENGTH 20
16994+#define HIFN_MAC_TRUNC_LENGTH 12
16995+
16996+#define MAX_SCATTER 64
16997+
16998+/*
16999+ * Data structure to hold all 4 rings and any other ring related data.
17000+ */
17001+struct hifn_dma {
17002+ /*
17003+ * Descriptor rings. We add +1 to the size to accomidate the
17004+ * jump descriptor.
17005+ */
17006+ struct hifn_desc cmdr[HIFN_D_CMD_RSIZE+1];
17007+ struct hifn_desc srcr[HIFN_D_SRC_RSIZE+1];
17008+ struct hifn_desc dstr[HIFN_D_DST_RSIZE+1];
17009+ struct hifn_desc resr[HIFN_D_RES_RSIZE+1];
17010+
17011+ struct hifn_command *hifn_commands[HIFN_D_RES_RSIZE];
17012+
17013+ u_char command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];
17014+ u_char result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];
17015+ u_int32_t slop[HIFN_D_CMD_RSIZE];
17016+
17017+ u_int64_t test_src, test_dst;
17018+
17019+ /*
17020+ * Our current positions for insertion and removal from the desriptor
17021+ * rings.
17022+ */
17023+ int cmdi, srci, dsti, resi;
17024+ volatile int cmdu, srcu, dstu, resu;
17025+ int cmdk, srck, dstk, resk;
17026+};
17027+
17028+struct hifn_session {
17029+ int hs_used;
17030+ int hs_mlen;
17031+ u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
17032+};
17033+
17034+#define HIFN_RING_SYNC(sc, r, i, f) \
17035+ /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
17036+
17037+#define HIFN_CMDR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), cmdr, (i), (f))
17038+#define HIFN_RESR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), resr, (i), (f))
17039+#define HIFN_SRCR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), srcr, (i), (f))
17040+#define HIFN_DSTR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), dstr, (i), (f))
17041+
17042+#define HIFN_CMD_SYNC(sc, i, f) \
17043+ /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
17044+
17045+#define HIFN_RES_SYNC(sc, i, f) \
17046+ /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
17047+
17048+typedef int bus_size_t;
17049+
17050+/*
17051+ * Holds data specific to a single HIFN board.
17052+ */
17053+struct hifn_softc {
17054+ softc_device_decl sc_dev;
17055+
17056+ struct pci_dev *sc_pcidev; /* PCI device pointer */
17057+ spinlock_t sc_mtx; /* per-instance lock */
17058+
17059+ int sc_num; /* for multiple devs */
17060+
17061+ ocf_iomem_t sc_bar0;
17062+ bus_size_t sc_bar0_lastreg;/* bar0 last reg written */
17063+ ocf_iomem_t sc_bar1;
17064+ bus_size_t sc_bar1_lastreg;/* bar1 last reg written */
17065+
17066+ int sc_irq;
17067+
17068+ u_int32_t sc_dmaier;
17069+ u_int32_t sc_drammodel; /* 1=dram, 0=sram */
17070+ u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
17071+
17072+ struct hifn_dma *sc_dma;
17073+ dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
17074+
17075+ int sc_dmansegs;
17076+ int32_t sc_cid;
17077+ int sc_maxses;
17078+ int sc_nsessions;
17079+ struct hifn_session *sc_sessions;
17080+ int sc_ramsize;
17081+ int sc_flags;
17082+#define HIFN_HAS_RNG 0x1 /* includes random number generator */
17083+#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
17084+#define HIFN_HAS_AES 0x4 /* includes AES support */
17085+#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
17086+#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
17087+
17088+ struct timer_list sc_tickto; /* for managing DMA */
17089+
17090+ int sc_rngfirst;
17091+ int sc_rnghz; /* RNG polling frequency */
17092+
17093+ int sc_c_busy; /* command ring busy */
17094+ int sc_s_busy; /* source data ring busy */
17095+ int sc_d_busy; /* destination data ring busy */
17096+ int sc_r_busy; /* result ring busy */
17097+ int sc_active; /* for initial countdown */
17098+ int sc_needwakeup; /* ops q'd wating on resources */
17099+ int sc_curbatch; /* # ops submitted w/o int */
17100+ int sc_suspended;
17101+#ifdef HIFN_VULCANDEV
17102+ struct cdev *sc_pkdev;
17103+#endif
17104+};
17105+
17106+#define HIFN_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
17107+#define HIFN_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
17108+
17109+/*
17110+ * hifn_command_t
17111+ *
17112+ * This is the control structure used to pass commands to hifn_encrypt().
17113+ *
17114+ * flags
17115+ * -----
17116+ * Flags is the bitwise "or" values for command configuration. A single
17117+ * encrypt direction needs to be set:
17118+ *
17119+ * HIFN_ENCODE or HIFN_DECODE
17120+ *
17121+ * To use cryptography, a single crypto algorithm must be included:
17122+ *
17123+ * HIFN_CRYPT_3DES or HIFN_CRYPT_DES
17124+ *
17125+ * To use authentication is used, a single MAC algorithm must be included:
17126+ *
17127+ * HIFN_MAC_MD5 or HIFN_MAC_SHA1
17128+ *
17129+ * By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash.
17130+ * If the value below is set, hash values are truncated or assumed
17131+ * truncated to 12 bytes:
17132+ *
17133+ * HIFN_MAC_TRUNC
17134+ *
17135+ * Keys for encryption and authentication can be sent as part of a command,
17136+ * or the last key value used with a particular session can be retrieved
17137+ * and used again if either of these flags are not specified.
17138+ *
17139+ * HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY
17140+ *
17141+ * session_num
17142+ * -----------
17143+ * A number between 0 and 2048 (for DRAM models) or a number between
17144+ * 0 and 768 (for SRAM models). Those who don't want to use session
17145+ * numbers should leave value at zero and send a new crypt key and/or
17146+ * new MAC key on every command. If you use session numbers and
17147+ * don't send a key with a command, the last key sent for that same
17148+ * session number will be used.
17149+ *
17150+ * Warning: Using session numbers and multiboard at the same time
17151+ * is currently broken.
17152+ *
17153+ * mbuf
17154+ * ----
17155+ * Either fill in the mbuf pointer and npa=0 or
17156+ * fill packp[] and packl[] and set npa to > 0
17157+ *
17158+ * mac_header_skip
17159+ * ---------------
17160+ * The number of bytes of the source_buf that are skipped over before
17161+ * authentication begins. This must be a number between 0 and 2^16-1
17162+ * and can be used by IPsec implementers to skip over IP headers.
17163+ * *** Value ignored if authentication not used ***
17164+ *
17165+ * crypt_header_skip
17166+ * -----------------
17167+ * The number of bytes of the source_buf that are skipped over before
17168+ * the cryptographic operation begins. This must be a number between 0
17169+ * and 2^16-1. For IPsec, this number will always be 8 bytes larger
17170+ * than the auth_header_skip (to skip over the ESP header).
17171+ * *** Value ignored if cryptography not used ***
17172+ *
17173+ */
17174+struct hifn_operand {
17175+ union {
17176+ struct sk_buff *skb;
17177+ struct uio *io;
17178+ unsigned char *buf;
17179+ } u;
17180+ void *map;
17181+ bus_size_t mapsize;
17182+ int nsegs;
17183+ struct {
17184+ dma_addr_t ds_addr;
17185+ int ds_len;
17186+ } segs[MAX_SCATTER];
17187+};
17188+
17189+struct hifn_command {
17190+ u_int16_t session_num;
17191+ u_int16_t base_masks, cry_masks, mac_masks;
17192+ u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];
17193+ int cklen;
17194+ int sloplen, slopidx;
17195+
17196+ struct hifn_operand src;
17197+ struct hifn_operand dst;
17198+
17199+ struct hifn_softc *softc;
17200+ struct cryptop *crp;
17201+ struct cryptodesc *enccrd, *maccrd;
17202+};
17203+
17204+#define src_skb src.u.skb
17205+#define src_io src.u.io
17206+#define src_map src.map
17207+#define src_mapsize src.mapsize
17208+#define src_segs src.segs
17209+#define src_nsegs src.nsegs
17210+#define src_buf src.u.buf
17211+
17212+#define dst_skb dst.u.skb
17213+#define dst_io dst.u.io
17214+#define dst_map dst.map
17215+#define dst_mapsize dst.mapsize
17216+#define dst_segs dst.segs
17217+#define dst_nsegs dst.nsegs
17218+#define dst_buf dst.u.buf
17219+
17220+/*
17221+ * Return values for hifn_crypto()
17222+ */
17223+#define HIFN_CRYPTO_SUCCESS 0
17224+#define HIFN_CRYPTO_BAD_INPUT (-1)
17225+#define HIFN_CRYPTO_RINGS_FULL (-2)
17226+
17227+/**************************************************************************
17228+ *
17229+ * Function: hifn_crypto
17230+ *
17231+ * Purpose: Called by external drivers to begin an encryption on the
17232+ * HIFN board.
17233+ *
17234+ * Blocking/Non-blocking Issues
17235+ * ============================
17236+ * The driver cannot block in hifn_crypto (no calls to tsleep) currently.
17237+ * hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough
17238+ * room in any of the rings for the request to proceed.
17239+ *
17240+ * Return Values
17241+ * =============
17242+ * 0 for success, negative values on error
17243+ *
17244+ * Defines for negative error codes are:
17245+ *
17246+ * HIFN_CRYPTO_BAD_INPUT : The passed in command had invalid settings.
17247+ * HIFN_CRYPTO_RINGS_FULL : All DMA rings were full and non-blocking
17248+ * behaviour was requested.
17249+ *
17250+ *************************************************************************/
17251+
17252+/*
17253+ * Convert back and forth from 'sid' to 'card' and 'session'
17254+ */
17255+#define HIFN_CARD(sid) (((sid) & 0xf0000000) >> 28)
17256+#define HIFN_SESSION(sid) ((sid) & 0x000007ff)
17257+#define HIFN_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
17258+
17259+#endif /* _KERNEL */
17260+
17261+struct hifn_stats {
17262+ u_int64_t hst_ibytes;
17263+ u_int64_t hst_obytes;
17264+ u_int32_t hst_ipackets;
17265+ u_int32_t hst_opackets;
17266+ u_int32_t hst_invalid;
17267+ u_int32_t hst_nomem; /* malloc or one of hst_nomem_* */
17268+ u_int32_t hst_abort;
17269+ u_int32_t hst_noirq; /* IRQ for no reason */
17270+ u_int32_t hst_totbatch; /* ops submitted w/o interrupt */
17271+ u_int32_t hst_maxbatch; /* max ops submitted together */
17272+ u_int32_t hst_unaligned; /* unaligned src caused copy */
17273+ /*
17274+ * The following divides hst_nomem into more specific buckets.
17275+ */
17276+ u_int32_t hst_nomem_map; /* bus_dmamap_create failed */
17277+ u_int32_t hst_nomem_load; /* bus_dmamap_load_* failed */
17278+ u_int32_t hst_nomem_mbuf; /* MGET* failed */
17279+ u_int32_t hst_nomem_mcl; /* MCLGET* failed */
17280+ u_int32_t hst_nomem_cr; /* out of command/result descriptor */
17281+ u_int32_t hst_nomem_sd; /* out of src/dst descriptors */
17282+};
17283+
17284+#endif /* __HIFN7751VAR_H__ */
17285diff --git a/crypto/ocf/hifn/hifnHIPP.c b/crypto/ocf/hifn/hifnHIPP.c
17286new file mode 100644
17287index 0000000..1785147
17288--- /dev/null
17289+++ b/crypto/ocf/hifn/hifnHIPP.c
17290@@ -0,0 +1,420 @@
17291+/*-
17292+ * Driver for Hifn HIPP-I/II chipset
17293+ * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
17294+ *
17295+ * Redistribution and use in source and binary forms, with or without
17296+ * modification, are permitted provided that the following conditions
17297+ * are met:
17298+ *
17299+ * 1. Redistributions of source code must retain the above copyright
17300+ * notice, this list of conditions and the following disclaimer.
17301+ * 2. Redistributions in binary form must reproduce the above copyright
17302+ * notice, this list of conditions and the following disclaimer in the
17303+ * documentation and/or other materials provided with the distribution.
17304+ * 3. The name of the author may not be used to endorse or promote products
17305+ * derived from this software without specific prior written permission.
17306+ *
17307+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17308+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17309+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17310+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17311+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17312+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
17313+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
17314+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17315+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
17316+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17317+ *
17318+ * Effort sponsored by Hifn Inc.
17319+ *
17320+ */
17321+
17322+/*
17323+ * Driver for various Hifn encryption processors.
17324+ */
17325+#ifndef AUTOCONF_INCLUDED
17326+#include <linux/config.h>
17327+#endif
17328+#include <linux/module.h>
17329+#include <linux/init.h>
17330+#include <linux/list.h>
17331+#include <linux/slab.h>
17332+#include <linux/wait.h>
17333+#include <linux/sched.h>
17334+#include <linux/pci.h>
17335+#include <linux/delay.h>
17336+#include <linux/interrupt.h>
17337+#include <linux/spinlock.h>
17338+#include <linux/random.h>
17339+#include <linux/version.h>
17340+#include <linux/skbuff.h>
17341+#include <linux/uio.h>
17342+#include <linux/sysfs.h>
17343+#include <linux/miscdevice.h>
17344+#include <asm/io.h>
17345+
17346+#include <cryptodev.h>
17347+
17348+#include "hifnHIPPreg.h"
17349+#include "hifnHIPPvar.h"
17350+
17351+#if 1
17352+#define DPRINTF(a...) if (hipp_debug) { \
17353+ printk("%s: ", sc ? \
17354+ device_get_nameunit(sc->sc_dev) : "hifn"); \
17355+ printk(a); \
17356+ } else
17357+#else
17358+#define DPRINTF(a...)
17359+#endif
17360+
17361+typedef int bus_size_t;
17362+
17363+static inline int
17364+pci_get_revid(struct pci_dev *dev)
17365+{
17366+ u8 rid = 0;
17367+ pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
17368+ return rid;
17369+}
17370+
17371+#define debug hipp_debug
17372+int hipp_debug = 0;
17373+module_param(hipp_debug, int, 0644);
17374+MODULE_PARM_DESC(hipp_debug, "Enable debug");
17375+
17376+int hipp_maxbatch = 1;
17377+module_param(hipp_maxbatch, int, 0644);
17378+MODULE_PARM_DESC(hipp_maxbatch, "max ops to batch w/o interrupt");
17379+
17380+static int hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent);
17381+static void hipp_remove(struct pci_dev *dev);
17382+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
17383+static irqreturn_t hipp_intr(int irq, void *arg);
17384+#else
17385+static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs);
17386+#endif
17387+
17388+static int hipp_num_chips = 0;
17389+static struct hipp_softc *hipp_chip_idx[HIPP_MAX_CHIPS];
17390+
17391+static int hipp_newsession(device_t, u_int32_t *, struct cryptoini *);
17392+static int hipp_freesession(device_t, u_int64_t);
17393+static int hipp_process(device_t, struct cryptop *, int);
17394+
17395+static device_method_t hipp_methods = {
17396+ /* crypto device methods */
17397+ DEVMETHOD(cryptodev_newsession, hipp_newsession),
17398+ DEVMETHOD(cryptodev_freesession,hipp_freesession),
17399+ DEVMETHOD(cryptodev_process, hipp_process),
17400+};
17401+
17402+static __inline u_int32_t
17403+READ_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg)
17404+{
17405+ u_int32_t v = readl(sc->sc_bar[barno] + reg);
17406+ //sc->sc_bar0_lastreg = (bus_size_t) -1;
17407+ return (v);
17408+}
17409+static __inline void
17410+WRITE_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg, u_int32_t val)
17411+{
17412+ writel(val, sc->sc_bar[barno] + reg);
17413+}
17414+
17415+#define READ_REG_0(sc, reg) READ_REG(sc, 0, reg)
17416+#define WRITE_REG_0(sc, reg, val) WRITE_REG(sc,0, reg, val)
17417+#define READ_REG_1(sc, reg) READ_REG(sc, 1, reg)
17418+#define WRITE_REG_1(sc, reg, val) WRITE_REG(sc,1, reg, val)
17419+
17420+static int
17421+hipp_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
17422+{
17423+ return EINVAL;
17424+}
17425+
17426+static int
17427+hipp_freesession(device_t dev, u_int64_t tid)
17428+{
17429+ return EINVAL;
17430+}
17431+
17432+static int
17433+hipp_process(device_t dev, struct cryptop *crp, int hint)
17434+{
17435+ return EINVAL;
17436+}
17437+
17438+static const char*
17439+hipp_partname(struct hipp_softc *sc, char buf[128], size_t blen)
17440+{
17441+ char *n = NULL;
17442+
17443+ switch (pci_get_vendor(sc->sc_pcidev)) {
17444+ case PCI_VENDOR_HIFN:
17445+ switch (pci_get_device(sc->sc_pcidev)) {
17446+ case PCI_PRODUCT_HIFN_7855: n = "Hifn 7855";
17447+ case PCI_PRODUCT_HIFN_8155: n = "Hifn 8155";
17448+ case PCI_PRODUCT_HIFN_6500: n = "Hifn 6500";
17449+ }
17450+ }
17451+
17452+ if(n==NULL) {
17453+ snprintf(buf, blen, "VID=%02x,PID=%02x",
17454+ pci_get_vendor(sc->sc_pcidev),
17455+ pci_get_device(sc->sc_pcidev));
17456+ } else {
17457+ buf[0]='\0';
17458+ strncat(buf, n, blen);
17459+ }
17460+ return buf;
17461+}
17462+
17463+struct hipp_fs_entry {
17464+ struct attribute attr;
17465+ /* other stuff */
17466+};
17467+
17468+
17469+static ssize_t
17470+cryptoid_show(struct device *dev,
17471+ struct device_attribute *attr,
17472+ char *buf)
17473+{
17474+ struct hipp_softc *sc;
17475+
17476+ sc = pci_get_drvdata(to_pci_dev (dev));
17477+ return sprintf (buf, "%d\n", sc->sc_cid);
17478+}
17479+
17480+struct device_attribute hipp_dev_cryptoid = __ATTR_RO(cryptoid);
17481+
17482+/*
17483+ * Attach an interface that successfully probed.
17484+ */
17485+static int
17486+hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent)
17487+{
17488+ struct hipp_softc *sc = NULL;
17489+ int i;
17490+ //char rbase;
17491+ //u_int16_t ena;
17492+ int rev;
17493+ //int rseg;
17494+ int rc;
17495+
17496+ DPRINTF("%s()\n", __FUNCTION__);
17497+
17498+ if (pci_enable_device(dev) < 0)
17499+ return(-ENODEV);
17500+
17501+ if (pci_set_mwi(dev))
17502+ return(-ENODEV);
17503+
17504+ if (!dev->irq) {
17505+ printk("hifn: found device with no IRQ assigned. check BIOS settings!");
17506+ pci_disable_device(dev);
17507+ return(-ENODEV);
17508+ }
17509+
17510+ sc = (struct hipp_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
17511+ if (!sc)
17512+ return(-ENOMEM);
17513+ memset(sc, 0, sizeof(*sc));
17514+
17515+ softc_device_init(sc, "hifn-hipp", hipp_num_chips, hipp_methods);
17516+
17517+ sc->sc_pcidev = dev;
17518+ sc->sc_irq = -1;
17519+ sc->sc_cid = -1;
17520+ sc->sc_num = hipp_num_chips++;
17521+
17522+ if (sc->sc_num < HIPP_MAX_CHIPS)
17523+ hipp_chip_idx[sc->sc_num] = sc;
17524+
17525+ pci_set_drvdata(sc->sc_pcidev, sc);
17526+
17527+ spin_lock_init(&sc->sc_mtx);
17528+
17529+ /*
17530+ * Setup PCI resources.
17531+ * The READ_REG_0, WRITE_REG_0, READ_REG_1,
17532+ * and WRITE_REG_1 macros throughout the driver are used
17533+ * to permit better debugging.
17534+ */
17535+ for(i=0; i<4; i++) {
17536+ unsigned long mem_start, mem_len;
17537+ mem_start = pci_resource_start(sc->sc_pcidev, i);
17538+ mem_len = pci_resource_len(sc->sc_pcidev, i);
17539+ sc->sc_barphy[i] = (caddr_t)mem_start;
17540+ sc->sc_bar[i] = (ocf_iomem_t) ioremap(mem_start, mem_len);
17541+ if (!sc->sc_bar[i]) {
17542+ device_printf(sc->sc_dev, "cannot map bar%d register space\n", i);
17543+ goto fail;
17544+ }
17545+ }
17546+
17547+ //hipp_reset_board(sc, 0);
17548+ pci_set_master(sc->sc_pcidev);
17549+
17550+ /*
17551+ * Arrange the interrupt line.
17552+ */
17553+ rc = request_irq(dev->irq, hipp_intr, IRQF_SHARED, "hifn", sc);
17554+ if (rc) {
17555+ device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
17556+ goto fail;
17557+ }
17558+ sc->sc_irq = dev->irq;
17559+
17560+ rev = READ_REG_1(sc, HIPP_1_REVID) & 0xffff;
17561+
17562+ {
17563+ char b[32];
17564+ device_printf(sc->sc_dev, "%s, rev %u",
17565+ hipp_partname(sc, b, sizeof(b)), rev);
17566+ }
17567+
17568+#if 0
17569+ if (sc->sc_flags & HIFN_IS_7956)
17570+ printf(", pll=0x%x<%s clk, %ux mult>",
17571+ sc->sc_pllconfig,
17572+ sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
17573+ 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
17574+#endif
17575+ printf("\n");
17576+
17577+ sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
17578+ if (sc->sc_cid < 0) {
17579+ device_printf(sc->sc_dev, "could not get crypto driver id\n");
17580+ goto fail;
17581+ }
17582+
17583+#if 0 /* cannot work with a non-GPL module */
17584+ /* make a sysfs entry to let the world know what entry we got */
17585+ sysfs_create_file(&sc->sc_pcidev->dev.kobj, &hipp_dev_cryptoid.attr);
17586+#endif
17587+
17588+#if 0
17589+ init_timer(&sc->sc_tickto);
17590+ sc->sc_tickto.function = hifn_tick;
17591+ sc->sc_tickto.data = (unsigned long) sc->sc_num;
17592+ mod_timer(&sc->sc_tickto, jiffies + HZ);
17593+#endif
17594+
17595+#if 0 /* no code here yet ?? */
17596+ crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
17597+#endif
17598+
17599+ return (0);
17600+
17601+fail:
17602+ if (sc->sc_cid >= 0)
17603+ crypto_unregister_all(sc->sc_cid);
17604+ if (sc->sc_irq != -1)
17605+ free_irq(sc->sc_irq, sc);
17606+
17607+#if 0
17608+ if (sc->sc_dma) {
17609+ /* Turn off DMA polling */
17610+ WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
17611+ HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
17612+
17613+ pci_free_consistent(sc->sc_pcidev,
17614+ sizeof(*sc->sc_dma),
17615+ sc->sc_dma, sc->sc_dma_physaddr);
17616+ }
17617+#endif
17618+ kfree(sc);
17619+ return (-ENXIO);
17620+}
17621+
17622+/*
17623+ * Detach an interface that successfully probed.
17624+ */
17625+static void
17626+hipp_remove(struct pci_dev *dev)
17627+{
17628+ struct hipp_softc *sc = pci_get_drvdata(dev);
17629+ unsigned long l_flags;
17630+
17631+ DPRINTF("%s()\n", __FUNCTION__);
17632+
17633+ /* disable interrupts */
17634+ HIPP_LOCK(sc);
17635+
17636+#if 0
17637+ WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
17638+ HIFN_UNLOCK(sc);
17639+
17640+ /*XXX other resources */
17641+ del_timer_sync(&sc->sc_tickto);
17642+
17643+ /* Turn off DMA polling */
17644+ WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
17645+ HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
17646+#endif
17647+
17648+ crypto_unregister_all(sc->sc_cid);
17649+
17650+ free_irq(sc->sc_irq, sc);
17651+
17652+#if 0
17653+ pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
17654+ sc->sc_dma, sc->sc_dma_physaddr);
17655+#endif
17656+}
17657+
17658+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
17659+static irqreturn_t hipp_intr(int irq, void *arg)
17660+#else
17661+static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs)
17662+#endif
17663+{
17664+ struct hipp_softc *sc = arg;
17665+
17666+ sc = sc; /* shut up compiler */
17667+
17668+ return IRQ_HANDLED;
17669+}
17670+
17671+static struct pci_device_id hipp_pci_tbl[] = {
17672+ { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7855,
17673+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
17674+ { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_8155,
17675+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
17676+};
17677+MODULE_DEVICE_TABLE(pci, hipp_pci_tbl);
17678+
17679+static struct pci_driver hipp_driver = {
17680+ .name = "hipp",
17681+ .id_table = hipp_pci_tbl,
17682+ .probe = hipp_probe,
17683+ .remove = hipp_remove,
17684+ /* add PM stuff here one day */
17685+};
17686+
17687+static int __init hipp_init (void)
17688+{
17689+ struct hipp_softc *sc = NULL;
17690+ int rc;
17691+
17692+ DPRINTF("%s(%p)\n", __FUNCTION__, hipp_init);
17693+
17694+ rc = pci_register_driver(&hipp_driver);
17695+ pci_register_driver_compat(&hipp_driver, rc);
17696+
17697+ return rc;
17698+}
17699+
17700+static void __exit hipp_exit (void)
17701+{
17702+ pci_unregister_driver(&hipp_driver);
17703+}
17704+
17705+module_init(hipp_init);
17706+module_exit(hipp_exit);
17707+
17708+MODULE_LICENSE("BSD");
17709+MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
17710+MODULE_DESCRIPTION("OCF driver for hifn HIPP-I/II PCI crypto devices");
17711diff --git a/crypto/ocf/hifn/hifnHIPPreg.h b/crypto/ocf/hifn/hifnHIPPreg.h
17712new file mode 100644
17713index 0000000..8c0e720
17714--- /dev/null
17715+++ b/crypto/ocf/hifn/hifnHIPPreg.h
17716@@ -0,0 +1,46 @@
17717+/*-
17718+ * Hifn HIPP-I/HIPP-II (7855/8155) driver.
17719+ * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
17720+ *
17721+ * Redistribution and use in source and binary forms, with or without
17722+ * modification, are permitted provided that the following conditions
17723+ * are met:
17724+ *
17725+ * 1. Redistributions of source code must retain the above copyright
17726+ * notice, this list of conditions and the following disclaimer.
17727+ * 2. Redistributions in binary form must reproduce the above copyright
17728+ * notice, this list of conditions and the following disclaimer in the
17729+ * documentation and/or other materials provided with the distribution.
17730+ * 3. The name of the author may not be used to endorse or promote products
17731+ * derived from this software without specific prior written permission.
17732+ *
17733+ *
17734+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17735+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17736+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17737+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17738+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17739+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
17740+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
17741+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17742+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
17743+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17744+ *
17745+ * Effort sponsored by Hifn inc.
17746+ *
17747+ */
17748+
17749+#ifndef __HIFNHIPP_H__
17750+#define __HIFNHIPP_H__
17751+
17752+/*
17753+ * PCI vendor and device identifiers
17754+ */
17755+#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
17756+#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
17757+#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
17758+#define PCI_PRODUCT_HIFN_8155 0x999 /* XXX 8155 */
17759+
17760+#define HIPP_1_REVID 0x01 /* BOGUS */
17761+
17762+#endif /* __HIPP_H__ */
17763diff --git a/crypto/ocf/hifn/hifnHIPPvar.h b/crypto/ocf/hifn/hifnHIPPvar.h
17764new file mode 100644
17765index 0000000..dde47f7
17766--- /dev/null
17767+++ b/crypto/ocf/hifn/hifnHIPPvar.h
17768@@ -0,0 +1,93 @@
17769+/*
17770+ * Hifn HIPP-I/HIPP-II (7855/8155) driver.
17771+ * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com> *
17772+ *
17773+ * Redistribution and use in source and binary forms, with or without
17774+ * modification, are permitted provided that the following conditions
17775+ * are met:
17776+ *
17777+ * 1. Redistributions of source code must retain the above copyright
17778+ * notice, this list of conditions and the following disclaimer.
17779+ * 2. Redistributions in binary form must reproduce the above copyright
17780+ * notice, this list of conditions and the following disclaimer in the
17781+ * documentation and/or other materials provided with the distribution.
17782+ * 3. The name of the author may not be used to endorse or promote products
17783+ * derived from this software without specific prior written permission.
17784+ *
17785+ *
17786+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17787+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17788+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17789+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17790+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17791+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
17792+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
17793+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17794+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
17795+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17796+ *
17797+ * Effort sponsored by Hifn inc.
17798+ *
17799+ */
17800+
17801+#ifndef __HIFNHIPPVAR_H__
17802+#define __HIFNHIPPVAR_H__
17803+
17804+#define HIPP_MAX_CHIPS 8
17805+
17806+/*
17807+ * Holds data specific to a single Hifn HIPP-I board.
17808+ */
17809+struct hipp_softc {
17810+ softc_device_decl sc_dev;
17811+
17812+ struct pci_dev *sc_pcidev; /* device backpointer */
17813+ ocf_iomem_t sc_bar[5];
17814+ caddr_t sc_barphy[5]; /* physical address */
17815+ int sc_num; /* for multiple devs */
17816+ spinlock_t sc_mtx; /* per-instance lock */
17817+ int32_t sc_cid;
17818+ int sc_irq;
17819+
17820+#if 0
17821+
17822+ u_int32_t sc_dmaier;
17823+ u_int32_t sc_drammodel; /* 1=dram, 0=sram */
17824+ u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
17825+
17826+ struct hifn_dma *sc_dma;
17827+ dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
17828+
17829+ int sc_dmansegs;
17830+ int sc_maxses;
17831+ int sc_nsessions;
17832+ struct hifn_session *sc_sessions;
17833+ int sc_ramsize;
17834+ int sc_flags;
17835+#define HIFN_HAS_RNG 0x1 /* includes random number generator */
17836+#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
17837+#define HIFN_HAS_AES 0x4 /* includes AES support */
17838+#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
17839+#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
17840+
17841+ struct timer_list sc_tickto; /* for managing DMA */
17842+
17843+ int sc_rngfirst;
17844+ int sc_rnghz; /* RNG polling frequency */
17845+
17846+ int sc_c_busy; /* command ring busy */
17847+ int sc_s_busy; /* source data ring busy */
17848+ int sc_d_busy; /* destination data ring busy */
17849+ int sc_r_busy; /* result ring busy */
17850+ int sc_active; /* for initial countdown */
17851+ int sc_needwakeup; /* ops q'd wating on resources */
17852+ int sc_curbatch; /* # ops submitted w/o int */
17853+ int sc_suspended;
17854+ struct miscdevice sc_miscdev;
17855+#endif
17856+};
17857+
17858+#define HIPP_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
17859+#define HIPP_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
17860+
17861+#endif /* __HIFNHIPPVAR_H__ */
17862diff --git a/crypto/ocf/ixp4xx/Makefile b/crypto/ocf/ixp4xx/Makefile
17863new file mode 100644
17864index 0000000..d94a3b7
17865--- /dev/null
17866+++ b/crypto/ocf/ixp4xx/Makefile
17867@@ -0,0 +1,104 @@
17868+# for SGlinux builds
17869+-include $(ROOTDIR)/modules/.config
17870+
17871+#
17872+# You will need to point this at your Intel ixp425 includes, this portion
17873+# of the Makefile only really works under SGLinux with the appropriate libs
17874+# installed. They can be downloaded from http://www.snapgear.org/
17875+#
17876+ifeq ($(CONFIG_CPU_IXP46X),y)
17877+IXPLATFORM = ixp46X
17878+else
17879+ifeq ($(CONFIG_CPU_IXP43X),y)
17880+IXPLATFORM = ixp43X
17881+else
17882+IXPLATFORM = ixp42X
17883+endif
17884+endif
17885+
17886+ifdef CONFIG_IXP400_LIB_2_4
17887+IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp400_xscale_sw
17888+OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp_osal
17889+endif
17890+ifdef CONFIG_IXP400_LIB_2_1
17891+IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp400_xscale_sw
17892+OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp_osal
17893+endif
17894+ifdef CONFIG_IXP400_LIB_2_0
17895+IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp400_xscale_sw
17896+OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp_osal
17897+endif
17898+ifdef IX_XSCALE_SW
17899+ifdef CONFIG_IXP400_LIB_2_4
17900+IXP_CFLAGS = \
17901+ -I$(ROOTDIR)/. \
17902+ -I$(IX_XSCALE_SW)/src/include \
17903+ -I$(OSAL_DIR)/common/include/ \
17904+ -I$(OSAL_DIR)/common/include/modules/ \
17905+ -I$(OSAL_DIR)/common/include/modules/ddk/ \
17906+ -I$(OSAL_DIR)/common/include/modules/bufferMgt/ \
17907+ -I$(OSAL_DIR)/common/include/modules/ioMem/ \
17908+ -I$(OSAL_DIR)/common/os/linux/include/ \
17909+ -I$(OSAL_DIR)/common/os/linux/include/core/ \
17910+ -I$(OSAL_DIR)/common/os/linux/include/modules/ \
17911+ -I$(OSAL_DIR)/common/os/linux/include/modules/ddk/ \
17912+ -I$(OSAL_DIR)/common/os/linux/include/modules/bufferMgt/ \
17913+ -I$(OSAL_DIR)/common/os/linux/include/modules/ioMem/ \
17914+ -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/include/ \
17915+ -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/os/linux/include/ \
17916+ -DENABLE_IOMEM -DENABLE_BUFFERMGT -DENABLE_DDK \
17917+ -DUSE_IXP4XX_CRYPTO
17918+else
17919+IXP_CFLAGS = \
17920+ -I$(ROOTDIR)/. \
17921+ -I$(IX_XSCALE_SW)/src/include \
17922+ -I$(OSAL_DIR)/ \
17923+ -I$(OSAL_DIR)/os/linux/include/ \
17924+ -I$(OSAL_DIR)/os/linux/include/modules/ \
17925+ -I$(OSAL_DIR)/os/linux/include/modules/ioMem/ \
17926+ -I$(OSAL_DIR)/os/linux/include/modules/bufferMgt/ \
17927+ -I$(OSAL_DIR)/os/linux/include/core/ \
17928+ -I$(OSAL_DIR)/os/linux/include/platforms/ \
17929+ -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ \
17930+ -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp425 \
17931+ -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp465 \
17932+ -I$(OSAL_DIR)/os/linux/include/core/ \
17933+ -I$(OSAL_DIR)/include/ \
17934+ -I$(OSAL_DIR)/include/modules/ \
17935+ -I$(OSAL_DIR)/include/modules/bufferMgt/ \
17936+ -I$(OSAL_DIR)/include/modules/ioMem/ \
17937+ -I$(OSAL_DIR)/include/platforms/ \
17938+ -I$(OSAL_DIR)/include/platforms/ixp400/ \
17939+ -DUSE_IXP4XX_CRYPTO
17940+endif
17941+endif
17942+ifdef CONFIG_IXP400_LIB_1_4
17943+IXP_CFLAGS = \
17944+ -I$(ROOTDIR)/. \
17945+ -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/include \
17946+ -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/linux \
17947+ -DUSE_IXP4XX_CRYPTO
17948+endif
17949+ifndef IXPDIR
17950+IXPDIR = ixp-version-is-not-supported
17951+endif
17952+
17953+ifeq ($(CONFIG_CPU_IXP46X),y)
17954+IXP_CFLAGS += -D__ixp46X
17955+else
17956+ifeq ($(CONFIG_CPU_IXP43X),y)
17957+IXP_CFLAGS += -D__ixp43X
17958+else
17959+IXP_CFLAGS += -D__ixp42X
17960+endif
17961+endif
17962+
17963+obj-$(CONFIG_OCF_IXP4XX) += ixp4xx.o
17964+
17965+obj ?= .
17966+EXTRA_CFLAGS += $(IXP_CFLAGS) -I$(obj)/.. -I$(obj)/.
17967+
17968+ifdef TOPDIR
17969+-include $(TOPDIR)/Rules.make
17970+endif
17971+
17972diff --git a/crypto/ocf/ixp4xx/ixp4xx.c b/crypto/ocf/ixp4xx/ixp4xx.c
17973new file mode 100644
17974index 0000000..7af7b0a
17975--- /dev/null
17976+++ b/crypto/ocf/ixp4xx/ixp4xx.c
17977@@ -0,0 +1,1324 @@
17978+/*
17979+ * An OCF module that uses Intels IXP CryptACC API to do the crypto.
17980+ * This driver requires the IXP400 Access Library that is available
17981+ * from Intel in order to operate (or compile).
17982+ *
17983+ * Written by David McCullough <david_mccullough@mcafee.com>
17984+ * Copyright (C) 2006-2010 David McCullough
17985+ * Copyright (C) 2004-2005 Intel Corporation.
17986+ *
17987+ * LICENSE TERMS
17988+ *
17989+ * The free distribution and use of this software in both source and binary
17990+ * form is allowed (with or without changes) provided that:
17991+ *
17992+ * 1. distributions of this source code include the above copyright
17993+ * notice, this list of conditions and the following disclaimer;
17994+ *
17995+ * 2. distributions in binary form include the above copyright
17996+ * notice, this list of conditions and the following disclaimer
17997+ * in the documentation and/or other associated materials;
17998+ *
17999+ * 3. the copyright holder's name is not used to endorse products
18000+ * built using this software without specific written permission.
18001+ *
18002+ * ALTERNATIVELY, provided that this notice is retained in full, this product
18003+ * may be distributed under the terms of the GNU General Public License (GPL),
18004+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
18005+ *
18006+ * DISCLAIMER
18007+ *
18008+ * This software is provided 'as is' with no explicit or implied warranties
18009+ * in respect of its properties, including, but not limited to, correctness
18010+ * and/or fitness for purpose.
18011+ */
18012+
18013+#ifndef AUTOCONF_INCLUDED
18014+#include <linux/config.h>
18015+#endif
18016+#include <linux/module.h>
18017+#include <linux/init.h>
18018+#include <linux/list.h>
18019+#include <linux/slab.h>
18020+#include <linux/sched.h>
18021+#include <linux/wait.h>
18022+#include <linux/crypto.h>
18023+#include <linux/interrupt.h>
18024+#include <asm/scatterlist.h>
18025+
18026+#include <IxTypes.h>
18027+#include <IxOsBuffMgt.h>
18028+#include <IxNpeDl.h>
18029+#include <IxCryptoAcc.h>
18030+#include <IxQMgr.h>
18031+#include <IxOsServices.h>
18032+#include <IxOsCacheMMU.h>
18033+
18034+#include <cryptodev.h>
18035+#include <uio.h>
18036+
18037+#ifndef IX_MBUF_PRIV
18038+#define IX_MBUF_PRIV(x) ((x)->priv)
18039+#endif
18040+
18041+struct ixp_data;
18042+
18043+struct ixp_q {
18044+ struct list_head ixp_q_list;
18045+ struct ixp_data *ixp_q_data;
18046+ struct cryptop *ixp_q_crp;
18047+ struct cryptodesc *ixp_q_ccrd;
18048+ struct cryptodesc *ixp_q_acrd;
18049+ IX_MBUF ixp_q_mbuf;
18050+ UINT8 *ixp_hash_dest; /* Location for hash in client buffer */
18051+ UINT8 *ixp_hash_src; /* Location of hash in internal buffer */
18052+ unsigned char ixp_q_iv_data[IX_CRYPTO_ACC_MAX_CIPHER_IV_LENGTH];
18053+ unsigned char *ixp_q_iv;
18054+};
18055+
18056+struct ixp_data {
18057+ int ixp_registered; /* is the context registered */
18058+ int ixp_crd_flags; /* detect direction changes */
18059+
18060+ int ixp_cipher_alg;
18061+ int ixp_auth_alg;
18062+
18063+ UINT32 ixp_ctx_id;
18064+ UINT32 ixp_hash_key_id; /* used when hashing */
18065+ IxCryptoAccCtx ixp_ctx;
18066+ IX_MBUF ixp_pri_mbuf;
18067+ IX_MBUF ixp_sec_mbuf;
18068+
18069+ struct work_struct ixp_pending_work;
18070+ struct work_struct ixp_registration_work;
18071+ struct list_head ixp_q; /* unprocessed requests */
18072+};
18073+
18074+#ifdef __ixp46X
18075+
18076+#define MAX_IOP_SIZE 64 /* words */
18077+#define MAX_OOP_SIZE 128
18078+
18079+#define MAX_PARAMS 3
18080+
18081+struct ixp_pkq {
18082+ struct list_head pkq_list;
18083+ struct cryptkop *pkq_krp;
18084+
18085+ IxCryptoAccPkeEauInOperands pkq_op;
18086+ IxCryptoAccPkeEauOpResult pkq_result;
18087+
18088+ UINT32 pkq_ibuf0[MAX_IOP_SIZE];
18089+ UINT32 pkq_ibuf1[MAX_IOP_SIZE];
18090+ UINT32 pkq_ibuf2[MAX_IOP_SIZE];
18091+ UINT32 pkq_obuf[MAX_OOP_SIZE];
18092+};
18093+
18094+static LIST_HEAD(ixp_pkq); /* current PK wait list */
18095+static struct ixp_pkq *ixp_pk_cur;
18096+static spinlock_t ixp_pkq_lock;
18097+
18098+#endif /* __ixp46X */
18099+
18100+static int ixp_blocked = 0;
18101+
18102+static int32_t ixp_id = -1;
18103+static struct ixp_data **ixp_sessions = NULL;
18104+static u_int32_t ixp_sesnum = 0;
18105+
18106+static int ixp_process(device_t, struct cryptop *, int);
18107+static int ixp_newsession(device_t, u_int32_t *, struct cryptoini *);
18108+static int ixp_freesession(device_t, u_int64_t);
18109+#ifdef __ixp46X
18110+static int ixp_kprocess(device_t, struct cryptkop *krp, int hint);
18111+#endif
18112+
18113+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
18114+static kmem_cache_t *qcache;
18115+#else
18116+static struct kmem_cache *qcache;
18117+#endif
18118+
18119+#define debug ixp_debug
18120+static int ixp_debug = 0;
18121+module_param(ixp_debug, int, 0644);
18122+MODULE_PARM_DESC(ixp_debug, "Enable debug");
18123+
18124+static int ixp_init_crypto = 1;
18125+module_param(ixp_init_crypto, int, 0444); /* RO after load/boot */
18126+MODULE_PARM_DESC(ixp_init_crypto, "Call ixCryptoAccInit (default is 1)");
18127+
18128+static void ixp_process_pending(void *arg);
18129+static void ixp_registration(void *arg);
18130+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
18131+static void ixp_process_pending_wq(struct work_struct *work);
18132+static void ixp_registration_wq(struct work_struct *work);
18133+#endif
18134+
18135+/*
18136+ * dummy device structure
18137+ */
18138+
18139+static struct {
18140+ softc_device_decl sc_dev;
18141+} ixpdev;
18142+
18143+static device_method_t ixp_methods = {
18144+ /* crypto device methods */
18145+ DEVMETHOD(cryptodev_newsession, ixp_newsession),
18146+ DEVMETHOD(cryptodev_freesession,ixp_freesession),
18147+ DEVMETHOD(cryptodev_process, ixp_process),
18148+#ifdef __ixp46X
18149+ DEVMETHOD(cryptodev_kprocess, ixp_kprocess),
18150+#endif
18151+};
18152+
18153+/*
18154+ * Generate a new software session.
18155+ */
18156+static int
18157+ixp_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
18158+{
18159+ struct ixp_data *ixp;
18160+ u_int32_t i;
18161+#define AUTH_LEN(cri, def) \
18162+ (cri->cri_mlen ? cri->cri_mlen : (def))
18163+
18164+ dprintk("%s():alg %d\n", __FUNCTION__,cri->cri_alg);
18165+ if (sid == NULL || cri == NULL) {
18166+ dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
18167+ return EINVAL;
18168+ }
18169+
18170+ if (ixp_sessions) {
18171+ for (i = 1; i < ixp_sesnum; i++)
18172+ if (ixp_sessions[i] == NULL)
18173+ break;
18174+ } else
18175+ i = 1; /* NB: to silence compiler warning */
18176+
18177+ if (ixp_sessions == NULL || i == ixp_sesnum) {
18178+ struct ixp_data **ixpd;
18179+
18180+ if (ixp_sessions == NULL) {
18181+ i = 1; /* We leave ixp_sessions[0] empty */
18182+ ixp_sesnum = CRYPTO_SW_SESSIONS;
18183+ } else
18184+ ixp_sesnum *= 2;
18185+
18186+ ixpd = kmalloc(ixp_sesnum * sizeof(struct ixp_data *), SLAB_ATOMIC);
18187+ if (ixpd == NULL) {
18188+ /* Reset session number */
18189+ if (ixp_sesnum == CRYPTO_SW_SESSIONS)
18190+ ixp_sesnum = 0;
18191+ else
18192+ ixp_sesnum /= 2;
18193+ dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
18194+ return ENOBUFS;
18195+ }
18196+ memset(ixpd, 0, ixp_sesnum * sizeof(struct ixp_data *));
18197+
18198+ /* Copy existing sessions */
18199+ if (ixp_sessions) {
18200+ memcpy(ixpd, ixp_sessions,
18201+ (ixp_sesnum / 2) * sizeof(struct ixp_data *));
18202+ kfree(ixp_sessions);
18203+ }
18204+
18205+ ixp_sessions = ixpd;
18206+ }
18207+
18208+ ixp_sessions[i] = (struct ixp_data *) kmalloc(sizeof(struct ixp_data),
18209+ SLAB_ATOMIC);
18210+ if (ixp_sessions[i] == NULL) {
18211+ ixp_freesession(NULL, i);
18212+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
18213+ return ENOBUFS;
18214+ }
18215+
18216+ *sid = i;
18217+
18218+ ixp = ixp_sessions[i];
18219+ memset(ixp, 0, sizeof(*ixp));
18220+
18221+ ixp->ixp_cipher_alg = -1;
18222+ ixp->ixp_auth_alg = -1;
18223+ ixp->ixp_ctx_id = -1;
18224+ INIT_LIST_HEAD(&ixp->ixp_q);
18225+
18226+ ixp->ixp_ctx.useDifferentSrcAndDestMbufs = 0;
18227+
18228+ while (cri) {
18229+ switch (cri->cri_alg) {
18230+ case CRYPTO_DES_CBC:
18231+ ixp->ixp_cipher_alg = cri->cri_alg;
18232+ ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_DES;
18233+ ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
18234+ ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
18235+ ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
18236+ ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
18237+ IX_CRYPTO_ACC_DES_IV_64;
18238+ memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
18239+ cri->cri_key, (cri->cri_klen + 7) / 8);
18240+ break;
18241+
18242+ case CRYPTO_3DES_CBC:
18243+ ixp->ixp_cipher_alg = cri->cri_alg;
18244+ ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
18245+ ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
18246+ ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
18247+ ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
18248+ ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
18249+ IX_CRYPTO_ACC_DES_IV_64;
18250+ memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
18251+ cri->cri_key, (cri->cri_klen + 7) / 8);
18252+ break;
18253+
18254+ case CRYPTO_RIJNDAEL128_CBC:
18255+ ixp->ixp_cipher_alg = cri->cri_alg;
18256+ ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_AES;
18257+ ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
18258+ ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
18259+ ixp->ixp_ctx.cipherCtx.cipherBlockLen = 16;
18260+ ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen = 16;
18261+ memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
18262+ cri->cri_key, (cri->cri_klen + 7) / 8);
18263+ break;
18264+
18265+ case CRYPTO_MD5:
18266+ case CRYPTO_MD5_HMAC:
18267+ ixp->ixp_auth_alg = cri->cri_alg;
18268+ ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_MD5;
18269+ ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, MD5_HASH_LEN);
18270+ ixp->ixp_ctx.authCtx.aadLen = 0;
18271+ /* Only MD5_HMAC needs a key */
18272+ if (cri->cri_alg == CRYPTO_MD5_HMAC) {
18273+ ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
18274+ if (ixp->ixp_ctx.authCtx.authKeyLen >
18275+ sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
18276+ printk(
18277+ "ixp4xx: Invalid key length for MD5_HMAC - %d bits\n",
18278+ cri->cri_klen);
18279+ ixp_freesession(NULL, i);
18280+ return EINVAL;
18281+ }
18282+ memcpy(ixp->ixp_ctx.authCtx.key.authKey,
18283+ cri->cri_key, (cri->cri_klen + 7) / 8);
18284+ }
18285+ break;
18286+
18287+ case CRYPTO_SHA1:
18288+ case CRYPTO_SHA1_HMAC:
18289+ ixp->ixp_auth_alg = cri->cri_alg;
18290+ ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
18291+ ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, SHA1_HASH_LEN);
18292+ ixp->ixp_ctx.authCtx.aadLen = 0;
18293+ /* Only SHA1_HMAC needs a key */
18294+ if (cri->cri_alg == CRYPTO_SHA1_HMAC) {
18295+ ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
18296+ if (ixp->ixp_ctx.authCtx.authKeyLen >
18297+ sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
18298+ printk(
18299+ "ixp4xx: Invalid key length for SHA1_HMAC - %d bits\n",
18300+ cri->cri_klen);
18301+ ixp_freesession(NULL, i);
18302+ return EINVAL;
18303+ }
18304+ memcpy(ixp->ixp_ctx.authCtx.key.authKey,
18305+ cri->cri_key, (cri->cri_klen + 7) / 8);
18306+ }
18307+ break;
18308+
18309+ default:
18310+ printk("ixp: unknown algo 0x%x\n", cri->cri_alg);
18311+ ixp_freesession(NULL, i);
18312+ return EINVAL;
18313+ }
18314+ cri = cri->cri_next;
18315+ }
18316+
18317+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
18318+ INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending_wq);
18319+ INIT_WORK(&ixp->ixp_registration_work, ixp_registration_wq);
18320+#else
18321+ INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending, ixp);
18322+ INIT_WORK(&ixp->ixp_registration_work, ixp_registration, ixp);
18323+#endif
18324+
18325+ return 0;
18326+}
18327+
18328+
18329+/*
18330+ * Free a session.
18331+ */
18332+static int
18333+ixp_freesession(device_t dev, u_int64_t tid)
18334+{
18335+ u_int32_t sid = CRYPTO_SESID2LID(tid);
18336+
18337+ dprintk("%s()\n", __FUNCTION__);
18338+ if (sid > ixp_sesnum || ixp_sessions == NULL ||
18339+ ixp_sessions[sid] == NULL) {
18340+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
18341+ return EINVAL;
18342+ }
18343+
18344+ /* Silently accept and return */
18345+ if (sid == 0)
18346+ return 0;
18347+
18348+ if (ixp_sessions[sid]) {
18349+ if (ixp_sessions[sid]->ixp_ctx_id != -1) {
18350+ ixCryptoAccCtxUnregister(ixp_sessions[sid]->ixp_ctx_id);
18351+ ixp_sessions[sid]->ixp_ctx_id = -1;
18352+ }
18353+ kfree(ixp_sessions[sid]);
18354+ }
18355+ ixp_sessions[sid] = NULL;
18356+ if (ixp_blocked) {
18357+ ixp_blocked = 0;
18358+ crypto_unblock(ixp_id, CRYPTO_SYMQ);
18359+ }
18360+ return 0;
18361+}
18362+
18363+
18364+/*
18365+ * callback for when hash processing is complete
18366+ */
18367+
18368+static void
18369+ixp_hash_perform_cb(
18370+ UINT32 hash_key_id,
18371+ IX_MBUF *bufp,
18372+ IxCryptoAccStatus status)
18373+{
18374+ struct ixp_q *q;
18375+
18376+ dprintk("%s(%u, %p, 0x%x)\n", __FUNCTION__, hash_key_id, bufp, status);
18377+
18378+ if (bufp == NULL) {
18379+ printk("ixp: NULL buf in %s\n", __FUNCTION__);
18380+ return;
18381+ }
18382+
18383+ q = IX_MBUF_PRIV(bufp);
18384+ if (q == NULL) {
18385+ printk("ixp: NULL priv in %s\n", __FUNCTION__);
18386+ return;
18387+ }
18388+
18389+ if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
18390+ /* On success, need to copy hash back into original client buffer */
18391+ memcpy(q->ixp_hash_dest, q->ixp_hash_src,
18392+ (q->ixp_q_data->ixp_auth_alg == CRYPTO_SHA1) ?
18393+ SHA1_HASH_LEN : MD5_HASH_LEN);
18394+ }
18395+ else {
18396+ printk("ixp: hash perform failed status=%d\n", status);
18397+ q->ixp_q_crp->crp_etype = EINVAL;
18398+ }
18399+
18400+ /* Free internal buffer used for hashing */
18401+ kfree(IX_MBUF_MDATA(&q->ixp_q_mbuf));
18402+
18403+ crypto_done(q->ixp_q_crp);
18404+ kmem_cache_free(qcache, q);
18405+}
18406+
18407+/*
18408+ * setup a request and perform it
18409+ */
18410+static void
18411+ixp_q_process(struct ixp_q *q)
18412+{
18413+ IxCryptoAccStatus status;
18414+ struct ixp_data *ixp = q->ixp_q_data;
18415+ int auth_off = 0;
18416+ int auth_len = 0;
18417+ int crypt_off = 0;
18418+ int crypt_len = 0;
18419+ int icv_off = 0;
18420+ char *crypt_func;
18421+
18422+ dprintk("%s(%p)\n", __FUNCTION__, q);
18423+
18424+ if (q->ixp_q_ccrd) {
18425+ if (q->ixp_q_ccrd->crd_flags & CRD_F_IV_EXPLICIT) {
18426+ q->ixp_q_iv = q->ixp_q_ccrd->crd_iv;
18427+ } else {
18428+ q->ixp_q_iv = q->ixp_q_iv_data;
18429+ crypto_copydata(q->ixp_q_crp->crp_flags, q->ixp_q_crp->crp_buf,
18430+ q->ixp_q_ccrd->crd_inject,
18431+ ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen,
18432+ (caddr_t) q->ixp_q_iv);
18433+ }
18434+
18435+ if (q->ixp_q_acrd) {
18436+ auth_off = q->ixp_q_acrd->crd_skip;
18437+ auth_len = q->ixp_q_acrd->crd_len;
18438+ icv_off = q->ixp_q_acrd->crd_inject;
18439+ }
18440+
18441+ crypt_off = q->ixp_q_ccrd->crd_skip;
18442+ crypt_len = q->ixp_q_ccrd->crd_len;
18443+ } else { /* if (q->ixp_q_acrd) */
18444+ auth_off = q->ixp_q_acrd->crd_skip;
18445+ auth_len = q->ixp_q_acrd->crd_len;
18446+ icv_off = q->ixp_q_acrd->crd_inject;
18447+ }
18448+
18449+ if (q->ixp_q_crp->crp_flags & CRYPTO_F_SKBUF) {
18450+ struct sk_buff *skb = (struct sk_buff *) q->ixp_q_crp->crp_buf;
18451+ if (skb_shinfo(skb)->nr_frags) {
18452+ /*
18453+ * DAVIDM fix this limitation one day by using
18454+ * a buffer pool and chaining, it is not currently
18455+ * needed for current user/kernel space acceleration
18456+ */
18457+ printk("ixp: Cannot handle fragmented skb's yet !\n");
18458+ q->ixp_q_crp->crp_etype = ENOENT;
18459+ goto done;
18460+ }
18461+ IX_MBUF_MLEN(&q->ixp_q_mbuf) =
18462+ IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = skb->len;
18463+ IX_MBUF_MDATA(&q->ixp_q_mbuf) = skb->data;
18464+ } else if (q->ixp_q_crp->crp_flags & CRYPTO_F_IOV) {
18465+ struct uio *uiop = (struct uio *) q->ixp_q_crp->crp_buf;
18466+ if (uiop->uio_iovcnt != 1) {
18467+ /*
18468+ * DAVIDM fix this limitation one day by using
18469+ * a buffer pool and chaining, it is not currently
18470+ * needed for current user/kernel space acceleration
18471+ */
18472+ printk("ixp: Cannot handle more than 1 iovec yet !\n");
18473+ q->ixp_q_crp->crp_etype = ENOENT;
18474+ goto done;
18475+ }
18476+ IX_MBUF_MLEN(&q->ixp_q_mbuf) =
18477+ IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_len;
18478+ IX_MBUF_MDATA(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_base;
18479+ } else /* contig buffer */ {
18480+ IX_MBUF_MLEN(&q->ixp_q_mbuf) =
18481+ IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_ilen;
18482+ IX_MBUF_MDATA(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_buf;
18483+ }
18484+
18485+ IX_MBUF_PRIV(&q->ixp_q_mbuf) = q;
18486+
18487+ if (ixp->ixp_auth_alg == CRYPTO_SHA1 || ixp->ixp_auth_alg == CRYPTO_MD5) {
18488+ /*
18489+ * For SHA1 and MD5 hash, need to create an internal buffer that is big
18490+ * enough to hold the original data + the appropriate padding for the
18491+ * hash algorithm.
18492+ */
18493+ UINT8 *tbuf = NULL;
18494+
18495+ IX_MBUF_MLEN(&q->ixp_q_mbuf) = IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) =
18496+ ((IX_MBUF_MLEN(&q->ixp_q_mbuf) * 8) + 72 + 511) / 8;
18497+ tbuf = kmalloc(IX_MBUF_MLEN(&q->ixp_q_mbuf), SLAB_ATOMIC);
18498+
18499+ if (IX_MBUF_MDATA(&q->ixp_q_mbuf) == NULL) {
18500+ printk("ixp: kmalloc(%u, SLAB_ATOMIC) failed\n",
18501+ IX_MBUF_MLEN(&q->ixp_q_mbuf));
18502+ q->ixp_q_crp->crp_etype = ENOMEM;
18503+ goto done;
18504+ }
18505+ memcpy(tbuf, &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off], auth_len);
18506+
18507+ /* Set location in client buffer to copy hash into */
18508+ q->ixp_hash_dest =
18509+ &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off + auth_len];
18510+
18511+ IX_MBUF_MDATA(&q->ixp_q_mbuf) = tbuf;
18512+
18513+ /* Set location in internal buffer for where hash starts */
18514+ q->ixp_hash_src = &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_len];
18515+
18516+ crypt_func = "ixCryptoAccHashPerform";
18517+ status = ixCryptoAccHashPerform(ixp->ixp_ctx.authCtx.authAlgo,
18518+ &q->ixp_q_mbuf, ixp_hash_perform_cb, 0, auth_len, auth_len,
18519+ &ixp->ixp_hash_key_id);
18520+ }
18521+ else {
18522+ crypt_func = "ixCryptoAccAuthCryptPerform";
18523+ status = ixCryptoAccAuthCryptPerform(ixp->ixp_ctx_id, &q->ixp_q_mbuf,
18524+ NULL, auth_off, auth_len, crypt_off, crypt_len, icv_off,
18525+ q->ixp_q_iv);
18526+ }
18527+
18528+ if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
18529+ return;
18530+
18531+ if (IX_CRYPTO_ACC_STATUS_QUEUE_FULL == status) {
18532+ q->ixp_q_crp->crp_etype = ENOMEM;
18533+ goto done;
18534+ }
18535+
18536+ printk("ixp: %s failed %u\n", crypt_func, status);
18537+ q->ixp_q_crp->crp_etype = EINVAL;
18538+
18539+done:
18540+ crypto_done(q->ixp_q_crp);
18541+ kmem_cache_free(qcache, q);
18542+}
18543+
18544+
18545+/*
18546+ * because we cannot process the Q from the Register callback
18547+ * we do it here on a task Q.
18548+ */
18549+
18550+static void
18551+ixp_process_pending(void *arg)
18552+{
18553+ struct ixp_data *ixp = arg;
18554+ struct ixp_q *q = NULL;
18555+
18556+ dprintk("%s(%p)\n", __FUNCTION__, arg);
18557+
18558+ if (!ixp)
18559+ return;
18560+
18561+ while (!list_empty(&ixp->ixp_q)) {
18562+ q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
18563+ list_del(&q->ixp_q_list);
18564+ ixp_q_process(q);
18565+ }
18566+}
18567+
18568+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
18569+static void
18570+ixp_process_pending_wq(struct work_struct *work)
18571+{
18572+ struct ixp_data *ixp = container_of(work, struct ixp_data, ixp_pending_work);
18573+ ixp_process_pending(ixp);
18574+}
18575+#endif
18576+
18577+/*
18578+ * callback for when context registration is complete
18579+ */
18580+
18581+static void
18582+ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
18583+{
18584+ int i;
18585+ struct ixp_data *ixp;
18586+ struct ixp_q *q;
18587+
18588+ dprintk("%s(%d, %p, %d)\n", __FUNCTION__, ctx_id, bufp, status);
18589+
18590+ /*
18591+ * free any buffer passed in to this routine
18592+ */
18593+ if (bufp) {
18594+ IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
18595+ kfree(IX_MBUF_MDATA(bufp));
18596+ IX_MBUF_MDATA(bufp) = NULL;
18597+ }
18598+
18599+ for (i = 0; i < ixp_sesnum; i++) {
18600+ ixp = ixp_sessions[i];
18601+ if (ixp && ixp->ixp_ctx_id == ctx_id)
18602+ break;
18603+ }
18604+ if (i >= ixp_sesnum) {
18605+ printk("ixp: invalid context id %d\n", ctx_id);
18606+ return;
18607+ }
18608+
18609+ if (IX_CRYPTO_ACC_STATUS_WAIT == status) {
18610+ /* this is normal to free the first of two buffers */
18611+ dprintk("ixp: register not finished yet.\n");
18612+ return;
18613+ }
18614+
18615+ if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
18616+ printk("ixp: register failed 0x%x\n", status);
18617+ while (!list_empty(&ixp->ixp_q)) {
18618+ q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
18619+ list_del(&q->ixp_q_list);
18620+ q->ixp_q_crp->crp_etype = EINVAL;
18621+ crypto_done(q->ixp_q_crp);
18622+ kmem_cache_free(qcache, q);
18623+ }
18624+ return;
18625+ }
18626+
18627+ /*
18628+ * we are now registered, we cannot start processing the Q here
18629+ * or we get strange errors with AES (DES/3DES seem to be ok).
18630+ */
18631+ ixp->ixp_registered = 1;
18632+ schedule_work(&ixp->ixp_pending_work);
18633+}
18634+
18635+
18636+/*
18637+ * callback for when data processing is complete
18638+ */
18639+
18640+static void
18641+ixp_perform_cb(
18642+ UINT32 ctx_id,
18643+ IX_MBUF *sbufp,
18644+ IX_MBUF *dbufp,
18645+ IxCryptoAccStatus status)
18646+{
18647+ struct ixp_q *q;
18648+
18649+ dprintk("%s(%d, %p, %p, 0x%x)\n", __FUNCTION__, ctx_id, sbufp,
18650+ dbufp, status);
18651+
18652+ if (sbufp == NULL) {
18653+ printk("ixp: NULL sbuf in ixp_perform_cb\n");
18654+ return;
18655+ }
18656+
18657+ q = IX_MBUF_PRIV(sbufp);
18658+ if (q == NULL) {
18659+ printk("ixp: NULL priv in ixp_perform_cb\n");
18660+ return;
18661+ }
18662+
18663+ if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
18664+ printk("ixp: perform failed status=%d\n", status);
18665+ q->ixp_q_crp->crp_etype = EINVAL;
18666+ }
18667+
18668+ crypto_done(q->ixp_q_crp);
18669+ kmem_cache_free(qcache, q);
18670+}
18671+
18672+
18673+/*
18674+ * registration is not callable at IRQ time, so we defer
18675+ * to a task queue, this routines completes the registration for us
18676+ * when the task queue runs
18677+ *
18678+ * Unfortunately this means we cannot tell OCF that the driver is blocked,
18679+ * we do that on the next request.
18680+ */
18681+
18682+static void
18683+ixp_registration(void *arg)
18684+{
18685+ struct ixp_data *ixp = arg;
18686+ struct ixp_q *q = NULL;
18687+ IX_MBUF *pri = NULL, *sec = NULL;
18688+ int status = IX_CRYPTO_ACC_STATUS_SUCCESS;
18689+
18690+ if (!ixp) {
18691+ printk("ixp: ixp_registration with no arg\n");
18692+ return;
18693+ }
18694+
18695+ if (ixp->ixp_ctx_id != -1) {
18696+ ixCryptoAccCtxUnregister(ixp->ixp_ctx_id);
18697+ ixp->ixp_ctx_id = -1;
18698+ }
18699+
18700+ if (list_empty(&ixp->ixp_q)) {
18701+ printk("ixp: ixp_registration with no Q\n");
18702+ return;
18703+ }
18704+
18705+ /*
18706+ * setup the primary and secondary buffers
18707+ */
18708+ q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
18709+ if (q->ixp_q_acrd) {
18710+ pri = &ixp->ixp_pri_mbuf;
18711+ sec = &ixp->ixp_sec_mbuf;
18712+ IX_MBUF_MLEN(pri) = IX_MBUF_PKT_LEN(pri) = 128;
18713+ IX_MBUF_MDATA(pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
18714+ IX_MBUF_MLEN(sec) = IX_MBUF_PKT_LEN(sec) = 128;
18715+ IX_MBUF_MDATA(sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
18716+ }
18717+
18718+ /* Only need to register if a crypt op or HMAC op */
18719+ if (!(ixp->ixp_auth_alg == CRYPTO_SHA1 ||
18720+ ixp->ixp_auth_alg == CRYPTO_MD5)) {
18721+ status = ixCryptoAccCtxRegister(
18722+ &ixp->ixp_ctx,
18723+ pri, sec,
18724+ ixp_register_cb,
18725+ ixp_perform_cb,
18726+ &ixp->ixp_ctx_id);
18727+ }
18728+ else {
18729+ /* Otherwise we start processing pending q */
18730+ schedule_work(&ixp->ixp_pending_work);
18731+ }
18732+
18733+ if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
18734+ return;
18735+
18736+ if (IX_CRYPTO_ACC_STATUS_EXCEED_MAX_TUNNELS == status) {
18737+ printk("ixp: ixCryptoAccCtxRegister failed (out of tunnels)\n");
18738+ ixp_blocked = 1;
18739+ /* perhaps we should return EGAIN on queued ops ? */
18740+ return;
18741+ }
18742+
18743+ printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
18744+ ixp->ixp_ctx_id = -1;
18745+
18746+ /*
18747+ * everything waiting is toasted
18748+ */
18749+ while (!list_empty(&ixp->ixp_q)) {
18750+ q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
18751+ list_del(&q->ixp_q_list);
18752+ q->ixp_q_crp->crp_etype = ENOENT;
18753+ crypto_done(q->ixp_q_crp);
18754+ kmem_cache_free(qcache, q);
18755+ }
18756+}
18757+
18758+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
18759+static void
18760+ixp_registration_wq(struct work_struct *work)
18761+{
18762+ struct ixp_data *ixp = container_of(work, struct ixp_data,
18763+ ixp_registration_work);
18764+ ixp_registration(ixp);
18765+}
18766+#endif
18767+
18768+/*
18769+ * Process a request.
18770+ */
18771+static int
18772+ixp_process(device_t dev, struct cryptop *crp, int hint)
18773+{
18774+ struct ixp_data *ixp;
18775+ unsigned int lid;
18776+ struct ixp_q *q = NULL;
18777+ int status;
18778+
18779+ dprintk("%s()\n", __FUNCTION__);
18780+
18781+ /* Sanity check */
18782+ if (crp == NULL) {
18783+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
18784+ return EINVAL;
18785+ }
18786+
18787+ crp->crp_etype = 0;
18788+
18789+ if (ixp_blocked)
18790+ return ERESTART;
18791+
18792+ if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
18793+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
18794+ crp->crp_etype = EINVAL;
18795+ goto done;
18796+ }
18797+
18798+ /*
18799+ * find the session we are using
18800+ */
18801+
18802+ lid = crp->crp_sid & 0xffffffff;
18803+ if (lid >= ixp_sesnum || lid == 0 || ixp_sessions == NULL ||
18804+ ixp_sessions[lid] == NULL) {
18805+ crp->crp_etype = ENOENT;
18806+ dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
18807+ goto done;
18808+ }
18809+ ixp = ixp_sessions[lid];
18810+
18811+ /*
18812+ * setup a new request ready for queuing
18813+ */
18814+ q = kmem_cache_alloc(qcache, SLAB_ATOMIC);
18815+ if (q == NULL) {
18816+ dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
18817+ crp->crp_etype = ENOMEM;
18818+ goto done;
18819+ }
18820+ /*
18821+ * save some cycles by only zeroing the important bits
18822+ */
18823+ memset(&q->ixp_q_mbuf, 0, sizeof(q->ixp_q_mbuf));
18824+ q->ixp_q_ccrd = NULL;
18825+ q->ixp_q_acrd = NULL;
18826+ q->ixp_q_crp = crp;
18827+ q->ixp_q_data = ixp;
18828+
18829+ /*
18830+ * point the cipher and auth descriptors appropriately
18831+ * check that we have something to do
18832+ */
18833+ if (crp->crp_desc->crd_alg == ixp->ixp_cipher_alg)
18834+ q->ixp_q_ccrd = crp->crp_desc;
18835+ else if (crp->crp_desc->crd_alg == ixp->ixp_auth_alg)
18836+ q->ixp_q_acrd = crp->crp_desc;
18837+ else {
18838+ crp->crp_etype = ENOENT;
18839+ dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
18840+ goto done;
18841+ }
18842+ if (crp->crp_desc->crd_next) {
18843+ if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_cipher_alg)
18844+ q->ixp_q_ccrd = crp->crp_desc->crd_next;
18845+ else if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_auth_alg)
18846+ q->ixp_q_acrd = crp->crp_desc->crd_next;
18847+ else {
18848+ crp->crp_etype = ENOENT;
18849+ dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
18850+ goto done;
18851+ }
18852+ }
18853+
18854+ /*
18855+ * If there is a direction change for this context then we mark it as
18856+ * unregistered and re-register is for the new direction. This is not
18857+ * a very expensive operation and currently only tends to happen when
18858+ * user-space application are doing benchmarks
18859+ *
18860+ * DM - we should be checking for pending requests before unregistering.
18861+ */
18862+ if (q->ixp_q_ccrd && ixp->ixp_registered &&
18863+ ixp->ixp_crd_flags != (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT)) {
18864+ dprintk("%s - detected direction change on session\n", __FUNCTION__);
18865+ ixp->ixp_registered = 0;
18866+ }
18867+
18868+ /*
18869+ * if we are registered, call straight into the perform code
18870+ */
18871+ if (ixp->ixp_registered) {
18872+ ixp_q_process(q);
18873+ return 0;
18874+ }
18875+
18876+ /*
18877+ * the only part of the context not set in newsession is the direction
18878+ * dependent parts
18879+ */
18880+ if (q->ixp_q_ccrd) {
18881+ ixp->ixp_crd_flags = (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT);
18882+ if (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT) {
18883+ ixp->ixp_ctx.operation = q->ixp_q_acrd ?
18884+ IX_CRYPTO_ACC_OP_ENCRYPT_AUTH : IX_CRYPTO_ACC_OP_ENCRYPT;
18885+ } else {
18886+ ixp->ixp_ctx.operation = q->ixp_q_acrd ?
18887+ IX_CRYPTO_ACC_OP_AUTH_DECRYPT : IX_CRYPTO_ACC_OP_DECRYPT;
18888+ }
18889+ } else {
18890+ /* q->ixp_q_acrd must be set if we are here */
18891+ ixp->ixp_ctx.operation = IX_CRYPTO_ACC_OP_AUTH_CALC;
18892+ }
18893+
18894+ status = list_empty(&ixp->ixp_q);
18895+ list_add_tail(&q->ixp_q_list, &ixp->ixp_q);
18896+ if (status)
18897+ schedule_work(&ixp->ixp_registration_work);
18898+ return 0;
18899+
18900+done:
18901+ if (q)
18902+ kmem_cache_free(qcache, q);
18903+ crypto_done(crp);
18904+ return 0;
18905+}
18906+
18907+
18908+#ifdef __ixp46X
18909+/*
18910+ * key processing support for the ixp465
18911+ */
18912+
18913+
18914+/*
18915+ * copy a BN (LE) into a buffer (BE) an fill out the op appropriately
18916+ * assume zeroed and only copy bits that are significant
18917+ */
18918+
18919+static int
18920+ixp_copy_ibuf(struct crparam *p, IxCryptoAccPkeEauOperand *op, UINT32 *buf)
18921+{
18922+ unsigned char *src = (unsigned char *) p->crp_p;
18923+ unsigned char *dst;
18924+ int len, bits = p->crp_nbits;
18925+
18926+ dprintk("%s()\n", __FUNCTION__);
18927+
18928+ if (bits > MAX_IOP_SIZE * sizeof(UINT32) * 8) {
18929+ dprintk("%s - ibuf too big (%d > %d)\n", __FUNCTION__,
18930+ bits, MAX_IOP_SIZE * sizeof(UINT32) * 8);
18931+ return -1;
18932+ }
18933+
18934+ len = (bits + 31) / 32; /* the number UINT32's needed */
18935+
18936+ dst = (unsigned char *) &buf[len];
18937+ dst--;
18938+
18939+ while (bits > 0) {
18940+ *dst-- = *src++;
18941+ bits -= 8;
18942+ }
18943+
18944+#if 0 /* no need to zero remaining bits as it is done during request alloc */
18945+ while (dst > (unsigned char *) buf)
18946+ *dst-- = '\0';
18947+#endif
18948+
18949+ op->pData = buf;
18950+ op->dataLen = len;
18951+ return 0;
18952+}
18953+
18954+/*
18955+ * copy out the result, be as forgiving as we can about small output buffers
18956+ */
18957+
18958+static int
18959+ixp_copy_obuf(struct crparam *p, IxCryptoAccPkeEauOpResult *op, UINT32 *buf)
18960+{
18961+ unsigned char *dst = (unsigned char *) p->crp_p;
18962+ unsigned char *src = (unsigned char *) buf;
18963+ int len, z, bits = p->crp_nbits;
18964+
18965+ dprintk("%s()\n", __FUNCTION__);
18966+
18967+ len = op->dataLen * sizeof(UINT32);
18968+
18969+ /* skip leading zeroes to be small buffer friendly */
18970+ z = 0;
18971+ while (z < len && src[z] == '\0')
18972+ z++;
18973+
18974+ src += len;
18975+ src--;
18976+ len -= z;
18977+
18978+ while (len > 0 && bits > 0) {
18979+ *dst++ = *src--;
18980+ len--;
18981+ bits -= 8;
18982+ }
18983+
18984+ while (bits > 0) {
18985+ *dst++ = '\0';
18986+ bits -= 8;
18987+ }
18988+
18989+ if (len > 0) {
18990+ dprintk("%s - obuf is %d (z=%d, ob=%d) bytes too small\n",
18991+ __FUNCTION__, len, z, p->crp_nbits / 8);
18992+ return -1;
18993+ }
18994+
18995+ return 0;
18996+}
18997+
18998+
18999+/*
19000+ * the parameter offsets for exp_mod
19001+ */
19002+
19003+#define IXP_PARAM_BASE 0
19004+#define IXP_PARAM_EXP 1
19005+#define IXP_PARAM_MOD 2
19006+#define IXP_PARAM_RES 3
19007+
19008+/*
19009+ * key processing complete callback, is also used to start processing
19010+ * by passing a NULL for pResult
19011+ */
19012+
19013+static void
19014+ixp_kperform_cb(
19015+ IxCryptoAccPkeEauOperation operation,
19016+ IxCryptoAccPkeEauOpResult *pResult,
19017+ BOOL carryOrBorrow,
19018+ IxCryptoAccStatus status)
19019+{
19020+ struct ixp_pkq *q, *tmp;
19021+ unsigned long flags;
19022+
19023+ dprintk("%s(0x%x, %p, %d, 0x%x)\n", __FUNCTION__, operation, pResult,
19024+ carryOrBorrow, status);
19025+
19026+ /* handle a completed request */
19027+ if (pResult) {
19028+ if (ixp_pk_cur && &ixp_pk_cur->pkq_result == pResult) {
19029+ q = ixp_pk_cur;
19030+ if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
19031+ dprintk("%s() - op failed 0x%x\n", __FUNCTION__, status);
19032+ q->pkq_krp->krp_status = ERANGE; /* could do better */
19033+ } else {
19034+ /* copy out the result */
19035+ if (ixp_copy_obuf(&q->pkq_krp->krp_param[IXP_PARAM_RES],
19036+ &q->pkq_result, q->pkq_obuf))
19037+ q->pkq_krp->krp_status = ERANGE;
19038+ }
19039+ crypto_kdone(q->pkq_krp);
19040+ kfree(q);
19041+ ixp_pk_cur = NULL;
19042+ } else
19043+ printk("%s - callback with invalid result pointer\n", __FUNCTION__);
19044+ }
19045+
19046+ spin_lock_irqsave(&ixp_pkq_lock, flags);
19047+ if (ixp_pk_cur || list_empty(&ixp_pkq)) {
19048+ spin_unlock_irqrestore(&ixp_pkq_lock, flags);
19049+ return;
19050+ }
19051+
19052+ list_for_each_entry_safe(q, tmp, &ixp_pkq, pkq_list) {
19053+
19054+ list_del(&q->pkq_list);
19055+ ixp_pk_cur = q;
19056+
19057+ spin_unlock_irqrestore(&ixp_pkq_lock, flags);
19058+
19059+ status = ixCryptoAccPkeEauPerform(
19060+ IX_CRYPTO_ACC_OP_EAU_MOD_EXP,
19061+ &q->pkq_op,
19062+ ixp_kperform_cb,
19063+ &q->pkq_result);
19064+
19065+ if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
19066+ dprintk("%s() - ixCryptoAccPkeEauPerform SUCCESS\n", __FUNCTION__);
19067+ return; /* callback will return here for callback */
19068+ } else if (status == IX_CRYPTO_ACC_STATUS_RETRY) {
19069+ printk("%s() - ixCryptoAccPkeEauPerform RETRY\n", __FUNCTION__);
19070+ } else {
19071+ printk("%s() - ixCryptoAccPkeEauPerform failed %d\n",
19072+ __FUNCTION__, status);
19073+ }
19074+ q->pkq_krp->krp_status = ERANGE; /* could do better */
19075+ crypto_kdone(q->pkq_krp);
19076+ kfree(q);
19077+ spin_lock_irqsave(&ixp_pkq_lock, flags);
19078+ }
19079+ spin_unlock_irqrestore(&ixp_pkq_lock, flags);
19080+}
19081+
19082+
19083+static int
19084+ixp_kprocess(device_t dev, struct cryptkop *krp, int hint)
19085+{
19086+ struct ixp_pkq *q;
19087+ int rc = 0;
19088+ unsigned long flags;
19089+
19090+ dprintk("%s l1=%d l2=%d l3=%d l4=%d\n", __FUNCTION__,
19091+ krp->krp_param[IXP_PARAM_BASE].crp_nbits,
19092+ krp->krp_param[IXP_PARAM_EXP].crp_nbits,
19093+ krp->krp_param[IXP_PARAM_MOD].crp_nbits,
19094+ krp->krp_param[IXP_PARAM_RES].crp_nbits);
19095+
19096+
19097+ if (krp->krp_op != CRK_MOD_EXP) {
19098+ krp->krp_status = EOPNOTSUPP;
19099+ goto err;
19100+ }
19101+
19102+ q = (struct ixp_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
19103+ if (q == NULL) {
19104+ krp->krp_status = ENOMEM;
19105+ goto err;
19106+ }
19107+
19108+ /*
19109+ * The PKE engine does not appear to zero the output buffer
19110+ * appropriately, so we need to do it all here.
19111+ */
19112+ memset(q, 0, sizeof(*q));
19113+
19114+ q->pkq_krp = krp;
19115+ INIT_LIST_HEAD(&q->pkq_list);
19116+
19117+ if (ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_BASE], &q->pkq_op.modExpOpr.M,
19118+ q->pkq_ibuf0))
19119+ rc = 1;
19120+ if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_EXP],
19121+ &q->pkq_op.modExpOpr.e, q->pkq_ibuf1))
19122+ rc = 2;
19123+ if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_MOD],
19124+ &q->pkq_op.modExpOpr.N, q->pkq_ibuf2))
19125+ rc = 3;
19126+
19127+ if (rc) {
19128+ kfree(q);
19129+ krp->krp_status = ERANGE;
19130+ goto err;
19131+ }
19132+
19133+ q->pkq_result.pData = q->pkq_obuf;
19134+ q->pkq_result.dataLen =
19135+ (krp->krp_param[IXP_PARAM_RES].crp_nbits + 31) / 32;
19136+
19137+ spin_lock_irqsave(&ixp_pkq_lock, flags);
19138+ list_add_tail(&q->pkq_list, &ixp_pkq);
19139+ spin_unlock_irqrestore(&ixp_pkq_lock, flags);
19140+
19141+ if (!ixp_pk_cur)
19142+ ixp_kperform_cb(0, NULL, 0, 0);
19143+ return (0);
19144+
19145+err:
19146+ crypto_kdone(krp);
19147+ return (0);
19148+}
19149+
19150+
19151+
19152+#ifdef CONFIG_OCF_RANDOMHARVEST
19153+/*
19154+ * We run the random number generator output through SHA so that it
19155+ * is FIPS compliant.
19156+ */
19157+
19158+static volatile int sha_done = 0;
19159+static unsigned char sha_digest[20];
19160+
19161+static void
19162+ixp_hash_cb(UINT8 *digest, IxCryptoAccStatus status)
19163+{
19164+ dprintk("%s(%p, %d)\n", __FUNCTION__, digest, status);
19165+ if (sha_digest != digest)
19166+ printk("digest error\n");
19167+ if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
19168+ sha_done = 1;
19169+ else
19170+ sha_done = -status;
19171+}
19172+
19173+static int
19174+ixp_read_random(void *arg, u_int32_t *buf, int maxwords)
19175+{
19176+ IxCryptoAccStatus status;
19177+ int i, n, rc;
19178+
19179+ dprintk("%s(%p, %d)\n", __FUNCTION__, buf, maxwords);
19180+ memset(buf, 0, maxwords * sizeof(*buf));
19181+ status = ixCryptoAccPkePseudoRandomNumberGet(maxwords, buf);
19182+ if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
19183+ dprintk("%s: ixCryptoAccPkePseudoRandomNumberGet failed %d\n",
19184+ __FUNCTION__, status);
19185+ return 0;
19186+ }
19187+
19188+ /*
19189+ * run the random data through SHA to make it look more random
19190+ */
19191+
19192+ n = sizeof(sha_digest); /* process digest bytes at a time */
19193+
19194+ rc = 0;
19195+ for (i = 0; i < maxwords; i += n / sizeof(*buf)) {
19196+ if ((maxwords - i) * sizeof(*buf) < n)
19197+ n = (maxwords - i) * sizeof(*buf);
19198+ sha_done = 0;
19199+ status = ixCryptoAccPkeHashPerform(IX_CRYPTO_ACC_AUTH_SHA1,
19200+ (UINT8 *) &buf[i], n, ixp_hash_cb, sha_digest);
19201+ if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
19202+ dprintk("ixCryptoAccPkeHashPerform failed %d\n", status);
19203+ return -EIO;
19204+ }
19205+ while (!sha_done)
19206+ schedule();
19207+ if (sha_done < 0) {
19208+ dprintk("ixCryptoAccPkeHashPerform failed CB %d\n", -sha_done);
19209+ return 0;
19210+ }
19211+ memcpy(&buf[i], sha_digest, n);
19212+ rc += n / sizeof(*buf);;
19213+ }
19214+
19215+ return rc;
19216+}
19217+#endif /* CONFIG_OCF_RANDOMHARVEST */
19218+
19219+#endif /* __ixp46X */
19220+
19221+
19222+
19223+/*
19224+ * our driver startup and shutdown routines
19225+ */
19226+
19227+static int
19228+ixp_init(void)
19229+{
19230+ dprintk("%s(%p)\n", __FUNCTION__, ixp_init);
19231+
19232+ if (ixp_init_crypto && ixCryptoAccInit() != IX_CRYPTO_ACC_STATUS_SUCCESS)
19233+ printk("ixCryptoAccInit failed, assuming already initialised!\n");
19234+
19235+ qcache = kmem_cache_create("ixp4xx_q", sizeof(struct ixp_q), 0,
19236+ SLAB_HWCACHE_ALIGN, NULL
19237+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
19238+ , NULL
19239+#endif
19240+ );
19241+ if (!qcache) {
19242+ printk("failed to create Qcache\n");
19243+ return -ENOENT;
19244+ }
19245+
19246+ memset(&ixpdev, 0, sizeof(ixpdev));
19247+ softc_device_init(&ixpdev, "ixp4xx", 0, ixp_methods);
19248+
19249+ ixp_id = crypto_get_driverid(softc_get_device(&ixpdev),
19250+ CRYPTOCAP_F_HARDWARE);
19251+ if (ixp_id < 0)
19252+ panic("IXP/OCF crypto device cannot initialize!");
19253+
19254+#define REGISTER(alg) \
19255+ crypto_register(ixp_id,alg,0,0)
19256+
19257+ REGISTER(CRYPTO_DES_CBC);
19258+ REGISTER(CRYPTO_3DES_CBC);
19259+ REGISTER(CRYPTO_RIJNDAEL128_CBC);
19260+#ifdef CONFIG_OCF_IXP4XX_SHA1_MD5
19261+ REGISTER(CRYPTO_MD5);
19262+ REGISTER(CRYPTO_SHA1);
19263+#endif
19264+ REGISTER(CRYPTO_MD5_HMAC);
19265+ REGISTER(CRYPTO_SHA1_HMAC);
19266+#undef REGISTER
19267+
19268+#ifdef __ixp46X
19269+ spin_lock_init(&ixp_pkq_lock);
19270+ /*
19271+ * we do not enable the go fast options here as they can potentially
19272+ * allow timing based attacks
19273+ *
19274+ * http://www.openssl.org/news/secadv_20030219.txt
19275+ */
19276+ ixCryptoAccPkeEauExpConfig(0, 0);
19277+ crypto_kregister(ixp_id, CRK_MOD_EXP, 0);
19278+#ifdef CONFIG_OCF_RANDOMHARVEST
19279+ crypto_rregister(ixp_id, ixp_read_random, NULL);
19280+#endif
19281+#endif
19282+
19283+ return 0;
19284+}
19285+
19286+static void
19287+ixp_exit(void)
19288+{
19289+ dprintk("%s()\n", __FUNCTION__);
19290+ crypto_unregister_all(ixp_id);
19291+ ixp_id = -1;
19292+ kmem_cache_destroy(qcache);
19293+ qcache = NULL;
19294+}
19295+
19296+module_init(ixp_init);
19297+module_exit(ixp_exit);
19298+
19299+MODULE_LICENSE("Dual BSD/GPL");
19300+MODULE_AUTHOR("David McCullough <dmccullough@cyberguard.com>");
19301+MODULE_DESCRIPTION("ixp (OCF module for IXP4xx crypto)");
19302diff --git a/crypto/ocf/kirkwood/Makefile b/crypto/ocf/kirkwood/Makefile
19303new file mode 100644
19304index 0000000..6dafd00
19305--- /dev/null
19306+++ b/crypto/ocf/kirkwood/Makefile
19307@@ -0,0 +1,19 @@
19308+# for SGlinux builds
19309+-include $(ROOTDIR)/modules/.config
19310+
19311+obj-$(CONFIG_OCF_KIRKWOOD) += mv_cesa.o
19312+
19313+mv_cesa-y := cesa/mvCesa.o cesa/mvLru.o cesa/mvMD5.o cesa/mvSHA1.o cesa/AES/mvAesAlg.o cesa/AES/mvAesApi.o cesa/mvCesaDebug.o cesa_ocf_drv.o
19314+
19315+# Extra objects required by the CESA driver
19316+mv_cesa-y += mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.o mvHal/kw_family/boardEnv/mvBoardEnvLib.o mvHal/mv_hal/twsi/mvTwsi.o mvHal/kw_family/ctrlEnv/sys/mvCpuIf.o mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.o mvHal/kw_family/ctrlEnv/sys/mvSysDram.o mvHal/linux_oss/mvOs.o mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.o mvHal/mv_hal/gpp/mvGpp.o mvHal/kw_family/ctrlEnv/sys/mvSysPex.o mvHal/mv_hal/pex/mvPex.o mvHal/kw_family/boardEnv/mvBoardEnvSpec.o mvHal/common/mvCommon.o mvHal/common/mvDebug.o mvHal/kw_family/ctrlEnv/sys/mvSysCesa.o
19317+
19318+ifdef src
19319+EXTRA_CFLAGS += -I$(src)/.. -I$(src)/cesa -I$(src)/mvHal -I$(src)/mvHal/common -I$(src)/mvHal/kw_family -I$(src)/mvHal/mv_hal -I$(src)/mvHal/linux_oss -I$(src)
19320+endif
19321+
19322+EXTRA_CFLAGS += -DMV_LINUX -DMV_CPU_LE -DMV_ARM -DMV_INCLUDE_CESA -DMV_INCLUDE_PEX -DMV_CACHE_COHERENCY=3
19323+ifdef TOPDIR
19324+-include $(TOPDIR)/Rules.make
19325+endif
19326+
19327diff --git a/crypto/ocf/kirkwood/cesa/AES/mvAes.h b/crypto/ocf/kirkwood/cesa/AES/mvAes.h
19328new file mode 100644
19329index 0000000..969727f
19330--- /dev/null
19331+++ b/crypto/ocf/kirkwood/cesa/AES/mvAes.h
19332@@ -0,0 +1,62 @@
19333+/* mvAes.h v2.0 August '99
19334+ * Reference ANSI C code
19335+ */
19336+
19337+/* AES Cipher header file for ANSI C Submissions
19338+ Lawrence E. Bassham III
19339+ Computer Security Division
19340+ National Institute of Standards and Technology
19341+
19342+ April 15, 1998
19343+
19344+ This sample is to assist implementers developing to the Cryptographic
19345+API Profile for AES Candidate Algorithm Submissions. Please consult this
19346+document as a cross-reference.
19347+
19348+ ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE
19349+MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH
19350+THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS CANNOT
19351+BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO INCLUDE
19352+IMPLEMENTATION SPECIFIC INFORMATION.
19353+*/
19354+
19355+/* Includes:
19356+ Standard include files
19357+*/
19358+
19359+#include "mvOs.h"
19360+
19361+
19362+/* Error Codes - CHANGE POSSIBLE: inclusion of additional error codes */
19363+
19364+/* Key direction is invalid, e.g., unknown value */
19365+#define AES_BAD_KEY_DIR -1
19366+
19367+/* Key material not of correct length */
19368+#define AES_BAD_KEY_MAT -2
19369+
19370+/* Key passed is not valid */
19371+#define AES_BAD_KEY_INSTANCE -3
19372+
19373+/* Params struct passed to cipherInit invalid */
19374+#define AES_BAD_CIPHER_MODE -4
19375+
19376+/* Cipher in wrong state (e.g., not initialized) */
19377+#define AES_BAD_CIPHER_STATE -5
19378+
19379+#define AES_BAD_CIPHER_INSTANCE -7
19380+
19381+
19382+/* Function protoypes */
19383+/* CHANGED: makeKey(): parameter blockLen added
19384+ this parameter is absolutely necessary if you want to
19385+ setup the round keys in a variable block length setting
19386+ cipherInit(): parameter blockLen added (for obvious reasons)
19387+ */
19388+int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen);
19389+int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
19390+ MV_U32 *plain, int numBlocks, MV_U32 *cipher);
19391+int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
19392+ MV_U32 *plain, int numBlocks, MV_U32 *cipher);
19393+
19394+
19395diff --git a/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c b/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c
19396new file mode 100644
19397index 0000000..2f57e4f
19398--- /dev/null
19399+++ b/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c
19400@@ -0,0 +1,317 @@
19401+/* rijndael-alg-ref.c v2.0 August '99
19402+ * Reference ANSI C code
19403+ * authors: Paulo Barreto
19404+ * Vincent Rijmen, K.U.Leuven
19405+ *
19406+ * This code is placed in the public domain.
19407+ */
19408+
19409+#include "mvOs.h"
19410+
19411+#include "mvAesAlg.h"
19412+
19413+#include "mvAesBoxes.dat"
19414+
19415+
19416+MV_U8 mul1(MV_U8 aa, MV_U8 bb);
19417+void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC);
19418+void ShiftRow128Enc(MV_U8 a[4][MAXBC]);
19419+void ShiftRow128Dec(MV_U8 a[4][MAXBC]);
19420+void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]);
19421+void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]);
19422+void InvMixColumn(MV_U8 a[4][MAXBC]);
19423+
19424+
19425+#define mul(aa, bb) (mask[bb] & Alogtable[aa + Logtable[bb]])
19426+
19427+MV_U8 mul1(MV_U8 aa, MV_U8 bb)
19428+{
19429+ return mask[bb] & Alogtable[aa + Logtable[bb]];
19430+}
19431+
19432+
19433+void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC)
19434+{
19435+ /* Exor corresponding text input and round key input bytes
19436+ */
19437+ ((MV_U32*)(&(a[0][0])))[0] ^= ((MV_U32*)(&(rk[0][0])))[0];
19438+ ((MV_U32*)(&(a[1][0])))[0] ^= ((MV_U32*)(&(rk[1][0])))[0];
19439+ ((MV_U32*)(&(a[2][0])))[0] ^= ((MV_U32*)(&(rk[2][0])))[0];
19440+ ((MV_U32*)(&(a[3][0])))[0] ^= ((MV_U32*)(&(rk[3][0])))[0];
19441+
19442+}
19443+
19444+void ShiftRow128Enc(MV_U8 a[4][MAXBC]) {
19445+ /* Row 0 remains unchanged
19446+ * The other three rows are shifted a variable amount
19447+ */
19448+ MV_U8 tmp[MAXBC];
19449+
19450+ tmp[0] = a[1][1];
19451+ tmp[1] = a[1][2];
19452+ tmp[2] = a[1][3];
19453+ tmp[3] = a[1][0];
19454+
19455+ ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
19456+ /*
19457+ a[1][0] = tmp[0];
19458+ a[1][1] = tmp[1];
19459+ a[1][2] = tmp[2];
19460+ a[1][3] = tmp[3];
19461+ */
19462+ tmp[0] = a[2][2];
19463+ tmp[1] = a[2][3];
19464+ tmp[2] = a[2][0];
19465+ tmp[3] = a[2][1];
19466+
19467+ ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
19468+ /*
19469+ a[2][0] = tmp[0];
19470+ a[2][1] = tmp[1];
19471+ a[2][2] = tmp[2];
19472+ a[2][3] = tmp[3];
19473+ */
19474+ tmp[0] = a[3][3];
19475+ tmp[1] = a[3][0];
19476+ tmp[2] = a[3][1];
19477+ tmp[3] = a[3][2];
19478+
19479+ ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
19480+ /*
19481+ a[3][0] = tmp[0];
19482+ a[3][1] = tmp[1];
19483+ a[3][2] = tmp[2];
19484+ a[3][3] = tmp[3];
19485+ */
19486+}
19487+
19488+void ShiftRow128Dec(MV_U8 a[4][MAXBC]) {
19489+ /* Row 0 remains unchanged
19490+ * The other three rows are shifted a variable amount
19491+ */
19492+ MV_U8 tmp[MAXBC];
19493+
19494+ tmp[0] = a[1][3];
19495+ tmp[1] = a[1][0];
19496+ tmp[2] = a[1][1];
19497+ tmp[3] = a[1][2];
19498+
19499+ ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
19500+ /*
19501+ a[1][0] = tmp[0];
19502+ a[1][1] = tmp[1];
19503+ a[1][2] = tmp[2];
19504+ a[1][3] = tmp[3];
19505+ */
19506+
19507+ tmp[0] = a[2][2];
19508+ tmp[1] = a[2][3];
19509+ tmp[2] = a[2][0];
19510+ tmp[3] = a[2][1];
19511+
19512+ ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
19513+ /*
19514+ a[2][0] = tmp[0];
19515+ a[2][1] = tmp[1];
19516+ a[2][2] = tmp[2];
19517+ a[2][3] = tmp[3];
19518+ */
19519+
19520+ tmp[0] = a[3][1];
19521+ tmp[1] = a[3][2];
19522+ tmp[2] = a[3][3];
19523+ tmp[3] = a[3][0];
19524+
19525+ ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
19526+ /*
19527+ a[3][0] = tmp[0];
19528+ a[3][1] = tmp[1];
19529+ a[3][2] = tmp[2];
19530+ a[3][3] = tmp[3];
19531+ */
19532+}
19533+
19534+void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]) {
19535+ /* Replace every byte of the input by the byte at that place
19536+ * in the nonlinear S-box
19537+ */
19538+ int i, j;
19539+
19540+ for(i = 0; i < 4; i++)
19541+ for(j = 0; j < 4; j++) a[i][j] = box[a[i][j]] ;
19542+}
19543+
19544+void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]) {
19545+ /* Mix the four bytes of every column in a linear way
19546+ */
19547+ MV_U8 b[4][MAXBC];
19548+ int i, j;
19549+
19550+ for(j = 0; j < 4; j++){
19551+ b[0][j] = mul(25,a[0][j]) ^ mul(1,a[1][j]) ^ a[2][j] ^ a[3][j];
19552+ b[1][j] = mul(25,a[1][j]) ^ mul(1,a[2][j]) ^ a[3][j] ^ a[0][j];
19553+ b[2][j] = mul(25,a[2][j]) ^ mul(1,a[3][j]) ^ a[0][j] ^ a[1][j];
19554+ b[3][j] = mul(25,a[3][j]) ^ mul(1,a[0][j]) ^ a[1][j] ^ a[2][j];
19555+ }
19556+ for(i = 0; i < 4; i++)
19557+ /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
19558+ ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0] ^ ((MV_U32*)(&(rk[i][0])))[0];;
19559+}
19560+
19561+void InvMixColumn(MV_U8 a[4][MAXBC]) {
19562+ /* Mix the four bytes of every column in a linear way
19563+ * This is the opposite operation of Mixcolumn
19564+ */
19565+ MV_U8 b[4][MAXBC];
19566+ int i, j;
19567+
19568+ for(j = 0; j < 4; j++){
19569+ b[0][j] = mul(223,a[0][j]) ^ mul(104,a[1][j]) ^ mul(238,a[2][j]) ^ mul(199,a[3][j]);
19570+ b[1][j] = mul(223,a[1][j]) ^ mul(104,a[2][j]) ^ mul(238,a[3][j]) ^ mul(199,a[0][j]);
19571+ b[2][j] = mul(223,a[2][j]) ^ mul(104,a[3][j]) ^ mul(238,a[0][j]) ^ mul(199,a[1][j]);
19572+ b[3][j] = mul(223,a[3][j]) ^ mul(104,a[0][j]) ^ mul(238,a[1][j]) ^ mul(199,a[2][j]);
19573+ }
19574+ for(i = 0; i < 4; i++)
19575+ /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
19576+ ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0];
19577+}
19578+
19579+int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 W[MAXROUNDS+1][4][MAXBC])
19580+{
19581+ /* Calculate the necessary round keys
19582+ * The number of calculations depends on keyBits and blockBits
19583+ */
19584+ int KC, BC, ROUNDS;
19585+ int i, j, t, rconpointer = 0;
19586+ MV_U8 tk[4][MAXKC];
19587+
19588+ switch (keyBits) {
19589+ case 128: KC = 4; break;
19590+ case 192: KC = 6; break;
19591+ case 256: KC = 8; break;
19592+ default : return (-1);
19593+ }
19594+
19595+ switch (blockBits) {
19596+ case 128: BC = 4; break;
19597+ case 192: BC = 6; break;
19598+ case 256: BC = 8; break;
19599+ default : return (-2);
19600+ }
19601+
19602+ switch (keyBits >= blockBits ? keyBits : blockBits) {
19603+ case 128: ROUNDS = 10; break;
19604+ case 192: ROUNDS = 12; break;
19605+ case 256: ROUNDS = 14; break;
19606+ default : return (-3); /* this cannot happen */
19607+ }
19608+
19609+
19610+ for(j = 0; j < KC; j++)
19611+ for(i = 0; i < 4; i++)
19612+ tk[i][j] = k[i][j];
19613+ t = 0;
19614+ /* copy values into round key array */
19615+ for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
19616+ for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
19617+
19618+ while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
19619+ /* calculate new values */
19620+ for(i = 0; i < 4; i++)
19621+ tk[i][0] ^= S[tk[(i+1)%4][KC-1]];
19622+ tk[0][0] ^= rcon[rconpointer++];
19623+
19624+ if (KC != 8)
19625+ for(j = 1; j < KC; j++)
19626+ for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
19627+ else {
19628+ for(j = 1; j < KC/2; j++)
19629+ for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
19630+ for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]];
19631+ for(j = KC/2 + 1; j < KC; j++)
19632+ for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
19633+ }
19634+ /* copy values into round key array */
19635+ for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
19636+ for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
19637+ }
19638+
19639+ return 0;
19640+}
19641+
19642+
19643+
19644+int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
19645+{
19646+ /* Encryption of one block.
19647+ */
19648+ int r, BC, ROUNDS;
19649+
19650+ BC = 4;
19651+ ROUNDS = rounds;
19652+
19653+ /* begin with a key addition
19654+ */
19655+
19656+ KeyAddition(a,rk[0],BC);
19657+
19658+ /* ROUNDS-1 ordinary rounds
19659+ */
19660+ for(r = 1; r < ROUNDS; r++) {
19661+ Substitution(a,S);
19662+ ShiftRow128Enc(a);
19663+ MixColumn(a, rk[r]);
19664+ /*KeyAddition(a,rk[r],BC);*/
19665+ }
19666+
19667+ /* Last round is special: there is no MixColumn
19668+ */
19669+ Substitution(a,S);
19670+ ShiftRow128Enc(a);
19671+ KeyAddition(a,rk[ROUNDS],BC);
19672+
19673+ return 0;
19674+}
19675+
19676+
19677+int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
19678+{
19679+ int r, BC, ROUNDS;
19680+
19681+ BC = 4;
19682+ ROUNDS = rounds;
19683+
19684+ /* To decrypt: apply the inverse operations of the encrypt routine,
19685+ * in opposite order
19686+ *
19687+ * (KeyAddition is an involution: it 's equal to its inverse)
19688+ * (the inverse of Substitution with table S is Substitution with the inverse table of S)
19689+ * (the inverse of Shiftrow is Shiftrow over a suitable distance)
19690+ */
19691+
19692+ /* First the special round:
19693+ * without InvMixColumn
19694+ * with extra KeyAddition
19695+ */
19696+ KeyAddition(a,rk[ROUNDS],BC);
19697+ ShiftRow128Dec(a);
19698+ Substitution(a,Si);
19699+
19700+ /* ROUNDS-1 ordinary rounds
19701+ */
19702+ for(r = ROUNDS-1; r > 0; r--) {
19703+ KeyAddition(a,rk[r],BC);
19704+ InvMixColumn(a);
19705+ ShiftRow128Dec(a);
19706+ Substitution(a,Si);
19707+
19708+ }
19709+
19710+ /* End with the extra key addition
19711+ */
19712+
19713+ KeyAddition(a,rk[0],BC);
19714+
19715+ return 0;
19716+}
19717+
19718diff --git a/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h b/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h
19719new file mode 100644
19720index 0000000..ec81e40
19721--- /dev/null
19722+++ b/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h
19723@@ -0,0 +1,19 @@
19724+/* rijndael-alg-ref.h v2.0 August '99
19725+ * Reference ANSI C code
19726+ * authors: Paulo Barreto
19727+ * Vincent Rijmen, K.U.Leuven
19728+ */
19729+#ifndef __RIJNDAEL_ALG_H
19730+#define __RIJNDAEL_ALG_H
19731+
19732+#define MAXBC (128/32)
19733+#define MAXKC (256/32)
19734+#define MAXROUNDS 14
19735+
19736+
19737+int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 rk[MAXROUNDS+1][4][MAXBC]);
19738+
19739+int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
19740+int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
19741+
19742+#endif /* __RIJNDAEL_ALG_H */
19743diff --git a/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c b/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c
19744new file mode 100644
19745index 0000000..70ae60d
19746--- /dev/null
19747+++ b/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c
19748@@ -0,0 +1,312 @@
19749+/* rijndael-api-ref.c v2.1 April 2000
19750+ * Reference ANSI C code
19751+ * authors: v2.0 Paulo Barreto
19752+ * Vincent Rijmen, K.U.Leuven
19753+ * v2.1 Vincent Rijmen, K.U.Leuven
19754+ *
19755+ * This code is placed in the public domain.
19756+ */
19757+#include "mvOs.h"
19758+
19759+#include "mvAes.h"
19760+#include "mvAesAlg.h"
19761+
19762+
19763+/* Defines:
19764+ Add any additional defines you need
19765+*/
19766+
19767+#define MODE_ECB 1 /* Are we ciphering in ECB mode? */
19768+#define MODE_CBC 2 /* Are we ciphering in CBC mode? */
19769+#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
19770+
19771+
19772+int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen)
19773+{
19774+ MV_U8 W[MAXROUNDS+1][4][MAXBC];
19775+ MV_U8 k[4][MAXKC];
19776+ MV_U8 j;
19777+ int i, rounds, KC;
19778+
19779+ if (expandedKey == NULL)
19780+ {
19781+ return AES_BAD_KEY_INSTANCE;
19782+ }
19783+
19784+ if (!((keyLen == 128) || (keyLen == 192) || (keyLen == 256)))
19785+ {
19786+ return AES_BAD_KEY_MAT;
19787+ }
19788+
19789+ if (keyMaterial == NULL)
19790+ {
19791+ return AES_BAD_KEY_MAT;
19792+ }
19793+
19794+ /* initialize key schedule: */
19795+ for(i=0; i<keyLen/8; i++)
19796+ {
19797+ j = keyMaterial[i];
19798+ k[i % 4][i / 4] = j;
19799+ }
19800+
19801+ rijndaelKeySched (k, keyLen, blockLen, W);
19802+#ifdef MV_AES_DEBUG
19803+ {
19804+ MV_U8* pW = &W[0][0][0];
19805+ int x;
19806+
19807+ mvOsPrintf("Expended Key: size = %d\n", sizeof(W));
19808+ for(i=0; i<sizeof(W); i++)
19809+ {
19810+ mvOsPrintf("%02x ", pW[i]);
19811+ }
19812+ for(i=0; i<MAXROUNDS+1; i++)
19813+ {
19814+ mvOsPrintf("\n Round #%02d: ", i);
19815+ for(x=0; x<MAXBC; x++)
19816+ {
19817+ mvOsPrintf("%02x%02x%02x%02x ",
19818+ W[i][0][x], W[i][1][x], W[i][2][x], W[i][3][x]);
19819+ }
19820+ mvOsPrintf("\n");
19821+ }
19822+ }
19823+#endif /* MV_AES_DEBUG */
19824+ switch (keyLen)
19825+ {
19826+ case 128:
19827+ rounds = 10;
19828+ KC = 4;
19829+ break;
19830+ case 192:
19831+ rounds = 12;
19832+ KC = 6;
19833+ break;
19834+ case 256:
19835+ rounds = 14;
19836+ KC = 8;
19837+ break;
19838+ default :
19839+ return (-1);
19840+ }
19841+
19842+ for(i=0; i<MAXBC; i++)
19843+ {
19844+ for(j=0; j<4; j++)
19845+ {
19846+ expandedKey[i*4+j] = W[rounds][j][i];
19847+ }
19848+ }
19849+ for(; i<KC; i++)
19850+ {
19851+ for(j=0; j<4; j++)
19852+ {
19853+ expandedKey[i*4+j] = W[rounds-1][j][i+MAXBC-KC];
19854+ }
19855+ }
19856+
19857+
19858+ return 0;
19859+}
19860+
19861+int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
19862+ MV_U32 *plain, int numBlocks, MV_U32 *cipher)
19863+{
19864+ int i, j, t;
19865+ MV_U8 block[4][MAXBC];
19866+ int rounds;
19867+ char *input, *outBuffer;
19868+
19869+ input = (char*)plain;
19870+ outBuffer = (char*)cipher;
19871+
19872+ /* check parameter consistency: */
19873+ if( (expandedKey == NULL) || ((keyLen != 128) && (keyLen != 192) && (keyLen != 256)))
19874+ {
19875+ return AES_BAD_KEY_MAT;
19876+ }
19877+ if ((mode != MODE_ECB && mode != MODE_CBC))
19878+ {
19879+ return AES_BAD_CIPHER_STATE;
19880+ }
19881+
19882+ switch (keyLen)
19883+ {
19884+ case 128: rounds = 10; break;
19885+ case 192: rounds = 12; break;
19886+ case 256: rounds = 14; break;
19887+ default : return (-3); /* this cannot happen */
19888+ }
19889+
19890+
19891+ switch (mode)
19892+ {
19893+ case MODE_ECB:
19894+ for (i = 0; i < numBlocks; i++)
19895+ {
19896+ for (j = 0; j < 4; j++)
19897+ {
19898+ for(t = 0; t < 4; t++)
19899+ /* parse input stream into rectangular array */
19900+ block[t][j] = input[16*i+4*j+t] & 0xFF;
19901+ }
19902+ rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
19903+ for (j = 0; j < 4; j++)
19904+ {
19905+ /* parse rectangular array into output ciphertext bytes */
19906+ for(t = 0; t < 4; t++)
19907+ outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
19908+
19909+ }
19910+ }
19911+ break;
19912+
19913+ case MODE_CBC:
19914+ for (j = 0; j < 4; j++)
19915+ {
19916+ for(t = 0; t < 4; t++)
19917+ /* parse initial value into rectangular array */
19918+ block[t][j] = IV[t+4*j] & 0xFF;
19919+ }
19920+ for (i = 0; i < numBlocks; i++)
19921+ {
19922+ for (j = 0; j < 4; j++)
19923+ {
19924+ for(t = 0; t < 4; t++)
19925+ /* parse input stream into rectangular array and exor with
19926+ IV or the previous ciphertext */
19927+ block[t][j] ^= input[16*i+4*j+t] & 0xFF;
19928+ }
19929+ rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
19930+ for (j = 0; j < 4; j++)
19931+ {
19932+ /* parse rectangular array into output ciphertext bytes */
19933+ for(t = 0; t < 4; t++)
19934+ outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
19935+ }
19936+ }
19937+ break;
19938+
19939+ default: return AES_BAD_CIPHER_STATE;
19940+ }
19941+
19942+ return 0;
19943+}
19944+
19945+int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
19946+ MV_U32 *srcData, int numBlocks, MV_U32 *dstData)
19947+{
19948+ int i, j, t;
19949+ MV_U8 block[4][MAXBC];
19950+ MV_U8 iv[4][MAXBC];
19951+ int rounds;
19952+ char *input, *outBuffer;
19953+
19954+ input = (char*)srcData;
19955+ outBuffer = (char*)dstData;
19956+
19957+ if (expandedKey == NULL)
19958+ {
19959+ return AES_BAD_KEY_MAT;
19960+ }
19961+
19962+ /* check parameter consistency: */
19963+ if (keyLen != 128 && keyLen != 192 && keyLen != 256)
19964+ {
19965+ return AES_BAD_KEY_MAT;
19966+ }
19967+ if ((mode != MODE_ECB && mode != MODE_CBC))
19968+ {
19969+ return AES_BAD_CIPHER_STATE;
19970+ }
19971+
19972+ switch (keyLen)
19973+ {
19974+ case 128: rounds = 10; break;
19975+ case 192: rounds = 12; break;
19976+ case 256: rounds = 14; break;
19977+ default : return (-3); /* this cannot happen */
19978+ }
19979+
19980+
19981+ switch (mode)
19982+ {
19983+ case MODE_ECB:
19984+ for (i = 0; i < numBlocks; i++)
19985+ {
19986+ for (j = 0; j < 4; j++)
19987+ {
19988+ for(t = 0; t < 4; t++)
19989+ {
19990+ /* parse input stream into rectangular array */
19991+ block[t][j] = input[16*i+4*j+t] & 0xFF;
19992+ }
19993+ }
19994+ rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
19995+ for (j = 0; j < 4; j++)
19996+ {
19997+ /* parse rectangular array into output ciphertext bytes */
19998+ for(t = 0; t < 4; t++)
19999+ outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
20000+ }
20001+ }
20002+ break;
20003+
20004+ case MODE_CBC:
20005+ /* first block */
20006+ for (j = 0; j < 4; j++)
20007+ {
20008+ for(t = 0; t < 4; t++)
20009+ {
20010+ /* parse input stream into rectangular array */
20011+ block[t][j] = input[4*j+t] & 0xFF;
20012+ iv[t][j] = block[t][j];
20013+ }
20014+ }
20015+ rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
20016+
20017+ for (j = 0; j < 4; j++)
20018+ {
20019+ /* exor the IV and parse rectangular array into output ciphertext bytes */
20020+ for(t = 0; t < 4; t++)
20021+ {
20022+ outBuffer[4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);
20023+ IV[t+4*j] = iv[t][j];
20024+ }
20025+ }
20026+
20027+ /* next blocks */
20028+ for (i = 1; i < numBlocks; i++)
20029+ {
20030+ for (j = 0; j < 4; j++)
20031+ {
20032+ for(t = 0; t < 4; t++)
20033+ {
20034+ /* parse input stream into rectangular array */
20035+ iv[t][j] = input[16*i+4*j+t] & 0xFF;
20036+ block[t][j] = iv[t][j];
20037+ }
20038+ }
20039+ rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
20040+
20041+ for (j = 0; j < 4; j++)
20042+ {
20043+ /* exor previous ciphertext block and parse rectangular array
20044+ into output ciphertext bytes */
20045+ for(t = 0; t < 4; t++)
20046+ {
20047+ outBuffer[16*i+4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);
20048+ IV[t+4*j] = iv[t][j];
20049+ }
20050+ }
20051+ }
20052+ break;
20053+
20054+ default: return AES_BAD_CIPHER_STATE;
20055+ }
20056+
20057+ return 0;
20058+}
20059+
20060+
20061diff --git a/crypto/ocf/kirkwood/cesa/mvCesa.c b/crypto/ocf/kirkwood/cesa/mvCesa.c
20062new file mode 100644
20063index 0000000..e09ad62
20064--- /dev/null
20065+++ b/crypto/ocf/kirkwood/cesa/mvCesa.c
20066@@ -0,0 +1,3126 @@
20067+/*******************************************************************************
20068+Copyright (C) Marvell International Ltd. and its affiliates
20069+
20070+This software file (the "File") is owned and distributed by Marvell
20071+International Ltd. and/or its affiliates ("Marvell") under the following
20072+alternative licensing terms. Once you have made an election to distribute the
20073+File under one of the following license alternatives, please (i) delete this
20074+introductory statement regarding license alternatives, (ii) delete the two
20075+license alternatives that you have not elected to use and (iii) preserve the
20076+Marvell copyright notice above.
20077+
20078+********************************************************************************
20079+Marvell Commercial License Option
20080+
20081+If you received this File from Marvell and you have entered into a commercial
20082+license agreement (a "Commercial License") with Marvell, the File is licensed
20083+to you under the terms of the applicable Commercial License.
20084+
20085+********************************************************************************
20086+Marvell GPL License Option
20087+
20088+If you received this File from Marvell, you may opt to use, redistribute and/or
20089+modify this File in accordance with the terms and conditions of the General
20090+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
20091+available along with the File in the license.txt file or by writing to the Free
20092+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
20093+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
20094+
20095+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
20096+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
20097+DISCLAIMED. The GPL License provides additional details about this warranty
20098+disclaimer.
20099+********************************************************************************
20100+Marvell BSD License Option
20101+
20102+If you received this File from Marvell, you may opt to use, redistribute and/or
20103+modify this File under the following licensing terms.
20104+Redistribution and use in source and binary forms, with or without modification,
20105+are permitted provided that the following conditions are met:
20106+
20107+ * Redistributions of source code must retain the above copyright notice,
20108+ this list of conditions and the following disclaimer.
20109+
20110+ * Redistributions in binary form must reproduce the above copyright
20111+ notice, this list of conditions and the following disclaimer in the
20112+ documentation and/or other materials provided with the distribution.
20113+
20114+ * Neither the name of Marvell nor the names of its contributors may be
20115+ used to endorse or promote products derived from this software without
20116+ specific prior written permission.
20117+
20118+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20119+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20120+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20121+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20122+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20123+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20124+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20125+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20126+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20127+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20128+
20129+*******************************************************************************/
20130+
20131+#include "cesa/mvCesa.h"
20132+
20133+#include "ctrlEnv/mvCtrlEnvLib.h"
20134+#undef CESA_DEBUG
20135+
20136+
20137+/********** Global variables **********/
20138+
20139+/* If request size is more than MV_CESA_MAX_BUF_SIZE the
20140+ * request is processed as fragmented request.
20141+ */
20142+
20143+MV_CESA_STATS cesaStats;
20144+
20145+MV_BUF_INFO cesaSramSaBuf;
20146+short cesaLastSid = -1;
20147+MV_CESA_SA* pCesaSAD = NULL;
20148+MV_U16 cesaMaxSA = 0;
20149+
20150+MV_CESA_REQ* pCesaReqFirst = NULL;
20151+MV_CESA_REQ* pCesaReqLast = NULL;
20152+MV_CESA_REQ* pCesaReqEmpty = NULL;
20153+MV_CESA_REQ* pCesaReqProcess = NULL;
20154+int cesaQueueDepth = 0;
20155+int cesaReqResources = 0;
20156+
20157+MV_CESA_SRAM_MAP* cesaSramVirtPtr = NULL;
20158+MV_U32 cesaCryptEngBase = 0;
20159+void *cesaOsHandle = NULL;
20160+#if (MV_CESA_VERSION >= 3)
20161+MV_U32 cesaChainLength = 0;
20162+int chainReqNum = 0;
20163+MV_U32 chainIndex = 0;
20164+MV_CESA_REQ* pNextActiveChain = 0;
20165+MV_CESA_REQ* pEndCurrChain = 0;
20166+MV_BOOL isFirstReq = MV_TRUE;
20167+#endif
20168+
20169+static INLINE MV_U8* mvCesaSramAddrGet(void)
20170+{
20171+#ifdef MV_CESA_NO_SRAM
20172+ return (MV_U8*)cesaSramVirtPtr;
20173+#else
20174+ return (MV_U8*)cesaCryptEngBase;
20175+#endif /* MV_CESA_NO_SRAM */
20176+}
20177+
20178+static INLINE MV_ULONG mvCesaSramVirtToPhys(void* pDev, MV_U8* pSramVirt)
20179+{
20180+#ifdef MV_CESA_NO_SRAM
20181+ return (MV_ULONG)mvOsIoVirtToPhy(NULL, pSramVirt);
20182+#else
20183+ return (MV_ULONG)pSramVirt;
20184+#endif /* MV_CESA_NO_SRAM */
20185+}
20186+
20187+/* Internal Function prototypes */
20188+
20189+static INLINE void mvCesaSramDescrBuild(MV_U32 config, int frag,
20190+ int cryptoOffset, int ivOffset, int cryptoLength,
20191+ int macOffset, int digestOffset, int macLength, int macTotalLen,
20192+ MV_CESA_REQ *pCesaReq, MV_DMA_DESC* pDmaDesc);
20193+
20194+static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc);
20195+
20196+static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
20197+ MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
20198+ int offset, int copySize, MV_BOOL skipFlush);
20199+
20200+static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,
20201+ unsigned char innerIV[], unsigned char outerIV[]);
20202+
20203+static MV_STATUS mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,
20204+ int macDataSize);
20205+
20206+static MV_CESA_COMMAND* mvCesaCtrModeInit(void);
20207+
20208+static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd);
20209+static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd);
20210+static void mvCesaCtrModeFinish(MV_CESA_COMMAND *pCmd);
20211+
20212+static INLINE MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq);
20213+static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag);
20214+
20215+static INLINE MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset);
20216+static INLINE MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd);
20217+
20218+static INLINE void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq,
20219+ int cryptoOffset, int macOffset,
20220+ int* pCopySize, int* pCryptoDataSize, int* pMacDataSize);
20221+static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size);
20222+
20223+
20224+/* Go to the next request in the request queue */
20225+static INLINE MV_CESA_REQ* MV_CESA_REQ_NEXT_PTR(MV_CESA_REQ* pReq)
20226+{
20227+ if(pReq == pCesaReqLast)
20228+ return pCesaReqFirst;
20229+
20230+ return pReq+1;
20231+}
20232+
20233+#if (MV_CESA_VERSION >= 3)
20234+/* Go to the previous request in the request queue */
20235+static INLINE MV_CESA_REQ* MV_CESA_REQ_PREV_PTR(MV_CESA_REQ* pReq)
20236+{
20237+ if(pReq == pCesaReqFirst)
20238+ return pCesaReqLast;
20239+
20240+ return pReq-1;
20241+}
20242+
20243+#endif
20244+
20245+
20246+static INLINE void mvCesaReqProcessStart(MV_CESA_REQ* pReq)
20247+{
20248+ int frag;
20249+
20250+#if (MV_CESA_VERSION >= 3)
20251+ pReq->state = MV_CESA_CHAIN;
20252+#else
20253+ pReq->state = MV_CESA_PROCESS;
20254+#endif
20255+ cesaStats.startCount++;
20256+
20257+ if(pReq->fragMode == MV_CESA_FRAG_NONE)
20258+ {
20259+ frag = 0;
20260+ }
20261+ else
20262+ {
20263+ frag = pReq->frags.nextFrag;
20264+ pReq->frags.nextFrag++;
20265+ }
20266+#if (MV_CESA_VERSION >= 2)
20267+ /* Enable TDMA engine */
20268+ MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);
20269+ MV_REG_WRITE(MV_CESA_TDMA_NEXT_DESC_PTR_REG,
20270+ (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
20271+#else
20272+ /* Enable IDMA engine */
20273+ MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
20274+ MV_REG_WRITE(IDMA_NEXT_DESC_PTR_REG(0),
20275+ (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
20276+#endif /* MV_CESA_VERSION >= 2 */
20277+
20278+#if defined(MV_BRIDGE_SYNC_REORDER)
20279+ mvOsBridgeReorderWA();
20280+#endif
20281+
20282+ /* Start Accelerator */
20283+ MV_REG_WRITE(MV_CESA_CMD_REG, MV_CESA_CMD_CHAN_ENABLE_MASK);
20284+}
20285+
20286+
20287+/*******************************************************************************
20288+* mvCesaHalInit - Initialize the CESA driver
20289+*
20290+* DESCRIPTION:
20291+* This function initialize the CESA driver.
20292+* 1) Session database
20293+* 2) Request queue
20294+* 4) DMA descriptor lists - one list per request. Each list
20295+* has MV_CESA_MAX_DMA_DESC descriptors.
20296+*
20297+* INPUT:
20298+* numOfSession - maximum number of supported sessions
20299+* queueDepth - number of elements in the request queue.
20300+* pSramBase - virtual address of Sram
20301+* osHandle - A handle used by the OS to allocate memory for the
20302+* module (Passed to the OS Services layer)
20303+*
20304+* RETURN:
20305+* MV_OK - Success
20306+* MV_NO_RESOURCE - Fail, can't allocate resources:
20307+* Session database, request queue,
20308+* DMA descriptors list, LRU cache database.
20309+* MV_NOT_ALIGNED - Sram base address is not 8 byte aligned.
20310+*
20311+*******************************************************************************/
20312+MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase,
20313+ void *osHandle)
20314+{
20315+ int i, req;
20316+ MV_U32 descOffsetReg, configReg;
20317+ MV_CESA_SRAM_SA *pSramSA;
20318+
20319+
20320+ mvOsPrintf("mvCesaInit: sessions=%d, queue=%d, pSram=%p\n",
20321+ numOfSession, queueDepth, pSramBase);
20322+
20323+ cesaOsHandle = osHandle;
20324+ /* Create Session database */
20325+ pCesaSAD = mvOsMalloc(sizeof(MV_CESA_SA)*numOfSession);
20326+ if(pCesaSAD == NULL)
20327+ {
20328+ mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d SAs\n",
20329+ sizeof(MV_CESA_SA)*numOfSession, numOfSession);
20330+ mvCesaFinish();
20331+ return MV_NO_RESOURCE;
20332+ }
20333+ memset(pCesaSAD, 0, sizeof(MV_CESA_SA)*numOfSession);
20334+ cesaMaxSA = numOfSession;
20335+
20336+ /* Allocate imag of sramSA in the DRAM */
20337+ cesaSramSaBuf.bufSize = sizeof(MV_CESA_SRAM_SA)*numOfSession +
20338+ CPU_D_CACHE_LINE_SIZE;
20339+
20340+ cesaSramSaBuf.bufVirtPtr = mvOsIoCachedMalloc(osHandle,cesaSramSaBuf.bufSize,
20341+ &cesaSramSaBuf.bufPhysAddr,
20342+ &cesaSramSaBuf.memHandle);
20343+
20344+ if(cesaSramSaBuf.bufVirtPtr == NULL)
20345+ {
20346+ mvOsPrintf("mvCesaInit: Can't allocate %d bytes for sramSA structures\n",
20347+ cesaSramSaBuf.bufSize);
20348+ mvCesaFinish();
20349+ return MV_NO_RESOURCE;
20350+ }
20351+ memset(cesaSramSaBuf.bufVirtPtr, 0, cesaSramSaBuf.bufSize);
20352+ pSramSA = (MV_CESA_SRAM_SA*)MV_ALIGN_UP((MV_ULONG)cesaSramSaBuf.bufVirtPtr,
20353+ CPU_D_CACHE_LINE_SIZE);
20354+ for(i=0; i<numOfSession; i++)
20355+ {
20356+ pCesaSAD[i].pSramSA = &pSramSA[i];
20357+ }
20358+
20359+ /* Create request queue */
20360+ pCesaReqFirst = mvOsMalloc(sizeof(MV_CESA_REQ)*queueDepth);
20361+ if(pCesaReqFirst == NULL)
20362+ {
20363+ mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d requests\n",
20364+ sizeof(MV_CESA_REQ)*queueDepth, queueDepth);
20365+ mvCesaFinish();
20366+ return MV_NO_RESOURCE;
20367+ }
20368+ memset(pCesaReqFirst, 0, sizeof(MV_CESA_REQ)*queueDepth);
20369+ pCesaReqEmpty = pCesaReqFirst;
20370+ pCesaReqLast = pCesaReqFirst + (queueDepth-1);
20371+ pCesaReqProcess = pCesaReqEmpty;
20372+ cesaQueueDepth = queueDepth;
20373+ cesaReqResources = queueDepth;
20374+#if (MV_CESA_VERSION >= 3)
20375+ cesaChainLength = MAX_CESA_CHAIN_LENGTH;
20376+#endif
20377+ /* pSramBase must be 8 byte aligned */
20378+ if( MV_IS_NOT_ALIGN((MV_ULONG)pSramBase, 8) )
20379+ {
20380+ mvOsPrintf("mvCesaInit: pSramBase (%p) must be 8 byte aligned\n",
20381+ pSramBase);
20382+ mvCesaFinish();
20383+ return MV_NOT_ALIGNED;
20384+ }
20385+ cesaSramVirtPtr = (MV_CESA_SRAM_MAP*)pSramBase;
20386+
20387+ cesaCryptEngBase = cryptEngBase;
20388+
20389+ /*memset(cesaSramVirtPtr, 0, sizeof(MV_CESA_SRAM_MAP));*/
20390+
20391+ /* Clear registers */
20392+ MV_REG_WRITE( MV_CESA_CFG_REG, 0);
20393+ MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
20394+ MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
20395+
20396+ /* Initialize DMA descriptor lists for all requests in Request queue */
20397+ descOffsetReg = configReg = 0;
20398+ for(req=0; req<queueDepth; req++)
20399+ {
20400+ int frag;
20401+ MV_CESA_REQ* pReq;
20402+ MV_DMA_DESC* pDmaDesc;
20403+
20404+ pReq = &pCesaReqFirst[req];
20405+
20406+ pReq->cesaDescBuf.bufSize = sizeof(MV_CESA_DESC)*MV_CESA_MAX_REQ_FRAGS +
20407+ CPU_D_CACHE_LINE_SIZE;
20408+
20409+ pReq->cesaDescBuf.bufVirtPtr =
20410+ mvOsIoCachedMalloc(osHandle,pReq->cesaDescBuf.bufSize,
20411+ &pReq->cesaDescBuf.bufPhysAddr,
20412+ &pReq->cesaDescBuf.memHandle);
20413+
20414+ if(pReq->cesaDescBuf.bufVirtPtr == NULL)
20415+ {
20416+ mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for CESA descriptors\n",
20417+ req, pReq->cesaDescBuf.bufSize);
20418+ mvCesaFinish();
20419+ return MV_NO_RESOURCE;
20420+ }
20421+ memset(pReq->cesaDescBuf.bufVirtPtr, 0, pReq->cesaDescBuf.bufSize);
20422+ pReq->pCesaDesc = (MV_CESA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->cesaDescBuf.bufVirtPtr,
20423+ CPU_D_CACHE_LINE_SIZE);
20424+
20425+ pReq->dmaDescBuf.bufSize = sizeof(MV_DMA_DESC)*MV_CESA_MAX_DMA_DESC*MV_CESA_MAX_REQ_FRAGS +
20426+ CPU_D_CACHE_LINE_SIZE;
20427+
20428+ pReq->dmaDescBuf.bufVirtPtr =
20429+ mvOsIoCachedMalloc(osHandle,pReq->dmaDescBuf.bufSize,
20430+ &pReq->dmaDescBuf.bufPhysAddr,
20431+ &pReq->dmaDescBuf.memHandle);
20432+
20433+ if(pReq->dmaDescBuf.bufVirtPtr == NULL)
20434+ {
20435+ mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for DMA descriptor list\n",
20436+ req, pReq->dmaDescBuf.bufSize);
20437+ mvCesaFinish();
20438+ return MV_NO_RESOURCE;
20439+ }
20440+ memset(pReq->dmaDescBuf.bufVirtPtr, 0, pReq->dmaDescBuf.bufSize);
20441+ pDmaDesc = (MV_DMA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->dmaDescBuf.bufVirtPtr,
20442+ CPU_D_CACHE_LINE_SIZE);
20443+
20444+ for(frag=0; frag<MV_CESA_MAX_REQ_FRAGS; frag++)
20445+ {
20446+ MV_CESA_DMA* pDma = &pReq->dma[frag];
20447+
20448+ pDma->pDmaFirst = pDmaDesc;
20449+ pDma->pDmaLast = NULL;
20450+
20451+ for(i=0; i<MV_CESA_MAX_DMA_DESC-1; i++)
20452+ {
20453+ /* link all DMA descriptors together */
20454+ pDma->pDmaFirst[i].phyNextDescPtr =
20455+ MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pDmaDesc[i+1]));
20456+ }
20457+ pDma->pDmaFirst[i].phyNextDescPtr = 0;
20458+ mvOsCacheFlush(NULL, &pDma->pDmaFirst[0], MV_CESA_MAX_DMA_DESC*sizeof(MV_DMA_DESC));
20459+
20460+ pDmaDesc += MV_CESA_MAX_DMA_DESC;
20461+ }
20462+ }
20463+ /*mvCesaCryptoIvSet(NULL, MV_CESA_MAX_IV_LENGTH);*/
20464+ descOffsetReg = (MV_U16)((MV_U8*)&cesaSramVirtPtr->desc - mvCesaSramAddrGet());
20465+ MV_REG_WRITE(MV_CESA_CHAN_DESC_OFFSET_REG, descOffsetReg);
20466+
20467+ configReg |= (MV_CESA_CFG_WAIT_DMA_MASK | MV_CESA_CFG_ACT_DMA_MASK);
20468+#if (MV_CESA_VERSION >= 3)
20469+ configReg |= MV_CESA_CFG_CHAIN_MODE_MASK;
20470+#endif
20471+
20472+#if (MV_CESA_VERSION >= 2)
20473+ /* Initialize TDMA engine */
20474+ MV_REG_WRITE(MV_CESA_TDMA_CTRL_REG, MV_CESA_TDMA_CTRL_VALUE);
20475+ MV_REG_WRITE(MV_CESA_TDMA_BYTE_COUNT_REG, 0);
20476+ MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);
20477+#else
20478+ /* Initialize IDMA #0 engine */
20479+ MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
20480+ MV_REG_WRITE(IDMA_BYTE_COUNT_REG(0), 0);
20481+ MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
20482+ MV_REG_WRITE(IDMA_CTRL_HIGH_REG(0), ICCHR_ENDIAN_LITTLE
20483+#ifdef MV_CPU_LE
20484+ | ICCHR_DESC_BYTE_SWAP_EN
20485+#endif
20486+ );
20487+ /* Clear Cause Byte of IDMA channel to be used */
20488+ MV_REG_WRITE( IDMA_CAUSE_REG, ~ICICR_CAUSE_MASK_ALL(0));
20489+ MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), MV_CESA_IDMA_CTRL_LOW_VALUE);
20490+#endif /* (MV_CESA_VERSION >= 2) */
20491+
20492+ /* Set CESA configuration registers */
20493+ MV_REG_WRITE( MV_CESA_CFG_REG, configReg);
20494+ mvCesaDebugStatsClear();
20495+
20496+ return MV_OK;
20497+}
20498+
20499+/*******************************************************************************
20500+* mvCesaFinish - Shutdown the CESA driver
20501+*
20502+* DESCRIPTION:
20503+* This function shutdown the CESA driver and free all allocted resources.
20504+*
20505+* INPUT: None
20506+*
20507+* RETURN:
20508+* MV_OK - Success
20509+* Other - Fail
20510+*
20511+*******************************************************************************/
20512+MV_STATUS mvCesaFinish (void)
20513+{
20514+ int req;
20515+ MV_CESA_REQ* pReq;
20516+
20517+ mvOsPrintf("mvCesaFinish: \n");
20518+
20519+ cesaSramVirtPtr = NULL;
20520+
20521+ /* Free all resources: DMA list, etc. */
20522+ for(req=0; req<cesaQueueDepth; req++)
20523+ {
20524+ pReq = &pCesaReqFirst[req];
20525+ if(pReq->dmaDescBuf.bufVirtPtr != NULL)
20526+ {
20527+ mvOsIoCachedFree(cesaOsHandle,pReq->dmaDescBuf.bufSize,
20528+ pReq->dmaDescBuf.bufPhysAddr,
20529+ pReq->dmaDescBuf.bufVirtPtr,
20530+ pReq->dmaDescBuf.memHandle);
20531+ }
20532+ if(pReq->cesaDescBuf.bufVirtPtr != NULL)
20533+ {
20534+ mvOsIoCachedFree(cesaOsHandle,pReq->cesaDescBuf.bufSize,
20535+ pReq->cesaDescBuf.bufPhysAddr,
20536+ pReq->cesaDescBuf.bufVirtPtr,
20537+ pReq->cesaDescBuf.memHandle);
20538+ }
20539+ }
20540+#if (MV_CESA_VERSION < 2)
20541+ MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
20542+#endif /* (MV_CESA_VERSION < 2) */
20543+
20544+ /* Free request queue */
20545+ if(pCesaReqFirst != NULL)
20546+ {
20547+ mvOsFree(pCesaReqFirst);
20548+ pCesaReqFirst = pCesaReqLast = NULL;
20549+ pCesaReqEmpty = pCesaReqProcess = NULL;
20550+ cesaQueueDepth = cesaReqResources = 0;
20551+ }
20552+ /* Free SA database */
20553+ if(pCesaSAD != NULL)
20554+ {
20555+ mvOsFree(pCesaSAD);
20556+ pCesaSAD = NULL;
20557+ cesaMaxSA = 0;
20558+ }
20559+ MV_REG_WRITE( MV_CESA_CFG_REG, 0);
20560+ MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
20561+ MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
20562+
20563+ return MV_OK;
20564+}
20565+
20566+/*******************************************************************************
20567+* mvCesaCryptoIvSet - Set IV value for Crypto algorithm working in CBC mode
20568+*
20569+* DESCRIPTION:
20570+* This function set IV value using by Crypto algorithms in CBC mode.
20571+* Each channel has its own IV value.
20572+* This function gets IV value from the caller. If no IV value passed from
20573+* the caller or only part of IV passed, the function will init the rest part
20574+* of IV value (or the whole IV) by random value.
20575+*
20576+* INPUT:
20577+* MV_U8* pIV - Pointer to IV value supplied by user. If pIV==NULL
20578+* the function will generate random IV value.
20579+* int ivSize - size (in bytes) of IV provided by user. If ivSize is
20580+* smaller than maximum IV size, the function will complete
20581+* IV by random value.
20582+*
20583+* RETURN:
20584+* MV_OK - Success
20585+* Other - Fail
20586+*
20587+*******************************************************************************/
20588+MV_STATUS mvCesaCryptoIvSet(MV_U8* pIV, int ivSize)
20589+{
20590+ MV_U8* pSramIV;
20591+#if defined(MV646xx)
20592+ mvOsPrintf("mvCesaCryptoIvSet: ERR. shouldn't use this call on MV64660\n");
20593+#endif
20594+ pSramIV = cesaSramVirtPtr->cryptoIV;
20595+ if(ivSize > MV_CESA_MAX_IV_LENGTH)
20596+ {
20597+ mvOsPrintf("mvCesaCryptoIvSet: ivSize (%d) is too large\n", ivSize);
20598+ ivSize = MV_CESA_MAX_IV_LENGTH;
20599+ }
20600+ if(pIV != NULL)
20601+ {
20602+ memcpy(pSramIV, pIV, ivSize);
20603+ ivSize = MV_CESA_MAX_IV_LENGTH - ivSize;
20604+ pSramIV += ivSize;
20605+ }
20606+
20607+ while(ivSize > 0)
20608+ {
20609+ int size, mv_random = mvOsRand();
20610+
20611+ size = MV_MIN(ivSize, sizeof(mv_random));
20612+ memcpy(pSramIV, (void*)&mv_random, size);
20613+
20614+ pSramIV += size;
20615+ ivSize -= size;
20616+ }
20617+/*
20618+ mvOsCacheFlush(NULL, cesaSramVirtPtr->cryptoIV,
20619+ MV_CESA_MAX_IV_LENGTH);
20620+ mvOsCacheInvalidate(NULL, cesaSramVirtPtr->cryptoIV,
20621+ MV_CESA_MAX_IV_LENGTH);
20622+*/
20623+ return MV_OK;
20624+}
20625+
20626+/*******************************************************************************
20627+* mvCesaSessionOpen - Open new uni-directional crypto session
20628+*
20629+* DESCRIPTION:
20630+* This function open new session.
20631+*
20632+* INPUT:
20633+* MV_CESA_OPEN_SESSION *pSession - pointer to new session input parameters
20634+*
20635+* OUTPUT:
20636+* short *pSid - session ID, should be used for all future
20637+* requests over this session.
20638+*
20639+* RETURN:
20640+* MV_OK - Session opend successfully.
20641+* MV_FULL - All sessions are in use, no free place in
20642+* SA database.
20643+* MV_BAD_PARAM - One of session input parameters is invalid.
20644+*
20645+*******************************************************************************/
20646+MV_STATUS mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid)
20647+{
20648+ short sid;
20649+ MV_U32 config = 0;
20650+ int digestSize;
20651+
20652+ cesaStats.openedCount++;
20653+
20654+ /* Find free entry in SAD */
20655+ for(sid=0; sid<cesaMaxSA; sid++)
20656+ {
20657+ if(pCesaSAD[sid].valid == 0)
20658+ {
20659+ break;
20660+ }
20661+ }
20662+ if(sid == cesaMaxSA)
20663+ {
20664+ mvOsPrintf("mvCesaSessionOpen: SA Database is FULL\n");
20665+ return MV_FULL;
20666+ }
20667+
20668+ /* Check Input parameters for Open session */
20669+ if (pSession->operation >= MV_CESA_MAX_OPERATION)
20670+ {
20671+ mvOsPrintf("mvCesaSessionOpen: Unexpected operation %d\n",
20672+ pSession->operation);
20673+ return MV_BAD_PARAM;
20674+ }
20675+ config |= (pSession->operation << MV_CESA_OPERATION_OFFSET);
20676+
20677+ if( (pSession->direction != MV_CESA_DIR_ENCODE) &&
20678+ (pSession->direction != MV_CESA_DIR_DECODE) )
20679+ {
20680+ mvOsPrintf("mvCesaSessionOpen: Unexpected direction %d\n",
20681+ pSession->direction);
20682+ return MV_BAD_PARAM;
20683+ }
20684+ config |= (pSession->direction << MV_CESA_DIRECTION_BIT);
20685+ /* Clear SA entry */
20686+ /* memset(&pCesaSAD[sid], 0, sizeof(pCesaSAD[sid])); */
20687+
20688+ /* Check AUTH parameters and update SA entry */
20689+ if(pSession->operation != MV_CESA_CRYPTO_ONLY)
20690+ {
20691+ /* For HMAC (MD5 and SHA1) - Maximum Key size is 64 bytes */
20692+ if( (pSession->macMode == MV_CESA_MAC_HMAC_MD5) ||
20693+ (pSession->macMode == MV_CESA_MAC_HMAC_SHA1) )
20694+ {
20695+ if(pSession->macKeyLength > MV_CESA_MAX_MAC_KEY_LENGTH)
20696+ {
20697+ mvOsPrintf("mvCesaSessionOpen: macKeyLength %d is too large\n",
20698+ pSession->macKeyLength);
20699+ return MV_BAD_PARAM;
20700+ }
20701+ mvCesaHmacIvGet(pSession->macMode, pSession->macKey, pSession->macKeyLength,
20702+ pCesaSAD[sid].pSramSA->macInnerIV,
20703+ pCesaSAD[sid].pSramSA->macOuterIV);
20704+ pCesaSAD[sid].macKeyLength = pSession->macKeyLength;
20705+ }
20706+ switch(pSession->macMode)
20707+ {
20708+ case MV_CESA_MAC_MD5:
20709+ case MV_CESA_MAC_HMAC_MD5:
20710+ digestSize = MV_CESA_MD5_DIGEST_SIZE;
20711+ break;
20712+
20713+ case MV_CESA_MAC_SHA1:
20714+ case MV_CESA_MAC_HMAC_SHA1:
20715+ digestSize = MV_CESA_SHA1_DIGEST_SIZE;
20716+ break;
20717+
20718+ default:
20719+ mvOsPrintf("mvCesaSessionOpen: Unexpected macMode %d\n",
20720+ pSession->macMode);
20721+ return MV_BAD_PARAM;
20722+ }
20723+ config |= (pSession->macMode << MV_CESA_MAC_MODE_OFFSET);
20724+
20725+ /* Supported digest sizes: MD5 - 16 bytes (128 bits), */
20726+ /* SHA1 - 20 bytes (160 bits) or 12 bytes (96 bits) for both */
20727+ if( (pSession->digestSize != digestSize) && (pSession->digestSize != 12))
20728+ {
20729+ mvOsPrintf("mvCesaSessionOpen: Unexpected digest size %d\n",
20730+ pSession->digestSize);
20731+ mvOsPrintf("\t Valid values [bytes]: MD5-16, SHA1-20, Both-12\n");
20732+ return MV_BAD_PARAM;
20733+ }
20734+ pCesaSAD[sid].digestSize = pSession->digestSize;
20735+
20736+ if(pCesaSAD[sid].digestSize == 12)
20737+ {
20738+ /* Set MV_CESA_MAC_DIGEST_SIZE_BIT if digest size is 96 bits */
20739+ config |= (MV_CESA_MAC_DIGEST_96B << MV_CESA_MAC_DIGEST_SIZE_BIT);
20740+ }
20741+ }
20742+
20743+ /* Check CRYPTO parameters and update SA entry */
20744+ if(pSession->operation != MV_CESA_MAC_ONLY)
20745+ {
20746+ switch(pSession->cryptoAlgorithm)
20747+ {
20748+ case MV_CESA_CRYPTO_DES:
20749+ pCesaSAD[sid].cryptoKeyLength = MV_CESA_DES_KEY_LENGTH;
20750+ pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;
20751+ break;
20752+
20753+ case MV_CESA_CRYPTO_3DES:
20754+ pCesaSAD[sid].cryptoKeyLength = MV_CESA_3DES_KEY_LENGTH;
20755+ pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;
20756+ /* Only EDE mode is supported */
20757+ config |= (MV_CESA_CRYPTO_3DES_EDE <<
20758+ MV_CESA_CRYPTO_3DES_MODE_BIT);
20759+ break;
20760+
20761+ case MV_CESA_CRYPTO_AES:
20762+ switch(pSession->cryptoKeyLength)
20763+ {
20764+ case 16:
20765+ pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_128_KEY_LENGTH;
20766+ config |= (MV_CESA_CRYPTO_AES_KEY_128 <<
20767+ MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
20768+ break;
20769+
20770+ case 24:
20771+ pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_192_KEY_LENGTH;
20772+ config |= (MV_CESA_CRYPTO_AES_KEY_192 <<
20773+ MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
20774+ break;
20775+
20776+ case 32:
20777+ default:
20778+ pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_256_KEY_LENGTH;
20779+ config |= (MV_CESA_CRYPTO_AES_KEY_256 <<
20780+ MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
20781+ break;
20782+ }
20783+ pCesaSAD[sid].cryptoBlockSize = MV_CESA_AES_BLOCK_SIZE;
20784+ break;
20785+
20786+ default:
20787+ mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoAlgorithm %d\n",
20788+ pSession->cryptoAlgorithm);
20789+ return MV_BAD_PARAM;
20790+ }
20791+ config |= (pSession->cryptoAlgorithm << MV_CESA_CRYPTO_ALG_OFFSET);
20792+
20793+ if(pSession->cryptoKeyLength != pCesaSAD[sid].cryptoKeyLength)
20794+ {
20795+ mvOsPrintf("cesaSessionOpen: Wrong CryptoKeySize %d != %d\n",
20796+ pSession->cryptoKeyLength, pCesaSAD[sid].cryptoKeyLength);
20797+ return MV_BAD_PARAM;
20798+ }
20799+
20800+ /* Copy Crypto key */
20801+ if( (pSession->cryptoAlgorithm == MV_CESA_CRYPTO_AES) &&
20802+ (pSession->direction == MV_CESA_DIR_DECODE))
20803+ {
20804+ /* Crypto Key for AES decode is computed from original key material */
20805+ /* and depend on cryptoKeyLength (128/192/256 bits) */
20806+ aesMakeKey(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey,
20807+ pSession->cryptoKeyLength*8, MV_CESA_AES_BLOCK_SIZE*8);
20808+ }
20809+ else
20810+ {
20811+ /*panic("mvCesaSessionOpen2");*/
20812+ memcpy(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey,
20813+ pCesaSAD[sid].cryptoKeyLength);
20814+
20815+ }
20816+
20817+ switch(pSession->cryptoMode)
20818+ {
20819+ case MV_CESA_CRYPTO_ECB:
20820+ pCesaSAD[sid].cryptoIvSize = 0;
20821+ break;
20822+
20823+ case MV_CESA_CRYPTO_CBC:
20824+ pCesaSAD[sid].cryptoIvSize = pCesaSAD[sid].cryptoBlockSize;
20825+ break;
20826+
20827+ case MV_CESA_CRYPTO_CTR:
20828+ /* Supported only for AES algorithm */
20829+ if(pSession->cryptoAlgorithm != MV_CESA_CRYPTO_AES)
20830+ {
20831+ mvOsPrintf("mvCesaSessionOpen: CRYPTO CTR mode supported for AES only\n");
20832+ return MV_BAD_PARAM;
20833+ }
20834+ pCesaSAD[sid].cryptoIvSize = 0;
20835+ pCesaSAD[sid].ctrMode = 1;
20836+ /* Replace to ECB mode for HW */
20837+ pSession->cryptoMode = MV_CESA_CRYPTO_ECB;
20838+ break;
20839+
20840+ default:
20841+ mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoMode %d\n",
20842+ pSession->cryptoMode);
20843+ return MV_BAD_PARAM;
20844+ }
20845+
20846+ config |= (pSession->cryptoMode << MV_CESA_CRYPTO_MODE_BIT);
20847+ }
20848+ pCesaSAD[sid].config = config;
20849+
20850+ mvOsCacheFlush(NULL, pCesaSAD[sid].pSramSA, sizeof(MV_CESA_SRAM_SA));
20851+ if(pSid != NULL)
20852+ *pSid = sid;
20853+
20854+ pCesaSAD[sid].valid = 1;
20855+ return MV_OK;
20856+}
20857+
20858+/*******************************************************************************
20859+* mvCesaSessionClose - Close active crypto session
20860+*
20861+* DESCRIPTION:
20862+* This function closes existing session
20863+*
20864+* INPUT:
20865+* short sid - Unique identifier of the session to be closed
20866+*
20867+* RETURN:
20868+* MV_OK - Session closed successfully.
20869+* MV_BAD_PARAM - Session identifier is out of valid range.
20870+* MV_NOT_FOUND - There is no active session with such ID.
20871+*
20872+*******************************************************************************/
20873+MV_STATUS mvCesaSessionClose(short sid)
20874+{
20875+ cesaStats.closedCount++;
20876+
20877+ if(sid >= cesaMaxSA)
20878+ {
20879+ mvOsPrintf("CESA Error: sid (%d) is too big\n", sid);
20880+ return MV_BAD_PARAM;
20881+ }
20882+ if(pCesaSAD[sid].valid == 0)
20883+ {
20884+ mvOsPrintf("CESA Warning: Session (sid=%d) is invalid\n", sid);
20885+ return MV_NOT_FOUND;
20886+ }
20887+ if(cesaLastSid == sid)
20888+ cesaLastSid = -1;
20889+
20890+ pCesaSAD[sid].valid = 0;
20891+ return MV_OK;
20892+}
20893+
20894+/*******************************************************************************
20895+* mvCesaAction - Perform crypto operation
20896+*
20897+* DESCRIPTION:
20898+* This function set new CESA request FIFO queue for further HW processing.
20899+* The function checks request parameters before set new request to the queue.
20900+* If one of the CESA channels is ready for processing the request will be
20901+* passed to HW. When request processing is finished the CESA interrupt will
20902+* be generated by HW. The caller should call mvCesaReadyGet() function to
20903+* complete request processing and get result.
20904+*
20905+* INPUT:
20906+* MV_CESA_COMMAND *pCmd - pointer to new CESA request.
20907+* It includes pointers to Source and Destination
20908+* buffers, session identifier get from
20909+* mvCesaSessionOpen() function, pointer to caller
20910+* private data and all needed crypto parameters.
20911+*
20912+* RETURN:
20913+* MV_OK - request successfully added to request queue
20914+* and will be processed.
20915+* MV_NO_MORE - request successfully added to request queue and will
20916+* be processed, but request queue became Full and next
20917+* request will not be accepted.
20918+* MV_NO_RESOURCE - request queue is FULL and the request can not
20919+* be processed.
20920+* MV_OUT_OF_CPU_MEM - memory allocation needed for request processing is
20921+* failed. Request can not be processed.
20922+* MV_NOT_ALLOWED - This mixed request (CRYPTO+MAC) can not be processed
20923+* as one request and should be splitted for two requests:
20924+* CRYPTO_ONLY and MAC_ONLY.
20925+* MV_BAD_PARAM - One of the request parameters is out of valid range.
20926+* The request can not be processed.
20927+*
20928+*******************************************************************************/
20929+MV_STATUS mvCesaAction (MV_CESA_COMMAND *pCmd)
20930+{
20931+ MV_STATUS status;
20932+ MV_CESA_REQ* pReq = pCesaReqEmpty;
20933+ int sid = pCmd->sessionId;
20934+ MV_CESA_SA* pSA = &pCesaSAD[sid];
20935+#if (MV_CESA_VERSION >= 3)
20936+ MV_CESA_REQ* pFromReq;
20937+ MV_CESA_REQ* pToReq;
20938+#endif
20939+ cesaStats.reqCount++;
20940+
20941+ /* Check that the request queue is not FULL */
20942+ if(cesaReqResources == 0)
20943+ return MV_NO_RESOURCE;
20944+
20945+ if( (sid >= cesaMaxSA) || (!pSA->valid) )
20946+ {
20947+ mvOsPrintf("CESA Action Error: Session sid=%d is INVALID\n", sid);
20948+ return MV_BAD_PARAM;
20949+ }
20950+ pSA->count++;
20951+
20952+ if(pSA->ctrMode)
20953+ {
20954+ /* AES in CTR mode can't be mixed with Authentication */
20955+ if( (pSA->config & MV_CESA_OPERATION_MASK) !=
20956+ (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
20957+ {
20958+ mvOsPrintf("mvCesaAction : CRYPTO CTR mode can't be mixed with AUTH\n");
20959+ return MV_NOT_ALLOWED;
20960+ }
20961+ /* All other request parameters should not be checked because key stream */
20962+ /* (not user data) processed by AES HW engine */
20963+ pReq->pOrgCmd = pCmd;
20964+ /* Allocate temporary pCmd structure for Key stream */
20965+ pCmd = mvCesaCtrModeInit();
20966+ if(pCmd == NULL)
20967+ return MV_OUT_OF_CPU_MEM;
20968+
20969+ /* Prepare Key stream */
20970+ mvCesaCtrModePrepare(pCmd, pReq->pOrgCmd);
20971+ pReq->fixOffset = 0;
20972+ }
20973+ else
20974+ {
20975+ /* Check request parameters and calculae fixOffset */
20976+ status = mvCesaParamCheck(pSA, pCmd, &pReq->fixOffset);
20977+ if(status != MV_OK)
20978+ {
20979+ return status;
20980+ }
20981+ }
20982+ pReq->pCmd = pCmd;
20983+
20984+ /* Check if the packet need fragmentation */
20985+ if(pCmd->pSrc->mbufSize <= sizeof(cesaSramVirtPtr->buf) )
20986+ {
20987+ /* request size is smaller than single buffer size */
20988+ pReq->fragMode = MV_CESA_FRAG_NONE;
20989+
20990+ /* Prepare NOT fragmented packets */
20991+ status = mvCesaReqProcess(pReq);
20992+ if(status != MV_OK)
20993+ {
20994+ mvOsPrintf("CesaReady: ReqProcess error: pReq=%p, status=0x%x\n",
20995+ pReq, status);
20996+ }
20997+#if (MV_CESA_VERSION >= 3)
20998+ pReq->frags.numFrag = 1;
20999+#endif
21000+ }
21001+ else
21002+ {
21003+ MV_U8 frag = 0;
21004+
21005+ /* request size is larger than buffer size - needs fragmentation */
21006+
21007+ /* Check restrictions for processing fragmented packets */
21008+ status = mvCesaFragParamCheck(pSA, pCmd);
21009+ if(status != MV_OK)
21010+ return status;
21011+
21012+ pReq->fragMode = MV_CESA_FRAG_FIRST;
21013+ pReq->frags.nextFrag = 0;
21014+
21015+ /* Prepare Process Fragmented packets */
21016+ while(pReq->fragMode != MV_CESA_FRAG_LAST)
21017+ {
21018+ if(frag >= MV_CESA_MAX_REQ_FRAGS)
21019+ {
21020+ mvOsPrintf("mvCesaAction Error: Too large request frag=%d\n", frag);
21021+ return MV_OUT_OF_CPU_MEM;
21022+ }
21023+ status = mvCesaFragReqProcess(pReq, frag);
21024+ if(status == MV_OK) {
21025+#if (MV_CESA_VERSION >= 3)
21026+ if(frag) {
21027+ pReq->dma[frag-1].pDmaLast->phyNextDescPtr =
21028+ MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
21029+ mvOsCacheFlush(NULL, pReq->dma[frag-1].pDmaLast, sizeof(MV_DMA_DESC));
21030+ }
21031+#endif
21032+ frag++;
21033+ }
21034+ }
21035+ pReq->frags.numFrag = frag;
21036+#if (MV_CESA_VERSION >= 3)
21037+ if(chainReqNum) {
21038+ chainReqNum += pReq->frags.numFrag;
21039+ if(chainReqNum >= MAX_CESA_CHAIN_LENGTH)
21040+ chainReqNum = MAX_CESA_CHAIN_LENGTH;
21041+ }
21042+#endif
21043+ }
21044+
21045+ pReq->state = MV_CESA_PENDING;
21046+
21047+ pCesaReqEmpty = MV_CESA_REQ_NEXT_PTR(pReq);
21048+ cesaReqResources -= 1;
21049+
21050+/* #ifdef CESA_DEBUG */
21051+ if( (cesaQueueDepth - cesaReqResources) > cesaStats.maxReqCount)
21052+ cesaStats.maxReqCount = (cesaQueueDepth - cesaReqResources);
21053+/* #endif CESA_DEBUG */
21054+
21055+ cesaLastSid = sid;
21056+
21057+#if (MV_CESA_VERSION >= 3)
21058+ /* Are we within chain bounderies and follows the first request ? */
21059+ if((chainReqNum > 0) && (chainReqNum < MAX_CESA_CHAIN_LENGTH)) {
21060+ if(chainIndex) {
21061+ pFromReq = MV_CESA_REQ_PREV_PTR(pReq);
21062+ pToReq = pReq;
21063+ pReq->state = MV_CESA_CHAIN;
21064+ /* assume concatenating is possible */
21065+ pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast->phyNextDescPtr =
21066+ MV_32BIT_LE(mvCesaVirtToPhys(&pToReq->dmaDescBuf, pToReq->dma[0].pDmaFirst));
21067+ mvOsCacheFlush(NULL, pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast, sizeof(MV_DMA_DESC));
21068+
21069+ /* align active & next pointers */
21070+ if(pNextActiveChain->state != MV_CESA_PENDING)
21071+ pEndCurrChain = pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pReq);
21072+ }
21073+ else { /* we have only one chain, start new one */
21074+ chainReqNum = 0;
21075+ chainIndex++;
21076+ /* align active & next pointers */
21077+ if(pNextActiveChain->state != MV_CESA_PENDING)
21078+ pEndCurrChain = pNextActiveChain = pReq;
21079+ }
21080+ }
21081+ else {
21082+ /* In case we concatenate full chain */
21083+ if(chainReqNum == MAX_CESA_CHAIN_LENGTH) {
21084+ chainIndex++;
21085+ if(pNextActiveChain->state != MV_CESA_PENDING)
21086+ pEndCurrChain = pNextActiveChain = pReq;
21087+ chainReqNum = 0;
21088+ }
21089+
21090+ pReq = pCesaReqProcess;
21091+ if(pReq->state == MV_CESA_PENDING) {
21092+ pNextActiveChain = pReq;
21093+ pEndCurrChain = MV_CESA_REQ_NEXT_PTR(pReq);
21094+ /* Start Process new request */
21095+ mvCesaReqProcessStart(pReq);
21096+ }
21097+ }
21098+
21099+ chainReqNum++;
21100+
21101+ if((chainIndex < MAX_CESA_CHAIN_LENGTH) && (chainReqNum > cesaStats.maxChainUsage))
21102+ cesaStats.maxChainUsage = chainReqNum;
21103+
21104+#else
21105+
21106+ /* Check status of CESA channels and process requests if possible */
21107+ pReq = pCesaReqProcess;
21108+ if(pReq->state == MV_CESA_PENDING)
21109+ {
21110+ /* Start Process new request */
21111+ mvCesaReqProcessStart(pReq);
21112+ }
21113+#endif
21114+ /* If request queue became FULL - return MV_NO_MORE */
21115+ if(cesaReqResources == 0)
21116+ return MV_NO_MORE;
21117+
21118+ return MV_OK;
21119+
21120+}
21121+
21122+/*******************************************************************************
21123+* mvCesaReadyGet - Get crypto request that processing is finished
21124+*
21125+* DESCRIPTION:
21126+* This function complete request processing and return ready request to
21127+* caller. To don't miss interrupts the caller must call this function
21128+* while MV_OK or MV_TERMINATE values returned.
21129+*
21130+* INPUT:
21131+* MV_U32 chanMap - map of CESA channels finished thier job
21132+* accordingly with CESA Cause register.
21133+* MV_CESA_RESULT* pResult - pointer to structure contains information
21134+* about ready request. It includes pointer to
21135+* user private structure "pReqPrv", session identifier
21136+* for this request "sessionId" and return code.
21137+* Return code set to MV_FAIL if calculated digest value
21138+* on decode direction is different than digest value
21139+* in the packet.
21140+*
21141+* RETURN:
21142+* MV_OK - Success, ready request is returned.
21143+* MV_NOT_READY - Next request is not ready yet. New interrupt will
21144+* be generated for futher request processing.
21145+* MV_EMPTY - There is no more request for processing.
21146+* MV_BUSY - Fragmented request is not ready yet.
21147+* MV_TERMINATE - Call this function once more to complete processing
21148+* of fragmented request.
21149+*
21150+*******************************************************************************/
21151+MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult)
21152+{
21153+ MV_STATUS status, readyStatus = MV_NOT_READY;
21154+ MV_U32 statusReg;
21155+ MV_CESA_REQ* pReq;
21156+ MV_CESA_SA* pSA;
21157+
21158+#if (MV_CESA_VERSION >= 3)
21159+ if(isFirstReq == MV_TRUE) {
21160+ if(chainIndex == 0)
21161+ chainReqNum = 0;
21162+
21163+ isFirstReq = MV_FALSE;
21164+
21165+ if(pNextActiveChain->state == MV_CESA_PENDING) {
21166+ /* Start request Process */
21167+ mvCesaReqProcessStart(pNextActiveChain);
21168+ pEndCurrChain = pNextActiveChain;
21169+ if(chainIndex > 0)
21170+ chainIndex--;
21171+ /* Update pNextActiveChain to next chain head */
21172+ while(pNextActiveChain->state == MV_CESA_CHAIN)
21173+ pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pNextActiveChain);
21174+ }
21175+ }
21176+
21177+ /* Check if there are more processed requests - can we remove pEndCurrChain ??? */
21178+ if(pCesaReqProcess == pEndCurrChain) {
21179+ isFirstReq = MV_TRUE;
21180+ pEndCurrChain = pNextActiveChain;
21181+#else
21182+ if(pCesaReqProcess->state != MV_CESA_PROCESS) {
21183+#endif
21184+ return MV_EMPTY;
21185+ }
21186+
21187+#ifdef CESA_DEBUG
21188+ statusReg = MV_REG_READ(MV_CESA_STATUS_REG);
21189+ if( statusReg & MV_CESA_STATUS_ACTIVE_MASK )
21190+ {
21191+ mvOsPrintf("mvCesaReadyGet: Not Ready, Status = 0x%x\n", statusReg);
21192+ cesaStats.notReadyCount++;
21193+ return MV_NOT_READY;
21194+ }
21195+#endif /* CESA_DEBUG */
21196+
21197+ cesaStats.readyCount++;
21198+
21199+ pReq = pCesaReqProcess;
21200+ pSA = &pCesaSAD[pReq->pCmd->sessionId];
21201+
21202+ pResult->retCode = MV_OK;
21203+ if(pReq->fragMode != MV_CESA_FRAG_NONE)
21204+ {
21205+ MV_U8* pNewDigest;
21206+ int frag;
21207+#if (MV_CESA_VERSION >= 3)
21208+ pReq->frags.nextFrag = 1;
21209+ while(pReq->frags.nextFrag <= pReq->frags.numFrag) {
21210+#endif
21211+ frag = (pReq->frags.nextFrag - 1);
21212+
21213+ /* Restore DMA descriptor list */
21214+ pReq->dma[frag].pDmaLast->phyNextDescPtr =
21215+ MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[frag].pDmaLast[1]));
21216+ pReq->dma[frag].pDmaLast = NULL;
21217+
21218+ /* Special processing for finished fragmented request */
21219+ if(pReq->frags.nextFrag >= pReq->frags.numFrag)
21220+ {
21221+ mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);
21222+
21223+ /* Fragmented packet is ready */
21224+ if( (pSA->config & MV_CESA_OPERATION_MASK) !=
21225+ (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
21226+ {
21227+ int macDataSize = pReq->pCmd->macLength - pReq->frags.macSize;
21228+
21229+ if(macDataSize != 0)
21230+ {
21231+ /* Calculate all other blocks by SW */
21232+ mvCesaFragAuthComplete(pReq, pSA, macDataSize);
21233+ }
21234+
21235+ /* Copy new digest from SRAM to the Destination buffer */
21236+ pNewDigest = cesaSramVirtPtr->buf + pReq->frags.newDigestOffset;
21237+ status = mvCesaCopyToMbuf(pNewDigest, pReq->pCmd->pDst,
21238+ pReq->pCmd->digestOffset, pSA->digestSize);
21239+
21240+ /* For decryption: Compare new digest value with original one */
21241+ if((pSA->config & MV_CESA_DIRECTION_MASK) ==
21242+ (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
21243+ {
21244+ if( memcmp(pNewDigest, pReq->frags.orgDigest, pSA->digestSize) != 0)
21245+ {
21246+/*
21247+ mvOsPrintf("Digest error: chan=%d, newDigest=%p, orgDigest=%p, status = 0x%x\n",
21248+ chan, pNewDigest, pReq->frags.orgDigest, MV_REG_READ(MV_CESA_STATUS_REG));
21249+*/
21250+ /* Signiture verification is failed */
21251+ pResult->retCode = MV_FAIL;
21252+ }
21253+ }
21254+ }
21255+ readyStatus = MV_OK;
21256+ }
21257+#if (MV_CESA_VERSION >= 3)
21258+ pReq->frags.nextFrag++;
21259+ }
21260+#endif
21261+ }
21262+ else
21263+ {
21264+ mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);
21265+
21266+ /* Restore DMA descriptor list */
21267+ pReq->dma[0].pDmaLast->phyNextDescPtr =
21268+ MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[0].pDmaLast[1]));
21269+ pReq->dma[0].pDmaLast = NULL;
21270+ if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
21271+ (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) &&
21272+ ((pSA->config & MV_CESA_DIRECTION_MASK) ==
21273+ (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT)) )
21274+ {
21275+ /* For AUTH on decode : Check Digest result in Status register */
21276+ statusReg = MV_REG_READ(MV_CESA_STATUS_REG);
21277+ if(statusReg & MV_CESA_STATUS_DIGEST_ERR_MASK)
21278+ {
21279+/*
21280+ mvOsPrintf("Digest error: chan=%d, status = 0x%x\n",
21281+ chan, statusReg);
21282+*/
21283+ /* Signiture verification is failed */
21284+ pResult->retCode = MV_FAIL;
21285+ }
21286+ }
21287+ readyStatus = MV_OK;
21288+ }
21289+
21290+ if(readyStatus == MV_OK)
21291+ {
21292+ /* If Request is ready - Prepare pResult structure */
21293+ pResult->pReqPrv = pReq->pCmd->pReqPrv;
21294+ pResult->sessionId = pReq->pCmd->sessionId;
21295+
21296+ pReq->state = MV_CESA_IDLE;
21297+ pCesaReqProcess = MV_CESA_REQ_NEXT_PTR(pReq);
21298+ cesaReqResources++;
21299+
21300+ if(pSA->ctrMode)
21301+ {
21302+ /* For AES CTR mode - complete processing and free allocated resources */
21303+ mvCesaCtrModeComplete(pReq->pOrgCmd, pReq->pCmd);
21304+ mvCesaCtrModeFinish(pReq->pCmd);
21305+ pReq->pOrgCmd = NULL;
21306+ }
21307+ }
21308+
21309+#if (MV_CESA_VERSION < 3)
21310+ if(pCesaReqProcess->state == MV_CESA_PROCESS)
21311+ {
21312+ /* Start request Process */
21313+ mvCesaReqProcessStart(pCesaReqProcess);
21314+ if(readyStatus == MV_NOT_READY)
21315+ readyStatus = MV_BUSY;
21316+ }
21317+ else if(pCesaReqProcess != pCesaReqEmpty)
21318+ {
21319+ /* Start process new request from the queue */
21320+ mvCesaReqProcessStart(pCesaReqProcess);
21321+ }
21322+#endif
21323+ return readyStatus;
21324+}
21325+
21326+/***************** Functions to work with CESA_MBUF structure ******************/
21327+
21328+/*******************************************************************************
21329+* mvCesaMbufOffset - Locate offset in the Mbuf structure
21330+*
21331+* DESCRIPTION:
21332+* This function locates offset inside Multi-Bufeer structure.
21333+* It get fragment number and place in the fragment where the offset
21334+* is located.
21335+*
21336+*
21337+* INPUT:
21338+* MV_CESA_MBUF* pMbuf - Pointer to multi-buffer structure
21339+* int offset - Offset from the beginning of the data presented by
21340+* the Mbuf structure.
21341+*
21342+* OUTPUT:
21343+* int* pBufOffset - Offset from the beginning of the fragment where
21344+* the offset is located.
21345+*
21346+* RETURN:
21347+* int - Number of fragment, where the offset is located\
21348+*
21349+*******************************************************************************/
21350+int mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset)
21351+{
21352+ int frag = 0;
21353+
21354+ while(offset > 0)
21355+ {
21356+ if(frag >= pMbuf->numFrags)
21357+ {
21358+ mvOsPrintf("mvCesaMbufOffset: Error: frag (%d) > numFrags (%d)\n",
21359+ frag, pMbuf->numFrags);
21360+ return MV_INVALID;
21361+ }
21362+ if(offset < pMbuf->pFrags[frag].bufSize)
21363+ {
21364+ break;
21365+ }
21366+ offset -= pMbuf->pFrags[frag].bufSize;
21367+ frag++;
21368+ }
21369+ if(pBufOffset != NULL)
21370+ *pBufOffset = offset;
21371+
21372+ return frag;
21373+}
21374+
21375+/*******************************************************************************
21376+* mvCesaCopyFromMbuf - Copy data from the Mbuf structure to continuous buffer
21377+*
21378+* DESCRIPTION:
21379+*
21380+*
21381+* INPUT:
21382+* MV_U8* pDstBuf - Pointer to continuous buffer, where data is
21383+* copied to.
21384+* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
21385+* copied from.
21386+* int offset - Offset in the Mbuf structure where located first
21387+* byte of data should be copied.
21388+* int size - Size of data should be copied
21389+*
21390+* RETURN:
21391+* MV_OK - Success, all data is copied successfully.
21392+* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
21393+* No data is copied.
21394+* MV_EMPTY - Multi-buffer structure has not enough data to copy
21395+* Data from the offset to end of Mbuf data is copied.
21396+*
21397+*******************************************************************************/
21398+MV_STATUS mvCesaCopyFromMbuf(MV_U8* pDstBuf, MV_CESA_MBUF* pSrcMbuf,
21399+ int offset, int size)
21400+{
21401+ int frag, fragOffset, bufSize;
21402+ MV_U8* pBuf;
21403+
21404+ if(size == 0)
21405+ return MV_OK;
21406+
21407+ frag = mvCesaMbufOffset(pSrcMbuf, offset, &fragOffset);
21408+ if(frag == MV_INVALID)
21409+ {
21410+ mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
21411+ return MV_OUT_OF_RANGE;
21412+ }
21413+
21414+ bufSize = pSrcMbuf->pFrags[frag].bufSize - fragOffset;
21415+ pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr + fragOffset;
21416+ while(MV_TRUE)
21417+ {
21418+ if(size <= bufSize)
21419+ {
21420+ memcpy(pDstBuf, pBuf, size);
21421+ return MV_OK;
21422+ }
21423+ memcpy(pDstBuf, pBuf, bufSize);
21424+ size -= bufSize;
21425+ frag++;
21426+ pDstBuf += bufSize;
21427+ if(frag >= pSrcMbuf->numFrags)
21428+ break;
21429+
21430+ bufSize = pSrcMbuf->pFrags[frag].bufSize;
21431+ pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr;
21432+ }
21433+ mvOsPrintf("mvCesaCopyFromMbuf: Mbuf is EMPTY - %d bytes isn't copied\n",
21434+ size);
21435+ return MV_EMPTY;
21436+}
21437+
21438+/*******************************************************************************
21439+* mvCesaCopyToMbuf - Copy data from continuous buffer to the Mbuf structure
21440+*
21441+* DESCRIPTION:
21442+*
21443+*
21444+* INPUT:
21445+* MV_U8* pSrcBuf - Pointer to continuous buffer, where data is
21446+* copied from.
21447+* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
21448+* copied to.
21449+* int offset - Offset in the Mbuf structure where located first
21450+* byte of data should be copied.
21451+* int size - Size of data should be copied
21452+*
21453+* RETURN:
21454+* MV_OK - Success, all data is copied successfully.
21455+* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
21456+* No data is copied.
21457+* MV_FULL - Multi-buffer structure has not enough place to copy
21458+* all data. Data from the offset to end of Mbuf data
21459+* is copied.
21460+*
21461+*******************************************************************************/
21462+MV_STATUS mvCesaCopyToMbuf(MV_U8* pSrcBuf, MV_CESA_MBUF* pDstMbuf,
21463+ int offset, int size)
21464+{
21465+ int frag, fragOffset, bufSize;
21466+ MV_U8* pBuf;
21467+
21468+ if(size == 0)
21469+ return MV_OK;
21470+
21471+ frag = mvCesaMbufOffset(pDstMbuf, offset, &fragOffset);
21472+ if(frag == MV_INVALID)
21473+ {
21474+ mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
21475+ return MV_OUT_OF_RANGE;
21476+ }
21477+
21478+ bufSize = pDstMbuf->pFrags[frag].bufSize - fragOffset;
21479+ pBuf = pDstMbuf->pFrags[frag].bufVirtPtr + fragOffset;
21480+ while(MV_TRUE)
21481+ {
21482+ if(size <= bufSize)
21483+ {
21484+ memcpy(pBuf, pSrcBuf, size);
21485+ return MV_OK;
21486+ }
21487+ memcpy(pBuf, pSrcBuf, bufSize);
21488+ size -= bufSize;
21489+ frag++;
21490+ pSrcBuf += bufSize;
21491+ if(frag >= pDstMbuf->numFrags)
21492+ break;
21493+
21494+ bufSize = pDstMbuf->pFrags[frag].bufSize;
21495+ pBuf = pDstMbuf->pFrags[frag].bufVirtPtr;
21496+ }
21497+ mvOsPrintf("mvCesaCopyToMbuf: Mbuf is FULL - %d bytes isn't copied\n",
21498+ size);
21499+ return MV_FULL;
21500+}
21501+
21502+/*******************************************************************************
21503+* mvCesaMbufCopy - Copy data from one Mbuf structure to the other Mbuf structure
21504+*
21505+* DESCRIPTION:
21506+*
21507+*
21508+* INPUT:
21509+*
21510+* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
21511+* copied to.
21512+* int dstMbufOffset - Offset in the dstMbuf structure where first byte
21513+* of data should be copied to.
21514+* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
21515+* copied from.
21516+* int srcMbufOffset - Offset in the srcMbuf structure where first byte
21517+* of data should be copied from.
21518+* int size - Size of data should be copied
21519+*
21520+* RETURN:
21521+* MV_OK - Success, all data is copied successfully.
21522+* MV_OUT_OF_RANGE - Failed, srcMbufOffset or dstMbufOffset is out of
21523+* srcMbuf or dstMbuf structure correspondently.
21524+* No data is copied.
21525+* MV_BAD_SIZE - srcMbuf or dstMbuf structure is too small to copy
21526+* all data. Partial data is copied
21527+*
21528+*******************************************************************************/
21529+MV_STATUS mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,
21530+ MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size)
21531+{
21532+ int srcFrag, dstFrag, srcSize, dstSize, srcOffset, dstOffset;
21533+ int copySize;
21534+ MV_U8 *pSrc, *pDst;
21535+
21536+ if(size == 0)
21537+ return MV_OK;
21538+
21539+ srcFrag = mvCesaMbufOffset(pMbufSrc, srcMbufOffset, &srcOffset);
21540+ if(srcFrag == MV_INVALID)
21541+ {
21542+ mvOsPrintf("CESA srcMbuf Error: offset (%d) out of range\n", srcMbufOffset);
21543+ return MV_OUT_OF_RANGE;
21544+ }
21545+ pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr + srcOffset;
21546+ srcSize = pMbufSrc->pFrags[srcFrag].bufSize - srcOffset;
21547+
21548+ dstFrag = mvCesaMbufOffset(pMbufDst, dstMbufOffset, &dstOffset);
21549+ if(dstFrag == MV_INVALID)
21550+ {
21551+ mvOsPrintf("CESA dstMbuf Error: offset (%d) out of range\n", dstMbufOffset);
21552+ return MV_OUT_OF_RANGE;
21553+ }
21554+ pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr + dstOffset;
21555+ dstSize = pMbufDst->pFrags[dstFrag].bufSize - dstOffset;
21556+
21557+ while(size > 0)
21558+ {
21559+ copySize = MV_MIN(srcSize, dstSize);
21560+ if(size <= copySize)
21561+ {
21562+ memcpy(pDst, pSrc, size);
21563+ return MV_OK;
21564+ }
21565+ memcpy(pDst, pSrc, copySize);
21566+ size -= copySize;
21567+ srcSize -= copySize;
21568+ dstSize -= copySize;
21569+
21570+ if(srcSize == 0)
21571+ {
21572+ srcFrag++;
21573+ if(srcFrag >= pMbufSrc->numFrags)
21574+ break;
21575+
21576+ pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr;
21577+ srcSize = pMbufSrc->pFrags[srcFrag].bufSize;
21578+ }
21579+
21580+ if(dstSize == 0)
21581+ {
21582+ dstFrag++;
21583+ if(dstFrag >= pMbufDst->numFrags)
21584+ break;
21585+
21586+ pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr;
21587+ dstSize = pMbufDst->pFrags[dstFrag].bufSize;
21588+ }
21589+ }
21590+ mvOsPrintf("mvCesaMbufCopy: BAD size - %d bytes isn't copied\n",
21591+ size);
21592+
21593+ return MV_BAD_SIZE;
21594+}
21595+
21596+static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size)
21597+{
21598+ int frag, fragOffset, bufSize;
21599+ MV_U8* pBuf;
21600+
21601+ if(size == 0)
21602+ return MV_OK;
21603+
21604+ frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
21605+ if(frag == MV_INVALID)
21606+ {
21607+ mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
21608+ return MV_OUT_OF_RANGE;
21609+ }
21610+
21611+ bufSize = pMbuf->pFrags[frag].bufSize - fragOffset;
21612+ pBuf = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
21613+ while(MV_TRUE)
21614+ {
21615+ if(size <= bufSize)
21616+ {
21617+ mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), size);
21618+ return MV_OK;
21619+ }
21620+
21621+ mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), bufSize);
21622+ size -= bufSize;
21623+ frag++;
21624+ if(frag >= pMbuf->numFrags)
21625+ break;
21626+
21627+ bufSize = pMbuf->pFrags[frag].bufSize;
21628+ pBuf = pMbuf->pFrags[frag].bufVirtPtr;
21629+ }
21630+ mvOsPrintf("%s: Mbuf is FULL - %d bytes isn't Unmapped\n",
21631+ __FUNCTION__, size);
21632+ return MV_FULL;
21633+}
21634+
21635+
21636+/*************************************** Local Functions ******************************/
21637+
21638+/*******************************************************************************
21639+* mvCesaFragReqProcess - Process fragmented request
21640+*
21641+* DESCRIPTION:
21642+* This function processes a fragment of fragmented request (First, Middle or Last)
21643+*
21644+*
21645+* INPUT:
21646+* MV_CESA_REQ* pReq - Pointer to the request in the request queue.
21647+*
21648+* RETURN:
21649+* MV_OK - The fragment is successfully passed to HW for processing.
21650+* MV_TERMINATE - Means, that HW finished its work on this packet and no more
21651+* interrupts will be generated for this request.
21652+* Function mvCesaReadyGet() must be called to complete request
21653+* processing and get request result.
21654+*
21655+*******************************************************************************/
21656+static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag)
21657+{
21658+ int i, copySize, cryptoDataSize, macDataSize, sid;
21659+ int cryptoIvOffset, digestOffset;
21660+ MV_U32 config;
21661+ MV_CESA_COMMAND* pCmd = pReq->pCmd;
21662+ MV_CESA_SA* pSA;
21663+ MV_CESA_MBUF* pMbuf;
21664+ MV_DMA_DESC* pDmaDesc = pReq->dma[frag].pDmaFirst;
21665+ MV_U8* pSramBuf = cesaSramVirtPtr->buf;
21666+ int macTotalLen = 0;
21667+ int fixOffset, cryptoOffset, macOffset;
21668+
21669+ cesaStats.fragCount++;
21670+
21671+ sid = pReq->pCmd->sessionId;
21672+
21673+ pSA = &pCesaSAD[sid];
21674+
21675+ cryptoIvOffset = digestOffset = 0;
21676+ i = macDataSize = 0;
21677+ cryptoDataSize = 0;
21678+
21679+ /* First fragment processing */
21680+ if(pReq->fragMode == MV_CESA_FRAG_FIRST)
21681+ {
21682+ /* pReq->frags monitors processing of fragmented request between fragments */
21683+ pReq->frags.bufOffset = 0;
21684+ pReq->frags.cryptoSize = 0;
21685+ pReq->frags.macSize = 0;
21686+
21687+ config = pSA->config | (MV_CESA_FRAG_FIRST << MV_CESA_FRAG_MODE_OFFSET);
21688+
21689+ /* fixOffset can be not equal to zero only for FIRST fragment */
21690+ fixOffset = pReq->fixOffset;
21691+ /* For FIRST fragment crypto and mac offsets are taken from pCmd */
21692+ cryptoOffset = pCmd->cryptoOffset;
21693+ macOffset = pCmd->macOffset;
21694+
21695+ copySize = sizeof(cesaSramVirtPtr->buf) - pReq->fixOffset;
21696+
21697+ /* Find fragment size: Must meet all requirements for CRYPTO and MAC
21698+ * cryptoDataSize - size of data will be encrypted/decrypted in this fragment
21699+ * macDataSize - size of data will be signed/verified in this fragment
21700+ * copySize - size of data will be copied from srcMbuf to SRAM and
21701+ * back to dstMbuf for this fragment
21702+ */
21703+ mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,
21704+ &copySize, &cryptoDataSize, &macDataSize);
21705+
21706+ if( (pSA->config & MV_CESA_OPERATION_MASK) !=
21707+ (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET))
21708+ {
21709+ /* CryptoIV special processing */
21710+ if( (pSA->config & MV_CESA_CRYPTO_MODE_MASK) ==
21711+ (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT) )
21712+ {
21713+ /* In CBC mode for encode direction when IV from user */
21714+ if( (pCmd->ivFromUser) &&
21715+ ((pSA->config & MV_CESA_DIRECTION_MASK) ==
21716+ (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) )
21717+ {
21718+
21719+ /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
21720+ * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
21721+ * in the buffer to SRAM IVPointer
21722+ */
21723+ i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
21724+ MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
21725+ }
21726+
21727+ /* Special processing when IV is not located in the first fragment */
21728+ if(pCmd->ivOffset > (copySize - pSA->cryptoIvSize))
21729+ {
21730+ /* Prepare dummy place for cryptoIV in SRAM */
21731+ cryptoIvOffset = cesaSramVirtPtr->tempCryptoIV - mvCesaSramAddrGet();
21732+
21733+ /* For Decryption: Copy IV value from pCmd->ivOffset to Special SRAM place */
21734+ if((pSA->config & MV_CESA_DIRECTION_MASK) ==
21735+ (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
21736+ {
21737+ i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->tempCryptoIV, &pDmaDesc[i],
21738+ MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
21739+ }
21740+ else
21741+ {
21742+ /* For Encryption when IV is NOT from User: */
21743+ /* Copy IV from SRAM to buffer (pCmd->ivOffset) */
21744+ if(pCmd->ivFromUser == 0)
21745+ {
21746+ /* copy IV value from cryptoIV to Buffer (pCmd->ivOffset) */
21747+ i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
21748+ MV_TRUE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
21749+ }
21750+ }
21751+ }
21752+ else
21753+ {
21754+ cryptoIvOffset = pCmd->ivOffset;
21755+ }
21756+ }
21757+ }
21758+
21759+ if( (pSA->config & MV_CESA_OPERATION_MASK) !=
21760+ (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
21761+ {
21762+ /* MAC digest special processing on Decode direction */
21763+ if((pSA->config & MV_CESA_DIRECTION_MASK) ==
21764+ (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
21765+ {
21766+ /* Save digest from pCmd->digestOffset */
21767+ mvCesaCopyFromMbuf(pReq->frags.orgDigest,
21768+ pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);
21769+
21770+ /* If pCmd->digestOffset is not located on the first */
21771+ if(pCmd->digestOffset > (copySize - pSA->digestSize))
21772+ {
21773+ MV_U8 digestZero[MV_CESA_MAX_DIGEST_SIZE];
21774+
21775+ /* Set zeros to pCmd->digestOffset (DRAM) */
21776+ memset(digestZero, 0, MV_CESA_MAX_DIGEST_SIZE);
21777+ mvCesaCopyToMbuf(digestZero, pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);
21778+
21779+ /* Prepare dummy place for digest in SRAM */
21780+ digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
21781+ }
21782+ else
21783+ {
21784+ digestOffset = pCmd->digestOffset;
21785+ }
21786+ }
21787+ }
21788+ /* Update SA in SRAM */
21789+ if(cesaLastSid != sid)
21790+ {
21791+ mvCesaSramSaUpdate(sid, &pDmaDesc[i]);
21792+ i++;
21793+ }
21794+
21795+ pReq->fragMode = MV_CESA_FRAG_MIDDLE;
21796+ }
21797+ else
21798+ {
21799+ /* Continue fragment */
21800+ fixOffset = 0;
21801+ cryptoOffset = 0;
21802+ macOffset = 0;
21803+ if( (pCmd->pSrc->mbufSize - pReq->frags.bufOffset) <= sizeof(cesaSramVirtPtr->buf))
21804+ {
21805+ /* Last fragment */
21806+ config = pSA->config | (MV_CESA_FRAG_LAST << MV_CESA_FRAG_MODE_OFFSET);
21807+ pReq->fragMode = MV_CESA_FRAG_LAST;
21808+ copySize = pCmd->pSrc->mbufSize - pReq->frags.bufOffset;
21809+
21810+ if( (pSA->config & MV_CESA_OPERATION_MASK) !=
21811+ (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
21812+ {
21813+ macDataSize = pCmd->macLength - pReq->frags.macSize;
21814+
21815+ /* If pCmd->digestOffset is not located on last fragment */
21816+ if(pCmd->digestOffset < pReq->frags.bufOffset)
21817+ {
21818+ /* Prepare dummy place for digest in SRAM */
21819+ digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
21820+ }
21821+ else
21822+ {
21823+ digestOffset = pCmd->digestOffset - pReq->frags.bufOffset;
21824+ }
21825+ pReq->frags.newDigestOffset = digestOffset;
21826+ macTotalLen = pCmd->macLength;
21827+
21828+ /* HW can't calculate the Digest correctly for fragmented packets
21829+ * in the following cases:
21830+ * - MV88F5182 ||
21831+ * - MV88F5181L when total macLength more that 16 Kbytes ||
21832+ * - total macLength more that 64 Kbytes
21833+ */
21834+ if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||
21835+ ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&
21836+ (mvCtrlRevGet() >= MV_5181L_A0_REV) &&
21837+ (pCmd->macLength >= (1 << 14)) ) )
21838+ {
21839+ return MV_TERMINATE;
21840+ }
21841+ }
21842+ if( (pSA->config & MV_CESA_OPERATION_MASK) !=
21843+ (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
21844+ {
21845+ cryptoDataSize = pCmd->cryptoLength - pReq->frags.cryptoSize;
21846+ }
21847+
21848+ /* cryptoIvOffset - don't care */
21849+ }
21850+ else
21851+ {
21852+ /* WA for MV88F5182 SHA1 and MD5 fragmentation mode */
21853+ if( (mvCtrlModelGet() == MV_5182_DEV_ID) &&
21854+ (((pSA->config & MV_CESA_MAC_MODE_MASK) ==
21855+ (MV_CESA_MAC_MD5 << MV_CESA_MAC_MODE_OFFSET)) ||
21856+ ((pSA->config & MV_CESA_MAC_MODE_MASK) ==
21857+ (MV_CESA_MAC_SHA1 << MV_CESA_MAC_MODE_OFFSET))) )
21858+ {
21859+ pReq->frags.newDigestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
21860+ pReq->fragMode = MV_CESA_FRAG_LAST;
21861+
21862+ return MV_TERMINATE;
21863+ }
21864+ /* Middle fragment */
21865+ config = pSA->config | (MV_CESA_FRAG_MIDDLE << MV_CESA_FRAG_MODE_OFFSET);
21866+ copySize = sizeof(cesaSramVirtPtr->buf);
21867+ /* digestOffset and cryptoIvOffset - don't care */
21868+
21869+ /* Find fragment size */
21870+ mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,
21871+ &copySize, &cryptoDataSize, &macDataSize);
21872+ }
21873+ }
21874+ /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
21875+ pMbuf = pCmd->pSrc;
21876+ i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
21877+ MV_FALSE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);
21878+
21879+ /* Prepare CESA descriptor to copy from DRAM to SRAM by DMA */
21880+ mvCesaSramDescrBuild(config, frag,
21881+ cryptoOffset + fixOffset, cryptoIvOffset + fixOffset,
21882+ cryptoDataSize, macOffset + fixOffset,
21883+ digestOffset + fixOffset, macDataSize, macTotalLen,
21884+ pReq, &pDmaDesc[i]);
21885+ i++;
21886+
21887+ /* Add special descriptor Ownership for CPU */
21888+ pDmaDesc[i].byteCnt = 0;
21889+ pDmaDesc[i].phySrcAdd = 0;
21890+ pDmaDesc[i].phyDestAdd = 0;
21891+ i++;
21892+
21893+ /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
21894+ pMbuf = pCmd->pDst;
21895+ i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
21896+ MV_TRUE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);
21897+
21898+ /* Next field of Last DMA descriptor must be NULL */
21899+ pDmaDesc[i-1].phyNextDescPtr = 0;
21900+ pReq->dma[frag].pDmaLast = &pDmaDesc[i-1];
21901+ mvOsCacheFlush(NULL, pReq->dma[frag].pDmaFirst,
21902+ i*sizeof(MV_DMA_DESC));
21903+
21904+ /*mvCesaDebugDescriptor(&cesaSramVirtPtr->desc[frag]);*/
21905+
21906+ pReq->frags.bufOffset += copySize;
21907+ pReq->frags.cryptoSize += cryptoDataSize;
21908+ pReq->frags.macSize += macDataSize;
21909+
21910+ return MV_OK;
21911+}
21912+
21913+
21914+/*******************************************************************************
21915+* mvCesaReqProcess - Process regular (Non-fragmented) request
21916+*
21917+* DESCRIPTION:
21918+* This function processes the whole (not fragmented) request
21919+*
21920+* INPUT:
21921+* MV_CESA_REQ* pReq - Pointer to the request in the request queue.
21922+*
21923+* RETURN:
21924+* MV_OK - The request is successfully passed to HW for processing.
21925+* Other - Failure. The request will not be processed
21926+*
21927+*******************************************************************************/
21928+static MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq)
21929+{
21930+ MV_CESA_MBUF *pMbuf;
21931+ MV_DMA_DESC *pDmaDesc;
21932+ MV_U8 *pSramBuf;
21933+ int sid, i, fixOffset;
21934+ MV_CESA_SA *pSA;
21935+ MV_CESA_COMMAND *pCmd = pReq->pCmd;
21936+
21937+ cesaStats.procCount++;
21938+
21939+ sid = pCmd->sessionId;
21940+ pSA = &pCesaSAD[sid];
21941+ pDmaDesc = pReq->dma[0].pDmaFirst;
21942+ pSramBuf = cesaSramVirtPtr->buf;
21943+ fixOffset = pReq->fixOffset;
21944+
21945+/*
21946+ mvOsPrintf("mvCesaReqProcess: sid=%d, pSA=%p, pDmaDesc=%p, pSramBuf=%p\n",
21947+ sid, pSA, pDmaDesc, pSramBuf);
21948+*/
21949+ i = 0;
21950+
21951+ /* Crypto IV Special processing in CBC mode for Encryption direction */
21952+ if( ((pSA->config & MV_CESA_OPERATION_MASK) != (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) &&
21953+ ((pSA->config & MV_CESA_CRYPTO_MODE_MASK) == (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT)) &&
21954+ ((pSA->config & MV_CESA_DIRECTION_MASK) == (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) &&
21955+ (pCmd->ivFromUser) )
21956+ {
21957+ /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
21958+ * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
21959+ * in the buffer to SRAM IVPointer
21960+ */
21961+ i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
21962+ MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
21963+ }
21964+
21965+ /* Update SA in SRAM */
21966+ if(cesaLastSid != sid)
21967+ {
21968+ mvCesaSramSaUpdate(sid, &pDmaDesc[i]);
21969+ i++;
21970+ }
21971+
21972+ /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
21973+ pMbuf = pCmd->pSrc;
21974+ i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
21975+ MV_FALSE, 0, pMbuf->mbufSize, pCmd->skipFlush);
21976+
21977+ /* Prepare Security Accelerator descriptor to SRAM words 0 - 7 */
21978+ mvCesaSramDescrBuild(pSA->config, 0, pCmd->cryptoOffset + fixOffset,
21979+ pCmd->ivOffset + fixOffset, pCmd->cryptoLength,
21980+ pCmd->macOffset + fixOffset, pCmd->digestOffset + fixOffset,
21981+ pCmd->macLength, pCmd->macLength, pReq, &pDmaDesc[i]);
21982+ i++;
21983+
21984+ /* Add special descriptor Ownership for CPU */
21985+ pDmaDesc[i].byteCnt = 0;
21986+ pDmaDesc[i].phySrcAdd = 0;
21987+ pDmaDesc[i].phyDestAdd = 0;
21988+ i++;
21989+
21990+ /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
21991+ pMbuf = pCmd->pDst;
21992+ i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
21993+ MV_TRUE, 0, pMbuf->mbufSize, pCmd->skipFlush);
21994+
21995+ /* Next field of Last DMA descriptor must be NULL */
21996+ pDmaDesc[i-1].phyNextDescPtr = 0;
21997+ pReq->dma[0].pDmaLast = &pDmaDesc[i-1];
21998+ mvOsCacheFlush(NULL, pReq->dma[0].pDmaFirst, i*sizeof(MV_DMA_DESC));
21999+
22000+ return MV_OK;
22001+}
22002+
22003+
22004+/*******************************************************************************
22005+* mvCesaSramDescrBuild - Set CESA descriptor in SRAM
22006+*
22007+* DESCRIPTION:
22008+* This function builds CESA descriptor in SRAM from all Command parameters
22009+*
22010+*
22011+* INPUT:
22012+* int chan - CESA channel uses the descriptor
22013+* MV_U32 config - 32 bits of WORD_0 in CESA descriptor structure
22014+* int cryptoOffset - Offset from the beginning of SRAM buffer where
22015+* data for encryption/decription is started.
22016+* int ivOffset - Offset of crypto IV from the SRAM base. Valid only
22017+* for first fragment.
22018+* int cryptoLength - Size (in bytes) of data for encryption/descryption
22019+* operation on this fragment.
22020+* int macOffset - Offset from the beginning of SRAM buffer where
22021+* data for Authentication is started
22022+* int digestOffset - Offset from the beginning of SRAM buffer where
22023+* digest is located. Valid for first and last fragments.
22024+* int macLength - Size (in bytes) of data for Authentication
22025+* operation on this fragment.
22026+* int macTotalLen - Toatl size (in bytes) of data for Authentication
22027+* operation on the whole request (packet). Valid for
22028+* last fragment only.
22029+*
22030+* RETURN: None
22031+*
22032+*******************************************************************************/
22033+static void mvCesaSramDescrBuild(MV_U32 config, int frag,
22034+ int cryptoOffset, int ivOffset, int cryptoLength,
22035+ int macOffset, int digestOffset, int macLength,
22036+ int macTotalLen, MV_CESA_REQ* pReq, MV_DMA_DESC* pDmaDesc)
22037+{
22038+ MV_CESA_DESC* pCesaDesc = &pReq->pCesaDesc[frag];
22039+ MV_CESA_DESC* pSramDesc = pSramDesc = &cesaSramVirtPtr->desc;
22040+ MV_U16 sramBufOffset = (MV_U16)((MV_U8*)cesaSramVirtPtr->buf - mvCesaSramAddrGet());
22041+
22042+ pCesaDesc->config = MV_32BIT_LE(config);
22043+
22044+ if( (config & MV_CESA_OPERATION_MASK) !=
22045+ (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
22046+ {
22047+ /* word 1 */
22048+ pCesaDesc->cryptoSrcOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);
22049+ pCesaDesc->cryptoDstOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);
22050+ /* word 2 */
22051+ pCesaDesc->cryptoDataLen = MV_16BIT_LE(cryptoLength);
22052+ /* word 3 */
22053+ pCesaDesc->cryptoKeyOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.cryptoKey -
22054+ mvCesaSramAddrGet()));
22055+ /* word 4 */
22056+ pCesaDesc->cryptoIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->cryptoIV -
22057+ mvCesaSramAddrGet()));
22058+ pCesaDesc->cryptoIvBufOffset = MV_16BIT_LE(sramBufOffset + ivOffset);
22059+ }
22060+
22061+ if( (config & MV_CESA_OPERATION_MASK) !=
22062+ (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
22063+ {
22064+ /* word 5 */
22065+ pCesaDesc->macSrcOffset = MV_16BIT_LE(sramBufOffset + macOffset);
22066+ pCesaDesc->macTotalLen = MV_16BIT_LE(macTotalLen);
22067+
22068+ /* word 6 */
22069+ pCesaDesc->macDigestOffset = MV_16BIT_LE(sramBufOffset + digestOffset);
22070+ pCesaDesc->macDataLen = MV_16BIT_LE(macLength);
22071+
22072+ /* word 7 */
22073+ pCesaDesc->macInnerIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macInnerIV -
22074+ mvCesaSramAddrGet()));
22075+ pCesaDesc->macOuterIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macOuterIV -
22076+ mvCesaSramAddrGet()));
22077+ }
22078+ /* Prepare DMA descriptor to CESA descriptor from DRAM to SRAM */
22079+ pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&pReq->cesaDescBuf, pCesaDesc));
22080+ pDmaDesc->phyDestAdd = MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)pSramDesc));
22081+ pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_DESC) | BIT31);
22082+
22083+ /* flush Source buffer */
22084+ mvOsCacheFlush(NULL, pCesaDesc, sizeof(MV_CESA_DESC));
22085+}
22086+
22087+/*******************************************************************************
22088+* mvCesaSramSaUpdate - Move required SA information to SRAM if needed.
22089+*
22090+* DESCRIPTION:
22091+* Copy to SRAM values of the required SA.
22092+*
22093+*
22094+* INPUT:
22095+* short sid - Session ID needs SRAM Cache update
22096+* MV_DMA_DESC *pDmaDesc - Pointer to DMA descriptor used to
22097+* copy SA values from DRAM to SRAM.
22098+*
22099+* RETURN:
22100+* MV_OK - Cache entry for this SA copied to SRAM.
22101+* MV_NO_CHANGE - Cache entry for this SA already exist in SRAM
22102+*
22103+*******************************************************************************/
22104+static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc)
22105+{
22106+ MV_CESA_SA *pSA = &pCesaSAD[sid];
22107+
22108+ /* Prepare DMA descriptor to Copy CACHE_SA from SA database in DRAM to SRAM */
22109+ pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_SRAM_SA) | BIT31);
22110+ pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&cesaSramSaBuf, pSA->pSramSA));
22111+ pDmaDesc->phyDestAdd =
22112+ MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)&cesaSramVirtPtr->sramSA));
22113+
22114+ /* Source buffer is already flushed during OpenSession*/
22115+ /*mvOsCacheFlush(NULL, &pSA->sramSA, sizeof(MV_CESA_SRAM_SA));*/
22116+}
22117+
22118+/*******************************************************************************
22119+* mvCesaDmaCopyPrepare - prepare DMA descriptor list to copy data presented by
22120+* Mbuf structure from DRAM to SRAM
22121+*
22122+* DESCRIPTION:
22123+*
22124+*
22125+* INPUT:
22126+* MV_CESA_MBUF* pMbuf - pointer to Mbuf structure contains request
22127+* data in DRAM
22128+* MV_U8* pSramBuf - pointer to buffer in SRAM where data should
22129+* be copied to.
22130+* MV_DMA_DESC* pDmaDesc - pointer to first DMA descriptor for this copy.
22131+* The function set number of DMA descriptors needed
22132+* to copy the copySize bytes from Mbuf.
22133+* MV_BOOL isToMbuf - Copy direction.
22134+* MV_TRUE means copy from SRAM buffer to Mbuf in DRAM.
22135+* MV_FALSE means copy from Mbuf in DRAM to SRAM buffer.
22136+* int offset - Offset in the Mbuf structure that copy should be
22137+* started from.
22138+* int copySize - Size of data should be copied.
22139+*
22140+* RETURN:
22141+* int - number of DMA descriptors used for the copy.
22142+*
22143+*******************************************************************************/
22144+#ifndef MV_NETBSD
22145+static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
22146+ MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
22147+ int offset, int copySize, MV_BOOL skipFlush)
22148+{
22149+ int bufOffset, bufSize, size, frag, i;
22150+ MV_U8* pBuf;
22151+
22152+ i = 0;
22153+
22154+ /* Calculate start place for copy: fragment number and offset in the fragment */
22155+ frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);
22156+ bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;
22157+ pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;
22158+
22159+ /* Size accumulate total copy size */
22160+ size = 0;
22161+
22162+ /* Create DMA lists to copy mBuf from pSrc to SRAM */
22163+ while(size < copySize)
22164+ {
22165+ /* Find copy size for each DMA descriptor */
22166+ bufSize = MV_MIN(bufSize, (copySize - size));
22167+ pDmaDesc[i].byteCnt = MV_32BIT_LE(bufSize | BIT31);
22168+ if(isToMbuf)
22169+ {
22170+ pDmaDesc[i].phyDestAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
22171+ pDmaDesc[i].phySrcAdd =
22172+ MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));
22173+ /* invalidate the buffer */
22174+ if(skipFlush == MV_FALSE)
22175+ mvOsCacheInvalidate(NULL, pBuf, bufSize);
22176+ }
22177+ else
22178+ {
22179+ pDmaDesc[i].phySrcAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
22180+ pDmaDesc[i].phyDestAdd =
22181+ MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));
22182+ /* flush the buffer */
22183+ if(skipFlush == MV_FALSE)
22184+ mvOsCacheFlush(NULL, pBuf, bufSize);
22185+ }
22186+
22187+ /* Count number of used DMA descriptors */
22188+ i++;
22189+ size += bufSize;
22190+
22191+ /* go to next fragment in the Mbuf */
22192+ frag++;
22193+ pBuf = pMbuf->pFrags[frag].bufVirtPtr;
22194+ bufSize = pMbuf->pFrags[frag].bufSize;
22195+ }
22196+ return i;
22197+}
22198+#else /* MV_NETBSD */
22199+static int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
22200+ MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
22201+ int offset, int copySize, MV_BOOL skipFlush)
22202+{
22203+ int bufOffset, bufSize, thisSize, size, frag, i;
22204+ MV_ULONG bufPhys, sramPhys;
22205+ MV_U8* pBuf;
22206+
22207+ /*
22208+ * Calculate start place for copy: fragment number and offset in
22209+ * the fragment
22210+ */
22211+ frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);
22212+
22213+ /*
22214+ * Get SRAM physical address only once. We can update it in-place
22215+ * as we build the descriptor chain.
22216+ */
22217+ sramPhys = mvCesaSramVirtToPhys(NULL, pSramBuf);
22218+
22219+ /*
22220+ * 'size' accumulates total copy size, 'i' counts desccriptors.
22221+ */
22222+ size = i = 0;
22223+
22224+ /* Create DMA lists to copy mBuf from pSrc to SRAM */
22225+ while (size < copySize) {
22226+ /*
22227+ * Calculate # of bytes to copy from the current fragment,
22228+ * and the pointer to the start of data
22229+ */
22230+ bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;
22231+ pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;
22232+ bufOffset = 0; /* First frag may be non-zero */
22233+ frag++;
22234+
22235+ /*
22236+ * As long as there is data in the current fragment...
22237+ */
22238+ while (bufSize > 0) {
22239+ /*
22240+ * Ensure we don't cross an MMU page boundary.
22241+ * XXX: This is NetBSD-specific, but it is a
22242+ * quick and dirty way to fix the problem.
22243+ * A true HAL would rely on the OS-specific
22244+ * driver to do this...
22245+ */
22246+ thisSize = PAGE_SIZE -
22247+ (((MV_ULONG)pBuf) & (PAGE_SIZE - 1));
22248+ thisSize = MV_MIN(bufSize, thisSize);
22249+ /*
22250+ * Make sure we don't copy more than requested
22251+ */
22252+ if (thisSize > (copySize - size)) {
22253+ thisSize = copySize - size;
22254+ bufSize = 0;
22255+ }
22256+
22257+ /*
22258+ * Physicall address of this fragment
22259+ */
22260+ bufPhys = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
22261+
22262+ /*
22263+ * Set up the descriptor
22264+ */
22265+ pDmaDesc[i].byteCnt = MV_32BIT_LE(thisSize | BIT31);
22266+ if(isToMbuf) {
22267+ pDmaDesc[i].phyDestAdd = bufPhys;
22268+ pDmaDesc[i].phySrcAdd = MV_32BIT_LE(sramPhys);
22269+ /* invalidate the buffer */
22270+ if(skipFlush == MV_FALSE)
22271+ mvOsCacheInvalidate(NULL, pBuf, thisSize);
22272+ } else {
22273+ pDmaDesc[i].phySrcAdd = bufPhys;
22274+ pDmaDesc[i].phyDestAdd = MV_32BIT_LE(sramPhys);
22275+ /* flush the buffer */
22276+ if(skipFlush == MV_FALSE)
22277+ mvOsCacheFlush(NULL, pBuf, thisSize);
22278+ }
22279+
22280+ pDmaDesc[i].phyNextDescPtr =
22281+ MV_32BIT_LE(mvOsIoVirtToPhy(NULL,(&pDmaDesc[i+1])));
22282+
22283+ /* flush the DMA desc */
22284+ mvOsCacheFlush(NULL, &pDmaDesc[i], sizeof(MV_DMA_DESC));
22285+
22286+ /* Update state */
22287+ bufSize -= thisSize;
22288+ sramPhys += thisSize;
22289+ pBuf += thisSize;
22290+ size += thisSize;
22291+ i++;
22292+ }
22293+ }
22294+
22295+ return i;
22296+}
22297+#endif /* MV_NETBSD */
22298+/*******************************************************************************
22299+* mvCesaHmacIvGet - Calculate Inner and Outter values from HMAC key
22300+*
22301+* DESCRIPTION:
22302+* This function calculate Inner and Outer values used for HMAC algorithm.
22303+* This operation allows improve performance fro the whole HMAC processing.
22304+*
22305+* INPUT:
22306+* MV_CESA_MAC_MODE macMode - Authentication mode: HMAC_MD5 or HMAC_SHA1.
22307+* unsigned char key[] - Pointer to HMAC key.
22308+* int keyLength - Size of HMAC key (maximum 64 bytes)
22309+*
22310+* OUTPUT:
22311+* unsigned char innerIV[] - HASH(key^inner)
22312+* unsigned char outerIV[] - HASH(key^outter)
22313+*
22314+* RETURN: None
22315+*
22316+*******************************************************************************/
22317+static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,
22318+ unsigned char innerIV[], unsigned char outerIV[])
22319+{
22320+ unsigned char inner[MV_CESA_MAX_MAC_KEY_LENGTH];
22321+ unsigned char outer[MV_CESA_MAX_MAC_KEY_LENGTH];
22322+ int i, digestSize = 0;
22323+#if defined(MV_CPU_LE) || defined(MV_PPC)
22324+ MV_U32 swapped32, val32, *pVal32;
22325+#endif
22326+ for(i=0; i<keyLength; i++)
22327+ {
22328+ inner[i] = 0x36 ^ key[i];
22329+ outer[i] = 0x5c ^ key[i];
22330+ }
22331+
22332+ for(i=keyLength; i<MV_CESA_MAX_MAC_KEY_LENGTH; i++)
22333+ {
22334+ inner[i] = 0x36;
22335+ outer[i] = 0x5c;
22336+ }
22337+ if(macMode == MV_CESA_MAC_HMAC_MD5)
22338+ {
22339+ MV_MD5_CONTEXT ctx;
22340+
22341+ mvMD5Init(&ctx);
22342+ mvMD5Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);
22343+
22344+ memcpy(innerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);
22345+ memset(&ctx, 0, sizeof(ctx));
22346+
22347+ mvMD5Init(&ctx);
22348+ mvMD5Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);
22349+ memcpy(outerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);
22350+ memset(&ctx, 0, sizeof(ctx));
22351+ digestSize = MV_CESA_MD5_DIGEST_SIZE;
22352+ }
22353+ else if(macMode == MV_CESA_MAC_HMAC_SHA1)
22354+ {
22355+ MV_SHA1_CTX ctx;
22356+
22357+ mvSHA1Init(&ctx);
22358+ mvSHA1Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);
22359+ memcpy(innerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);
22360+ memset(&ctx, 0, sizeof(ctx));
22361+
22362+ mvSHA1Init(&ctx);
22363+ mvSHA1Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);
22364+ memcpy(outerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);
22365+ memset(&ctx, 0, sizeof(ctx));
22366+ digestSize = MV_CESA_SHA1_DIGEST_SIZE;
22367+ }
22368+ else
22369+ {
22370+ mvOsPrintf("hmacGetIV: Unexpected macMode %d\n", macMode);
22371+ }
22372+#if defined(MV_CPU_LE) || defined(MV_PPC)
22373+ /* 32 bits Swap of Inner and Outer values */
22374+ pVal32 = (MV_U32*)innerIV;
22375+ for(i=0; i<digestSize/4; i++)
22376+ {
22377+ val32 = *pVal32;
22378+ swapped32 = MV_BYTE_SWAP_32BIT(val32);
22379+ *pVal32 = swapped32;
22380+ pVal32++;
22381+ }
22382+ pVal32 = (MV_U32*)outerIV;
22383+ for(i=0; i<digestSize/4; i++)
22384+ {
22385+ val32 = *pVal32;
22386+ swapped32 = MV_BYTE_SWAP_32BIT(val32);
22387+ *pVal32 = swapped32;
22388+ pVal32++;
22389+ }
22390+#endif /* defined(MV_CPU_LE) || defined(MV_PPC) */
22391+}
22392+
22393+
22394+/*******************************************************************************
22395+* mvCesaFragSha1Complete - Complete SHA1 authentication started by HW using SW
22396+*
22397+* DESCRIPTION:
22398+*
22399+*
22400+* INPUT:
22401+* MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
22402+* for SHA1 is placed.
22403+* int offset - Offset in the Mbuf structure where
22404+* unprocessed data for SHA1 is started.
22405+* MV_U8* pOuterIV - Pointer to OUTER for this session.
22406+* If pOuterIV==NULL - MAC mode is HASH_SHA1
22407+* If pOuterIV!=NULL - MAC mode is HMAC_SHA1
22408+* int macLeftSize - Size of unprocessed data for SHA1.
22409+* int macTotalSize - Total size of data for SHA1 in the
22410+* request (processed + unprocessed)
22411+*
22412+* OUTPUT:
22413+* MV_U8* pDigest - Pointer to place where calculated Digest will
22414+* be stored.
22415+*
22416+* RETURN: None
22417+*
22418+*******************************************************************************/
22419+static void mvCesaFragSha1Complete(MV_CESA_MBUF* pMbuf, int offset,
22420+ MV_U8* pOuterIV, int macLeftSize,
22421+ int macTotalSize, MV_U8* pDigest)
22422+{
22423+ MV_SHA1_CTX ctx;
22424+ MV_U8 *pData;
22425+ int i, frag, fragOffset, size;
22426+
22427+ /* Read temporary Digest from HW */
22428+ for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)
22429+ {
22430+ ctx.state[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));
22431+ }
22432+ /* Initialize MV_SHA1_CTX structure */
22433+ memset(ctx.buffer, 0, 64);
22434+ /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
22435+ /* so count[1] is always 0 */
22436+ ctx.count[0] = ((macTotalSize - macLeftSize) * 8);
22437+ ctx.count[1] = 0;
22438+
22439+ /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
22440+ if(pOuterIV != NULL)
22441+ ctx.count[0] += (64 * 8);
22442+
22443+ /* Get place of unprocessed data in the Mbuf structure */
22444+ frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
22445+ if(frag == MV_INVALID)
22446+ {
22447+ mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
22448+ return;
22449+ }
22450+
22451+ pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
22452+ size = pMbuf->pFrags[frag].bufSize - fragOffset;
22453+
22454+ /* Complete Inner part */
22455+ while(macLeftSize > 0)
22456+ {
22457+ if(macLeftSize <= size)
22458+ {
22459+ mvSHA1Update(&ctx, pData, macLeftSize);
22460+ break;
22461+ }
22462+ mvSHA1Update(&ctx, pData, size);
22463+ macLeftSize -= size;
22464+ frag++;
22465+ pData = pMbuf->pFrags[frag].bufVirtPtr;
22466+ size = pMbuf->pFrags[frag].bufSize;
22467+ }
22468+ mvSHA1Final(pDigest, &ctx);
22469+/*
22470+ mvOsPrintf("mvCesaFragSha1Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
22471+ pOuterIV, macLeftSize, macTotalSize);
22472+ mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);
22473+*/
22474+
22475+ if(pOuterIV != NULL)
22476+ {
22477+ /* If HMAC - Complete Outer part */
22478+ for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)
22479+ {
22480+#if defined(MV_CPU_LE) || defined(MV_ARM)
22481+ ctx.state[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);
22482+#else
22483+ ctx.state[i] = ((MV_U32*)pOuterIV)[i];
22484+#endif
22485+ }
22486+ memset(ctx.buffer, 0, 64);
22487+
22488+ ctx.count[0] = 64*8;
22489+ ctx.count[1] = 0;
22490+ mvSHA1Update(&ctx, pDigest, MV_CESA_SHA1_DIGEST_SIZE);
22491+ mvSHA1Final(pDigest, &ctx);
22492+ }
22493+}
22494+
22495+/*******************************************************************************
22496+* mvCesaFragMd5Complete - Complete MD5 authentication started by HW using SW
22497+*
22498+* DESCRIPTION:
22499+*
22500+*
22501+* INPUT:
22502+* MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
22503+* for SHA1 is placed.
22504+* int offset - Offset in the Mbuf structure where
22505+* unprocessed data for MD5 is started.
22506+* MV_U8* pOuterIV - Pointer to OUTER for this session.
22507+* If pOuterIV==NULL - MAC mode is HASH_MD5
22508+* If pOuterIV!=NULL - MAC mode is HMAC_MD5
22509+* int macLeftSize - Size of unprocessed data for MD5.
22510+* int macTotalSize - Total size of data for MD5 in the
22511+* request (processed + unprocessed)
22512+*
22513+* OUTPUT:
22514+* MV_U8* pDigest - Pointer to place where calculated Digest will
22515+* be stored.
22516+*
22517+* RETURN: None
22518+*
22519+*******************************************************************************/
22520+static void mvCesaFragMd5Complete(MV_CESA_MBUF* pMbuf, int offset,
22521+ MV_U8* pOuterIV, int macLeftSize,
22522+ int macTotalSize, MV_U8* pDigest)
22523+{
22524+ MV_MD5_CONTEXT ctx;
22525+ MV_U8 *pData;
22526+ int i, frag, fragOffset, size;
22527+
22528+ /* Read temporary Digest from HW */
22529+ for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)
22530+ {
22531+ ctx.buf[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));
22532+ }
22533+ memset(ctx.in, 0, 64);
22534+
22535+ /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
22536+ /* so count[1] is always 0 */
22537+ ctx.bits[0] = ((macTotalSize - macLeftSize) * 8);
22538+ ctx.bits[1] = 0;
22539+
22540+ /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
22541+ if(pOuterIV != NULL)
22542+ ctx.bits[0] += (64 * 8);
22543+
22544+ frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
22545+ if(frag == MV_INVALID)
22546+ {
22547+ mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
22548+ return;
22549+ }
22550+
22551+ pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
22552+ size = pMbuf->pFrags[frag].bufSize - fragOffset;
22553+
22554+ /* Complete Inner part */
22555+ while(macLeftSize > 0)
22556+ {
22557+ if(macLeftSize <= size)
22558+ {
22559+ mvMD5Update(&ctx, pData, macLeftSize);
22560+ break;
22561+ }
22562+ mvMD5Update(&ctx, pData, size);
22563+ macLeftSize -= size;
22564+ frag++;
22565+ pData = pMbuf->pFrags[frag].bufVirtPtr;
22566+ size = pMbuf->pFrags[frag].bufSize;
22567+ }
22568+ mvMD5Final(pDigest, &ctx);
22569+
22570+/*
22571+ mvOsPrintf("mvCesaFragMd5Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
22572+ pOuterIV, macLeftSize, macTotalSize);
22573+ mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);
22574+*/
22575+ if(pOuterIV != NULL)
22576+ {
22577+ /* Complete Outer part */
22578+ for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)
22579+ {
22580+#if defined(MV_CPU_LE) || defined(MV_ARM)
22581+ ctx.buf[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);
22582+#else
22583+ ctx.buf[i] = ((MV_U32*)pOuterIV)[i];
22584+#endif
22585+ }
22586+ memset(ctx.in, 0, 64);
22587+
22588+ ctx.bits[0] = 64*8;
22589+ ctx.bits[1] = 0;
22590+ mvMD5Update(&ctx, pDigest, MV_CESA_MD5_DIGEST_SIZE);
22591+ mvMD5Final(pDigest, &ctx);
22592+ }
22593+}
22594+
22595+/*******************************************************************************
22596+* mvCesaFragAuthComplete -
22597+*
22598+* DESCRIPTION:
22599+*
22600+*
22601+* INPUT:
22602+* MV_CESA_REQ* pReq,
22603+* MV_CESA_SA* pSA,
22604+* int macDataSize
22605+*
22606+* RETURN:
22607+* MV_STATUS
22608+*
22609+*******************************************************************************/
22610+static MV_STATUS mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,
22611+ int macDataSize)
22612+{
22613+ MV_CESA_COMMAND* pCmd = pReq->pCmd;
22614+ MV_U8* pDigest;
22615+ MV_CESA_MAC_MODE macMode;
22616+ MV_U8* pOuterIV = NULL;
22617+
22618+ /* Copy data from Source fragment to Destination */
22619+ if(pCmd->pSrc != pCmd->pDst)
22620+ {
22621+ mvCesaMbufCopy(pCmd->pDst, pReq->frags.bufOffset,
22622+ pCmd->pSrc, pReq->frags.bufOffset, macDataSize);
22623+ }
22624+
22625+/*
22626+ mvCesaCopyFromMbuf(cesaSramVirtPtr->buf[0], pCmd->pSrc, pReq->frags.bufOffset, macDataSize);
22627+ mvCesaCopyToMbuf(cesaSramVirtPtr->buf[0], pCmd->pDst, pReq->frags.bufOffset, macDataSize);
22628+*/
22629+ pDigest = (mvCesaSramAddrGet() + pReq->frags.newDigestOffset);
22630+
22631+ macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;
22632+/*
22633+ mvOsPrintf("macDataSize=%d, macLength=%d, digestOffset=%d, macMode=%d\n",
22634+ macDataSize, pCmd->macLength, pCmd->digestOffset, macMode);
22635+*/
22636+ switch(macMode)
22637+ {
22638+ case MV_CESA_MAC_HMAC_MD5:
22639+ pOuterIV = pSA->pSramSA->macOuterIV;
22640+
22641+ case MV_CESA_MAC_MD5:
22642+ mvCesaFragMd5Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,
22643+ macDataSize, pCmd->macLength, pDigest);
22644+ break;
22645+
22646+ case MV_CESA_MAC_HMAC_SHA1:
22647+ pOuterIV = pSA->pSramSA->macOuterIV;
22648+
22649+ case MV_CESA_MAC_SHA1:
22650+ mvCesaFragSha1Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,
22651+ macDataSize, pCmd->macLength, pDigest);
22652+ break;
22653+
22654+ default:
22655+ mvOsPrintf("mvCesaFragAuthComplete: Unexpected macMode %d\n", macMode);
22656+ return MV_BAD_PARAM;
22657+ }
22658+ return MV_OK;
22659+}
22660+
22661+/*******************************************************************************
22662+* mvCesaCtrModeInit -
22663+*
22664+* DESCRIPTION:
22665+*
22666+*
22667+* INPUT: NONE
22668+*
22669+*
22670+* RETURN:
22671+* MV_CESA_COMMAND*
22672+*
22673+*******************************************************************************/
22674+static MV_CESA_COMMAND* mvCesaCtrModeInit(void)
22675+{
22676+ MV_CESA_MBUF *pMbuf;
22677+ MV_U8 *pBuf;
22678+ MV_CESA_COMMAND *pCmd;
22679+
22680+ pBuf = mvOsMalloc(sizeof(MV_CESA_COMMAND) +
22681+ sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) + 100);
22682+ if(pBuf == NULL)
22683+ {
22684+ mvOsPrintf("mvCesaSessionOpen: Can't allocate %u bytes for CTR Mode\n",
22685+ sizeof(MV_CESA_COMMAND) + sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) );
22686+ return NULL;
22687+ }
22688+ pCmd = (MV_CESA_COMMAND*)pBuf;
22689+ pBuf += sizeof(MV_CESA_COMMAND);
22690+
22691+ pMbuf = (MV_CESA_MBUF*)pBuf;
22692+ pBuf += sizeof(MV_CESA_MBUF);
22693+
22694+ pMbuf->pFrags = (MV_BUF_INFO*)pBuf;
22695+
22696+ pMbuf->numFrags = 1;
22697+ pCmd->pSrc = pMbuf;
22698+ pCmd->pDst = pMbuf;
22699+/*
22700+ mvOsPrintf("CtrModeInit: pCmd=%p, pSrc=%p, pDst=%p, pFrags=%p\n",
22701+ pCmd, pCmd->pSrc, pCmd->pDst,
22702+ pMbuf->pFrags);
22703+*/
22704+ return pCmd;
22705+}
22706+
22707+/*******************************************************************************
22708+* mvCesaCtrModePrepare -
22709+*
22710+* DESCRIPTION:
22711+*
22712+*
22713+* INPUT:
22714+* MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd
22715+*
22716+* RETURN:
22717+* MV_STATUS
22718+*
22719+*******************************************************************************/
22720+static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd)
22721+{
22722+ MV_CESA_MBUF *pMbuf;
22723+ MV_U8 *pBuf, *pIV;
22724+ MV_U32 counter, *pCounter;
22725+ int cryptoSize = MV_ALIGN_UP(pCmd->cryptoLength, MV_CESA_AES_BLOCK_SIZE);
22726+/*
22727+ mvOsPrintf("CtrModePrepare: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
22728+ pCmd, pCmd->pSrc, pCmd->pDst,
22729+ pCtrModeCmd, pCtrModeCmd->pSrc, pCtrModeCmd->pDst);
22730+*/
22731+ pMbuf = pCtrModeCmd->pSrc;
22732+
22733+ /* Allocate buffer for Key stream */
22734+ pBuf = mvOsIoCachedMalloc(cesaOsHandle,cryptoSize,
22735+ &pMbuf->pFrags[0].bufPhysAddr,
22736+ &pMbuf->pFrags[0].memHandle);
22737+ if(pBuf == NULL)
22738+ {
22739+ mvOsPrintf("mvCesaCtrModePrepare: Can't allocate %d bytes\n", cryptoSize);
22740+ return MV_OUT_OF_CPU_MEM;
22741+ }
22742+ memset(pBuf, 0, cryptoSize);
22743+ mvOsCacheFlush(NULL, pBuf, cryptoSize);
22744+
22745+ pMbuf->pFrags[0].bufVirtPtr = pBuf;
22746+ pMbuf->mbufSize = cryptoSize;
22747+ pMbuf->pFrags[0].bufSize = cryptoSize;
22748+
22749+ pCtrModeCmd->pReqPrv = pCmd->pReqPrv;
22750+ pCtrModeCmd->sessionId = pCmd->sessionId;
22751+
22752+ /* ivFromUser and ivOffset are don't care */
22753+ pCtrModeCmd->cryptoOffset = 0;
22754+ pCtrModeCmd->cryptoLength = cryptoSize;
22755+
22756+ /* digestOffset, macOffset and macLength are don't care */
22757+
22758+ mvCesaCopyFromMbuf(pBuf, pCmd->pSrc, pCmd->ivOffset, MV_CESA_AES_BLOCK_SIZE);
22759+ pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));
22760+ counter = *pCounter;
22761+ counter = MV_32BIT_BE(counter);
22762+ pIV = pBuf;
22763+ cryptoSize -= MV_CESA_AES_BLOCK_SIZE;
22764+
22765+ /* fill key stream */
22766+ while(cryptoSize > 0)
22767+ {
22768+ pBuf += MV_CESA_AES_BLOCK_SIZE;
22769+ memcpy(pBuf, pIV, MV_CESA_AES_BLOCK_SIZE - sizeof(counter));
22770+ pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));
22771+ counter++;
22772+ *pCounter = MV_32BIT_BE(counter);
22773+ cryptoSize -= MV_CESA_AES_BLOCK_SIZE;
22774+ }
22775+
22776+ return MV_OK;
22777+}
22778+
22779+/*******************************************************************************
22780+* mvCesaCtrModeComplete -
22781+*
22782+* DESCRIPTION:
22783+*
22784+*
22785+* INPUT:
22786+* MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd
22787+*
22788+* RETURN:
22789+* MV_STATUS
22790+*
22791+*******************************************************************************/
22792+static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd)
22793+{
22794+ int srcFrag, dstFrag, srcOffset, dstOffset, keyOffset, srcSize, dstSize;
22795+ int cryptoSize = pCmd->cryptoLength;
22796+ MV_U8 *pSrc, *pDst, *pKey;
22797+ MV_STATUS status = MV_OK;
22798+/*
22799+ mvOsPrintf("CtrModeComplete: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
22800+ pCmd, pCmd->pSrc, pCmd->pDst,
22801+ pOrgCmd, pOrgCmd->pSrc, pOrgCmd->pDst);
22802+*/
22803+ /* XOR source data with key stream to destination data */
22804+ pKey = pCmd->pDst->pFrags[0].bufVirtPtr;
22805+ keyOffset = 0;
22806+
22807+ if( (pOrgCmd->pSrc != pOrgCmd->pDst) &&
22808+ (pOrgCmd->cryptoOffset > 0) )
22809+ {
22810+ /* Copy Prefix from source buffer to destination buffer */
22811+
22812+ status = mvCesaMbufCopy(pOrgCmd->pDst, 0,
22813+ pOrgCmd->pSrc, 0, pOrgCmd->cryptoOffset);
22814+/*
22815+ status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
22816+ 0, pOrgCmd->cryptoOffset);
22817+ status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
22818+ 0, pOrgCmd->cryptoOffset);
22819+*/
22820+ }
22821+
22822+ srcFrag = mvCesaMbufOffset(pOrgCmd->pSrc, pOrgCmd->cryptoOffset, &srcOffset);
22823+ pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;
22824+ srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;
22825+
22826+ dstFrag = mvCesaMbufOffset(pOrgCmd->pDst, pOrgCmd->cryptoOffset, &dstOffset);
22827+ pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;
22828+ dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;
22829+
22830+ while(cryptoSize > 0)
22831+ {
22832+ pDst[dstOffset] = (pSrc[srcOffset] ^ pKey[keyOffset]);
22833+
22834+ cryptoSize--;
22835+ dstOffset++;
22836+ srcOffset++;
22837+ keyOffset++;
22838+
22839+ if(srcOffset >= srcSize)
22840+ {
22841+ srcFrag++;
22842+ srcOffset = 0;
22843+ pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;
22844+ srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;
22845+ }
22846+
22847+ if(dstOffset >= dstSize)
22848+ {
22849+ dstFrag++;
22850+ dstOffset = 0;
22851+ pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;
22852+ dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;
22853+ }
22854+ }
22855+
22856+ if(pOrgCmd->pSrc != pOrgCmd->pDst)
22857+ {
22858+ /* Copy Suffix from source buffer to destination buffer */
22859+ srcOffset = pOrgCmd->cryptoOffset + pOrgCmd->cryptoLength;
22860+
22861+ if( (pOrgCmd->pDst->mbufSize - srcOffset) > 0)
22862+ {
22863+ status = mvCesaMbufCopy(pOrgCmd->pDst, srcOffset,
22864+ pOrgCmd->pSrc, srcOffset,
22865+ pOrgCmd->pDst->mbufSize - srcOffset);
22866+ }
22867+
22868+/*
22869+ status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
22870+ srcOffset, pOrgCmd->pSrc->mbufSize - srcOffset);
22871+ status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
22872+ srcOffset, pOrgCmd->pDst->mbufSize - srcOffset);
22873+*/
22874+ }
22875+
22876+ /* Free buffer used for Key stream */
22877+ mvOsIoCachedFree(cesaOsHandle,pCmd->pDst->pFrags[0].bufSize,
22878+ pCmd->pDst->pFrags[0].bufPhysAddr,
22879+ pCmd->pDst->pFrags[0].bufVirtPtr,
22880+ pCmd->pDst->pFrags[0].memHandle);
22881+
22882+ return MV_OK;
22883+}
22884+
22885+/*******************************************************************************
22886+* mvCesaCtrModeFinish -
22887+*
22888+* DESCRIPTION:
22889+*
22890+*
22891+* INPUT:
22892+* MV_CESA_COMMAND* pCmd
22893+*
22894+* RETURN:
22895+* MV_STATUS
22896+*
22897+*******************************************************************************/
22898+static void mvCesaCtrModeFinish(MV_CESA_COMMAND* pCmd)
22899+{
22900+ mvOsFree(pCmd);
22901+}
22902+
22903+/*******************************************************************************
22904+* mvCesaParamCheck -
22905+*
22906+* DESCRIPTION:
22907+*
22908+*
22909+* INPUT:
22910+* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset
22911+*
22912+* RETURN:
22913+* MV_STATUS
22914+*
22915+*******************************************************************************/
22916+static MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,
22917+ MV_U8* pFixOffset)
22918+{
22919+ MV_U8 fixOffset = 0xFF;
22920+
22921+ /* Check AUTH operation parameters */
22922+ if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
22923+ (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )
22924+ {
22925+ /* MAC offset should be at least 4 byte aligned */
22926+ if( MV_IS_NOT_ALIGN(pCmd->macOffset, 4) )
22927+ {
22928+ mvOsPrintf("mvCesaAction: macOffset %d must be 4 byte aligned\n",
22929+ pCmd->macOffset);
22930+ return MV_BAD_PARAM;
22931+ }
22932+ /* Digest offset must be 4 byte aligned */
22933+ if( MV_IS_NOT_ALIGN(pCmd->digestOffset, 4) )
22934+ {
22935+ mvOsPrintf("mvCesaAction: digestOffset %d must be 4 byte aligned\n",
22936+ pCmd->digestOffset);
22937+ return MV_BAD_PARAM;
22938+ }
22939+ /* In addition all offsets should be the same alignment: 8 or 4 */
22940+ if(fixOffset == 0xFF)
22941+ {
22942+ fixOffset = (pCmd->macOffset % 8);
22943+ }
22944+ else
22945+ {
22946+ if( (pCmd->macOffset % 8) != fixOffset)
22947+ {
22948+ mvOsPrintf("mvCesaAction: macOffset %d mod 8 must be equal %d\n",
22949+ pCmd->macOffset, fixOffset);
22950+ return MV_BAD_PARAM;
22951+ }
22952+ }
22953+ if( (pCmd->digestOffset % 8) != fixOffset)
22954+ {
22955+ mvOsPrintf("mvCesaAction: digestOffset %d mod 8 must be equal %d\n",
22956+ pCmd->digestOffset, fixOffset);
22957+ return MV_BAD_PARAM;
22958+ }
22959+ }
22960+ /* Check CRYPTO operation parameters */
22961+ if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
22962+ (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )
22963+ {
22964+ /* CryptoOffset should be at least 4 byte aligned */
22965+ if( MV_IS_NOT_ALIGN(pCmd->cryptoOffset, 4) )
22966+ {
22967+ mvOsPrintf("CesaAction: cryptoOffset=%d must be 4 byte aligned\n",
22968+ pCmd->cryptoOffset);
22969+ return MV_BAD_PARAM;
22970+ }
22971+ /* cryptoLength should be the whole number of blocks */
22972+ if( MV_IS_NOT_ALIGN(pCmd->cryptoLength, pSA->cryptoBlockSize) )
22973+ {
22974+ mvOsPrintf("mvCesaAction: cryptoLength=%d must be %d byte aligned\n",
22975+ pCmd->cryptoLength, pSA->cryptoBlockSize);
22976+ return MV_BAD_PARAM;
22977+ }
22978+ if(fixOffset == 0xFF)
22979+ {
22980+ fixOffset = (pCmd->cryptoOffset % 8);
22981+ }
22982+ else
22983+ {
22984+ /* In addition all offsets should be the same alignment: 8 or 4 */
22985+ if( (pCmd->cryptoOffset % 8) != fixOffset)
22986+ {
22987+ mvOsPrintf("mvCesaAction: cryptoOffset %d mod 8 must be equal %d \n",
22988+ pCmd->cryptoOffset, fixOffset);
22989+ return MV_BAD_PARAM;
22990+ }
22991+ }
22992+
22993+ /* check for CBC mode */
22994+ if(pSA->cryptoIvSize > 0)
22995+ {
22996+ /* cryptoIV must not be part of CryptoLength */
22997+ if( ((pCmd->ivOffset + pSA->cryptoIvSize) > pCmd->cryptoOffset) &&
22998+ (pCmd->ivOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )
22999+ {
23000+ mvOsPrintf("mvCesaFragParamCheck: cryptoIvOffset (%d) is part of cryptoLength (%d+%d)\n",
23001+ pCmd->ivOffset, pCmd->macOffset, pCmd->macLength);
23002+ return MV_BAD_PARAM;
23003+ }
23004+
23005+ /* ivOffset must be 4 byte aligned */
23006+ if( MV_IS_NOT_ALIGN(pCmd->ivOffset, 4) )
23007+ {
23008+ mvOsPrintf("CesaAction: ivOffset=%d must be 4 byte aligned\n",
23009+ pCmd->ivOffset);
23010+ return MV_BAD_PARAM;
23011+ }
23012+ /* In addition all offsets should be the same alignment: 8 or 4 */
23013+ if( (pCmd->ivOffset % 8) != fixOffset)
23014+ {
23015+ mvOsPrintf("mvCesaAction: ivOffset %d mod 8 must be %d\n",
23016+ pCmd->ivOffset, fixOffset);
23017+ return MV_BAD_PARAM;
23018+ }
23019+ }
23020+ }
23021+ return MV_OK;
23022+}
23023+
23024+/*******************************************************************************
23025+* mvCesaFragParamCheck -
23026+*
23027+* DESCRIPTION:
23028+*
23029+*
23030+* INPUT:
23031+* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd
23032+*
23033+* RETURN:
23034+* MV_STATUS
23035+*
23036+*******************************************************************************/
23037+static MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd)
23038+{
23039+ int offset;
23040+
23041+ if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
23042+ (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )
23043+ {
23044+ /* macOffset must be less that SRAM buffer size */
23045+ if(pCmd->macOffset > (sizeof(cesaSramVirtPtr->buf) - MV_CESA_AUTH_BLOCK_SIZE))
23046+ {
23047+ mvOsPrintf("mvCesaFragParamCheck: macOffset is too large (%d)\n",
23048+ pCmd->macOffset);
23049+ return MV_BAD_PARAM;
23050+ }
23051+ /* macOffset+macSize must be more than mbufSize - SRAM buffer size */
23052+ if( ((pCmd->macOffset + pCmd->macLength) > pCmd->pSrc->mbufSize) ||
23053+ ((pCmd->pSrc->mbufSize - (pCmd->macOffset + pCmd->macLength)) >=
23054+ sizeof(cesaSramVirtPtr->buf)) )
23055+ {
23056+ mvOsPrintf("mvCesaFragParamCheck: macLength is too large (%d), mbufSize=%d\n",
23057+ pCmd->macLength, pCmd->pSrc->mbufSize);
23058+ return MV_BAD_PARAM;
23059+ }
23060+ }
23061+
23062+ if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
23063+ (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )
23064+ {
23065+ /* cryptoOffset must be less that SRAM buffer size */
23066+ /* 4 for possible fixOffset */
23067+ if( (pCmd->cryptoOffset + 4) > (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize))
23068+ {
23069+ mvOsPrintf("mvCesaFragParamCheck: cryptoOffset is too large (%d)\n",
23070+ pCmd->cryptoOffset);
23071+ return MV_BAD_PARAM;
23072+ }
23073+
23074+ /* cryptoOffset+cryptoSize must be more than mbufSize - SRAM buffer size */
23075+ if( ((pCmd->cryptoOffset + pCmd->cryptoLength) > pCmd->pSrc->mbufSize) ||
23076+ ((pCmd->pSrc->mbufSize - (pCmd->cryptoOffset + pCmd->cryptoLength)) >=
23077+ (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize)) )
23078+ {
23079+ mvOsPrintf("mvCesaFragParamCheck: cryptoLength is too large (%d), mbufSize=%d\n",
23080+ pCmd->cryptoLength, pCmd->pSrc->mbufSize);
23081+ return MV_BAD_PARAM;
23082+ }
23083+ }
23084+
23085+ /* When MAC_THEN_CRYPTO or CRYPTO_THEN_MAC */
23086+ if( ((pSA->config & MV_CESA_OPERATION_MASK) ==
23087+ (MV_CESA_MAC_THEN_CRYPTO << MV_CESA_OPERATION_OFFSET)) ||
23088+ ((pSA->config & MV_CESA_OPERATION_MASK) ==
23089+ (MV_CESA_CRYPTO_THEN_MAC << MV_CESA_OPERATION_OFFSET)) )
23090+ {
23091+ if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||
23092+ ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&
23093+ (mvCtrlRevGet() >= MV_5181L_A0_REV) &&
23094+ (pCmd->macLength >= (1 << 14)) ) )
23095+ {
23096+ return MV_NOT_ALLOWED;
23097+ }
23098+
23099+ /* abs(cryptoOffset-macOffset) must be aligned cryptoBlockSize */
23100+ if(pCmd->cryptoOffset > pCmd->macOffset)
23101+ {
23102+ offset = pCmd->cryptoOffset - pCmd->macOffset;
23103+ }
23104+ else
23105+ {
23106+ offset = pCmd->macOffset - pCmd->cryptoOffset;
23107+ }
23108+
23109+ if( MV_IS_NOT_ALIGN(offset, pSA->cryptoBlockSize) )
23110+ {
23111+/*
23112+ mvOsPrintf("mvCesaFragParamCheck: (cryptoOffset - macOffset) must be %d byte aligned\n",
23113+ pSA->cryptoBlockSize);
23114+*/
23115+ return MV_NOT_ALLOWED;
23116+ }
23117+ /* Digest must not be part of CryptoLength */
23118+ if( ((pCmd->digestOffset + pSA->digestSize) > pCmd->cryptoOffset) &&
23119+ (pCmd->digestOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )
23120+ {
23121+/*
23122+ mvOsPrintf("mvCesaFragParamCheck: digestOffset (%d) is part of cryptoLength (%d+%d)\n",
23123+ pCmd->digestOffset, pCmd->cryptoOffset, pCmd->cryptoLength);
23124+*/
23125+ return MV_NOT_ALLOWED;
23126+ }
23127+ }
23128+ return MV_OK;
23129+}
23130+
23131+/*******************************************************************************
23132+* mvCesaFragSizeFind -
23133+*
23134+* DESCRIPTION:
23135+*
23136+*
23137+* INPUT:
23138+* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,
23139+* int cryptoOffset, int macOffset,
23140+*
23141+* OUTPUT:
23142+* int* pCopySize, int* pCryptoDataSize, int* pMacDataSize
23143+*
23144+* RETURN:
23145+* MV_STATUS
23146+*
23147+*******************************************************************************/
23148+static void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq,
23149+ int cryptoOffset, int macOffset,
23150+ int* pCopySize, int* pCryptoDataSize, int* pMacDataSize)
23151+{
23152+ MV_CESA_COMMAND *pCmd = pReq->pCmd;
23153+ int cryptoDataSize, macDataSize, copySize;
23154+
23155+ cryptoDataSize = macDataSize = 0;
23156+ copySize = *pCopySize;
23157+
23158+ if( (pSA->config & MV_CESA_OPERATION_MASK) !=
23159+ (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
23160+ {
23161+ cryptoDataSize = MV_MIN( (copySize - cryptoOffset),
23162+ (pCmd->cryptoLength - (pReq->frags.cryptoSize + 1)) );
23163+
23164+ /* cryptoSize for each fragment must be the whole number of blocksSize */
23165+ if( MV_IS_NOT_ALIGN(cryptoDataSize, pSA->cryptoBlockSize) )
23166+ {
23167+ cryptoDataSize = MV_ALIGN_DOWN(cryptoDataSize, pSA->cryptoBlockSize);
23168+ copySize = cryptoOffset + cryptoDataSize;
23169+ }
23170+ }
23171+ if( (pSA->config & MV_CESA_OPERATION_MASK) !=
23172+ (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
23173+ {
23174+ macDataSize = MV_MIN( (copySize - macOffset),
23175+ (pCmd->macLength - (pReq->frags.macSize + 1)));
23176+
23177+ /* macSize for each fragment (except last) must be the whole number of blocksSize */
23178+ if( MV_IS_NOT_ALIGN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE) )
23179+ {
23180+ macDataSize = MV_ALIGN_DOWN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE);
23181+ copySize = macOffset + macDataSize;
23182+ }
23183+ cryptoDataSize = copySize - cryptoOffset;
23184+ }
23185+ *pCopySize = copySize;
23186+
23187+ if(pCryptoDataSize != NULL)
23188+ *pCryptoDataSize = cryptoDataSize;
23189+
23190+ if(pMacDataSize != NULL)
23191+ *pMacDataSize = macDataSize;
23192+}
23193diff --git a/crypto/ocf/kirkwood/cesa/mvCesa.h b/crypto/ocf/kirkwood/cesa/mvCesa.h
23194new file mode 100644
23195index 0000000..6898699
23196--- /dev/null
23197+++ b/crypto/ocf/kirkwood/cesa/mvCesa.h
23198@@ -0,0 +1,412 @@
23199+/*******************************************************************************
23200+Copyright (C) Marvell International Ltd. and its affiliates
23201+
23202+This software file (the "File") is owned and distributed by Marvell
23203+International Ltd. and/or its affiliates ("Marvell") under the following
23204+alternative licensing terms. Once you have made an election to distribute the
23205+File under one of the following license alternatives, please (i) delete this
23206+introductory statement regarding license alternatives, (ii) delete the two
23207+license alternatives that you have not elected to use and (iii) preserve the
23208+Marvell copyright notice above.
23209+
23210+********************************************************************************
23211+Marvell Commercial License Option
23212+
23213+If you received this File from Marvell and you have entered into a commercial
23214+license agreement (a "Commercial License") with Marvell, the File is licensed
23215+to you under the terms of the applicable Commercial License.
23216+
23217+********************************************************************************
23218+Marvell GPL License Option
23219+
23220+If you received this File from Marvell, you may opt to use, redistribute and/or
23221+modify this File in accordance with the terms and conditions of the General
23222+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
23223+available along with the File in the license.txt file or by writing to the Free
23224+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
23225+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
23226+
23227+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
23228+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
23229+DISCLAIMED. The GPL License provides additional details about this warranty
23230+disclaimer.
23231+********************************************************************************
23232+Marvell BSD License Option
23233+
23234+If you received this File from Marvell, you may opt to use, redistribute and/or
23235+modify this File under the following licensing terms.
23236+Redistribution and use in source and binary forms, with or without modification,
23237+are permitted provided that the following conditions are met:
23238+
23239+ * Redistributions of source code must retain the above copyright notice,
23240+ this list of conditions and the following disclaimer.
23241+
23242+ * Redistributions in binary form must reproduce the above copyright
23243+ notice, this list of conditions and the following disclaimer in the
23244+ documentation and/or other materials provided with the distribution.
23245+
23246+ * Neither the name of Marvell nor the names of its contributors may be
23247+ used to endorse or promote products derived from this software without
23248+ specific prior written permission.
23249+
23250+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23251+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23252+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23253+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23254+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23255+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23256+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23257+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23258+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23259+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23260+
23261+*******************************************************************************/
23262+
23263+/*******************************************************************************
23264+* mvCesa.h - Header File for Cryptographic Engines and Security Accelerator
23265+*
23266+* DESCRIPTION:
23267+* This header file contains macros typedefs and function declaration for
23268+* the Marvell Cryptographic Engines and Security Accelerator.
23269+*
23270+*******************************************************************************/
23271+
23272+#ifndef __mvCesa_h__
23273+#define __mvCesa_h__
23274+
23275+#include "mvOs.h"
23276+#include "mvCommon.h"
23277+#include "mvDebug.h"
23278+
23279+#include "ctrlEnv/mvCtrlEnvSpec.h"
23280+
23281+#include "cesa/mvMD5.h"
23282+#include "cesa/mvSHA1.h"
23283+
23284+#include "cesa/mvCesa.h"
23285+#include "cesa/AES/mvAes.h"
23286+#include "mvSysHwConfig.h"
23287+
23288+#ifdef MV_INCLUDE_IDMA
23289+#include "idma/mvIdma.h"
23290+#include "idma/mvIdmaRegs.h"
23291+#else
23292+/* Redefine MV_DMA_DESC structure */
23293+typedef struct _mvDmaDesc
23294+{
23295+ MV_U32 byteCnt; /* The total number of bytes to transfer */
23296+ MV_U32 phySrcAdd; /* The physical source address */
23297+ MV_U32 phyDestAdd; /* The physical destination address */
23298+ MV_U32 phyNextDescPtr; /* If we are using chain mode DMA transfer, */
23299+ /* then this pointer should point to the */
23300+ /* physical address of the next descriptor, */
23301+ /* otherwise it should be NULL. */
23302+}MV_DMA_DESC;
23303+#endif /* MV_INCLUDE_IDMA */
23304+
23305+#include "cesa/mvCesaRegs.h"
23306+
23307+#define MV_CESA_AUTH_BLOCK_SIZE 64 /* bytes */
23308+
23309+#define MV_CESA_MD5_DIGEST_SIZE 16 /* bytes */
23310+#define MV_CESA_SHA1_DIGEST_SIZE 20 /* bytes */
23311+
23312+#define MV_CESA_MAX_DIGEST_SIZE MV_CESA_SHA1_DIGEST_SIZE
23313+
23314+#define MV_CESA_DES_KEY_LENGTH 8 /* bytes = 64 bits */
23315+#define MV_CESA_3DES_KEY_LENGTH 24 /* bytes = 192 bits */
23316+#define MV_CESA_AES_128_KEY_LENGTH 16 /* bytes = 128 bits */
23317+#define MV_CESA_AES_192_KEY_LENGTH 24 /* bytes = 192 bits */
23318+#define MV_CESA_AES_256_KEY_LENGTH 32 /* bytes = 256 bits */
23319+
23320+#define MV_CESA_MAX_CRYPTO_KEY_LENGTH MV_CESA_AES_256_KEY_LENGTH
23321+
23322+#define MV_CESA_DES_BLOCK_SIZE 8 /* bytes = 64 bits */
23323+#define MV_CESA_3DES_BLOCK_SIZE 8 /* bytes = 64 bits */
23324+
23325+#define MV_CESA_AES_BLOCK_SIZE 16 /* bytes = 128 bits */
23326+
23327+#define MV_CESA_MAX_IV_LENGTH MV_CESA_AES_BLOCK_SIZE
23328+
23329+#define MV_CESA_MAX_MAC_KEY_LENGTH 64 /* bytes */
23330+
23331+typedef struct
23332+{
23333+ MV_U8 cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];
23334+ MV_U8 macKey[MV_CESA_MAX_MAC_KEY_LENGTH];
23335+ MV_CESA_OPERATION operation;
23336+ MV_CESA_DIRECTION direction;
23337+ MV_CESA_CRYPTO_ALG cryptoAlgorithm;
23338+ MV_CESA_CRYPTO_MODE cryptoMode;
23339+ MV_U8 cryptoKeyLength;
23340+ MV_CESA_MAC_MODE macMode;
23341+ MV_U8 macKeyLength;
23342+ MV_U8 digestSize;
23343+
23344+} MV_CESA_OPEN_SESSION;
23345+
23346+typedef struct
23347+{
23348+ MV_BUF_INFO *pFrags;
23349+ MV_U16 numFrags;
23350+ MV_U16 mbufSize;
23351+
23352+} MV_CESA_MBUF;
23353+
23354+typedef struct
23355+{
23356+ void* pReqPrv; /* instead of reqId */
23357+ MV_U32 retCode;
23358+ MV_16 sessionId;
23359+
23360+} MV_CESA_RESULT;
23361+
23362+typedef void (*MV_CESA_CALLBACK) (MV_CESA_RESULT* pResult);
23363+
23364+
23365+typedef struct
23366+{
23367+ void* pReqPrv; /* instead of reqId */
23368+ MV_CESA_MBUF* pSrc;
23369+ MV_CESA_MBUF* pDst;
23370+ MV_CESA_CALLBACK* pFuncCB;
23371+ MV_16 sessionId;
23372+ MV_U16 ivFromUser;
23373+ MV_U16 ivOffset;
23374+ MV_U16 cryptoOffset;
23375+ MV_U16 cryptoLength;
23376+ MV_U16 digestOffset;
23377+ MV_U16 macOffset;
23378+ MV_U16 macLength;
23379+ MV_BOOL skipFlush;
23380+} MV_CESA_COMMAND;
23381+
23382+
23383+
23384+MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase, void *osHandle);
23385+MV_STATUS mvCesaFinish (void);
23386+MV_STATUS mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid);
23387+MV_STATUS mvCesaSessionClose(short sid);
23388+MV_STATUS mvCesaCryptoIvSet(MV_U8* pIV, int ivSize);
23389+
23390+MV_STATUS mvCesaAction (MV_CESA_COMMAND* pCmd);
23391+
23392+MV_U32 mvCesaInProcessGet(void);
23393+MV_STATUS mvCesaReadyDispatch(void);
23394+MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult);
23395+MV_BOOL mvCesaIsReady(void);
23396+
23397+int mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset);
23398+MV_STATUS mvCesaCopyFromMbuf(MV_U8* pDst, MV_CESA_MBUF* pSrcMbuf,
23399+ int offset, int size);
23400+MV_STATUS mvCesaCopyToMbuf(MV_U8* pSrc, MV_CESA_MBUF* pDstMbuf,
23401+ int offset, int size);
23402+MV_STATUS mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,
23403+ MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size);
23404+
23405+/********** Debug functions ********/
23406+
23407+void mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size);
23408+void mvCesaDebugSA(short sid, int mode);
23409+void mvCesaDebugStats(void);
23410+void mvCesaDebugStatsClear(void);
23411+void mvCesaDebugRegs(void);
23412+void mvCesaDebugStatus(void);
23413+void mvCesaDebugQueue(int mode);
23414+void mvCesaDebugSram(int mode);
23415+void mvCesaDebugSAD(int mode);
23416+
23417+
23418+/******** CESA Private definitions ********/
23419+#if (MV_CESA_VERSION >= 2)
23420+#if (MV_CACHE_COHERENCY == MV_CACHE_COHER_SW)
23421+#define MV_CESA_TDMA_CTRL_VALUE MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
23422+ | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
23423+ | MV_CESA_TDMA_OUTSTAND_READ_EN_MASK \
23424+ | MV_CESA_TDMA_NO_BYTE_SWAP_MASK \
23425+ | MV_CESA_TDMA_ENABLE_MASK
23426+#else
23427+#define MV_CESA_TDMA_CTRL_VALUE MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_32B) \
23428+ | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
23429+ /*| MV_CESA_TDMA_OUTSTAND_READ_EN_MASK */\
23430+ | MV_CESA_TDMA_ENABLE_MASK
23431+
23432+#endif
23433+#else
23434+#define MV_CESA_IDMA_CTRL_LOW_VALUE ICCLR_DST_BURST_LIM_128BYTE \
23435+ | ICCLR_SRC_BURST_LIM_128BYTE \
23436+ | ICCLR_INT_MODE_MASK \
23437+ | ICCLR_BLOCK_MODE \
23438+ | ICCLR_CHAN_ENABLE \
23439+ | ICCLR_DESC_MODE_16M
23440+#endif /* MV_CESA_VERSION >= 2 */
23441+
23442+#define MV_CESA_MAX_PKT_SIZE (64 * 1024)
23443+#define MV_CESA_MAX_MBUF_FRAGS 20
23444+
23445+#define MV_CESA_MAX_REQ_FRAGS ( (MV_CESA_MAX_PKT_SIZE / MV_CESA_MAX_BUF_SIZE) + 1)
23446+
23447+#define MV_CESA_MAX_DMA_DESC (MV_CESA_MAX_MBUF_FRAGS*2 + 5)
23448+
23449+#define MAX_CESA_CHAIN_LENGTH 20
23450+
23451+typedef enum
23452+{
23453+ MV_CESA_IDLE = 0,
23454+ MV_CESA_PENDING,
23455+ MV_CESA_PROCESS,
23456+ MV_CESA_READY,
23457+#if (MV_CESA_VERSION >= 3)
23458+ MV_CESA_CHAIN,
23459+#endif
23460+} MV_CESA_STATE;
23461+
23462+
23463+/* Session database */
23464+
23465+/* Map of Key materials of the session in SRAM.
23466+ * Each field must be 8 byte aligned
23467+ * Total size: 32 + 24 + 24 = 80 bytes
23468+ */
23469+typedef struct
23470+{
23471+ MV_U8 cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];
23472+ MV_U8 macInnerIV[MV_CESA_MAX_DIGEST_SIZE];
23473+ MV_U8 reservedInner[4];
23474+ MV_U8 macOuterIV[MV_CESA_MAX_DIGEST_SIZE];
23475+ MV_U8 reservedOuter[4];
23476+
23477+} MV_CESA_SRAM_SA;
23478+
23479+typedef struct
23480+{
23481+ MV_CESA_SRAM_SA* pSramSA;
23482+ MV_U32 config;
23483+ MV_U8 cryptoKeyLength;
23484+ MV_U8 cryptoIvSize;
23485+ MV_U8 cryptoBlockSize;
23486+ MV_U8 digestSize;
23487+ MV_U8 macKeyLength;
23488+ MV_U8 valid;
23489+ MV_U8 ctrMode;
23490+ MV_U32 count;
23491+
23492+} MV_CESA_SA;
23493+
23494+/* DMA list management */
23495+typedef struct
23496+{
23497+ MV_DMA_DESC* pDmaFirst;
23498+ MV_DMA_DESC* pDmaLast;
23499+
23500+} MV_CESA_DMA;
23501+
23502+
23503+typedef struct
23504+{
23505+ MV_U8 numFrag;
23506+ MV_U8 nextFrag;
23507+ int bufOffset;
23508+ int cryptoSize;
23509+ int macSize;
23510+ int newDigestOffset;
23511+ MV_U8 orgDigest[MV_CESA_MAX_DIGEST_SIZE];
23512+
23513+} MV_CESA_FRAGS;
23514+
23515+/* Request queue */
23516+typedef struct
23517+{
23518+ MV_U8 state;
23519+ MV_U8 fragMode;
23520+ MV_U8 fixOffset;
23521+ MV_CESA_COMMAND* pCmd;
23522+ MV_CESA_COMMAND* pOrgCmd;
23523+ MV_BUF_INFO dmaDescBuf;
23524+ MV_CESA_DMA dma[MV_CESA_MAX_REQ_FRAGS];
23525+ MV_BUF_INFO cesaDescBuf;
23526+ MV_CESA_DESC* pCesaDesc;
23527+ MV_CESA_FRAGS frags;
23528+
23529+
23530+} MV_CESA_REQ;
23531+
23532+
23533+/* SRAM map */
23534+/* Total SRAM size calculation */
23535+/* SRAM size =
23536+ * MV_CESA_MAX_BUF_SIZE +
23537+ * sizeof(MV_CESA_DESC) +
23538+ * MV_CESA_MAX_IV_LENGTH +
23539+ * MV_CESA_MAX_IV_LENGTH +
23540+ * MV_CESA_MAX_DIGEST_SIZE +
23541+ * sizeof(MV_CESA_SRAM_SA)
23542+ * = 1600 + 32 + 16 + 16 + 24 + 80 + 280 (reserved) = 2048 bytes
23543+ * = 3200 + 32 + 16 + 16 + 24 + 80 + 728 (reserved) = 4096 bytes
23544+ */
23545+typedef struct
23546+{
23547+ MV_U8 buf[MV_CESA_MAX_BUF_SIZE];
23548+ MV_CESA_DESC desc;
23549+ MV_U8 cryptoIV[MV_CESA_MAX_IV_LENGTH];
23550+ MV_U8 tempCryptoIV[MV_CESA_MAX_IV_LENGTH];
23551+ MV_U8 tempDigest[MV_CESA_MAX_DIGEST_SIZE+4];
23552+ MV_CESA_SRAM_SA sramSA;
23553+
23554+} MV_CESA_SRAM_MAP;
23555+
23556+
23557+typedef struct
23558+{
23559+ MV_U32 openedCount;
23560+ MV_U32 closedCount;
23561+ MV_U32 fragCount;
23562+ MV_U32 reqCount;
23563+ MV_U32 maxReqCount;
23564+ MV_U32 procCount;
23565+ MV_U32 readyCount;
23566+ MV_U32 notReadyCount;
23567+ MV_U32 startCount;
23568+#if (MV_CESA_VERSION >= 3)
23569+ MV_U32 maxChainUsage;
23570+#endif
23571+
23572+} MV_CESA_STATS;
23573+
23574+
23575+/* External variables */
23576+
23577+extern MV_CESA_STATS cesaStats;
23578+extern MV_CESA_FRAGS cesaFrags;
23579+
23580+extern MV_BUF_INFO cesaSramSaBuf;
23581+
23582+extern MV_CESA_SA* pCesaSAD;
23583+extern MV_U16 cesaMaxSA;
23584+
23585+extern MV_CESA_REQ* pCesaReqFirst;
23586+extern MV_CESA_REQ* pCesaReqLast;
23587+extern MV_CESA_REQ* pCesaReqEmpty;
23588+extern MV_CESA_REQ* pCesaReqProcess;
23589+extern int cesaQueueDepth;
23590+extern int cesaReqResources;
23591+#if (MV_CESA_VERSION>= 3)
23592+extern MV_U32 cesaChainLength;
23593+#endif
23594+
23595+extern MV_CESA_SRAM_MAP* cesaSramVirtPtr;
23596+extern MV_U32 cesaSramPhysAddr;
23597+
23598+static INLINE MV_ULONG mvCesaVirtToPhys(MV_BUF_INFO* pBufInfo, void* pVirt)
23599+{
23600+ return (pBufInfo->bufPhysAddr + ((MV_U8*)pVirt - pBufInfo->bufVirtPtr));
23601+}
23602+
23603+/* Additional DEBUG functions */
23604+void mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode);
23605+void mvCesaDebugCmd(MV_CESA_COMMAND* pCmd, int mode);
23606+void mvCesaDebugDescriptor(MV_CESA_DESC* pDesc);
23607+
23608+
23609+
23610+#endif /* __mvCesa_h__ */
23611diff --git a/crypto/ocf/kirkwood/cesa/mvCesaDebug.c b/crypto/ocf/kirkwood/cesa/mvCesaDebug.c
23612new file mode 100644
23613index 0000000..0b7cb48
23614--- /dev/null
23615+++ b/crypto/ocf/kirkwood/cesa/mvCesaDebug.c
23616@@ -0,0 +1,484 @@
23617+/*******************************************************************************
23618+Copyright (C) Marvell International Ltd. and its affiliates
23619+
23620+This software file (the "File") is owned and distributed by Marvell
23621+International Ltd. and/or its affiliates ("Marvell") under the following
23622+alternative licensing terms. Once you have made an election to distribute the
23623+File under one of the following license alternatives, please (i) delete this
23624+introductory statement regarding license alternatives, (ii) delete the two
23625+license alternatives that you have not elected to use and (iii) preserve the
23626+Marvell copyright notice above.
23627+
23628+********************************************************************************
23629+Marvell Commercial License Option
23630+
23631+If you received this File from Marvell and you have entered into a commercial
23632+license agreement (a "Commercial License") with Marvell, the File is licensed
23633+to you under the terms of the applicable Commercial License.
23634+
23635+********************************************************************************
23636+Marvell GPL License Option
23637+
23638+If you received this File from Marvell, you may opt to use, redistribute and/or
23639+modify this File in accordance with the terms and conditions of the General
23640+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
23641+available along with the File in the license.txt file or by writing to the Free
23642+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
23643+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
23644+
23645+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
23646+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
23647+DISCLAIMED. The GPL License provides additional details about this warranty
23648+disclaimer.
23649+********************************************************************************
23650+Marvell BSD License Option
23651+
23652+If you received this File from Marvell, you may opt to use, redistribute and/or
23653+modify this File under the following licensing terms.
23654+Redistribution and use in source and binary forms, with or without modification,
23655+are permitted provided that the following conditions are met:
23656+
23657+ * Redistributions of source code must retain the above copyright notice,
23658+ this list of conditions and the following disclaimer.
23659+
23660+ * Redistributions in binary form must reproduce the above copyright
23661+ notice, this list of conditions and the following disclaimer in the
23662+ documentation and/or other materials provided with the distribution.
23663+
23664+ * Neither the name of Marvell nor the names of its contributors may be
23665+ used to endorse or promote products derived from this software without
23666+ specific prior written permission.
23667+
23668+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23669+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23670+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23671+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23672+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23673+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23674+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23675+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23676+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23677+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23678+
23679+*******************************************************************************/
23680+
23681+#include "mvOs.h"
23682+#include "mvDebug.h"
23683+
23684+#include "cesa/mvMD5.h"
23685+#include "cesa/mvSHA1.h"
23686+
23687+#include "cesa/mvCesa.h"
23688+#include "cesa/mvCesaRegs.h"
23689+#include "cesa/AES/mvAes.h"
23690+
23691+static const char* mvCesaDebugStateStr(MV_CESA_STATE state)
23692+{
23693+ switch(state)
23694+ {
23695+ case MV_CESA_IDLE:
23696+ return "Idle";
23697+
23698+ case MV_CESA_PENDING:
23699+ return "Pend";
23700+
23701+ case MV_CESA_PROCESS:
23702+ return "Proc";
23703+
23704+ case MV_CESA_READY:
23705+ return "Ready";
23706+
23707+ default:
23708+ break;
23709+ }
23710+ return "Unknown";
23711+}
23712+
23713+static const char* mvCesaDebugOperStr(MV_CESA_OPERATION oper)
23714+{
23715+ switch(oper)
23716+ {
23717+ case MV_CESA_MAC_ONLY:
23718+ return "MacOnly";
23719+
23720+ case MV_CESA_CRYPTO_ONLY:
23721+ return "CryptoOnly";
23722+
23723+ case MV_CESA_MAC_THEN_CRYPTO:
23724+ return "MacCrypto";
23725+
23726+ case MV_CESA_CRYPTO_THEN_MAC:
23727+ return "CryptoMac";
23728+
23729+ default:
23730+ break;
23731+ }
23732+ return "Null";
23733+}
23734+
23735+static const char* mvCesaDebugCryptoAlgStr(MV_CESA_CRYPTO_ALG cryptoAlg)
23736+{
23737+ switch(cryptoAlg)
23738+ {
23739+ case MV_CESA_CRYPTO_DES:
23740+ return "DES";
23741+
23742+ case MV_CESA_CRYPTO_3DES:
23743+ return "3DES";
23744+
23745+ case MV_CESA_CRYPTO_AES:
23746+ return "AES";
23747+
23748+ default:
23749+ break;
23750+ }
23751+ return "Null";
23752+}
23753+
23754+static const char* mvCesaDebugMacModeStr(MV_CESA_MAC_MODE macMode)
23755+{
23756+ switch(macMode)
23757+ {
23758+ case MV_CESA_MAC_MD5:
23759+ return "MD5";
23760+
23761+ case MV_CESA_MAC_SHA1:
23762+ return "SHA1";
23763+
23764+ case MV_CESA_MAC_HMAC_MD5:
23765+ return "HMAC-MD5";
23766+
23767+ case MV_CESA_MAC_HMAC_SHA1:
23768+ return "HMAC_SHA1";
23769+
23770+ default:
23771+ break;
23772+ }
23773+ return "Null";
23774+}
23775+
23776+void mvCesaDebugCmd(MV_CESA_COMMAND* pCmd, int mode)
23777+{
23778+ mvOsPrintf("pCmd=%p, pReqPrv=%p, pSrc=%p, pDst=%p, pCB=%p, sid=%d\n",
23779+ pCmd, pCmd->pReqPrv, pCmd->pSrc, pCmd->pDst,
23780+ pCmd->pFuncCB, pCmd->sessionId);
23781+ mvOsPrintf("isUser=%d, ivOffs=%d, crOffs=%d, crLen=%d, digest=%d, macOffs=%d, macLen=%d\n",
23782+ pCmd->ivFromUser, pCmd->ivOffset, pCmd->cryptoOffset, pCmd->cryptoLength,
23783+ pCmd->digestOffset, pCmd->macOffset, pCmd->macLength);
23784+}
23785+
23786+/* no need to use in tool */
23787+void mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size)
23788+{
23789+ int frag, len, fragOffset;
23790+
23791+ if(str != NULL)
23792+ mvOsPrintf("%s: pMbuf=%p, numFrags=%d, mbufSize=%d\n",
23793+ str, pMbuf, pMbuf->numFrags, pMbuf->mbufSize);
23794+
23795+ frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
23796+ if(frag == MV_INVALID)
23797+ {
23798+ mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
23799+ return;
23800+ }
23801+
23802+ for(; frag<pMbuf->numFrags; frag++)
23803+ {
23804+ mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n",
23805+ frag, pMbuf->pFrags[frag].bufVirtPtr,
23806+ pMbuf->pFrags[frag].bufSize);
23807+ if(size > 0)
23808+ {
23809+ len = MV_MIN(pMbuf->pFrags[frag].bufSize, size);
23810+ mvDebugMemDump(pMbuf->pFrags[frag].bufVirtPtr+fragOffset, len, 1);
23811+ size -= len;
23812+ fragOffset = 0;
23813+ }
23814+ }
23815+}
23816+
23817+void mvCesaDebugRegs(void)
23818+{
23819+ mvOsPrintf("\t CESA Registers:\n");
23820+
23821+ mvOsPrintf("MV_CESA_CMD_REG : 0x%X = 0x%08x\n",
23822+ MV_CESA_CMD_REG,
23823+ MV_REG_READ( MV_CESA_CMD_REG ) );
23824+
23825+ mvOsPrintf("MV_CESA_CHAN_DESC_OFFSET_REG : 0x%X = 0x%08x\n",
23826+ MV_CESA_CHAN_DESC_OFFSET_REG,
23827+ MV_REG_READ(MV_CESA_CHAN_DESC_OFFSET_REG) );
23828+
23829+ mvOsPrintf("MV_CESA_CFG_REG : 0x%X = 0x%08x\n",
23830+ MV_CESA_CFG_REG,
23831+ MV_REG_READ( MV_CESA_CFG_REG ) );
23832+
23833+ mvOsPrintf("MV_CESA_STATUS_REG : 0x%X = 0x%08x\n",
23834+ MV_CESA_STATUS_REG,
23835+ MV_REG_READ( MV_CESA_STATUS_REG ) );
23836+
23837+ mvOsPrintf("MV_CESA_ISR_CAUSE_REG : 0x%X = 0x%08x\n",
23838+ MV_CESA_ISR_CAUSE_REG,
23839+ MV_REG_READ( MV_CESA_ISR_CAUSE_REG ) );
23840+
23841+ mvOsPrintf("MV_CESA_ISR_MASK_REG : 0x%X = 0x%08x\n",
23842+ MV_CESA_ISR_MASK_REG,
23843+ MV_REG_READ( MV_CESA_ISR_MASK_REG ) );
23844+#if (MV_CESA_VERSION >= 2)
23845+ mvOsPrintf("MV_CESA_TDMA_CTRL_REG : 0x%X = 0x%08x\n",
23846+ MV_CESA_TDMA_CTRL_REG,
23847+ MV_REG_READ( MV_CESA_TDMA_CTRL_REG ) );
23848+
23849+ mvOsPrintf("MV_CESA_TDMA_BYTE_COUNT_REG : 0x%X = 0x%08x\n",
23850+ MV_CESA_TDMA_BYTE_COUNT_REG,
23851+ MV_REG_READ( MV_CESA_TDMA_BYTE_COUNT_REG ) );
23852+
23853+ mvOsPrintf("MV_CESA_TDMA_SRC_ADDR_REG : 0x%X = 0x%08x\n",
23854+ MV_CESA_TDMA_SRC_ADDR_REG,
23855+ MV_REG_READ( MV_CESA_TDMA_SRC_ADDR_REG ) );
23856+
23857+ mvOsPrintf("MV_CESA_TDMA_DST_ADDR_REG : 0x%X = 0x%08x\n",
23858+ MV_CESA_TDMA_DST_ADDR_REG,
23859+ MV_REG_READ( MV_CESA_TDMA_DST_ADDR_REG ) );
23860+
23861+ mvOsPrintf("MV_CESA_TDMA_NEXT_DESC_PTR_REG : 0x%X = 0x%08x\n",
23862+ MV_CESA_TDMA_NEXT_DESC_PTR_REG,
23863+ MV_REG_READ( MV_CESA_TDMA_NEXT_DESC_PTR_REG ) );
23864+
23865+ mvOsPrintf("MV_CESA_TDMA_CURR_DESC_PTR_REG : 0x%X = 0x%08x\n",
23866+ MV_CESA_TDMA_CURR_DESC_PTR_REG,
23867+ MV_REG_READ( MV_CESA_TDMA_CURR_DESC_PTR_REG ) );
23868+
23869+ mvOsPrintf("MV_CESA_TDMA_ERROR_CAUSE_REG : 0x%X = 0x%08x\n",
23870+ MV_CESA_TDMA_ERROR_CAUSE_REG,
23871+ MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );
23872+
23873+ mvOsPrintf("MV_CESA_TDMA_ERROR_MASK_REG : 0x%X = 0x%08x\n",
23874+ MV_CESA_TDMA_ERROR_MASK_REG,
23875+ MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );
23876+
23877+#endif
23878+}
23879+
23880+void mvCesaDebugStatus(void)
23881+{
23882+ mvOsPrintf("\n\t CESA Status\n\n");
23883+
23884+ mvOsPrintf("pReqQ=%p, qDepth=%d, reqSize=%ld bytes, qRes=%d, ",
23885+ pCesaReqFirst, cesaQueueDepth, sizeof(MV_CESA_REQ),
23886+ cesaReqResources);
23887+#if (MV_CESA_VERSION >= 3)
23888+ mvOsPrintf("chainLength=%u\n",cesaChainLength);
23889+#else
23890+ mvOsPrintf("\n");
23891+#endif
23892+
23893+ mvOsPrintf("pSAD=%p, maxSA=%d, sizeSA=%ld bytes\n",
23894+ pCesaSAD, cesaMaxSA, sizeof(MV_CESA_SA));
23895+
23896+ mvOsPrintf("\n");
23897+
23898+ mvCesaDebugRegs();
23899+ mvCesaDebugStats();
23900+ mvCesaDebugStatsClear();
23901+}
23902+
23903+void mvCesaDebugDescriptor(MV_CESA_DESC* pDesc)
23904+{
23905+ mvOsPrintf("config=0x%08x, crSrcOffs=0x%04x, crDstOffs=0x%04x\n",
23906+ pDesc->config, pDesc->cryptoSrcOffset, pDesc->cryptoDstOffset);
23907+
23908+ mvOsPrintf("crLen=0x%04x, crKeyOffs=0x%04x, ivOffs=0x%04x, ivBufOffs=0x%04x\n",
23909+ pDesc->cryptoDataLen, pDesc->cryptoKeyOffset,
23910+ pDesc->cryptoIvOffset, pDesc->cryptoIvBufOffset);
23911+
23912+ mvOsPrintf("macSrc=0x%04x, digest=0x%04x, macLen=0x%04x, inIv=0x%04x, outIv=0x%04x\n",
23913+ pDesc->macSrcOffset, pDesc->macDigestOffset, pDesc->macDataLen,
23914+ pDesc->macInnerIvOffset, pDesc->macOuterIvOffset);
23915+}
23916+
23917+void mvCesaDebugQueue(int mode)
23918+{
23919+ mvOsPrintf("\n\t CESA Request Queue:\n\n");
23920+
23921+ mvOsPrintf("pFirstReq=%p, pLastReq=%p, qDepth=%d, reqSize=%ld bytes\n",
23922+ pCesaReqFirst, pCesaReqLast, cesaQueueDepth, sizeof(MV_CESA_REQ));
23923+
23924+ mvOsPrintf("pEmpty=%p, pProcess=%p, qResources=%d\n",
23925+ pCesaReqEmpty, pCesaReqProcess,
23926+ cesaReqResources);
23927+
23928+ if(mode != 0)
23929+ {
23930+ int count = 0;
23931+ MV_CESA_REQ* pReq = pCesaReqFirst;
23932+
23933+ for(count=0; count<cesaQueueDepth; count++)
23934+ {
23935+ /* Print out requsts */
23936+ mvOsPrintf("%02d. pReq=%p, state=%s, frag=0x%x, pCmd=%p, pDma=%p, pDesc=%p\n",
23937+ count, pReq, mvCesaDebugStateStr(pReq->state),
23938+ pReq->fragMode, pReq->pCmd, pReq->dma[0].pDmaFirst, &pReq->pCesaDesc[0]);
23939+ if(pReq->fragMode != MV_CESA_FRAG_NONE)
23940+ {
23941+ int frag;
23942+
23943+ mvOsPrintf("pFrags=%p, num=%d, next=%d, bufOffset=%d, cryptoSize=%d, macSize=%d\n",
23944+ &pReq->frags, pReq->frags.numFrag, pReq->frags.nextFrag,
23945+ pReq->frags.bufOffset, pReq->frags.cryptoSize, pReq->frags.macSize);
23946+ for(frag=0; frag<pReq->frags.numFrag; frag++)
23947+ {
23948+ mvOsPrintf("#%d: pDmaFirst=%p, pDesc=%p\n", frag,
23949+ pReq->dma[frag].pDmaFirst, &pReq->pCesaDesc[frag]);
23950+ }
23951+ }
23952+ if(mode > 1)
23953+ {
23954+ /* Print out Command */
23955+ mvCesaDebugCmd(pReq->pCmd, mode);
23956+
23957+ /* Print out Descriptor */
23958+ mvCesaDebugDescriptor(&pReq->pCesaDesc[0]);
23959+ }
23960+ pReq++;
23961+ }
23962+ }
23963+}
23964+
23965+
23966+void mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode)
23967+{
23968+ if(pSramSA == NULL)
23969+ {
23970+ mvOsPrintf("cesaSramSA: Unexpected pSramSA=%p\n", pSramSA);
23971+ return;
23972+ }
23973+ mvOsPrintf("pSramSA=%p, sizeSramSA=%ld bytes\n",
23974+ pSramSA, sizeof(MV_CESA_SRAM_SA));
23975+
23976+ if(mode != 0)
23977+ {
23978+ mvOsPrintf("cryptoKey=%p, maxCryptoKey=%d bytes\n",
23979+ pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH);
23980+ mvDebugMemDump(pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH, 1);
23981+
23982+ mvOsPrintf("macInnerIV=%p, maxInnerIV=%d bytes\n",
23983+ pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE);
23984+ mvDebugMemDump(pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE, 1);
23985+
23986+ mvOsPrintf("macOuterIV=%p, maxOuterIV=%d bytes\n",
23987+ pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE);
23988+ mvDebugMemDump(pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE, 1);
23989+ }
23990+}
23991+
23992+void mvCesaDebugSA(short sid, int mode)
23993+{
23994+ MV_CESA_OPERATION oper;
23995+ MV_CESA_DIRECTION dir;
23996+ MV_CESA_CRYPTO_ALG cryptoAlg;
23997+ MV_CESA_CRYPTO_MODE cryptoMode;
23998+ MV_CESA_MAC_MODE macMode;
23999+ MV_CESA_SA* pSA = &pCesaSAD[sid];
24000+
24001+ if( (pSA->valid) || ((pSA->count != 0) && (mode > 0)) || (mode >= 2) )
24002+ {
24003+ mvOsPrintf("\n\nCESA SA Entry #%d (%p) - %s (count=%d)\n",
24004+ sid, pSA,
24005+ pSA->valid ? "Valid" : "Invalid", pSA->count);
24006+
24007+ oper = (pSA->config & MV_CESA_OPERATION_MASK) >> MV_CESA_OPERATION_OFFSET;
24008+ dir = (pSA->config & MV_CESA_DIRECTION_MASK) >> MV_CESA_DIRECTION_BIT;
24009+ mvOsPrintf("%s - %s ", mvCesaDebugOperStr(oper),
24010+ (dir == MV_CESA_DIR_ENCODE) ? "Encode" : "Decode");
24011+ if(oper != MV_CESA_MAC_ONLY)
24012+ {
24013+ cryptoAlg = (pSA->config & MV_CESA_CRYPTO_ALG_MASK) >> MV_CESA_CRYPTO_ALG_OFFSET;
24014+ cryptoMode = (pSA->config & MV_CESA_CRYPTO_MODE_MASK) >> MV_CESA_CRYPTO_MODE_BIT;
24015+ mvOsPrintf("- %s - %s ", mvCesaDebugCryptoAlgStr(cryptoAlg),
24016+ (cryptoMode == MV_CESA_CRYPTO_ECB) ? "ECB" : "CBC");
24017+ }
24018+ if(oper != MV_CESA_CRYPTO_ONLY)
24019+ {
24020+ macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;
24021+ mvOsPrintf("- %s ", mvCesaDebugMacModeStr(macMode));
24022+ }
24023+ mvOsPrintf("\n");
24024+
24025+ if(mode > 0)
24026+ {
24027+ mvOsPrintf("config=0x%08x, cryptoKeySize=%d, digestSize=%d\n",
24028+ pCesaSAD[sid].config, pCesaSAD[sid].cryptoKeyLength,
24029+ pCesaSAD[sid].digestSize);
24030+
24031+ mvCesaDebugSramSA(pCesaSAD[sid].pSramSA, mode);
24032+ }
24033+ }
24034+}
24035+
24036+
24037+/**/
24038+void mvCesaDebugSram(int mode)
24039+{
24040+ mvOsPrintf("\n\t SRAM contents: size=%ld, pVirt=%p\n\n",
24041+ sizeof(MV_CESA_SRAM_MAP), cesaSramVirtPtr);
24042+
24043+ mvOsPrintf("\n\t Sram buffer: size=%d, pVirt=%p\n",
24044+ MV_CESA_MAX_BUF_SIZE, cesaSramVirtPtr->buf);
24045+ if(mode != 0)
24046+ mvDebugMemDump(cesaSramVirtPtr->buf, 64, 1);
24047+
24048+ mvOsPrintf("\n");
24049+ mvOsPrintf("\n\t Sram descriptor: size=%ld, pVirt=%p\n",
24050+ sizeof(MV_CESA_DESC), &cesaSramVirtPtr->desc);
24051+ if(mode != 0)
24052+ {
24053+ mvOsPrintf("\n");
24054+ mvCesaDebugDescriptor(&cesaSramVirtPtr->desc);
24055+ }
24056+ mvOsPrintf("\n\t Sram IV: size=%d, pVirt=%p\n",
24057+ MV_CESA_MAX_IV_LENGTH, &cesaSramVirtPtr->cryptoIV);
24058+ if(mode != 0)
24059+ {
24060+ mvOsPrintf("\n");
24061+ mvDebugMemDump(cesaSramVirtPtr->cryptoIV, MV_CESA_MAX_IV_LENGTH, 1);
24062+ }
24063+ mvOsPrintf("\n");
24064+ mvCesaDebugSramSA(&cesaSramVirtPtr->sramSA, 0);
24065+}
24066+
24067+void mvCesaDebugSAD(int mode)
24068+{
24069+ int sid;
24070+
24071+ mvOsPrintf("\n\t Cesa SAD status: pSAD=%p, maxSA=%d\n",
24072+ pCesaSAD, cesaMaxSA);
24073+
24074+ for(sid=0; sid<cesaMaxSA; sid++)
24075+ {
24076+ mvCesaDebugSA(sid, mode);
24077+ }
24078+}
24079+
24080+void mvCesaDebugStats(void)
24081+{
24082+ mvOsPrintf("\n\t Cesa Statistics\n");
24083+
24084+ mvOsPrintf("Opened=%u, Closed=%u\n",
24085+ cesaStats.openedCount, cesaStats.closedCount);
24086+ mvOsPrintf("Req=%u, maxReq=%u, frags=%u, start=%u\n",
24087+ cesaStats.reqCount, cesaStats.maxReqCount,
24088+ cesaStats.fragCount, cesaStats.startCount);
24089+#if (MV_CESA_VERSION >= 3)
24090+ mvOsPrintf("maxChainUsage=%u\n",cesaStats.maxChainUsage);
24091+#endif
24092+ mvOsPrintf("\n");
24093+ mvOsPrintf("proc=%u, ready=%u, notReady=%u\n",
24094+ cesaStats.procCount, cesaStats.readyCount, cesaStats.notReadyCount);
24095+}
24096+
24097+void mvCesaDebugStatsClear(void)
24098+{
24099+ memset(&cesaStats, 0, sizeof(cesaStats));
24100+}
24101diff --git a/crypto/ocf/kirkwood/cesa/mvCesaRegs.h b/crypto/ocf/kirkwood/cesa/mvCesaRegs.h
24102new file mode 100644
24103index 0000000..c6eecae
24104--- /dev/null
24105+++ b/crypto/ocf/kirkwood/cesa/mvCesaRegs.h
24106@@ -0,0 +1,357 @@
24107+/*******************************************************************************
24108+Copyright (C) Marvell International Ltd. and its affiliates
24109+
24110+This software file (the "File") is owned and distributed by Marvell
24111+International Ltd. and/or its affiliates ("Marvell") under the following
24112+alternative licensing terms. Once you have made an election to distribute the
24113+File under one of the following license alternatives, please (i) delete this
24114+introductory statement regarding license alternatives, (ii) delete the two
24115+license alternatives that you have not elected to use and (iii) preserve the
24116+Marvell copyright notice above.
24117+
24118+********************************************************************************
24119+Marvell Commercial License Option
24120+
24121+If you received this File from Marvell and you have entered into a commercial
24122+license agreement (a "Commercial License") with Marvell, the File is licensed
24123+to you under the terms of the applicable Commercial License.
24124+
24125+********************************************************************************
24126+Marvell GPL License Option
24127+
24128+If you received this File from Marvell, you may opt to use, redistribute and/or
24129+modify this File in accordance with the terms and conditions of the General
24130+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
24131+available along with the File in the license.txt file or by writing to the Free
24132+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
24133+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
24134+
24135+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
24136+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
24137+DISCLAIMED. The GPL License provides additional details about this warranty
24138+disclaimer.
24139+********************************************************************************
24140+Marvell BSD License Option
24141+
24142+If you received this File from Marvell, you may opt to use, redistribute and/or
24143+modify this File under the following licensing terms.
24144+Redistribution and use in source and binary forms, with or without modification,
24145+are permitted provided that the following conditions are met:
24146+
24147+ * Redistributions of source code must retain the above copyright notice,
24148+ this list of conditions and the following disclaimer.
24149+
24150+ * Redistributions in binary form must reproduce the above copyright
24151+ notice, this list of conditions and the following disclaimer in the
24152+ documentation and/or other materials provided with the distribution.
24153+
24154+ * Neither the name of Marvell nor the names of its contributors may be
24155+ used to endorse or promote products derived from this software without
24156+ specific prior written permission.
24157+
24158+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24159+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24160+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24161+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24162+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24163+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24164+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24165+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24166+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24167+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24168+
24169+*******************************************************************************/
24170+
24171+#ifndef __mvCesaRegs_h__
24172+#define __mvCesaRegs_h__
24173+
24174+#include "mvTypes.h"
24175+
24176+typedef struct
24177+{
24178+ /* word 0 */
24179+ MV_U32 config;
24180+ /* word 1 */
24181+ MV_U16 cryptoSrcOffset;
24182+ MV_U16 cryptoDstOffset;
24183+ /* word 2 */
24184+ MV_U16 cryptoDataLen;
24185+ MV_U16 reserved1;
24186+ /* word 3 */
24187+ MV_U16 cryptoKeyOffset;
24188+ MV_U16 reserved2;
24189+ /* word 4 */
24190+ MV_U16 cryptoIvOffset;
24191+ MV_U16 cryptoIvBufOffset;
24192+ /* word 5 */
24193+ MV_U16 macSrcOffset;
24194+ MV_U16 macTotalLen;
24195+ /* word 6 */
24196+ MV_U16 macDigestOffset;
24197+ MV_U16 macDataLen;
24198+ /* word 7 */
24199+ MV_U16 macInnerIvOffset;
24200+ MV_U16 macOuterIvOffset;
24201+
24202+} MV_CESA_DESC;
24203+
24204+/* operation */
24205+typedef enum
24206+{
24207+ MV_CESA_MAC_ONLY = 0,
24208+ MV_CESA_CRYPTO_ONLY = 1,
24209+ MV_CESA_MAC_THEN_CRYPTO = 2,
24210+ MV_CESA_CRYPTO_THEN_MAC = 3,
24211+
24212+ MV_CESA_MAX_OPERATION
24213+
24214+} MV_CESA_OPERATION;
24215+
24216+#define MV_CESA_OPERATION_OFFSET 0
24217+#define MV_CESA_OPERATION_MASK (0x3 << MV_CESA_OPERATION_OFFSET)
24218+
24219+/* mac algorithm */
24220+typedef enum
24221+{
24222+ MV_CESA_MAC_NULL = 0,
24223+ MV_CESA_MAC_MD5 = 4,
24224+ MV_CESA_MAC_SHA1 = 5,
24225+ MV_CESA_MAC_HMAC_MD5 = 6,
24226+ MV_CESA_MAC_HMAC_SHA1 = 7,
24227+
24228+} MV_CESA_MAC_MODE;
24229+
24230+#define MV_CESA_MAC_MODE_OFFSET 4
24231+#define MV_CESA_MAC_MODE_MASK (0x7 << MV_CESA_MAC_MODE_OFFSET)
24232+
24233+typedef enum
24234+{
24235+ MV_CESA_MAC_DIGEST_FULL = 0,
24236+ MV_CESA_MAC_DIGEST_96B = 1,
24237+
24238+} MV_CESA_MAC_DIGEST_SIZE;
24239+
24240+#define MV_CESA_MAC_DIGEST_SIZE_BIT 7
24241+#define MV_CESA_MAC_DIGEST_SIZE_MASK (1 << MV_CESA_MAC_DIGEST_SIZE_BIT)
24242+
24243+
24244+typedef enum
24245+{
24246+ MV_CESA_CRYPTO_NULL = 0,
24247+ MV_CESA_CRYPTO_DES = 1,
24248+ MV_CESA_CRYPTO_3DES = 2,
24249+ MV_CESA_CRYPTO_AES = 3,
24250+
24251+} MV_CESA_CRYPTO_ALG;
24252+
24253+#define MV_CESA_CRYPTO_ALG_OFFSET 8
24254+#define MV_CESA_CRYPTO_ALG_MASK (0x3 << MV_CESA_CRYPTO_ALG_OFFSET)
24255+
24256+
24257+/* direction */
24258+typedef enum
24259+{
24260+ MV_CESA_DIR_ENCODE = 0,
24261+ MV_CESA_DIR_DECODE = 1,
24262+
24263+} MV_CESA_DIRECTION;
24264+
24265+#define MV_CESA_DIRECTION_BIT 12
24266+#define MV_CESA_DIRECTION_MASK (1 << MV_CESA_DIRECTION_BIT)
24267+
24268+/* crypto IV mode */
24269+typedef enum
24270+{
24271+ MV_CESA_CRYPTO_ECB = 0,
24272+ MV_CESA_CRYPTO_CBC = 1,
24273+
24274+ /* NO HW Support */
24275+ MV_CESA_CRYPTO_CTR = 10,
24276+
24277+} MV_CESA_CRYPTO_MODE;
24278+
24279+#define MV_CESA_CRYPTO_MODE_BIT 16
24280+#define MV_CESA_CRYPTO_MODE_MASK (1 << MV_CESA_CRYPTO_MODE_BIT)
24281+
24282+/* 3DES mode */
24283+typedef enum
24284+{
24285+ MV_CESA_CRYPTO_3DES_EEE = 0,
24286+ MV_CESA_CRYPTO_3DES_EDE = 1,
24287+
24288+} MV_CESA_CRYPTO_3DES_MODE;
24289+
24290+#define MV_CESA_CRYPTO_3DES_MODE_BIT 20
24291+#define MV_CESA_CRYPTO_3DES_MODE_MASK (1 << MV_CESA_CRYPTO_3DES_MODE_BIT)
24292+
24293+
24294+/* AES Key Length */
24295+typedef enum
24296+{
24297+ MV_CESA_CRYPTO_AES_KEY_128 = 0,
24298+ MV_CESA_CRYPTO_AES_KEY_192 = 1,
24299+ MV_CESA_CRYPTO_AES_KEY_256 = 2,
24300+
24301+} MV_CESA_CRYPTO_AES_KEY_LEN;
24302+
24303+#define MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET 24
24304+#define MV_CESA_CRYPTO_AES_KEY_LEN_MASK (0x3 << MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET)
24305+
24306+/* Fragmentation mode */
24307+typedef enum
24308+{
24309+ MV_CESA_FRAG_NONE = 0,
24310+ MV_CESA_FRAG_FIRST = 1,
24311+ MV_CESA_FRAG_LAST = 2,
24312+ MV_CESA_FRAG_MIDDLE = 3,
24313+
24314+} MV_CESA_FRAG_MODE;
24315+
24316+#define MV_CESA_FRAG_MODE_OFFSET 30
24317+#define MV_CESA_FRAG_MODE_MASK (0x3 << MV_CESA_FRAG_MODE_OFFSET)
24318+/*---------------------------------------------------------------------------*/
24319+
24320+/********** Security Accelerator Command Register **************/
24321+#define MV_CESA_CMD_REG (MV_CESA_REG_BASE + 0xE00)
24322+
24323+#define MV_CESA_CMD_CHAN_ENABLE_BIT 0
24324+#define MV_CESA_CMD_CHAN_ENABLE_MASK (1 << MV_CESA_CMD_CHAN_ENABLE_BIT)
24325+
24326+#define MV_CESA_CMD_CHAN_DISABLE_BIT 2
24327+#define MV_CESA_CMD_CHAN_DISABLE_MASK (1 << MV_CESA_CMD_CHAN_DISABLE_BIT)
24328+
24329+/********** Security Accelerator Descriptor Pointers Register **********/
24330+#define MV_CESA_CHAN_DESC_OFFSET_REG (MV_CESA_REG_BASE + 0xE04)
24331+
24332+/********** Security Accelerator Configuration Register **********/
24333+#define MV_CESA_CFG_REG (MV_CESA_REG_BASE + 0xE08)
24334+
24335+#define MV_CESA_CFG_STOP_DIGEST_ERR_BIT 0
24336+#define MV_CESA_CFG_STOP_DIGEST_ERR_MASK (1 << MV_CESA_CFG_STOP_DIGEST_ERR_BIT)
24337+
24338+#define MV_CESA_CFG_WAIT_DMA_BIT 7
24339+#define MV_CESA_CFG_WAIT_DMA_MASK (1 << MV_CESA_CFG_WAIT_DMA_BIT)
24340+
24341+#define MV_CESA_CFG_ACT_DMA_BIT 9
24342+#define MV_CESA_CFG_ACT_DMA_MASK (1 << MV_CESA_CFG_ACT_DMA_BIT)
24343+
24344+#define MV_CESA_CFG_CHAIN_MODE_BIT 11
24345+#define MV_CESA_CFG_CHAIN_MODE_MASK (1 << MV_CESA_CFG_CHAIN_MODE_BIT)
24346+
24347+/********** Security Accelerator Status Register ***********/
24348+#define MV_CESA_STATUS_REG (MV_CESA_REG_BASE + 0xE0C)
24349+
24350+#define MV_CESA_STATUS_ACTIVE_BIT 0
24351+#define MV_CESA_STATUS_ACTIVE_MASK (1 << MV_CESA_STATUS_ACTIVE_BIT)
24352+
24353+#define MV_CESA_STATUS_DIGEST_ERR_BIT 8
24354+#define MV_CESA_STATUS_DIGEST_ERR_MASK (1 << MV_CESA_STATUS_DIGEST_ERR_BIT)
24355+
24356+
24357+/* Cryptographic Engines and Security Accelerator Interrupt Cause Register */
24358+#define MV_CESA_ISR_CAUSE_REG (MV_CESA_REG_BASE + 0xE20)
24359+
24360+/* Cryptographic Engines and Security Accelerator Interrupt Mask Register */
24361+#define MV_CESA_ISR_MASK_REG (MV_CESA_REG_BASE + 0xE24)
24362+
24363+#define MV_CESA_CAUSE_AUTH_MASK (1 << 0)
24364+#define MV_CESA_CAUSE_DES_MASK (1 << 1)
24365+#define MV_CESA_CAUSE_AES_ENCR_MASK (1 << 2)
24366+#define MV_CESA_CAUSE_AES_DECR_MASK (1 << 3)
24367+#define MV_CESA_CAUSE_DES_ALL_MASK (1 << 4)
24368+
24369+#define MV_CESA_CAUSE_ACC_BIT 5
24370+#define MV_CESA_CAUSE_ACC_MASK (1 << MV_CESA_CAUSE_ACC_BIT)
24371+
24372+#define MV_CESA_CAUSE_ACC_DMA_BIT 7
24373+#define MV_CESA_CAUSE_ACC_DMA_MASK (1 << MV_CESA_CAUSE_ACC_DMA_BIT)
24374+#define MV_CESA_CAUSE_ACC_DMA_ALL_MASK (3 << MV_CESA_CAUSE_ACC_DMA_BIT)
24375+
24376+#define MV_CESA_CAUSE_DMA_COMPL_BIT 9
24377+#define MV_CESA_CAUSE_DMA_COMPL_MASK (1 << MV_CESA_CAUSE_DMA_COMPL_BIT)
24378+
24379+#define MV_CESA_CAUSE_DMA_OWN_ERR_BIT 10
24380+#define MV_CESA_CAUSE_DMA_OWN_ERR_MASK (1 < MV_CESA_CAUSE_DMA_OWN_ERR_BIT)
24381+
24382+#define MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT 11
24383+#define MV_CESA_CAUSE_DMA_CHAIN_PKT_MASK (1 < MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT)
24384+
24385+
24386+#define MV_CESA_AUTH_DATA_IN_REG (MV_CESA_REG_BASE + 0xd38)
24387+#define MV_CESA_AUTH_BIT_COUNT_LOW_REG (MV_CESA_REG_BASE + 0xd20)
24388+#define MV_CESA_AUTH_BIT_COUNT_HIGH_REG (MV_CESA_REG_BASE + 0xd24)
24389+
24390+#define MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i) (MV_CESA_REG_BASE + 0xd00 + (i<<2))
24391+
24392+#define MV_CESA_AUTH_INIT_VAL_DIGEST_A_REG (MV_CESA_REG_BASE + 0xd00)
24393+#define MV_CESA_AUTH_INIT_VAL_DIGEST_B_REG (MV_CESA_REG_BASE + 0xd04)
24394+#define MV_CESA_AUTH_INIT_VAL_DIGEST_C_REG (MV_CESA_REG_BASE + 0xd08)
24395+#define MV_CESA_AUTH_INIT_VAL_DIGEST_D_REG (MV_CESA_REG_BASE + 0xd0c)
24396+#define MV_CESA_AUTH_INIT_VAL_DIGEST_E_REG (MV_CESA_REG_BASE + 0xd10)
24397+#define MV_CESA_AUTH_COMMAND_REG (MV_CESA_REG_BASE + 0xd18)
24398+
24399+#define MV_CESA_AUTH_ALGORITHM_BIT 0
24400+#define MV_CESA_AUTH_ALGORITHM_MD5 (0<<AUTH_ALGORITHM_BIT)
24401+#define MV_CESA_AUTH_ALGORITHM_SHA1 (1<<AUTH_ALGORITHM_BIT)
24402+
24403+#define MV_CESA_AUTH_IV_MODE_BIT 1
24404+#define MV_CESA_AUTH_IV_MODE_INIT (0<<AUTH_IV_MODE_BIT)
24405+#define MV_CESA_AUTH_IV_MODE_CONTINUE (1<<AUTH_IV_MODE_BIT)
24406+
24407+#define MV_CESA_AUTH_DATA_BYTE_SWAP_BIT 2
24408+#define MV_CESA_AUTH_DATA_BYTE_SWAP_MASK (1<<AUTH_DATA_BYTE_SWAP_BIT)
24409+
24410+
24411+#define MV_CESA_AUTH_IV_BYTE_SWAP_BIT 4
24412+#define MV_CESA_AUTH_IV_BYTE_SWAP_MASK (1<<AUTH_IV_BYTE_SWAP_BIT)
24413+
24414+#define MV_CESA_AUTH_TERMINATION_BIT 31
24415+#define MV_CESA_AUTH_TERMINATION_MASK (1<<AUTH_TERMINATION_BIT)
24416+
24417+
24418+/*************** TDMA Control Register ************************************************/
24419+#define MV_CESA_TDMA_CTRL_REG (MV_CESA_TDMA_REG_BASE + 0x840)
24420+
24421+#define MV_CESA_TDMA_BURST_32B 3
24422+#define MV_CESA_TDMA_BURST_128B 4
24423+
24424+#define MV_CESA_TDMA_DST_BURST_OFFSET 0
24425+#define MV_CESA_TDMA_DST_BURST_ALL_MASK (0x7<<MV_CESA_TDMA_DST_BURST_OFFSET)
24426+#define MV_CESA_TDMA_DST_BURST_MASK(burst) ((burst)<<MV_CESA_TDMA_DST_BURST_OFFSET)
24427+
24428+#define MV_CESA_TDMA_OUTSTAND_READ_EN_BIT 4
24429+#define MV_CESA_TDMA_OUTSTAND_READ_EN_MASK (1<<MV_CESA_TDMA_OUTSTAND_READ_EN_BIT)
24430+
24431+#define MV_CESA_TDMA_SRC_BURST_OFFSET 6
24432+#define MV_CESA_TDMA_SRC_BURST_ALL_MASK (0x7<<MV_CESA_TDMA_SRC_BURST_OFFSET)
24433+#define MV_CESA_TDMA_SRC_BURST_MASK(burst) ((burst)<<MV_CESA_TDMA_SRC_BURST_OFFSET)
24434+
24435+#define MV_CESA_TDMA_CHAIN_MODE_BIT 9
24436+#define MV_CESA_TDMA_NON_CHAIN_MODE_MASK (1<<MV_CESA_TDMA_CHAIN_MODE_BIT)
24437+
24438+#define MV_CESA_TDMA_BYTE_SWAP_BIT 11
24439+#define MV_CESA_TDMA_BYTE_SWAP_MASK (0 << MV_CESA_TDMA_BYTE_SWAP_BIT)
24440+#define MV_CESA_TDMA_NO_BYTE_SWAP_MASK (1 << MV_CESA_TDMA_BYTE_SWAP_BIT)
24441+
24442+#define MV_CESA_TDMA_ENABLE_BIT 12
24443+#define MV_CESA_TDMA_ENABLE_MASK (1<<MV_CESA_TDMA_ENABLE_BIT)
24444+
24445+#define MV_CESA_TDMA_FETCH_NEXT_DESC_BIT 13
24446+#define MV_CESA_TDMA_FETCH_NEXT_DESC_MASK (1<<MV_CESA_TDMA_FETCH_NEXT_DESC_BIT)
24447+
24448+#define MV_CESA_TDMA_CHAN_ACTIVE_BIT 14
24449+#define MV_CESA_TDMA_CHAN_ACTIVE_MASK (1<<MV_CESA_TDMA_CHAN_ACTIVE_BIT)
24450+/*------------------------------------------------------------------------------------*/
24451+
24452+#define MV_CESA_TDMA_BYTE_COUNT_REG (MV_CESA_TDMA_REG_BASE + 0x800)
24453+#define MV_CESA_TDMA_SRC_ADDR_REG (MV_CESA_TDMA_REG_BASE + 0x810)
24454+#define MV_CESA_TDMA_DST_ADDR_REG (MV_CESA_TDMA_REG_BASE + 0x820)
24455+#define MV_CESA_TDMA_NEXT_DESC_PTR_REG (MV_CESA_TDMA_REG_BASE + 0x830)
24456+#define MV_CESA_TDMA_CURR_DESC_PTR_REG (MV_CESA_TDMA_REG_BASE + 0x870)
24457+
24458+#define MV_CESA_TDMA_ERROR_CAUSE_REG (MV_CESA_TDMA_REG_BASE + 0x8C0)
24459+#define MV_CESA_TDMA_ERROR_MASK_REG (MV_CESA_TDMA_REG_BASE + 0x8C4)
24460+
24461+
24462+#endif /* __mvCesaRegs_h__ */
24463+
24464diff --git a/crypto/ocf/kirkwood/cesa/mvCesaTest.c b/crypto/ocf/kirkwood/cesa/mvCesaTest.c
24465new file mode 100644
24466index 0000000..694f780
24467--- /dev/null
24468+++ b/crypto/ocf/kirkwood/cesa/mvCesaTest.c
24469@@ -0,0 +1,3096 @@
24470+/*******************************************************************************
24471+Copyright (C) Marvell International Ltd. and its affiliates
24472+
24473+This software file (the "File") is owned and distributed by Marvell
24474+International Ltd. and/or its affiliates ("Marvell") under the following
24475+alternative licensing terms. Once you have made an election to distribute the
24476+File under one of the following license alternatives, please (i) delete this
24477+introductory statement regarding license alternatives, (ii) delete the two
24478+license alternatives that you have not elected to use and (iii) preserve the
24479+Marvell copyright notice above.
24480+
24481+********************************************************************************
24482+Marvell Commercial License Option
24483+
24484+If you received this File from Marvell and you have entered into a commercial
24485+license agreement (a "Commercial License") with Marvell, the File is licensed
24486+to you under the terms of the applicable Commercial License.
24487+
24488+********************************************************************************
24489+Marvell GPL License Option
24490+
24491+If you received this File from Marvell, you may opt to use, redistribute and/or
24492+modify this File in accordance with the terms and conditions of the General
24493+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
24494+available along with the File in the license.txt file or by writing to the Free
24495+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
24496+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
24497+
24498+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
24499+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
24500+DISCLAIMED. The GPL License provides additional details about this warranty
24501+disclaimer.
24502+********************************************************************************
24503+Marvell BSD License Option
24504+
24505+If you received this File from Marvell, you may opt to use, redistribute and/or
24506+modify this File under the following licensing terms.
24507+Redistribution and use in source and binary forms, with or without modification,
24508+are permitted provided that the following conditions are met:
24509+
24510+ * Redistributions of source code must retain the above copyright notice,
24511+ this list of conditions and the following disclaimer.
24512+
24513+ * Redistributions in binary form must reproduce the above copyright
24514+ notice, this list of conditions and the following disclaimer in the
24515+ documentation and/or other materials provided with the distribution.
24516+
24517+ * Neither the name of Marvell nor the names of its contributors may be
24518+ used to endorse or promote products derived from this software without
24519+ specific prior written permission.
24520+
24521+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24522+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24523+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24524+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24525+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24526+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24527+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24528+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24529+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24530+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24531+
24532+*******************************************************************************/
24533+
24534+#include "mvOs.h"
24535+
24536+#if defined(MV_VXWORKS)
24537+
24538+#include "sysLib.h"
24539+#include "logLib.h"
24540+#include "tickLib.h"
24541+#include "intLib.h"
24542+#include "config.h"
24543+
24544+
24545+SEM_ID cesaSemId = NULL;
24546+SEM_ID cesaWaitSemId = NULL;
24547+
24548+#define CESA_TEST_LOCK(flags) flags = intLock()
24549+#define CESA_TEST_UNLOCK(flags) intUnlock(flags)
24550+
24551+#define CESA_TEST_WAIT_INIT() cesaWaitSemId = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)
24552+#define CESA_TEST_WAKE_UP() semGive(cesaWaitSemId)
24553+#define CESA_TEST_WAIT(cond, ms) semTake(cesaWaitSemId, (sysClkRateGet()*ms)/1000)
24554+
24555+#define CESA_TEST_TICK_GET() tickGet()
24556+#define CESA_TEST_TICK_TO_MS(tick) (((tick)*1000)/sysClkRateGet())
24557+
24558+#elif defined(MV_LINUX)
24559+
24560+#include <linux/wait.h>
24561+wait_queue_head_t cesaTest_waitq;
24562+spinlock_t cesaLock;
24563+
24564+#define CESA_TEST_LOCK(flags) spin_lock_irqsave( &cesaLock, flags)
24565+#define CESA_TEST_UNLOCK(flags) spin_unlock_irqrestore( &cesaLock, flags);
24566+
24567+#define CESA_TEST_WAIT_INIT() init_waitqueue_head(&cesaTest_waitq)
24568+#define CESA_TEST_WAKE_UP() wake_up(&cesaTest_waitq)
24569+#define CESA_TEST_WAIT(cond, ms) wait_event_timeout(cesaTest_waitq, (cond), msecs_to_jiffies(ms))
24570+
24571+#define CESA_TEST_TICK_GET() jiffies
24572+#define CESA_TEST_TICK_TO_MS(tick) jiffies_to_msecs(tick)
24573+
24574+#elif defined(MV_NETBSD)
24575+
24576+#include <sys/param.h>
24577+#include <sys/kernel.h>
24578+static int cesaLock;
24579+
24580+#define CESA_TEST_LOCK(flags) flags = splnet()
24581+#define CESA_TEST_UNLOCK(flags) splx(flags)
24582+
24583+#define CESA_TEST_WAIT_INIT() /* nothing */
24584+#define CESA_TEST_WAKE_UP() wakeup(&cesaLock)
24585+#define CESA_TEST_WAIT(cond, ms) \
24586+do { \
24587+ while (!(cond)) \
24588+ tsleep(&cesaLock, PWAIT, "cesatest",mstohz(ms)); \
24589+} while (/*CONSTCOND*/0)
24590+
24591+#define CESA_TEST_TICK_GET() hardclock_ticks
24592+#define CESA_TEST_TICK_TO_MS(tick) ((1000/hz)*(tick))
24593+
24594+#define request_irq(i,h,t,n,a) \
24595+ !mv_intr_establish((i),IPL_NET,(int(*)(void *))(h),(a))
24596+
24597+#else
24598+#error "Only Linux, VxWorks, or NetBSD OS are supported"
24599+#endif
24600+
24601+#include "mvDebug.h"
24602+
24603+#include "mvSysHwConfig.h"
24604+#include "boardEnv/mvBoardEnvLib.h"
24605+#include "ctrlEnv/sys/mvCpuIf.h"
24606+#include "cntmr/mvCntmr.h"
24607+#include "cesa/mvCesa.h"
24608+#include "cesa/mvCesaRegs.h"
24609+#include "cesa/mvMD5.h"
24610+#include "cesa/mvSHA1.h"
24611+
24612+#if defined(CONFIG_MV646xx)
24613+#include "marvell_pic.h"
24614+#endif
24615+
24616+#define MV_CESA_USE_TIMER_ID 0
24617+#define CESA_DEF_BUF_SIZE 1500
24618+#define CESA_DEF_BUF_NUM 1
24619+#define CESA_DEF_SESSION_NUM 32
24620+
24621+#define CESA_DEF_ITER_NUM 100
24622+
24623+#define CESA_DEF_REQ_SIZE 256
24624+
24625+
24626+/* CESA Tests Debug */
24627+#undef CESA_TEST_DEBUG
24628+
24629+#ifdef CESA_TEST_DEBUG
24630+
24631+# define CESA_TEST_DEBUG_PRINT(msg) mvOsPrintf msg
24632+# define CESA_TEST_DEBUG_CODE(code) code
24633+
24634+typedef struct
24635+{
24636+ int type; /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */
24637+ MV_U32 timeStamp;
24638+ MV_U32 cause;
24639+ MV_U32 realCause;
24640+ MV_U32 dmaCause;
24641+ int resources;
24642+ MV_CESA_REQ* pReqReady;
24643+ MV_CESA_REQ* pReqEmpty;
24644+ MV_CESA_REQ* pReqProcess;
24645+} MV_CESA_TEST_TRACE;
24646+
24647+#define MV_CESA_TEST_TRACE_SIZE 25
24648+
24649+static int cesaTestTraceIdx = 0;
24650+static MV_CESA_TEST_TRACE cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];
24651+
24652+static void cesaTestTraceAdd(int type, MV_U32 cause)
24653+{
24654+ cesaTestTrace[cesaTestTraceIdx].type = type;
24655+ cesaTestTrace[cesaTestTraceIdx].cause = cause;
24656+ cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
24657+ cesaTestTrace[cesaTestTraceIdx].dmaCause = MV_REG_READ(IDMA_CAUSE_REG);
24658+ cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;
24659+ cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;
24660+ cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;
24661+ cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;
24662+ cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);
24663+ cesaTestTraceIdx++;
24664+ if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)
24665+ cesaTestTraceIdx = 0;
24666+}
24667+
24668+#else
24669+
24670+# define CESA_TEST_DEBUG_PRINT(msg)
24671+# define CESA_TEST_DEBUG_CODE(code)
24672+
24673+#endif /* CESA_TEST_DEBUG */
24674+
24675+int cesaExpReqId=0;
24676+int cesaCbIter=0;
24677+
24678+int cesaIdx;
24679+int cesaIteration;
24680+int cesaRateSize;
24681+int cesaReqSize;
24682+unsigned long cesaTaskId;
24683+int cesaBufNum;
24684+int cesaBufSize;
24685+int cesaCheckOffset;
24686+int cesaCheckSize;
24687+int cesaCheckMode;
24688+int cesaTestIdx;
24689+int cesaCaseIdx;
24690+
24691+
24692+MV_U32 cesaTestIsrCount = 0;
24693+MV_U32 cesaTestIsrMissCount = 0;
24694+
24695+MV_U32 cesaCryptoError = 0;
24696+MV_U32 cesaReqIdError = 0;
24697+MV_U32 cesaError = 0;
24698+
24699+char* cesaHexBuffer = NULL;
24700+
24701+char* cesaBinBuffer = NULL;
24702+char* cesaExpBinBuffer = NULL;
24703+
24704+char* cesaInputHexStr = NULL;
24705+char* cesaOutputHexStr = NULL;
24706+
24707+MV_BUF_INFO cesaReqBufs[CESA_DEF_REQ_SIZE];
24708+
24709+MV_CESA_COMMAND* cesaCmdRing;
24710+MV_CESA_RESULT cesaResult;
24711+
24712+int cesaTestFull = 0;
24713+
24714+MV_BOOL cesaIsReady = MV_FALSE;
24715+MV_U32 cesaCycles = 0;
24716+MV_U32 cesaBeginTicks = 0;
24717+MV_U32 cesaEndTicks = 0;
24718+MV_U32 cesaRate = 0;
24719+MV_U32 cesaRateAfterDot = 0;
24720+
24721+void *cesaTestOSHandle = NULL;
24722+
24723+enum
24724+{
24725+ CESA_FAST_CHECK_MODE = 0,
24726+ CESA_FULL_CHECK_MODE,
24727+ CESA_NULL_CHECK_MODE,
24728+ CESA_SHOW_CHECK_MODE,
24729+ CESA_SW_SHOW_CHECK_MODE,
24730+ CESA_SW_NULL_CHECK_MODE,
24731+
24732+ CESA_MAX_CHECK_MODE
24733+};
24734+
24735+enum
24736+{
24737+ DES_TEST_TYPE = 0,
24738+ TRIPLE_DES_TEST_TYPE = 1,
24739+ AES_TEST_TYPE = 2,
24740+ MD5_TEST_TYPE = 3,
24741+ SHA_TEST_TYPE = 4,
24742+ COMBINED_TEST_TYPE = 5,
24743+
24744+ MAX_TEST_TYPE
24745+};
24746+
24747+/* Tests data base */
24748+typedef struct
24749+{
24750+ short sid;
24751+ char cryptoAlgorithm; /* DES/3DES/AES */
24752+ char cryptoMode; /* ECB or CBC */
24753+ char macAlgorithm; /* MD5 / SHA1 */
24754+ char operation; /* CRYPTO/HMAC/CRYPTO+HMAC/HMAC+CRYPTO */
24755+ char direction; /* ENCODE(SIGN)/DECODE(VERIFY) */
24756+ unsigned char* pCryptoKey;
24757+ int cryptoKeySize;
24758+ unsigned char* pMacKey;
24759+ int macKeySize;
24760+ const char* name;
24761+
24762+} MV_CESA_TEST_SESSION;
24763+
24764+typedef struct
24765+{
24766+ MV_CESA_TEST_SESSION* pSessions;
24767+ int numSessions;
24768+
24769+} MV_CESA_TEST_DB_ENTRY;
24770+
24771+typedef struct
24772+{
24773+ char* plainHexStr;
24774+ char* cipherHexStr;
24775+ unsigned char* pCryptoIV;
24776+ int cryptoLength;
24777+ int macLength;
24778+ int digestOffset;
24779+
24780+} MV_CESA_TEST_CASE;
24781+
24782+typedef struct
24783+{
24784+ int size;
24785+ const char* outputHexStr;
24786+
24787+} MV_CESA_SIZE_TEST;
24788+
24789+static unsigned char cryptoKey1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
24790+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
24791+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
24792+
24793+static unsigned char cryptoKey7[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
24794+static unsigned char iv1[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef};
24795+
24796+
24797+static unsigned char cryptoKey2[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
24798+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
24799+
24800+static unsigned char cryptoKey3[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
24801+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
24802+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
24803+
24804+static unsigned char cryptoKey4[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
24805+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
24806+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
24807+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
24808+
24809+static unsigned char cryptoKey5[] = {0x56, 0xe4, 0x7a, 0x38, 0xc5, 0x59, 0x89, 0x74,
24810+ 0xbc, 0x46, 0x90, 0x3d, 0xba, 0x29, 0x03, 0x49};
24811+
24812+
24813+static unsigned char key3des1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
24814+ 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
24815+ 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23};
24816+
24817+/* Input ASCII string: The quick brown fox jump */
24818+static char plain3des1[] = "54686520717566636B2062726F776E20666F78206A756D70";
24819+static char cipher3des1[] = "A826FD8CE53B855FCCE21C8112256FE668D5C05DD9B6B900";
24820+
24821+static unsigned char key3des2[] = {0x62, 0x7f, 0x46, 0x0e, 0x08, 0x10, 0x4a, 0x10,
24822+ 0x43, 0xcd, 0x26, 0x5d, 0x58, 0x40, 0xea, 0xf1,
24823+ 0x31, 0x3e, 0xdf, 0x97, 0xdf, 0x2a, 0x8a, 0x8c};
24824+
24825+static unsigned char iv3des2[] = {0x8e, 0x29, 0xf7, 0x5e, 0xa7, 0x7e, 0x54, 0x75};
24826+
24827+static char plain3des2[] = "326a494cd33fe756";
24828+
24829+static char cipher3desCbc2[] = "8e29f75ea77e5475"
24830+ "b22b8d66de970692";
24831+
24832+static unsigned char key3des3[] = {0x37, 0xae, 0x5e, 0xbf, 0x46, 0xdf, 0xf2, 0xdc,
24833+ 0x07, 0x54, 0xb9, 0x4f, 0x31, 0xcb, 0xb3, 0x85,
24834+ 0x5e, 0x7f, 0xd3, 0x6d, 0xc8, 0x70, 0xbf, 0xae};
24835+
24836+static unsigned char iv3des3[] = {0x3d, 0x1d, 0xe3, 0xcc, 0x13, 0x2e, 0x3b, 0x65};
24837+
24838+static char plain3des3[] = "84401f78fe6c10876d8ea23094ea5309";
24839+
24840+static char cipher3desCbc3[] = "3d1de3cc132e3b65"
24841+ "7b1f7c7e3b1c948ebd04a75ffba7d2f5";
24842+
24843+static unsigned char iv5[] = {0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c,
24844+ 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9};
24845+
24846+static unsigned char aesCtrKey[] = {0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
24847+ 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC};
24848+
24849+static unsigned char mdKey1[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
24850+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
24851+
24852+static unsigned char mdKey2[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
24853+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
24854+
24855+static unsigned char shaKey1[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
24856+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
24857+ 0x0b, 0x0b, 0x0b, 0x0b};
24858+
24859+static unsigned char shaKey2[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
24860+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
24861+ 0xaa, 0xaa, 0xaa, 0xaa};
24862+
24863+static unsigned char mdKey4[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
24864+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
24865+
24866+static unsigned char shaKey4[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
24867+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
24868+ 0x11, 0x12, 0x13, 0x14};
24869+
24870+
24871+static MV_CESA_TEST_SESSION desTestSessions[] =
24872+{
24873+/*000*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
24874+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24875+ MV_CESA_DIR_ENCODE,
24876+ cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
24877+ NULL, 0,
24878+ "DES ECB encode",
24879+ },
24880+/*001*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
24881+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24882+ MV_CESA_DIR_DECODE,
24883+ cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
24884+ NULL, 0,
24885+ "DES ECB decode",
24886+ },
24887+/*002*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,
24888+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24889+ MV_CESA_DIR_ENCODE,
24890+ cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
24891+ NULL, 0,
24892+ "DES CBC encode"
24893+ },
24894+/*003*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,
24895+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24896+ MV_CESA_DIR_DECODE,
24897+ cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
24898+ NULL, 0,
24899+ "DES CBC decode"
24900+ },
24901+/*004*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
24902+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24903+ MV_CESA_DIR_ENCODE,
24904+ NULL, 0, NULL, 0,
24905+ "NULL Crypto Algorithm encode"
24906+ },
24907+};
24908+
24909+
24910+static MV_CESA_TEST_SESSION tripleDesTestSessions[] =
24911+{
24912+/*100*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
24913+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24914+ MV_CESA_DIR_ENCODE,
24915+ cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
24916+ NULL, 0,
24917+ "3DES ECB encode",
24918+ },
24919+/*101*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
24920+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24921+ MV_CESA_DIR_DECODE,
24922+ cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
24923+ NULL, 0,
24924+ "3DES ECB decode",
24925+ },
24926+/*102*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
24927+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24928+ MV_CESA_DIR_ENCODE,
24929+ cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
24930+ NULL, 0,
24931+ "3DES CBC encode"
24932+ },
24933+/*103*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
24934+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24935+ MV_CESA_DIR_DECODE,
24936+ cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
24937+ NULL, 0,
24938+ "3DES CBC decode"
24939+ },
24940+/*104*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
24941+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24942+ MV_CESA_DIR_ENCODE,
24943+ key3des1, sizeof(key3des1),
24944+ NULL, 0,
24945+ "3DES ECB encode"
24946+ },
24947+/*105*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
24948+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24949+ MV_CESA_DIR_ENCODE,
24950+ key3des2, sizeof(key3des2),
24951+ NULL, 0,
24952+ "3DES ECB encode"
24953+ },
24954+/*106*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
24955+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24956+ MV_CESA_DIR_ENCODE,
24957+ key3des3, sizeof(key3des3),
24958+ NULL, 0,
24959+ "3DES ECB encode"
24960+ },
24961+};
24962+
24963+
24964+static MV_CESA_TEST_SESSION aesTestSessions[] =
24965+{
24966+/*200*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
24967+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24968+ MV_CESA_DIR_ENCODE,
24969+ cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),
24970+ NULL, 0,
24971+ "AES-128 ECB encode"
24972+ },
24973+/*201*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
24974+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24975+ MV_CESA_DIR_DECODE,
24976+ cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),
24977+ NULL, 0,
24978+ "AES-128 ECB decode"
24979+ },
24980+/*202*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
24981+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24982+ MV_CESA_DIR_ENCODE,
24983+ cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
24984+ NULL, 0,
24985+ "AES-128 CBC encode"
24986+ },
24987+/*203*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
24988+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24989+ MV_CESA_DIR_DECODE,
24990+ cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
24991+ NULL, 0,
24992+ "AES-128 CBC decode"
24993+ },
24994+/*204*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
24995+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
24996+ MV_CESA_DIR_ENCODE,
24997+ cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),
24998+ NULL, 0,
24999+ "AES-192 ECB encode"
25000+ },
25001+/*205*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
25002+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
25003+ MV_CESA_DIR_DECODE,
25004+ cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),
25005+ NULL, 0,
25006+ "AES-192 ECB decode"
25007+ },
25008+/*206*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
25009+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
25010+ MV_CESA_DIR_ENCODE,
25011+ cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),
25012+ NULL, 0,
25013+ "AES-256 ECB encode"
25014+ },
25015+/*207*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
25016+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
25017+ MV_CESA_DIR_DECODE,
25018+ cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),
25019+ NULL, 0,
25020+ "AES-256 ECB decode"
25021+ },
25022+/*208*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CTR,
25023+ MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
25024+ MV_CESA_DIR_ENCODE,
25025+ aesCtrKey, sizeof(aesCtrKey)/sizeof(aesCtrKey[0]),
25026+ NULL, 0,
25027+ "AES-128 CTR encode"
25028+ },
25029+};
25030+
25031+
25032+static MV_CESA_TEST_SESSION md5TestSessions[] =
25033+{
25034+/*300*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
25035+ MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
25036+ MV_CESA_DIR_ENCODE,
25037+ NULL, 0,
25038+ mdKey1, sizeof(mdKey1),
25039+ "HMAC-MD5 Generate Signature"
25040+ },
25041+/*301*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
25042+ MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
25043+ MV_CESA_DIR_DECODE,
25044+ NULL, 0,
25045+ mdKey1, sizeof(mdKey1),
25046+ "HMAC-MD5 Verify Signature"
25047+ },
25048+/*302*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
25049+ MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
25050+ MV_CESA_DIR_ENCODE,
25051+ NULL, 0,
25052+ mdKey2, sizeof(mdKey2),
25053+ "HMAC-MD5 Generate Signature"
25054+ },
25055+/*303*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
25056+ MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
25057+ MV_CESA_DIR_DECODE,
25058+ NULL, 0,
25059+ mdKey2, sizeof(mdKey2),
25060+ "HMAC-MD5 Verify Signature"
25061+ },
25062+/*304*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
25063+ MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
25064+ MV_CESA_DIR_ENCODE,
25065+ NULL, 0,
25066+ mdKey4, sizeof(mdKey4),
25067+ "HMAC-MD5 Generate Signature"
25068+ },
25069+/*305*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
25070+ MV_CESA_MAC_MD5, MV_CESA_MAC_ONLY,
25071+ MV_CESA_DIR_ENCODE,
25072+ NULL, 0,
25073+ NULL, 0,
25074+ "HASH-MD5 Generate Signature"
25075+ },
25076+};
25077+
25078+
25079+static MV_CESA_TEST_SESSION shaTestSessions[] =
25080+{
25081+/*400*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
25082+ MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
25083+ MV_CESA_DIR_ENCODE,
25084+ NULL, 0,
25085+ shaKey1, sizeof(shaKey1),
25086+ "HMAC-SHA1 Generate Signature"
25087+ },
25088+/*401*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
25089+ MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
25090+ MV_CESA_DIR_DECODE,
25091+ NULL, 0,
25092+ shaKey1, sizeof(shaKey1),
25093+ "HMAC-SHA1 Verify Signature"
25094+ },
25095+/*402*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
25096+ MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
25097+ MV_CESA_DIR_ENCODE,
25098+ NULL, 0,
25099+ shaKey2, sizeof(shaKey2),
25100+ "HMAC-SHA1 Generate Signature"
25101+ },
25102+/*403*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
25103+ MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
25104+ MV_CESA_DIR_DECODE,
25105+ NULL, 0,
25106+ shaKey2, sizeof(shaKey2),
25107+ "HMAC-SHA1 Verify Signature"
25108+ },
25109+/*404*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
25110+ MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
25111+ MV_CESA_DIR_ENCODE,
25112+ NULL, 0,
25113+ shaKey4, sizeof(shaKey4),
25114+ "HMAC-SHA1 Generate Signature"
25115+ },
25116+/*405*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
25117+ MV_CESA_MAC_SHA1, MV_CESA_MAC_ONLY,
25118+ MV_CESA_DIR_ENCODE,
25119+ NULL, 0,
25120+ NULL, 0,
25121+ "HASH-SHA1 Generate Signature"
25122+ },
25123+};
25124+
25125+static MV_CESA_TEST_SESSION combinedTestSessions[] =
25126+{
25127+/*500*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
25128+ MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
25129+ MV_CESA_DIR_ENCODE,
25130+ cryptoKey1, MV_CESA_DES_KEY_LENGTH,
25131+ mdKey4, sizeof(mdKey4),
25132+ "DES + MD5 encode"
25133+ },
25134+/*501*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
25135+ MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
25136+ MV_CESA_DIR_ENCODE,
25137+ cryptoKey1, MV_CESA_DES_KEY_LENGTH,
25138+ shaKey4, sizeof(shaKey4),
25139+ "DES + SHA1 encode"
25140+ },
25141+/*502*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
25142+ MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
25143+ MV_CESA_DIR_ENCODE,
25144+ cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
25145+ mdKey4, sizeof(mdKey4),
25146+ "3DES + MD5 encode"
25147+ },
25148+/*503*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
25149+ MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
25150+ MV_CESA_DIR_ENCODE,
25151+ cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
25152+ shaKey4, sizeof(shaKey4),
25153+ "3DES + SHA1 encode"
25154+ },
25155+/*504*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
25156+ MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
25157+ MV_CESA_DIR_ENCODE,
25158+ cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
25159+ mdKey4, sizeof(mdKey4),
25160+ "3DES CBC + MD5 encode"
25161+ },
25162+/*505*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
25163+ MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
25164+ MV_CESA_DIR_ENCODE,
25165+ cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
25166+ shaKey4, sizeof(shaKey4),
25167+ "3DES CBC + SHA1 encode"
25168+ },
25169+/*506*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
25170+ MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
25171+ MV_CESA_DIR_ENCODE,
25172+ cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
25173+ mdKey4, sizeof(mdKey4),
25174+ "AES-128 CBC + MD5 encode"
25175+ },
25176+/*507*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
25177+ MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
25178+ MV_CESA_DIR_ENCODE,
25179+ cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
25180+ shaKey4, sizeof(shaKey4),
25181+ "AES-128 CBC + SHA1 encode"
25182+ },
25183+/*508*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
25184+ MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_THEN_CRYPTO,
25185+ MV_CESA_DIR_DECODE,
25186+ cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
25187+ mdKey4, sizeof(mdKey4),
25188+ "HMAC-MD5 + 3DES decode"
25189+ },
25190+};
25191+
25192+
25193+static MV_CESA_TEST_DB_ENTRY cesaTestsDB[MAX_TEST_TYPE+1] =
25194+{
25195+ { desTestSessions, sizeof(desTestSessions)/sizeof(desTestSessions[0]) },
25196+ { tripleDesTestSessions, sizeof(tripleDesTestSessions)/sizeof(tripleDesTestSessions[0]) },
25197+ { aesTestSessions, sizeof(aesTestSessions)/sizeof(aesTestSessions[0]) },
25198+ { md5TestSessions, sizeof(md5TestSessions)/sizeof(md5TestSessions[0]) },
25199+ { shaTestSessions, sizeof(shaTestSessions)/sizeof(shaTestSessions[0]) },
25200+ { combinedTestSessions, sizeof(combinedTestSessions)/sizeof(combinedTestSessions[0]) },
25201+ { NULL, 0 }
25202+};
25203+
25204+
25205+char cesaNullPlainHexText[] = "000000000000000000000000000000000000000000000000";
25206+
25207+char cesaPlainAsciiText[] = "Now is the time for all ";
25208+char cesaPlainHexEbc[] = "4e6f77206973207468652074696d6520666f7220616c6c20";
25209+char cesaCipherHexEcb[] = "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53";
25210+char cesaPlainHexCbc[] = "1234567890abcdef4e6f77206973207468652074696d6520666f7220616c6c20";
25211+char cesaCipherHexCbc[] = "1234567890abcdefe5c7cdde872bf27c43e934008c389c0f683788499a7c05f6";
25212+
25213+char cesaAesPlainHexEcb[] = "000102030405060708090a0b0c0d0e0f";
25214+char cesaAes128cipherHexEcb[] = "0a940bb5416ef045f1c39458c653ea5a";
25215+char cesaAes192cipherHexEcb[] = "0060bffe46834bb8da5cf9a61ff220ae";
25216+char cesaAes256cipherHexEcb[] = "5a6e045708fb7196f02e553d02c3a692";
25217+
25218+char cesaAsciiStr1[] = "Hi There";
25219+char cesaDataHexStr1[] = "4869205468657265";
25220+char cesaHmacMd5digestHex1[] = "9294727a3638bb1c13f48ef8158bfc9d";
25221+char cesaHmacSha1digestHex1[] = "b617318655057264e28bc0b6fb378c8ef146be00";
25222+char cesaDataAndMd5digest1[] = "48692054686572659294727a3638bb1c13f48ef8158bfc9d";
25223+char cesaDataAndSha1digest1[] = "4869205468657265b617318655057264e28bc0b6fb378c8ef146be00";
25224+
25225+char cesaAesPlainText[] = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
25226+ "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
25227+ "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
25228+ "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
25229+
25230+char cesaAes128CipherCbc[] = "c30e32ffedc0774e6aff6af0869f71aa"
25231+ "0f3af07a9a31a9c684db207eb0ef8e4e"
25232+ "35907aa632c3ffdf868bb7b29d3d46ad"
25233+ "83ce9f9a102ee99d49a53e87f4c3da55";
25234+
25235+char cesaAesIvPlainText[] = "8ce82eefbea0da3c44699ed7db51b7d9"
25236+ "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
25237+ "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
25238+ "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
25239+ "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
25240+
25241+char cesaAes128IvCipherCbc[] = "8ce82eefbea0da3c44699ed7db51b7d9"
25242+ "c30e32ffedc0774e6aff6af0869f71aa"
25243+ "0f3af07a9a31a9c684db207eb0ef8e4e"
25244+ "35907aa632c3ffdf868bb7b29d3d46ad"
25245+ "83ce9f9a102ee99d49a53e87f4c3da55";
25246+
25247+char cesaAesCtrPlain[] = "00E0017B27777F3F4A1786F000000001"
25248+ "000102030405060708090A0B0C0D0E0F"
25249+ "101112131415161718191A1B1C1D1E1F"
25250+ "20212223";
25251+
25252+char cesaAesCtrCipher[] = "00E0017B27777F3F4A1786F000000001"
25253+ "C1CF48A89F2FFDD9CF4652E9EFDB72D7"
25254+ "4540A42BDE6D7836D59A5CEAAEF31053"
25255+ "25B2072F";
25256+
25257+
25258+
25259+/* Input cesaHmacHex3 is '0xdd' repeated 50 times */
25260+char cesaHmacMd5digestHex3[] = "56be34521d144c88dbb8c733f0e8b3f6";
25261+char cesaHmacSha1digestHex3[] = "125d7342b9ac11cd91a39af48aa17b4f63f175d3";
25262+char cesaDataHexStr3[50*2+1] = "";
25263+char cesaDataAndMd5digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacMd5digestHex3)+8*2+1] = "";
25264+char cesaDataAndSha1digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacSha1digestHex3)+8*2+1] = "";
25265+
25266+/* Ascii string is "abc" */
25267+char hashHexStr3[] = "616263";
25268+char hashMd5digest3[] = "900150983cd24fb0d6963f7d28e17f72";
25269+char hashSha1digest3[] = "a9993e364706816aba3e25717850c26c9cd0d89d";
25270+
25271+char hashHexStr80[] = "31323334353637383930"
25272+ "31323334353637383930"
25273+ "31323334353637383930"
25274+ "31323334353637383930"
25275+ "31323334353637383930"
25276+ "31323334353637383930"
25277+ "31323334353637383930"
25278+ "31323334353637383930";
25279+
25280+char hashMd5digest80[] = "57edf4a22be3c955ac49da2e2107b67a";
25281+
25282+char tripleDesThenMd5digest80[] = "b7726a03aad490bd6c5a452a89a1b271";
25283+char tripleDesThenSha1digest80[] = "b2ddeaca91030eab5b95a234ef2c0f6e738ff883";
25284+
25285+char cbc3desThenMd5digest80[] = "6f463057e1a90e0e91ae505b527bcec0";
25286+char cbc3desThenSha1digest80[] = "1b002ed050be743aa98860cf35659646bb8efcc0";
25287+
25288+char cbcAes128ThenMd5digest80[] = "6b6e863ac5a71d15e3e9b1c86c9ba05f";
25289+char cbcAes128ThenSha1digest80[] = "13558472d1fc1c90dffec6e5136c7203452d509b";
25290+
25291+
25292+static MV_CESA_TEST_CASE cesaTestCases[] =
25293+{
25294+ /* plainHexStr cipherHexStr IV crypto mac digest */
25295+ /* Length Length Offset */
25296+ /*0*/ { NULL, NULL, NULL, 0, 0, -1 },
25297+ /*1*/ { cesaPlainHexEbc, cesaCipherHexEcb, NULL, 24, 0, -1 },
25298+ /*2*/ { cesaPlainHexCbc, cesaCipherHexCbc, NULL, 24, 0, -1 },
25299+ /*3*/ { cesaAesPlainHexEcb, cesaAes128cipherHexEcb, NULL, 16, 0, -1 },
25300+ /*4*/ { cesaAesPlainHexEcb, cesaAes192cipherHexEcb, NULL, 16, 0, -1 },
25301+ /*5*/ { cesaAesPlainHexEcb, cesaAes256cipherHexEcb, NULL, 16, 0, -1 },
25302+ /*6*/ { cesaDataHexStr1, cesaHmacMd5digestHex1, NULL, 0, 8, -1 },
25303+ /*7*/ { NULL, cesaDataAndMd5digest1, NULL, 0, 8, -1 },
25304+ /*8*/ { cesaDataHexStr3, cesaHmacMd5digestHex3, NULL, 0, 50, -1 },
25305+ /*9*/ { NULL, cesaDataAndMd5digest3, NULL, 0, 50, -1 },
25306+/*10*/ { cesaAesPlainText, cesaAes128IvCipherCbc, iv5, 64, 0, -1 },
25307+/*11*/ { cesaDataHexStr1, cesaHmacSha1digestHex1, NULL, 0, 8, -1 },
25308+/*12*/ { NULL, cesaDataAndSha1digest1, NULL, 0, 8, -1 },
25309+/*13*/ { cesaDataHexStr3, cesaHmacSha1digestHex3, NULL, 0, 50, -1 },
25310+/*14*/ { NULL, cesaDataAndSha1digest3, NULL, 0, 50, -1 },
25311+/*15*/ { hashHexStr3, hashMd5digest3, NULL, 0, 3, -1 },
25312+/*16*/ { hashHexStr3, hashSha1digest3, NULL, 0, 3, -1 },
25313+/*17*/ { hashHexStr80, tripleDesThenMd5digest80, NULL, 80, 80, -1 },
25314+/*18*/ { hashHexStr80, tripleDesThenSha1digest80, NULL, 80, 80, -1 },
25315+/*19*/ { hashHexStr80, cbc3desThenMd5digest80, iv1, 80, 80, -1 },
25316+/*20*/ { hashHexStr80, cbc3desThenSha1digest80, iv1, 80, 80, -1 },
25317+/*21*/ { hashHexStr80, cbcAes128ThenMd5digest80, iv5, 80, 80, -1 },
25318+/*22*/ { hashHexStr80, cbcAes128ThenSha1digest80, iv5, 80, 80, -1 },
25319+/*23*/ { cesaAesCtrPlain, cesaAesCtrCipher, NULL, 36, 0, -1 },
25320+/*24*/ { cesaAesIvPlainText, cesaAes128IvCipherCbc, NULL, 64, 0, -1 },
25321+/*25*/ { plain3des1, cipher3des1, NULL, 0, 0, -1 },
25322+/*26*/ { plain3des2, cipher3desCbc2, iv3des2,0, 0, -1 },
25323+/*27*/ { plain3des3, cipher3desCbc3, iv3des3,0, 0, -1 },
25324+};
25325+
25326+
25327+/* Key = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
25328+ * 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
25329+ * Input 0xdd repeated "size" times
25330+ */
25331+static MV_CESA_SIZE_TEST mdMultiSizeTest302[] =
25332+{
25333+ { 80, "7a031a640c14a4872814930b1ef3a5b2" },
25334+ { 512, "5488e6c5a14dc72a79f28312ca5b939b" },
25335+ { 1000, "d00814f586a8b78a05724239d2531821" },
25336+ { 1001, "bf07df7b7f49d3f5b5ecacd4e9e63281" },
25337+ { 1002, "1ed4a1a802e87817a819d4e37bb4d0f7" },
25338+ { 1003, "5972ab64a4f265ee371dac2f2f137f90" },
25339+ { 1004, "71f95e7ec3aa7df2548e90898abdb28e" },
25340+ { 1005, "e082790b4857fcfc266e92e59e608814" },
25341+ { 1006, "9500f02fd8ac7fde8b10e4fece9a920d" },
25342+ { 1336, "e42edcce57d0b75b01aa09d71427948b" },
25343+ { 1344, "bb5454ada0deb49ba0a97ffd60f57071" },
25344+ { 1399, "0f44d793e744b24d53f44f295082ee8c" },
25345+ { 1400, "359de8a03a9b707928c6c60e0e8d79f1" },
25346+ { 1401, "e913858b484cbe2b384099ea88d8855b" },
25347+ { 1402, "d9848a164af53620e0540c1d7d87629e" },
25348+ { 1403, "0c9ee1c2c9ef45e9b625c26cbaf3e822" },
25349+ { 1404, "12edd4f609416e3c936170360561b064" },
25350+ { 1405, "7fc912718a05446395345009132bf562" },
25351+ { 1406, "882f17425e579ff0d85a91a59f308aa0" },
25352+ { 1407, "005cae408630a2fb5db82ad9db7e59da" },
25353+ { 1408, "64655f8b404b3fea7a3e3e609bc5088f" },
25354+ { 1409, "4a145284a7f74e01b6bb1a0ec6a0dd80" },
25355+ { 2048, "67caf64475650732def374ebb8bde3fd" },
25356+ { 2049, "6c84f11f472825f7e6cd125c2981884b" },
25357+ { 2050, "8999586754a73a99efbe4dbad2816d41" },
25358+ { 2051, "ba6946b610e098d286bc81091659dfff" },
25359+ { 2052, "d0afa01c92d4d13def2b024f36faed83" },
25360+ { 3072, "61d8beac61806afa2585d74a9a0e6974" },
25361+ { 3074, "f6501a28dcc24d1e4770505c51a87ed3" },
25362+ { 3075, "ea4a6929be67e33e61ff475369248b73" },
25363+ { 4048, "aa8c4d68f282a07e7385acdfa69f4bed" },
25364+ { 4052, "afb5ed2c0e1d430ea59e59ed5ed6b18a" },
25365+ { 4058, "9e8553f9bdd43aebe0bd729f0e600c99" },
25366+ { 6144, "f628f3e5d183fe5cdd3a5abee39cf872" },
25367+ { 6150, "89a3efcea9a2f25f919168ad4a1fd292" },
25368+ { 6400, "cdd176b7fb747873efa4da5e32bdf88f" },
25369+ { 6528, "b1d707b027354aca152c45ee559ccd3f" },
25370+ { 8192, "c600ea4429ac47f9941f09182166e51a" },
25371+ {16384, "16e8754bfbeb4c649218422792267a37" },
25372+ {18432, "0fd0607521b0aa8b52219cfbe215f63e" },
25373+ { 0, NULL },
25374+};
25375+
25376+/* Key = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
25377+ * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
25378+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
25379+ */
25380+static MV_CESA_SIZE_TEST mdMultiSizeTest304[] =
25381+{
25382+ { 80, "a456c4723fee6068530af5a2afa71627" },
25383+ { 512, "f85c2a2344f5de68b432208ad13e5794" },
25384+ { 1000, "35464d6821fd4a293a41eb84e274c8c5" },
25385+ { 1001, "c08eedbdce60cceb54bc2d732bb32c8b" },
25386+ { 1002, "5664f71800c011cc311cb6943339c1b8" },
25387+ { 1003, "779c723b044c585dc7802b13e8501bdc" },
25388+ { 1004, "55e500766a2c307bc5c5fdd15e4cacd4" },
25389+ { 1005, "d5f978954f5c38529d1679d2b714f068" },
25390+ { 1006, "cd3efc827ce628b7281b72172693abf9" },
25391+ { 1336, "6f04479910785878ae6335b8d1e87edf" },
25392+ { 1344, "b6d27b50c2bce1ba2a8e1b5cc4324368" },
25393+ { 1399, "65f70a1d4c86e5eaeb0704c8a7816795" },
25394+ { 1400, "3394b5adc4cb3ff98843ca260a44a88a" },
25395+ { 1401, "3a06f3582033a66a4e57e0603ce94e74" },
25396+ { 1402, "e4d97f5ed51edc48abfa46eeb5c31752" },
25397+ { 1403, "3d05e40b080ee3bedf293cb87b7140e7" },
25398+ { 1404, "8cf294fc3cd153ab18dccb2a52cbf244" },
25399+ { 1405, "d1487bd42f6edd9b4dab316631159221" },
25400+ { 1406, "0527123b6bf6936cf5d369dc18c6c70f" },
25401+ { 1407, "3224a06639db70212a0cd1ae1fcc570a" },
25402+ { 1408, "a9e13335612c0356f5e2c27086e86c43" },
25403+ { 1409, "a86d1f37d1ed8a3552e9a4f04dceea98" },
25404+ { 2048, "396905c9b961cd0f6152abfb69c4449c" },
25405+ { 2049, "49f39bff85d9dcf059fadb89efc4a70f" },
25406+ { 2050, "3a2b4823bc4d0415656550226a63e34a" },
25407+ { 2051, "dec60580d406c782540f398ad0bcc7e0" },
25408+ { 2052, "32f76610a14310309eb748fe025081bf" },
25409+ { 3072, "45edc1a42bf9d708a621076b63b774da" },
25410+ { 3074, "9be1b333fe7c0c9f835fb369dc45f778" },
25411+ { 3075, "8c06fcac7bd0e7b7a17fd6508c09a549" },
25412+ { 4048, "0ddaef848184bf0ad98507a10f1e90e4" },
25413+ { 4052, "81976bcaeb274223983996c137875cb8" },
25414+ { 4058, "0b0a7a1c82bc7cbc64d8b7cd2dc2bb22" },
25415+ { 6144, "1c24056f52725ede2dff0d7f9fc9855f" },
25416+ { 6150, "b7f4b65681c4e43ee68ca466ca9ca4ec" },
25417+ { 6400, "443bbaab9f7331ddd4bf11b659cd43c8" },
25418+ { 6528, "216f44f23047cfee03a7a64f88f9a995" },
25419+ { 8192, "ac7a993b2cad54879dba1bde63e39097" },
25420+ { 8320, "55ed7be9682d6c0025b3221a62088d08" },
25421+ {16384, "c6c722087653b62007aea668277175e5" },
25422+ {18432, "f1faca8e907872c809e14ffbd85792d6" },
25423+ { 0, NULL },
25424+};
25425+
25426+/* HASH-MD5
25427+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
25428+ * repeated "size" times
25429+ */
25430+static MV_CESA_SIZE_TEST mdMultiSizeTest305[] =
25431+{
25432+ { 80, "57edf4a22be3c955ac49da2e2107b67a" },
25433+ { 512, "c729ae8f0736cc377a9767a660eaa04e" },
25434+ { 1000, "f1257a8659eb92d36fe14c6bf3852a6a" },
25435+ { 1001, "f8a46fe8ea04fdc8c7de0e84042d3878" },
25436+ { 1002, "da188dd67bff87d58aa3c02af2d0cc0f" },
25437+ { 1003, "961753017feee04c9b93a8e51658a829" },
25438+ { 1004, "dd68c4338608dcc87807a711636bf2af" },
25439+ { 1005, "e338d567d3ce66bf69ada29658a8759b" },
25440+ { 1006, "443c9811e8b92599b0b149e8d7ec700a" },
25441+ { 1336, "89a98511706008ba4cbd0b4a24fa5646" },
25442+ { 1344, "335a919805f370b9e402a62c6fe01739" },
25443+ { 1399, "5d18d0eddcd84212fe28d812b5e80e3b" },
25444+ { 1400, "6b695c240d2dffd0dffc99459ca76db6" },
25445+ { 1401, "49590f61298a76719bc93a57a30136f5" },
25446+ { 1402, "94c2999fa3ef1910a683d69b2b8476f2" },
25447+ { 1403, "37073a02ab00ecba2645c57c228860db" },
25448+ { 1404, "1bcd06994fce28b624f0c5fdc2dcdd2b" },
25449+ { 1405, "11b93671a64c95079e8cf9e7cddc8b3d" },
25450+ { 1406, "4b6695772a4c66313fa4871017d05f36" },
25451+ { 1407, "d1539b97fbfda1c075624e958de19c5b" },
25452+ { 1408, "b801b9b69920907cd018e8063092ede9" },
25453+ { 1409, "b765f1406cfe78e238273ed01bbcaf7e" },
25454+ { 2048, "1d7e2c64ac29e2b3fb4c272844ed31f5" },
25455+ { 2049, "71d38fac49c6b1f4478d8d88447bcdd0" },
25456+ { 2050, "141c34a5592b1bebfa731e0b23d0cdba" },
25457+ { 2051, "c5e1853f21c59f5d6039bd13d4b380d8" },
25458+ { 2052, "dd44a0d128b63d4b5cccd967906472d7" },
25459+ { 3072, "37d158e33b21390822739d13db7b87fe" },
25460+ { 3074, "aef3b209d01d39d0597fe03634bbf441" },
25461+ { 3075, "335ffb428eabf210bada96d74d5a4012" },
25462+ { 4048, "2434c2b43d798d2819487a886261fc64" },
25463+ { 4052, "ac2fa84a8a33065b2e92e36432e861f8" },
25464+ { 4058, "856781f85616c341c3533d090c1e1e84" },
25465+ { 6144, "e5d134c652c18bf19833e115f7a82e9b" },
25466+ { 6150, "a09a353be7795fac2401dac5601872e6" },
25467+ { 6400, "08b9033ac6a1821398f50af75a2dbc83" },
25468+ { 6528, "3d47aa193a8540c091e7e02f779e6751" },
25469+ { 8192, "d3164e710c0626f6f395b38f20141cb7" },
25470+ { 8320, "b727589d9183ff4e8491dd24466974a3" },
25471+ {16384, "3f54d970793d2274d5b20d10a69938ac" },
25472+ {18432, "f558511dcf81985b7a1bb57fad970531" },
25473+ { 0, NULL },
25474+};
25475+
25476+
25477+/* Key = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
25478+ * 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
25479+ * 0xaa, 0xaa, 0xaa, 0xaa
25480+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
25481+ */
25482+static MV_CESA_SIZE_TEST shaMultiSizeTest402[] =
25483+{
25484+ { 80, "e812f370e659705a1649940d1f78cd7af18affd3" },
25485+ { 512, "e547f886b2c15d995ed76a8a924cb408c8080f66" },
25486+ { 1000, "239443194409f1a5342ecde1a092c8f3a3ed790a" },
25487+ { 1001, "f278ab9a102850a9f48dc4e9e6822afe2d0c52b5" },
25488+ { 1002, "8bcc667df5ab6ece988b3af361d09747c77f4e72" },
25489+ { 1003, "0fae6046c7dc1d3e356b25af836f6077a363f338" },
25490+ { 1004, "0ea48401cc92ae6bc92ae76685269cb0167fbe1a" },
25491+ { 1005, "ecbcd7c879b295bafcd8766cbeac58cc371e31d1" },
25492+ { 1006, "eb4a4a3d07d1e9a15e6f1ab8a9c47f243e27324c" },
25493+ { 1336, "f5950ee1d77c10e9011d2149699c9366fe52529c" },
25494+ { 1344, "b04263604a63c351b0b3b9cf1785b4bdba6c8838" },
25495+ { 1399, "8cb1cff61d5b784045974a2fc69386e3b8d24218" },
25496+ { 1400, "9bb2f3fcbeddb2b90f0be797cd647334a2816d51" },
25497+ { 1401, "23ae462a7a0cb440f7445791079a5d75a535dd33" },
25498+ { 1402, "832974b524a4d3f9cc2f45a3cabf5ccef65cd2aa" },
25499+ { 1403, "d1c683742fe404c3c20d5704a5430e7832a7ec95" },
25500+ { 1404, "867c79042e64f310628e219d8b85594cd0c7adc3" },
25501+ { 1405, "c9d81d49d13d94358f56ccfd61af02b36c69f7c3" },
25502+ { 1406, "0df43daab2786172f9b8d07d61f14a070cf1287a" },
25503+ { 1407, "0fd8f3ad7f169534b274d4c66bbddd89f759e391" },
25504+ { 1408, "3987511182b18473a564436003139b808fa46343" },
25505+ { 1409, "ef667e063c9e9f539a8987a8d0bd3066ee85d901" },
25506+ { 2048, "921109c99f3fedaca21727156d5f2b4460175327" },
25507+ { 2049, "47188600dd165eb45f27c27196d3c46f4f042c1b" },
25508+ { 2050, "8831939904009338de10e7fa670847041387807d" },
25509+ { 2051, "2f8ebb5db2997d614e767be1050366f3641e7520" },
25510+ { 2052, "669e51cd730dae158d3bef8adba075bd95a0d011" },
25511+ { 3072, "cfee66cfd83abc8451af3c96c6b35a41cc6c55f5" },
25512+ { 3074, "216ea26f02976a261b7d21a4dd3085157bedfabd" },
25513+ { 3075, "bd612ebba021fd8e012b14c3bd60c8c5161fabc0" },
25514+ { 4048, "c2564c1fdf2d5e9d7dde7aace2643428e90662e8" },
25515+ { 4052, "91ce61fe924b445dfe7b5a1dcd10a27caec16df6" },
25516+ { 4058, "db2a9be5ee8124f091c7ebd699266c5de223c164" },
25517+ { 6144, "855109903feae2ba3a7a05a326b8a171116eb368" },
25518+ { 6150, "37520bb3a668294d9c7b073e7e3daf8fee248a78" },
25519+ { 6400, "60a353c841b6d2b1a05890349dad2fa33c7536b7" },
25520+ { 6528, "9e53a43a69bb42d7c8522ca8bd632e421d5edb36" },
25521+ { 8192, "a918cb0da862eaea0a33ee0efea50243e6b4927c" },
25522+ { 8320, "29a5dcf55d1db29cd113fcf0572ae414f1c71329" },
25523+ {16384, "6fb27966138e0c8d5a0d65ace817ebd53633cee1" },
25524+ {18432, "ca09900d891c7c9ae2a559b10f63a217003341c1" },
25525+ { 0, NULL },
25526+};
25527+
25528+/* Key = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
25529+ * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
25530+ * 0x11, 0x12, 0x13, 0x14
25531+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
25532+ */
25533+static MV_CESA_SIZE_TEST shaMultiSizeTest404[] =
25534+{
25535+ { 80, "beaf20a34b06a87558d156c0949bc3957d40222e" },
25536+ { 512, "3353955358d886bc2940a3c7f337ff7dafb59c7b" },
25537+ { 1000, "8737a542c5e9b2b6244b757ebb69d5bd602a829f" },
25538+ { 1001, "fd9e7582d8a5d3c9fe3b923e4e6a41b07a1eb4d4" },
25539+ { 1002, "a146d14a6fc3c274ff600568f4d75b977989e00d" },
25540+ { 1003, "be22601bbc027ddef2dec97d30b3dc424fd803c5" },
25541+ { 1004, "3e71fe99b2fe2b7bfdf4dbf0c7f3da25d7ea35e7" },
25542+ { 1005, "2c422735d7295408fddd76f5e8a83a2a8da13df3" },
25543+ { 1006, "6d875319049314b61855101a647b9ba3313428e6" },
25544+ { 1336, "c1631ea80bad9dc43a180712461b65a0598c711c" },
25545+ { 1344, "816069bf91d34581005746e2e0283d0f9c7b7605" },
25546+ { 1399, "4e139866dc61cfcb8b67ca2ebd637b3a538593af" },
25547+ { 1400, "ff2a0f8dd2b02c5417910f6f55d33a78e081a723" },
25548+ { 1401, "ab00c12be62336964cbce31ae97fe2a0002984d5" },
25549+ { 1402, "61349e7f999f3a1acc56c3e9a5060a9c4a7b05b6" },
25550+ { 1403, "3edbc0f61e435bc1317fa27d840076093fb79353" },
25551+ { 1404, "d052c6dfdbe63d45dab23ef9893e2aa4636aca1e" },
25552+ { 1405, "0cc16b7388d67bf0add15a31e6e6c753cfae4987" },
25553+ { 1406, "c96ba7eaad74253c38c22101b558d2850b1d1b90" },
25554+ { 1407, "3445428a40d2c6556e7c55797ad8d323b61a48d9" },
25555+ { 1408, "8d6444f937a09317c89834187b8ea9b8d3a8c56b" },
25556+ { 1409, "c700acd3ecd19014ea2bdb4d42510c467e088475" },
25557+ { 2048, "ee27d2a0cb77470c2f496212dfd68b5bb7b04e4b" },
25558+ { 2049, "683762d7a02983b26a6d046e6451d9cd82c25932" },
25559+ { 2050, "0fd20f1d55a9ee18363c2a6fd54aa13aee69992f" },
25560+ { 2051, "86c267d8cc4bc8d59090e4f8b303da960fd228b7" },
25561+ { 2052, "452395ae05b3ec503eea34f86fc0832485ad97c1" },
25562+ { 3072, "75198e3cfd0b9bcff2dabdf8e38e6fdaa33ca49a" },
25563+ { 3074, "4e24785ef080141ce4aab4675986d9acea624d7c" },
25564+ { 3075, "3a20c5978dd637ec0e809bf84f0d9ccf30bc65bf" },
25565+ { 4048, "3c32da256be7a7554922bf5fed51b0d2d09e59ad" },
25566+ { 4052, "fff898426ea16e54325ae391a32c6c9bce4c23c0" },
25567+ { 4058, "c800b9e562e1c91e1310116341a3c91d37f848ec" },
25568+ { 6144, "d91d509d0cc4376c2d05bf9a5097717a373530e6" },
25569+ { 6150, "d957030e0f13c5df07d9eec298542d8f94a07f12" },
25570+ { 6400, "bb745313c3d7dc17b3f955e5534ad500a1082613" },
25571+ { 6528, "77905f80d9ca82080bbb3e5654896dabfcfd1bdb" },
25572+ { 8192, "5237fd9a81830c974396f99f32047586612ff3c0" },
25573+ { 8320, "57668e28d5f2dba0839518a11db0f6af3d7e08bf" },
25574+ {16384, "62e093fde467f0748087beea32e9af97d5c61241" },
25575+ {18432, "845fb33130c7d6ea554fd5aacb9c50cf7ccb5929" },
25576+ { 0, NULL },
25577+};
25578+
25579+/* HASH-SHA1
25580+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
25581+ * repeated "size" times
25582+ */
25583+static MV_CESA_SIZE_TEST shaMultiSizeTest405[] =
25584+{
25585+ { 80, "50abf5706a150990a08b2c5ea40fa0e585554732" },
25586+ { 512, "f14516a08948fa27917a974d219741a697ba0087" },
25587+ { 1000, "0bd18c378d5788817eb4f1e5dc07d867efa5cbf4" },
25588+ { 1001, "ca29b85c35db1b8aef83c977893a11159d1b7aa2" },
25589+ { 1002, "d83bc973eaaedb8a31437994dabbb3304b0be086" },
25590+ { 1003, "2cf7bbef0acd6c00536b5c58ca470df9a3a90b6c" },
25591+ { 1004, "e4375d09b1223385a8a393066f8209acfd936a80" },
25592+ { 1005, "1029b38043e027745d019ce1d2d68e3d8b9d8f99" },
25593+ { 1006, "deea16dcebbd8ac137e2b984deb639b9fb5e9680" },
25594+ { 1336, "ea031b065fff63dcfb6a41956e4777520cdbc55d" },
25595+ { 1344, "b52096c6445e6c0a8355995c70dc36ae186c863c" },
25596+ { 1399, "cde2f6f8379870db4b32cf17471dc828a8dbff2b" },
25597+ { 1400, "e53ff664064bc09fe5054c650806bd42d8179518" },
25598+ { 1401, "d1156db5ddafcace64cdb510ff0d4af9b9a8ad64" },
25599+ { 1402, "34ede0e9a909dd84a2ae291539105c0507b958e1" },
25600+ { 1403, "a772ca3536da77e6ad3251e4f9e1234a4d7b87c0" },
25601+ { 1404, "29740fd2b04e7a8bfd32242db6233156ad699948" },
25602+ { 1405, "65b17397495b70ce4865dad93bf991b74c97cce1" },
25603+ { 1406, "a7ee89cd0754061fdb91af7ea6abad2c69d542e3" },
25604+ { 1407, "3eebf82f7420188e23d328b7ce93580b279a5715" },
25605+ { 1408, "e08d3363a8b9a490dfb3a4c453452b8f114deeec" },
25606+ { 1409, "95d74df739181a4ff30b8c39e28793a36598e924" },
25607+ { 2048, "aa40262509c2abf84aab0197f83187fc90056d91" },
25608+ { 2049, "7dec28ef105bc313bade8d9a7cdeac58b99de5ea" },
25609+ { 2050, "d2e30f77ec81197de20f56588a156094ecb88450" },
25610+ { 2051, "6b22ccc874833e96551a39da0c0edcaa0d969d92" },
25611+ { 2052, "f843141e57875cd669af58744bc60aa9ea59549c" },
25612+ { 3072, "09c5fedeaa62c132e673cc3c608a00142273d086" },
25613+ { 3074, "b09e95eea9c7b1b007a58accec488301901a7f3d" },
25614+ { 3075, "e6226b77b4ada287a8c9bbcf4ed71eec5ce632dc" },
25615+ { 4048, "e99394894f855821951ddddf5bfc628547435f5c" },
25616+ { 4052, "32d2f1af38be9cfba6cd03d55a254d0b3e1eb382" },
25617+ { 4058, "d906552a4f2aca3a22e1fecccbcd183d7289d0ef" },
25618+ { 6144, "2e7f62d35a860988e1224dc0543204af19316041" },
25619+ { 6150, "d6b89698ee133df46fec9d552fadc328aa5a1b51" },
25620+ { 6400, "dff50e90c46853988fa3a4b4ce5dda6945aae976" },
25621+ { 6528, "9e63ec0430b96db02d38bc78357a2f63de2ab7f8" },
25622+ { 8192, "971eb71ed60394d5ab5abb12e88420bdd41b5992" },
25623+ { 8320, "91606a31b46afeaac965cecf87297e791b211013" },
25624+ {16384, "547f830a5ec1f5f170ce818f156b1002cabc7569" },
25625+ {18432, "f16f272787f3b8d539652e4dc315af6ab4fda0ef" },
25626+ { 0, NULL },
25627+};
25628+
25629+/* CryptoKey = 0x01234567, 0x89abcdef,
25630+ * 0x01234567, 0x89abcdef,
25631+ * 0x01234567, 0x89abcdef;
25632+ * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
25633+ * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
25634+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
25635+ * Note: only sizes aligned to 3DES block size (8 bytes) allowed
25636+ */
25637+static MV_CESA_SIZE_TEST tripleDesMdMultiSizeTest502[] =
25638+{
25639+ { 64, "9586962a2aaaef28803dec2e17807a7f" },
25640+ { 80, "b7726a03aad490bd6c5a452a89a1b271" },
25641+ { 352, "f1ed9563aecc3c0d2766eb2bed3b4e4c" },
25642+ { 512, "0f9decb11ab40fe86f4d4d9397bc020e" },
25643+ { 1000, "3ba69deac12cab8ff9dff7dbd9669927" },
25644+ { 1336, "6cf47bf1e80e03e2c1d0945bc50d37d2" },
25645+ { 1344, "4be388dab21ceb3fa1b8d302e9b821f7" },
25646+ { 1400, "a58b79fb21dd9bfc6ec93e3b99fb0ef1" },
25647+ { 1408, "8bc97379fc2ac3237effcdd4f7a86528" },
25648+ { 2048, "1339f03ab3076f25a20bc4cba16eb5bf" },
25649+ { 3072, "731204d2d90c4b36ae41f5e1fb874288" },
25650+ { 4048, "c028d998cfda5642547b7e1ed5ea16e4" },
25651+ { 6144, "b1b19cd910cc51bd22992f1e59f1e068" },
25652+ { 6400, "44e4613496ba622deb0e7cb768135a2f" },
25653+ { 6528, "3b06b0a86f8db9cd67f9448dfcf10549" },
25654+ { 8192, "d581780b7163138a0f412be681457d82" },
25655+ {16384, "03b8ac05527faaf1bed03df149c65ccf" },
25656+ {18432, "677c8a86a41dab6c5d81b85b8fb10ff6" },
25657+ { 0, NULL },
25658+};
25659+
25660+
25661+/* CryptoKey = 0x01234567, 0x89abcdef,
25662+ * 0x01234567, 0x89abcdef,
25663+ * 0x01234567, 0x89abcdef;
25664+ * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
25665+ * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
25666+ * 0x11, 0x12, 0x13, 0x14
25667+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
25668+ * Note: only sizes aligned to 3DES block size (8 bytes) allowed
25669+ */
25670+static MV_CESA_SIZE_TEST tripleDesShaMultiSizeTest503[] =
25671+{
25672+ { 64, "44a1e9bcbfc1429630d9ea68b7a48b0427a684f2" },
25673+ { 80, "b2ddeaca91030eab5b95a234ef2c0f6e738ff883" },
25674+ { 352, "4b91864c7ff629bdff75d9726421f76705452aaf" },
25675+ { 512, "6dd37faceeb2aa98ba74f4242ed6734a4d546af5" },
25676+ { 1000, "463661c30300be512a9df40904f0757cde5f1141" },
25677+ { 1336, "b931f831d9034fe59c65176400b039fe9c1f44a5" },
25678+ { 1344, "af8866b1cd4a4887d6185bfe72470ffdfb3648e1" },
25679+ { 1400, "49c6caf07296d5e31d2504d088bc5b20c3ee7cdb" },
25680+ { 1408, "fcae8deedbc6ebf0763575dc7e9de075b448a0f4" },
25681+ { 2048, "edece5012146c1faa0dd10f50b183ba5d2af58ac" },
25682+ { 3072, "5b83625adb43a488b8d64fecf39bb766818547b7" },
25683+ { 4048, "d2c533678d26c970293af60f14c8279dc708bfc9" },
25684+ { 6144, "b8f67af4f991b08b725f969b049ebf813bfacc5c" },
25685+ { 6400, "d9a6c7f746ac7a60ef2edbed2841cf851c25cfb0" },
25686+ { 6528, "376792b8c8d18161d15579fb7829e6e3a27e9946" },
25687+ { 8192, "d890eabdca195b34ef8724b28360cffa92ae5655" },
25688+ {16384, "a167ee52639ec7bf19aee9c6e8f76667c14134b9" },
25689+ {18432, "e4396ab56f67296b220985a12078f4a0e365d2cc" },
25690+ { 0, NULL },
25691+};
25692+
25693+/* CryptoKey = 0x01234567, 0x89abcdef,
25694+ * 0x01234567, 0x89abcdef,
25695+ * 0x01234567, 0x89abcdef
25696+ * IV = 0x12345678, 0x90abcdef
25697+ * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
25698+ * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
25699+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
25700+ * Note: only sizes aligned to 3DES block size (8 bytes) allowed
25701+ */
25702+static MV_CESA_SIZE_TEST cbc3desMdMultiSizeTest504[] =
25703+{
25704+ { 64, "8d10e00802460ede0058c139ba48bd2d" },
25705+ { 80, "6f463057e1a90e0e91ae505b527bcec0" },
25706+ { 352, "4938d48bdf86aece2c6851e7c6079788" },
25707+ { 512, "516705d59f3cf810ebf2a13a23a7d42e" },
25708+ { 1000, "a5a000ee5c830e67ddc6a2d2e5644b31" },
25709+ { 1336, "44af60087b74ed07950088efbe3b126a" },
25710+ { 1344, "1f5b39e0577920af731dabbfcf6dfc2a" },
25711+ { 1400, "6804ea640e29b9cd39e08bc37dbce734" },
25712+ { 1408, "4fb436624b02516fc9d1535466574bf9" },
25713+ { 2048, "c909b0985c423d8d86719f701e9e83db" },
25714+ { 3072, "cfe0bc34ef97213ee3d3f8b10122db21" },
25715+ { 4048, "03ea10b5ae4ddeb20aed6af373082ed1" },
25716+ { 6144, "b9a0ff4f87fc14b3c2dc6f0ed0998fdf" },
25717+ { 6400, "6995f85d9d4985dd99e974ec7dda9dd6" },
25718+ { 6528, "bbbb548ce2fa3d58467f6a6a5168a0e6" },
25719+ { 8192, "afe101fbe745bb449ae4f50d10801456" },
25720+ {16384, "9741706d0b1c923340c4660ff97cacdf" },
25721+ {18432, "b0217becb73cb8f61fd79c7ce9d023fb" },
25722+ { 0, NULL },
25723+};
25724+
25725+
25726+/* CryptoKey = 0x01234567, 0x89abcdef,
25727+ * 0x01234567, 0x89abcdef,
25728+ * 0x01234567, 0x89abcdef;
25729+ * IV = 0x12345678, 0x90abcdef
25730+ * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
25731+ * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
25732+ * 0x11, 0x12, 0x13, 0x14
25733+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
25734+ * Note: only sizes aligned to 3DES block size (8 bytes) allowed
25735+ */
25736+static MV_CESA_SIZE_TEST cbc3desShaMultiSizeTest505[] =
25737+{
25738+ { 64, "409187e5bdb0be4a7754ca3747f7433dc4f01b98" },
25739+ { 80, "1b002ed050be743aa98860cf35659646bb8efcc0" },
25740+ { 352, "6cbf7ebe50fa4fa6eecc19eca23f9eae553ccfff" },
25741+ { 512, "cfb5253fb4bf72b743320c30c7e48c54965853b0" },
25742+ { 1000, "95e04e1ca2937e7c5a9aba9e42d2bcdb8a7af21f" },
25743+ { 1336, "3b5c1f5eee5837ebf67b83ae01405542d77a6627" },
25744+ { 1344, "2b3d42ab25615437f98a1ee310b81d07a02badc2" },
25745+ { 1400, "7f8687df7c1af44e4baf3c934b6cca5ab6bc993e" },
25746+ { 1408, "473a581c5f04f7527d50793c845471ac87e86430" },
25747+ { 2048, "e41d20cae7ebe34e6e828ed62b1e5734019037bb" },
25748+ { 3072, "275664afd7a561d804e6b0d204e53939cde653ae" },
25749+ { 4048, "0d220cc5b34aeeb46bbbd637dde6290b5a8285a3" },
25750+ { 6144, "cb393ddcc8b1c206060625b7d822ef9839e67bc5" },
25751+ { 6400, "dd3317e2a627fc04800f74a4b05bfda00fab0347" },
25752+ { 6528, "8a74c3b2441ab3f5a7e08895cc432566219a7c41" },
25753+ { 8192, "b8e6ef3a549ed0e005bd5b8b1a5fe6689e9711a7" },
25754+ {16384, "55f59404008276cdac0e2ba0d193af2d40eac5ce" },
25755+ {18432, "86ae6c4fc72369a54cce39938e2d0296cd9c6ec5" },
25756+ { 0, NULL },
25757+};
25758+
25759+
25760+/* CryptoKey = 0x01234567, 0x89abcdef,
25761+ * 0x01234567, 0x89abcdef,
25762+ * 0x01234567, 0x89abcdef
25763+ * IV = 0x12345678, 0x90abcdef
25764+ * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
25765+ * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
25766+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
25767+ * Note: only sizes aligned to AES block size (16 bytes) allowed
25768+ */
25769+static MV_CESA_SIZE_TEST cbcAes128md5multiSizeTest506[] =
25770+{
25771+ { 16, "7ca4c2ba866751598720c5c4aa0d6786" },
25772+ { 64, "7dba7fb988e80da609b1fea7254bced8" },
25773+ { 80, "6b6e863ac5a71d15e3e9b1c86c9ba05f" },
25774+ { 352, "a1ceb9c2e3021002400d525187a9f38c" },
25775+ { 512, "596c055c1c55db748379223164075641" },
25776+ { 1008, "f920989c02f3b3603f53c99d89492377" },
25777+ { 1344, "2e496b73759d77ed32ea222dbd2e7b41" },
25778+ { 1408, "7178c046b3a8d772efdb6a71c4991ea4" },
25779+ { 2048, "a917f0099c69eb94079a8421714b6aad" },
25780+ { 3072, "693cd5033d7f5391d3c958519fa9e934" },
25781+ { 4048, "139dca91bcff65b3c40771749052906b" },
25782+ { 6144, "428d9cef6df4fb70a6e9b6bbe4819e55" },
25783+ { 6400, "9c0b909e76daa811e12b1fc17000a0c4" },
25784+ { 6528, "ad876f6297186a7be1f1b907ed860eda" },
25785+ { 8192, "479cbbaca37dd3191ea1f3e8134a0ef4" },
25786+ {16384, "60fda559c74f91df538100c9842f2f15" },
25787+ {18432, "4a3eb1cba1fa45f3981270953f720c42" },
25788+ { 0, NULL },
25789+};
25790+
25791+
25792+/* CryptoKey = 0x01234567, 0x89abcdef,
25793+ * 0x01234567, 0x89abcdef,
25794+ * 0x01234567, 0x89abcdef;
25795+ * IV = 0x12345678, 0x90abcdef
25796+ * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
25797+ * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
25798+ * 0x11, 0x12, 0x13, 0x14
25799+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
25800+ * Note: only sizes aligned to AES block size (16 bytes) allowed
25801+ */
25802+static MV_CESA_SIZE_TEST cbcAes128sha1multiSizeTest507[] =
25803+{
25804+ { 16, "9aa8dc1c45f0946daf78057fa978759c625c1fee" },
25805+ { 64, "9f588fc1ede851e5f8b20256abc9979465ae2189" },
25806+ { 80, "13558472d1fc1c90dffec6e5136c7203452d509b" },
25807+ { 352, "6b93518e006cfaa1f7adb24615e7291fb0a27e06" },
25808+ { 512, "096874951a77fbbf333e49d80c096ee2016e09bd" },
25809+ { 1008, "696fc203c2e4b5ae0ec5d1db3f623c490bc6dbac" },
25810+ { 1344, "79bf77509935ccd3528caaac6a5eb6481f74029b" },
25811+ { 1408, "627f9462b95fc188e8cfa7eec15119bdc5d4fcf1" },
25812+ { 2048, "3d50d0c005feba92fe41502d609fced9c882b4d1" },
25813+ { 3072, "758807e5b983e3a91c06fb218fe0f73f77111e94" },
25814+ { 4048, "ca90e85242e33f005da3504416a52098d0d31fb2" },
25815+ { 6144, "8044c1d4fd06642dfc46990b4f18b61ef1e972cf" },
25816+ { 6400, "166f1f4ea57409f04feba9fb1e39af0e00bd6f43" },
25817+ { 6528, "0389016a39485d6e330f8b4215ddf718b404f7e9" },
25818+ { 8192, "6df7ee2a8b61d6f7f860ce8dbf778f0c2a5b508b" },
25819+ {16384, "a70a6d8dfa1f91ded621c3dbaed34162bc48783f" },
25820+ {18432, "8dfad627922ce15df1eed10bdbed49244efa57db" },
25821+ { 0, NULL },
25822+};
25823+
25824+
25825+void cesaTestPrintStatus(void);
25826+
25827+
25828+/*------------------------- LOCAL FUNCTIONs ---------------------------------*/
25829+MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,
25830+ MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize);
25831+MV_STATUS testClose(int idx);
25832+MV_STATUS testOpen(int idx);
25833+void close_session(int sid);
25834+void cesaTestCheckReady(const MV_CESA_RESULT *r);
25835+void cesaCheckReady(MV_CESA_RESULT* r);
25836+void printTestResults(int idx, MV_STATUS status, int checkMode);
25837+void cesaLastResult(void);
25838+void cesaTestPrintReq(int req, int offset, int size);
25839+
25840+void cesaTestPrintStatus(void);
25841+void cesaTestPrintSession(int idx);
25842+void sizeTest(int testIdx, int iter, int checkMode);
25843+void multiTest(int iter, int reqSize, int checkMode);
25844+void oneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);
25845+void multiSizeTest(int idx, int iter, int checkMode, char* inputData);
25846+void cesaTest(int iter, int reqSize, int checkMode);
25847+void cesaOneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);
25848+void combiTest(int iter, int reqSize, int checkMode);
25849+void shaTest(int iter, int reqSize, int checkMode);
25850+void mdTest(int iter, int reqSize, int checkMode);
25851+void aesTest(int iter, int reqSize, int checkMode);
25852+void tripleDesTest(int iter, int reqSize, int checkMode);
25853+void desTest(int iter, int reqSize, int checkMode);
25854+void cesaTestStop(void);
25855+MV_STATUS testRun(int idx, int caseIdx, int iter,int reqSize, int checkMode);
25856+void cesaTestStart(int bufNum, int bufSize);
25857+
25858+
25859+static MV_U32 getRate(MV_U32* remainder)
25860+{
25861+ MV_U32 kBits, milliSec, rate;
25862+
25863+ milliSec = 0;
25864+ if( (cesaEndTicks - cesaBeginTicks) > 0)
25865+ {
25866+ milliSec = CESA_TEST_TICK_TO_MS(cesaEndTicks - cesaBeginTicks);
25867+ }
25868+ if(milliSec == 0)
25869+ {
25870+ if(remainder != NULL)
25871+ *remainder = 0;
25872+ return 0;
25873+ }
25874+
25875+ kBits = (cesaIteration*cesaRateSize*8)/1000;
25876+ rate = kBits/milliSec;
25877+ if(remainder != NULL)
25878+ *remainder = ((kBits % milliSec)*10)/milliSec;
25879+
25880+ return rate;
25881+}
25882+
25883+static char* extractMbuf(MV_CESA_MBUF *pMbuf,
25884+ int offset, int size, char* hexStr)
25885+{
25886+ mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, size);
25887+ mvBinToHex((const MV_U8*)cesaBinBuffer, hexStr, size);
25888+
25889+ return hexStr;
25890+}
25891+
25892+static MV_BOOL cesaCheckMbuf(MV_CESA_MBUF *pMbuf,
25893+ const char* hexString, int offset,
25894+ int checkSize)
25895+{
25896+ MV_BOOL isFailed = MV_FALSE;
25897+ MV_STATUS status;
25898+ int size = strlen(hexString)/2;
25899+ int checkedSize = 0;
25900+/*
25901+ mvOsPrintf("cesaCheckMbuf: pMbuf=%p, offset=%d, checkSize=%d, mBufSize=%d\n",
25902+ pMbuf, offset, checkSize, pMbuf->mbufSize);
25903+*/
25904+ if(pMbuf->mbufSize < (checkSize + offset))
25905+ {
25906+ mvOsPrintf("checkSize (%d) is too large: offset=%d, mbufSize=%d\n",
25907+ checkSize, offset, pMbuf->mbufSize);
25908+ return MV_TRUE;
25909+ }
25910+ status = mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, checkSize);
25911+ if(status != MV_OK)
25912+ {
25913+ mvOsPrintf("CesaTest: Can't copy %d bytes from Mbuf=%p to checkBuf=%p\n",
25914+ checkSize, pMbuf, cesaBinBuffer);
25915+ return MV_TRUE;
25916+ }
25917+/*
25918+ mvDebugMemDump(cesaBinBuffer, size, 1);
25919+*/
25920+ mvHexToBin(hexString, (MV_U8*)cesaExpBinBuffer, size);
25921+
25922+ /* Compare buffers */
25923+ while(checkSize > checkedSize)
25924+ {
25925+ size = MV_MIN(size, (checkSize - checkedSize));
25926+ if(memcmp(cesaExpBinBuffer, &cesaBinBuffer[checkedSize], size) != 0)
25927+ {
25928+ mvOsPrintf("CheckMbuf failed: checkSize=%d, size=%d, checkedSize=%d\n",
25929+ checkSize, size, checkedSize);
25930+ mvDebugMemDump(&cesaBinBuffer[checkedSize], size, 1);
25931+ mvDebugMemDump(cesaExpBinBuffer, size, 1);
25932+
25933+ isFailed = MV_TRUE;
25934+ break;
25935+ }
25936+ checkedSize += size;
25937+ }
25938+
25939+ return isFailed;
25940+}
25941+
25942+static MV_STATUS cesaSetMbuf(MV_CESA_MBUF *pMbuf,
25943+ const char* hexString,
25944+ int offset, int reqSize)
25945+{
25946+ MV_STATUS status = MV_OK;
25947+ int copySize, size = strlen(hexString)/2;
25948+
25949+ mvHexToBin(hexString, (MV_U8*)cesaBinBuffer, size);
25950+
25951+ copySize = 0;
25952+ while(reqSize > copySize)
25953+ {
25954+ size = MV_MIN(size, (reqSize - copySize));
25955+
25956+ status = mvCesaCopyToMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset+copySize, size);
25957+ if(status != MV_OK)
25958+ {
25959+ mvOsPrintf("cesaSetMbuf Error: Copy %d of %d bytes to MBuf\n",
25960+ copySize, reqSize);
25961+ break;
25962+ }
25963+ copySize += size;
25964+ }
25965+ pMbuf->mbufSize = offset+copySize;
25966+ return status;
25967+}
25968+
25969+static MV_CESA_TEST_SESSION* getTestSessionDb(int idx, int* pTestIdx)
25970+{
25971+ int testIdx, dbIdx = idx/100;
25972+
25973+ if(dbIdx > MAX_TEST_TYPE)
25974+ {
25975+ mvOsPrintf("Wrong index %d - No such test type\n", idx);
25976+ return NULL;
25977+ }
25978+ testIdx = idx % 100;
25979+
25980+ if(testIdx >= cesaTestsDB[dbIdx].numSessions)
25981+ {
25982+ mvOsPrintf("Wrong index %d - No such test\n", idx);
25983+ return NULL;
25984+ }
25985+ if(pTestIdx != NULL)
25986+ *pTestIdx = testIdx;
25987+
25988+ return cesaTestsDB[dbIdx].pSessions;
25989+}
25990+
25991+/* Debug */
25992+void cesaTestPrintReq(int req, int offset, int size)
25993+{
25994+ MV_CESA_MBUF* pMbuf;
25995+
25996+ mvOsPrintf("cesaTestPrintReq: req=%d, offset=%d, size=%d\n",
25997+ req, offset, size);
25998+ mvDebugMemDump(cesaCmdRing, 128, 4);
25999+
26000+ pMbuf = cesaCmdRing[req].pSrc;
26001+ mvCesaDebugMbuf("src", pMbuf, offset,size);
26002+ pMbuf = cesaCmdRing[req].pDst;
26003+ mvCesaDebugMbuf("dst", pMbuf, offset, size);
26004+
26005+ cesaTestPrintStatus();
26006+}
26007+
26008+void cesaLastResult(void)
26009+{
26010+ mvOsPrintf("Last Result: ReqId = %d, SessionId = %d, rc = (%d)\n",
26011+ (MV_U32)cesaResult.pReqPrv, cesaResult.sessionId,
26012+ cesaResult.retCode);
26013+}
26014+
26015+void printTestResults(int idx, MV_STATUS status, int checkMode)
26016+{
26017+ int testIdx;
26018+ MV_CESA_TEST_SESSION* pTestSessions = getTestSessionDb(idx, &testIdx);
26019+
26020+ if(pTestSessions == NULL)
26021+ return;
26022+
26023+ mvOsPrintf("%-35s %4dx%-4d : ", pTestSessions[testIdx].name,
26024+ cesaIteration, cesaReqSize);
26025+ if( (status == MV_OK) &&
26026+ (cesaCryptoError == 0) &&
26027+ (cesaError == 0) &&
26028+ (cesaReqIdError == 0) )
26029+ {
26030+ mvOsPrintf("Passed, Rate=%3u.%u Mbps (%5u cpp)\n",
26031+ cesaRate, cesaRateAfterDot, cesaEndTicks - cesaBeginTicks);
26032+ }
26033+ else
26034+ {
26035+ mvOsPrintf("Failed, Status = 0x%x\n", status);
26036+ if(cesaCryptoError > 0)
26037+ mvOsPrintf("cryptoError : %d\n", cesaCryptoError);
26038+ if(cesaReqIdError > 0)
26039+ mvOsPrintf("reqIdError : %d\n", cesaReqIdError);
26040+ if(cesaError > 0)
26041+ mvOsPrintf("cesaError : %d\n", cesaError);
26042+ }
26043+ if(cesaTestIsrMissCount > 0)
26044+ mvOsPrintf("cesaIsrMissed : %d\n", cesaTestIsrMissCount);
26045+}
26046+
26047+void cesaCheckReady(MV_CESA_RESULT* r)
26048+{
26049+ int reqId;
26050+ MV_CESA_MBUF *pMbuf;
26051+ MV_BOOL isFailed;
26052+
26053+ cesaResult = *r;
26054+ reqId = (int)cesaResult.pReqPrv;
26055+ pMbuf = cesaCmdRing[reqId].pDst;
26056+
26057+/*
26058+ mvOsPrintf("cesaCheckReady: reqId=%d, checkOffset=%d, checkSize=%d\n",
26059+ reqId, cesaCheckOffset, cesaCheckSize);
26060+*/
26061+ /* Check expected reqId */
26062+ if(reqId != cesaExpReqId)
26063+ {
26064+ cesaReqIdError++;
26065+/*
26066+ mvOsPrintf("CESA reqId Error: cbIter=%d (%d), reqId=%d, expReqId=%d\n",
26067+ cesaCbIter, cesaIteration, reqId, cesaExpReqId);
26068+*/
26069+ }
26070+ else
26071+ {
26072+ if( (cesaCheckMode == CESA_FULL_CHECK_MODE) ||
26073+ (cesaCheckMode == CESA_FAST_CHECK_MODE) )
26074+ {
26075+ if(cesaResult.retCode != MV_OK)
26076+ {
26077+ cesaError++;
26078+
26079+ mvOsPrintf("CESA Error: cbIter=%d (%d), reqId=%d, rc=%d\n",
26080+ cesaCbIter, cesaIteration, reqId, cesaResult.retCode);
26081+ }
26082+ else
26083+ {
26084+ if( (cesaCheckSize > 0) && (cesaOutputHexStr != NULL) )
26085+ {
26086+ /* Check expected output */
26087+
26088+ isFailed = cesaCheckMbuf(pMbuf, cesaOutputHexStr, cesaCheckOffset, cesaCheckSize);
26089+ if(isFailed)
26090+ {
26091+ mvOsPrintf("CESA Crypto Error: cbIter=%d (%d), reqId=%d\n",
26092+ cesaCbIter, cesaIteration, reqId);
26093+
26094+ CESA_TEST_DEBUG_PRINT(("Error: reqId=%d, reqSize=%d, checkOffset=%d, checkSize=%d\n",
26095+ reqId, cesaReqSize, cesaCheckOffset, cesaCheckSize));
26096+
26097+ CESA_TEST_DEBUG_PRINT(("Output str: %s\n", cesaOutputHexStr));
26098+
26099+ CESA_TEST_DEBUG_CODE( mvCesaDebugMbuf("error", pMbuf, 0, cesaCheckOffset+cesaCheckSize) );
26100+
26101+ cesaCryptoError++;
26102+ }
26103+ }
26104+ }
26105+ }
26106+ }
26107+ if(cesaCheckMode == CESA_SHOW_CHECK_MODE)
26108+ {
26109+ extractMbuf(pMbuf, cesaCheckOffset, cesaCheckSize, cesaHexBuffer);
26110+ mvOsPrintf("%4d, %s\n", cesaCheckOffset, cesaHexBuffer);
26111+ }
26112+
26113+ cesaCbIter++;
26114+ if(cesaCbIter >= cesaIteration)
26115+ {
26116+ cesaCbIter = 0;
26117+ cesaExpReqId = 0;
26118+ cesaIsReady = MV_TRUE;
26119+
26120+ cesaEndTicks = CESA_TEST_TICK_GET();
26121+ cesaRate = getRate(&cesaRateAfterDot);
26122+ }
26123+ else
26124+ {
26125+ cesaExpReqId = reqId + 1;
26126+ if(cesaExpReqId == CESA_DEF_REQ_SIZE)
26127+ cesaExpReqId = 0;
26128+ }
26129+}
26130+
26131+
26132+#ifdef MV_NETBSD
26133+static int cesaTestReadyIsr(void *arg)
26134+#else
26135+#ifdef __KERNEL__
26136+static irqreturn_t cesaTestReadyIsr( int irq , void *dev_id)
26137+#endif
26138+#ifdef MV_VXWORKS
26139+void cesaTestReadyIsr(void)
26140+#endif
26141+#endif
26142+{
26143+ MV_U32 cause;
26144+ MV_STATUS status;
26145+ MV_CESA_RESULT result;
26146+
26147+ cesaTestIsrCount++;
26148+ /* Clear cause register */
26149+ cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
26150+ if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)
26151+ {
26152+ mvOsPrintf("cesaTestReadyIsr: cause=0x%x\n", cause);
26153+#ifdef MV_NETBSD
26154+ return 0;
26155+#else
26156+#ifdef __KERNEL__
26157+ return 1;
26158+#else
26159+ return;
26160+#endif
26161+#endif
26162+ }
26163+
26164+ MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
26165+
26166+ while(MV_TRUE)
26167+ {
26168+ /* Get Ready requests */
26169+ status = mvCesaReadyGet(&result);
26170+ if(status == MV_OK)
26171+ cesaCheckReady(&result);
26172+
26173+ break;
26174+ }
26175+ if( (cesaTestFull == 1) && (status != MV_BUSY) )
26176+ {
26177+ cesaTestFull = 0;
26178+ CESA_TEST_WAKE_UP();
26179+ }
26180+
26181+#ifdef __KERNEL__
26182+ return 1;
26183+#endif
26184+}
26185+
26186+void
26187+cesaTestCheckReady(const MV_CESA_RESULT *r)
26188+{
26189+ MV_CESA_RESULT result = *r;
26190+
26191+ cesaCheckReady(&result);
26192+
26193+ if (cesaTestFull == 1) {
26194+ cesaTestFull = 0;
26195+ CESA_TEST_WAKE_UP();
26196+ }
26197+}
26198+
26199+static INLINE int open_session(MV_CESA_OPEN_SESSION* pOs)
26200+{
26201+ MV_U16 sid;
26202+ MV_STATUS status;
26203+
26204+ status = mvCesaSessionOpen(pOs, (short*)&sid);
26205+ if(status != MV_OK)
26206+ {
26207+ mvOsPrintf("CesaTest: Can't open new session - status = 0x%x\n",
26208+ status);
26209+ return -1;
26210+ }
26211+
26212+ return (int)sid;
26213+}
26214+
26215+void close_session(int sid)
26216+{
26217+ MV_STATUS status;
26218+
26219+ status = mvCesaSessionClose(sid);
26220+ if(status != MV_OK)
26221+ {
26222+ mvOsPrintf("CesaTest: Can't close session %d - status = 0x%x\n",
26223+ sid, status);
26224+ }
26225+}
26226+
26227+MV_STATUS testOpen(int idx)
26228+{
26229+ MV_CESA_OPEN_SESSION os;
26230+ int sid, i, testIdx;
26231+ MV_CESA_TEST_SESSION* pTestSession;
26232+ MV_U16 digestSize = 0;
26233+
26234+ pTestSession = getTestSessionDb(idx, &testIdx);
26235+ if(pTestSession == NULL)
26236+ {
26237+ mvOsPrintf("Test %d is not exist\n", idx);
26238+ return MV_BAD_PARAM;
26239+ }
26240+ pTestSession = &pTestSession[testIdx];
26241+
26242+ if(pTestSession->sid != -1)
26243+ {
26244+ mvOsPrintf("Session for test %d already created: sid=%d\n",
26245+ idx, pTestSession->sid);
26246+ return MV_OK;
26247+ }
26248+
26249+ os.cryptoAlgorithm = pTestSession->cryptoAlgorithm;
26250+ os.macMode = pTestSession->macAlgorithm;
26251+ switch(os.macMode)
26252+ {
26253+ case MV_CESA_MAC_MD5:
26254+ case MV_CESA_MAC_HMAC_MD5:
26255+ digestSize = MV_CESA_MD5_DIGEST_SIZE;
26256+ break;
26257+
26258+ case MV_CESA_MAC_SHA1:
26259+ case MV_CESA_MAC_HMAC_SHA1:
26260+ digestSize = MV_CESA_SHA1_DIGEST_SIZE;
26261+ break;
26262+
26263+ case MV_CESA_MAC_NULL:
26264+ digestSize = 0;
26265+ }
26266+ os.cryptoMode = pTestSession->cryptoMode;
26267+ os.direction = pTestSession->direction;
26268+ os.operation = pTestSession->operation;
26269+
26270+ for(i=0; i<pTestSession->cryptoKeySize; i++)
26271+ os.cryptoKey[i] = pTestSession->pCryptoKey[i];
26272+
26273+ os.cryptoKeyLength = pTestSession->cryptoKeySize;
26274+
26275+ for(i=0; i<pTestSession->macKeySize; i++)
26276+ os.macKey[i] = pTestSession->pMacKey[i];
26277+
26278+ os.macKeyLength = pTestSession->macKeySize;
26279+ os.digestSize = digestSize;
26280+
26281+ sid = open_session(&os);
26282+ if(sid == -1)
26283+ {
26284+ mvOsPrintf("Can't open session for test %d: rc=0x%x\n",
26285+ idx, cesaResult.retCode);
26286+ return cesaResult.retCode;
26287+ }
26288+ CESA_TEST_DEBUG_PRINT(("Opened session: sid = %d\n", sid));
26289+ pTestSession->sid = sid;
26290+ return MV_OK;
26291+}
26292+
26293+MV_STATUS testClose(int idx)
26294+{
26295+ int testIdx;
26296+ MV_CESA_TEST_SESSION* pTestSession;
26297+
26298+ pTestSession = getTestSessionDb(idx, &testIdx);
26299+ if(pTestSession == NULL)
26300+ {
26301+ mvOsPrintf("Test %d is not exist\n", idx);
26302+ return MV_BAD_PARAM;
26303+ }
26304+ pTestSession = &pTestSession[testIdx];
26305+
26306+ if(pTestSession->sid == -1)
26307+ {
26308+ mvOsPrintf("Test session %d is not opened\n", idx);
26309+ return MV_NO_SUCH;
26310+ }
26311+
26312+ close_session(pTestSession->sid);
26313+ pTestSession->sid = -1;
26314+
26315+ return MV_OK;
26316+}
26317+
26318+MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,
26319+ MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize)
26320+{
26321+ int cmdReqId = 0;
26322+ int i;
26323+ MV_STATUS rc = MV_OK;
26324+ char ivZeroHex[] = "0000";
26325+
26326+ if(iter == 0)
26327+ iter = CESA_DEF_ITER_NUM;
26328+
26329+ if(pCmd == NULL)
26330+ {
26331+ mvOsPrintf("testCmd failed: pCmd=NULL\n");
26332+ return MV_BAD_PARAM;
26333+ }
26334+ pCmd->sessionId = sid;
26335+
26336+ cesaCryptoError = 0;
26337+ cesaReqIdError = 0;
26338+ cesaError = 0;
26339+ cesaTestIsrMissCount = 0;
26340+ cesaIsReady = MV_FALSE;
26341+ cesaIteration = iter;
26342+
26343+ if(cesaInputHexStr == NULL)
26344+ cesaInputHexStr = cesaPlainHexEbc;
26345+
26346+ for(i=0; i<CESA_DEF_REQ_SIZE; i++)
26347+ {
26348+ pCmd->pSrc = (MV_CESA_MBUF*)(cesaCmdRing[i].pSrc);
26349+ if(pIV != NULL)
26350+ {
26351+ /* If IV from SA - set IV in Source buffer to zeros */
26352+ cesaSetMbuf(pCmd->pSrc, ivZeroHex, 0, pCmd->cryptoOffset);
26353+ cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, pCmd->cryptoOffset,
26354+ (cesaReqSize - pCmd->cryptoOffset));
26355+ }
26356+ else
26357+ {
26358+ cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, 0, cesaReqSize);
26359+ }
26360+ pCmd->pDst = (MV_CESA_MBUF*)(cesaCmdRing[i].pDst);
26361+ cesaSetMbuf(pCmd->pDst, cesaNullPlainHexText, 0, cesaReqSize);
26362+
26363+ memcpy(&cesaCmdRing[i], pCmd, sizeof(*pCmd));
26364+ }
26365+
26366+ if(cesaCheckMode == CESA_SW_SHOW_CHECK_MODE)
26367+ {
26368+ MV_U8 pDigest[MV_CESA_MAX_DIGEST_SIZE];
26369+
26370+ if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)
26371+ {
26372+ mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);
26373+ mvOsPrintf("SW HASH_MD5: reqSize=%d, macLength=%d\n",
26374+ cesaReqSize, pCmd->macLength);
26375+ mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);
26376+ return MV_OK;
26377+ }
26378+ if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)
26379+ {
26380+ mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);
26381+ mvOsPrintf("SW HASH_SHA1: reqSize=%d, macLength=%d\n",
26382+ cesaReqSize, pCmd->macLength);
26383+ mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);
26384+ return MV_OK;
26385+ }
26386+ }
26387+
26388+ cesaBeginTicks = CESA_TEST_TICK_GET();
26389+ CESA_TEST_DEBUG_CODE( memset(cesaTestTrace, 0, sizeof(cesaTestTrace));
26390+ cesaTestTraceIdx = 0;
26391+ );
26392+
26393+ if(cesaCheckMode == CESA_SW_NULL_CHECK_MODE)
26394+ {
26395+ volatile MV_U8 pDigest[MV_CESA_MAX_DIGEST_SIZE];
26396+
26397+ for(i=0; i<iter; i++)
26398+ {
26399+ if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)
26400+ {
26401+ mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (unsigned char*)pDigest);
26402+ }
26403+ if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)
26404+ {
26405+ mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (MV_U8 *)pDigest);
26406+ }
26407+ }
26408+ cesaEndTicks = CESA_TEST_TICK_GET();
26409+ cesaRate = getRate(&cesaRateAfterDot);
26410+ cesaIsReady = MV_TRUE;
26411+
26412+ return MV_OK;
26413+ }
26414+
26415+ /*cesaTestIsrCount = 0;*/
26416+ /*mvCesaDebugStatsClear();*/
26417+
26418+#ifndef MV_NETBSD
26419+ MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
26420+#endif
26421+
26422+ for(i=0; i<iter; i++)
26423+ {
26424+ unsigned long flags;
26425+
26426+ pCmd = &cesaCmdRing[cmdReqId];
26427+ pCmd->pReqPrv = (void*)cmdReqId;
26428+
26429+ CESA_TEST_LOCK(flags);
26430+
26431+ rc = mvCesaAction(pCmd);
26432+ if(rc == MV_NO_RESOURCE)
26433+ cesaTestFull = 1;
26434+
26435+ CESA_TEST_UNLOCK(flags);
26436+
26437+ if(rc == MV_NO_RESOURCE)
26438+ {
26439+ CESA_TEST_LOCK(flags);
26440+ CESA_TEST_WAIT( (cesaTestFull == 0), 100);
26441+ CESA_TEST_UNLOCK(flags);
26442+ if(cesaTestFull == 1)
26443+ {
26444+ mvOsPrintf("CESA Test timeout: i=%d, iter=%d, cesaTestFull=%d\n",
26445+ i, iter, cesaTestFull);
26446+ cesaTestFull = 0;
26447+ return MV_TIMEOUT;
26448+ }
26449+
26450+ CESA_TEST_LOCK(flags);
26451+
26452+ rc = mvCesaAction(pCmd);
26453+
26454+ CESA_TEST_UNLOCK(flags);
26455+ }
26456+ if( (rc != MV_OK) && (rc != MV_NO_MORE) )
26457+ {
26458+ mvOsPrintf("mvCesaAction failed: rc=%d\n", rc);
26459+ return rc;
26460+ }
26461+
26462+ cmdReqId++;
26463+ if(cmdReqId >= CESA_DEF_REQ_SIZE)
26464+ cmdReqId = 0;
26465+
26466+#ifdef MV_LINUX
26467+ /* Reschedule each 16 requests */
26468+ if( (i & 0xF) == 0)
26469+ schedule();
26470+#endif
26471+ }
26472+ return MV_OK;
26473+}
26474+
26475+void cesaTestStart(int bufNum, int bufSize)
26476+{
26477+ int i, j, idx;
26478+ MV_CESA_MBUF *pMbufSrc, *pMbufDst;
26479+ MV_BUF_INFO *pFragsSrc, *pFragsDst;
26480+ char *pBuf;
26481+#ifndef MV_NETBSD
26482+ int numOfSessions, queueDepth;
26483+ char *pSram;
26484+ MV_STATUS status;
26485+ MV_CPU_DEC_WIN addrDecWin;
26486+#endif
26487+
26488+ cesaCmdRing = mvOsMalloc(sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
26489+ if(cesaCmdRing == NULL)
26490+ {
26491+ mvOsPrintf("testStart: Can't allocate %ld bytes of memory\n",
26492+ sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
26493+ return;
26494+ }
26495+ memset(cesaCmdRing, 0, sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
26496+
26497+ if(bufNum == 0)
26498+ bufNum = CESA_DEF_BUF_NUM;
26499+
26500+ if(bufSize == 0)
26501+ bufSize = CESA_DEF_BUF_SIZE;
26502+
26503+ cesaBufNum = bufNum;
26504+ cesaBufSize = bufSize;
26505+ mvOsPrintf("CESA test started: bufNum = %d, bufSize = %d\n",
26506+ bufNum, bufSize);
26507+
26508+ cesaHexBuffer = mvOsMalloc(2*bufNum*bufSize);
26509+ if(cesaHexBuffer == NULL)
26510+ {
26511+ mvOsPrintf("testStart: Can't malloc %d bytes for cesaHexBuffer.\n",
26512+ 2*bufNum*bufSize);
26513+ return;
26514+ }
26515+ memset(cesaHexBuffer, 0, (2*bufNum*bufSize));
26516+
26517+ cesaBinBuffer = mvOsMalloc(bufNum*bufSize);
26518+ if(cesaBinBuffer == NULL)
26519+ {
26520+ mvOsPrintf("testStart: Can't malloc %d bytes for cesaBinBuffer\n",
26521+ bufNum*bufSize);
26522+ return;
26523+ }
26524+ memset(cesaBinBuffer, 0, (bufNum*bufSize));
26525+
26526+ cesaExpBinBuffer = mvOsMalloc(bufNum*bufSize);
26527+ if(cesaExpBinBuffer == NULL)
26528+ {
26529+ mvOsPrintf("testStart: Can't malloc %d bytes for cesaExpBinBuffer\n",
26530+ bufNum*bufSize);
26531+ return;
26532+ }
26533+ memset(cesaExpBinBuffer, 0, (bufNum*bufSize));
26534+
26535+ CESA_TEST_WAIT_INIT();
26536+
26537+ pMbufSrc = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
26538+ pFragsSrc = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
26539+
26540+ pMbufDst = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
26541+ pFragsDst = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
26542+
26543+ if( (pMbufSrc == NULL) || (pFragsSrc == NULL) ||
26544+ (pMbufDst == NULL) || (pFragsDst == NULL) )
26545+ {
26546+ mvOsPrintf("testStart: Can't malloc Src and Dst pMbuf and pFrags structures.\n");
26547+ /* !!!! Dima cesaTestCleanup();*/
26548+ return;
26549+ }
26550+
26551+ memset(pMbufSrc, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
26552+ memset(pFragsSrc, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
26553+
26554+ memset(pMbufDst, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
26555+ memset(pFragsDst, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
26556+
26557+ mvOsPrintf("Cesa Test Start: pMbufSrc=%p, pFragsSrc=%p, pMbufDst=%p, pFragsDst=%p\n",
26558+ pMbufSrc, pFragsSrc, pMbufDst, pFragsDst);
26559+
26560+ idx = 0;
26561+ for(i=0; i<CESA_DEF_REQ_SIZE; i++)
26562+ {
26563+ pBuf = mvOsIoCachedMalloc(cesaTestOSHandle,bufSize * bufNum * 2,
26564+ &cesaReqBufs[i].bufPhysAddr,
26565+ &cesaReqBufs[i].memHandle);
26566+ if(pBuf == NULL)
26567+ {
26568+ mvOsPrintf("testStart: Can't malloc %d bytes for pBuf\n",
26569+ bufSize * bufNum * 2);
26570+ return;
26571+ }
26572+
26573+ memset(pBuf, 0, bufSize * bufNum * 2);
26574+ mvOsCacheFlush(cesaTestOSHandle,pBuf, bufSize * bufNum * 2);
26575+ if(pBuf == NULL)
26576+ {
26577+ mvOsPrintf("cesaTestStart: Can't allocate %d bytes for req_%d buffers\n",
26578+ bufSize * bufNum * 2, i);
26579+ return;
26580+ }
26581+
26582+ cesaReqBufs[i].bufVirtPtr = (MV_U8*)pBuf;
26583+ cesaReqBufs[i].bufSize = bufSize * bufNum * 2;
26584+
26585+ cesaCmdRing[i].pSrc = &pMbufSrc[i];
26586+ cesaCmdRing[i].pSrc->pFrags = &pFragsSrc[idx];
26587+ cesaCmdRing[i].pSrc->numFrags = bufNum;
26588+ cesaCmdRing[i].pSrc->mbufSize = 0;
26589+
26590+ cesaCmdRing[i].pDst = &pMbufDst[i];
26591+ cesaCmdRing[i].pDst->pFrags = &pFragsDst[idx];
26592+ cesaCmdRing[i].pDst->numFrags = bufNum;
26593+ cesaCmdRing[i].pDst->mbufSize = 0;
26594+
26595+ for(j=0; j<bufNum; j++)
26596+ {
26597+ cesaCmdRing[i].pSrc->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;
26598+ cesaCmdRing[i].pSrc->pFrags[j].bufSize = bufSize;
26599+ pBuf += bufSize;
26600+ cesaCmdRing[i].pDst->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;
26601+ cesaCmdRing[i].pDst->pFrags[j].bufSize = bufSize;
26602+ pBuf += bufSize;
26603+ }
26604+ idx += bufNum;
26605+ }
26606+
26607+#ifndef MV_NETBSD
26608+ if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)
26609+ pSram = (char*)addrDecWin.addrWin.baseLow;
26610+ else
26611+ {
26612+ mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");
26613+ return;
26614+ }
26615+
26616+#ifdef MV_CESA_NO_SRAM
26617+ pSram = mvOsMalloc(4*1024+8);
26618+ if(pSram == NULL)
26619+ {
26620+ mvOsPrintf("CesaTest: can't allocate %d bytes for SRAM simulation\n",
26621+ 4*1024+8);
26622+ /* !!!! Dima cesaTestCleanup();*/
26623+ return;
26624+ }
26625+ pSram = (MV_U8*)MV_ALIGN_UP((MV_U32)pSram, 8);
26626+#endif /* MV_CESA_NO_SRAM */
26627+
26628+ numOfSessions = CESA_DEF_SESSION_NUM;
26629+ queueDepth = CESA_DEF_REQ_SIZE - MV_CESA_MAX_CHAN;
26630+
26631+ status = mvCesaInit(numOfSessions, queueDepth, pSram, NULL);
26632+ if(status != MV_OK)
26633+ {
26634+ mvOsPrintf("mvCesaInit is Failed: status = 0x%x\n", status);
26635+ /* !!!! Dima cesaTestCleanup();*/
26636+ return;
26637+ }
26638+#endif /* !MV_NETBSD */
26639+
26640+ /* Prepare data for tests */
26641+ for(i=0; i<50; i++)
26642+ strcat((char*)cesaDataHexStr3, "dd");
26643+
26644+ strcpy((char*)cesaDataAndMd5digest3, cesaDataHexStr3);
26645+ strcpy((char*)cesaDataAndSha1digest3, cesaDataHexStr3);
26646+
26647+ /* Digest must be 8 byte aligned */
26648+ for(; i<56; i++)
26649+ {
26650+ strcat((char*)cesaDataAndMd5digest3, "00");
26651+ strcat((char*)cesaDataAndSha1digest3, "00");
26652+ }
26653+ strcat((char*)cesaDataAndMd5digest3, cesaHmacMd5digestHex3);
26654+ strcat((char*)cesaDataAndSha1digest3, cesaHmacSha1digestHex3);
26655+
26656+#ifndef MV_NETBSD
26657+ MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
26658+ MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);
26659+#endif
26660+
26661+#ifdef MV_VXWORKS
26662+ {
26663+ MV_STATUS status;
26664+
26665+ status = intConnect((VOIDFUNCPTR *)INT_LVL_CESA, cesaTestReadyIsr, (int)NULL);
26666+ if (status != OK)
26667+ {
26668+ mvOsPrintf("CESA: Can't connect CESA (%d) interrupt, status=0x%x \n",
26669+ INT_LVL_CESA, status);
26670+ /* !!!! Dima cesaTestCleanup();*/
26671+ return;
26672+ }
26673+ cesaSemId = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
26674+ if(cesaSemId == NULL)
26675+ {
26676+ mvOsPrintf("cesaTestStart: Can't create semaphore\n");
26677+ return;
26678+ }
26679+ intEnable(INT_LVL_CESA);
26680+ }
26681+#endif /* MV_VXWORKS */
26682+
26683+#if !defined(MV_NETBSD) && defined(__KERNEL__)
26684+ if( request_irq(CESA_IRQ, cesaTestReadyIsr, (SA_INTERRUPT) , "cesa_test", NULL ) )
26685+ {
26686+ mvOsPrintf( "cannot assign irq\n" );
26687+ /* !!!! Dima cesaTestCleanup();*/
26688+ return;
26689+ }
26690+ spin_lock_init( &cesaLock );
26691+#endif
26692+}
26693+
26694+MV_STATUS testRun(int idx, int caseIdx, int iter,
26695+ int reqSize, int checkMode)
26696+{
26697+ int testIdx, count, sid, digestSize;
26698+ int blockSize;
26699+ MV_CESA_TEST_SESSION* pTestSession;
26700+ MV_CESA_COMMAND cmd;
26701+ MV_STATUS status;
26702+
26703+ memset(&cmd, 0, sizeof(cmd));
26704+
26705+ pTestSession = getTestSessionDb(idx, &testIdx);
26706+ if(pTestSession == NULL)
26707+ {
26708+ mvOsPrintf("Test %d is not exist\n", idx);
26709+ return MV_BAD_PARAM;
26710+ }
26711+ pTestSession = &pTestSession[testIdx];
26712+
26713+ sid = pTestSession->sid;
26714+ if(sid == -1)
26715+ {
26716+ mvOsPrintf("Test %d is not opened\n", idx);
26717+ return MV_BAD_STATE;
26718+ }
26719+ switch(pTestSession->cryptoAlgorithm)
26720+ {
26721+ case MV_CESA_CRYPTO_DES:
26722+ case MV_CESA_CRYPTO_3DES:
26723+ blockSize = MV_CESA_DES_BLOCK_SIZE;
26724+ break;
26725+
26726+ case MV_CESA_CRYPTO_AES:
26727+ blockSize = MV_CESA_AES_BLOCK_SIZE;
26728+ break;
26729+
26730+ case MV_CESA_CRYPTO_NULL:
26731+ blockSize = 0;
26732+ break;
26733+
26734+ default:
26735+ mvOsPrintf("cesaTestRun: Bad CryptoAlgorithm=%d\n",
26736+ pTestSession->cryptoAlgorithm);
26737+ return MV_BAD_PARAM;
26738+ }
26739+ switch(pTestSession->macAlgorithm)
26740+ {
26741+ case MV_CESA_MAC_MD5:
26742+ case MV_CESA_MAC_HMAC_MD5:
26743+ digestSize = MV_CESA_MD5_DIGEST_SIZE;
26744+ break;
26745+
26746+ case MV_CESA_MAC_SHA1:
26747+ case MV_CESA_MAC_HMAC_SHA1:
26748+ digestSize = MV_CESA_SHA1_DIGEST_SIZE;
26749+ break;
26750+ default:
26751+ digestSize = 0;
26752+ }
26753+
26754+ if(iter == 0)
26755+ iter = CESA_DEF_ITER_NUM;
26756+
26757+ if(pTestSession->direction == MV_CESA_DIR_ENCODE)
26758+ {
26759+ cesaOutputHexStr = cesaTestCases[caseIdx].cipherHexStr;
26760+ cesaInputHexStr = cesaTestCases[caseIdx].plainHexStr;
26761+ }
26762+ else
26763+ {
26764+ cesaOutputHexStr = cesaTestCases[caseIdx].plainHexStr;
26765+ cesaInputHexStr = cesaTestCases[caseIdx].cipherHexStr;
26766+ }
26767+
26768+ cmd.sessionId = sid;
26769+ if(checkMode == CESA_FAST_CHECK_MODE)
26770+ {
26771+ cmd.cryptoLength = cesaTestCases[caseIdx].cryptoLength;
26772+ cmd.macLength = cesaTestCases[caseIdx].macLength;
26773+ }
26774+ else
26775+ {
26776+ cmd.cryptoLength = reqSize;
26777+ cmd.macLength = reqSize;
26778+ }
26779+ cesaRateSize = cmd.cryptoLength;
26780+ cesaReqSize = cmd.cryptoLength;
26781+ cmd.cryptoOffset = 0;
26782+ if(pTestSession->operation != MV_CESA_MAC_ONLY)
26783+ {
26784+ if( (pTestSession->cryptoMode == MV_CESA_CRYPTO_CBC) ||
26785+ (pTestSession->cryptoMode == MV_CESA_CRYPTO_CTR) )
26786+ {
26787+ cmd.ivOffset = 0;
26788+ cmd.cryptoOffset = blockSize;
26789+ if(cesaTestCases[caseIdx].pCryptoIV == NULL)
26790+ {
26791+ cmd.ivFromUser = 1;
26792+ }
26793+ else
26794+ {
26795+ cmd.ivFromUser = 0;
26796+ mvCesaCryptoIvSet(cesaTestCases[caseIdx].pCryptoIV, blockSize);
26797+ }
26798+ cesaReqSize = cmd.cryptoOffset + cmd.cryptoLength;
26799+ }
26800+ }
26801+
26802+/*
26803+ mvOsPrintf("ivFromUser=%d, cryptoLength=%d, cesaReqSize=%d, cryptoOffset=%d\n",
26804+ cmd.ivFromUser, cmd.cryptoLength, cesaReqSize, cmd.cryptoOffset);
26805+*/
26806+ if(pTestSession->operation != MV_CESA_CRYPTO_ONLY)
26807+ {
26808+ cmd.macOffset = cmd.cryptoOffset;
26809+
26810+ if(cesaTestCases[caseIdx].digestOffset == -1)
26811+ {
26812+ cmd.digestOffset = cmd.macOffset + cmd.macLength;
26813+ cmd.digestOffset = MV_ALIGN_UP(cmd.digestOffset, 8);
26814+ }
26815+ else
26816+ {
26817+ cmd.digestOffset = cesaTestCases[caseIdx].digestOffset;
26818+ }
26819+ if( (cmd.digestOffset + digestSize) > cesaReqSize)
26820+ cesaReqSize = cmd.digestOffset + digestSize;
26821+ }
26822+
26823+ cesaCheckMode = checkMode;
26824+
26825+ if(checkMode == CESA_NULL_CHECK_MODE)
26826+ {
26827+ cesaCheckSize = 0;
26828+ cesaCheckOffset = 0;
26829+ }
26830+ else
26831+ {
26832+ if(pTestSession->operation == MV_CESA_CRYPTO_ONLY)
26833+ {
26834+ cesaCheckOffset = 0;
26835+ cesaCheckSize = cmd.cryptoLength;
26836+ }
26837+ else
26838+ {
26839+ cesaCheckSize = digestSize;
26840+ cesaCheckOffset = cmd.digestOffset;
26841+ }
26842+ }
26843+/*
26844+ mvOsPrintf("reqSize=%d, checkSize=%d, checkOffset=%d, checkMode=%d\n",
26845+ cesaReqSize, cesaCheckSize, cesaCheckOffset, cesaCheckMode);
26846+
26847+ mvOsPrintf("blockSize=%d, ivOffset=%d, ivFromUser=%d, crOffset=%d, crLength=%d\n",
26848+ blockSize, cmd.ivOffset, cmd.ivFromUser,
26849+ cmd.cryptoOffset, cmd.cryptoLength);
26850+
26851+ mvOsPrintf("macOffset=%d, digestOffset=%d, macLength=%d\n",
26852+ cmd.macOffset, cmd.digestOffset, cmd.macLength);
26853+*/
26854+ status = testCmd(sid, iter, &cmd, pTestSession,
26855+ cesaTestCases[caseIdx].pCryptoIV, blockSize);
26856+
26857+ if(status != MV_OK)
26858+ return status;
26859+
26860+ /* Wait when all callbacks is received */
26861+ count = 0;
26862+ while(cesaIsReady == MV_FALSE)
26863+ {
26864+ mvOsSleep(10);
26865+ count++;
26866+ if(count > 100)
26867+ {
26868+ mvOsPrintf("testRun: Timeout occured\n");
26869+ return MV_TIMEOUT;
26870+ }
26871+ }
26872+
26873+ return MV_OK;
26874+}
26875+
26876+
26877+void cesaTestStop(void)
26878+{
26879+ MV_CESA_MBUF *pMbufSrc, *pMbufDst;
26880+ MV_BUF_INFO *pFragsSrc, *pFragsDst;
26881+ int i;
26882+
26883+ /* Release all allocated memories */
26884+ pMbufSrc = (MV_CESA_MBUF*)(cesaCmdRing[0].pSrc);
26885+ pFragsSrc = cesaCmdRing[0].pSrc->pFrags;
26886+
26887+ pMbufDst = (MV_CESA_MBUF*)(cesaCmdRing[0].pDst);
26888+ pFragsDst = cesaCmdRing[0].pDst->pFrags;
26889+
26890+ mvOsFree(pMbufSrc);
26891+ mvOsFree(pMbufDst);
26892+ mvOsFree(pFragsSrc);
26893+ mvOsFree(pFragsDst);
26894+
26895+ for(i=0; i<CESA_DEF_REQ_SIZE; i++)
26896+ {
26897+ mvOsIoCachedFree(cesaTestOSHandle,cesaReqBufs[i].bufSize,
26898+ cesaReqBufs[i].bufPhysAddr,cesaReqBufs[i].bufVirtPtr,
26899+ cesaReqBufs[i].memHandle);
26900+ }
26901+ cesaDataHexStr3[0] = '\0';
26902+}
26903+
26904+void desTest(int iter, int reqSize, int checkMode)
26905+{
26906+ int mode, i;
26907+ MV_STATUS status;
26908+
26909+ mode = checkMode;
26910+ if(checkMode == CESA_FULL_CHECK_MODE)
26911+ mode = CESA_FAST_CHECK_MODE;
26912+ i = iter;
26913+ if(mode != CESA_NULL_CHECK_MODE)
26914+ i = 1;
26915+
26916+ testOpen(0);
26917+ testOpen(1);
26918+ testOpen(2);
26919+ testOpen(3);
26920+
26921+/* DES / ECB mode / Encrypt only */
26922+ status = testRun(0, 1, iter, reqSize, checkMode);
26923+ printTestResults(0, status, checkMode);
26924+
26925+/* DES / ECB mode / Decrypt only */
26926+ status = testRun(1, 1, iter, reqSize, checkMode);
26927+ printTestResults(1, status, checkMode);
26928+
26929+/* DES / CBC mode / Encrypt only */
26930+ status = testRun(2, 2, i, reqSize, mode);
26931+ printTestResults(2, status, mode);
26932+
26933+/* DES / CBC mode / Decrypt only */
26934+ status = testRun(3, 2, iter, reqSize, mode);
26935+ printTestResults(3, status, mode);
26936+
26937+ testClose(0);
26938+ testClose(1);
26939+ testClose(2);
26940+ testClose(3);
26941+}
26942+
26943+void tripleDesTest(int iter, int reqSize, int checkMode)
26944+{
26945+ int mode, i;
26946+ MV_STATUS status;
26947+
26948+ mode = checkMode;
26949+ if(checkMode == CESA_FULL_CHECK_MODE)
26950+ mode = CESA_FAST_CHECK_MODE;
26951+ i = iter;
26952+ if(mode != CESA_NULL_CHECK_MODE)
26953+ i = 1;
26954+
26955+ testOpen(100);
26956+ testOpen(101);
26957+ testOpen(102);
26958+ testOpen(103);
26959+
26960+/* 3DES / ECB mode / Encrypt only */
26961+ status = testRun(100, 1, iter, reqSize, checkMode);
26962+ printTestResults(100, status, checkMode);
26963+
26964+/* 3DES / ECB mode / Decrypt only */
26965+ status = testRun(101, 1, iter, reqSize, checkMode);
26966+ printTestResults(101, status, checkMode);
26967+
26968+/* 3DES / CBC mode / Encrypt only */
26969+ status = testRun(102, 2, i, reqSize, mode);
26970+ printTestResults(102, status, mode);
26971+
26972+/* 3DES / CBC mode / Decrypt only */
26973+ status = testRun(103, 2, iter, reqSize, mode);
26974+ printTestResults(103, status, mode);
26975+
26976+ testClose(100);
26977+ testClose(101);
26978+ testClose(102);
26979+ testClose(103);
26980+}
26981+
26982+void aesTest(int iter, int reqSize, int checkMode)
26983+{
26984+ MV_STATUS status;
26985+ int mode, i;
26986+
26987+ mode = checkMode;
26988+ if(checkMode == CESA_FULL_CHECK_MODE)
26989+ mode = CESA_FAST_CHECK_MODE;
26990+
26991+ i = iter;
26992+ if(mode != CESA_NULL_CHECK_MODE)
26993+ i = 1;
26994+
26995+ testOpen(200);
26996+ testOpen(201);
26997+ testOpen(202);
26998+ testOpen(203);
26999+ testOpen(204);
27000+ testOpen(205);
27001+ testOpen(206);
27002+ testOpen(207);
27003+ testOpen(208);
27004+
27005+/* AES-128 Encode ECB mode */
27006+ status = testRun(200, 3, iter, reqSize, checkMode);
27007+ printTestResults(200, status, checkMode);
27008+
27009+/* AES-128 Decode ECB mode */
27010+ status = testRun(201, 3, iter, reqSize, checkMode);
27011+ printTestResults(201, status, checkMode);
27012+
27013+/* AES-128 Encode CBC mode (IV from SA) */
27014+ status = testRun(202, 10, i, reqSize, mode);
27015+ printTestResults(202, status, mode);
27016+
27017+/* AES-128 Encode CBC mode (IV from User) */
27018+ status = testRun(202, 24, i, reqSize, mode);
27019+ printTestResults(202, status, mode);
27020+
27021+/* AES-128 Decode CBC mode */
27022+ status = testRun(203, 24, iter, reqSize, mode);
27023+ printTestResults(203, status, checkMode);
27024+
27025+/* AES-192 Encode ECB mode */
27026+ status = testRun(204, 4, iter, reqSize, checkMode);
27027+ printTestResults(204, status, checkMode);
27028+
27029+/* AES-192 Decode ECB mode */
27030+ status = testRun(205, 4, iter, reqSize, checkMode);
27031+ printTestResults(205, status, checkMode);
27032+
27033+/* AES-256 Encode ECB mode */
27034+ status = testRun(206, 5, iter, reqSize, checkMode);
27035+ printTestResults(206, status, checkMode);
27036+
27037+/* AES-256 Decode ECB mode */
27038+ status = testRun(207, 5, iter, reqSize, checkMode);
27039+ printTestResults(207, status, checkMode);
27040+
27041+#if defined(MV_LINUX)
27042+/* AES-128 Encode CTR mode */
27043+ status = testRun(208, 23, iter, reqSize, mode);
27044+ printTestResults(208, status, checkMode);
27045+#endif
27046+ testClose(200);
27047+ testClose(201);
27048+ testClose(202);
27049+ testClose(203);
27050+ testClose(204);
27051+ testClose(205);
27052+ testClose(206);
27053+ testClose(207);
27054+ testClose(208);
27055+}
27056+
27057+
27058+void mdTest(int iter, int reqSize, int checkMode)
27059+{
27060+ int mode;
27061+ MV_STATUS status;
27062+
27063+ if(iter == 0)
27064+ iter = CESA_DEF_ITER_NUM;
27065+
27066+ mode = checkMode;
27067+ if(checkMode == CESA_FULL_CHECK_MODE)
27068+ mode = CESA_FAST_CHECK_MODE;
27069+
27070+ testOpen(300);
27071+ testOpen(301);
27072+ testOpen(302);
27073+ testOpen(303);
27074+ testOpen(305);
27075+
27076+/* HMAC-MD5 Generate signature test */
27077+ status = testRun(300, 6, iter, reqSize, mode);
27078+ printTestResults(300, status, checkMode);
27079+
27080+/* HMAC-MD5 Verify Signature test */
27081+ status = testRun(301, 7, iter, reqSize, mode);
27082+ printTestResults(301, status, checkMode);
27083+
27084+/* HMAC-MD5 Generate signature test */
27085+ status = testRun(302, 8, iter, reqSize, mode);
27086+ printTestResults(302, status, checkMode);
27087+
27088+/* HMAC-MD5 Verify Signature test */
27089+ status = testRun(303, 9, iter, reqSize, mode);
27090+ printTestResults(303, status, checkMode);
27091+
27092+/* HASH-MD5 Generate signature test */
27093+ status = testRun(305, 15, iter, reqSize, mode);
27094+ printTestResults(305, status, checkMode);
27095+
27096+ testClose(300);
27097+ testClose(301);
27098+ testClose(302);
27099+ testClose(303);
27100+ testClose(305);
27101+}
27102+
27103+void shaTest(int iter, int reqSize, int checkMode)
27104+{
27105+ int mode;
27106+ MV_STATUS status;
27107+
27108+ if(iter == 0)
27109+ iter = CESA_DEF_ITER_NUM;
27110+
27111+ mode = checkMode;
27112+ if(checkMode == CESA_FULL_CHECK_MODE)
27113+ mode = CESA_FAST_CHECK_MODE;
27114+
27115+ testOpen(400);
27116+ testOpen(401);
27117+ testOpen(402);
27118+ testOpen(403);
27119+ testOpen(405);
27120+
27121+/* HMAC-SHA1 Generate signature test */
27122+ status = testRun(400, 11, iter, reqSize, mode);
27123+ printTestResults(400, status, checkMode);
27124+
27125+/* HMAC-SHA1 Verify Signature test */
27126+ status = testRun(401, 12, iter, reqSize, mode);
27127+ printTestResults(401, status, checkMode);
27128+
27129+/* HMAC-SHA1 Generate signature test */
27130+ status = testRun(402, 13, iter, reqSize, mode);
27131+ printTestResults(402, status, checkMode);
27132+
27133+/* HMAC-SHA1 Verify Signature test */
27134+ status = testRun(403, 14, iter, reqSize, mode);
27135+ printTestResults(403, status, checkMode);
27136+
27137+/* HMAC-SHA1 Generate signature test */
27138+ status = testRun(405, 16, iter, reqSize, mode);
27139+ printTestResults(405, status, checkMode);
27140+
27141+ testClose(400);
27142+ testClose(401);
27143+ testClose(402);
27144+ testClose(403);
27145+ testClose(405);
27146+}
27147+
27148+void combiTest(int iter, int reqSize, int checkMode)
27149+{
27150+ MV_STATUS status;
27151+ int mode, i;
27152+
27153+ mode = checkMode;
27154+ if(checkMode == CESA_FULL_CHECK_MODE)
27155+ mode = CESA_FAST_CHECK_MODE;
27156+
27157+ if(iter == 0)
27158+ iter = CESA_DEF_ITER_NUM;
27159+
27160+ i = iter;
27161+ if(mode != CESA_NULL_CHECK_MODE)
27162+ i = 1;
27163+
27164+ testOpen(500);
27165+ testOpen(501);
27166+ testOpen(502);
27167+ testOpen(503);
27168+ testOpen(504);
27169+ testOpen(505);
27170+ testOpen(506);
27171+ testOpen(507);
27172+
27173+/* DES ECB + MD5 encode test */
27174+ status = testRun(500, 17, iter, reqSize, mode);
27175+ printTestResults(500, status, mode);
27176+
27177+/* DES ECB + SHA1 encode test */
27178+ status = testRun(501, 18, iter, reqSize, mode);
27179+ printTestResults(501, status, mode);
27180+
27181+/* 3DES ECB + MD5 encode test */
27182+ status = testRun(502, 17, iter, reqSize, mode);
27183+ printTestResults(502, status, mode);
27184+
27185+/* 3DES ECB + SHA1 encode test */
27186+ status = testRun(503, 18, iter, reqSize, mode);
27187+ printTestResults(503, status, mode);
27188+
27189+/* 3DES CBC + MD5 encode test */
27190+ status = testRun(504, 19, i, reqSize, mode);
27191+ printTestResults(504, status, mode);
27192+
27193+/* 3DES CBC + SHA1 encode test */
27194+ status = testRun(505, 20, i, reqSize, mode);
27195+ printTestResults(505, status, mode);
27196+
27197+/* AES-128 CBC + MD5 encode test */
27198+ status = testRun(506, 21, i, reqSize, mode);
27199+ printTestResults(506, status, mode);
27200+
27201+/* AES-128 CBC + SHA1 encode test */
27202+ status = testRun(507, 22, i, reqSize, mode);
27203+ printTestResults(507, status, mode);
27204+
27205+ testClose(500);
27206+ testClose(501);
27207+ testClose(502);
27208+ testClose(503);
27209+ testClose(504);
27210+ testClose(505);
27211+ testClose(506);
27212+ testClose(507);
27213+}
27214+
27215+void cesaOneTest(int testIdx, int caseIdx,
27216+ int iter, int reqSize, int checkMode)
27217+{
27218+ MV_STATUS status;
27219+
27220+ if(iter == 0)
27221+ iter = CESA_DEF_ITER_NUM;
27222+
27223+ mvOsPrintf("test=%d, case=%d, size=%d, iter=%d\n",
27224+ testIdx, caseIdx, reqSize, iter);
27225+
27226+ status = testOpen(testIdx);
27227+
27228+ status = testRun(testIdx, caseIdx, iter, reqSize, checkMode);
27229+ printTestResults(testIdx, status, checkMode);
27230+ status = testClose(testIdx);
27231+
27232+}
27233+
27234+void cesaTest(int iter, int reqSize, int checkMode)
27235+{
27236+ if(iter == 0)
27237+ iter = CESA_DEF_ITER_NUM;
27238+
27239+ mvOsPrintf("%d iteration\n", iter);
27240+ mvOsPrintf("%d size\n\n", reqSize);
27241+
27242+/* DES tests */
27243+ desTest(iter, reqSize, checkMode);
27244+
27245+/* 3DES tests */
27246+ tripleDesTest(iter, reqSize, checkMode);
27247+
27248+/* AES tests */
27249+ aesTest(iter, reqSize, checkMode);
27250+
27251+/* MD5 tests */
27252+ mdTest(iter, reqSize, checkMode);
27253+
27254+/* SHA-1 tests */
27255+ shaTest(iter, reqSize, checkMode);
27256+}
27257+
27258+void multiSizeTest(int idx, int iter, int checkMode, char* inputData)
27259+{
27260+ MV_STATUS status;
27261+ int i;
27262+ MV_CESA_SIZE_TEST* pMultiTest;
27263+
27264+ if( testOpen(idx) != MV_OK)
27265+ return;
27266+
27267+ if(iter == 0)
27268+ iter = CESA_DEF_ITER_NUM;
27269+
27270+ if(checkMode == CESA_SHOW_CHECK_MODE)
27271+ {
27272+ iter = 1;
27273+ }
27274+ else
27275+ checkMode = CESA_FULL_CHECK_MODE;
27276+
27277+ cesaTestCases[0].plainHexStr = inputData;
27278+ cesaTestCases[0].pCryptoIV = NULL;
27279+
27280+ switch(idx)
27281+ {
27282+ case 302:
27283+ pMultiTest = mdMultiSizeTest302;
27284+ if(inputData == NULL)
27285+ cesaTestCases[0].plainHexStr = cesaDataHexStr3;
27286+ break;
27287+
27288+ case 304:
27289+ pMultiTest = mdMultiSizeTest304;
27290+ if(inputData == NULL)
27291+ cesaTestCases[0].plainHexStr = hashHexStr80;
27292+ break;
27293+
27294+ case 305:
27295+ pMultiTest = mdMultiSizeTest305;
27296+ if(inputData == NULL)
27297+ cesaTestCases[0].plainHexStr = hashHexStr80;
27298+ break;
27299+
27300+ case 402:
27301+ pMultiTest = shaMultiSizeTest402;
27302+ if(inputData == NULL)
27303+ cesaTestCases[0].plainHexStr = hashHexStr80;
27304+ break;
27305+
27306+ case 404:
27307+ pMultiTest = shaMultiSizeTest404;
27308+ if(inputData == NULL)
27309+ cesaTestCases[0].plainHexStr = hashHexStr80;
27310+ break;
27311+
27312+ case 405:
27313+ pMultiTest = shaMultiSizeTest405;
27314+ if(inputData == NULL)
27315+ cesaTestCases[0].plainHexStr = hashHexStr80;
27316+ break;
27317+
27318+ case 502:
27319+ pMultiTest = tripleDesMdMultiSizeTest502;
27320+ if(inputData == NULL)
27321+ cesaTestCases[0].plainHexStr = hashHexStr80;
27322+ break;
27323+
27324+ case 503:
27325+ pMultiTest = tripleDesShaMultiSizeTest503;
27326+ if(inputData == NULL)
27327+ cesaTestCases[0].plainHexStr = hashHexStr80;
27328+ break;
27329+
27330+ case 504:
27331+ iter = 1;
27332+ pMultiTest = cbc3desMdMultiSizeTest504;
27333+ cesaTestCases[0].pCryptoIV = iv1;
27334+ if(inputData == NULL)
27335+ cesaTestCases[0].plainHexStr = hashHexStr80;
27336+ break;
27337+
27338+ case 505:
27339+ iter = 1;
27340+ pMultiTest = cbc3desShaMultiSizeTest505;
27341+ cesaTestCases[0].pCryptoIV = iv1;
27342+ if(inputData == NULL)
27343+ cesaTestCases[0].plainHexStr = hashHexStr80;
27344+ break;
27345+
27346+ case 506:
27347+ iter = 1;
27348+ pMultiTest = cbcAes128md5multiSizeTest506;
27349+ cesaTestCases[0].pCryptoIV = iv5;
27350+ if(inputData == NULL)
27351+ cesaTestCases[0].plainHexStr = hashHexStr80;
27352+ break;
27353+
27354+ case 507:
27355+ iter = 1;
27356+ pMultiTest = cbcAes128sha1multiSizeTest507;
27357+ cesaTestCases[0].pCryptoIV = iv5;
27358+ if(inputData == NULL)
27359+ cesaTestCases[0].plainHexStr = hashHexStr80;
27360+ break;
27361+
27362+ default:
27363+ iter = 1;
27364+ checkMode = CESA_SHOW_CHECK_MODE;
27365+ pMultiTest = mdMultiSizeTest302;
27366+ if(inputData == NULL)
27367+ cesaTestCases[0].plainHexStr = hashHexStr80;
27368+ }
27369+ i = 0;
27370+ while(pMultiTest[i].outputHexStr != NULL)
27371+ {
27372+ cesaTestCases[0].cipherHexStr = (char *)pMultiTest[i].outputHexStr;
27373+ status = testRun(idx, 0, iter, pMultiTest[i].size,
27374+ checkMode);
27375+ if(checkMode != CESA_SHOW_CHECK_MODE)
27376+ {
27377+ cesaReqSize = pMultiTest[i].size;
27378+ printTestResults(idx, status, checkMode);
27379+ }
27380+ if(status != MV_OK)
27381+ break;
27382+ i++;
27383+ }
27384+ testClose(idx);
27385+/*
27386+ mvCesaDebugStatus();
27387+ cesaTestPrintStatus();
27388+*/
27389+}
27390+
27391+void open_session_test(int idx, int caseIdx, int iter)
27392+{
27393+ int reqIdError, cryptoError, openErrors, i;
27394+ int openErrDisp[100];
27395+ MV_STATUS status;
27396+
27397+ memset(openErrDisp, 0, sizeof(openErrDisp));
27398+ openErrors = 0;
27399+ reqIdError = 0;
27400+ cryptoError = 0;
27401+ for(i=0; i<iter; i++)
27402+ {
27403+ status = testOpen(idx);
27404+ if(status != MV_OK)
27405+ {
27406+ openErrors++;
27407+ openErrDisp[status]++;
27408+ }
27409+ else
27410+ {
27411+ testRun(idx, caseIdx, 1, 0, CESA_FAST_CHECK_MODE);
27412+ if(cesaCryptoError > 0)
27413+ cryptoError++;
27414+ if(cesaReqIdError > 0)
27415+ reqIdError++;
27416+
27417+ testClose(idx);
27418+ }
27419+ }
27420+ if(cryptoError > 0)
27421+ mvOsPrintf("cryptoError : %d\n", cryptoError);
27422+ if(reqIdError > 0)
27423+ mvOsPrintf("reqIdError : %d\n", reqIdError);
27424+
27425+ if(openErrors > 0)
27426+ {
27427+ mvOsPrintf("Open Errors = %d\n", openErrors);
27428+ for(i=0; i<100; i++)
27429+ {
27430+ if(openErrDisp[i] != 0)
27431+ mvOsPrintf("Error %d - occurs %d times\n", i, openErrDisp[i]);
27432+ }
27433+ }
27434+}
27435+
27436+
27437+void loopback_test(int idx, int iter, int size, char* pPlainData)
27438+{
27439+}
27440+
27441+
27442+#if defined(MV_VXWORKS)
27443+int testMode = 0;
27444+unsigned __TASKCONV cesaTask(void* args)
27445+{
27446+ int reqSize = cesaReqSize;
27447+
27448+ if(testMode == 0)
27449+ {
27450+ cesaOneTest(cesaTestIdx, cesaCaseIdx, cesaIteration,
27451+ reqSize, cesaCheckMode);
27452+ }
27453+ else
27454+ {
27455+ if(testMode == 1)
27456+ {
27457+ cesaTest(cesaIteration, reqSize, cesaCheckMode);
27458+ combiTest(cesaIteration, reqSize, cesaCheckMode);
27459+ }
27460+ else
27461+ {
27462+ multiSizeTest(cesaIdx, cesaIteration, cesaCheckMode, NULL);
27463+ }
27464+ }
27465+ return 0;
27466+}
27467+
27468+void oneTest(int testIdx, int caseIdx,
27469+ int iter, int reqSize, int checkMode)
27470+{
27471+ long rc;
27472+
27473+ cesaIteration = iter;
27474+ cesaReqSize = cesaRateSize = reqSize;
27475+ cesaCheckMode = checkMode;
27476+ testMode = 0;
27477+ cesaTestIdx = testIdx;
27478+ cesaCaseIdx = caseIdx;
27479+ rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
27480+ if (rc != MV_OK)
27481+ {
27482+ mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);
27483+ }
27484+}
27485+
27486+void multiTest(int iter, int reqSize, int checkMode)
27487+{
27488+ long rc;
27489+
27490+ cesaIteration = iter;
27491+ cesaCheckMode = checkMode;
27492+ cesaReqSize = reqSize;
27493+ testMode = 1;
27494+ rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
27495+ if (rc != MV_OK)
27496+ {
27497+ mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);
27498+ }
27499+}
27500+
27501+void sizeTest(int testIdx, int iter, int checkMode)
27502+{
27503+ long rc;
27504+
27505+ cesaIteration = iter;
27506+ cesaCheckMode = checkMode;
27507+ testMode = 2;
27508+ cesaIdx = testIdx;
27509+ rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
27510+ if (rc != MV_OK)
27511+ {
27512+ mvOsPrintf("hMW: Can't create CESA test task, rc = %ld\n", rc);
27513+ }
27514+}
27515+
27516+#endif /* MV_VXWORKS */
27517+
27518+extern void mvCesaDebugSA(short sid, int mode);
27519+void cesaTestPrintSession(int idx)
27520+{
27521+ int testIdx;
27522+ MV_CESA_TEST_SESSION* pTestSession;
27523+
27524+ pTestSession = getTestSessionDb(idx, &testIdx);
27525+ if(pTestSession == NULL)
27526+ {
27527+ mvOsPrintf("Test %d is not exist\n", idx);
27528+ return;
27529+ }
27530+ pTestSession = &pTestSession[testIdx];
27531+
27532+ if(pTestSession->sid == -1)
27533+ {
27534+ mvOsPrintf("Test session %d is not opened\n", idx);
27535+ return;
27536+ }
27537+
27538+ mvCesaDebugSA(pTestSession->sid, 1);
27539+}
27540+
27541+void cesaTestPrintStatus(void)
27542+{
27543+ mvOsPrintf("\n\t Cesa Test Status\n\n");
27544+
27545+ mvOsPrintf("isrCount=%d\n",
27546+ cesaTestIsrCount);
27547+
27548+#ifdef CESA_TEST_DEBUG
27549+ {
27550+ int i, j;
27551+ j = cesaTestTraceIdx;
27552+ mvOsPrintf("No Type Cause rCause iCause Res Time pReady pProc pEmpty\n");
27553+ for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)
27554+ {
27555+ mvOsPrintf("%02d. %d 0x%04x 0x%04x 0x%04x 0x%02x 0x%02x %02d 0x%06x %p %p %p\n",
27556+ j, cesaTestTrace[j].type, cesaTestTrace[j].cause, cesaTestTrace[j].realCause,
27557+ cesaTestTrace[j].dmaCause, cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,
27558+ cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);
27559+ j++;
27560+ if(j == MV_CESA_TEST_TRACE_SIZE)
27561+ j = 0;
27562+ }
27563+ }
27564+#endif /* CESA_TEST_DEBUG */
27565+}
27566diff --git a/crypto/ocf/kirkwood/cesa/mvLru.c b/crypto/ocf/kirkwood/cesa/mvLru.c
27567new file mode 100644
27568index 0000000..4b5f877
27569--- /dev/null
27570+++ b/crypto/ocf/kirkwood/cesa/mvLru.c
27571@@ -0,0 +1,158 @@
27572+/*******************************************************************************
27573+Copyright (C) Marvell International Ltd. and its affiliates
27574+
27575+This software file (the "File") is owned and distributed by Marvell
27576+International Ltd. and/or its affiliates ("Marvell") under the following
27577+alternative licensing terms. Once you have made an election to distribute the
27578+File under one of the following license alternatives, please (i) delete this
27579+introductory statement regarding license alternatives, (ii) delete the two
27580+license alternatives that you have not elected to use and (iii) preserve the
27581+Marvell copyright notice above.
27582+
27583+********************************************************************************
27584+Marvell Commercial License Option
27585+
27586+If you received this File from Marvell and you have entered into a commercial
27587+license agreement (a "Commercial License") with Marvell, the File is licensed
27588+to you under the terms of the applicable Commercial License.
27589+
27590+********************************************************************************
27591+Marvell GPL License Option
27592+
27593+If you received this File from Marvell, you may opt to use, redistribute and/or
27594+modify this File in accordance with the terms and conditions of the General
27595+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
27596+available along with the File in the license.txt file or by writing to the Free
27597+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
27598+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
27599+
27600+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
27601+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
27602+DISCLAIMED. The GPL License provides additional details about this warranty
27603+disclaimer.
27604+********************************************************************************
27605+Marvell BSD License Option
27606+
27607+If you received this File from Marvell, you may opt to use, redistribute and/or
27608+modify this File under the following licensing terms.
27609+Redistribution and use in source and binary forms, with or without modification,
27610+are permitted provided that the following conditions are met:
27611+
27612+ * Redistributions of source code must retain the above copyright notice,
27613+ this list of conditions and the following disclaimer.
27614+
27615+ * Redistributions in binary form must reproduce the above copyright
27616+ notice, this list of conditions and the following disclaimer in the
27617+ documentation and/or other materials provided with the distribution.
27618+
27619+ * Neither the name of Marvell nor the names of its contributors may be
27620+ used to endorse or promote products derived from this software without
27621+ specific prior written permission.
27622+
27623+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27624+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27625+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27626+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
27627+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27628+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27629+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27630+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27631+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27632+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27633+
27634+*******************************************************************************/
27635+
27636+#include "mvOs.h"
27637+#include "mvLru.h"
27638+/* LRU Cache support */
27639+
27640+
27641+/* Init LRU cache database */
27642+MV_LRU_CACHE* mvLruCacheInit(int numOfEntries)
27643+{
27644+ int i;
27645+ MV_LRU_CACHE* pLruCache;
27646+
27647+ pLruCache = mvOsMalloc(sizeof(MV_LRU_CACHE));
27648+ if(pLruCache == NULL)
27649+ {
27650+ return NULL;
27651+ }
27652+ memset(pLruCache, 0, sizeof(MV_LRU_CACHE));
27653+
27654+ pLruCache->table = mvOsMalloc(numOfEntries*sizeof(MV_LRU_ENTRY));
27655+ if(pLruCache->table == NULL)
27656+ {
27657+ mvOsFree(pLruCache);
27658+ return NULL;
27659+ }
27660+ memset(pLruCache->table, 0, numOfEntries*sizeof(MV_LRU_ENTRY));
27661+ pLruCache->tableSize = numOfEntries;
27662+
27663+ for(i=0; i<numOfEntries; i++)
27664+ {
27665+ pLruCache->table[i].next = i+1;
27666+ pLruCache->table[i].prev = i-1;
27667+ }
27668+ pLruCache->least = 0;
27669+ pLruCache->most = numOfEntries-1;
27670+
27671+ return pLruCache;
27672+}
27673+
27674+void mvLruCacheFinish(MV_LRU_CACHE* pLruCache)
27675+{
27676+ mvOsFree(pLruCache->table);
27677+ mvOsFree(pLruCache);
27678+}
27679+
27680+/* Update LRU cache database after using cache Index */
27681+void mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx)
27682+{
27683+ int prev, next;
27684+
27685+ if(cacheIdx == pLruHndl->most)
27686+ return;
27687+
27688+ next = pLruHndl->table[cacheIdx].next;
27689+ if(cacheIdx == pLruHndl->least)
27690+ {
27691+ pLruHndl->least = next;
27692+ }
27693+ else
27694+ {
27695+ prev = pLruHndl->table[cacheIdx].prev;
27696+
27697+ pLruHndl->table[next].prev = prev;
27698+ pLruHndl->table[prev].next = next;
27699+ }
27700+
27701+ pLruHndl->table[pLruHndl->most].next = cacheIdx;
27702+ pLruHndl->table[cacheIdx].prev = pLruHndl->most;
27703+ pLruHndl->most = cacheIdx;
27704+}
27705+
27706+/* Delete LRU cache entry */
27707+void mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx)
27708+{
27709+ int prev, next;
27710+
27711+ if(cacheIdx == pLruHndl->least)
27712+ return;
27713+
27714+ prev = pLruHndl->table[cacheIdx].prev;
27715+ if(cacheIdx == pLruHndl->most)
27716+ {
27717+ pLruHndl->most = prev;
27718+ }
27719+ else
27720+ {
27721+ next = pLruHndl->table[cacheIdx].next;
27722+
27723+ pLruHndl->table[next].prev = prev;
27724+ pLruHndl->table[prev].next = next;
27725+ }
27726+ pLruHndl->table[pLruHndl->least].prev = cacheIdx;
27727+ pLruHndl->table[cacheIdx].next = pLruHndl->least;
27728+ pLruHndl->least = cacheIdx;
27729+}
27730diff --git a/crypto/ocf/kirkwood/cesa/mvLru.h b/crypto/ocf/kirkwood/cesa/mvLru.h
27731new file mode 100644
27732index 0000000..39d2f89
27733--- /dev/null
27734+++ b/crypto/ocf/kirkwood/cesa/mvLru.h
27735@@ -0,0 +1,112 @@
27736+/*******************************************************************************
27737+Copyright (C) Marvell International Ltd. and its affiliates
27738+
27739+This software file (the "File") is owned and distributed by Marvell
27740+International Ltd. and/or its affiliates ("Marvell") under the following
27741+alternative licensing terms. Once you have made an election to distribute the
27742+File under one of the following license alternatives, please (i) delete this
27743+introductory statement regarding license alternatives, (ii) delete the two
27744+license alternatives that you have not elected to use and (iii) preserve the
27745+Marvell copyright notice above.
27746+
27747+********************************************************************************
27748+Marvell Commercial License Option
27749+
27750+If you received this File from Marvell and you have entered into a commercial
27751+license agreement (a "Commercial License") with Marvell, the File is licensed
27752+to you under the terms of the applicable Commercial License.
27753+
27754+********************************************************************************
27755+Marvell GPL License Option
27756+
27757+If you received this File from Marvell, you may opt to use, redistribute and/or
27758+modify this File in accordance with the terms and conditions of the General
27759+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
27760+available along with the File in the license.txt file or by writing to the Free
27761+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
27762+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
27763+
27764+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
27765+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
27766+DISCLAIMED. The GPL License provides additional details about this warranty
27767+disclaimer.
27768+********************************************************************************
27769+Marvell BSD License Option
27770+
27771+If you received this File from Marvell, you may opt to use, redistribute and/or
27772+modify this File under the following licensing terms.
27773+Redistribution and use in source and binary forms, with or without modification,
27774+are permitted provided that the following conditions are met:
27775+
27776+ * Redistributions of source code must retain the above copyright notice,
27777+ this list of conditions and the following disclaimer.
27778+
27779+ * Redistributions in binary form must reproduce the above copyright
27780+ notice, this list of conditions and the following disclaimer in the
27781+ documentation and/or other materials provided with the distribution.
27782+
27783+ * Neither the name of Marvell nor the names of its contributors may be
27784+ used to endorse or promote products derived from this software without
27785+ specific prior written permission.
27786+
27787+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27788+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27789+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27790+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
27791+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27792+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27793+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27794+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27795+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27796+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27797+
27798+*******************************************************************************/
27799+/*******************************************************************************
27800+* mvLru.h - Header File for Least Recently Used Cache algorithm
27801+*
27802+* DESCRIPTION:
27803+* This header file contains macros typedefs and function declaration for
27804+* the Least Recently Used Cache algorithm.
27805+*
27806+*******************************************************************************/
27807+
27808+#ifndef __mvLru_h__
27809+#define __mvLru_h__
27810+
27811+
27812+typedef struct
27813+{
27814+ int next;
27815+ int prev;
27816+} MV_LRU_ENTRY;
27817+
27818+typedef struct
27819+{
27820+ int least;
27821+ int most;
27822+ MV_LRU_ENTRY* table;
27823+ int tableSize;
27824+
27825+}MV_LRU_CACHE;
27826+
27827+
27828+/* Find Cache index for replacement LRU */
27829+static INLINE int mvLruCacheIdxFind(MV_LRU_CACHE* pLruHndl)
27830+{
27831+ return pLruHndl->least;
27832+}
27833+
27834+/* Init LRU cache module */
27835+MV_LRU_CACHE* mvLruCacheInit(int numOfEntries);
27836+
27837+/* Finish LRU cache module */
27838+void mvLruCacheFinish(MV_LRU_CACHE* pLruHndl);
27839+
27840+/* Update LRU cache database after using cache Index */
27841+void mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx);
27842+
27843+/* Delete LRU cache entry */
27844+void mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx);
27845+
27846+
27847+#endif /* __mvLru_h__ */
27848diff --git a/crypto/ocf/kirkwood/cesa/mvMD5.c b/crypto/ocf/kirkwood/cesa/mvMD5.c
27849new file mode 100644
27850index 0000000..b012976
27851--- /dev/null
27852+++ b/crypto/ocf/kirkwood/cesa/mvMD5.c
27853@@ -0,0 +1,349 @@
27854+/*******************************************************************************
27855+Copyright (C) Marvell International Ltd. and its affiliates
27856+
27857+This software file (the "File") is owned and distributed by Marvell
27858+International Ltd. and/or its affiliates ("Marvell") under the following
27859+alternative licensing terms. Once you have made an election to distribute the
27860+File under one of the following license alternatives, please (i) delete this
27861+introductory statement regarding license alternatives, (ii) delete the two
27862+license alternatives that you have not elected to use and (iii) preserve the
27863+Marvell copyright notice above.
27864+
27865+********************************************************************************
27866+Marvell Commercial License Option
27867+
27868+If you received this File from Marvell and you have entered into a commercial
27869+license agreement (a "Commercial License") with Marvell, the File is licensed
27870+to you under the terms of the applicable Commercial License.
27871+
27872+********************************************************************************
27873+Marvell GPL License Option
27874+
27875+If you received this File from Marvell, you may opt to use, redistribute and/or
27876+modify this File in accordance with the terms and conditions of the General
27877+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
27878+available along with the File in the license.txt file or by writing to the Free
27879+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
27880+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
27881+
27882+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
27883+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
27884+DISCLAIMED. The GPL License provides additional details about this warranty
27885+disclaimer.
27886+********************************************************************************
27887+Marvell BSD License Option
27888+
27889+If you received this File from Marvell, you may opt to use, redistribute and/or
27890+modify this File under the following licensing terms.
27891+Redistribution and use in source and binary forms, with or without modification,
27892+are permitted provided that the following conditions are met:
27893+
27894+ * Redistributions of source code must retain the above copyright notice,
27895+ this list of conditions and the following disclaimer.
27896+
27897+ * Redistributions in binary form must reproduce the above copyright
27898+ notice, this list of conditions and the following disclaimer in the
27899+ documentation and/or other materials provided with the distribution.
27900+
27901+ * Neither the name of Marvell nor the names of its contributors may be
27902+ used to endorse or promote products derived from this software without
27903+ specific prior written permission.
27904+
27905+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27906+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27907+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27908+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
27909+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27910+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27911+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27912+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27913+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27914+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27915+
27916+*******************************************************************************/
27917+
27918+#include "mvOs.h"
27919+#include "mvMD5.h"
27920+
27921+static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN]);
27922+
27923+#ifdef MV_CPU_LE
27924+#define mvByteReverse(buf, len) /* Nothing */
27925+#else
27926+static void mvByteReverse(unsigned char *buf, unsigned longs);
27927+
27928+/*
27929+ * Note: this code is harmless on little-endian machines.
27930+ */
27931+static void mvByteReverse(unsigned char *buf, unsigned longs)
27932+{
27933+ MV_U32 t;
27934+
27935+ do
27936+ {
27937+ t = (MV_U32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
27938+ ((unsigned) buf[1] << 8 | buf[0]);
27939+ *(MV_U32 *) buf = t;
27940+ buf += 4;
27941+ } while (--longs);
27942+}
27943+#endif
27944+
27945+/*
27946+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
27947+ * initialization constants.
27948+ */
27949+void mvMD5Init(MV_MD5_CONTEXT *ctx)
27950+{
27951+ ctx->buf[0] = 0x67452301;
27952+ ctx->buf[1] = 0xefcdab89;
27953+ ctx->buf[2] = 0x98badcfe;
27954+ ctx->buf[3] = 0x10325476;
27955+
27956+ ctx->bits[0] = 0;
27957+ ctx->bits[1] = 0;
27958+}
27959+
27960+/*
27961+ * Update context to reflect the concatenation of another buffer full
27962+ * of bytes.
27963+ */
27964+void mvMD5Update(MV_MD5_CONTEXT *ctx, unsigned char const *buf, unsigned len)
27965+{
27966+ MV_U32 t;
27967+
27968+ /* Update bitcount */
27969+
27970+ t = ctx->bits[0];
27971+ if ((ctx->bits[0] = t + ((MV_U32) len << 3)) < t)
27972+ ctx->bits[1]++; /* Carry from low to high */
27973+ ctx->bits[1] += len >> 29;
27974+
27975+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
27976+
27977+ /* Handle any leading odd-sized chunks */
27978+
27979+ if (t)
27980+ {
27981+ unsigned char *p = (unsigned char *) ctx->in + t;
27982+
27983+ t = 64 - t;
27984+ if (len < t)
27985+ {
27986+ memcpy(p, buf, len);
27987+ return;
27988+ }
27989+ memcpy(p, buf, t);
27990+ mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
27991+ mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
27992+ buf += t;
27993+ len -= t;
27994+ }
27995+ /* Process data in 64-byte chunks */
27996+
27997+ while (len >= 64)
27998+ {
27999+ memcpy(ctx->in, buf, 64);
28000+ mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
28001+ mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
28002+ buf += 64;
28003+ len -= 64;
28004+ }
28005+
28006+ /* Handle any remaining bytes of data. */
28007+
28008+ memcpy(ctx->in, buf, len);
28009+}
28010+
28011+/*
28012+ * Final wrapup - pad to 64-byte boundary with the bit pattern
28013+ * 1 0* (64-bit count of bits processed, MSB-first)
28014+ */
28015+void mvMD5Final(unsigned char digest[MV_MD5_MAC_LEN], MV_MD5_CONTEXT *ctx)
28016+{
28017+ unsigned count;
28018+ unsigned char *p;
28019+
28020+ /* Compute number of bytes mod 64 */
28021+ count = (ctx->bits[0] >> 3) & 0x3F;
28022+
28023+ /* Set the first char of padding to 0x80. This is safe since there is
28024+ always at least one byte free */
28025+ p = ctx->in + count;
28026+ *p++ = 0x80;
28027+
28028+ /* Bytes of padding needed to make 64 bytes */
28029+ count = 64 - 1 - count;
28030+
28031+ /* Pad out to 56 mod 64 */
28032+ if (count < 8)
28033+ {
28034+ /* Two lots of padding: Pad the first block to 64 bytes */
28035+ memset(p, 0, count);
28036+ mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
28037+ mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
28038+
28039+ /* Now fill the next block with 56 bytes */
28040+ memset(ctx->in, 0, 56);
28041+ }
28042+ else
28043+ {
28044+ /* Pad block to 56 bytes */
28045+ memset(p, 0, count - 8);
28046+ }
28047+ mvByteReverse(ctx->in, 14);
28048+
28049+ /* Append length in bits and transform */
28050+ ((MV_U32 *) ctx->in)[14] = ctx->bits[0];
28051+ ((MV_U32 *) ctx->in)[15] = ctx->bits[1];
28052+
28053+ mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
28054+ mvByteReverse((unsigned char *) ctx->buf, 4);
28055+ memcpy(digest, ctx->buf, MV_MD5_MAC_LEN);
28056+ memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
28057+}
28058+
28059+/* The four core functions - F1 is optimized somewhat */
28060+
28061+/* #define F1(x, y, z) (x & y | ~x & z) */
28062+#define F1(x, y, z) (z ^ (x & (y ^ z)))
28063+#define F2(x, y, z) F1(z, x, y)
28064+#define F3(x, y, z) (x ^ y ^ z)
28065+#define F4(x, y, z) (y ^ (x | ~z))
28066+
28067+/* This is the central step in the MD5 algorithm. */
28068+#define MD5STEP(f, w, x, y, z, data, s) \
28069+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
28070+
28071+/*
28072+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
28073+ * reflect the addition of 16 longwords of new data. MD5Update blocks
28074+ * the data and converts bytes into longwords for this routine.
28075+ */
28076+static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN])
28077+{
28078+ register MV_U32 a, b, c, d;
28079+
28080+ a = buf[0];
28081+ b = buf[1];
28082+ c = buf[2];
28083+ d = buf[3];
28084+
28085+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
28086+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
28087+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
28088+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
28089+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
28090+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
28091+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
28092+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
28093+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
28094+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
28095+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
28096+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
28097+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
28098+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
28099+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
28100+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
28101+
28102+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
28103+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
28104+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
28105+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
28106+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
28107+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
28108+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
28109+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
28110+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
28111+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
28112+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
28113+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
28114+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
28115+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
28116+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
28117+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
28118+
28119+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
28120+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
28121+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
28122+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
28123+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
28124+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
28125+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
28126+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
28127+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
28128+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
28129+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
28130+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
28131+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
28132+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
28133+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
28134+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
28135+
28136+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
28137+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
28138+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
28139+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
28140+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
28141+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
28142+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
28143+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
28144+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
28145+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
28146+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
28147+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
28148+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
28149+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
28150+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
28151+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
28152+
28153+ buf[0] += a;
28154+ buf[1] += b;
28155+ buf[2] += c;
28156+ buf[3] += d;
28157+}
28158+
28159+void mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest)
28160+{
28161+ MV_MD5_CONTEXT ctx;
28162+
28163+ mvMD5Init(&ctx);
28164+ mvMD5Update(&ctx, buf, len);
28165+ mvMD5Final(digest, &ctx);
28166+}
28167+
28168+
28169+void mvHmacMd5(unsigned char const* text, int text_len,
28170+ unsigned char const* key, int key_len,
28171+ unsigned char* digest)
28172+{
28173+ int i;
28174+ MV_MD5_CONTEXT ctx;
28175+ unsigned char k_ipad[64+1]; /* inner padding - key XORd with ipad */
28176+ unsigned char k_opad[64+1]; /* outer padding - key XORd with opad */
28177+
28178+ /* start out by storing key in pads */
28179+ memset(k_ipad, 0, 64);
28180+ memcpy(k_ipad, key, key_len);
28181+ memset(k_opad, 0, 64);
28182+ memcpy(k_opad, key, key_len);
28183+
28184+ /* XOR key with ipad and opad values */
28185+ for (i=0; i<64; i++)
28186+ {
28187+ k_ipad[i] ^= 0x36;
28188+ k_opad[i] ^= 0x5c;
28189+ }
28190+
28191+ /* perform inner MD5 */
28192+ mvMD5Init(&ctx); /* init ctx for 1st pass */
28193+ mvMD5Update(&ctx, k_ipad, 64); /* start with inner pad */
28194+ mvMD5Update(&ctx, text, text_len); /* then text of datagram */
28195+ mvMD5Final(digest, &ctx); /* finish up 1st pass */
28196+
28197+ /* perform outer MD5 */
28198+ mvMD5Init(&ctx); /* init ctx for 2nd pass */
28199+ mvMD5Update(&ctx, k_opad, 64); /* start with outer pad */
28200+ mvMD5Update(&ctx, digest, 16); /* then results of 1st hash */
28201+ mvMD5Final(digest, &ctx); /* finish up 2nd pass */
28202+}
28203diff --git a/crypto/ocf/kirkwood/cesa/mvMD5.h b/crypto/ocf/kirkwood/cesa/mvMD5.h
28204new file mode 100644
28205index 0000000..d20281e
28206--- /dev/null
28207+++ b/crypto/ocf/kirkwood/cesa/mvMD5.h
28208@@ -0,0 +1,93 @@
28209+/*******************************************************************************
28210+Copyright (C) Marvell International Ltd. and its affiliates
28211+
28212+This software file (the "File") is owned and distributed by Marvell
28213+International Ltd. and/or its affiliates ("Marvell") under the following
28214+alternative licensing terms. Once you have made an election to distribute the
28215+File under one of the following license alternatives, please (i) delete this
28216+introductory statement regarding license alternatives, (ii) delete the two
28217+license alternatives that you have not elected to use and (iii) preserve the
28218+Marvell copyright notice above.
28219+
28220+********************************************************************************
28221+Marvell Commercial License Option
28222+
28223+If you received this File from Marvell and you have entered into a commercial
28224+license agreement (a "Commercial License") with Marvell, the File is licensed
28225+to you under the terms of the applicable Commercial License.
28226+
28227+********************************************************************************
28228+Marvell GPL License Option
28229+
28230+If you received this File from Marvell, you may opt to use, redistribute and/or
28231+modify this File in accordance with the terms and conditions of the General
28232+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
28233+available along with the File in the license.txt file or by writing to the Free
28234+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
28235+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
28236+
28237+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
28238+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
28239+DISCLAIMED. The GPL License provides additional details about this warranty
28240+disclaimer.
28241+********************************************************************************
28242+Marvell BSD License Option
28243+
28244+If you received this File from Marvell, you may opt to use, redistribute and/or
28245+modify this File under the following licensing terms.
28246+Redistribution and use in source and binary forms, with or without modification,
28247+are permitted provided that the following conditions are met:
28248+
28249+ * Redistributions of source code must retain the above copyright notice,
28250+ this list of conditions and the following disclaimer.
28251+
28252+ * Redistributions in binary form must reproduce the above copyright
28253+ notice, this list of conditions and the following disclaimer in the
28254+ documentation and/or other materials provided with the distribution.
28255+
28256+ * Neither the name of Marvell nor the names of its contributors may be
28257+ used to endorse or promote products derived from this software without
28258+ specific prior written permission.
28259+
28260+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
28261+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28262+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28263+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28264+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28265+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28266+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28267+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28268+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28269+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28270+
28271+*******************************************************************************/
28272+
28273+#ifndef __mvMD5_h__
28274+#define __mvMD5_h__
28275+
28276+#include "mvMD5.h"
28277+
28278+#define MV_MD5_MAC_LEN 16
28279+
28280+
28281+typedef struct
28282+{
28283+ MV_U32 buf[4];
28284+ MV_U32 bits[2];
28285+ MV_U8 in[64];
28286+
28287+} MV_MD5_CONTEXT;
28288+
28289+void mvMD5Init(MV_MD5_CONTEXT *context);
28290+void mvMD5Update(MV_MD5_CONTEXT *context, unsigned char const *buf,
28291+ unsigned len);
28292+void mvMD5Final(unsigned char digest[16], MV_MD5_CONTEXT *context);
28293+
28294+void mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest);
28295+
28296+void mvHmacMd5(unsigned char const* text, int text_len,
28297+ unsigned char const* key, int key_len,
28298+ unsigned char* digest);
28299+
28300+
28301+#endif /* __mvMD5_h__ */
28302diff --git a/crypto/ocf/kirkwood/cesa/mvSHA1.c b/crypto/ocf/kirkwood/cesa/mvSHA1.c
28303new file mode 100644
28304index 0000000..6342985
28305--- /dev/null
28306+++ b/crypto/ocf/kirkwood/cesa/mvSHA1.c
28307@@ -0,0 +1,239 @@
28308+/*******************************************************************************
28309+Copyright (C) Marvell International Ltd. and its affiliates
28310+
28311+This software file (the "File") is owned and distributed by Marvell
28312+International Ltd. and/or its affiliates ("Marvell") under the following
28313+alternative licensing terms. Once you have made an election to distribute the
28314+File under one of the following license alternatives, please (i) delete this
28315+introductory statement regarding license alternatives, (ii) delete the two
28316+license alternatives that you have not elected to use and (iii) preserve the
28317+Marvell copyright notice above.
28318+
28319+********************************************************************************
28320+Marvell Commercial License Option
28321+
28322+If you received this File from Marvell and you have entered into a commercial
28323+license agreement (a "Commercial License") with Marvell, the File is licensed
28324+to you under the terms of the applicable Commercial License.
28325+
28326+********************************************************************************
28327+Marvell GPL License Option
28328+
28329+If you received this File from Marvell, you may opt to use, redistribute and/or
28330+modify this File in accordance with the terms and conditions of the General
28331+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
28332+available along with the File in the license.txt file or by writing to the Free
28333+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
28334+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
28335+
28336+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
28337+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
28338+DISCLAIMED. The GPL License provides additional details about this warranty
28339+disclaimer.
28340+********************************************************************************
28341+Marvell BSD License Option
28342+
28343+If you received this File from Marvell, you may opt to use, redistribute and/or
28344+modify this File under the following licensing terms.
28345+Redistribution and use in source and binary forms, with or without modification,
28346+are permitted provided that the following conditions are met:
28347+
28348+ * Redistributions of source code must retain the above copyright notice,
28349+ this list of conditions and the following disclaimer.
28350+
28351+ * Redistributions in binary form must reproduce the above copyright
28352+ notice, this list of conditions and the following disclaimer in the
28353+ documentation and/or other materials provided with the distribution.
28354+
28355+ * Neither the name of Marvell nor the names of its contributors may be
28356+ used to endorse or promote products derived from this software without
28357+ specific prior written permission.
28358+
28359+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
28360+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28361+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28362+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28363+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28364+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28365+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28366+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28367+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28368+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28369+
28370+*******************************************************************************/
28371+
28372+#include "mvOs.h"
28373+#include "mvSHA1.h"
28374+
28375+#define SHA1HANDSOFF
28376+
28377+typedef union
28378+{
28379+ MV_U8 c[64];
28380+ MV_U32 l[16];
28381+
28382+} CHAR64LONG16;
28383+
28384+static void mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer);
28385+
28386+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
28387+
28388+
28389+#ifdef MV_CPU_LE
28390+#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
28391+ (rol(block->l[i], 8) & 0x00FF00FF))
28392+#else
28393+#define blk0(i) block->l[i]
28394+#endif
28395+#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
28396+ block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
28397+
28398+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
28399+#define R0(v,w,x,y,z,i) \
28400+ z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
28401+ w = rol(w, 30);
28402+#define R1(v,w,x,y,z,i) \
28403+ z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
28404+ w = rol(w, 30);
28405+#define R2(v,w,x,y,z,i) \
28406+ z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
28407+#define R3(v,w,x,y,z,i) \
28408+ z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
28409+ w = rol(w, 30);
28410+#define R4(v,w,x,y,z,i) \
28411+ z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
28412+ w=rol(w, 30);
28413+
28414+/* Hash a single 512-bit block. This is the core of the algorithm. */
28415+static void mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer)
28416+{
28417+ MV_U32 a, b, c, d, e;
28418+ CHAR64LONG16* block;
28419+
28420+#ifdef SHA1HANDSOFF
28421+ static MV_U32 workspace[16];
28422+
28423+ block = (CHAR64LONG16 *) workspace;
28424+ memcpy(block, buffer, 64);
28425+#else
28426+ block = (CHAR64LONG16 *) buffer;
28427+#endif
28428+ /* Copy context->state[] to working vars */
28429+ a = state[0];
28430+ b = state[1];
28431+ c = state[2];
28432+ d = state[3];
28433+ e = state[4];
28434+ /* 4 rounds of 20 operations each. Loop unrolled. */
28435+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
28436+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
28437+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
28438+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
28439+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
28440+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
28441+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
28442+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
28443+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
28444+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
28445+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
28446+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
28447+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
28448+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
28449+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
28450+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
28451+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
28452+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
28453+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
28454+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
28455+ /* Add the working vars back into context.state[] */
28456+ state[0] += a;
28457+ state[1] += b;
28458+ state[2] += c;
28459+ state[3] += d;
28460+ state[4] += e;
28461+ /* Wipe variables */
28462+ a = b = c = d = e = 0;
28463+}
28464+
28465+void mvSHA1Init(MV_SHA1_CTX* context)
28466+{
28467+ /* SHA1 initialization constants */
28468+ context->state[0] = 0x67452301;
28469+ context->state[1] = 0xEFCDAB89;
28470+ context->state[2] = 0x98BADCFE;
28471+ context->state[3] = 0x10325476;
28472+ context->state[4] = 0xC3D2E1F0;
28473+ context->count[0] = context->count[1] = 0;
28474+}
28475+
28476+
28477+/* Run your data through this. */
28478+void mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *data,
28479+ unsigned int len)
28480+{
28481+ MV_U32 i, j;
28482+
28483+ j = (context->count[0] >> 3) & 63;
28484+ if ((context->count[0] += len << 3) < (len << 3))
28485+ context->count[1]++;
28486+ context->count[1] += (len >> 29);
28487+ if ((j + len) > 63)
28488+ {
28489+ memcpy(&context->buffer[j], data, (i = 64-j));
28490+ mvSHA1Transform(context->state, context->buffer);
28491+ for ( ; i + 63 < len; i += 64)
28492+ {
28493+ mvSHA1Transform(context->state, &data[i]);
28494+ }
28495+ j = 0;
28496+ }
28497+ else
28498+ {
28499+ i = 0;
28500+ }
28501+ memcpy(&context->buffer[j], &data[i], len - i);
28502+}
28503+
28504+void mvSHA1Final(MV_U8* digest, MV_SHA1_CTX* context)
28505+{
28506+ MV_U32 i;
28507+ MV_U8 finalcount[8];
28508+
28509+ for (i = 0; i < 8; i++)
28510+ {
28511+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >>
28512+ ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
28513+ }
28514+ mvSHA1Update(context, (const unsigned char *) "\200", 1);
28515+ while ((context->count[0] & 504) != 448)
28516+ {
28517+ mvSHA1Update(context, (const unsigned char *) "\0", 1);
28518+ }
28519+ mvSHA1Update(context, finalcount, 8); /* Should cause a mvSHA1Transform()
28520+ */
28521+ for (i = 0; i < 20; i++)
28522+ {
28523+ digest[i] = (unsigned char)
28524+ ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
28525+ }
28526+ /* Wipe variables */
28527+ i = 0;
28528+ memset(context->buffer, 0, 64);
28529+ memset(context->state, 0, 20);
28530+ memset(context->count, 0, 8);
28531+ memset(finalcount, 0, 8);
28532+
28533+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
28534+ mvSHA1Transform(context->state, context->buffer);
28535+#endif
28536+}
28537+
28538+
28539+void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest)
28540+{
28541+ MV_SHA1_CTX ctx;
28542+
28543+ mvSHA1Init(&ctx);
28544+ mvSHA1Update(&ctx, buf, len);
28545+ mvSHA1Final(digest, &ctx);
28546+}
28547diff --git a/crypto/ocf/kirkwood/cesa/mvSHA1.h b/crypto/ocf/kirkwood/cesa/mvSHA1.h
28548new file mode 100644
28549index 0000000..1914f47
28550--- /dev/null
28551+++ b/crypto/ocf/kirkwood/cesa/mvSHA1.h
28552@@ -0,0 +1,88 @@
28553+/*******************************************************************************
28554+Copyright (C) Marvell International Ltd. and its affiliates
28555+
28556+This software file (the "File") is owned and distributed by Marvell
28557+International Ltd. and/or its affiliates ("Marvell") under the following
28558+alternative licensing terms. Once you have made an election to distribute the
28559+File under one of the following license alternatives, please (i) delete this
28560+introductory statement regarding license alternatives, (ii) delete the two
28561+license alternatives that you have not elected to use and (iii) preserve the
28562+Marvell copyright notice above.
28563+
28564+********************************************************************************
28565+Marvell Commercial License Option
28566+
28567+If you received this File from Marvell and you have entered into a commercial
28568+license agreement (a "Commercial License") with Marvell, the File is licensed
28569+to you under the terms of the applicable Commercial License.
28570+
28571+********************************************************************************
28572+Marvell GPL License Option
28573+
28574+If you received this File from Marvell, you may opt to use, redistribute and/or
28575+modify this File in accordance with the terms and conditions of the General
28576+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
28577+available along with the File in the license.txt file or by writing to the Free
28578+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
28579+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
28580+
28581+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
28582+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
28583+DISCLAIMED. The GPL License provides additional details about this warranty
28584+disclaimer.
28585+********************************************************************************
28586+Marvell BSD License Option
28587+
28588+If you received this File from Marvell, you may opt to use, redistribute and/or
28589+modify this File under the following licensing terms.
28590+Redistribution and use in source and binary forms, with or without modification,
28591+are permitted provided that the following conditions are met:
28592+
28593+ * Redistributions of source code must retain the above copyright notice,
28594+ this list of conditions and the following disclaimer.
28595+
28596+ * Redistributions in binary form must reproduce the above copyright
28597+ notice, this list of conditions and the following disclaimer in the
28598+ documentation and/or other materials provided with the distribution.
28599+
28600+ * Neither the name of Marvell nor the names of its contributors may be
28601+ used to endorse or promote products derived from this software without
28602+ specific prior written permission.
28603+
28604+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
28605+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28606+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28607+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28608+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28609+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28610+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28611+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28612+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28613+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28614+
28615+*******************************************************************************/
28616+
28617+#ifndef __mvSHA1_h__
28618+#define __mvSHA1_h__
28619+
28620+#include "mvSHA1.h"
28621+
28622+#define MV_SHA1_MAC_LEN 20
28623+
28624+
28625+typedef struct
28626+{
28627+ MV_U32 state[5];
28628+ MV_U32 count[2];
28629+ MV_U8 buffer[64];
28630+
28631+} MV_SHA1_CTX;
28632+
28633+void mvSHA1Init(MV_SHA1_CTX *context);
28634+void mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *buf, unsigned int len);
28635+void mvSHA1Final(MV_U8* digest, MV_SHA1_CTX *context);
28636+
28637+void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest);
28638+
28639+
28640+#endif /* __mvSHA1_h__ */
28641diff --git a/crypto/ocf/kirkwood/cesa_ocf_drv.c b/crypto/ocf/kirkwood/cesa_ocf_drv.c
28642new file mode 100644
28643index 0000000..c056b1f
28644--- /dev/null
28645+++ b/crypto/ocf/kirkwood/cesa_ocf_drv.c
28646@@ -0,0 +1,1296 @@
28647+/*******************************************************************************
28648+Copyright (C) Marvell International Ltd. and its affiliates
28649+
28650+This software file (the "File") is owned and distributed by Marvell
28651+International Ltd. and/or its affiliates ("Marvell") under the following
28652+alternative licensing terms. Once you have made an election to distribute the
28653+File under one of the following license alternatives, please (i) delete this
28654+introductory statement regarding license alternatives, (ii) delete the two
28655+license alternatives that you have not elected to use and (iii) preserve the
28656+Marvell copyright notice above.
28657+
28658+
28659+********************************************************************************
28660+Marvell GPL License Option
28661+
28662+If you received this File from Marvell, you may opt to use, redistribute and/or
28663+modify this File in accordance with the terms and conditions of the General
28664+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
28665+available along with the File in the license.txt file or by writing to the Free
28666+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
28667+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
28668+
28669+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
28670+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
28671+DISCLAIMED. The GPL License provides additional details about this warranty
28672+disclaimer.
28673+*******************************************************************************/
28674+
28675+#ifndef AUTOCONF_INCLUDED
28676+#include <linux/config.h>
28677+#endif
28678+#include <linux/module.h>
28679+#include <linux/init.h>
28680+#include <linux/list.h>
28681+#include <linux/slab.h>
28682+#include <linux/sched.h>
28683+#include <linux/wait.h>
28684+#include <linux/crypto.h>
28685+#include <linux/mm.h>
28686+#include <linux/skbuff.h>
28687+#include <linux/random.h>
28688+#include <linux/platform_device.h>
28689+#include <asm/scatterlist.h>
28690+#include <linux/spinlock.h>
28691+#include "ctrlEnv/sys/mvSysCesa.h"
28692+#include "cesa/mvCesa.h" /* moved here before cryptodev.h due to include dependencies */
28693+#include <cryptodev.h>
28694+#include <uio.h>
28695+#include <plat/mv_cesa.h>
28696+#include <linux/mbus.h>
28697+#include "mvDebug.h"
28698+
28699+#include "cesa/mvMD5.h"
28700+#include "cesa/mvSHA1.h"
28701+
28702+#include "cesa/mvCesaRegs.h"
28703+#include "cesa/AES/mvAes.h"
28704+#include "cesa/mvLru.h"
28705+
28706+#undef RT_DEBUG
28707+#ifdef RT_DEBUG
28708+static int debug = 1;
28709+module_param(debug, int, 1);
28710+MODULE_PARM_DESC(debug, "Enable debug");
28711+#undef dprintk
28712+#define dprintk(a...) if (debug) { printk(a); } else
28713+#else
28714+static int debug = 0;
28715+#undef dprintk
28716+#define dprintk(a...)
28717+#endif
28718+
28719+
28720+/* TDMA Regs */
28721+#define WINDOW_BASE(i) 0xA00 + (i << 3)
28722+#define WINDOW_CTRL(i) 0xA04 + (i << 3)
28723+
28724+/* interrupt handling */
28725+#undef CESA_OCF_POLLING
28726+#undef CESA_OCF_TASKLET
28727+
28728+#if defined(CESA_OCF_POLLING) && defined(CESA_OCF_TASKLET)
28729+#error "don't use both tasklet and polling mode"
28730+#endif
28731+
28732+extern int cesaReqResources;
28733+/* support for spliting action into 2 actions */
28734+#define CESA_OCF_SPLIT
28735+
28736+/* general defines */
28737+#define CESA_OCF_MAX_SES 128
28738+#define CESA_Q_SIZE 64
28739+
28740+
28741+/* data structures */
28742+struct cesa_ocf_data {
28743+ int cipher_alg;
28744+ int auth_alg;
28745+ int encrypt_tn_auth;
28746+#define auth_tn_decrypt encrypt_tn_auth
28747+ int ivlen;
28748+ int digestlen;
28749+ short sid_encrypt;
28750+ short sid_decrypt;
28751+ /* fragment workaround sessions */
28752+ short frag_wa_encrypt;
28753+ short frag_wa_decrypt;
28754+ short frag_wa_auth;
28755+};
28756+
28757+/* CESA device data */
28758+struct cesa_dev {
28759+ void __iomem *sram;
28760+ void __iomem *reg;
28761+ struct mv_cesa_platform_data *plat_data;
28762+ int irq;
28763+};
28764+
28765+#define DIGEST_BUF_SIZE 32
28766+struct cesa_ocf_process {
28767+ MV_CESA_COMMAND cesa_cmd;
28768+ MV_CESA_MBUF cesa_mbuf;
28769+ MV_BUF_INFO cesa_bufs[MV_CESA_MAX_MBUF_FRAGS];
28770+ char digest[DIGEST_BUF_SIZE];
28771+ int digest_len;
28772+ struct cryptop *crp;
28773+ int need_cb;
28774+};
28775+
28776+/* global variables */
28777+static int32_t cesa_ocf_id = -1;
28778+static struct cesa_ocf_data *cesa_ocf_sessions[CESA_OCF_MAX_SES];
28779+static spinlock_t cesa_lock;
28780+static struct cesa_dev cesa_device;
28781+
28782+/* static APIs */
28783+static int cesa_ocf_process (device_t, struct cryptop *, int);
28784+static int cesa_ocf_newsession (device_t, u_int32_t *, struct cryptoini *);
28785+static int cesa_ocf_freesession (device_t, u_int64_t);
28786+static void cesa_callback (unsigned long);
28787+static irqreturn_t cesa_interrupt_handler (int, void *);
28788+#ifdef CESA_OCF_POLLING
28789+static void cesa_interrupt_polling(void);
28790+#endif
28791+#ifdef CESA_OCF_TASKLET
28792+static struct tasklet_struct cesa_ocf_tasklet;
28793+#endif
28794+
28795+static struct timeval tt_start;
28796+static struct timeval tt_end;
28797+
28798+/*
28799+ * dummy device structure
28800+ */
28801+
28802+static struct {
28803+ softc_device_decl sc_dev;
28804+} mv_cesa_dev;
28805+
28806+static device_method_t mv_cesa_methods = {
28807+ /* crypto device methods */
28808+ DEVMETHOD(cryptodev_newsession, cesa_ocf_newsession),
28809+ DEVMETHOD(cryptodev_freesession,cesa_ocf_freesession),
28810+ DEVMETHOD(cryptodev_process, cesa_ocf_process),
28811+ DEVMETHOD(cryptodev_kprocess, NULL),
28812+};
28813+
28814+
28815+
28816+/* Add debug Trace */
28817+#undef CESA_OCF_TRACE_DEBUG
28818+#ifdef CESA_OCF_TRACE_DEBUG
28819+
28820+#define MV_CESA_USE_TIMER_ID 0
28821+
28822+typedef struct
28823+{
28824+ int type; /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */
28825+ MV_U32 timeStamp;
28826+ MV_U32 cause;
28827+ MV_U32 realCause;
28828+ MV_U32 dmaCause;
28829+ int resources;
28830+ MV_CESA_REQ* pReqReady;
28831+ MV_CESA_REQ* pReqEmpty;
28832+ MV_CESA_REQ* pReqProcess;
28833+} MV_CESA_TEST_TRACE;
28834+
28835+#define MV_CESA_TEST_TRACE_SIZE 50
28836+
28837+static int cesaTestTraceIdx = 0;
28838+static MV_CESA_TEST_TRACE cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];
28839+
28840+static void cesaTestTraceAdd(int type)
28841+{
28842+ cesaTestTrace[cesaTestTraceIdx].type = type;
28843+ cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
28844+ //cesaTestTrace[cesaTestTraceIdx].idmaCause = MV_REG_READ(IDMA_CAUSE_REG);
28845+ cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;
28846+ cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;
28847+ cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;
28848+ cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;
28849+ cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);
28850+ cesaTestTraceIdx++;
28851+ if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)
28852+ cesaTestTraceIdx = 0;
28853+}
28854+
28855+#else /* CESA_OCF_TRACE_DEBUG */
28856+
28857+#define cesaTestTraceAdd(x)
28858+
28859+#endif /* CESA_OCF_TRACE_DEBUG */
28860+
28861+unsigned int
28862+get_usec(unsigned int start)
28863+{
28864+ if(start) {
28865+ do_gettimeofday (&tt_start);
28866+ return 0;
28867+ }
28868+ else {
28869+ do_gettimeofday (&tt_end);
28870+ tt_end.tv_sec -= tt_start.tv_sec;
28871+ tt_end.tv_usec -= tt_start.tv_usec;
28872+ if (tt_end.tv_usec < 0) {
28873+ tt_end.tv_usec += 1000 * 1000;
28874+ tt_end.tv_sec -= 1;
28875+ }
28876+ }
28877+ printk("time taken is %d\n", (unsigned int)(tt_end.tv_usec + tt_end.tv_sec * 1000000));
28878+ return (tt_end.tv_usec + tt_end.tv_sec * 1000000);
28879+}
28880+
28881+#ifdef RT_DEBUG
28882+/*
28883+ * check that the crp action match the current session
28884+ */
28885+static int
28886+ocf_check_action(struct cryptop *crp, struct cesa_ocf_data *cesa_ocf_cur_ses) {
28887+ int count = 0;
28888+ int encrypt = 0, decrypt = 0, auth = 0;
28889+ struct cryptodesc *crd;
28890+
28891+ /* Go through crypto descriptors, processing as we go */
28892+ for (crd = crp->crp_desc; crd; crd = crd->crd_next, count++) {
28893+ if(count > 2) {
28894+ printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
28895+ return 1;
28896+ }
28897+
28898+ /* Encryption /Decryption */
28899+ if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
28900+ /* check that the action is compatible with session */
28901+ if(encrypt || decrypt) {
28902+ printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
28903+ return 1;
28904+ }
28905+
28906+ if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
28907+ if( (count == 2) && (cesa_ocf_cur_ses->encrypt_tn_auth) ) {
28908+ printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
28909+ return 1;
28910+ }
28911+ encrypt++;
28912+ }
28913+ else { /* decrypt */
28914+ if( (count == 2) && !(cesa_ocf_cur_ses->auth_tn_decrypt) ) {
28915+ printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
28916+ return 1;
28917+ }
28918+ decrypt++;
28919+ }
28920+
28921+ }
28922+ /* Authentication */
28923+ else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
28924+ /* check that the action is compatible with session */
28925+ if(auth) {
28926+ printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
28927+ return 1;
28928+ }
28929+ if( (count == 2) && (decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
28930+ printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
28931+ return 1;
28932+ }
28933+ if( (count == 2) && (encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)) {
28934+ printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
28935+ return 1;
28936+ }
28937+ auth++;
28938+ }
28939+ else {
28940+ printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
28941+ return 1;
28942+ }
28943+ }
28944+ return 0;
28945+
28946+}
28947+#endif
28948+
28949+/*
28950+ * Process a request.
28951+ */
28952+static int
28953+cesa_ocf_process(device_t dev, struct cryptop *crp, int hint)
28954+{
28955+ struct cesa_ocf_process *cesa_ocf_cmd = NULL;
28956+ struct cesa_ocf_process *cesa_ocf_cmd_wa = NULL;
28957+ MV_CESA_COMMAND *cesa_cmd;
28958+ struct cryptodesc *crd;
28959+ struct cesa_ocf_data *cesa_ocf_cur_ses;
28960+ int sid = 0, temp_len = 0, i;
28961+ int encrypt = 0, decrypt = 0, auth = 0;
28962+ int status;
28963+ struct sk_buff *skb = NULL;
28964+ struct uio *uiop = NULL;
28965+ unsigned char *ivp;
28966+ MV_BUF_INFO *p_buf_info;
28967+ MV_CESA_MBUF *p_mbuf_info;
28968+ unsigned long flags;
28969+
28970+ dprintk("%s()\n", __FUNCTION__);
28971+
28972+ if( cesaReqResources <= 1 ) {
28973+ dprintk("%s,%d: ERESTART\n", __FILE__, __LINE__);
28974+ return ERESTART;
28975+ }
28976+
28977+#ifdef RT_DEBUG
28978+ /* Sanity check */
28979+ if (crp == NULL) {
28980+ printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
28981+ return EINVAL;
28982+ }
28983+
28984+ if (crp->crp_desc == NULL || crp->crp_buf == NULL ) {
28985+ printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
28986+ crp->crp_etype = EINVAL;
28987+ return EINVAL;
28988+ }
28989+
28990+ sid = crp->crp_sid & 0xffffffff;
28991+ if ((sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL)) {
28992+ crp->crp_etype = ENOENT;
28993+ printk("%s,%d: ENOENT session %d \n", __FILE__, __LINE__, sid);
28994+ return EINVAL;
28995+ }
28996+#endif
28997+
28998+ sid = crp->crp_sid & 0xffffffff;
28999+ crp->crp_etype = 0;
29000+ cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
29001+
29002+#ifdef RT_DEBUG
29003+ if(ocf_check_action(crp, cesa_ocf_cur_ses)){
29004+ goto p_error;
29005+ }
29006+#endif
29007+
29008+ /* malloc a new cesa process */
29009+ cesa_ocf_cmd = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
29010+
29011+ if (cesa_ocf_cmd == NULL) {
29012+ printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
29013+ goto p_error;
29014+ }
29015+ memset(cesa_ocf_cmd, 0, sizeof(struct cesa_ocf_process));
29016+
29017+ /* init cesa_process */
29018+ cesa_ocf_cmd->crp = crp;
29019+ /* always call callback */
29020+ cesa_ocf_cmd->need_cb = 1;
29021+
29022+ /* init cesa_cmd for usage of the HALs */
29023+ cesa_cmd = &cesa_ocf_cmd->cesa_cmd;
29024+ cesa_cmd->pReqPrv = (void *)cesa_ocf_cmd;
29025+ cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_encrypt; /* defualt use encrypt */
29026+
29027+ /* prepare src buffer */
29028+ /* we send the entire buffer to the HAL, even if only part of it should be encrypt/auth. */
29029+ /* if not using seesions for both encrypt and auth, then it will be wiser to to copy only */
29030+ /* from skip to crd_len. */
29031+ p_buf_info = cesa_ocf_cmd->cesa_bufs;
29032+ p_mbuf_info = &cesa_ocf_cmd->cesa_mbuf;
29033+
29034+ p_buf_info += 2; /* save 2 first buffers for IV and digest -
29035+ we won't append them to the end since, they
29036+ might be places in an unaligned addresses. */
29037+
29038+ p_mbuf_info->pFrags = p_buf_info;
29039+ temp_len = 0;
29040+
29041+ /* handle SKB */
29042+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
29043+
29044+ dprintk("%s,%d: handle SKB.\n", __FILE__, __LINE__);
29045+ skb = (struct sk_buff *) crp->crp_buf;
29046+
29047+ if (skb_shinfo(skb)->nr_frags >= (MV_CESA_MAX_MBUF_FRAGS - 1)) {
29048+ printk("%s,%d: %d nr_frags > MV_CESA_MAX_MBUF_FRAGS", __FILE__, __LINE__, skb_shinfo(skb)->nr_frags);
29049+ goto p_error;
29050+ }
29051+
29052+ p_mbuf_info->mbufSize = skb->len;
29053+ temp_len = skb->len;
29054+ /* first skb fragment */
29055+ p_buf_info->bufSize = skb_headlen(skb);
29056+ p_buf_info->bufVirtPtr = skb->data;
29057+ p_buf_info++;
29058+
29059+ /* now handle all other skb fragments */
29060+ for ( i = 0; i < skb_shinfo(skb)->nr_frags; i++ ) {
29061+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
29062+ p_buf_info->bufSize = frag->size;
29063+ p_buf_info->bufVirtPtr = page_address(frag->page) + frag->page_offset;
29064+ p_buf_info++;
29065+ }
29066+ p_mbuf_info->numFrags = skb_shinfo(skb)->nr_frags + 1;
29067+ }
29068+ /* handle UIO */
29069+ else if(crp->crp_flags & CRYPTO_F_IOV) {
29070+
29071+ dprintk("%s,%d: handle UIO.\n", __FILE__, __LINE__);
29072+ uiop = (struct uio *) crp->crp_buf;
29073+
29074+ if (uiop->uio_iovcnt > (MV_CESA_MAX_MBUF_FRAGS - 1)) {
29075+ printk("%s,%d: %d uio_iovcnt > MV_CESA_MAX_MBUF_FRAGS \n", __FILE__, __LINE__, uiop->uio_iovcnt);
29076+ goto p_error;
29077+ }
29078+
29079+ p_mbuf_info->mbufSize = crp->crp_ilen;
29080+ p_mbuf_info->numFrags = uiop->uio_iovcnt;
29081+ for(i = 0; i < uiop->uio_iovcnt; i++) {
29082+ p_buf_info->bufVirtPtr = uiop->uio_iov[i].iov_base;
29083+ p_buf_info->bufSize = uiop->uio_iov[i].iov_len;
29084+ temp_len += p_buf_info->bufSize;
29085+ dprintk("%s,%d: buf %x-> addr %x, size %x \n"
29086+ , __FILE__, __LINE__, i, (unsigned int)p_buf_info->bufVirtPtr, p_buf_info->bufSize);
29087+ p_buf_info++;
29088+ }
29089+
29090+ }
29091+ /* handle CONTIG */
29092+ else {
29093+ dprintk("%s,%d: handle CONTIG.\n", __FILE__, __LINE__);
29094+ p_mbuf_info->numFrags = 1;
29095+ p_mbuf_info->mbufSize = crp->crp_ilen;
29096+ p_buf_info->bufVirtPtr = crp->crp_buf;
29097+ p_buf_info->bufSize = crp->crp_ilen;
29098+ temp_len = crp->crp_ilen;
29099+ p_buf_info++;
29100+ }
29101+
29102+ /* Support up to 64K why? cause! */
29103+ if(crp->crp_ilen > 64*1024) {
29104+ printk("%s,%d: buf too big %x \n", __FILE__, __LINE__, crp->crp_ilen);
29105+ goto p_error;
29106+ }
29107+
29108+ if( temp_len != crp->crp_ilen ) {
29109+ printk("%s,%d: warning size don't match.(%x %x) \n", __FILE__, __LINE__, temp_len, crp->crp_ilen);
29110+ }
29111+
29112+ cesa_cmd->pSrc = p_mbuf_info;
29113+ cesa_cmd->pDst = p_mbuf_info;
29114+
29115+ /* restore p_buf_info to point to first available buf */
29116+ p_buf_info = cesa_ocf_cmd->cesa_bufs;
29117+ p_buf_info += 1;
29118+
29119+
29120+ /* Go through crypto descriptors, processing as we go */
29121+ for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
29122+
29123+ /* Encryption /Decryption */
29124+ if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
29125+
29126+ dprintk("%s,%d: cipher", __FILE__, __LINE__);
29127+
29128+ cesa_cmd->cryptoOffset = crd->crd_skip;
29129+ cesa_cmd->cryptoLength = crd->crd_len;
29130+
29131+ if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
29132+ dprintk(" encrypt \n");
29133+ encrypt++;
29134+
29135+ /* handle IV */
29136+ if (crd->crd_flags & CRD_F_IV_EXPLICIT) { /* IV from USER */
29137+ dprintk("%s,%d: IV from USER (offset %x) \n", __FILE__, __LINE__, crd->crd_inject);
29138+ cesa_cmd->ivFromUser = 1;
29139+ ivp = crd->crd_iv;
29140+
29141+ /*
29142+ * do we have to copy the IV back to the buffer ?
29143+ */
29144+ if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
29145+ dprintk("%s,%d: copy the IV back to the buffer\n", __FILE__, __LINE__);
29146+ cesa_cmd->ivOffset = crd->crd_inject;
29147+ crypto_copy_bits_back(crp->crp_buf, crd->crd_inject, ivp, cesa_ocf_cur_ses->ivlen);
29148+ }
29149+ else {
29150+ dprintk("%s,%d: don't copy the IV back to the buffer \n", __FILE__, __LINE__);
29151+ p_mbuf_info->numFrags++;
29152+ p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
29153+ p_mbuf_info->pFrags = p_buf_info;
29154+
29155+ p_buf_info->bufVirtPtr = ivp;
29156+ p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
29157+ p_buf_info--;
29158+
29159+ /* offsets */
29160+ cesa_cmd->ivOffset = 0;
29161+ cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
29162+ if(auth) {
29163+ cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
29164+ cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
29165+ }
29166+ }
29167+ }
29168+ else { /* random IV */
29169+ dprintk("%s,%d: random IV \n", __FILE__, __LINE__);
29170+ cesa_cmd->ivFromUser = 0;
29171+
29172+ /*
29173+ * do we have to copy the IV back to the buffer ?
29174+ */
29175+ /* in this mode the HAL will always copy the IV */
29176+ /* given by the session to the ivOffset */
29177+ if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
29178+ cesa_cmd->ivOffset = crd->crd_inject;
29179+ }
29180+ else {
29181+ /* if IV isn't copy, then how will the user know which IV did we use??? */
29182+ printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
29183+ goto p_error;
29184+ }
29185+ }
29186+ }
29187+ else { /* decrypt */
29188+ dprintk(" decrypt \n");
29189+ decrypt++;
29190+ cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_decrypt;
29191+
29192+ /* handle IV */
29193+ if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
29194+ dprintk("%s,%d: IV from USER \n", __FILE__, __LINE__);
29195+ /* append the IV buf to the mbuf */
29196+ cesa_cmd->ivFromUser = 1;
29197+ p_mbuf_info->numFrags++;
29198+ p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
29199+ p_mbuf_info->pFrags = p_buf_info;
29200+
29201+ p_buf_info->bufVirtPtr = crd->crd_iv;
29202+ p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
29203+ p_buf_info--;
29204+
29205+ /* offsets */
29206+ cesa_cmd->ivOffset = 0;
29207+ cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
29208+ if(auth) {
29209+ cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
29210+ cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
29211+ }
29212+ }
29213+ else {
29214+ dprintk("%s,%d: IV inside the buffer \n", __FILE__, __LINE__);
29215+ cesa_cmd->ivFromUser = 0;
29216+ cesa_cmd->ivOffset = crd->crd_inject;
29217+ }
29218+ }
29219+
29220+ }
29221+ /* Authentication */
29222+ else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
29223+ dprintk("%s,%d: Authentication \n", __FILE__, __LINE__);
29224+ auth++;
29225+ cesa_cmd->macOffset = crd->crd_skip;
29226+ cesa_cmd->macLength = crd->crd_len;
29227+
29228+ /* digest + mac */
29229+ cesa_cmd->digestOffset = crd->crd_inject;
29230+ }
29231+ else {
29232+ printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
29233+ goto p_error;
29234+ }
29235+ }
29236+
29237+ dprintk("\n");
29238+ dprintk("%s,%d: Sending Action: \n", __FILE__, __LINE__);
29239+ dprintk("%s,%d: IV from user: %d. IV offset %x \n", __FILE__, __LINE__, cesa_cmd->ivFromUser, cesa_cmd->ivOffset);
29240+ dprintk("%s,%d: crypt offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->cryptoOffset, cesa_cmd->cryptoLength);
29241+ dprintk("%s,%d: Auth offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->macOffset, cesa_cmd->macLength);
29242+ dprintk("%s,%d: set digest in offset %x . \n", __FILE__, __LINE__, cesa_cmd->digestOffset);
29243+ if(debug) {
29244+ mvCesaDebugMbuf("SRC BUFFER", cesa_cmd->pSrc, 0, cesa_cmd->pSrc->mbufSize);
29245+ }
29246+
29247+
29248+ /* send action to HAL */
29249+ spin_lock_irqsave(&cesa_lock, flags);
29250+ status = mvCesaAction(cesa_cmd);
29251+ spin_unlock_irqrestore(&cesa_lock, flags);
29252+
29253+ /* action not allowed */
29254+ if(status == MV_NOT_ALLOWED) {
29255+#ifdef CESA_OCF_SPLIT
29256+ /* if both encrypt and auth try to split */
29257+ if(auth && (encrypt || decrypt)) {
29258+ MV_CESA_COMMAND *cesa_cmd_wa;
29259+
29260+ /* malloc a new cesa process and init it */
29261+ cesa_ocf_cmd_wa = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
29262+
29263+ if (cesa_ocf_cmd_wa == NULL) {
29264+ printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
29265+ goto p_error;
29266+ }
29267+ memcpy(cesa_ocf_cmd_wa, cesa_ocf_cmd, sizeof(struct cesa_ocf_process));
29268+ cesa_cmd_wa = &cesa_ocf_cmd_wa->cesa_cmd;
29269+ cesa_cmd_wa->pReqPrv = (void *)cesa_ocf_cmd_wa;
29270+ cesa_ocf_cmd_wa->need_cb = 0;
29271+
29272+ /* break requests to two operation, first operation completion won't call callback */
29273+ if((decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
29274+ cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
29275+ cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
29276+ }
29277+ else if((decrypt) && !(cesa_ocf_cur_ses->auth_tn_decrypt)) {
29278+ cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
29279+ cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
29280+ }
29281+ else if((encrypt) && (cesa_ocf_cur_ses->encrypt_tn_auth)) {
29282+ cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
29283+ cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
29284+ }
29285+ else if((encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)){
29286+ cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
29287+ cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
29288+ }
29289+ else {
29290+ printk("%s,%d: Unsupporterd fragment wa mode \n", __FILE__, __LINE__);
29291+ goto p_error;
29292+ }
29293+
29294+ /* send the 2 actions to the HAL */
29295+ spin_lock_irqsave(&cesa_lock, flags);
29296+ status = mvCesaAction(cesa_cmd_wa);
29297+ spin_unlock_irqrestore(&cesa_lock, flags);
29298+
29299+ if((status != MV_NO_MORE) && (status != MV_OK)) {
29300+ printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
29301+ goto p_error;
29302+ }
29303+ spin_lock_irqsave(&cesa_lock, flags);
29304+ status = mvCesaAction(cesa_cmd);
29305+ spin_unlock_irqrestore(&cesa_lock, flags);
29306+
29307+ }
29308+ /* action not allowed and can't split */
29309+ else
29310+#endif
29311+ {
29312+ goto p_error;
29313+ }
29314+ }
29315+
29316+ /* Hal Q is full, send again. This should never happen */
29317+ if(status == MV_NO_RESOURCE) {
29318+ printk("%s,%d: cesa no more resources \n", __FILE__, __LINE__);
29319+ if(cesa_ocf_cmd)
29320+ kfree(cesa_ocf_cmd);
29321+ if(cesa_ocf_cmd_wa)
29322+ kfree(cesa_ocf_cmd_wa);
29323+ return ERESTART;
29324+ }
29325+ else if((status != MV_NO_MORE) && (status != MV_OK)) {
29326+ printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
29327+ goto p_error;
29328+ }
29329+
29330+
29331+#ifdef CESA_OCF_POLLING
29332+ cesa_interrupt_polling();
29333+#endif
29334+ cesaTestTraceAdd(5);
29335+
29336+ return 0;
29337+p_error:
29338+ crp->crp_etype = EINVAL;
29339+ if(cesa_ocf_cmd)
29340+ kfree(cesa_ocf_cmd);
29341+ if(cesa_ocf_cmd_wa)
29342+ kfree(cesa_ocf_cmd_wa);
29343+ return EINVAL;
29344+}
29345+
29346+/*
29347+ * cesa callback.
29348+ */
29349+static void
29350+cesa_callback(unsigned long dummy)
29351+{
29352+ struct cesa_ocf_process *cesa_ocf_cmd = NULL;
29353+ struct cryptop *crp = NULL;
29354+ MV_CESA_RESULT result[MV_CESA_MAX_CHAN];
29355+ int res_idx = 0,i;
29356+ MV_STATUS status;
29357+
29358+ dprintk("%s()\n", __FUNCTION__);
29359+
29360+#ifdef CESA_OCF_TASKLET
29361+ disable_irq(cesa_device.irq);
29362+#endif
29363+ while(MV_TRUE) {
29364+
29365+ /* Get Ready requests */
29366+ spin_lock(&cesa_lock);
29367+ status = mvCesaReadyGet(&result[res_idx]);
29368+ spin_unlock(&cesa_lock);
29369+
29370+ cesaTestTraceAdd(2);
29371+
29372+ if(status != MV_OK) {
29373+#ifdef CESA_OCF_POLLING
29374+ if(status == MV_BUSY) { /* Fragment */
29375+ cesa_interrupt_polling();
29376+ return;
29377+ }
29378+#endif
29379+ break;
29380+ }
29381+ res_idx++;
29382+ break;
29383+ }
29384+
29385+ for(i = 0; i < res_idx; i++) {
29386+
29387+ if(!result[i].pReqPrv) {
29388+ printk("%s,%d: warning private is NULL\n", __FILE__, __LINE__);
29389+ break;
29390+ }
29391+
29392+ cesa_ocf_cmd = result[i].pReqPrv;
29393+ crp = cesa_ocf_cmd->crp;
29394+
29395+ // ignore HMAC error.
29396+ //if(result->retCode)
29397+ // crp->crp_etype = EIO;
29398+
29399+#if defined(CESA_OCF_POLLING)
29400+ if(!cesa_ocf_cmd->need_cb){
29401+ cesa_interrupt_polling();
29402+ }
29403+#endif
29404+ if(cesa_ocf_cmd->need_cb) {
29405+ if(debug) {
29406+ mvCesaDebugMbuf("DST BUFFER", cesa_ocf_cmd->cesa_cmd.pDst, 0, cesa_ocf_cmd->cesa_cmd.pDst->mbufSize);
29407+ }
29408+ crypto_done(crp);
29409+ }
29410+ kfree(cesa_ocf_cmd);
29411+ }
29412+#ifdef CESA_OCF_TASKLET
29413+ enable_irq(cesa_device.irq);
29414+#endif
29415+
29416+ cesaTestTraceAdd(3);
29417+
29418+ return;
29419+}
29420+
29421+#ifdef CESA_OCF_POLLING
29422+static void
29423+cesa_interrupt_polling(void)
29424+{
29425+ u32 cause;
29426+
29427+ dprintk("%s()\n", __FUNCTION__);
29428+
29429+ /* Read cause register */
29430+ do {
29431+ cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
29432+ cause &= MV_CESA_CAUSE_ACC_DMA_ALL_MASK;
29433+
29434+ } while (cause == 0);
29435+
29436+ /* clear interrupts */
29437+ MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
29438+
29439+ cesa_callback(0);
29440+
29441+ return;
29442+}
29443+
29444+#endif
29445+
29446+/*
29447+ * cesa Interrupt polling routine.
29448+ */
29449+static irqreturn_t
29450+cesa_interrupt_handler(int irq, void *arg)
29451+{
29452+ u32 cause;
29453+
29454+ dprintk("%s()\n", __FUNCTION__);
29455+
29456+ cesaTestTraceAdd(0);
29457+
29458+ /* Read cause register */
29459+ cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
29460+
29461+ if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)
29462+ {
29463+ /* Empty interrupt */
29464+ dprintk("%s,%d: cesaTestReadyIsr: cause=0x%x\n", __FILE__, __LINE__, cause);
29465+ return IRQ_HANDLED;
29466+ }
29467+
29468+ /* clear interrupts */
29469+ MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
29470+
29471+ cesaTestTraceAdd(1);
29472+#ifdef CESA_OCF_TASKLET
29473+ tasklet_hi_schedule(&cesa_ocf_tasklet);
29474+#else
29475+ cesa_callback(0);
29476+#endif
29477+ return IRQ_HANDLED;
29478+}
29479+
29480+/*
29481+ * Open a session.
29482+ */
29483+static int
29484+/*cesa_ocf_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)*/
29485+cesa_ocf_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
29486+{
29487+ u32 status = 0, i;
29488+ u32 count = 0, auth = 0, encrypt =0;
29489+ struct cesa_ocf_data *cesa_ocf_cur_ses;
29490+ MV_CESA_OPEN_SESSION cesa_session;
29491+ MV_CESA_OPEN_SESSION *cesa_ses = &cesa_session;
29492+
29493+
29494+ dprintk("%s()\n", __FUNCTION__);
29495+ if (sid == NULL || cri == NULL) {
29496+ printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
29497+ return EINVAL;
29498+ }
29499+
29500+ /* leave first empty like in other implementations */
29501+ for (i = 1; i < CESA_OCF_MAX_SES; i++) {
29502+ if (cesa_ocf_sessions[i] == NULL)
29503+ break;
29504+ }
29505+
29506+ if(i >= CESA_OCF_MAX_SES) {
29507+ printk("%s,%d: no more sessions \n", __FILE__, __LINE__);
29508+ return EINVAL;
29509+ }
29510+
29511+ cesa_ocf_sessions[i] = (struct cesa_ocf_data *) kmalloc(sizeof(struct cesa_ocf_data), GFP_ATOMIC);
29512+ if (cesa_ocf_sessions[i] == NULL) {
29513+ cesa_ocf_freesession(NULL, i);
29514+ printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
29515+ return ENOBUFS;
29516+ }
29517+ dprintk("%s,%d: new session %d \n", __FILE__, __LINE__, i);
29518+
29519+ *sid = i;
29520+ cesa_ocf_cur_ses = cesa_ocf_sessions[i];
29521+ memset(cesa_ocf_cur_ses, 0, sizeof(struct cesa_ocf_data));
29522+ cesa_ocf_cur_ses->sid_encrypt = -1;
29523+ cesa_ocf_cur_ses->sid_decrypt = -1;
29524+ cesa_ocf_cur_ses->frag_wa_encrypt = -1;
29525+ cesa_ocf_cur_ses->frag_wa_decrypt = -1;
29526+ cesa_ocf_cur_ses->frag_wa_auth = -1;
29527+
29528+ /* init the session */
29529+ memset(cesa_ses, 0, sizeof(MV_CESA_OPEN_SESSION));
29530+ count = 1;
29531+ while (cri) {
29532+ if(count > 2) {
29533+ printk("%s,%d: don't support more then 2 operations\n", __FILE__, __LINE__);
29534+ goto error;
29535+ }
29536+ switch (cri->cri_alg) {
29537+ case CRYPTO_AES_CBC:
29538+ dprintk("%s,%d: (%d) AES CBC \n", __FILE__, __LINE__, count);
29539+ cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
29540+ cesa_ocf_cur_ses->ivlen = MV_CESA_AES_BLOCK_SIZE;
29541+ cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_AES;
29542+ cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
29543+ if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
29544+ printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
29545+ goto error;
29546+ }
29547+ memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
29548+ dprintk("%s,%d: key length %d \n", __FILE__, __LINE__, cri->cri_klen/8);
29549+ cesa_ses->cryptoKeyLength = cri->cri_klen/8;
29550+ encrypt += count;
29551+ break;
29552+ case CRYPTO_3DES_CBC:
29553+ dprintk("%s,%d: (%d) 3DES CBC \n", __FILE__, __LINE__, count);
29554+ cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
29555+ cesa_ocf_cur_ses->ivlen = MV_CESA_3DES_BLOCK_SIZE;
29556+ cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_3DES;
29557+ cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
29558+ if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
29559+ printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
29560+ goto error;
29561+ }
29562+ memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
29563+ cesa_ses->cryptoKeyLength = cri->cri_klen/8;
29564+ encrypt += count;
29565+ break;
29566+ case CRYPTO_DES_CBC:
29567+ dprintk("%s,%d: (%d) DES CBC \n", __FILE__, __LINE__, count);
29568+ cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
29569+ cesa_ocf_cur_ses->ivlen = MV_CESA_DES_BLOCK_SIZE;
29570+ cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_DES;
29571+ cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
29572+ if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
29573+ printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
29574+ goto error;
29575+ }
29576+ memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
29577+ cesa_ses->cryptoKeyLength = cri->cri_klen/8;
29578+ encrypt += count;
29579+ break;
29580+ case CRYPTO_MD5:
29581+ case CRYPTO_MD5_HMAC:
29582+ dprintk("%s,%d: (%d) %sMD5 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_MD5)? "H-":" ");
29583+ cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
29584+ cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MD5_DIGEST_SIZE : 12;
29585+ cesa_ses->macMode = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MAC_MD5 : MV_CESA_MAC_HMAC_MD5;
29586+ if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
29587+ printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
29588+ goto error;
29589+ }
29590+ cesa_ses->macKeyLength = cri->cri_klen/8;
29591+ memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
29592+ cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
29593+ auth += count;
29594+ break;
29595+ case CRYPTO_SHA1:
29596+ case CRYPTO_SHA1_HMAC:
29597+ dprintk("%s,%d: (%d) %sSHA1 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_SHA1)? "H-":" ");
29598+ cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
29599+ cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_SHA1_DIGEST_SIZE : 12;
29600+ cesa_ses->macMode = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_MAC_SHA1 : MV_CESA_MAC_HMAC_SHA1;
29601+ if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
29602+ printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
29603+ goto error;
29604+ }
29605+ cesa_ses->macKeyLength = cri->cri_klen/8;
29606+ memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
29607+ cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
29608+ auth += count;
29609+ break;
29610+ default:
29611+ printk("%s,%d: unknown algo 0x%x\n", __FILE__, __LINE__, cri->cri_alg);
29612+ goto error;
29613+ }
29614+ cri = cri->cri_next;
29615+ count++;
29616+ }
29617+
29618+ if((encrypt > 2) || (auth > 2)) {
29619+ printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
29620+ goto error;
29621+ }
29622+ /* create new sessions in HAL */
29623+ if(encrypt) {
29624+ cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
29625+ /* encrypt session */
29626+ if(auth == 1) {
29627+ cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
29628+ }
29629+ else if(auth == 2) {
29630+ cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
29631+ cesa_ocf_cur_ses->encrypt_tn_auth = 1;
29632+ }
29633+ else {
29634+ cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
29635+ }
29636+ cesa_ses->direction = MV_CESA_DIR_ENCODE;
29637+ status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
29638+ if(status != MV_OK) {
29639+ printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
29640+ goto error;
29641+ }
29642+ /* decrypt session */
29643+ if( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) {
29644+ cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
29645+ }
29646+ else if( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC ) {
29647+ cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
29648+ }
29649+ cesa_ses->direction = MV_CESA_DIR_DECODE;
29650+ status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_decrypt);
29651+ if(status != MV_OK) {
29652+ printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
29653+ goto error;
29654+ }
29655+
29656+ /* preapre one action sessions for case we will need to split an action */
29657+#ifdef CESA_OCF_SPLIT
29658+ if(( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) ||
29659+ ( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC )) {
29660+ /* open one session for encode and one for decode */
29661+ cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
29662+ cesa_ses->direction = MV_CESA_DIR_ENCODE;
29663+ status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_encrypt);
29664+ if(status != MV_OK) {
29665+ printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
29666+ goto error;
29667+ }
29668+
29669+ cesa_ses->direction = MV_CESA_DIR_DECODE;
29670+ status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_decrypt);
29671+ if(status != MV_OK) {
29672+ printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
29673+ goto error;
29674+ }
29675+ /* open one session for auth */
29676+ cesa_ses->operation = MV_CESA_MAC_ONLY;
29677+ cesa_ses->direction = MV_CESA_DIR_ENCODE;
29678+ status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_auth);
29679+ if(status != MV_OK) {
29680+ printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
29681+ goto error;
29682+ }
29683+ }
29684+#endif
29685+ }
29686+ else { /* only auth */
29687+ cesa_ses->operation = MV_CESA_MAC_ONLY;
29688+ cesa_ses->direction = MV_CESA_DIR_ENCODE;
29689+ status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
29690+ if(status != MV_OK) {
29691+ printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
29692+ goto error;
29693+ }
29694+ }
29695+
29696+ return 0;
29697+error:
29698+ cesa_ocf_freesession(NULL, *sid);
29699+ return EINVAL;
29700+
29701+}
29702+
29703+
29704+/*
29705+ * Free a session.
29706+ */
29707+static int
29708+cesa_ocf_freesession(device_t dev, u_int64_t tid)
29709+{
29710+ struct cesa_ocf_data *cesa_ocf_cur_ses;
29711+ u_int32_t sid = CRYPTO_SESID2LID(tid);
29712+ //unsigned long flags;
29713+
29714+ dprintk("%s() %d \n", __FUNCTION__, sid);
29715+ if ( (sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL) ) {
29716+ printk("%s,%d: EINVAL can't free session %d \n", __FILE__, __LINE__, sid);
29717+ return(EINVAL);
29718+ }
29719+
29720+ /* Silently accept and return */
29721+ if (sid == 0)
29722+ return(0);
29723+
29724+ /* release session from HAL */
29725+ cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
29726+ if (cesa_ocf_cur_ses->sid_encrypt != -1) {
29727+ mvCesaSessionClose(cesa_ocf_cur_ses->sid_encrypt);
29728+ }
29729+ if (cesa_ocf_cur_ses->sid_decrypt != -1) {
29730+ mvCesaSessionClose(cesa_ocf_cur_ses->sid_decrypt);
29731+ }
29732+ if (cesa_ocf_cur_ses->frag_wa_encrypt != -1) {
29733+ mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_encrypt);
29734+ }
29735+ if (cesa_ocf_cur_ses->frag_wa_decrypt != -1) {
29736+ mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_decrypt);
29737+ }
29738+ if (cesa_ocf_cur_ses->frag_wa_auth != -1) {
29739+ mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_auth);
29740+ }
29741+
29742+ kfree(cesa_ocf_cur_ses);
29743+ cesa_ocf_sessions[sid] = NULL;
29744+
29745+ return 0;
29746+}
29747+
29748+
29749+/* TDMA Window setup */
29750+
29751+static void __init
29752+setup_tdma_mbus_windows(struct cesa_dev *dev)
29753+{
29754+ int i;
29755+
29756+ for (i = 0; i < 4; i++) {
29757+ writel(0, dev->reg + WINDOW_BASE(i));
29758+ writel(0, dev->reg + WINDOW_CTRL(i));
29759+ }
29760+
29761+ for (i = 0; i < dev->plat_data->dram->num_cs; i++) {
29762+ struct mbus_dram_window *cs = dev->plat_data->dram->cs + i;
29763+ writel(
29764+ ((cs->size - 1) & 0xffff0000) |
29765+ (cs->mbus_attr << 8) |
29766+ (dev->plat_data->dram->mbus_dram_target_id << 4) | 1,
29767+ dev->reg + WINDOW_CTRL(i)
29768+ );
29769+ writel(cs->base, dev->reg + WINDOW_BASE(i));
29770+ }
29771+}
29772+
29773+/*
29774+ * our driver startup and shutdown routines
29775+ */
29776+static int
29777+mv_cesa_ocf_init(struct platform_device *pdev)
29778+{
29779+#if defined(CONFIG_MV78200) || defined(CONFIG_MV632X)
29780+ if (MV_FALSE == mvSocUnitIsMappedToThisCpu(CESA))
29781+ {
29782+ dprintk("CESA is not mapped to this CPU\n");
29783+ return -ENODEV;
29784+ }
29785+#endif
29786+
29787+ dprintk("%s\n", __FUNCTION__);
29788+ memset(&mv_cesa_dev, 0, sizeof(mv_cesa_dev));
29789+ softc_device_init(&mv_cesa_dev, "MV CESA", 0, mv_cesa_methods);
29790+ cesa_ocf_id = crypto_get_driverid(softc_get_device(&mv_cesa_dev),CRYPTOCAP_F_HARDWARE);
29791+
29792+ if (cesa_ocf_id < 0)
29793+ panic("MV CESA crypto device cannot initialize!");
29794+
29795+ dprintk("%s,%d: cesa ocf device id is %d \n", __FILE__, __LINE__, cesa_ocf_id);
29796+
29797+ /* CESA unit is auto power on off */
29798+#if 0
29799+ if (MV_FALSE == mvCtrlPwrClckGet(CESA_UNIT_ID,0))
29800+ {
29801+ printk("\nWarning CESA %d is Powered Off\n",0);
29802+ return EINVAL;
29803+ }
29804+#endif
29805+
29806+ memset(&cesa_device, 0, sizeof(struct cesa_dev));
29807+ /* Get the IRQ, and crypto memory regions */
29808+ {
29809+ struct resource *res;
29810+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
29811+
29812+ if (!res)
29813+ return -ENXIO;
29814+
29815+ cesa_device.sram = ioremap(res->start, res->end - res->start + 1);
29816+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
29817+
29818+ if (!res) {
29819+ iounmap(cesa_device.sram);
29820+ return -ENXIO;
29821+ }
29822+ cesa_device.reg = ioremap(res->start, res->end - res->start + 1);
29823+ cesa_device.irq = platform_get_irq(pdev, 0);
29824+ cesa_device.plat_data = pdev->dev.platform_data;
29825+ setup_tdma_mbus_windows(&cesa_device);
29826+
29827+ }
29828+
29829+
29830+ if( MV_OK != mvCesaInit(CESA_OCF_MAX_SES*5, CESA_Q_SIZE, cesa_device.reg,
29831+ NULL) ) {
29832+ printk("%s,%d: mvCesaInit Failed. \n", __FILE__, __LINE__);
29833+ return EINVAL;
29834+ }
29835+
29836+ /* clear and unmask Int */
29837+ MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
29838+#ifndef CESA_OCF_POLLING
29839+ MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);
29840+#endif
29841+#ifdef CESA_OCF_TASKLET
29842+ tasklet_init(&cesa_ocf_tasklet, cesa_callback, (unsigned int) 0);
29843+#endif
29844+ /* register interrupt */
29845+ if( request_irq( cesa_device.irq, cesa_interrupt_handler,
29846+ (IRQF_DISABLED) , "cesa", &cesa_ocf_id) < 0) {
29847+ printk("%s,%d: cannot assign irq %x\n", __FILE__, __LINE__, cesa_device.reg);
29848+ return EINVAL;
29849+ }
29850+
29851+
29852+ memset(cesa_ocf_sessions, 0, sizeof(struct cesa_ocf_data *) * CESA_OCF_MAX_SES);
29853+
29854+#define REGISTER(alg) \
29855+ crypto_register(cesa_ocf_id, alg, 0,0)
29856+ REGISTER(CRYPTO_AES_CBC);
29857+ REGISTER(CRYPTO_DES_CBC);
29858+ REGISTER(CRYPTO_3DES_CBC);
29859+ REGISTER(CRYPTO_MD5);
29860+ REGISTER(CRYPTO_MD5_HMAC);
29861+ REGISTER(CRYPTO_SHA1);
29862+ REGISTER(CRYPTO_SHA1_HMAC);
29863+#undef REGISTER
29864+
29865+ return 0;
29866+}
29867+
29868+static void
29869+mv_cesa_ocf_exit(struct platform_device *pdev)
29870+{
29871+ dprintk("%s()\n", __FUNCTION__);
29872+
29873+ crypto_unregister_all(cesa_ocf_id);
29874+ cesa_ocf_id = -1;
29875+ iounmap(cesa_device.reg);
29876+ iounmap(cesa_device.sram);
29877+ free_irq(cesa_device.irq, NULL);
29878+
29879+ /* mask and clear Int */
29880+ MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
29881+ MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
29882+
29883+
29884+ if( MV_OK != mvCesaFinish() ) {
29885+ printk("%s,%d: mvCesaFinish Failed. \n", __FILE__, __LINE__);
29886+ return;
29887+ }
29888+}
29889+
29890+
29891+void cesa_ocf_debug(void)
29892+{
29893+
29894+#ifdef CESA_OCF_TRACE_DEBUG
29895+ {
29896+ int i, j;
29897+ j = cesaTestTraceIdx;
29898+ mvOsPrintf("No Type rCause iCause Proc Isr Res Time pReady pProc pEmpty\n");
29899+ for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)
29900+ {
29901+ mvOsPrintf("%02d. %d 0x%04x 0x%04x 0x%02x 0x%02x %02d 0x%06x %p %p %p\n",
29902+ j, cesaTestTrace[j].type, cesaTestTrace[j].realCause,
29903+ cesaTestTrace[j].idmaCause,
29904+ cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,
29905+ cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);
29906+ j++;
29907+ if(j == MV_CESA_TEST_TRACE_SIZE)
29908+ j = 0;
29909+ }
29910+ }
29911+#endif
29912+
29913+}
29914+
29915+static struct platform_driver marvell_cesa = {
29916+ .probe = mv_cesa_ocf_init,
29917+ .remove = mv_cesa_ocf_exit,
29918+ .driver = {
29919+ .owner = THIS_MODULE,
29920+ .name = "mv_crypto",
29921+ },
29922+};
29923+
29924+MODULE_ALIAS("platform:mv_crypto");
29925+
29926+static int __init mv_cesa_init(void)
29927+{
29928+ return platform_driver_register(&marvell_cesa);
29929+}
29930+
29931+module_init(mv_cesa_init);
29932+
29933+static void __exit mv_cesa_exit(void)
29934+{
29935+ platform_driver_unregister(&marvell_cesa);
29936+}
29937+
29938+module_exit(mv_cesa_exit);
29939+
29940+MODULE_LICENSE("GPL");
29941+MODULE_AUTHOR("Ronen Shitrit");
29942+MODULE_DESCRIPTION("OCF module for Orion CESA crypto");
29943diff --git a/crypto/ocf/kirkwood/mvHal/common/mv802_3.h b/crypto/ocf/kirkwood/mvHal/common/mv802_3.h
29944new file mode 100644
29945index 0000000..b03cdbd
29946--- /dev/null
29947+++ b/crypto/ocf/kirkwood/mvHal/common/mv802_3.h
29948@@ -0,0 +1,213 @@
29949+/*******************************************************************************
29950+Copyright (C) Marvell International Ltd. and its affiliates
29951+
29952+This software file (the "File") is owned and distributed by Marvell
29953+International Ltd. and/or its affiliates ("Marvell") under the following
29954+alternative licensing terms. Once you have made an election to distribute the
29955+File under one of the following license alternatives, please (i) delete this
29956+introductory statement regarding license alternatives, (ii) delete the two
29957+license alternatives that you have not elected to use and (iii) preserve the
29958+Marvell copyright notice above.
29959+
29960+********************************************************************************
29961+Marvell Commercial License Option
29962+
29963+If you received this File from Marvell and you have entered into a commercial
29964+license agreement (a "Commercial License") with Marvell, the File is licensed
29965+to you under the terms of the applicable Commercial License.
29966+
29967+********************************************************************************
29968+Marvell GPL License Option
29969+
29970+If you received this File from Marvell, you may opt to use, redistribute and/or
29971+modify this File in accordance with the terms and conditions of the General
29972+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
29973+available along with the File in the license.txt file or by writing to the Free
29974+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
29975+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
29976+
29977+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
29978+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
29979+DISCLAIMED. The GPL License provides additional details about this warranty
29980+disclaimer.
29981+********************************************************************************
29982+Marvell BSD License Option
29983+
29984+If you received this File from Marvell, you may opt to use, redistribute and/or
29985+modify this File under the following licensing terms.
29986+Redistribution and use in source and binary forms, with or without modification,
29987+are permitted provided that the following conditions are met:
29988+
29989+ * Redistributions of source code must retain the above copyright notice,
29990+ this list of conditions and the following disclaimer.
29991+
29992+ * Redistributions in binary form must reproduce the above copyright
29993+ notice, this list of conditions and the following disclaimer in the
29994+ documentation and/or other materials provided with the distribution.
29995+
29996+ * Neither the name of Marvell nor the names of its contributors may be
29997+ used to endorse or promote products derived from this software without
29998+ specific prior written permission.
29999+
30000+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
30001+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30002+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30003+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
30004+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30005+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30006+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30007+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30008+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30009+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30010+
30011+*******************************************************************************/
30012+
30013+
30014+#ifndef __INCmv802_3h
30015+#define __INCmv802_3h
30016+
30017+
30018+/* includes */
30019+#include "mvTypes.h"
30020+
30021+/* Defines */
30022+#define MV_MAX_ETH_DATA 1500
30023+
30024+/* 802.3 types */
30025+#define MV_IP_TYPE 0x0800
30026+#define MV_IP_ARP_TYPE 0x0806
30027+#define MV_APPLE_TALK_ARP_TYPE 0x80F3
30028+#define MV_NOVELL_IPX_TYPE 0x8137
30029+#define MV_EAPOL_TYPE 0x888e
30030+
30031+
30032+
30033+/* Encapsulation header for RFC1042 and Ethernet_tunnel */
30034+
30035+#define MV_RFC1042_SNAP_HEADER {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}
30036+
30037+#define MV_ETH_SNAP_LSB 0xF8
30038+
30039+
30040+#define MV_MAC_ADDR_SIZE (6)
30041+#define MV_MAC_STR_SIZE (20)
30042+#define MV_VLAN_HLEN (4)
30043+
30044+/* This macro checks for a multicast mac address */
30045+#define MV_IS_MULTICAST_MAC(mac) (((mac)[0] & 0x1) == 1)
30046+
30047+
30048+/* This macro checks for an broadcast mac address */
30049+#define MV_IS_BROADCAST_MAC(mac) \
30050+ (((mac)[0] == 0xFF) && \
30051+ ((mac)[1] == 0xFF) && \
30052+ ((mac)[2] == 0xFF) && \
30053+ ((mac)[3] == 0xFF) && \
30054+ ((mac)[4] == 0xFF) && \
30055+ ((mac)[5] == 0xFF))
30056+
30057+
30058+/* Typedefs */
30059+typedef struct
30060+{
30061+ MV_U8 pDA[MV_MAC_ADDR_SIZE];
30062+ MV_U8 pSA[MV_MAC_ADDR_SIZE];
30063+ MV_U16 typeOrLen;
30064+
30065+} MV_802_3_HEADER;
30066+
30067+enum {
30068+ MV_IP_PROTO_NULL = 0, /* Dummy protocol for TCP */
30069+ MV_IP_PROTO_ICMP = 1, /* Internet Control Message Protocol */
30070+ MV_IP_PROTO_IGMP = 2, /* Internet Group Management Protocol */
30071+ MV_IP_PROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
30072+ MV_IP_PROTO_TCP = 6, /* Transmission Control Protocol */
30073+ MV_IP_PROTO_EGP = 8, /* Exterior Gateway Protocol */
30074+ MV_IP_PROTO_PUP = 12, /* PUP protocol */
30075+ MV_IP_PROTO_UDP = 17, /* User Datagram Protocol */
30076+ MV_IP_PROTO_IDP = 22, /* XNS IDP protocol */
30077+ MV_IP_PROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
30078+ MV_IP_PROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
30079+ MV_IP_PROTO_RSVP = 46, /* RSVP protocol */
30080+ MV_IP_PROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
30081+ MV_IP_PROTO_ESP = 50, /* Encapsulation Security Payload protocol */
30082+ MV_IP_PROTO_AH = 51, /* Authentication Header protocol */
30083+ MV_IP_PROTO_BEETPH = 94, /* IP option pseudo header for BEET */
30084+ MV_IP_PROTO_PIM = 103,
30085+ MV_IP_PROTO_COMP = 108, /* Compression Header protocol */
30086+ MV_IP_PROTO_ZERO_HOP = 114, /* Any 0 hop protocol (IANA) */
30087+ MV_IP_PROTO_SCTP = 132, /* Stream Control Transport Protocol */
30088+ MV_IP_PROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
30089+
30090+ MV_IP_PROTO_RAW = 255, /* Raw IP packets */
30091+ MV_IP_PROTO_MAX
30092+};
30093+
30094+typedef struct
30095+{
30096+ MV_U8 version;
30097+ MV_U8 tos;
30098+ MV_U16 totalLength;
30099+ MV_U16 identifier;
30100+ MV_U16 fragmentCtrl;
30101+ MV_U8 ttl;
30102+ MV_U8 protocol;
30103+ MV_U16 checksum;
30104+ MV_U32 srcIP;
30105+ MV_U32 dstIP;
30106+
30107+} MV_IP_HEADER;
30108+
30109+typedef struct
30110+{
30111+ MV_U32 spi;
30112+ MV_U32 seqNum;
30113+} MV_ESP_HEADER;
30114+
30115+#define MV_ICMP_ECHOREPLY 0 /* Echo Reply */
30116+#define MV_ICMP_DEST_UNREACH 3 /* Destination Unreachable */
30117+#define MV_ICMP_SOURCE_QUENCH 4 /* Source Quench */
30118+#define MV_ICMP_REDIRECT 5 /* Redirect (change route) */
30119+#define MV_ICMP_ECHO 8 /* Echo Request */
30120+#define MV_ICMP_TIME_EXCEEDED 11 /* Time Exceeded */
30121+#define MV_ICMP_PARAMETERPROB 12 /* Parameter Problem */
30122+#define MV_ICMP_TIMESTAMP 13 /* Timestamp Request */
30123+#define MV_ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */
30124+#define MV_ICMP_INFO_REQUEST 15 /* Information Request */
30125+#define MV_ICMP_INFO_REPLY 16 /* Information Reply */
30126+#define MV_ICMP_ADDRESS 17 /* Address Mask Request */
30127+#define MV_ICMP_ADDRESSREPLY 18 /* Address Mask Reply */
30128+
30129+typedef struct
30130+{
30131+ MV_U8 type;
30132+ MV_U8 code;
30133+ MV_U16 checksum;
30134+ MV_U16 id;
30135+ MV_U16 sequence;
30136+
30137+} MV_ICMP_ECHO_HEADER;
30138+
30139+typedef struct
30140+{
30141+ MV_U16 source;
30142+ MV_U16 dest;
30143+ MV_U32 seq;
30144+ MV_U32 ack_seq;
30145+ MV_U16 flags;
30146+ MV_U16 window;
30147+ MV_U16 chksum;
30148+ MV_U16 urg_offset;
30149+
30150+} MV_TCP_HEADER;
30151+
30152+typedef struct
30153+{
30154+ MV_U16 source;
30155+ MV_U16 dest;
30156+ MV_U16 len;
30157+ MV_U16 check;
30158+
30159+} MV_UDP_HEADER;
30160+
30161+#endif /* __INCmv802_3h */
30162diff --git a/crypto/ocf/kirkwood/mvHal/common/mvCommon.c b/crypto/ocf/kirkwood/mvHal/common/mvCommon.c
30163new file mode 100644
30164index 0000000..ecb41a8
30165--- /dev/null
30166+++ b/crypto/ocf/kirkwood/mvHal/common/mvCommon.c
30167@@ -0,0 +1,277 @@
30168+/*******************************************************************************
30169+Copyright (C) Marvell International Ltd. and its affiliates
30170+
30171+This software file (the "File") is owned and distributed by Marvell
30172+International Ltd. and/or its affiliates ("Marvell") under the following
30173+alternative licensing terms. Once you have made an election to distribute the
30174+File under one of the following license alternatives, please (i) delete this
30175+introductory statement regarding license alternatives, (ii) delete the two
30176+license alternatives that you have not elected to use and (iii) preserve the
30177+Marvell copyright notice above.
30178+
30179+********************************************************************************
30180+Marvell Commercial License Option
30181+
30182+If you received this File from Marvell and you have entered into a commercial
30183+license agreement (a "Commercial License") with Marvell, the File is licensed
30184+to you under the terms of the applicable Commercial License.
30185+
30186+********************************************************************************
30187+Marvell GPL License Option
30188+
30189+If you received this File from Marvell, you may opt to use, redistribute and/or
30190+modify this File in accordance with the terms and conditions of the General
30191+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
30192+available along with the File in the license.txt file or by writing to the Free
30193+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
30194+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
30195+
30196+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
30197+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
30198+DISCLAIMED. The GPL License provides additional details about this warranty
30199+disclaimer.
30200+********************************************************************************
30201+Marvell BSD License Option
30202+
30203+If you received this File from Marvell, you may opt to use, redistribute and/or
30204+modify this File under the following licensing terms.
30205+Redistribution and use in source and binary forms, with or without modification,
30206+are permitted provided that the following conditions are met:
30207+
30208+ * Redistributions of source code must retain the above copyright notice,
30209+ this list of conditions and the following disclaimer.
30210+
30211+ * Redistributions in binary form must reproduce the above copyright
30212+ notice, this list of conditions and the following disclaimer in the
30213+ documentation and/or other materials provided with the distribution.
30214+
30215+ * Neither the name of Marvell nor the names of its contributors may be
30216+ used to endorse or promote products derived from this software without
30217+ specific prior written permission.
30218+
30219+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
30220+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30221+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30222+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
30223+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30224+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30225+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30226+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30227+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30228+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30229+
30230+*******************************************************************************/
30231+
30232+#include "mvOs.h"
30233+#include "mv802_3.h"
30234+#include "mvCommon.h"
30235+
30236+
30237+/*******************************************************************************
30238+* mvMacStrToHex - Convert MAC format string to hex.
30239+*
30240+* DESCRIPTION:
30241+* This function convert MAC format string to hex.
30242+*
30243+* INPUT:
30244+* macStr - MAC address string. Fornat of address string is
30245+* uu:vv:ww:xx:yy:zz, where ":" can be any delimiter.
30246+*
30247+* OUTPUT:
30248+* macHex - MAC in hex format.
30249+*
30250+* RETURN:
30251+* None.
30252+*
30253+*******************************************************************************/
30254+MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex)
30255+{
30256+ int i;
30257+ char tmp[3];
30258+
30259+ for(i = 0; i < MV_MAC_ADDR_SIZE; i++)
30260+ {
30261+ tmp[0] = macStr[(i * 3) + 0];
30262+ tmp[1] = macStr[(i * 3) + 1];
30263+ tmp[2] = '\0';
30264+ macHex[i] = (MV_U8) (strtol(tmp, NULL, 16));
30265+ }
30266+ return MV_OK;
30267+}
30268+
30269+/*******************************************************************************
30270+* mvMacHexToStr - Convert MAC in hex format to string format.
30271+*
30272+* DESCRIPTION:
30273+* This function convert MAC in hex format to string format.
30274+*
30275+* INPUT:
30276+* macHex - MAC in hex format.
30277+*
30278+* OUTPUT:
30279+* macStr - MAC address string. String format is uu:vv:ww:xx:yy:zz.
30280+*
30281+* RETURN:
30282+* None.
30283+*
30284+*******************************************************************************/
30285+MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr)
30286+{
30287+ int i;
30288+
30289+ for(i = 0; i < MV_MAC_ADDR_SIZE; i++)
30290+ {
30291+ mvOsSPrintf(&macStr[i * 3], "%02x:", macHex[i]);
30292+ }
30293+ macStr[(i * 3) - 1] = '\0';
30294+
30295+ return MV_OK;
30296+}
30297+
30298+/*******************************************************************************
30299+* mvSizePrint - Print the given size with size unit description.
30300+*
30301+* DESCRIPTION:
30302+* This function print the given size with size unit description.
30303+* FOr example when size paramter is 0x180000, the function prints:
30304+* "size 1MB+500KB"
30305+*
30306+* INPUT:
30307+* size - Size in bytes.
30308+*
30309+* OUTPUT:
30310+* None.
30311+*
30312+* RETURN:
30313+* None.
30314+*
30315+*******************************************************************************/
30316+MV_VOID mvSizePrint(MV_U32 size)
30317+{
30318+ mvOsOutput("size ");
30319+
30320+ if(size >= _1G)
30321+ {
30322+ mvOsOutput("%3dGB ", size / _1G);
30323+ size %= _1G;
30324+ if(size)
30325+ mvOsOutput("+");
30326+ }
30327+ if(size >= _1M )
30328+ {
30329+ mvOsOutput("%3dMB ", size / _1M);
30330+ size %= _1M;
30331+ if(size)
30332+ mvOsOutput("+");
30333+ }
30334+ if(size >= _1K)
30335+ {
30336+ mvOsOutput("%3dKB ", size / _1K);
30337+ size %= _1K;
30338+ if(size)
30339+ mvOsOutput("+");
30340+ }
30341+ if(size > 0)
30342+ {
30343+ mvOsOutput("%3dB ", size);
30344+ }
30345+}
30346+
30347+/*******************************************************************************
30348+* mvHexToBin - Convert hex to binary
30349+*
30350+* DESCRIPTION:
30351+* This function Convert hex to binary.
30352+*
30353+* INPUT:
30354+* pHexStr - hex buffer pointer.
30355+* size - Size to convert.
30356+*
30357+* OUTPUT:
30358+* pBin - Binary buffer pointer.
30359+*
30360+* RETURN:
30361+* None.
30362+*
30363+*******************************************************************************/
30364+MV_VOID mvHexToBin(const char* pHexStr, MV_U8* pBin, int size)
30365+{
30366+ int j, i;
30367+ char tmp[3];
30368+ MV_U8 byte;
30369+
30370+ for(j=0, i=0; j<size; j++, i+=2)
30371+ {
30372+ tmp[0] = pHexStr[i];
30373+ tmp[1] = pHexStr[i+1];
30374+ tmp[2] = '\0';
30375+ byte = (MV_U8) (strtol(tmp, NULL, 16) & 0xFF);
30376+ pBin[j] = byte;
30377+ }
30378+}
30379+
30380+void mvAsciiToHex(const char* asciiStr, char* hexStr)
30381+{
30382+ int i=0;
30383+
30384+ while(asciiStr[i] != 0)
30385+ {
30386+ mvOsSPrintf(&hexStr[i*2], "%02x", asciiStr[i]);
30387+ i++;
30388+ }
30389+ hexStr[i*2] = 0;
30390+}
30391+
30392+
30393+void mvBinToHex(const MV_U8* bin, char* hexStr, int size)
30394+{
30395+ int i;
30396+
30397+ for(i=0; i<size; i++)
30398+ {
30399+ mvOsSPrintf(&hexStr[i*2], "%02x", bin[i]);
30400+ }
30401+ hexStr[i*2] = '\0';
30402+}
30403+
30404+void mvBinToAscii(const MV_U8* bin, char* asciiStr, int size)
30405+{
30406+ int i;
30407+
30408+ for(i=0; i<size; i++)
30409+ {
30410+ mvOsSPrintf(&asciiStr[i*2], "%c", bin[i]);
30411+ }
30412+ asciiStr[i*2] = '\0';
30413+}
30414+
30415+/*******************************************************************************
30416+* mvLog2 -
30417+*
30418+* DESCRIPTION:
30419+* Calculate the Log2 of a given number.
30420+*
30421+* INPUT:
30422+* num - A number to calculate the Log2 for.
30423+*
30424+* OUTPUT:
30425+* None.
30426+*
30427+* RETURN:
30428+* Log 2 of the input number, or 0xFFFFFFFF if input is 0.
30429+*
30430+*******************************************************************************/
30431+MV_U32 mvLog2(MV_U32 num)
30432+{
30433+ MV_U32 result = 0;
30434+ if(num == 0)
30435+ return 0xFFFFFFFF;
30436+ while(num != 1)
30437+ {
30438+ num = num >> 1;
30439+ result++;
30440+ }
30441+ return result;
30442+}
30443+
30444+
30445diff --git a/crypto/ocf/kirkwood/mvHal/common/mvCommon.h b/crypto/ocf/kirkwood/mvHal/common/mvCommon.h
30446new file mode 100644
30447index 0000000..5caf47c
30448--- /dev/null
30449+++ b/crypto/ocf/kirkwood/mvHal/common/mvCommon.h
30450@@ -0,0 +1,308 @@
30451+/*******************************************************************************
30452+Copyright (C) Marvell International Ltd. and its affiliates
30453+
30454+This software file (the "File") is owned and distributed by Marvell
30455+International Ltd. and/or its affiliates ("Marvell") under the following
30456+alternative licensing terms. Once you have made an election to distribute the
30457+File under one of the following license alternatives, please (i) delete this
30458+introductory statement regarding license alternatives, (ii) delete the two
30459+license alternatives that you have not elected to use and (iii) preserve the
30460+Marvell copyright notice above.
30461+
30462+********************************************************************************
30463+Marvell Commercial License Option
30464+
30465+If you received this File from Marvell and you have entered into a commercial
30466+license agreement (a "Commercial License") with Marvell, the File is licensed
30467+to you under the terms of the applicable Commercial License.
30468+
30469+********************************************************************************
30470+Marvell GPL License Option
30471+
30472+If you received this File from Marvell, you may opt to use, redistribute and/or
30473+modify this File in accordance with the terms and conditions of the General
30474+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
30475+available along with the File in the license.txt file or by writing to the Free
30476+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
30477+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
30478+
30479+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
30480+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
30481+DISCLAIMED. The GPL License provides additional details about this warranty
30482+disclaimer.
30483+********************************************************************************
30484+Marvell BSD License Option
30485+
30486+If you received this File from Marvell, you may opt to use, redistribute and/or
30487+modify this File under the following licensing terms.
30488+Redistribution and use in source and binary forms, with or without modification,
30489+are permitted provided that the following conditions are met:
30490+
30491+ * Redistributions of source code must retain the above copyright notice,
30492+ this list of conditions and the following disclaimer.
30493+
30494+ * Redistributions in binary form must reproduce the above copyright
30495+ notice, this list of conditions and the following disclaimer in the
30496+ documentation and/or other materials provided with the distribution.
30497+
30498+ * Neither the name of Marvell nor the names of its contributors may be
30499+ used to endorse or promote products derived from this software without
30500+ specific prior written permission.
30501+
30502+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
30503+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30504+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30505+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
30506+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30507+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30508+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30509+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30510+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30511+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30512+
30513+*******************************************************************************/
30514+
30515+
30516+
30517+#ifndef __INCmvCommonh
30518+#define __INCmvCommonh
30519+
30520+#include "mvTypes.h"
30521+
30522+/* Swap tool */
30523+
30524+/* 16bit nibble swap. For example 0x1234 -> 0x2143 */
30525+#define MV_NIBBLE_SWAP_16BIT(X) (((X&0xf) << 4) | \
30526+ ((X&0xf0) >> 4) | \
30527+ ((X&0xf00) << 4) | \
30528+ ((X&0xf000) >> 4))
30529+
30530+/* 32bit nibble swap. For example 0x12345678 -> 0x21436587 */
30531+#define MV_NIBBLE_SWAP_32BIT(X) (((X&0xf) << 4) | \
30532+ ((X&0xf0) >> 4) | \
30533+ ((X&0xf00) << 4) | \
30534+ ((X&0xf000) >> 4) | \
30535+ ((X&0xf0000) << 4) | \
30536+ ((X&0xf00000) >> 4) | \
30537+ ((X&0xf000000) << 4) | \
30538+ ((X&0xf0000000) >> 4))
30539+
30540+/* 16bit byte swap. For example 0x1122 -> 0x2211 */
30541+#define MV_BYTE_SWAP_16BIT(X) ((((X)&0xff)<<8) | (((X)&0xff00)>>8))
30542+
30543+/* 32bit byte swap. For example 0x11223344 -> 0x44332211 */
30544+#define MV_BYTE_SWAP_32BIT(X) ((((X)&0xff)<<24) | \
30545+ (((X)&0xff00)<<8) | \
30546+ (((X)&0xff0000)>>8) | \
30547+ (((X)&0xff000000)>>24))
30548+
30549+/* 64bit byte swap. For example 0x11223344.55667788 -> 0x88776655.44332211 */
30550+#define MV_BYTE_SWAP_64BIT(X) ((l64) ((((X)&0xffULL)<<56) | \
30551+ (((X)&0xff00ULL)<<40) | \
30552+ (((X)&0xff0000ULL)<<24) | \
30553+ (((X)&0xff000000ULL)<<8) | \
30554+ (((X)&0xff00000000ULL)>>8) | \
30555+ (((X)&0xff0000000000ULL)>>24) | \
30556+ (((X)&0xff000000000000ULL)>>40) | \
30557+ (((X)&0xff00000000000000ULL)>>56)))
30558+
30559+/* Endianess macros. */
30560+#if defined(MV_CPU_LE)
30561+ #define MV_16BIT_LE(X) (X)
30562+ #define MV_32BIT_LE(X) (X)
30563+ #define MV_64BIT_LE(X) (X)
30564+ #define MV_16BIT_BE(X) MV_BYTE_SWAP_16BIT(X)
30565+ #define MV_32BIT_BE(X) MV_BYTE_SWAP_32BIT(X)
30566+ #define MV_64BIT_BE(X) MV_BYTE_SWAP_64BIT(X)
30567+#elif defined(MV_CPU_BE)
30568+ #define MV_16BIT_LE(X) MV_BYTE_SWAP_16BIT(X)
30569+ #define MV_32BIT_LE(X) MV_BYTE_SWAP_32BIT(X)
30570+ #define MV_64BIT_LE(X) MV_BYTE_SWAP_64BIT(X)
30571+ #define MV_16BIT_BE(X) (X)
30572+ #define MV_32BIT_BE(X) (X)
30573+ #define MV_64BIT_BE(X) (X)
30574+#else
30575+ #error "CPU endianess isn't defined!\n"
30576+#endif
30577+
30578+
30579+/* Bit field definitions */
30580+#define NO_BIT 0x00000000
30581+#define BIT0 0x00000001
30582+#define BIT1 0x00000002
30583+#define BIT2 0x00000004
30584+#define BIT3 0x00000008
30585+#define BIT4 0x00000010
30586+#define BIT5 0x00000020
30587+#define BIT6 0x00000040
30588+#define BIT7 0x00000080
30589+#define BIT8 0x00000100
30590+#define BIT9 0x00000200
30591+#define BIT10 0x00000400
30592+#define BIT11 0x00000800
30593+#define BIT12 0x00001000
30594+#define BIT13 0x00002000
30595+#define BIT14 0x00004000
30596+#define BIT15 0x00008000
30597+#define BIT16 0x00010000
30598+#define BIT17 0x00020000
30599+#define BIT18 0x00040000
30600+#define BIT19 0x00080000
30601+#define BIT20 0x00100000
30602+#define BIT21 0x00200000
30603+#define BIT22 0x00400000
30604+#define BIT23 0x00800000
30605+#define BIT24 0x01000000
30606+#define BIT25 0x02000000
30607+#define BIT26 0x04000000
30608+#define BIT27 0x08000000
30609+#define BIT28 0x10000000
30610+#define BIT29 0x20000000
30611+#define BIT30 0x40000000
30612+#define BIT31 0x80000000
30613+
30614+/* Handy sizes */
30615+#define _1K 0x00000400
30616+#define _2K 0x00000800
30617+#define _4K 0x00001000
30618+#define _8K 0x00002000
30619+#define _16K 0x00004000
30620+#define _32K 0x00008000
30621+#define _64K 0x00010000
30622+#define _128K 0x00020000
30623+#define _256K 0x00040000
30624+#define _512K 0x00080000
30625+
30626+#define _1M 0x00100000
30627+#define _2M 0x00200000
30628+#define _4M 0x00400000
30629+#define _8M 0x00800000
30630+#define _16M 0x01000000
30631+#define _32M 0x02000000
30632+#define _64M 0x04000000
30633+#define _128M 0x08000000
30634+#define _256M 0x10000000
30635+#define _512M 0x20000000
30636+
30637+#define _1G 0x40000000
30638+#define _2G 0x80000000
30639+
30640+/* Tclock and Sys clock define */
30641+#define _100MHz 100000000
30642+#define _125MHz 125000000
30643+#define _133MHz 133333334
30644+#define _150MHz 150000000
30645+#define _160MHz 160000000
30646+#define _166MHz 166666667
30647+#define _175MHz 175000000
30648+#define _178MHz 178000000
30649+#define _183MHz 183333334
30650+#define _187MHz 187000000
30651+#define _192MHz 192000000
30652+#define _194MHz 194000000
30653+#define _200MHz 200000000
30654+#define _233MHz 233333334
30655+#define _250MHz 250000000
30656+#define _266MHz 266666667
30657+#define _300MHz 300000000
30658+
30659+/* For better address window table readability */
30660+#define EN MV_TRUE
30661+#define DIS MV_FALSE
30662+#define N_A -1 /* Not applicable */
30663+
30664+/* Cache configuration options for memory (DRAM, SRAM, ... ) */
30665+
30666+/* Memory uncached, HW or SW cache coherency is not needed */
30667+#define MV_UNCACHED 0
30668+/* Memory cached, HW cache coherency supported in WriteThrough mode */
30669+#define MV_CACHE_COHER_HW_WT 1
30670+/* Memory cached, HW cache coherency supported in WriteBack mode */
30671+#define MV_CACHE_COHER_HW_WB 2
30672+/* Memory cached, No HW cache coherency, Cache coherency must be in SW */
30673+#define MV_CACHE_COHER_SW 3
30674+
30675+
30676+/* Macro for testing aligment. Positive if number is NOT aligned */
30677+#define MV_IS_NOT_ALIGN(number, align) ((number) & ((align) - 1))
30678+
30679+/* Macro for alignment up. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0340 */
30680+#define MV_ALIGN_UP(number, align) \
30681+(((number) & ((align) - 1)) ? (((number) + (align)) & ~((align)-1)) : (number))
30682+
30683+/* Macro for alignment down. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0320 */
30684+#define MV_ALIGN_DOWN(number, align) ((number) & ~((align)-1))
30685+
30686+/* This macro returns absolute value */
30687+#define MV_ABS(number) (((int)(number) < 0) ? -(int)(number) : (int)(number))
30688+
30689+
30690+/* Bit fields manipulation macros */
30691+
30692+/* An integer word which its 'x' bit is set */
30693+#define MV_BIT_MASK(bitNum) (1 << (bitNum) )
30694+
30695+/* Checks wheter bit 'x' in integer word is set */
30696+#define MV_BIT_CHECK(word, bitNum) ( (word) & MV_BIT_MASK(bitNum) )
30697+
30698+/* Clear (reset) bit 'x' in integer word (RMW - Read-Modify-Write) */
30699+#define MV_BIT_CLEAR(word, bitNum) ( (word) &= ~(MV_BIT_MASK(bitNum)) )
30700+
30701+/* Set bit 'x' in integer word (RMW) */
30702+#define MV_BIT_SET(word, bitNum) ( (word) |= MV_BIT_MASK(bitNum) )
30703+
30704+/* Invert bit 'x' in integer word (RMW) */
30705+#define MV_BIT_INV(word, bitNum) ( (word) ^= MV_BIT_MASK(bitNum) )
30706+
30707+/* Get the min between 'a' or 'b' */
30708+#define MV_MIN(a,b) (((a) < (b)) ? (a) : (b))
30709+
30710+/* Get the max between 'a' or 'b' */
30711+#define MV_MAX(a,b) (((a) < (b)) ? (b) : (a))
30712+
30713+/* Temporary */
30714+#define mvOsDivide(num, div) \
30715+({ \
30716+ int i=0, rem=(num); \
30717+ \
30718+ while(rem >= (div)) \
30719+ { \
30720+ rem -= (div); \
30721+ i++; \
30722+ } \
30723+ (i); \
30724+})
30725+
30726+/* Temporary */
30727+#define mvOsReminder(num, div) \
30728+({ \
30729+ int rem = (num); \
30730+ \
30731+ while(rem >= (div)) \
30732+ rem -= (div); \
30733+ (rem); \
30734+})
30735+
30736+#define MV_IP_QUAD(ipAddr) ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF), \
30737+ ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF)
30738+
30739+#define MV_IS_POWER_OF_2(num) ((num != 0) && ((num & (num - 1)) == 0))
30740+
30741+#ifndef MV_ASMLANGUAGE
30742+/* mvCommon API list */
30743+
30744+MV_VOID mvHexToBin(const char* pHexStr, MV_U8* pBin, int size);
30745+void mvAsciiToHex(const char* asciiStr, char* hexStr);
30746+void mvBinToHex(const MV_U8* bin, char* hexStr, int size);
30747+void mvBinToAscii(const MV_U8* bin, char* asciiStr, int size);
30748+
30749+MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex);
30750+MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr);
30751+void mvSizePrint(MV_U32);
30752+
30753+MV_U32 mvLog2(MV_U32 num);
30754+
30755+#endif /* MV_ASMLANGUAGE */
30756+
30757+
30758+#endif /* __INCmvCommonh */
30759diff --git a/crypto/ocf/kirkwood/mvHal/common/mvDebug.c b/crypto/ocf/kirkwood/mvHal/common/mvDebug.c
30760new file mode 100644
30761index 0000000..d98a9e4
30762--- /dev/null
30763+++ b/crypto/ocf/kirkwood/mvHal/common/mvDebug.c
30764@@ -0,0 +1,326 @@
30765+/*******************************************************************************
30766+Copyright (C) Marvell International Ltd. and its affiliates
30767+
30768+This software file (the "File") is owned and distributed by Marvell
30769+International Ltd. and/or its affiliates ("Marvell") under the following
30770+alternative licensing terms. Once you have made an election to distribute the
30771+File under one of the following license alternatives, please (i) delete this
30772+introductory statement regarding license alternatives, (ii) delete the two
30773+license alternatives that you have not elected to use and (iii) preserve the
30774+Marvell copyright notice above.
30775+
30776+********************************************************************************
30777+Marvell Commercial License Option
30778+
30779+If you received this File from Marvell and you have entered into a commercial
30780+license agreement (a "Commercial License") with Marvell, the File is licensed
30781+to you under the terms of the applicable Commercial License.
30782+
30783+********************************************************************************
30784+Marvell GPL License Option
30785+
30786+If you received this File from Marvell, you may opt to use, redistribute and/or
30787+modify this File in accordance with the terms and conditions of the General
30788+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
30789+available along with the File in the license.txt file or by writing to the Free
30790+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
30791+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
30792+
30793+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
30794+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
30795+DISCLAIMED. The GPL License provides additional details about this warranty
30796+disclaimer.
30797+********************************************************************************
30798+Marvell BSD License Option
30799+
30800+If you received this File from Marvell, you may opt to use, redistribute and/or
30801+modify this File under the following licensing terms.
30802+Redistribution and use in source and binary forms, with or without modification,
30803+are permitted provided that the following conditions are met:
30804+
30805+ * Redistributions of source code must retain the above copyright notice,
30806+ this list of conditions and the following disclaimer.
30807+
30808+ * Redistributions in binary form must reproduce the above copyright
30809+ notice, this list of conditions and the following disclaimer in the
30810+ documentation and/or other materials provided with the distribution.
30811+
30812+ * Neither the name of Marvell nor the names of its contributors may be
30813+ used to endorse or promote products derived from this software without
30814+ specific prior written permission.
30815+
30816+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
30817+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30818+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30819+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
30820+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30821+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30822+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30823+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30824+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30825+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30826+
30827+*******************************************************************************/
30828+
30829+
30830+
30831+/* includes */
30832+#include "mvOs.h"
30833+#include "mv802_3.h"
30834+#include "mvCommon.h"
30835+#include "mvDebug.h"
30836+
30837+/* Global variables effect on behave MV_DEBUG_PRINT and MV_DEBUG_CODE macros
30838+ * mvDebug - map of bits (one for each module) bit=1 means enable
30839+ * debug code and messages for this module
30840+ * mvModuleDebug - array of 32 bits varables one for each module
30841+ */
30842+MV_U32 mvDebug = 0;
30843+MV_U32 mvDebugModules[MV_MODULE_MAX];
30844+
30845+/* Init mvModuleDebug array to default values */
30846+void mvDebugInit(void)
30847+{
30848+ int bit;
30849+
30850+ mvDebug = 0;
30851+ for(bit=0; bit<MV_MODULE_MAX; bit++)
30852+ {
30853+ mvDebugModules[bit] = MV_DEBUG_FLAG_ERR | MV_DEBUG_FLAG_STATS;
30854+ mvDebug |= MV_BIT_MASK(bit);
30855+ }
30856+}
30857+
30858+void mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable)
30859+{
30860+ if (isEnable)
30861+ {
30862+ MV_BIT_SET(mvDebug, module);
30863+ }
30864+ else
30865+ MV_BIT_CLEAR(mvDebug, module);
30866+}
30867+
30868+void mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags)
30869+{
30870+ mvDebugModules[module] |= flags;
30871+}
30872+
30873+void mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags)
30874+{
30875+ mvDebugModules[module] &= ~flags;
30876+}
30877+
30878+/* Dump memory in specific format:
30879+ * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8
30880+ */
30881+void mvDebugMemDump(void* addr, int size, int access)
30882+{
30883+ int i, j;
30884+ MV_U32 memAddr = (MV_U32)addr;
30885+
30886+ if(access == 0)
30887+ access = 1;
30888+
30889+ if( (access != 4) && (access != 2) && (access != 1) )
30890+ {
30891+ mvOsPrintf("%d wrong access size. Access must be 1 or 2 or 4\n",
30892+ access);
30893+ return;
30894+ }
30895+ memAddr = MV_ALIGN_DOWN( (unsigned int)addr, 4);
30896+ size = MV_ALIGN_UP(size, 4);
30897+ addr = (void*)MV_ALIGN_DOWN( (unsigned int)addr, access);
30898+ while(size > 0)
30899+ {
30900+ mvOsPrintf("%08x: ", memAddr);
30901+ i = 0;
30902+ /* 32 bytes in the line */
30903+ while(i < 32)
30904+ {
30905+ if(memAddr >= (MV_U32)addr)
30906+ {
30907+ switch(access)
30908+ {
30909+ case 1:
30910+ if( memAddr == CPU_PHY_MEM(memAddr) )
30911+ {
30912+ mvOsPrintf("%02x ", MV_MEMIO8_READ(memAddr));
30913+ }
30914+ else
30915+ {
30916+ mvOsPrintf("%02x ", *((MV_U8*)memAddr));
30917+ }
30918+ break;
30919+
30920+ case 2:
30921+ if( memAddr == CPU_PHY_MEM(memAddr) )
30922+ {
30923+ mvOsPrintf("%04x ", MV_MEMIO16_READ(memAddr));
30924+ }
30925+ else
30926+ {
30927+ mvOsPrintf("%04x ", *((MV_U16*)memAddr));
30928+ }
30929+ break;
30930+
30931+ case 4:
30932+ if( memAddr == CPU_PHY_MEM(memAddr) )
30933+ {
30934+ mvOsPrintf("%08x ", MV_MEMIO32_READ(memAddr));
30935+ }
30936+ else
30937+ {
30938+ mvOsPrintf("%08x ", *((MV_U32*)memAddr));
30939+ }
30940+ break;
30941+ }
30942+ }
30943+ else
30944+ {
30945+ for(j=0; j<(access*2+1); j++)
30946+ mvOsPrintf(" ");
30947+ }
30948+ i += access;
30949+ memAddr += access;
30950+ size -= access;
30951+ if(size <= 0)
30952+ break;
30953+ }
30954+ mvOsPrintf("\n");
30955+ }
30956+}
30957+
30958+void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access)
30959+{
30960+ if(pBufInfo == NULL)
30961+ {
30962+ mvOsPrintf("\n!!! pBufInfo = NULL\n");
30963+ return;
30964+ }
30965+ mvOsPrintf("\n*** pBufInfo=0x%x, cmdSts=0x%08x, pBuf=0x%x, bufSize=%d\n",
30966+ (unsigned int)pBufInfo,
30967+ (unsigned int)pBufInfo->cmdSts,
30968+ (unsigned int)pBufInfo->pBuff,
30969+ (unsigned int)pBufInfo->bufSize);
30970+ mvOsPrintf("pData=0x%x, byteCnt=%d, pNext=0x%x, uInfo1=0x%x, uInfo2=0x%x\n",
30971+ (unsigned int)pBufInfo->pData,
30972+ (unsigned int)pBufInfo->byteCnt,
30973+ (unsigned int)pBufInfo->pNextBufInfo,
30974+ (unsigned int)pBufInfo->userInfo1,
30975+ (unsigned int)pBufInfo->userInfo2);
30976+ if(pBufInfo->pData != NULL)
30977+ {
30978+ if(size > pBufInfo->byteCnt)
30979+ size = pBufInfo->byteCnt;
30980+ mvDebugMemDump(pBufInfo->pData, size, access);
30981+ }
30982+}
30983+
30984+void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access)
30985+{
30986+ int frag, len;
30987+
30988+ if(pPktInfo == NULL)
30989+ {
30990+ mvOsPrintf("\n!!! pPktInfo = NULL\n");
30991+ return;
30992+ }
30993+ mvOsPrintf("\npPkt=%p, stat=0x%08x, numFr=%d, size=%d, pFr=%p, osInfo=0x%lx\n",
30994+ pPktInfo, pPktInfo->status, pPktInfo->numFrags, pPktInfo->pktSize,
30995+ pPktInfo->pFrags, pPktInfo->osInfo);
30996+
30997+ for(frag=0; frag<pPktInfo->numFrags; frag++)
30998+ {
30999+ mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n",
31000+ frag, pPktInfo->pFrags[frag].bufVirtPtr,
31001+ pPktInfo->pFrags[frag].bufSize);
31002+ if(size > 0)
31003+ {
31004+ len = MV_MIN((int)pPktInfo->pFrags[frag].bufSize, size);
31005+ mvDebugMemDump(pPktInfo->pFrags[frag].bufVirtPtr, len, access);
31006+ size -= len;
31007+ }
31008+ }
31009+
31010+}
31011+
31012+void mvDebugPrintIpAddr(MV_U32 ipAddr)
31013+{
31014+ mvOsPrintf("%d.%d.%d.%d", ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF),
31015+ ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF));
31016+}
31017+
31018+void mvDebugPrintMacAddr(const MV_U8* pMacAddr)
31019+{
31020+ int i;
31021+
31022+ mvOsPrintf("%02x", (unsigned int)pMacAddr[0]);
31023+ for(i=1; i<MV_MAC_ADDR_SIZE; i++)
31024+ {
31025+ mvOsPrintf(":%02x", pMacAddr[i]);
31026+ }
31027+ /* mvOsPrintf("\n");*/
31028+}
31029+
31030+
31031+/******* There are three functions deals with MV_DEBUG_TIMES structure ********/
31032+
31033+/* Reset MV_DEBUG_TIMES entry */
31034+void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* pName)
31035+{
31036+ pTimeEntry->begin = 0;
31037+ pTimeEntry->count = count;
31038+ pTimeEntry->end = 0;
31039+ pTimeEntry->left = pTimeEntry->count;
31040+ pTimeEntry->total = 0;
31041+ pTimeEntry->min = 0xFFFFFFFF;
31042+ pTimeEntry->max = 0x0;
31043+ strncpy(pTimeEntry->name, pName, sizeof(pTimeEntry->name)-1);
31044+ pTimeEntry->name[sizeof(pTimeEntry->name)-1] = '\0';
31045+}
31046+
31047+/* Print out MV_DEBUG_TIMES entry */
31048+void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle)
31049+{
31050+ int num;
31051+
31052+ if(isTitle == MV_TRUE)
31053+ mvOsPrintf("Event NumOfEvents TotalTime Average Min Max\n");
31054+
31055+ num = pTimeEntry->count-pTimeEntry->left;
31056+ if(num > 0)
31057+ {
31058+ mvOsPrintf("%-11s %6u 0x%08lx %6lu %6lu %6lu\n",
31059+ pTimeEntry->name, num, pTimeEntry->total, pTimeEntry->total/num,
31060+ pTimeEntry->min, pTimeEntry->max);
31061+ }
31062+}
31063+
31064+/* Update MV_DEBUG_TIMES entry */
31065+void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry)
31066+{
31067+ MV_U32 delta;
31068+
31069+ if(pTimeEntry->left > 0)
31070+ {
31071+ if(pTimeEntry->end <= pTimeEntry->begin)
31072+ {
31073+ delta = pTimeEntry->begin - pTimeEntry->end;
31074+ }
31075+ else
31076+ {
31077+ delta = ((MV_U32)0x10000 - pTimeEntry->end) + pTimeEntry->begin;
31078+ }
31079+ pTimeEntry->total += delta;
31080+
31081+ if(delta < pTimeEntry->min)
31082+ pTimeEntry->min = delta;
31083+
31084+ if(delta > pTimeEntry->max)
31085+ pTimeEntry->max = delta;
31086+
31087+ pTimeEntry->left--;
31088+ }
31089+}
31090+
31091diff --git a/crypto/ocf/kirkwood/mvHal/common/mvDebug.h b/crypto/ocf/kirkwood/mvHal/common/mvDebug.h
31092new file mode 100644
31093index 0000000..ed07a1f
31094--- /dev/null
31095+++ b/crypto/ocf/kirkwood/mvHal/common/mvDebug.h
31096@@ -0,0 +1,178 @@
31097+/*******************************************************************************
31098+Copyright (C) Marvell International Ltd. and its affiliates
31099+
31100+This software file (the "File") is owned and distributed by Marvell
31101+International Ltd. and/or its affiliates ("Marvell") under the following
31102+alternative licensing terms. Once you have made an election to distribute the
31103+File under one of the following license alternatives, please (i) delete this
31104+introductory statement regarding license alternatives, (ii) delete the two
31105+license alternatives that you have not elected to use and (iii) preserve the
31106+Marvell copyright notice above.
31107+
31108+********************************************************************************
31109+Marvell Commercial License Option
31110+
31111+If you received this File from Marvell and you have entered into a commercial
31112+license agreement (a "Commercial License") with Marvell, the File is licensed
31113+to you under the terms of the applicable Commercial License.
31114+
31115+********************************************************************************
31116+Marvell GPL License Option
31117+
31118+If you received this File from Marvell, you may opt to use, redistribute and/or
31119+modify this File in accordance with the terms and conditions of the General
31120+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
31121+available along with the File in the license.txt file or by writing to the Free
31122+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
31123+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
31124+
31125+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
31126+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
31127+DISCLAIMED. The GPL License provides additional details about this warranty
31128+disclaimer.
31129+********************************************************************************
31130+Marvell BSD License Option
31131+
31132+If you received this File from Marvell, you may opt to use, redistribute and/or
31133+modify this File under the following licensing terms.
31134+Redistribution and use in source and binary forms, with or without modification,
31135+are permitted provided that the following conditions are met:
31136+
31137+ * Redistributions of source code must retain the above copyright notice,
31138+ this list of conditions and the following disclaimer.
31139+
31140+ * Redistributions in binary form must reproduce the above copyright
31141+ notice, this list of conditions and the following disclaimer in the
31142+ documentation and/or other materials provided with the distribution.
31143+
31144+ * Neither the name of Marvell nor the names of its contributors may be
31145+ used to endorse or promote products derived from this software without
31146+ specific prior written permission.
31147+
31148+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
31149+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31150+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31151+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
31152+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31153+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31154+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31155+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31156+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31157+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31158+
31159+*******************************************************************************/
31160+
31161+
31162+
31163+#ifndef __INCmvDebugh
31164+#define __INCmvDebugh
31165+
31166+/* includes */
31167+#include "mvTypes.h"
31168+
31169+typedef enum
31170+{
31171+ MV_MODULE_INVALID = -1,
31172+ MV_MODULE_ETH = 0,
31173+ MV_MODULE_IDMA,
31174+ MV_MODULE_XOR,
31175+ MV_MODULE_TWASI,
31176+ MV_MODULE_MGI,
31177+ MV_MODULE_USB,
31178+ MV_MODULE_CESA,
31179+
31180+ MV_MODULE_MAX
31181+}MV_MODULE_ID;
31182+
31183+/* Define generic flags useful for most of modules */
31184+#define MV_DEBUG_FLAG_ALL (0)
31185+#define MV_DEBUG_FLAG_INIT (1 << 0)
31186+#define MV_DEBUG_FLAG_RX (1 << 1)
31187+#define MV_DEBUG_FLAG_TX (1 << 2)
31188+#define MV_DEBUG_FLAG_ERR (1 << 3)
31189+#define MV_DEBUG_FLAG_TRACE (1 << 4)
31190+#define MV_DEBUG_FLAG_DUMP (1 << 5)
31191+#define MV_DEBUG_FLAG_CACHE (1 << 6)
31192+#define MV_DEBUG_FLAG_IOCTL (1 << 7)
31193+#define MV_DEBUG_FLAG_STATS (1 << 8)
31194+
31195+extern MV_U32 mvDebug;
31196+extern MV_U32 mvDebugModules[MV_MODULE_MAX];
31197+
31198+#ifdef MV_DEBUG
31199+# define MV_DEBUG_PRINT(module, flags, msg) mvOsPrintf msg
31200+# define MV_DEBUG_CODE(module, flags, code) code
31201+#elif defined(MV_RT_DEBUG)
31202+# define MV_DEBUG_PRINT(module, flags, msg) \
31203+ if( (mvDebug & (1<<(module))) && \
31204+ ((mvDebugModules[(module)] & (flags)) == (flags)) ) \
31205+ mvOsPrintf msg
31206+# define MV_DEBUG_CODE(module, flags, code) \
31207+ if( (mvDebug & (1<<(module))) && \
31208+ ((mvDebugModules[(module)] & (flags)) == (flags)) ) \
31209+ code
31210+#else
31211+# define MV_DEBUG_PRINT(module, flags, msg)
31212+# define MV_DEBUG_CODE(module, flags, code)
31213+#endif
31214+
31215+
31216+
31217+/* typedefs */
31218+
31219+/* time measurement structure used to check how much time pass between
31220+ * two points
31221+ */
31222+typedef struct {
31223+ char name[20]; /* name of the entry */
31224+ unsigned long begin; /* time measured on begin point */
31225+ unsigned long end; /* time measured on end point */
31226+ unsigned long total; /* Accumulated time */
31227+ unsigned long left; /* The rest measurement actions */
31228+ unsigned long count; /* Maximum measurement actions */
31229+ unsigned long min; /* Minimum time from begin to end */
31230+ unsigned long max; /* Maximum time from begin to end */
31231+} MV_DEBUG_TIMES;
31232+
31233+
31234+/* mvDebug.h API list */
31235+
31236+/****** Error Recording ******/
31237+
31238+/* Dump memory in specific format:
31239+ * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8
31240+ */
31241+void mvDebugMemDump(void* addr, int size, int access);
31242+
31243+void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access);
31244+
31245+void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access);
31246+
31247+void mvDebugPrintIpAddr(MV_U32 ipAddr);
31248+
31249+void mvDebugPrintMacAddr(const MV_U8* pMacAddr);
31250+
31251+/**** There are three functions deals with MV_DEBUG_TIMES structure ****/
31252+
31253+/* Reset MV_DEBUG_TIMES entry */
31254+void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* name);
31255+
31256+/* Update MV_DEBUG_TIMES entry */
31257+void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry);
31258+
31259+/* Print out MV_DEBUG_TIMES entry */
31260+void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle);
31261+
31262+
31263+/******** General ***********/
31264+
31265+/* Change value of mvDebugPrint global variable */
31266+
31267+void mvDebugInit(void);
31268+void mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable);
31269+void mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags);
31270+void mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags);
31271+
31272+
31273+#endif /* __INCmvDebug.h */
31274+
31275diff --git a/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h b/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h
31276new file mode 100644
31277index 0000000..2e0c04f
31278--- /dev/null
31279+++ b/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h
31280@@ -0,0 +1,225 @@
31281+/*******************************************************************************
31282+Copyright (C) Marvell International Ltd. and its affiliates
31283+
31284+This software file (the "File") is owned and distributed by Marvell
31285+International Ltd. and/or its affiliates ("Marvell") under the following
31286+alternative licensing terms. Once you have made an election to distribute the
31287+File under one of the following license alternatives, please (i) delete this
31288+introductory statement regarding license alternatives, (ii) delete the two
31289+license alternatives that you have not elected to use and (iii) preserve the
31290+Marvell copyright notice above.
31291+
31292+********************************************************************************
31293+Marvell Commercial License Option
31294+
31295+If you received this File from Marvell and you have entered into a commercial
31296+license agreement (a "Commercial License") with Marvell, the File is licensed
31297+to you under the terms of the applicable Commercial License.
31298+
31299+********************************************************************************
31300+Marvell GPL License Option
31301+
31302+If you received this File from Marvell, you may opt to use, redistribute and/or
31303+modify this File in accordance with the terms and conditions of the General
31304+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
31305+available along with the File in the license.txt file or by writing to the Free
31306+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
31307+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
31308+
31309+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
31310+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
31311+DISCLAIMED. The GPL License provides additional details about this warranty
31312+disclaimer.
31313+********************************************************************************
31314+Marvell BSD License Option
31315+
31316+If you received this File from Marvell, you may opt to use, redistribute and/or
31317+modify this File under the following licensing terms.
31318+Redistribution and use in source and binary forms, with or without modification,
31319+are permitted provided that the following conditions are met:
31320+
31321+ * Redistributions of source code must retain the above copyright notice,
31322+ this list of conditions and the following disclaimer.
31323+
31324+ * Redistributions in binary form must reproduce the above copyright
31325+ notice, this list of conditions and the following disclaimer in the
31326+ documentation and/or other materials provided with the distribution.
31327+
31328+ * Neither the name of Marvell nor the names of its contributors may be
31329+ used to endorse or promote products derived from this software without
31330+ specific prior written permission.
31331+
31332+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
31333+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31334+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31335+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
31336+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31337+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31338+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31339+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31340+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31341+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31342+
31343+*******************************************************************************/
31344+
31345+#ifndef __INCmvDeviceIdh
31346+#define __INCmvDeviceIdh
31347+
31348+#ifdef __cplusplus
31349+extern "C" {
31350+#endif /* __cplusplus */
31351+
31352+/* defines */
31353+#define MARVELL_VEN_ID 0x11ab
31354+
31355+/* Disco-3 */
31356+#define MV64460_DEV_ID 0x6480
31357+#define MV64460B_DEV_ID 0x6485
31358+#define MV64430_DEV_ID 0x6420
31359+
31360+/* Disco-5 */
31361+#define MV64560_DEV_ID 0x6450
31362+
31363+/* Disco-6 */
31364+#define MV64660_DEV_ID 0x6460
31365+
31366+/* Orion */
31367+#define MV_1181_DEV_ID 0x1181
31368+#define MV_5181_DEV_ID 0x5181
31369+#define MV_5281_DEV_ID 0x5281
31370+#define MV_5182_DEV_ID 0x5182
31371+#define MV_8660_DEV_ID 0x8660
31372+#define MV_5180_DEV_ID 0x5180
31373+#define MV_5082_DEV_ID 0x5082
31374+#define MV_1281_DEV_ID 0x1281
31375+#define MV_6082_DEV_ID 0x6082
31376+#define MV_6183_DEV_ID 0x6183
31377+#define MV_6183L_DEV_ID 0x6083
31378+
31379+#define MV_5281_D0_REV 0x4
31380+#define MV_5281_D0_ID ((MV_5281_DEV_ID << 16) | MV_5281_D0_REV)
31381+#define MV_5281_D0_NAME "88F5281 D0"
31382+
31383+#define MV_5281_D1_REV 0x5
31384+#define MV_5281_D1_ID ((MV_5281_DEV_ID << 16) | MV_5281_D1_REV)
31385+#define MV_5281_D1_NAME "88F5281 D1"
31386+
31387+#define MV_5281_D2_REV 0x6
31388+#define MV_5281_D2_ID ((MV_5281_DEV_ID << 16) | MV_5281_D2_REV)
31389+#define MV_5281_D2_NAME "88F5281 D2"
31390+
31391+
31392+#define MV_5181L_A0_REV 0x8 /* need for PCIE Er */
31393+#define MV_5181_A1_REV 0x1 /* for USB Er ..*/
31394+#define MV_5181_B0_REV 0x2
31395+#define MV_5181_B1_REV 0x3
31396+#define MV_5182_A1_REV 0x1
31397+#define MV_5180N_B1_REV 0x3
31398+#define MV_5181L_A0_ID ((MV_5181_DEV_ID << 16) | MV_5181L_A0_REV)
31399+
31400+
31401+
31402+/* kw */
31403+#define MV_6281_DEV_ID 0x6281
31404+#define MV_6192_DEV_ID 0x6192
31405+#define MV_6190_DEV_ID 0x6190
31406+#define MV_6180_DEV_ID 0x6180
31407+
31408+#define MV_6281_A0_REV 0x2
31409+#define MV_6281_A0_ID ((MV_6281_DEV_ID << 16) | MV_6281_A0_REV)
31410+#define MV_6281_A0_NAME "88F6281 A0"
31411+
31412+#define MV_6192_A0_REV 0x2
31413+#define MV_6192_A0_ID ((MV_6192_DEV_ID << 16) | MV_6192_A0_REV)
31414+#define MV_6192_A0_NAME "88F6192 A0"
31415+
31416+#define MV_6190_A0_REV 0x2
31417+#define MV_6190_A0_ID ((MV_6190_DEV_ID << 16) | MV_6190_A0_REV)
31418+#define MV_6190_A0_NAME "88F6190 A0"
31419+
31420+#define MV_6180_A0_REV 0x2
31421+#define MV_6180_A0_ID ((MV_6180_DEV_ID << 16) | MV_6180_A0_REV)
31422+#define MV_6180_A0_NAME "88F6180 A0"
31423+
31424+#define MV_6281_A1_REV 0x3
31425+#define MV_6281_A1_ID ((MV_6281_DEV_ID << 16) | MV_6281_A1_REV)
31426+#define MV_6281_A1_NAME "88F6281 A1"
31427+
31428+#define MV_6192_A1_REV 0x3
31429+#define MV_6192_A1_ID ((MV_6192_DEV_ID << 16) | MV_6192_A1_REV)
31430+#define MV_6192_A1_NAME "88F6192 A1"
31431+
31432+#define MV_6190_A1_REV 0x3
31433+#define MV_6190_A1_ID ((MV_6190_DEV_ID << 16) | MV_6190_A1_REV)
31434+#define MV_6190_A1_NAME "88F6190 A1"
31435+
31436+#define MV_6180_A1_REV 0x3
31437+#define MV_6180_A1_ID ((MV_6180_DEV_ID << 16) | MV_6180_A1_REV)
31438+#define MV_6180_A1_NAME "88F6180 A1"
31439+
31440+#define MV_88F6XXX_A0_REV 0x2
31441+#define MV_88F6XXX_A1_REV 0x3
31442+/* Disco-Duo */
31443+#define MV_78XX0_ZY_DEV_ID 0x6381
31444+#define MV_78XX0_ZY_NAME "MV78X00"
31445+
31446+#define MV_78XX0_Z0_REV 0x1
31447+#define MV_78XX0_Z0_ID ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Z0_REV)
31448+#define MV_78XX0_Z0_NAME "78X00 Z0"
31449+
31450+#define MV_78XX0_Y0_REV 0x2
31451+#define MV_78XX0_Y0_ID ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Y0_REV)
31452+#define MV_78XX0_Y0_NAME "78X00 Y0"
31453+
31454+#define MV_78XX0_DEV_ID 0x7800
31455+#define MV_78XX0_NAME "MV78X00"
31456+
31457+#define MV_76100_DEV_ID 0x7610
31458+#define MV_78200_DEV_ID 0x7820
31459+#define MV_78100_DEV_ID 0x7810
31460+#define MV_78XX0_A0_REV 0x1
31461+#define MV_78XX0_A1_REV 0x2
31462+
31463+#define MV_76100_NAME "MV76100"
31464+#define MV_78100_NAME "MV78100"
31465+#define MV_78200_NAME "MV78200"
31466+
31467+#define MV_76100_A0_ID ((MV_76100_DEV_ID << 16) | MV_78XX0_A0_REV)
31468+#define MV_78100_A0_ID ((MV_78100_DEV_ID << 16) | MV_78XX0_A0_REV)
31469+#define MV_78200_A0_ID ((MV_78200_DEV_ID << 16) | MV_78XX0_A0_REV)
31470+
31471+#define MV_76100_A1_ID ((MV_76100_DEV_ID << 16) | MV_78XX0_A1_REV)
31472+#define MV_78100_A1_ID ((MV_78100_DEV_ID << 16) | MV_78XX0_A1_REV)
31473+#define MV_78200_A1_ID ((MV_78200_DEV_ID << 16) | MV_78XX0_A1_REV)
31474+
31475+#define MV_76100_A0_NAME "MV76100 A0"
31476+#define MV_78100_A0_NAME "MV78100 A0"
31477+#define MV_78200_A0_NAME "MV78200 A0"
31478+#define MV_78XX0_A0_NAME "MV78XX0 A0"
31479+
31480+#define MV_76100_A1_NAME "MV76100 A1"
31481+#define MV_78100_A1_NAME "MV78100 A1"
31482+#define MV_78200_A1_NAME "MV78200 A1"
31483+#define MV_78XX0_A1_NAME "MV78XX0 A1"
31484+
31485+/*MV88F632X family*/
31486+#define MV_6321_DEV_ID 0x6321
31487+#define MV_6322_DEV_ID 0x6322
31488+#define MV_6323_DEV_ID 0x6323
31489+
31490+#define MV_6321_NAME "88F6321"
31491+#define MV_6322_NAME "88F6322"
31492+#define MV_6323_NAME "88F6323"
31493+
31494+#define MV_632X_A1_REV 0x2
31495+
31496+#define MV_6321_A1_ID ((MV_6321_DEV_ID << 16) | MV_632X_A1_REV)
31497+#define MV_6322_A1_ID ((MV_6322_DEV_ID << 16) | MV_632X_A1_REV)
31498+#define MV_6323_A1_ID ((MV_6323_DEV_ID << 16) | MV_632X_A1_REV)
31499+
31500+#define MV_6321_A1_NAME "88F6321 A1"
31501+#define MV_6322_A1_NAME "88F6322 A1"
31502+#define MV_6323_A1_NAME "88F6323 A1"
31503+
31504+
31505+#endif /* __INCmvDeviceIdh */
31506diff --git a/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h b/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h
31507new file mode 100644
31508index 0000000..1849198
31509--- /dev/null
31510+++ b/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h
31511@@ -0,0 +1,73 @@
31512+/*******************************************************************************
31513+Copyright (C) Marvell International Ltd. and its affiliates
31514+
31515+This software file (the "File") is owned and distributed by Marvell
31516+International Ltd. and/or its affiliates ("Marvell") under the following
31517+alternative licensing terms. Once you have made an election to distribute the
31518+File under one of the following license alternatives, please (i) delete this
31519+introductory statement regarding license alternatives, (ii) delete the two
31520+license alternatives that you have not elected to use and (iii) preserve the
31521+Marvell copyright notice above.
31522+
31523+********************************************************************************
31524+Marvell Commercial License Option
31525+
31526+If you received this File from Marvell and you have entered into a commercial
31527+license agreement (a "Commercial License") with Marvell, the File is licensed
31528+to you under the terms of the applicable Commercial License.
31529+
31530+********************************************************************************
31531+Marvell GPL License Option
31532+
31533+If you received this File from Marvell, you may opt to use, redistribute and/or
31534+modify this File in accordance with the terms and conditions of the General
31535+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
31536+available along with the File in the license.txt file or by writing to the Free
31537+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
31538+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
31539+
31540+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
31541+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
31542+DISCLAIMED. The GPL License provides additional details about this warranty
31543+disclaimer.
31544+********************************************************************************
31545+Marvell BSD License Option
31546+
31547+If you received this File from Marvell, you may opt to use, redistribute and/or
31548+modify this File under the following licensing terms.
31549+Redistribution and use in source and binary forms, with or without modification,
31550+are permitted provided that the following conditions are met:
31551+
31552+ * Redistributions of source code must retain the above copyright notice,
31553+ this list of conditions and the following disclaimer.
31554+
31555+ * Redistributions in binary form must reproduce the above copyright
31556+ notice, this list of conditions and the following disclaimer in the
31557+ documentation and/or other materials provided with the distribution.
31558+
31559+ * Neither the name of Marvell nor the names of its contributors may be
31560+ used to endorse or promote products derived from this software without
31561+ specific prior written permission.
31562+
31563+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
31564+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31565+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31566+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
31567+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31568+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31569+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31570+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31571+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31572+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31573+
31574+*******************************************************************************/
31575+
31576+
31577+#ifndef __INCmvHalVerh
31578+#define __INCmvHalVerh
31579+
31580+/* Defines */
31581+#define MV_HAL_VERSION "FEROCEON_HAL_3_1_7"
31582+#define MV_RELEASE_BASELINE "SoCandControllers_FEROCEON_RELEASE_7_9_2009_KW_4_3_4_DD_2_1_4_6183_1_1_4"
31583+
31584+#endif /* __INCmvHalVerh */
31585\ No newline at end of file
31586diff --git a/crypto/ocf/kirkwood/mvHal/common/mvStack.c b/crypto/ocf/kirkwood/mvHal/common/mvStack.c
31587new file mode 100644
31588index 0000000..7ba48ea
31589--- /dev/null
31590+++ b/crypto/ocf/kirkwood/mvHal/common/mvStack.c
31591@@ -0,0 +1,100 @@
31592+/*******************************************************************************
31593+* Copyright 2003, Marvell Semiconductor Israel LTD. *
31594+* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL. *
31595+* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT *
31596+* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE *
31597+* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL. *
31598+* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED, *
31599+* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE. *
31600+* *
31601+* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, *
31602+* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL *
31603+* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K. *
31604+* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL). *
31605+********************************************************************************
31606+* mvQueue.c
31607+*
31608+* FILENAME: $Workfile: mvStack.c $
31609+* REVISION: $Revision: 1.1 $
31610+* LAST UPDATE: $Modtime: $
31611+*
31612+* DESCRIPTION:
31613+* This file implements simple Stack LIFO functionality.
31614+*******************************************************************************/
31615+
31616+/* includes */
31617+#include "mvOs.h"
31618+#include "mvTypes.h"
31619+#include "mvDebug.h"
31620+#include "mvStack.h"
31621+
31622+/* defines */
31623+
31624+
31625+/* Public functions */
31626+
31627+
31628+/* Purpose: Create new stack
31629+ * Inputs:
31630+ * - MV_U32 noOfElements - maximum number of elements in the stack.
31631+ * Each element 4 bytes size
31632+ * Return: void* - pointer to created stack.
31633+ */
31634+void* mvStackCreate(int numOfElements)
31635+{
31636+ MV_STACK* pStack;
31637+ MV_U32* pStackElements;
31638+
31639+ pStack = (MV_STACK*)mvOsMalloc(sizeof(MV_STACK));
31640+ pStackElements = (MV_U32*)mvOsMalloc(numOfElements*sizeof(MV_U32));
31641+ if( (pStack == NULL) || (pStackElements == NULL) )
31642+ {
31643+ mvOsPrintf("mvStack: Can't create new stack\n");
31644+ return NULL;
31645+ }
31646+ memset(pStackElements, 0, numOfElements*sizeof(MV_U32));
31647+ pStack->numOfElements = numOfElements;
31648+ pStack->stackIdx = 0;
31649+ pStack->stackElements = pStackElements;
31650+
31651+ return pStack;
31652+}
31653+
31654+/* Purpose: Delete existing stack
31655+ * Inputs:
31656+ * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function
31657+ *
31658+ * Return: MV_STATUS MV_NOT_FOUND - Failure. StackHandle is not valid.
31659+ * MV_OK - Success.
31660+ */
31661+MV_STATUS mvStackDelete(void* stackHndl)
31662+{
31663+ MV_STACK* pStack = (MV_STACK*)stackHndl;
31664+
31665+ if( (pStack == NULL) || (pStack->stackElements == NULL) )
31666+ return MV_NOT_FOUND;
31667+
31668+ mvOsFree(pStack->stackElements);
31669+ mvOsFree(pStack);
31670+
31671+ return MV_OK;
31672+}
31673+
31674+
31675+/* PrintOut status of the stack */
31676+void mvStackStatus(void* stackHndl, MV_BOOL isPrintElements)
31677+{
31678+ int i;
31679+ MV_STACK* pStack = (MV_STACK*)stackHndl;
31680+
31681+ mvOsPrintf("StackHandle=%p, pElements=%p, numElements=%d, stackIdx=%d\n",
31682+ stackHndl, pStack->stackElements, pStack->numOfElements,
31683+ pStack->stackIdx);
31684+ if(isPrintElements == MV_TRUE)
31685+ {
31686+ for(i=0; i<pStack->stackIdx; i++)
31687+ {
31688+ mvOsPrintf("%3d. Value=0x%x\n", i, pStack->stackElements[i]);
31689+ }
31690+ }
31691+}
31692diff --git a/crypto/ocf/kirkwood/mvHal/common/mvStack.h b/crypto/ocf/kirkwood/mvHal/common/mvStack.h
31693new file mode 100644
31694index 0000000..7e33d91
31695--- /dev/null
31696+++ b/crypto/ocf/kirkwood/mvHal/common/mvStack.h
31697@@ -0,0 +1,140 @@
31698+/*******************************************************************************
31699+* Copyright 2003, Marvell Semiconductor Israel LTD. *
31700+* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL. *
31701+* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT *
31702+* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE *
31703+* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL. *
31704+* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED, *
31705+* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE. *
31706+* *
31707+* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, *
31708+* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL *
31709+* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K. *
31710+* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL). *
31711+********************************************************************************
31712+* mvStack.h - Header File for :
31713+*
31714+* FILENAME: $Workfile: mvStack.h $
31715+* REVISION: $Revision: 1.1 $
31716+* LAST UPDATE: $Modtime: $
31717+*
31718+* DESCRIPTION:
31719+* This file defines simple Stack (LIFO) functionality.
31720+*
31721+*******************************************************************************/
31722+
31723+#ifndef __mvStack_h__
31724+#define __mvStack_h__
31725+
31726+
31727+/* includes */
31728+#include "mvTypes.h"
31729+
31730+
31731+/* defines */
31732+
31733+
31734+/* typedefs */
31735+/* Data structure describes general purpose Stack */
31736+typedef struct
31737+{
31738+ int stackIdx;
31739+ int numOfElements;
31740+ MV_U32* stackElements;
31741+} MV_STACK;
31742+
31743+static INLINE MV_BOOL mvStackIsFull(void* stackHndl)
31744+{
31745+ MV_STACK* pStack = (MV_STACK*)stackHndl;
31746+
31747+ if(pStack->stackIdx == pStack->numOfElements)
31748+ return MV_TRUE;
31749+
31750+ return MV_FALSE;
31751+}
31752+
31753+static INLINE MV_BOOL mvStackIsEmpty(void* stackHndl)
31754+{
31755+ MV_STACK* pStack = (MV_STACK*)stackHndl;
31756+
31757+ if(pStack->stackIdx == 0)
31758+ return MV_TRUE;
31759+
31760+ return MV_FALSE;
31761+}
31762+/* Purpose: Push new element to stack
31763+ * Inputs:
31764+ * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function.
31765+ * - MV_U32 value - New element.
31766+ *
31767+ * Return: MV_STATUS MV_FULL - Failure. Stack is full.
31768+ * MV_OK - Success. Element is put to stack.
31769+ */
31770+static INLINE void mvStackPush(void* stackHndl, MV_U32 value)
31771+{
31772+ MV_STACK* pStack = (MV_STACK*)stackHndl;
31773+
31774+#ifdef MV_RT_DEBUG
31775+ if(pStack->stackIdx == pStack->numOfElements)
31776+ {
31777+ mvOsPrintf("mvStackPush: Stack is FULL\n");
31778+ return;
31779+ }
31780+#endif /* MV_RT_DEBUG */
31781+
31782+ pStack->stackElements[pStack->stackIdx] = value;
31783+ pStack->stackIdx++;
31784+}
31785+
31786+/* Purpose: Pop element from the top of stack and copy it to "pValue"
31787+ * Inputs:
31788+ * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function.
31789+ * - MV_U32 value - Element in the top of stack.
31790+ *
31791+ * Return: MV_STATUS MV_EMPTY - Failure. Stack is empty.
31792+ * MV_OK - Success. Element is removed from the stack and
31793+ * copied to pValue argument
31794+ */
31795+static INLINE MV_U32 mvStackPop(void* stackHndl)
31796+{
31797+ MV_STACK* pStack = (MV_STACK*)stackHndl;
31798+
31799+#ifdef MV_RT_DEBUG
31800+ if(pStack->stackIdx == 0)
31801+ {
31802+ mvOsPrintf("mvStackPop: Stack is EMPTY\n");
31803+ return 0;
31804+ }
31805+#endif /* MV_RT_DEBUG */
31806+
31807+ pStack->stackIdx--;
31808+ return pStack->stackElements[pStack->stackIdx];
31809+}
31810+
31811+static INLINE int mvStackIndex(void* stackHndl)
31812+{
31813+ MV_STACK* pStack = (MV_STACK*)stackHndl;
31814+
31815+ return pStack->stackIdx;
31816+}
31817+
31818+static INLINE int mvStackFreeElements(void* stackHndl)
31819+{
31820+ MV_STACK* pStack = (MV_STACK*)stackHndl;
31821+
31822+ return (pStack->numOfElements - pStack->stackIdx);
31823+}
31824+
31825+/* mvStack.h API list */
31826+
31827+/* Create new Stack */
31828+void* mvStackCreate(int numOfElements);
31829+
31830+/* Delete existing stack */
31831+MV_STATUS mvStackDelete(void* stackHndl);
31832+
31833+/* Print status of the stack */
31834+void mvStackStatus(void* stackHndl, MV_BOOL isPrintElements);
31835+
31836+#endif /* __mvStack_h__ */
31837+
31838diff --git a/crypto/ocf/kirkwood/mvHal/common/mvTypes.h b/crypto/ocf/kirkwood/mvHal/common/mvTypes.h
31839new file mode 100644
31840index 0000000..1538a24
31841--- /dev/null
31842+++ b/crypto/ocf/kirkwood/mvHal/common/mvTypes.h
31843@@ -0,0 +1,245 @@
31844+/*******************************************************************************
31845+Copyright (C) Marvell International Ltd. and its affiliates
31846+
31847+This software file (the "File") is owned and distributed by Marvell
31848+International Ltd. and/or its affiliates ("Marvell") under the following
31849+alternative licensing terms. Once you have made an election to distribute the
31850+File under one of the following license alternatives, please (i) delete this
31851+introductory statement regarding license alternatives, (ii) delete the two
31852+license alternatives that you have not elected to use and (iii) preserve the
31853+Marvell copyright notice above.
31854+
31855+********************************************************************************
31856+Marvell Commercial License Option
31857+
31858+If you received this File from Marvell and you have entered into a commercial
31859+license agreement (a "Commercial License") with Marvell, the File is licensed
31860+to you under the terms of the applicable Commercial License.
31861+
31862+********************************************************************************
31863+Marvell GPL License Option
31864+
31865+If you received this File from Marvell, you may opt to use, redistribute and/or
31866+modify this File in accordance with the terms and conditions of the General
31867+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
31868+available along with the File in the license.txt file or by writing to the Free
31869+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
31870+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
31871+
31872+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
31873+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
31874+DISCLAIMED. The GPL License provides additional details about this warranty
31875+disclaimer.
31876+********************************************************************************
31877+Marvell BSD License Option
31878+
31879+If you received this File from Marvell, you may opt to use, redistribute and/or
31880+modify this File under the following licensing terms.
31881+Redistribution and use in source and binary forms, with or without modification,
31882+are permitted provided that the following conditions are met:
31883+
31884+ * Redistributions of source code must retain the above copyright notice,
31885+ this list of conditions and the following disclaimer.
31886+
31887+ * Redistributions in binary form must reproduce the above copyright
31888+ notice, this list of conditions and the following disclaimer in the
31889+ documentation and/or other materials provided with the distribution.
31890+
31891+ * Neither the name of Marvell nor the names of its contributors may be
31892+ used to endorse or promote products derived from this software without
31893+ specific prior written permission.
31894+
31895+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
31896+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31897+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31898+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
31899+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31900+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31901+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31902+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31903+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31904+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31905+
31906+*******************************************************************************/
31907+
31908+
31909+#ifndef __INCmvTypesh
31910+#define __INCmvTypesh
31911+
31912+/* Defines */
31913+
31914+/* The following is a list of Marvell status */
31915+#define MV_ERROR (-1)
31916+#define MV_OK (0x00) /* Operation succeeded */
31917+#define MV_FAIL (0x01) /* Operation failed */
31918+#define MV_BAD_VALUE (0x02) /* Illegal value (general) */
31919+#define MV_OUT_OF_RANGE (0x03) /* The value is out of range */
31920+#define MV_BAD_PARAM (0x04) /* Illegal parameter in function called */
31921+#define MV_BAD_PTR (0x05) /* Illegal pointer value */
31922+#define MV_BAD_SIZE (0x06) /* Illegal size */
31923+#define MV_BAD_STATE (0x07) /* Illegal state of state machine */
31924+#define MV_SET_ERROR (0x08) /* Set operation failed */
31925+#define MV_GET_ERROR (0x09) /* Get operation failed */
31926+#define MV_CREATE_ERROR (0x0A) /* Fail while creating an item */
31927+#define MV_NOT_FOUND (0x0B) /* Item not found */
31928+#define MV_NO_MORE (0x0C) /* No more items found */
31929+#define MV_NO_SUCH (0x0D) /* No such item */
31930+#define MV_TIMEOUT (0x0E) /* Time Out */
31931+#define MV_NO_CHANGE (0x0F) /* Parameter(s) is already in this value */
31932+#define MV_NOT_SUPPORTED (0x10) /* This request is not support */
31933+#define MV_NOT_IMPLEMENTED (0x11) /* Request supported but not implemented */
31934+#define MV_NOT_INITIALIZED (0x12) /* The item is not initialized */
31935+#define MV_NO_RESOURCE (0x13) /* Resource not available (memory ...) */
31936+#define MV_FULL (0x14) /* Item is full (Queue or table etc...) */
31937+#define MV_EMPTY (0x15) /* Item is empty (Queue or table etc...) */
31938+#define MV_INIT_ERROR (0x16) /* Error occured while INIT process */
31939+#define MV_HW_ERROR (0x17) /* Hardware error */
31940+#define MV_TX_ERROR (0x18) /* Transmit operation not succeeded */
31941+#define MV_RX_ERROR (0x19) /* Recieve operation not succeeded */
31942+#define MV_NOT_READY (0x1A) /* The other side is not ready yet */
31943+#define MV_ALREADY_EXIST (0x1B) /* Tried to create existing item */
31944+#define MV_OUT_OF_CPU_MEM (0x1C) /* Cpu memory allocation failed. */
31945+#define MV_NOT_STARTED (0x1D) /* Not started yet */
31946+#define MV_BUSY (0x1E) /* Item is busy. */
31947+#define MV_TERMINATE (0x1F) /* Item terminates it's work. */
31948+#define MV_NOT_ALIGNED (0x20) /* Wrong alignment */
31949+#define MV_NOT_ALLOWED (0x21) /* Operation NOT allowed */
31950+#define MV_WRITE_PROTECT (0x22) /* Write protected */
31951+
31952+
31953+#define MV_INVALID (int)(-1)
31954+
31955+#define MV_FALSE 0
31956+#define MV_TRUE (!(MV_FALSE))
31957+
31958+
31959+#ifndef NULL
31960+#define NULL ((void*)0)
31961+#endif
31962+
31963+
31964+#ifndef MV_ASMLANGUAGE
31965+/* typedefs */
31966+
31967+typedef char MV_8;
31968+typedef unsigned char MV_U8;
31969+
31970+typedef int MV_32;
31971+typedef unsigned int MV_U32;
31972+
31973+typedef short MV_16;
31974+typedef unsigned short MV_U16;
31975+
31976+#ifdef MV_PPC64
31977+typedef long MV_64;
31978+typedef unsigned long MV_U64;
31979+#else
31980+typedef long long MV_64;
31981+typedef unsigned long long MV_U64;
31982+#endif
31983+
31984+typedef long MV_LONG; /* 32/64 */
31985+typedef unsigned long MV_ULONG; /* 32/64 */
31986+
31987+typedef int MV_STATUS;
31988+typedef int MV_BOOL;
31989+typedef void MV_VOID;
31990+typedef float MV_FLOAT;
31991+
31992+typedef int (*MV_FUNCPTR) (void); /* ptr to function returning int */
31993+typedef void (*MV_VOIDFUNCPTR) (void); /* ptr to function returning void */
31994+typedef double (*MV_DBLFUNCPTR) (void); /* ptr to function returning double*/
31995+typedef float (*MV_FLTFUNCPTR) (void); /* ptr to function returning float */
31996+
31997+typedef MV_U32 MV_KHZ;
31998+typedef MV_U32 MV_MHZ;
31999+typedef MV_U32 MV_HZ;
32000+
32001+
32002+/* This enumerator describes the set of commands that can be applied on */
32003+/* an engine (e.g. IDMA, XOR). Appling a comman depends on the current */
32004+/* status (see MV_STATE enumerator) */
32005+/* Start can be applied only when status is IDLE */
32006+/* Stop can be applied only when status is IDLE, ACTIVE or PAUSED */
32007+/* Pause can be applied only when status is ACTIVE */
32008+/* Restart can be applied only when status is PAUSED */
32009+typedef enum _mvCommand
32010+{
32011+ MV_START, /* Start */
32012+ MV_STOP, /* Stop */
32013+ MV_PAUSE, /* Pause */
32014+ MV_RESTART /* Restart */
32015+} MV_COMMAND;
32016+
32017+/* This enumerator describes the set of state conditions. */
32018+/* Moving from one state to other is stricted. */
32019+typedef enum _mvState
32020+{
32021+ MV_IDLE,
32022+ MV_ACTIVE,
32023+ MV_PAUSED,
32024+ MV_UNDEFINED_STATE
32025+} MV_STATE;
32026+
32027+
32028+/* This structure describes address space window. Window base can be */
32029+/* 64 bit, window size up to 4GB */
32030+typedef struct _mvAddrWin
32031+{
32032+ MV_U32 baseLow; /* 32bit base low */
32033+ MV_U32 baseHigh; /* 32bit base high */
32034+ MV_U32 size; /* 32bit size */
32035+}MV_ADDR_WIN;
32036+
32037+/* This binary enumerator describes protection attribute status */
32038+typedef enum _mvProtRight
32039+{
32040+ ALLOWED, /* Protection attribute allowed */
32041+ FORBIDDEN /* Protection attribute forbidden */
32042+}MV_PROT_RIGHT;
32043+
32044+/* Unified struct for Rx and Tx packet operations. The user is required to */
32045+/* be familier only with Tx/Rx descriptor command status. */
32046+typedef struct _bufInfo
32047+{
32048+ MV_U32 cmdSts; /* Tx/Rx command status */
32049+ MV_U16 byteCnt; /* Size of valid data in the buffer */
32050+ MV_U16 bufSize; /* Total size of the buffer */
32051+ MV_U8 *pBuff; /* Pointer to Buffer */
32052+ MV_U8 *pData; /* Pointer to data in the Buffer */
32053+ MV_U32 userInfo1; /* Tx/Rx attached user information 1 */
32054+ MV_U32 userInfo2; /* Tx/Rx attached user information 2 */
32055+ struct _bufInfo *pNextBufInfo; /* Next buffer in packet */
32056+} BUF_INFO;
32057+
32058+/* This structure contains information describing one of buffers
32059+ * (fragments) they are built Ethernet packet.
32060+ */
32061+typedef struct
32062+{
32063+ MV_U8* bufVirtPtr;
32064+ MV_ULONG bufPhysAddr;
32065+ MV_U32 bufSize;
32066+ MV_U32 dataSize;
32067+ MV_U32 memHandle;
32068+ MV_32 bufAddrShift;
32069+} MV_BUF_INFO;
32070+
32071+/* This structure contains information describing Ethernet packet.
32072+ * The packet can be divided for few buffers (fragments)
32073+ */
32074+typedef struct
32075+{
32076+ MV_ULONG osInfo;
32077+ MV_BUF_INFO *pFrags;
32078+ MV_U32 status;
32079+ MV_U16 pktSize;
32080+ MV_U16 numFrags;
32081+ MV_U32 ownerId;
32082+ MV_U32 fragIP;
32083+} MV_PKT_INFO;
32084+
32085+#endif /* MV_ASMLANGUAGE */
32086+
32087+#endif /* __INCmvTypesh */
32088+
32089diff --git a/crypto/ocf/kirkwood/mvHal/dbg-trace.c b/crypto/ocf/kirkwood/mvHal/dbg-trace.c
32090new file mode 100644
32091index 0000000..6576d35
32092--- /dev/null
32093+++ b/crypto/ocf/kirkwood/mvHal/dbg-trace.c
32094@@ -0,0 +1,110 @@
32095+#include <linux/kernel.h>
32096+#include <linux/slab.h>
32097+#include <linux/time.h>
32098+#include "dbg-trace.h"
32099+
32100+#define TRACE_ARR_LEN 800
32101+#define STR_LEN 128
32102+struct trace {
32103+ struct timeval tv;
32104+ char str[STR_LEN];
32105+ unsigned int callback_val1;
32106+ unsigned int callback_val2;
32107+ char valid;
32108+};
32109+static unsigned int (*trc_callback1) (unsigned char) = NULL;
32110+static unsigned int (*trc_callback2) (unsigned char) = NULL;
32111+static unsigned char trc_param1 = 0;
32112+static unsigned char trc_param2 = 0;
32113+struct trace *trc_arr;
32114+static int trc_index;
32115+static int trc_active = 0;
32116+
32117+void TRC_START()
32118+{
32119+ trc_active = 1;
32120+}
32121+
32122+void TRC_STOP()
32123+{
32124+ trc_active = 0;
32125+}
32126+
32127+void TRC_INIT(void *callback1, void *callback2, unsigned char callback1_param, unsigned char callback2_param)
32128+{
32129+ printk("Marvell debug tracing is on\n");
32130+ trc_arr = (struct trace *)kmalloc(TRACE_ARR_LEN*sizeof(struct trace),GFP_KERNEL);
32131+ if(trc_arr == NULL)
32132+ {
32133+ printk("Can't allocate Debug Trace buffer\n");
32134+ return;
32135+ }
32136+ memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));
32137+ trc_index = 0;
32138+ trc_callback1 = callback1;
32139+ trc_callback2 = callback2;
32140+ trc_param1 = callback1_param;
32141+ trc_param2 = callback2_param;
32142+}
32143+void TRC_REC(char *fmt,...)
32144+{
32145+ va_list args;
32146+ struct trace *trc = &trc_arr[trc_index];
32147+
32148+ if(trc_active == 0)
32149+ return;
32150+
32151+ do_gettimeofday(&trc->tv);
32152+ if(trc_callback1)
32153+ trc->callback_val1 = trc_callback1(trc_param1);
32154+ if(trc_callback2)
32155+ trc->callback_val2 = trc_callback2(trc_param2);
32156+ va_start(args, fmt);
32157+ vsprintf(trc->str,fmt,args);
32158+ va_end(args);
32159+ trc->valid = 1;
32160+ if((++trc_index) == TRACE_ARR_LEN) {
32161+ trc_index = 0;
32162+ }
32163+}
32164+void TRC_OUTPUT(void)
32165+{
32166+ int i,j;
32167+ struct trace *p;
32168+ printk("\n\nTrace %d items\n",TRACE_ARR_LEN);
32169+ for(i=0,j=trc_index; i<TRACE_ARR_LEN; i++,j++) {
32170+ if(j == TRACE_ARR_LEN)
32171+ j = 0;
32172+ p = &trc_arr[j];
32173+ if(p->valid) {
32174+ unsigned long uoffs;
32175+ struct trace *plast;
32176+ if(p == &trc_arr[0])
32177+ plast = &trc_arr[TRACE_ARR_LEN-1];
32178+ else
32179+ plast = p-1;
32180+ if(p->tv.tv_sec == ((plast)->tv.tv_sec))
32181+ uoffs = (p->tv.tv_usec - ((plast)->tv.tv_usec));
32182+ else
32183+ uoffs = (1000000 - ((plast)->tv.tv_usec)) +
32184+ ((p->tv.tv_sec - ((plast)->tv.tv_sec) - 1) * 1000000) +
32185+ p->tv.tv_usec;
32186+ printk("%03d: [+%ld usec]", j, (unsigned long)uoffs);
32187+ if(trc_callback1)
32188+ printk("[%u]",p->callback_val1);
32189+ if(trc_callback2)
32190+ printk("[%u]",p->callback_val2);
32191+ printk(": %s",p->str);
32192+ }
32193+ p->valid = 0;
32194+ }
32195+ memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));
32196+ trc_index = 0;
32197+}
32198+void TRC_RELEASE(void)
32199+{
32200+ kfree(trc_arr);
32201+ trc_index = 0;
32202+}
32203+
32204+
32205diff --git a/crypto/ocf/kirkwood/mvHal/dbg-trace.h b/crypto/ocf/kirkwood/mvHal/dbg-trace.h
32206new file mode 100644
32207index 0000000..e3dd480
32208--- /dev/null
32209+++ b/crypto/ocf/kirkwood/mvHal/dbg-trace.h
32210@@ -0,0 +1,24 @@
32211+
32212+#ifndef _MV_DBG_TRCE_H_
32213+#define _MV_DBG_TRCE_H_
32214+
32215+#ifdef CONFIG_MV_DBG_TRACE
32216+void TRC_INIT(void *callback1, void *callback2,
32217+ unsigned char callback1_param, unsigned char callback2_param);
32218+void TRC_REC(char *fmt,...);
32219+void TRC_OUTPUT(void);
32220+void TRC_RELEASE(void);
32221+void TRC_START(void);
32222+void TRC_STOP(void);
32223+
32224+#else
32225+#define TRC_INIT(x1,x2,x3,x4)
32226+#define TRC_REC(X...)
32227+#define TRC_OUTPUT()
32228+#define TRC_RELEASE()
32229+#define TRC_START()
32230+#define TRC_STOP()
32231+#endif
32232+
32233+
32234+#endif
32235diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c b/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c
32236new file mode 100644
32237index 0000000..8a6ba2c
32238--- /dev/null
32239+++ b/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c
32240@@ -0,0 +1,2513 @@
32241+/*******************************************************************************
32242+Copyright (C) Marvell International Ltd. and its affiliates
32243+
32244+This software file (the "File") is owned and distributed by Marvell
32245+International Ltd. and/or its affiliates ("Marvell") under the following
32246+alternative licensing terms. Once you have made an election to distribute the
32247+File under one of the following license alternatives, please (i) delete this
32248+introductory statement regarding license alternatives, (ii) delete the two
32249+license alternatives that you have not elected to use and (iii) preserve the
32250+Marvell copyright notice above.
32251+
32252+********************************************************************************
32253+Marvell Commercial License Option
32254+
32255+If you received this File from Marvell and you have entered into a commercial
32256+license agreement (a "Commercial License") with Marvell, the File is licensed
32257+to you under the terms of the applicable Commercial License.
32258+
32259+********************************************************************************
32260+Marvell GPL License Option
32261+
32262+If you received this File from Marvell, you may opt to use, redistribute and/or
32263+modify this File in accordance with the terms and conditions of the General
32264+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
32265+available along with the File in the license.txt file or by writing to the Free
32266+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
32267+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
32268+
32269+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
32270+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
32271+DISCLAIMED. The GPL License provides additional details about this warranty
32272+disclaimer.
32273+********************************************************************************
32274+Marvell BSD License Option
32275+
32276+If you received this File from Marvell, you may opt to use, redistribute and/or
32277+modify this File under the following licensing terms.
32278+Redistribution and use in source and binary forms, with or without modification,
32279+are permitted provided that the following conditions are met:
32280+
32281+ * Redistributions of source code must retain the above copyright notice,
32282+ this list of conditions and the following disclaimer.
32283+
32284+ * Redistributions in binary form must reproduce the above copyright
32285+ notice, this list of conditions and the following disclaimer in the
32286+ documentation and/or other materials provided with the distribution.
32287+
32288+ * Neither the name of Marvell nor the names of its contributors may be
32289+ used to endorse or promote products derived from this software without
32290+ specific prior written permission.
32291+
32292+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
32293+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32294+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
32295+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
32296+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32297+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32298+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
32299+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32300+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32301+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32302+
32303+*******************************************************************************/
32304+
32305+#include "boardEnv/mvBoardEnvLib.h"
32306+#include "ctrlEnv/mvCtrlEnvLib.h"
32307+#include "ctrlEnv/sys/mvCpuIf.h"
32308+#include "cpu/mvCpu.h"
32309+#include "cntmr/mvCntmr.h"
32310+#include "gpp/mvGpp.h"
32311+#include "twsi/mvTwsi.h"
32312+#include "pex/mvPex.h"
32313+#include "device/mvDevice.h"
32314+#include "eth/gbe/mvEthRegs.h"
32315+
32316+/* defines */
32317+/* #define MV_DEBUG */
32318+#ifdef MV_DEBUG
32319+ #define DB(x) x
32320+#else
32321+ #define DB(x)
32322+#endif
32323+
32324+extern MV_CPU_ARM_CLK _cpuARMDDRCLK[];
32325+
32326+#define CODE_IN_ROM MV_FALSE
32327+#define CODE_IN_RAM MV_TRUE
32328+
32329+extern MV_BOARD_INFO* boardInfoTbl[];
32330+#define BOARD_INFO(boardId) boardInfoTbl[boardId - BOARD_ID_BASE]
32331+
32332+/* Locals */
32333+static MV_DEV_CS_INFO* boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
32334+
32335+MV_U32 tClkRate = -1;
32336+
32337+
32338+/*******************************************************************************
32339+* mvBoardEnvInit - Init board
32340+*
32341+* DESCRIPTION:
32342+* In this function the board environment take care of device bank
32343+* initialization.
32344+*
32345+* INPUT:
32346+* None.
32347+*
32348+* OUTPUT:
32349+* None.
32350+*
32351+* RETURN:
32352+* None.
32353+*
32354+*******************************************************************************/
32355+MV_VOID mvBoardEnvInit(MV_VOID)
32356+{
32357+ MV_U32 boardId= mvBoardIdGet();
32358+
32359+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
32360+ {
32361+ mvOsPrintf("mvBoardEnvInit:Board unknown.\n");
32362+ return;
32363+
32364+ }
32365+
32366+ /* Set GPP Out value */
32367+ MV_REG_WRITE(GPP_DATA_OUT_REG(0), BOARD_INFO(boardId)->gppOutValLow);
32368+ MV_REG_WRITE(GPP_DATA_OUT_REG(1), BOARD_INFO(boardId)->gppOutValHigh);
32369+
32370+ /* set GPP polarity */
32371+ mvGppPolaritySet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValLow);
32372+ mvGppPolaritySet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValHigh);
32373+
32374+ /* Workaround for Erratum FE-MISC-70*/
32375+ if(mvCtrlRevGet()==MV_88F6XXX_A0_REV)
32376+ {
32377+ BOARD_INFO(boardId)->gppOutEnValLow &= 0xfffffffd;
32378+ BOARD_INFO(boardId)->gppOutEnValLow |= (BOARD_INFO(boardId)->gppOutEnValHigh) & 0x00000002;
32379+ } /*End of WA*/
32380+
32381+ /* Set GPP Out Enable*/
32382+ mvGppTypeSet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValLow);
32383+ mvGppTypeSet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValHigh);
32384+
32385+ /* Nand CE */
32386+ MV_REG_BIT_SET(NAND_CTRL_REG, NAND_ACTCEBOOT_BIT);
32387+}
32388+
32389+/*******************************************************************************
32390+* mvBoardModelGet - Get Board model
32391+*
32392+* DESCRIPTION:
32393+* This function returns 16bit describing board model.
32394+* Board model is constructed of one byte major and minor numbers in the
32395+* following manner:
32396+*
32397+* INPUT:
32398+* None.
32399+*
32400+* OUTPUT:
32401+* None.
32402+*
32403+* RETURN:
32404+* String describing board model.
32405+*
32406+*******************************************************************************/
32407+MV_U16 mvBoardModelGet(MV_VOID)
32408+{
32409+ return (mvBoardIdGet() >> 16);
32410+}
32411+
32412+/*******************************************************************************
32413+* mbBoardRevlGet - Get Board revision
32414+*
32415+* DESCRIPTION:
32416+* This function returns a 32bit describing the board revision.
32417+* Board revision is constructed of 4bytes. 2bytes describes major number
32418+* and the other 2bytes describes minor munber.
32419+* For example for board revision 3.4 the function will return
32420+* 0x00030004.
32421+*
32422+* INPUT:
32423+* None.
32424+*
32425+* OUTPUT:
32426+* None.
32427+*
32428+* RETURN:
32429+* String describing board model.
32430+*
32431+*******************************************************************************/
32432+MV_U16 mvBoardRevGet(MV_VOID)
32433+{
32434+ return (mvBoardIdGet() & 0xFFFF);
32435+}
32436+
32437+/*******************************************************************************
32438+* mvBoardNameGet - Get Board name
32439+*
32440+* DESCRIPTION:
32441+* This function returns a string describing the board model and revision.
32442+* String is extracted from board I2C EEPROM.
32443+*
32444+* INPUT:
32445+* None.
32446+*
32447+* OUTPUT:
32448+* pNameBuff - Buffer to contain board name string. Minimum size 32 chars.
32449+*
32450+* RETURN:
32451+*
32452+* MV_ERROR if informantion can not be read.
32453+*******************************************************************************/
32454+MV_STATUS mvBoardNameGet(char *pNameBuff)
32455+{
32456+ MV_U32 boardId= mvBoardIdGet();
32457+
32458+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
32459+ {
32460+ mvOsSPrintf (pNameBuff, "Board unknown.\n");
32461+ return MV_ERROR;
32462+
32463+ }
32464+
32465+ mvOsSPrintf (pNameBuff, "%s",BOARD_INFO(boardId)->boardName);
32466+
32467+ return MV_OK;
32468+}
32469+
32470+/*******************************************************************************
32471+* mvBoardIsPortInSgmii -
32472+*
32473+* DESCRIPTION:
32474+* This routine returns MV_TRUE for port number works in SGMII or MV_FALSE
32475+* For all other options.
32476+*
32477+* INPUT:
32478+* ethPortNum - Ethernet port number.
32479+*
32480+* OUTPUT:
32481+* None.
32482+*
32483+* RETURN:
32484+* MV_TRUE - port in SGMII.
32485+* MV_FALSE - other.
32486+*
32487+*******************************************************************************/
32488+MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum)
32489+{
32490+ MV_BOOL ethPortSgmiiSupport[BOARD_ETH_PORT_NUM] = MV_ETH_PORT_SGMII;
32491+
32492+ if(ethPortNum >= BOARD_ETH_PORT_NUM)
32493+ {
32494+ mvOsPrintf ("Invalid portNo=%d\n", ethPortNum);
32495+ return MV_FALSE;
32496+ }
32497+ return ethPortSgmiiSupport[ethPortNum];
32498+}
32499+
32500+/*******************************************************************************
32501+* mvBoardIsPortInGmii -
32502+*
32503+* DESCRIPTION:
32504+* This routine returns MV_TRUE for port number works in GMII or MV_FALSE
32505+* For all other options.
32506+*
32507+* INPUT:
32508+*
32509+* OUTPUT:
32510+* None.
32511+*
32512+* RETURN:
32513+* MV_TRUE - port in GMII.
32514+* MV_FALSE - other.
32515+*
32516+*******************************************************************************/
32517+MV_BOOL mvBoardIsPortInGmii(MV_VOID)
32518+{
32519+ MV_U32 devClassId, devClass = 0;
32520+ if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)
32521+ {
32522+ /* Get MPP module ID */
32523+ devClassId = mvBoarModuleTypeGet(devClass);
32524+ if (MV_BOARD_MODULE_GMII_ID == devClassId)
32525+ return MV_TRUE;
32526+ }
32527+ else if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII)
32528+ return MV_TRUE;
32529+
32530+ return MV_FALSE;
32531+}
32532+/*******************************************************************************
32533+* mvBoardPhyAddrGet - Get the phy address
32534+*
32535+* DESCRIPTION:
32536+* This routine returns the Phy address of a given ethernet port.
32537+*
32538+* INPUT:
32539+* ethPortNum - Ethernet port number.
32540+*
32541+* OUTPUT:
32542+* None.
32543+*
32544+* RETURN:
32545+* 32bit describing Phy address, -1 if the port number is wrong.
32546+*
32547+*******************************************************************************/
32548+MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum)
32549+{
32550+ MV_U32 boardId= mvBoardIdGet();
32551+
32552+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
32553+ {
32554+ mvOsPrintf("mvBoardPhyAddrGet: Board unknown.\n");
32555+ return MV_ERROR;
32556+ }
32557+
32558+ return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardEthSmiAddr;
32559+}
32560+
32561+/*******************************************************************************
32562+* mvBoardMacSpeedGet - Get the Mac speed
32563+*
32564+* DESCRIPTION:
32565+* This routine returns the Mac speed if pre define of a given ethernet port.
32566+*
32567+* INPUT:
32568+* ethPortNum - Ethernet port number.
32569+*
32570+* OUTPUT:
32571+* None.
32572+*
32573+* RETURN:
32574+* MV_BOARD_MAC_SPEED, -1 if the port number is wrong.
32575+*
32576+*******************************************************************************/
32577+MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum)
32578+{
32579+ MV_U32 boardId= mvBoardIdGet();
32580+
32581+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
32582+ {
32583+ mvOsPrintf("mvBoardMacSpeedGet: Board unknown.\n");
32584+ return MV_ERROR;
32585+ }
32586+
32587+ return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardMacSpeed;
32588+}
32589+
32590+/*******************************************************************************
32591+* mvBoardLinkStatusIrqGet - Get the IRQ number for the link status indication
32592+*
32593+* DESCRIPTION:
32594+* This routine returns the IRQ number for the link status indication.
32595+*
32596+* INPUT:
32597+* ethPortNum - Ethernet port number.
32598+*
32599+* OUTPUT:
32600+* None.
32601+*
32602+* RETURN:
32603+* the number of the IRQ for the link status indication, -1 if the port
32604+* number is wrong or if not relevant.
32605+*
32606+*******************************************************************************/
32607+MV_32 mvBoardLinkStatusIrqGet(MV_U32 ethPortNum)
32608+{
32609+ MV_U32 boardId = mvBoardIdGet();
32610+
32611+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
32612+ {
32613+ mvOsPrintf("mvBoardLinkStatusIrqGet: Board unknown.\n");
32614+ return MV_ERROR;
32615+ }
32616+
32617+ return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].linkStatusIrq;
32618+}
32619+
32620+/*******************************************************************************
32621+* mvBoardSwitchPortGet - Get the mapping between the board connector and the
32622+* Ethernet Switch port
32623+*
32624+* DESCRIPTION:
32625+* This routine returns the matching Switch port.
32626+*
32627+* INPUT:
32628+* ethPortNum - Ethernet port number.
32629+* boardPortNum - logical number of the connector on the board
32630+*
32631+* OUTPUT:
32632+* None.
32633+*
32634+* RETURN:
32635+* the matching Switch port, -1 if the port number is wrong or if not relevant.
32636+*
32637+*******************************************************************************/
32638+MV_32 mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum)
32639+{
32640+ MV_U32 boardId = mvBoardIdGet();
32641+
32642+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
32643+ {
32644+ mvOsPrintf("mvBoardSwitchPortGet: Board unknown.\n");
32645+ return MV_ERROR;
32646+ }
32647+ if (boardPortNum >= BOARD_ETH_SWITCH_PORT_NUM)
32648+ {
32649+ mvOsPrintf("mvBoardSwitchPortGet: Illegal board port number.\n");
32650+ return MV_ERROR;
32651+ }
32652+
32653+ return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdPort[boardPortNum];
32654+}
32655+
32656+/*******************************************************************************
32657+* mvBoardSwitchCpuPortGet - Get the the Ethernet Switch CPU port
32658+*
32659+* DESCRIPTION:
32660+* This routine returns the Switch CPU port.
32661+*
32662+* INPUT:
32663+* ethPortNum - Ethernet port number.
32664+*
32665+* OUTPUT:
32666+* None.
32667+*
32668+* RETURN:
32669+* the Switch CPU port, -1 if the port number is wrong or if not relevant.
32670+*
32671+*******************************************************************************/
32672+MV_32 mvBoardSwitchCpuPortGet(MV_U32 ethPortNum)
32673+{
32674+ MV_U32 boardId = mvBoardIdGet();
32675+
32676+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
32677+ {
32678+ mvOsPrintf("mvBoardSwitchCpuPortGet: Board unknown.\n");
32679+ return MV_ERROR;
32680+ }
32681+
32682+ return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdCpuPort;
32683+}
32684+
32685+/*******************************************************************************
32686+* mvBoardIsSwitchConnected - Get switch connection status
32687+* DESCRIPTION:
32688+* This routine returns port's connection status
32689+*
32690+* INPUT:
32691+* ethPortNum - Ethernet port number.
32692+*
32693+* OUTPUT:
32694+* None.
32695+*
32696+* RETURN:
32697+* 1 - if ethPortNum is connected to switch, 0 otherwise
32698+*
32699+*******************************************************************************/
32700+MV_32 mvBoardIsSwitchConnected(MV_U32 ethPortNum)
32701+{
32702+ MV_U32 boardId = mvBoardIdGet();
32703+
32704+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
32705+ {
32706+ mvOsPrintf("mvBoardIsSwitchConnected: Board unknown.\n");
32707+ return MV_ERROR;
32708+ }
32709+
32710+ if(ethPortNum >= BOARD_INFO(boardId)->numBoardMacInfo)
32711+ {
32712+ mvOsPrintf("mvBoardIsSwitchConnected: Illegal port number(%u)\n", ethPortNum);
32713+ return MV_ERROR;
32714+ }
32715+
32716+ if((MV_32)(BOARD_INFO(boardId)->pSwitchInfo))
32717+ return (MV_32)(BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].switchOnPort == ethPortNum);
32718+ else
32719+ return 0;
32720+}
32721+/*******************************************************************************
32722+* mvBoardSmiScanModeGet - Get Switch SMI scan mode
32723+*
32724+* DESCRIPTION:
32725+* This routine returns Switch SMI scan mode.
32726+*
32727+* INPUT:
32728+* ethPortNum - Ethernet port number.
32729+*
32730+* OUTPUT:
32731+* None.
32732+*
32733+* RETURN:
32734+* 1 for SMI_MANUAL_MODE, -1 if the port number is wrong or if not relevant.
32735+*
32736+*******************************************************************************/
32737+MV_32 mvBoardSmiScanModeGet(MV_U32 ethPortNum)
32738+{
32739+ MV_U32 boardId = mvBoardIdGet();
32740+
32741+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
32742+ {
32743+ mvOsPrintf("mvBoardSmiScanModeGet: Board unknown.\n");
32744+ return MV_ERROR;
32745+ }
32746+
32747+ return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].smiScanMode;
32748+}
32749+/*******************************************************************************
32750+* mvBoardSpecInitGet -
32751+*
32752+* DESCRIPTION:
32753+*
32754+* INPUT:
32755+*
32756+* OUTPUT:
32757+* None.
32758+*
32759+* RETURN: Return MV_TRUE and parameters in case board need spesific phy init,
32760+* otherwise return MV_FALSE.
32761+*
32762+*
32763+*******************************************************************************/
32764+
32765+MV_BOOL mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data)
32766+{
32767+ return MV_FALSE;
32768+}
32769+
32770+/*******************************************************************************
32771+* mvBoardTclkGet - Get the board Tclk (Controller clock)
32772+*
32773+* DESCRIPTION:
32774+* This routine extract the controller core clock.
32775+* This function uses the controller counters to make identification.
32776+* Note: In order to avoid interference, make sure task context switch
32777+* and interrupts will not occure during this function operation
32778+*
32779+* INPUT:
32780+* countNum - Counter number.
32781+*
32782+* OUTPUT:
32783+* None.
32784+*
32785+* RETURN:
32786+* 32bit clock cycles in Hertz.
32787+*
32788+*******************************************************************************/
32789+MV_U32 mvBoardTclkGet(MV_VOID)
32790+{
32791+ if(mvCtrlModelGet()==MV_6281_DEV_ID)
32792+ {
32793+#if defined(TCLK_AUTO_DETECT)
32794+ MV_U32 tmpTClkRate = MV_BOARD_TCLK_166MHZ;
32795+
32796+ tmpTClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
32797+ tmpTClkRate &= MSAR_TCLCK_MASK;
32798+
32799+ switch (tmpTClkRate)
32800+ {
32801+ case MSAR_TCLCK_166:
32802+ return MV_BOARD_TCLK_166MHZ;
32803+ break;
32804+ case MSAR_TCLCK_200:
32805+ return MV_BOARD_TCLK_200MHZ;
32806+ break;
32807+ }
32808+#else
32809+ return MV_BOARD_TCLK_200MHZ;
32810+#endif
32811+ }
32812+
32813+ return MV_BOARD_TCLK_166MHZ;
32814+
32815+}
32816+/*******************************************************************************
32817+* mvBoardSysClkGet - Get the board SysClk (CPU bus clock)
32818+*
32819+* DESCRIPTION:
32820+* This routine extract the CPU bus clock.
32821+*
32822+* INPUT:
32823+* countNum - Counter number.
32824+*
32825+* OUTPUT:
32826+* None.
32827+*
32828+* RETURN:
32829+* 32bit clock cycles in Hertz.
32830+*
32831+*******************************************************************************/
32832+static MV_U32 mvBoard6180SysClkGet(MV_VOID)
32833+{
32834+ MV_U32 sysClkRate=0;
32835+ MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
32836+
32837+ sysClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
32838+ sysClkRate = sysClkRate & MSAR_CPUCLCK_MASK_6180;
32839+ sysClkRate = sysClkRate >> MSAR_CPUCLCK_OFFS_6180;
32840+
32841+ sysClkRate = _cpu6180_ddr_l2_CLK[sysClkRate].ddrClk;
32842+
32843+ return sysClkRate;
32844+
32845+}
32846+
32847+MV_U32 mvBoardSysClkGet(MV_VOID)
32848+{
32849+#ifdef SYSCLK_AUTO_DETECT
32850+ MV_U32 sysClkRate, tmp, pClkRate, indexDdrRtio;
32851+ MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;
32852+ MV_U32 ddrRtio[][2] = MV_DDR_CLCK_RTIO_TBL;
32853+
32854+ if(mvCtrlModelGet() == MV_6180_DEV_ID)
32855+ return mvBoard6180SysClkGet();
32856+
32857+ tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);
32858+ pClkRate = MSAR_CPUCLCK_EXTRACT(tmp);
32859+ pClkRate = cpuCLK[pClkRate];
32860+
32861+ indexDdrRtio = tmp & MSAR_DDRCLCK_RTIO_MASK;
32862+ indexDdrRtio = indexDdrRtio >> MSAR_DDRCLCK_RTIO_OFFS;
32863+ if(ddrRtio[indexDdrRtio][0] != 0)
32864+ sysClkRate = ((pClkRate * ddrRtio[indexDdrRtio][1]) / ddrRtio[indexDdrRtio][0]);
32865+ else
32866+ sysClkRate = 0;
32867+ return sysClkRate;
32868+#else
32869+ return MV_BOARD_DEFAULT_SYSCLK;
32870+#endif
32871+}
32872+
32873+
32874+/*******************************************************************************
32875+* mvBoardPexBridgeIntPinGet - Get PEX to PCI bridge interrupt pin number
32876+*
32877+* DESCRIPTION:
32878+* Multi-ported PCI Express bridges that is implemented on the board
32879+* collapse interrupts across multiple conventional PCI/PCI-X buses.
32880+* A dual-headed PCI Express bridge would map (or "swizzle") the
32881+* interrupts per the following table (in accordance with the respective
32882+* logical PCI/PCI-X bridge's Device Number), collapse the INTA#-INTD#
32883+* signals from its two logical PCI/PCI-X bridges, collapse the
32884+* INTA#-INTD# signals from any internal sources, and convert the
32885+* signals to in-band PCI Express messages. 10
32886+* This function returns the upstream interrupt as it was converted by
32887+* the bridge, according to board configuration and the following table:
32888+* PCI dev num
32889+* Interrupt pin 7, 8, 9
32890+* A -> A D C
32891+* B -> B A D
32892+* C -> C B A
32893+* D -> D C B
32894+*
32895+*
32896+* INPUT:
32897+* devNum - PCI/PCIX device number.
32898+* intPin - PCI Int pin
32899+*
32900+* OUTPUT:
32901+* None.
32902+*
32903+* RETURN:
32904+* Int pin connected to the Interrupt controller
32905+*
32906+*******************************************************************************/
32907+MV_U32 mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin)
32908+{
32909+ MV_U32 realIntPin = ((intPin + (3 - (devNum % 4))) %4 );
32910+
32911+ if (realIntPin == 0) return 4;
32912+ else return realIntPin;
32913+
32914+}
32915+
32916+/*******************************************************************************
32917+* mvBoardDebugLedNumGet - Get number of debug Leds
32918+*
32919+* DESCRIPTION:
32920+* INPUT:
32921+* boardId
32922+*
32923+* OUTPUT:
32924+* None.
32925+*
32926+* RETURN:
32927+* None.
32928+*
32929+*******************************************************************************/
32930+MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId)
32931+{
32932+ return BOARD_INFO(boardId)->activeLedsNumber;
32933+}
32934+
32935+/*******************************************************************************
32936+* mvBoardDebugLeg - Set the board debug Leds
32937+*
32938+* DESCRIPTION: turn on/off status leds.
32939+* Note: assume MPP leds are part of group 0 only.
32940+*
32941+* INPUT:
32942+* hexNum - Number to be displied in hex by Leds.
32943+*
32944+* OUTPUT:
32945+* None.
32946+*
32947+* RETURN:
32948+* None.
32949+*
32950+*******************************************************************************/
32951+MV_VOID mvBoardDebugLed(MV_U32 hexNum)
32952+{
32953+ MV_U32 val = 0,totalMask, currentBitMask = 1,i;
32954+ MV_U32 boardId= mvBoardIdGet();
32955+
32956+ if (BOARD_INFO(boardId)->pLedGppPin == NULL)
32957+ return;
32958+
32959+ totalMask = (1 << BOARD_INFO(boardId)->activeLedsNumber) -1;
32960+ hexNum &= totalMask;
32961+ totalMask = 0;
32962+
32963+ for (i = 0 ; i < BOARD_INFO(boardId)->activeLedsNumber ; i++)
32964+ {
32965+ if (hexNum & currentBitMask)
32966+ {
32967+ val |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);
32968+ }
32969+
32970+ totalMask |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);
32971+
32972+ currentBitMask = (currentBitMask << 1);
32973+ }
32974+
32975+ if (BOARD_INFO(boardId)->ledsPolarity)
32976+ {
32977+ mvGppValueSet(0, totalMask, val);
32978+ }
32979+ else
32980+ {
32981+ mvGppValueSet(0, totalMask, ~val);
32982+ }
32983+}
32984+
32985+
32986+/*******************************************************************************
32987+* mvBoarGpioPinGet - mvBoarGpioPinGet
32988+*
32989+* DESCRIPTION:
32990+*
32991+* INPUT:
32992+* class - MV_BOARD_GPP_CLASS enum.
32993+*
32994+* OUTPUT:
32995+* None.
32996+*
32997+* RETURN:
32998+* GPIO pin number. The function return -1 for bad parameters.
32999+*
33000+*******************************************************************************/
33001+MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index)
33002+{
33003+ MV_U32 boardId, i;
33004+ MV_U32 indexFound = 0;
33005+
33006+ boardId = mvBoardIdGet();
33007+
33008+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
33009+ {
33010+ mvOsPrintf("mvBoardRTCGpioPinGet:Board unknown.\n");
33011+ return MV_ERROR;
33012+
33013+ }
33014+
33015+ for (i = 0; i < BOARD_INFO(boardId)->numBoardGppInfo; i++)
33016+ if (BOARD_INFO(boardId)->pBoardGppInfo[i].devClass == class) {
33017+ if (indexFound == index)
33018+ return (MV_U32)BOARD_INFO(boardId)->pBoardGppInfo[i].gppPinNum;
33019+ else
33020+ indexFound++;
33021+
33022+ }
33023+
33024+ return MV_ERROR;
33025+}
33026+
33027+
33028+/*******************************************************************************
33029+* mvBoardRTCGpioPinGet - mvBoardRTCGpioPinGet
33030+*
33031+* DESCRIPTION:
33032+*
33033+* INPUT:
33034+* None.
33035+*
33036+* OUTPUT:
33037+* None.
33038+*
33039+* RETURN:
33040+* GPIO pin number. The function return -1 for bad parameters.
33041+*
33042+*******************************************************************************/
33043+MV_32 mvBoardRTCGpioPinGet(MV_VOID)
33044+{
33045+ return mvBoarGpioPinNumGet(BOARD_GPP_RTC, 0);
33046+}
33047+
33048+
33049+/*******************************************************************************
33050+* mvBoardReset - mvBoardReset
33051+*
33052+* DESCRIPTION:
33053+* Reset the board
33054+* INPUT:
33055+* None.
33056+*
33057+* OUTPUT:
33058+* None.
33059+*
33060+* RETURN:
33061+* None
33062+*
33063+*******************************************************************************/
33064+MV_VOID mvBoardReset(MV_VOID)
33065+{
33066+ MV_32 resetPin;
33067+
33068+ /* Get gpp reset pin if define */
33069+ resetPin = mvBoardResetGpioPinGet();
33070+ if (resetPin != MV_ERROR)
33071+ {
33072+ MV_REG_BIT_RESET( GPP_DATA_OUT_REG(0) ,(1 << resetPin));
33073+ MV_REG_BIT_RESET( GPP_DATA_OUT_EN_REG(0) ,(1 << resetPin));
33074+
33075+ }
33076+ else
33077+ {
33078+ /* No gpp reset pin was found, try to reset ussing
33079+ system reset out */
33080+ MV_REG_BIT_SET( CPU_RSTOUTN_MASK_REG , BIT2);
33081+ MV_REG_BIT_SET( CPU_SYS_SOFT_RST_REG , BIT0);
33082+ }
33083+}
33084+
33085+/*******************************************************************************
33086+* mvBoardResetGpioPinGet - mvBoardResetGpioPinGet
33087+*
33088+* DESCRIPTION:
33089+*
33090+* INPUT:
33091+* None.
33092+*
33093+* OUTPUT:
33094+* None.
33095+*
33096+* RETURN:
33097+* GPIO pin number. The function return -1 for bad parameters.
33098+*
33099+*******************************************************************************/
33100+MV_32 mvBoardResetGpioPinGet(MV_VOID)
33101+{
33102+ return mvBoarGpioPinNumGet(BOARD_GPP_RESET, 0);
33103+}
33104+/*******************************************************************************
33105+* mvBoardSDIOGpioPinGet - mvBoardSDIOGpioPinGet
33106+*
33107+* DESCRIPTION:
33108+* used for hotswap detection
33109+* INPUT:
33110+* None.
33111+*
33112+* OUTPUT:
33113+* None.
33114+*
33115+* RETURN:
33116+* GPIO pin number. The function return -1 for bad parameters.
33117+*
33118+*******************************************************************************/
33119+MV_32 mvBoardSDIOGpioPinGet(MV_VOID)
33120+{
33121+ return mvBoarGpioPinNumGet(BOARD_GPP_SDIO_DETECT, 0);
33122+}
33123+
33124+/*******************************************************************************
33125+* mvBoardUSBVbusGpioPinGet - return Vbus input GPP
33126+*
33127+* DESCRIPTION:
33128+*
33129+* INPUT:
33130+* int devNo.
33131+*
33132+* OUTPUT:
33133+* None.
33134+*
33135+* RETURN:
33136+* GPIO pin number. The function return -1 for bad parameters.
33137+*
33138+*******************************************************************************/
33139+MV_32 mvBoardUSBVbusGpioPinGet(MV_32 devId)
33140+{
33141+ return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS, devId);
33142+}
33143+
33144+/*******************************************************************************
33145+* mvBoardUSBVbusEnGpioPinGet - return Vbus Enable output GPP
33146+*
33147+* DESCRIPTION:
33148+*
33149+* INPUT:
33150+* int devNo.
33151+*
33152+* OUTPUT:
33153+* None.
33154+*
33155+* RETURN:
33156+* GPIO pin number. The function return -1 for bad parameters.
33157+*
33158+*******************************************************************************/
33159+MV_32 mvBoardUSBVbusEnGpioPinGet(MV_32 devId)
33160+{
33161+ return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS_EN, devId);
33162+}
33163+
33164+
33165+/*******************************************************************************
33166+* mvBoardGpioIntMaskGet - Get GPIO mask for interrupt pins
33167+*
33168+* DESCRIPTION:
33169+* This function returns a 32-bit mask of GPP pins that connected to
33170+* interrupt generating sources on board.
33171+* For example if UART channel A is hardwired to GPP pin 8 and
33172+* UART channel B is hardwired to GPP pin 4 the fuinction will return
33173+* the value 0x000000110
33174+*
33175+* INPUT:
33176+* None.
33177+*
33178+* OUTPUT:
33179+* None.
33180+*
33181+* RETURN:
33182+* See description. The function return -1 if board is not identified.
33183+*
33184+*******************************************************************************/
33185+MV_32 mvBoardGpioIntMaskLowGet(MV_VOID)
33186+{
33187+ MV_U32 boardId;
33188+
33189+ boardId = mvBoardIdGet();
33190+
33191+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
33192+ {
33193+ mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");
33194+ return MV_ERROR;
33195+
33196+ }
33197+
33198+ return BOARD_INFO(boardId)->intsGppMaskLow;
33199+}
33200+MV_32 mvBoardGpioIntMaskHighGet(MV_VOID)
33201+{
33202+ MV_U32 boardId;
33203+
33204+ boardId = mvBoardIdGet();
33205+
33206+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
33207+ {
33208+ mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");
33209+ return MV_ERROR;
33210+
33211+ }
33212+
33213+ return BOARD_INFO(boardId)->intsGppMaskHigh;
33214+}
33215+
33216+
33217+/*******************************************************************************
33218+* mvBoardMppGet - Get board dependent MPP register value
33219+*
33220+* DESCRIPTION:
33221+* MPP settings are derived from board design.
33222+* MPP group consist of 8 MPPs. An MPP group represent MPP
33223+* control register.
33224+* This function retrieves board dependend MPP register value.
33225+*
33226+* INPUT:
33227+* mppGroupNum - MPP group number.
33228+*
33229+* OUTPUT:
33230+* None.
33231+*
33232+* RETURN:
33233+* 32bit value describing MPP control register value.
33234+*
33235+*******************************************************************************/
33236+MV_32 mvBoardMppGet(MV_U32 mppGroupNum)
33237+{
33238+ MV_U32 boardId;
33239+
33240+ boardId = mvBoardIdGet();
33241+
33242+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
33243+ {
33244+ mvOsPrintf("mvBoardMppGet:Board unknown.\n");
33245+ return MV_ERROR;
33246+
33247+ }
33248+
33249+ return BOARD_INFO(boardId)->pBoardMppConfigValue[0].mppGroup[mppGroupNum];
33250+}
33251+
33252+
33253+/*******************************************************************************
33254+* mvBoardMppGroupId - If MPP group type is AUTO then identify it using twsi
33255+*
33256+* DESCRIPTION:
33257+*
33258+* INPUT:
33259+*
33260+* OUTPUT:
33261+* None.
33262+*
33263+* RETURN:
33264+*
33265+*******************************************************************************/
33266+MV_VOID mvBoardMppGroupIdUpdate(MV_VOID)
33267+{
33268+
33269+ MV_BOARD_MPP_GROUP_CLASS devClass;
33270+ MV_BOARD_MODULE_ID_CLASS devClassId;
33271+ MV_BOARD_MPP_TYPE_CLASS mppGroupType;
33272+ MV_U32 devId;
33273+ MV_U32 maxMppGrp = 1;
33274+
33275+ devId = mvCtrlModelGet();
33276+
33277+ switch(devId){
33278+ case MV_6281_DEV_ID:
33279+ maxMppGrp = MV_6281_MPP_MAX_MODULE;
33280+ break;
33281+ case MV_6192_DEV_ID:
33282+ maxMppGrp = MV_6192_MPP_MAX_MODULE;
33283+ break;
33284+ case MV_6190_DEV_ID:
33285+ maxMppGrp = MV_6190_MPP_MAX_MODULE;
33286+ break;
33287+ case MV_6180_DEV_ID:
33288+ maxMppGrp = MV_6180_MPP_MAX_MODULE;
33289+ break;
33290+ }
33291+
33292+ for (devClass = 0; devClass < maxMppGrp; devClass++)
33293+ {
33294+ /* If MPP group can be defined by the module connected to it */
33295+ if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)
33296+ {
33297+ /* Get MPP module ID */
33298+ devClassId = mvBoarModuleTypeGet(devClass);
33299+ if (MV_ERROR != devClassId)
33300+ {
33301+ switch(devClassId)
33302+ {
33303+ case MV_BOARD_MODULE_TDM_ID:
33304+ case MV_BOARD_MODULE_TDM_5CHAN_ID:
33305+ mppGroupType = MV_BOARD_TDM;
33306+ break;
33307+ case MV_BOARD_MODULE_AUDIO_ID:
33308+ mppGroupType = MV_BOARD_AUDIO;
33309+ break;
33310+ case MV_BOARD_MODULE_RGMII_ID:
33311+ mppGroupType = MV_BOARD_RGMII;
33312+ break;
33313+ case MV_BOARD_MODULE_GMII_ID:
33314+ mppGroupType = MV_BOARD_GMII;
33315+ break;
33316+ case MV_BOARD_MODULE_TS_ID:
33317+ mppGroupType = MV_BOARD_TS;
33318+ break;
33319+ case MV_BOARD_MODULE_MII_ID:
33320+ mppGroupType = MV_BOARD_MII;
33321+ break;
33322+ default:
33323+ mppGroupType = MV_BOARD_OTHER;
33324+ break;
33325+ }
33326+ }
33327+ else
33328+ /* The module bay is empty */
33329+ mppGroupType = MV_BOARD_OTHER;
33330+
33331+ /* Update MPP group type */
33332+ mvBoardMppGroupTypeSet(devClass, mppGroupType);
33333+ }
33334+
33335+ /* Update MPP output voltage for RGMII 1.8V. Set port to GMII for GMII module */
33336+ if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_RGMII))
33337+ MV_REG_BIT_SET(MPP_OUTPUT_DRIVE_REG,MPP_1_8_RGMII1_OUTPUT_DRIVE | MPP_1_8_RGMII0_OUTPUT_DRIVE);
33338+ else
33339+ {
33340+ if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII))
33341+ {
33342+ MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);
33343+ MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(0),BIT3);
33344+ MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);
33345+ }
33346+ else if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_MII))
33347+ {
33348+ /* Assumption that the MDC & MDIO should be 3.3V */
33349+ MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);
33350+ /* Assumption that only ETH1 can be MII when using modules on DB */
33351+ MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);
33352+ }
33353+ }
33354+ }
33355+}
33356+
33357+/*******************************************************************************
33358+* mvBoardMppGroupTypeGet
33359+*
33360+* DESCRIPTION:
33361+*
33362+* INPUT:
33363+* mppGroupClass - MPP group number 0 for MPP[35:20] or 1 for MPP[49:36].
33364+*
33365+* OUTPUT:
33366+* None.
33367+*
33368+* RETURN:
33369+*
33370+*******************************************************************************/
33371+MV_BOARD_MPP_TYPE_CLASS mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass)
33372+{
33373+ MV_U32 boardId;
33374+
33375+ boardId = mvBoardIdGet();
33376+
33377+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
33378+ {
33379+ mvOsPrintf("mvBoardMppGet:Board unknown.\n");
33380+ return MV_ERROR;
33381+
33382+ }
33383+
33384+ if (mppGroupClass == MV_BOARD_MPP_GROUP_1)
33385+ return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1;
33386+ else
33387+ return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2;
33388+}
33389+
33390+/*******************************************************************************
33391+* mvBoardMppGroupTypeSet
33392+*
33393+* DESCRIPTION:
33394+*
33395+* INPUT:
33396+* mppGroupClass - MPP group number 0 for MPP[35:20] or 1 for MPP[49:36].
33397+* mppGroupType - MPP group type for MPP[35:20] or for MPP[49:36].
33398+*
33399+* OUTPUT:
33400+* None.
33401+*
33402+* RETURN:
33403+*
33404+*******************************************************************************/
33405+MV_VOID mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,
33406+ MV_BOARD_MPP_TYPE_CLASS mppGroupType)
33407+{
33408+ MV_U32 boardId;
33409+
33410+ boardId = mvBoardIdGet();
33411+
33412+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
33413+ {
33414+ mvOsPrintf("mvBoardMppGet:Board unknown.\n");
33415+ }
33416+
33417+ if (mppGroupClass == MV_BOARD_MPP_GROUP_1)
33418+ BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1 = mppGroupType;
33419+ else
33420+ BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2 = mppGroupType;
33421+
33422+}
33423+
33424+/*******************************************************************************
33425+* mvBoardMppMuxSet - Update MPP mux
33426+*
33427+* DESCRIPTION:
33428+*
33429+* INPUT:
33430+*
33431+* OUTPUT:
33432+* None.
33433+*
33434+* RETURN:
33435+*
33436+*******************************************************************************/
33437+MV_VOID mvBoardMppMuxSet(MV_VOID)
33438+{
33439+
33440+ MV_BOARD_MPP_GROUP_CLASS devClass;
33441+ MV_BOARD_MPP_TYPE_CLASS mppGroupType;
33442+ MV_U32 devId;
33443+ MV_U8 muxVal = 0xf;
33444+ MV_U32 maxMppGrp = 1;
33445+ MV_TWSI_SLAVE twsiSlave;
33446+ MV_TWSI_ADDR slave;
33447+
33448+ devId = mvCtrlModelGet();
33449+
33450+ switch(devId){
33451+ case MV_6281_DEV_ID:
33452+ maxMppGrp = MV_6281_MPP_MAX_MODULE;
33453+ break;
33454+ case MV_6192_DEV_ID:
33455+ maxMppGrp = MV_6192_MPP_MAX_MODULE;
33456+ break;
33457+ case MV_6190_DEV_ID:
33458+ maxMppGrp = MV_6190_MPP_MAX_MODULE;
33459+ break;
33460+ case MV_6180_DEV_ID:
33461+ maxMppGrp = MV_6180_MPP_MAX_MODULE;
33462+ break;
33463+ }
33464+
33465+ for (devClass = 0; devClass < maxMppGrp; devClass++)
33466+ {
33467+ mppGroupType = mvBoardMppGroupTypeGet(devClass);
33468+
33469+ switch(mppGroupType)
33470+ {
33471+ case MV_BOARD_TDM:
33472+ muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);
33473+ break;
33474+ case MV_BOARD_AUDIO:
33475+ muxVal &= ~(devClass ? 0x7 : 0x0); /*old Z0 value 0xd:0x0*/
33476+ break;
33477+ case MV_BOARD_TS:
33478+ muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);
33479+ break;
33480+ default:
33481+ muxVal |= (devClass ? 0xf : 0);
33482+ break;
33483+ }
33484+ }
33485+
33486+ /* TWSI init */
33487+ slave.type = ADDR7_BIT;
33488+ slave.address = 0;
33489+ mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
33490+
33491+ /* Read MPP module ID */
33492+ DB(mvOsPrintf("Board: twsi exp set\n"));
33493+ twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);
33494+ twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);
33495+ twsiSlave.validOffset = MV_TRUE;
33496+ /* Offset is the first command after the address which indicate the register number to be read
33497+ in next operation */
33498+ twsiSlave.offset = 2;
33499+ twsiSlave.moreThen256 = MV_FALSE;
33500+
33501+
33502+
33503+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
33504+ {
33505+ DB(mvOsPrintf("Board: twsi exp out val fail\n"));
33506+ return;
33507+ }
33508+ DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
33509+
33510+ /* Change twsi exp to output */
33511+ twsiSlave.offset = 6;
33512+ muxVal = 0;
33513+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
33514+ {
33515+ DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
33516+ return;
33517+ }
33518+ DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
33519+
33520+}
33521+
33522+/*******************************************************************************
33523+* mvBoardTdmMppSet - set MPPs in TDM module
33524+*
33525+* DESCRIPTION:
33526+*
33527+* INPUT: type of second telephony device
33528+*
33529+* OUTPUT:
33530+* None.
33531+*
33532+* RETURN:
33533+*
33534+*******************************************************************************/
33535+MV_VOID mvBoardTdmMppSet(MV_32 chType)
33536+{
33537+
33538+ MV_BOARD_MPP_GROUP_CLASS devClass;
33539+ MV_BOARD_MPP_TYPE_CLASS mppGroupType;
33540+ MV_U32 devId;
33541+ MV_U8 muxVal = 1;
33542+ MV_U8 muxValMask = 1;
33543+ MV_U8 twsiVal;
33544+ MV_U32 maxMppGrp = 1;
33545+ MV_TWSI_SLAVE twsiSlave;
33546+ MV_TWSI_ADDR slave;
33547+
33548+ devId = mvCtrlModelGet();
33549+
33550+ switch(devId){
33551+ case MV_6281_DEV_ID:
33552+ maxMppGrp = MV_6281_MPP_MAX_MODULE;
33553+ break;
33554+ case MV_6192_DEV_ID:
33555+ maxMppGrp = MV_6192_MPP_MAX_MODULE;
33556+ break;
33557+ case MV_6190_DEV_ID:
33558+ maxMppGrp = MV_6190_MPP_MAX_MODULE;
33559+ break;
33560+ case MV_6180_DEV_ID:
33561+ maxMppGrp = MV_6180_MPP_MAX_MODULE;
33562+ break;
33563+ }
33564+
33565+ for (devClass = 0; devClass < maxMppGrp; devClass++)
33566+ {
33567+ mppGroupType = mvBoardMppGroupTypeGet(devClass);
33568+ if(mppGroupType == MV_BOARD_TDM)
33569+ break;
33570+ }
33571+
33572+ if(devClass == maxMppGrp)
33573+ return; /* TDM module not found */
33574+
33575+ /* TWSI init */
33576+ slave.type = ADDR7_BIT;
33577+ slave.address = 0;
33578+ mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
33579+
33580+ /* Read MPP module ID */
33581+ DB(mvOsPrintf("Board: twsi exp set\n"));
33582+ twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);
33583+ twsiSlave.slaveAddr.type = ADDR7_BIT;
33584+ twsiSlave.validOffset = MV_TRUE;
33585+ /* Offset is the first command after the address which indicate the register number to be read
33586+ in next operation */
33587+ twsiSlave.offset = 3;
33588+ twsiSlave.moreThen256 = MV_FALSE;
33589+
33590+ if(mvBoardIdGet() == RD_88F6281A_ID)
33591+ {
33592+ muxVal = 0xc;
33593+ muxValMask = 0xf3;
33594+ }
33595+
33596+ mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
33597+ muxVal = (twsiVal & muxValMask) | muxVal;
33598+
33599+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
33600+ {
33601+ mvOsPrintf("Board: twsi exp out val fail\n");
33602+ return;
33603+ }
33604+ DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
33605+
33606+ /* Change twsi exp to output */
33607+ twsiSlave.offset = 7;
33608+ muxVal = 0xfe;
33609+ if(mvBoardIdGet() == RD_88F6281A_ID)
33610+ muxVal = 0xf3;
33611+
33612+ mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
33613+ muxVal = (twsiVal & muxVal);
33614+
33615+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
33616+ {
33617+ mvOsPrintf("Board: twsi exp change to out fail\n");
33618+ return;
33619+ }
33620+ DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
33621+ /* reset the line to 0 */
33622+ twsiSlave.offset = 3;
33623+ muxVal = 0;
33624+ muxValMask = 1;
33625+
33626+ if(mvBoardIdGet() == RD_88F6281A_ID) {
33627+ muxVal = 0x0;
33628+ muxValMask = 0xf3;
33629+ }
33630+
33631+ mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
33632+ muxVal = (twsiVal & muxValMask) | muxVal;
33633+
33634+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
33635+ {
33636+ mvOsPrintf("Board: twsi exp out val fail\n");
33637+ return;
33638+ }
33639+ DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
33640+
33641+ mvOsDelay(20);
33642+
33643+ /* set the line to 1 */
33644+ twsiSlave.offset = 3;
33645+ muxVal = 1;
33646+ muxValMask = 1;
33647+
33648+ if(mvBoardIdGet() == RD_88F6281A_ID)
33649+ {
33650+ muxVal = 0xc;
33651+ muxValMask = 0xf3;
33652+ if(chType) /* FXS - issue reset properly */
33653+ {
33654+ MV_REG_BIT_SET(GPP_DATA_OUT_REG(1), MV_GPP12);
33655+ mvOsDelay(50);
33656+ MV_REG_BIT_RESET(GPP_DATA_OUT_REG(1), MV_GPP12);
33657+ }
33658+ else /* FXO - issue reset via TDM_CODEC_RST*/
33659+ {
33660+ /* change MPP44 type to TDM_CODEC_RST(0x2) */
33661+ MV_REG_WRITE(MPP_CONTROL_REG5, ((MV_REG_READ(MPP_CONTROL_REG5) & 0xFFF0FFFF) | BIT17));
33662+ }
33663+ }
33664+
33665+ mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
33666+ muxVal = (twsiVal & muxValMask) | muxVal;
33667+
33668+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
33669+ {
33670+ mvOsPrintf("Board: twsi exp out val fail\n");
33671+ return;
33672+ }
33673+
33674+ /* TBD - 5 channels */
33675+#if defined(MV_TDM_5CHANNELS)
33676+ /* change MPP38 type to GPIO(0x0) & polarity for TDM_STROBE */
33677+ MV_REG_WRITE(MPP_CONTROL_REG4, (MV_REG_READ(MPP_CONTROL_REG4) & 0xF0FFFFFF));
33678+ mvGppPolaritySet(1, MV_GPP6, 0);
33679+
33680+ twsiSlave.offset = 6;
33681+ twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(2);
33682+
33683+ mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
33684+ muxVal = (twsiVal & ~BIT2);
33685+
33686+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
33687+ {
33688+ mvOsPrintf("Board: twsi exp change to out fail\n");
33689+ return;
33690+ }
33691+
33692+
33693+ twsiSlave.offset = 2;
33694+
33695+ mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
33696+ muxVal = (twsiVal & ~BIT2);
33697+
33698+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
33699+ {
33700+ mvOsPrintf("Board: twsi exp change to out fail\n");
33701+ return;
33702+ }
33703+#endif
33704+ DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
33705+
33706+
33707+}
33708+/*******************************************************************************
33709+* mvBoardVoiceConnModeGet - return SLIC/DAA connection & interrupt modes
33710+*
33711+* DESCRIPTION:
33712+*
33713+* INPUT:
33714+*
33715+* OUTPUT:
33716+* None.
33717+*
33718+* RETURN:
33719+*
33720+*******************************************************************************/
33721+
33722+MV_VOID mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode)
33723+{
33724+ switch(mvBoardIdGet())
33725+ {
33726+ case RD_88F6281A_ID:
33727+ *connMode = DAISY_CHAIN_MODE;
33728+ *irqMode = INTERRUPT_TO_TDM;
33729+ break;
33730+ case DB_88F6281A_BP_ID:
33731+ *connMode = DUAL_CHIP_SELECT_MODE;
33732+ *irqMode = INTERRUPT_TO_TDM;
33733+ break;
33734+ case RD_88F6192A_ID:
33735+ *connMode = DUAL_CHIP_SELECT_MODE;
33736+ *irqMode = INTERRUPT_TO_TDM;
33737+ break;
33738+ case DB_88F6192A_BP_ID:
33739+ *connMode = DUAL_CHIP_SELECT_MODE;
33740+ *irqMode = INTERRUPT_TO_TDM;
33741+ break;
33742+ default:
33743+ *connMode = *irqMode = -1;
33744+ mvOsPrintf("mvBoardVoiceAssembleModeGet: TDM not supported(boardId=0x%x)\n",mvBoardIdGet());
33745+ }
33746+ return;
33747+
33748+}
33749+
33750+/*******************************************************************************
33751+* mvBoardMppModuleTypePrint - print module detect
33752+*
33753+* DESCRIPTION:
33754+*
33755+* INPUT:
33756+*
33757+* OUTPUT:
33758+* None.
33759+*
33760+* RETURN:
33761+*
33762+*******************************************************************************/
33763+MV_VOID mvBoardMppModuleTypePrint(MV_VOID)
33764+{
33765+
33766+ MV_BOARD_MPP_GROUP_CLASS devClass;
33767+ MV_BOARD_MPP_TYPE_CLASS mppGroupType;
33768+ MV_U32 devId;
33769+ MV_U32 maxMppGrp = 1;
33770+
33771+ devId = mvCtrlModelGet();
33772+
33773+ switch(devId){
33774+ case MV_6281_DEV_ID:
33775+ maxMppGrp = MV_6281_MPP_MAX_MODULE;
33776+ break;
33777+ case MV_6192_DEV_ID:
33778+ maxMppGrp = MV_6192_MPP_MAX_MODULE;
33779+ break;
33780+ case MV_6190_DEV_ID:
33781+ maxMppGrp = MV_6190_MPP_MAX_MODULE;
33782+ break;
33783+ case MV_6180_DEV_ID:
33784+ maxMppGrp = MV_6180_MPP_MAX_MODULE;
33785+ break;
33786+ }
33787+
33788+ for (devClass = 0; devClass < maxMppGrp; devClass++)
33789+ {
33790+ mppGroupType = mvBoardMppGroupTypeGet(devClass);
33791+
33792+ switch(mppGroupType)
33793+ {
33794+ case MV_BOARD_TDM:
33795+ if(devId != MV_6190_DEV_ID)
33796+ mvOsPrintf("Module %d is TDM\n", devClass);
33797+ break;
33798+ case MV_BOARD_AUDIO:
33799+ if(devId != MV_6190_DEV_ID)
33800+ mvOsPrintf("Module %d is AUDIO\n", devClass);
33801+ break;
33802+ case MV_BOARD_RGMII:
33803+ if(devId != MV_6190_DEV_ID)
33804+ mvOsPrintf("Module %d is RGMII\n", devClass);
33805+ break;
33806+ case MV_BOARD_GMII:
33807+ if(devId != MV_6190_DEV_ID)
33808+ mvOsPrintf("Module %d is GMII\n", devClass);
33809+ break;
33810+ case MV_BOARD_TS:
33811+ if(devId != MV_6190_DEV_ID)
33812+ mvOsPrintf("Module %d is TS\n", devClass);
33813+ break;
33814+ default:
33815+ break;
33816+ }
33817+ }
33818+}
33819+
33820+/* Board devices API managments */
33821+
33822+/*******************************************************************************
33823+* mvBoardGetDeviceNumber - Get number of device of some type on the board
33824+*
33825+* DESCRIPTION:
33826+*
33827+* INPUT:
33828+* devType - The device type ( Flash,RTC , etc .. )
33829+*
33830+* OUTPUT:
33831+* None.
33832+*
33833+* RETURN:
33834+* If the device is found on the board the then the functions returns the
33835+* number of those devices else the function returns 0
33836+*
33837+*
33838+*******************************************************************************/
33839+MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass)
33840+{
33841+ MV_U32 foundIndex=0,devNum;
33842+ MV_U32 boardId= mvBoardIdGet();
33843+
33844+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
33845+ {
33846+ mvOsPrintf("mvBoardGetDeviceNumber:Board unknown.\n");
33847+ return 0xFFFFFFFF;
33848+
33849+ }
33850+
33851+ for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)
33852+ {
33853+ if (BOARD_INFO(boardId)->pDevCsInfo[devNum].devClass == devClass)
33854+ {
33855+ foundIndex++;
33856+ }
33857+ }
33858+
33859+ return foundIndex;
33860+
33861+}
33862+
33863+/*******************************************************************************
33864+* mvBoardGetDeviceBaseAddr - Get base address of a device existing on the board
33865+*
33866+* DESCRIPTION:
33867+*
33868+* INPUT:
33869+* devIndex - The device sequential number on the board
33870+* devType - The device type ( Flash,RTC , etc .. )
33871+*
33872+* OUTPUT:
33873+* None.
33874+*
33875+* RETURN:
33876+* If the device is found on the board the then the functions returns the
33877+* Base address else the function returns 0xffffffff
33878+*
33879+*
33880+*******************************************************************************/
33881+MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
33882+{
33883+ MV_DEV_CS_INFO* devEntry;
33884+ devEntry = boardGetDevEntry(devNum,devClass);
33885+ if (devEntry != NULL)
33886+ {
33887+ return mvCpuIfTargetWinBaseLowGet(DEV_TO_TARGET(devEntry->deviceCS));
33888+
33889+ }
33890+
33891+ return 0xFFFFFFFF;
33892+}
33893+
33894+/*******************************************************************************
33895+* mvBoardGetDeviceBusWidth - Get Bus width of a device existing on the board
33896+*
33897+* DESCRIPTION:
33898+*
33899+* INPUT:
33900+* devIndex - The device sequential number on the board
33901+* devType - The device type ( Flash,RTC , etc .. )
33902+*
33903+* OUTPUT:
33904+* None.
33905+*
33906+* RETURN:
33907+* If the device is found on the board the then the functions returns the
33908+* Bus width else the function returns 0xffffffff
33909+*
33910+*
33911+*******************************************************************************/
33912+MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
33913+{
33914+ MV_DEV_CS_INFO* devEntry;
33915+
33916+ devEntry = boardGetDevEntry(devNum,devClass);
33917+ if (devEntry != NULL)
33918+ {
33919+ return 8;
33920+ }
33921+
33922+ return 0xFFFFFFFF;
33923+
33924+}
33925+
33926+/*******************************************************************************
33927+* mvBoardGetDeviceWidth - Get dev width of a device existing on the board
33928+*
33929+* DESCRIPTION:
33930+*
33931+* INPUT:
33932+* devIndex - The device sequential number on the board
33933+* devType - The device type ( Flash,RTC , etc .. )
33934+*
33935+* OUTPUT:
33936+* None.
33937+*
33938+* RETURN:
33939+* If the device is found on the board the then the functions returns the
33940+* dev width else the function returns 0xffffffff
33941+*
33942+*
33943+*******************************************************************************/
33944+MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
33945+{
33946+ MV_DEV_CS_INFO* devEntry;
33947+ MV_U32 boardId= mvBoardIdGet();
33948+
33949+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
33950+ {
33951+ mvOsPrintf("Board unknown.\n");
33952+ return 0xFFFFFFFF;
33953+ }
33954+
33955+ devEntry = boardGetDevEntry(devNum,devClass);
33956+ if (devEntry != NULL)
33957+ return devEntry->devWidth;
33958+
33959+ return MV_ERROR;
33960+
33961+}
33962+
33963+/*******************************************************************************
33964+* mvBoardGetDeviceWinSize - Get the window size of a device existing on the board
33965+*
33966+* DESCRIPTION:
33967+*
33968+* INPUT:
33969+* devIndex - The device sequential number on the board
33970+* devType - The device type ( Flash,RTC , etc .. )
33971+*
33972+* OUTPUT:
33973+* None.
33974+*
33975+* RETURN:
33976+* If the device is found on the board the then the functions returns the
33977+* window size else the function returns 0xffffffff
33978+*
33979+*
33980+*******************************************************************************/
33981+MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
33982+{
33983+ MV_DEV_CS_INFO* devEntry;
33984+ MV_U32 boardId = mvBoardIdGet();
33985+
33986+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
33987+ {
33988+ mvOsPrintf("Board unknown.\n");
33989+ return 0xFFFFFFFF;
33990+ }
33991+
33992+ devEntry = boardGetDevEntry(devNum,devClass);
33993+ if (devEntry != NULL)
33994+ {
33995+ return mvCpuIfTargetWinSizeGet(DEV_TO_TARGET(devEntry->deviceCS));
33996+ }
33997+
33998+ return 0xFFFFFFFF;
33999+}
34000+
34001+
34002+/*******************************************************************************
34003+* boardGetDevEntry - returns the entry pointer of a device on the board
34004+*
34005+* DESCRIPTION:
34006+*
34007+* INPUT:
34008+* devIndex - The device sequential number on the board
34009+* devType - The device type ( Flash,RTC , etc .. )
34010+*
34011+* OUTPUT:
34012+* None.
34013+*
34014+* RETURN:
34015+* If the device is found on the board the then the functions returns the
34016+* dev number else the function returns 0x0
34017+*
34018+*
34019+*******************************************************************************/
34020+static MV_DEV_CS_INFO* boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
34021+{
34022+ MV_U32 foundIndex=0,devIndex;
34023+ MV_U32 boardId= mvBoardIdGet();
34024+
34025+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
34026+ {
34027+ mvOsPrintf("boardGetDevEntry: Board unknown.\n");
34028+ return NULL;
34029+
34030+ }
34031+
34032+ for (devIndex = START_DEV_CS; devIndex < BOARD_INFO(boardId)->numBoardDeviceIf; devIndex++)
34033+ {
34034+ /* TBR */
34035+ /*if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].deviceCS == MV_BOOTDEVICE_INDEX)
34036+ continue;*/
34037+
34038+ if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].devClass == devClass)
34039+ {
34040+ if (foundIndex == devNum)
34041+ {
34042+ return &(BOARD_INFO(boardId)->pDevCsInfo[devIndex]);
34043+ }
34044+ foundIndex++;
34045+ }
34046+ }
34047+
34048+ /* device not found */
34049+ return NULL;
34050+}
34051+
34052+/* Get device CS number */
34053+
34054+MV_U32 boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
34055+{
34056+ MV_DEV_CS_INFO* devEntry;
34057+ MV_U32 boardId= mvBoardIdGet();
34058+
34059+ if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
34060+ {
34061+ mvOsPrintf("Board unknown.\n");
34062+ return 0xFFFFFFFF;
34063+
34064+ }
34065+
34066+
34067+ devEntry = boardGetDevEntry(devNum,devClass);
34068+ if (devEntry != NULL)
34069+ return devEntry->deviceCS;
34070+
34071+ return 0xFFFFFFFF;
34072+
34073+}
34074+
34075+/*******************************************************************************
34076+* mvBoardRtcTwsiAddrTypeGet -
34077+*
34078+* DESCRIPTION:
34079+*
34080+* INPUT:
34081+*
34082+* OUTPUT:
34083+* None.
34084+*
34085+* RETURN:
34086+*
34087+*
34088+*******************************************************************************/
34089+MV_U8 mvBoardRtcTwsiAddrTypeGet()
34090+{
34091+ int i;
34092+ MV_U32 boardId= mvBoardIdGet();
34093+
34094+ for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
34095+ if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)
34096+ return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
34097+ return (MV_ERROR);
34098+}
34099+
34100+/*******************************************************************************
34101+* mvBoardRtcTwsiAddrGet -
34102+*
34103+* DESCRIPTION:
34104+*
34105+* INPUT:
34106+*
34107+* OUTPUT:
34108+* None.
34109+*
34110+* RETURN:
34111+*
34112+*
34113+*******************************************************************************/
34114+MV_U8 mvBoardRtcTwsiAddrGet()
34115+{
34116+ int i;
34117+ MV_U32 boardId= mvBoardIdGet();
34118+
34119+ for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
34120+ if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)
34121+ return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
34122+ return (0xFF);
34123+}
34124+
34125+/*******************************************************************************
34126+* mvBoardA2DTwsiAddrTypeGet -
34127+*
34128+* DESCRIPTION:
34129+*
34130+* INPUT:
34131+*
34132+* OUTPUT:
34133+* None.
34134+*
34135+* RETURN:
34136+*
34137+*
34138+*******************************************************************************/
34139+MV_U8 mvBoardA2DTwsiAddrTypeGet()
34140+{
34141+ int i;
34142+ MV_U32 boardId= mvBoardIdGet();
34143+
34144+ for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
34145+ if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)
34146+ return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
34147+ return (MV_ERROR);
34148+}
34149+
34150+/*******************************************************************************
34151+* mvBoardA2DTwsiAddrGet -
34152+*
34153+* DESCRIPTION:
34154+*
34155+* INPUT:
34156+*
34157+* OUTPUT:
34158+* None.
34159+*
34160+* RETURN:
34161+*
34162+*
34163+*******************************************************************************/
34164+MV_U8 mvBoardA2DTwsiAddrGet()
34165+{
34166+ int i;
34167+ MV_U32 boardId= mvBoardIdGet();
34168+
34169+ for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
34170+ if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)
34171+ return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
34172+ return (0xFF);
34173+}
34174+
34175+/*******************************************************************************
34176+* mvBoardTwsiExpAddrTypeGet -
34177+*
34178+* DESCRIPTION:
34179+*
34180+* INPUT:
34181+*
34182+* OUTPUT:
34183+* None.
34184+*
34185+* RETURN:
34186+*
34187+*
34188+*******************************************************************************/
34189+MV_U8 mvBoardTwsiExpAddrTypeGet(MV_U32 index)
34190+{
34191+ int i;
34192+ MV_U32 indexFound = 0;
34193+ MV_U32 boardId= mvBoardIdGet();
34194+
34195+ for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
34196+ if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)
34197+ {
34198+ if (indexFound == index)
34199+ return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
34200+ else
34201+ indexFound++;
34202+ }
34203+
34204+ return (MV_ERROR);
34205+}
34206+
34207+/*******************************************************************************
34208+* mvBoardTwsiExpAddrGet -
34209+*
34210+* DESCRIPTION:
34211+*
34212+* INPUT:
34213+*
34214+* OUTPUT:
34215+* None.
34216+*
34217+* RETURN:
34218+*
34219+*
34220+*******************************************************************************/
34221+MV_U8 mvBoardTwsiExpAddrGet(MV_U32 index)
34222+{
34223+ int i;
34224+ MV_U32 indexFound = 0;
34225+ MV_U32 boardId= mvBoardIdGet();
34226+
34227+ for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
34228+ if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)
34229+ {
34230+ if (indexFound == index)
34231+ return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
34232+ else
34233+ indexFound++;
34234+ }
34235+
34236+ return (0xFF);
34237+}
34238+
34239+
34240+/*******************************************************************************
34241+* mvBoardTwsiSatRAddrTypeGet -
34242+*
34243+* DESCRIPTION:
34244+*
34245+* INPUT:
34246+*
34247+* OUTPUT:
34248+* None.
34249+*
34250+* RETURN:
34251+*
34252+*
34253+*******************************************************************************/
34254+MV_U8 mvBoardTwsiSatRAddrTypeGet(MV_U32 index)
34255+{
34256+ int i;
34257+ MV_U32 indexFound = 0;
34258+ MV_U32 boardId= mvBoardIdGet();
34259+
34260+ for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
34261+ if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)
34262+ {
34263+ if (indexFound == index)
34264+ return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
34265+ else
34266+ indexFound++;
34267+ }
34268+
34269+ return (MV_ERROR);
34270+}
34271+
34272+/*******************************************************************************
34273+* mvBoardTwsiSatRAddrGet -
34274+*
34275+* DESCRIPTION:
34276+*
34277+* INPUT:
34278+*
34279+* OUTPUT:
34280+* None.
34281+*
34282+* RETURN:
34283+*
34284+*
34285+*******************************************************************************/
34286+MV_U8 mvBoardTwsiSatRAddrGet(MV_U32 index)
34287+{
34288+ int i;
34289+ MV_U32 indexFound = 0;
34290+ MV_U32 boardId= mvBoardIdGet();
34291+
34292+ for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
34293+ if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)
34294+ {
34295+ if (indexFound == index)
34296+ return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
34297+ else
34298+ indexFound++;
34299+ }
34300+
34301+ return (0xFF);
34302+}
34303+
34304+/*******************************************************************************
34305+* mvBoardNandWidthGet -
34306+*
34307+* DESCRIPTION: Get the width of the first NAND device in byte.
34308+*
34309+* INPUT:
34310+*
34311+* OUTPUT:
34312+* None.
34313+*
34314+* RETURN: 1, 2, 4 or MV_ERROR
34315+*
34316+*
34317+*******************************************************************************/
34318+/* */
34319+MV_32 mvBoardNandWidthGet(void)
34320+{
34321+ MV_U32 devNum;
34322+ MV_U32 devWidth;
34323+ MV_U32 boardId= mvBoardIdGet();
34324+
34325+ for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)
34326+ {
34327+ devWidth = mvBoardGetDeviceWidth(devNum, BOARD_DEV_NAND_FLASH);
34328+ if (devWidth != MV_ERROR)
34329+ return (devWidth / 8);
34330+ }
34331+
34332+ /* NAND wasn't found */
34333+ return MV_ERROR;
34334+}
34335+
34336+MV_U32 gBoardId = -1;
34337+
34338+/*******************************************************************************
34339+* mvBoardIdGet - Get Board model
34340+*
34341+* DESCRIPTION:
34342+* This function returns board ID.
34343+* Board ID is 32bit word constructed of board model (16bit) and
34344+* board revision (16bit) in the following way: 0xMMMMRRRR.
34345+*
34346+* INPUT:
34347+* None.
34348+*
34349+* OUTPUT:
34350+* None.
34351+*
34352+* RETURN:
34353+* 32bit board ID number, '-1' if board is undefined.
34354+*
34355+*******************************************************************************/
34356+MV_U32 mvBoardIdGet(MV_VOID)
34357+{
34358+ MV_U32 tmpBoardId = -1;
34359+
34360+ if(gBoardId == -1)
34361+ {
34362+ #if defined(DB_88F6281A)
34363+ tmpBoardId = DB_88F6281A_BP_ID;
34364+ #elif defined(RD_88F6281A)
34365+ tmpBoardId = RD_88F6281A_ID;
34366+ #elif defined(DB_88F6192A)
34367+ tmpBoardId = DB_88F6192A_BP_ID;
34368+ #elif defined(DB_88F6190A)
34369+ tmpBoardId = DB_88F6190A_BP_ID;
34370+ #elif defined(RD_88F6192A)
34371+ tmpBoardId = RD_88F6192A_ID;
34372+ #elif defined(RD_88F6190A)
34373+ tmpBoardId = RD_88F6190A_ID;
34374+ #elif defined(DB_88F6180A)
34375+ tmpBoardId = DB_88F6180A_BP_ID;
34376+ #elif defined(RD_88F6281A_PCAC)
34377+ tmpBoardId = RD_88F6281A_PCAC_ID;
34378+ #elif defined(RD_88F6281A_SHEEVA_PLUG)
34379+ tmpBoardId = SHEEVA_PLUG_ID;
34380+ #elif defined(DB_CUSTOMER)
34381+ tmpBoardId = DB_CUSTOMER_ID;
34382+ #endif
34383+ gBoardId = tmpBoardId;
34384+ }
34385+
34386+ return gBoardId;
34387+}
34388+
34389+
34390+/*******************************************************************************
34391+* mvBoarModuleTypeGet - mvBoarModuleTypeGet
34392+*
34393+* DESCRIPTION:
34394+*
34395+* INPUT:
34396+* group num - MV_BOARD_MPP_GROUP_CLASS enum
34397+*
34398+* OUTPUT:
34399+* None.
34400+*
34401+* RETURN:
34402+* module num - MV_BOARD_MODULE_CLASS enum
34403+*
34404+*******************************************************************************/
34405+MV_BOARD_MODULE_ID_CLASS mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass)
34406+{
34407+ MV_TWSI_SLAVE twsiSlave;
34408+ MV_TWSI_ADDR slave;
34409+ MV_U8 data;
34410+
34411+ /* TWSI init */
34412+ slave.type = ADDR7_BIT;
34413+ slave.address = 0;
34414+ mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
34415+
34416+ /* Read MPP module ID */
34417+ DB(mvOsPrintf("Board: Read MPP module ID\n"));
34418+ twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);
34419+ twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(devClass);
34420+ twsiSlave.validOffset = MV_TRUE;
34421+ /* Offset is the first command after the address which indicate the register number to be read
34422+ in next operation */
34423+ twsiSlave.offset = 0;
34424+ twsiSlave.moreThen256 = MV_FALSE;
34425+
34426+
34427+
34428+ if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )
34429+ {
34430+ DB(mvOsPrintf("Board: Read MPP module ID fail\n"));
34431+ return MV_ERROR;
34432+ }
34433+ DB(mvOsPrintf("Board: Read MPP module ID succeded\n"));
34434+
34435+ return data;
34436+}
34437+
34438+/*******************************************************************************
34439+* mvBoarTwsiSatRGet -
34440+*
34441+* DESCRIPTION:
34442+*
34443+* INPUT:
34444+* device num - one of three devices
34445+* reg num - 0 or 1
34446+*
34447+* OUTPUT:
34448+* None.
34449+*
34450+* RETURN:
34451+* reg value
34452+*
34453+*******************************************************************************/
34454+MV_U8 mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum)
34455+{
34456+ MV_TWSI_SLAVE twsiSlave;
34457+ MV_TWSI_ADDR slave;
34458+ MV_U8 data;
34459+
34460+ /* TWSI init */
34461+ slave.type = ADDR7_BIT;
34462+ slave.address = 0;
34463+ mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
34464+
34465+ /* Read MPP module ID */
34466+ DB(mvOsPrintf("Board: Read S@R device read\n"));
34467+ twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);
34468+ twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);
34469+ twsiSlave.validOffset = MV_TRUE;
34470+ /* Use offset as command */
34471+ twsiSlave.offset = regNum;
34472+ twsiSlave.moreThen256 = MV_FALSE;
34473+
34474+ if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )
34475+ {
34476+ DB(mvOsPrintf("Board: Read S@R fail\n"));
34477+ return MV_ERROR;
34478+ }
34479+ DB(mvOsPrintf("Board: Read S@R succeded\n"));
34480+
34481+ return data;
34482+}
34483+
34484+/*******************************************************************************
34485+* mvBoarTwsiSatRSet -
34486+*
34487+* DESCRIPTION:
34488+*
34489+* INPUT:
34490+* devNum - one of three devices
34491+* regNum - 0 or 1
34492+* regVal - value
34493+*
34494+*
34495+* OUTPUT:
34496+* None.
34497+*
34498+* RETURN:
34499+* reg value
34500+*
34501+*******************************************************************************/
34502+MV_STATUS mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal)
34503+{
34504+ MV_TWSI_SLAVE twsiSlave;
34505+ MV_TWSI_ADDR slave;
34506+
34507+ /* TWSI init */
34508+ slave.type = ADDR7_BIT;
34509+ slave.address = 0;
34510+ mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
34511+
34512+ /* Read MPP module ID */
34513+ twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);
34514+ twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);
34515+ twsiSlave.validOffset = MV_TRUE;
34516+ DB(mvOsPrintf("Board: Write S@R device addr %x, type %x, data %x\n", twsiSlave.slaveAddr.address,\
34517+ twsiSlave.slaveAddr.type, regVal));
34518+ /* Use offset as command */
34519+ twsiSlave.offset = regNum;
34520+ twsiSlave.moreThen256 = MV_FALSE;
34521+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &regVal, 1) )
34522+ {
34523+ DB(mvOsPrintf("Board: Write S@R fail\n"));
34524+ return MV_ERROR;
34525+ }
34526+ DB(mvOsPrintf("Board: Write S@R succeded\n"));
34527+
34528+ return MV_OK;
34529+}
34530+
34531+/*******************************************************************************
34532+* mvBoardSlicGpioPinGet -
34533+*
34534+* DESCRIPTION:
34535+*
34536+* INPUT:
34537+*
34538+* OUTPUT:
34539+* None.
34540+*
34541+* RETURN:
34542+*
34543+*
34544+*******************************************************************************/
34545+MV_32 mvBoardSlicGpioPinGet(MV_U32 slicNum)
34546+{
34547+ MV_U32 boardId;
34548+ boardId = mvBoardIdGet();
34549+
34550+ switch (boardId)
34551+ {
34552+ case DB_88F6281A_BP_ID:
34553+ case RD_88F6281A_ID:
34554+ default:
34555+ return MV_ERROR;
34556+ break;
34557+
34558+ }
34559+}
34560+
34561+/*******************************************************************************
34562+* mvBoardFanPowerControl - Turn on/off the fan power control on the RD-6281A
34563+*
34564+* DESCRIPTION:
34565+*
34566+* INPUT:
34567+* mode - MV_TRUE = on ; MV_FALSE = off
34568+*
34569+* OUTPUT:
34570+* MV_STATUS - MV_OK , MV_ERROR.
34571+*
34572+* RETURN:
34573+*
34574+*******************************************************************************/
34575+MV_STATUS mvBoardFanPowerControl(MV_BOOL mode)
34576+{
34577+
34578+ MV_U8 val = 1, twsiVal;
34579+ MV_TWSI_SLAVE twsiSlave;
34580+ MV_TWSI_ADDR slave;
34581+
34582+ if(mvBoardIdGet() != RD_88F6281A_ID)
34583+ return MV_ERROR;
34584+
34585+ /* TWSI init */
34586+ slave.type = ADDR7_BIT;
34587+ slave.address = 0;
34588+ mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
34589+
34590+ /* Read MPP module ID */
34591+ DB(mvOsPrintf("Board: twsi exp set\n"));
34592+ twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);
34593+ twsiSlave.slaveAddr.type = ADDR7_BIT;
34594+ twsiSlave.validOffset = MV_TRUE;
34595+ /* Offset is the first command after the address which indicate the register number to be read
34596+ in next operation */
34597+ twsiSlave.offset = 3;
34598+ twsiSlave.moreThen256 = MV_FALSE;
34599+ if(mode == MV_TRUE)
34600+ val = 0x1;
34601+ else
34602+ val = 0;
34603+ mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
34604+ val = (twsiVal & 0xfe) | val;
34605+
34606+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
34607+ {
34608+ DB(mvOsPrintf("Board: twsi exp out val fail\n"));
34609+ return MV_ERROR;
34610+ }
34611+ DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
34612+
34613+ /* Change twsi exp to output */
34614+ twsiSlave.offset = 7;
34615+ mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
34616+ val = (twsiVal & 0xfe);
34617+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
34618+ {
34619+ DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
34620+ return MV_ERROR;
34621+ }
34622+ DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
34623+ return MV_OK;
34624+}
34625+
34626+/*******************************************************************************
34627+* mvBoardHDDPowerControl - Turn on/off the HDD power control on the RD-6281A
34628+*
34629+* DESCRIPTION:
34630+*
34631+* INPUT:
34632+* mode - MV_TRUE = on ; MV_FALSE = off
34633+*
34634+* OUTPUT:
34635+* MV_STATUS - MV_OK , MV_ERROR.
34636+*
34637+* RETURN:
34638+*
34639+*******************************************************************************/
34640+MV_STATUS mvBoardHDDPowerControl(MV_BOOL mode)
34641+{
34642+
34643+ MV_U8 val = 1, twsiVal;
34644+ MV_TWSI_SLAVE twsiSlave;
34645+ MV_TWSI_ADDR slave;
34646+
34647+ if(mvBoardIdGet() != RD_88F6281A_ID)
34648+ return MV_ERROR;
34649+
34650+ /* TWSI init */
34651+ slave.type = ADDR7_BIT;
34652+ slave.address = 0;
34653+ mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
34654+
34655+ /* Read MPP module ID */
34656+ DB(mvOsPrintf("Board: twsi exp set\n"));
34657+ twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);
34658+ twsiSlave.slaveAddr.type = ADDR7_BIT;
34659+ twsiSlave.validOffset = MV_TRUE;
34660+ /* Offset is the first command after the address which indicate the register number to be read
34661+ in next operation */
34662+ twsiSlave.offset = 3;
34663+ twsiSlave.moreThen256 = MV_FALSE;
34664+ if(mode == MV_TRUE)
34665+ val = 0x2;
34666+ else
34667+ val = 0;
34668+ mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
34669+ val = (twsiVal & 0xfd) | val;
34670+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
34671+ {
34672+ DB(mvOsPrintf("Board: twsi exp out val fail\n"));
34673+ return MV_ERROR;
34674+ }
34675+ DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
34676+
34677+ /* Change twsi exp to output */
34678+ twsiSlave.offset = 7;
34679+ mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
34680+ val = (twsiVal & 0xfd);
34681+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
34682+ {
34683+ DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
34684+ return MV_ERROR;
34685+ }
34686+ DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
34687+ return MV_OK;
34688+}
34689+
34690+/*******************************************************************************
34691+* mvBoardSDioWPControl - Turn on/off the SDIO WP on the RD-6281A
34692+*
34693+* DESCRIPTION:
34694+*
34695+* INPUT:
34696+* mode - MV_TRUE = on ; MV_FALSE = off
34697+*
34698+* OUTPUT:
34699+* MV_STATUS - MV_OK , MV_ERROR.
34700+*
34701+* RETURN:
34702+*
34703+*******************************************************************************/
34704+MV_STATUS mvBoardSDioWPControl(MV_BOOL mode)
34705+{
34706+
34707+ MV_U8 val = 1, twsiVal;
34708+ MV_TWSI_SLAVE twsiSlave;
34709+ MV_TWSI_ADDR slave;
34710+
34711+ if(mvBoardIdGet() != RD_88F6281A_ID)
34712+ return MV_ERROR;
34713+
34714+ /* TWSI init */
34715+ slave.type = ADDR7_BIT;
34716+ slave.address = 0;
34717+ mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
34718+
34719+ /* Read MPP module ID */
34720+ DB(mvOsPrintf("Board: twsi exp set\n"));
34721+ twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(0);
34722+ twsiSlave.slaveAddr.type = ADDR7_BIT;
34723+ twsiSlave.validOffset = MV_TRUE;
34724+ /* Offset is the first command after the address which indicate the register number to be read
34725+ in next operation */
34726+ twsiSlave.offset = 3;
34727+ twsiSlave.moreThen256 = MV_FALSE;
34728+ if(mode == MV_TRUE)
34729+ val = 0x10;
34730+ else
34731+ val = 0;
34732+ mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
34733+ val = (twsiVal & 0xef) | val;
34734+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
34735+ {
34736+ DB(mvOsPrintf("Board: twsi exp out val fail\n"));
34737+ return MV_ERROR;
34738+ }
34739+ DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
34740+
34741+ /* Change twsi exp to output */
34742+ twsiSlave.offset = 7;
34743+ mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
34744+ val = (twsiVal & 0xef);
34745+ if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
34746+ {
34747+ DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
34748+ return MV_ERROR;
34749+ }
34750+ DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
34751+ return MV_OK;
34752+}
34753+
34754diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h b/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h
34755new file mode 100644
34756index 0000000..522493d
34757--- /dev/null
34758+++ b/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h
34759@@ -0,0 +1,376 @@
34760+/*******************************************************************************
34761+Copyright (C) Marvell International Ltd. and its affiliates
34762+
34763+This software file (the "File") is owned and distributed by Marvell
34764+International Ltd. and/or its affiliates ("Marvell") under the following
34765+alternative licensing terms. Once you have made an election to distribute the
34766+File under one of the following license alternatives, please (i) delete this
34767+introductory statement regarding license alternatives, (ii) delete the two
34768+license alternatives that you have not elected to use and (iii) preserve the
34769+Marvell copyright notice above.
34770+
34771+********************************************************************************
34772+Marvell Commercial License Option
34773+
34774+If you received this File from Marvell and you have entered into a commercial
34775+license agreement (a "Commercial License") with Marvell, the File is licensed
34776+to you under the terms of the applicable Commercial License.
34777+
34778+********************************************************************************
34779+Marvell GPL License Option
34780+
34781+If you received this File from Marvell, you may opt to use, redistribute and/or
34782+modify this File in accordance with the terms and conditions of the General
34783+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
34784+available along with the File in the license.txt file or by writing to the Free
34785+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
34786+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
34787+
34788+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
34789+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
34790+DISCLAIMED. The GPL License provides additional details about this warranty
34791+disclaimer.
34792+********************************************************************************
34793+Marvell BSD License Option
34794+
34795+If you received this File from Marvell, you may opt to use, redistribute and/or
34796+modify this File under the following licensing terms.
34797+Redistribution and use in source and binary forms, with or without modification,
34798+are permitted provided that the following conditions are met:
34799+
34800+ * Redistributions of source code must retain the above copyright notice,
34801+ this list of conditions and the following disclaimer.
34802+
34803+ * Redistributions in binary form must reproduce the above copyright
34804+ notice, this list of conditions and the following disclaimer in the
34805+ documentation and/or other materials provided with the distribution.
34806+
34807+ * Neither the name of Marvell nor the names of its contributors may be
34808+ used to endorse or promote products derived from this software without
34809+ specific prior written permission.
34810+
34811+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
34812+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34813+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34814+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
34815+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34816+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34817+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
34818+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34819+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34820+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34821+
34822+*******************************************************************************/
34823+#ifndef __INCmvBoardEnvLibh
34824+#define __INCmvBoardEnvLibh
34825+
34826+/* defines */
34827+/* The below constant macros defines the board I2C EEPROM data offsets */
34828+
34829+
34830+
34831+#include "ctrlEnv/mvCtrlEnvLib.h"
34832+#include "mvSysHwConfig.h"
34833+#include "boardEnv/mvBoardEnvSpec.h"
34834+
34835+
34836+/* DUART stuff for Tclk detection only */
34837+#define DUART_BAUD_RATE 115200
34838+#define MAX_CLOCK_MARGINE 5000000 /* Maximum detected clock margine */
34839+
34840+/* Voice devices assembly modes */
34841+#define DAISY_CHAIN_MODE 1
34842+#define DUAL_CHIP_SELECT_MODE 0
34843+#define INTERRUPT_TO_MPP 1
34844+#define INTERRUPT_TO_TDM 0
34845+
34846+
34847+#define BOARD_ETH_PORT_NUM MV_ETH_MAX_PORTS
34848+#define BOARD_ETH_SWITCH_PORT_NUM 5
34849+
34850+#define MV_BOARD_MAX_USB_IF 1
34851+#define MV_BOARD_MAX_MPP 7
34852+#define MV_BOARD_NAME_LEN 0x20
34853+
34854+typedef struct _boardData
34855+{
34856+ MV_U32 magic;
34857+ MV_U16 boardId;
34858+ MV_U8 boardVer;
34859+ MV_U8 boardRev;
34860+ MV_U32 reserved1;
34861+ MV_U32 reserved2;
34862+
34863+}BOARD_DATA;
34864+
34865+typedef enum _devBoardMppGroupClass
34866+{
34867+ MV_BOARD_MPP_GROUP_1,
34868+ MV_BOARD_MPP_GROUP_2,
34869+ MV_BOARD_MAX_MPP_GROUP
34870+}MV_BOARD_MPP_GROUP_CLASS;
34871+
34872+typedef enum _devBoardMppTypeClass
34873+{
34874+ MV_BOARD_AUTO,
34875+ MV_BOARD_TDM,
34876+ MV_BOARD_AUDIO,
34877+ MV_BOARD_RGMII,
34878+ MV_BOARD_GMII,
34879+ MV_BOARD_TS,
34880+ MV_BOARD_MII,
34881+ MV_BOARD_OTHER
34882+}MV_BOARD_MPP_TYPE_CLASS;
34883+
34884+typedef enum _devBoardModuleIdClass
34885+{
34886+ MV_BOARD_MODULE_TDM_ID = 1,
34887+ MV_BOARD_MODULE_AUDIO_ID,
34888+ MV_BOARD_MODULE_RGMII_ID,
34889+ MV_BOARD_MODULE_GMII_ID,
34890+ MV_BOARD_MODULE_TS_ID,
34891+ MV_BOARD_MODULE_MII_ID,
34892+ MV_BOARD_MODULE_TDM_5CHAN_ID,
34893+ MV_BOARD_MODULE_OTHER_ID
34894+}MV_BOARD_MODULE_ID_CLASS;
34895+
34896+typedef struct _boardMppTypeInfo
34897+{
34898+ MV_BOARD_MPP_TYPE_CLASS boardMppGroup1;
34899+ MV_BOARD_MPP_TYPE_CLASS boardMppGroup2;
34900+
34901+}MV_BOARD_MPP_TYPE_INFO;
34902+
34903+
34904+typedef enum _devBoardClass
34905+{
34906+ BOARD_DEV_NOR_FLASH,
34907+ BOARD_DEV_NAND_FLASH,
34908+ BOARD_DEV_SEVEN_SEG,
34909+ BOARD_DEV_FPGA,
34910+ BOARD_DEV_SRAM,
34911+ BOARD_DEV_SPI_FLASH,
34912+ BOARD_DEV_OTHER,
34913+}MV_BOARD_DEV_CLASS;
34914+
34915+typedef enum _devTwsiBoardClass
34916+{
34917+ BOARD_TWSI_RTC,
34918+ BOARD_DEV_TWSI_EXP,
34919+ BOARD_DEV_TWSI_SATR,
34920+ BOARD_TWSI_AUDIO_DEC,
34921+ BOARD_TWSI_OTHER
34922+}MV_BOARD_TWSI_CLASS;
34923+
34924+typedef enum _devGppBoardClass
34925+{
34926+ BOARD_GPP_RTC,
34927+ BOARD_GPP_MV_SWITCH,
34928+ BOARD_GPP_USB_VBUS,
34929+ BOARD_GPP_USB_VBUS_EN,
34930+ BOARD_GPP_USB_OC,
34931+ BOARD_GPP_USB_HOST_DEVICE,
34932+ BOARD_GPP_REF_CLCK,
34933+ BOARD_GPP_VOIP_SLIC,
34934+ BOARD_GPP_LIFELINE,
34935+ BOARD_GPP_BUTTON,
34936+ BOARD_GPP_TS_BUTTON_C,
34937+ BOARD_GPP_TS_BUTTON_U,
34938+ BOARD_GPP_TS_BUTTON_D,
34939+ BOARD_GPP_TS_BUTTON_L,
34940+ BOARD_GPP_TS_BUTTON_R,
34941+ BOARD_GPP_POWER_BUTTON,
34942+ BOARD_GPP_RESTOR_BUTTON,
34943+ BOARD_GPP_WPS_BUTTON,
34944+ BOARD_GPP_HDD0_POWER,
34945+ BOARD_GPP_HDD1_POWER,
34946+ BOARD_GPP_FAN_POWER,
34947+ BOARD_GPP_RESET,
34948+ BOARD_GPP_POWER_ON_LED,
34949+ BOARD_GPP_HDD_POWER,
34950+ BOARD_GPP_SDIO_POWER,
34951+ BOARD_GPP_SDIO_DETECT,
34952+ BOARD_GPP_SDIO_WP,
34953+ BOARD_GPP_SWITCH_PHY_INT,
34954+ BOARD_GPP_TSU_DIRCTION,
34955+ BOARD_GPP_OTHER
34956+}MV_BOARD_GPP_CLASS;
34957+
34958+
34959+typedef struct _devCsInfo
34960+{
34961+ MV_U8 deviceCS;
34962+ MV_U32 params;
34963+ MV_U32 devClass; /* MV_BOARD_DEV_CLASS */
34964+ MV_U8 devWidth;
34965+
34966+}MV_DEV_CS_INFO;
34967+
34968+
34969+#define MV_BOARD_PHY_FORCE_10MB 0x0
34970+#define MV_BOARD_PHY_FORCE_100MB 0x1
34971+#define MV_BOARD_PHY_FORCE_1000MB 0x2
34972+#define MV_BOARD_PHY_SPEED_AUTO 0x3
34973+
34974+typedef struct _boardSwitchInfo
34975+{
34976+ MV_32 linkStatusIrq;
34977+ MV_32 qdPort[BOARD_ETH_SWITCH_PORT_NUM];
34978+ MV_32 qdCpuPort;
34979+ MV_32 smiScanMode; /* 1 for SMI_MANUAL_MODE, 0 otherwise */
34980+ MV_32 switchOnPort;
34981+
34982+}MV_BOARD_SWITCH_INFO;
34983+
34984+typedef struct _boardLedInfo
34985+{
34986+ MV_U8 activeLedsNumber;
34987+ MV_U8 ledsPolarity; /* '0' or '1' to turn on led */
34988+ MV_U8* gppPinNum; /* Pointer to GPP values */
34989+
34990+}MV_BOARD_LED_INFO;
34991+
34992+typedef struct _boardGppInfo
34993+{
34994+ MV_BOARD_GPP_CLASS devClass;
34995+ MV_U8 gppPinNum;
34996+
34997+}MV_BOARD_GPP_INFO;
34998+
34999+
35000+typedef struct _boardTwsiInfo
35001+{
35002+ MV_BOARD_TWSI_CLASS devClass;
35003+ MV_U8 twsiDevAddr;
35004+ MV_U8 twsiDevAddrType;
35005+
35006+}MV_BOARD_TWSI_INFO;
35007+
35008+
35009+typedef enum _boardMacSpeed
35010+{
35011+ BOARD_MAC_SPEED_10M,
35012+ BOARD_MAC_SPEED_100M,
35013+ BOARD_MAC_SPEED_1000M,
35014+ BOARD_MAC_SPEED_AUTO,
35015+
35016+}MV_BOARD_MAC_SPEED;
35017+
35018+typedef struct _boardMacInfo
35019+{
35020+ MV_BOARD_MAC_SPEED boardMacSpeed;
35021+ MV_U8 boardEthSmiAddr;
35022+
35023+}MV_BOARD_MAC_INFO;
35024+
35025+typedef struct _boardMppInfo
35026+{
35027+ MV_U32 mppGroup[MV_BOARD_MAX_MPP];
35028+
35029+}MV_BOARD_MPP_INFO;
35030+
35031+typedef struct _boardInfo
35032+{
35033+ char boardName[MV_BOARD_NAME_LEN];
35034+ MV_U8 numBoardMppTypeValue;
35035+ MV_BOARD_MPP_TYPE_INFO* pBoardMppTypeValue;
35036+ MV_U8 numBoardMppConfigValue;
35037+ MV_BOARD_MPP_INFO* pBoardMppConfigValue;
35038+ MV_U32 intsGppMaskLow;
35039+ MV_U32 intsGppMaskHigh;
35040+ MV_U8 numBoardDeviceIf;
35041+ MV_DEV_CS_INFO* pDevCsInfo;
35042+ MV_U8 numBoardTwsiDev;
35043+ MV_BOARD_TWSI_INFO* pBoardTwsiDev;
35044+ MV_U8 numBoardMacInfo;
35045+ MV_BOARD_MAC_INFO* pBoardMacInfo;
35046+ MV_U8 numBoardGppInfo;
35047+ MV_BOARD_GPP_INFO* pBoardGppInfo;
35048+ MV_U8 activeLedsNumber;
35049+ MV_U8* pLedGppPin;
35050+ MV_U8 ledsPolarity; /* '0' or '1' to turn on led */
35051+ /* GPP values */
35052+ MV_U32 gppOutEnValLow;
35053+ MV_U32 gppOutEnValHigh;
35054+ MV_U32 gppOutValLow;
35055+ MV_U32 gppOutValHigh;
35056+ MV_U32 gppPolarityValLow;
35057+ MV_U32 gppPolarityValHigh;
35058+
35059+ /* Switch Configuration */
35060+ MV_BOARD_SWITCH_INFO* pSwitchInfo;
35061+}MV_BOARD_INFO;
35062+
35063+
35064+
35065+MV_VOID mvBoardEnvInit(MV_VOID);
35066+MV_U32 mvBoardIdGet(MV_VOID);
35067+MV_U16 mvBoardModelGet(MV_VOID);
35068+MV_U16 mvBoardRevGet(MV_VOID);
35069+MV_STATUS mvBoardNameGet(char *pNameBuff);
35070+MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum);
35071+MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum);
35072+MV_32 mvBoardLinkStatusIrqGet(MV_U32 ethPortNum);
35073+MV_32 mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum);
35074+MV_32 mvBoardSwitchCpuPortGet(MV_U32 ethPortNum);
35075+MV_32 mvBoardIsSwitchConnected(MV_U32 ethPortNum);
35076+MV_32 mvBoardSmiScanModeGet(MV_U32 ethPortNum);
35077+MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum);
35078+MV_BOOL mvBoardIsPortInGmii(MV_VOID);
35079+MV_U32 mvBoardTclkGet(MV_VOID);
35080+MV_U32 mvBoardSysClkGet(MV_VOID);
35081+MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId);
35082+MV_VOID mvBoardDebugLed(MV_U32 hexNum);
35083+MV_32 mvBoardMppGet(MV_U32 mppGroupNum);
35084+
35085+MV_U8 mvBoardRtcTwsiAddrTypeGet(MV_VOID);
35086+MV_U8 mvBoardRtcTwsiAddrGet(MV_VOID);
35087+
35088+MV_U8 mvBoardA2DTwsiAddrTypeGet(MV_VOID);
35089+MV_U8 mvBoardA2DTwsiAddrGet(MV_VOID);
35090+
35091+MV_U8 mvBoardTwsiExpAddrGet(MV_U32 index);
35092+MV_U8 mvBoardTwsiSatRAddrTypeGet(MV_U32 index);
35093+MV_U8 mvBoardTwsiSatRAddrGet(MV_U32 index);
35094+MV_U8 mvBoardTwsiExpAddrTypeGet(MV_U32 index);
35095+MV_BOARD_MODULE_ID_CLASS mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass);
35096+MV_BOARD_MPP_TYPE_CLASS mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass);
35097+MV_VOID mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,
35098+ MV_BOARD_MPP_TYPE_CLASS mppGroupType);
35099+MV_VOID mvBoardMppGroupIdUpdate(MV_VOID);
35100+MV_VOID mvBoardMppMuxSet(MV_VOID);
35101+MV_VOID mvBoardTdmMppSet(MV_32 chType);
35102+MV_VOID mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode);
35103+
35104+MV_VOID mvBoardMppModuleTypePrint(MV_VOID);
35105+MV_VOID mvBoardReset(MV_VOID);
35106+MV_U8 mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum);
35107+MV_STATUS mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal);
35108+MV_BOOL mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data);
35109+/* Board devices API managments */
35110+MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass);
35111+MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
35112+MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
35113+MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
35114+MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
35115+MV_U32 boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
35116+
35117+/* Gpio Pin Connections API */
35118+MV_32 mvBoardUSBVbusGpioPinGet(int devId);
35119+MV_32 mvBoardUSBVbusEnGpioPinGet(int devId);
35120+MV_U32 mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin);
35121+
35122+MV_32 mvBoardResetGpioPinGet(MV_VOID);
35123+MV_32 mvBoardRTCGpioPinGet(MV_VOID);
35124+MV_32 mvBoardGpioIntMaskLowGet(MV_VOID);
35125+MV_32 mvBoardGpioIntMaskHighGet(MV_VOID);
35126+MV_32 mvBoardSlicGpioPinGet(MV_U32 slicNum);
35127+
35128+MV_32 mvBoardSDIOGpioPinGet(MV_VOID);
35129+MV_STATUS mvBoardSDioWPControl(MV_BOOL mode);
35130+MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index);
35131+
35132+MV_32 mvBoardNandWidthGet(void);
35133+MV_STATUS mvBoardFanPowerControl(MV_BOOL mode);
35134+MV_STATUS mvBoardHDDPowerControl(MV_BOOL mode);
35135+#endif /* __INCmvBoardEnvLibh */
35136diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c b/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c
35137new file mode 100644
35138index 0000000..54508c0
35139--- /dev/null
35140+++ b/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c
35141@@ -0,0 +1,848 @@
35142+/*******************************************************************************
35143+Copyright (C) Marvell International Ltd. and its affiliates
35144+
35145+This software file (the "File") is owned and distributed by Marvell
35146+International Ltd. and/or its affiliates ("Marvell") under the following
35147+alternative licensing terms. Once you have made an election to distribute the
35148+File under one of the following license alternatives, please (i) delete this
35149+introductory statement regarding license alternatives, (ii) delete the two
35150+license alternatives that you have not elected to use and (iii) preserve the
35151+Marvell copyright notice above.
35152+
35153+********************************************************************************
35154+Marvell Commercial License Option
35155+
35156+If you received this File from Marvell and you have entered into a commercial
35157+license agreement (a "Commercial License") with Marvell, the File is licensed
35158+to you under the terms of the applicable Commercial License.
35159+
35160+********************************************************************************
35161+Marvell GPL License Option
35162+
35163+If you received this File from Marvell, you may opt to use, redistribute and/or
35164+modify this File in accordance with the terms and conditions of the General
35165+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
35166+available along with the File in the license.txt file or by writing to the Free
35167+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
35168+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
35169+
35170+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
35171+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
35172+DISCLAIMED. The GPL License provides additional details about this warranty
35173+disclaimer.
35174+********************************************************************************
35175+Marvell BSD License Option
35176+
35177+If you received this File from Marvell, you may opt to use, redistribute and/or
35178+modify this File under the following licensing terms.
35179+Redistribution and use in source and binary forms, with or without modification,
35180+are permitted provided that the following conditions are met:
35181+
35182+ * Redistributions of source code must retain the above copyright notice,
35183+ this list of conditions and the following disclaimer.
35184+
35185+ * Redistributions in binary form must reproduce the above copyright
35186+ notice, this list of conditions and the following disclaimer in the
35187+ documentation and/or other materials provided with the distribution.
35188+
35189+ * Neither the name of Marvell nor the names of its contributors may be
35190+ used to endorse or promote products derived from this software without
35191+ specific prior written permission.
35192+
35193+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
35194+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35195+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35196+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
35197+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35198+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35199+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
35200+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35201+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35202+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35203+
35204+*******************************************************************************/
35205+#include "mvCommon.h"
35206+#include "mvBoardEnvLib.h"
35207+#include "mvBoardEnvSpec.h"
35208+#include "twsi/mvTwsi.h"
35209+
35210+#define DB_88F6281A_BOARD_PCI_IF_NUM 0x0
35211+#define DB_88F6281A_BOARD_TWSI_DEF_NUM 0x7
35212+#define DB_88F6281A_BOARD_MAC_INFO_NUM 0x2
35213+#define DB_88F6281A_BOARD_GPP_INFO_NUM 0x3
35214+#define DB_88F6281A_BOARD_MPP_CONFIG_NUM 0x1
35215+#define DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM 0x1
35216+#if defined(MV_NAND) && defined(MV_NAND_BOOT)
35217+ #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
35218+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
35219+ #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x2
35220+#else
35221+ #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
35222+#endif
35223+#define DB_88F6281A_BOARD_DEBUG_LED_NUM 0x0
35224+
35225+
35226+MV_BOARD_TWSI_INFO db88f6281AInfoBoardTwsiDev[] =
35227+ /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
35228+ {
35229+ {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
35230+ {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
35231+ {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
35232+ {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
35233+ {BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},
35234+ {BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},
35235+ {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
35236+ };
35237+
35238+MV_BOARD_MAC_INFO db88f6281AInfoBoardMacInfo[] =
35239+ /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
35240+ {
35241+ {BOARD_MAC_SPEED_AUTO, 0x8},
35242+ {BOARD_MAC_SPEED_AUTO, 0x9}
35243+ };
35244+
35245+MV_BOARD_MPP_TYPE_INFO db88f6281AInfoBoardMppTypeInfo[] =
35246+ /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
35247+ MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
35248+ {{MV_BOARD_AUTO, MV_BOARD_AUTO}
35249+ };
35250+
35251+MV_BOARD_GPP_INFO db88f6281AInfoBoardGppInfo[] =
35252+ /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
35253+ {
35254+ {BOARD_GPP_TSU_DIRCTION, 33}
35255+ /*muxed with TDM/Audio module via IOexpender
35256+ {BOARD_GPP_SDIO_DETECT, 38},
35257+ {BOARD_GPP_USB_VBUS, 49}*/
35258+ };
35259+
35260+MV_DEV_CS_INFO db88f6281AInfoBoardDeCsInfo[] =
35261+ /*{deviceCS, params, devType, devWidth}*/
35262+#if defined(MV_NAND) && defined(MV_NAND_BOOT)
35263+ {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
35264+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
35265+ {
35266+ {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
35267+ {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
35268+ };
35269+#else
35270+ {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
35271+#endif
35272+
35273+MV_BOARD_MPP_INFO db88f6281AInfoBoardMppConfigValue[] =
35274+ {{{
35275+ DB_88F6281A_MPP0_7,
35276+ DB_88F6281A_MPP8_15,
35277+ DB_88F6281A_MPP16_23,
35278+ DB_88F6281A_MPP24_31,
35279+ DB_88F6281A_MPP32_39,
35280+ DB_88F6281A_MPP40_47,
35281+ DB_88F6281A_MPP48_55
35282+ }}};
35283+
35284+
35285+MV_BOARD_INFO db88f6281AInfo = {
35286+ "DB-88F6281A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
35287+ DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
35288+ db88f6281AInfoBoardMppTypeInfo,
35289+ DB_88F6281A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
35290+ db88f6281AInfoBoardMppConfigValue,
35291+ 0, /* intsGppMaskLow */
35292+ 0, /* intsGppMaskHigh */
35293+ DB_88F6281A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
35294+ db88f6281AInfoBoardDeCsInfo,
35295+ DB_88F6281A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
35296+ db88f6281AInfoBoardTwsiDev,
35297+ DB_88F6281A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
35298+ db88f6281AInfoBoardMacInfo,
35299+ DB_88F6281A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
35300+ db88f6281AInfoBoardGppInfo,
35301+ DB_88F6281A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
35302+ NULL,
35303+ 0, /* ledsPolarity */
35304+ DB_88F6281A_OE_LOW, /* gppOutEnLow */
35305+ DB_88F6281A_OE_HIGH, /* gppOutEnHigh */
35306+ DB_88F6281A_OE_VAL_LOW, /* gppOutValLow */
35307+ DB_88F6281A_OE_VAL_HIGH, /* gppOutValHigh */
35308+ 0, /* gppPolarityValLow */
35309+ BIT6, /* gppPolarityValHigh */
35310+ NULL /* pSwitchInfo */
35311+};
35312+
35313+
35314+#define RD_88F6281A_BOARD_PCI_IF_NUM 0x0
35315+#define RD_88F6281A_BOARD_TWSI_DEF_NUM 0x2
35316+#define RD_88F6281A_BOARD_MAC_INFO_NUM 0x2
35317+#define RD_88F6281A_BOARD_GPP_INFO_NUM 0x5
35318+#define RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM 0x1
35319+#define RD_88F6281A_BOARD_MPP_CONFIG_NUM 0x1
35320+#if defined(MV_NAND) && defined(MV_NAND_BOOT)
35321+ #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
35322+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
35323+ #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x2
35324+#else
35325+ #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
35326+#endif
35327+#define RD_88F6281A_BOARD_DEBUG_LED_NUM 0x0
35328+
35329+MV_BOARD_MAC_INFO rd88f6281AInfoBoardMacInfo[] =
35330+ /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
35331+ {{BOARD_MAC_SPEED_1000M, 0xa},
35332+ {BOARD_MAC_SPEED_AUTO, 0xb}
35333+ };
35334+
35335+MV_BOARD_SWITCH_INFO rd88f6281AInfoBoardSwitchInfo[] =
35336+ /* MV_32 linkStatusIrq, {MV_32 qdPort0, MV_32 qdPort1, MV_32 qdPort2, MV_32 qdPort3, MV_32 qdPort4},
35337+ MV_32 qdCpuPort, MV_32 smiScanMode, MV_32 switchOnPort} */
35338+ {{38, {0, 1, 2, 3, -1}, 5, 2, 0},
35339+ {-1, {-1}, -1, -1, -1}};
35340+
35341+MV_BOARD_TWSI_INFO rd88f6281AInfoBoardTwsiDev[] =
35342+ /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
35343+ {
35344+ {BOARD_DEV_TWSI_EXP, 0xFF, ADDR7_BIT}, /* dummy entry to align with modules indexes */
35345+ {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT}
35346+ };
35347+
35348+MV_BOARD_MPP_TYPE_INFO rd88f6281AInfoBoardMppTypeInfo[] =
35349+ {{MV_BOARD_RGMII, MV_BOARD_TDM}
35350+ };
35351+
35352+MV_DEV_CS_INFO rd88f6281AInfoBoardDeCsInfo[] =
35353+ /*{deviceCS, params, devType, devWidth}*/
35354+#if defined(MV_NAND) && defined(MV_NAND_BOOT)
35355+ {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
35356+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
35357+ {
35358+ {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
35359+ {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
35360+ };
35361+#else
35362+ {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
35363+#endif
35364+
35365+MV_BOARD_GPP_INFO rd88f6281AInfoBoardGppInfo[] =
35366+ /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
35367+ {{BOARD_GPP_SDIO_DETECT, 28},
35368+ {BOARD_GPP_USB_OC, 29},
35369+ {BOARD_GPP_WPS_BUTTON, 35},
35370+ {BOARD_GPP_MV_SWITCH, 38},
35371+ {BOARD_GPP_USB_VBUS, 49}
35372+ };
35373+
35374+MV_BOARD_MPP_INFO rd88f6281AInfoBoardMppConfigValue[] =
35375+ {{{
35376+ RD_88F6281A_MPP0_7,
35377+ RD_88F6281A_MPP8_15,
35378+ RD_88F6281A_MPP16_23,
35379+ RD_88F6281A_MPP24_31,
35380+ RD_88F6281A_MPP32_39,
35381+ RD_88F6281A_MPP40_47,
35382+ RD_88F6281A_MPP48_55
35383+ }}};
35384+
35385+MV_BOARD_INFO rd88f6281AInfo = {
35386+ "RD-88F6281A", /* boardName[MAX_BOARD_NAME_LEN] */
35387+ RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
35388+ rd88f6281AInfoBoardMppTypeInfo,
35389+ RD_88F6281A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
35390+ rd88f6281AInfoBoardMppConfigValue,
35391+ 0, /* intsGppMaskLow */
35392+ (1 << 3), /* intsGppMaskHigh */
35393+ RD_88F6281A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
35394+ rd88f6281AInfoBoardDeCsInfo,
35395+ RD_88F6281A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
35396+ rd88f6281AInfoBoardTwsiDev,
35397+ RD_88F6281A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
35398+ rd88f6281AInfoBoardMacInfo,
35399+ RD_88F6281A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
35400+ rd88f6281AInfoBoardGppInfo,
35401+ RD_88F6281A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
35402+ NULL,
35403+ 0, /* ledsPolarity */
35404+ RD_88F6281A_OE_LOW, /* gppOutEnLow */
35405+ RD_88F6281A_OE_HIGH, /* gppOutEnHigh */
35406+ RD_88F6281A_OE_VAL_LOW, /* gppOutValLow */
35407+ RD_88F6281A_OE_VAL_HIGH, /* gppOutValHigh */
35408+ 0, /* gppPolarityValLow */
35409+ BIT6, /* gppPolarityValHigh */
35410+ rd88f6281AInfoBoardSwitchInfo /* pSwitchInfo */
35411+};
35412+
35413+
35414+#define DB_88F6192A_BOARD_PCI_IF_NUM 0x0
35415+#define DB_88F6192A_BOARD_TWSI_DEF_NUM 0x7
35416+#define DB_88F6192A_BOARD_MAC_INFO_NUM 0x2
35417+#define DB_88F6192A_BOARD_GPP_INFO_NUM 0x3
35418+#define DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM 0x1
35419+#define DB_88F6192A_BOARD_MPP_CONFIG_NUM 0x1
35420+#if defined(MV_NAND) && defined(MV_NAND_BOOT)
35421+ #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
35422+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
35423+ #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x2
35424+#else
35425+ #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
35426+#endif
35427+#define DB_88F6192A_BOARD_DEBUG_LED_NUM 0x0
35428+
35429+MV_BOARD_TWSI_INFO db88f6192AInfoBoardTwsiDev[] =
35430+ /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
35431+ {
35432+ {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
35433+ {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
35434+ {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
35435+ {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
35436+ {BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},
35437+ {BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},
35438+ {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
35439+ };
35440+
35441+MV_BOARD_MAC_INFO db88f6192AInfoBoardMacInfo[] =
35442+ /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
35443+ {
35444+ {BOARD_MAC_SPEED_AUTO, 0x8},
35445+ {BOARD_MAC_SPEED_AUTO, 0x9}
35446+ };
35447+
35448+MV_BOARD_MPP_TYPE_INFO db88f6192AInfoBoardMppTypeInfo[] =
35449+ /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
35450+ MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
35451+ {{MV_BOARD_AUTO, MV_BOARD_OTHER}
35452+ };
35453+
35454+MV_DEV_CS_INFO db88f6192AInfoBoardDeCsInfo[] =
35455+ /*{deviceCS, params, devType, devWidth}*/
35456+#if defined(MV_NAND) && defined(MV_NAND_BOOT)
35457+ {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
35458+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
35459+ {
35460+ {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
35461+ {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
35462+ };
35463+#else
35464+ {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
35465+#endif
35466+
35467+MV_BOARD_GPP_INFO db88f6192AInfoBoardGppInfo[] =
35468+ /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
35469+ {
35470+ {BOARD_GPP_SDIO_WP, 20},
35471+ {BOARD_GPP_USB_VBUS, 22},
35472+ {BOARD_GPP_SDIO_DETECT, 23},
35473+ };
35474+
35475+MV_BOARD_MPP_INFO db88f6192AInfoBoardMppConfigValue[] =
35476+ {{{
35477+ DB_88F6192A_MPP0_7,
35478+ DB_88F6192A_MPP8_15,
35479+ DB_88F6192A_MPP16_23,
35480+ DB_88F6192A_MPP24_31,
35481+ DB_88F6192A_MPP32_35
35482+ }}};
35483+
35484+MV_BOARD_INFO db88f6192AInfo = {
35485+ "DB-88F6192A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
35486+ DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
35487+ db88f6192AInfoBoardMppTypeInfo,
35488+ DB_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
35489+ db88f6192AInfoBoardMppConfigValue,
35490+ 0, /* intsGppMaskLow */
35491+ (1 << 3), /* intsGppMaskHigh */
35492+ DB_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
35493+ db88f6192AInfoBoardDeCsInfo,
35494+ DB_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
35495+ db88f6192AInfoBoardTwsiDev,
35496+ DB_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
35497+ db88f6192AInfoBoardMacInfo,
35498+ DB_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
35499+ db88f6192AInfoBoardGppInfo,
35500+ DB_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
35501+ NULL,
35502+ 0, /* ledsPolarity */
35503+ DB_88F6192A_OE_LOW, /* gppOutEnLow */
35504+ DB_88F6192A_OE_HIGH, /* gppOutEnHigh */
35505+ DB_88F6192A_OE_VAL_LOW, /* gppOutValLow */
35506+ DB_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
35507+ 0, /* gppPolarityValLow */
35508+ 0, /* gppPolarityValHigh */
35509+ NULL /* pSwitchInfo */
35510+};
35511+
35512+#define DB_88F6190A_BOARD_MAC_INFO_NUM 0x1
35513+
35514+MV_BOARD_INFO db88f6190AInfo = {
35515+ "DB-88F6190A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
35516+ DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
35517+ db88f6192AInfoBoardMppTypeInfo,
35518+ DB_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
35519+ db88f6192AInfoBoardMppConfigValue,
35520+ 0, /* intsGppMaskLow */
35521+ (1 << 3), /* intsGppMaskHigh */
35522+ DB_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
35523+ db88f6192AInfoBoardDeCsInfo,
35524+ DB_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
35525+ db88f6192AInfoBoardTwsiDev,
35526+ DB_88F6190A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
35527+ db88f6192AInfoBoardMacInfo,
35528+ DB_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
35529+ db88f6192AInfoBoardGppInfo,
35530+ DB_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
35531+ NULL,
35532+ 0, /* ledsPolarity */
35533+ DB_88F6192A_OE_LOW, /* gppOutEnLow */
35534+ DB_88F6192A_OE_HIGH, /* gppOutEnHigh */
35535+ DB_88F6192A_OE_VAL_LOW, /* gppOutValLow */
35536+ DB_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
35537+ 0, /* gppPolarityValLow */
35538+ 0, /* gppPolarityValHigh */
35539+ NULL /* pSwitchInfo */
35540+};
35541+
35542+#define RD_88F6192A_BOARD_PCI_IF_NUM 0x0
35543+#define RD_88F6192A_BOARD_TWSI_DEF_NUM 0x0
35544+#define RD_88F6192A_BOARD_MAC_INFO_NUM 0x1
35545+#define RD_88F6192A_BOARD_GPP_INFO_NUM 0xE
35546+#define RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM 0x1
35547+#define RD_88F6192A_BOARD_MPP_CONFIG_NUM 0x1
35548+#define RD_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
35549+#define RD_88F6192A_BOARD_DEBUG_LED_NUM 0x3
35550+
35551+MV_U8 rd88f6192AInfoBoardDebugLedIf[] =
35552+ {17, 28, 29};
35553+
35554+MV_BOARD_MAC_INFO rd88f6192AInfoBoardMacInfo[] =
35555+ /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
35556+ {{BOARD_MAC_SPEED_AUTO, 0x8}
35557+ };
35558+
35559+MV_BOARD_MPP_TYPE_INFO rd88f6192AInfoBoardMppTypeInfo[] =
35560+ /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
35561+ MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
35562+ {{MV_BOARD_OTHER, MV_BOARD_OTHER}
35563+ };
35564+
35565+MV_DEV_CS_INFO rd88f6192AInfoBoardDeCsInfo[] =
35566+ /*{deviceCS, params, devType, devWidth}*/
35567+ {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
35568+
35569+MV_BOARD_GPP_INFO rd88f6192AInfoBoardGppInfo[] =
35570+ /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
35571+ {
35572+ {BOARD_GPP_USB_VBUS_EN, 10},
35573+ {BOARD_GPP_USB_HOST_DEVICE, 11},
35574+ {BOARD_GPP_RESET, 14},
35575+ {BOARD_GPP_POWER_ON_LED, 15},
35576+ {BOARD_GPP_HDD_POWER, 16},
35577+ {BOARD_GPP_WPS_BUTTON, 24},
35578+ {BOARD_GPP_TS_BUTTON_C, 25},
35579+ {BOARD_GPP_USB_VBUS, 26},
35580+ {BOARD_GPP_USB_OC, 27},
35581+ {BOARD_GPP_TS_BUTTON_U, 30},
35582+ {BOARD_GPP_TS_BUTTON_R, 31},
35583+ {BOARD_GPP_TS_BUTTON_L, 32},
35584+ {BOARD_GPP_TS_BUTTON_D, 34},
35585+ {BOARD_GPP_FAN_POWER, 35}
35586+ };
35587+
35588+MV_BOARD_MPP_INFO rd88f6192AInfoBoardMppConfigValue[] =
35589+ {{{
35590+ RD_88F6192A_MPP0_7,
35591+ RD_88F6192A_MPP8_15,
35592+ RD_88F6192A_MPP16_23,
35593+ RD_88F6192A_MPP24_31,
35594+ RD_88F6192A_MPP32_35
35595+ }}};
35596+
35597+MV_BOARD_INFO rd88f6192AInfo = {
35598+ "RD-88F6192A-NAS", /* boardName[MAX_BOARD_NAME_LEN] */
35599+ RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
35600+ rd88f6192AInfoBoardMppTypeInfo,
35601+ RD_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
35602+ rd88f6192AInfoBoardMppConfigValue,
35603+ 0, /* intsGppMaskLow */
35604+ (1 << 3), /* intsGppMaskHigh */
35605+ RD_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
35606+ rd88f6192AInfoBoardDeCsInfo,
35607+ RD_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
35608+ NULL,
35609+ RD_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
35610+ rd88f6192AInfoBoardMacInfo,
35611+ RD_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
35612+ rd88f6192AInfoBoardGppInfo,
35613+ RD_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
35614+ rd88f6192AInfoBoardDebugLedIf,
35615+ 0, /* ledsPolarity */
35616+ RD_88F6192A_OE_LOW, /* gppOutEnLow */
35617+ RD_88F6192A_OE_HIGH, /* gppOutEnHigh */
35618+ RD_88F6192A_OE_VAL_LOW, /* gppOutValLow */
35619+ RD_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
35620+ 0, /* gppPolarityValLow */
35621+ 0, /* gppPolarityValHigh */
35622+ NULL /* pSwitchInfo */
35623+};
35624+
35625+MV_BOARD_INFO rd88f6190AInfo = {
35626+ "RD-88F6190A-NAS", /* boardName[MAX_BOARD_NAME_LEN] */
35627+ RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
35628+ rd88f6192AInfoBoardMppTypeInfo,
35629+ RD_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
35630+ rd88f6192AInfoBoardMppConfigValue,
35631+ 0, /* intsGppMaskLow */
35632+ (1 << 3), /* intsGppMaskHigh */
35633+ RD_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
35634+ rd88f6192AInfoBoardDeCsInfo,
35635+ RD_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
35636+ NULL,
35637+ RD_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
35638+ rd88f6192AInfoBoardMacInfo,
35639+ RD_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
35640+ rd88f6192AInfoBoardGppInfo,
35641+ RD_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
35642+ rd88f6192AInfoBoardDebugLedIf,
35643+ 0, /* ledsPolarity */
35644+ RD_88F6192A_OE_LOW, /* gppOutEnLow */
35645+ RD_88F6192A_OE_HIGH, /* gppOutEnHigh */
35646+ RD_88F6192A_OE_VAL_LOW, /* gppOutValLow */
35647+ RD_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
35648+ 0, /* gppPolarityValLow */
35649+ 0, /* gppPolarityValHigh */
35650+ NULL /* pSwitchInfo */
35651+};
35652+
35653+#define DB_88F6180A_BOARD_PCI_IF_NUM 0x0
35654+#define DB_88F6180A_BOARD_TWSI_DEF_NUM 0x5
35655+#define DB_88F6180A_BOARD_MAC_INFO_NUM 0x1
35656+#define DB_88F6180A_BOARD_GPP_INFO_NUM 0x0
35657+#define DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM 0x2
35658+#define DB_88F6180A_BOARD_MPP_CONFIG_NUM 0x1
35659+#define DB_88F6180A_BOARD_DEVICE_CONFIG_NUM 0x1
35660+#define DB_88F6180A_BOARD_DEBUG_LED_NUM 0x0
35661+
35662+MV_BOARD_TWSI_INFO db88f6180AInfoBoardTwsiDev[] =
35663+ /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
35664+ {
35665+ {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
35666+ {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
35667+ {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
35668+ {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
35669+ {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
35670+ };
35671+
35672+MV_BOARD_MAC_INFO db88f6180AInfoBoardMacInfo[] =
35673+ /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
35674+ {{BOARD_MAC_SPEED_AUTO, 0x8}
35675+ };
35676+
35677+MV_BOARD_GPP_INFO db88f6180AInfoBoardGppInfo[] =
35678+ /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
35679+ {
35680+ /* Muxed with TDM/Audio module via IOexpender
35681+ {BOARD_GPP_USB_VBUS, 6} */
35682+ };
35683+
35684+MV_BOARD_MPP_TYPE_INFO db88f6180AInfoBoardMppTypeInfo[] =
35685+ /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
35686+ MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
35687+ {{MV_BOARD_OTHER, MV_BOARD_AUTO}
35688+ };
35689+
35690+MV_DEV_CS_INFO db88f6180AInfoBoardDeCsInfo[] =
35691+ /*{deviceCS, params, devType, devWidth}*/
35692+#if defined(MV_NAND_BOOT)
35693+ {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
35694+#else
35695+ {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
35696+#endif
35697+
35698+MV_BOARD_MPP_INFO db88f6180AInfoBoardMppConfigValue[] =
35699+ {{{
35700+ DB_88F6180A_MPP0_7,
35701+ DB_88F6180A_MPP8_15,
35702+ DB_88F6180A_MPP16_23,
35703+ DB_88F6180A_MPP24_31,
35704+ DB_88F6180A_MPP32_39,
35705+ DB_88F6180A_MPP40_44
35706+ }}};
35707+
35708+MV_BOARD_INFO db88f6180AInfo = {
35709+ "DB-88F6180A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
35710+ DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
35711+ db88f6180AInfoBoardMppTypeInfo,
35712+ DB_88F6180A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
35713+ db88f6180AInfoBoardMppConfigValue,
35714+ 0, /* intsGppMaskLow */
35715+ 0, /* intsGppMaskHigh */
35716+ DB_88F6180A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
35717+ db88f6180AInfoBoardDeCsInfo,
35718+ DB_88F6180A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
35719+ db88f6180AInfoBoardTwsiDev,
35720+ DB_88F6180A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
35721+ db88f6180AInfoBoardMacInfo,
35722+ DB_88F6180A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
35723+ NULL,
35724+ DB_88F6180A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
35725+ NULL,
35726+ 0, /* ledsPolarity */
35727+ DB_88F6180A_OE_LOW, /* gppOutEnLow */
35728+ DB_88F6180A_OE_HIGH, /* gppOutEnHigh */
35729+ DB_88F6180A_OE_VAL_LOW, /* gppOutValLow */
35730+ DB_88F6180A_OE_VAL_HIGH, /* gppOutValHigh */
35731+ 0, /* gppPolarityValLow */
35732+ 0, /* gppPolarityValHigh */
35733+ NULL /* pSwitchInfo */
35734+};
35735+
35736+
35737+#define RD_88F6281A_PCAC_BOARD_PCI_IF_NUM 0x0
35738+#define RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM 0x1
35739+#define RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM 0x1
35740+#define RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM 0x0
35741+#define RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM 0x1
35742+#define RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM 0x1
35743+#if defined(MV_NAND) && defined(MV_NAND_BOOT)
35744+ #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x1
35745+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
35746+ #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x2
35747+#else
35748+ #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x1
35749+#endif
35750+#define RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM 0x4
35751+
35752+MV_U8 rd88f6281APcacInfoBoardDebugLedIf[] =
35753+ {38, 39, 40, 41};
35754+
35755+MV_BOARD_MAC_INFO rd88f6281APcacInfoBoardMacInfo[] =
35756+ /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
35757+ {{BOARD_MAC_SPEED_AUTO, 0x8}
35758+ };
35759+
35760+MV_BOARD_TWSI_INFO rd88f6281APcacInfoBoardTwsiDev[] =
35761+ /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
35762+ {
35763+ {BOARD_TWSI_OTHER, 0xa7, ADDR7_BIT}
35764+ };
35765+
35766+MV_BOARD_MPP_TYPE_INFO rd88f6281APcacInfoBoardMppTypeInfo[] =
35767+ {{MV_BOARD_OTHER, MV_BOARD_OTHER}
35768+ };
35769+
35770+MV_DEV_CS_INFO rd88f6281APcacInfoBoardDeCsInfo[] =
35771+ /*{deviceCS, params, devType, devWidth}*/
35772+#if defined(MV_NAND) && defined(MV_NAND_BOOT)
35773+ {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
35774+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
35775+ {
35776+ {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
35777+ {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
35778+ };
35779+#else
35780+ {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
35781+#endif
35782+
35783+MV_BOARD_MPP_INFO rd88f6281APcacInfoBoardMppConfigValue[] =
35784+ {{{
35785+ RD_88F6281A_PCAC_MPP0_7,
35786+ RD_88F6281A_PCAC_MPP8_15,
35787+ RD_88F6281A_PCAC_MPP16_23,
35788+ RD_88F6281A_PCAC_MPP24_31,
35789+ RD_88F6281A_PCAC_MPP32_39,
35790+ RD_88F6281A_PCAC_MPP40_47,
35791+ RD_88F6281A_PCAC_MPP48_55
35792+ }}};
35793+
35794+MV_BOARD_INFO rd88f6281APcacInfo = {
35795+ "RD-88F6281A-PCAC", /* boardName[MAX_BOARD_NAME_LEN] */
35796+ RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
35797+ rd88f6281APcacInfoBoardMppTypeInfo,
35798+ RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
35799+ rd88f6281APcacInfoBoardMppConfigValue,
35800+ 0, /* intsGppMaskLow */
35801+ (1 << 3), /* intsGppMaskHigh */
35802+ RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
35803+ rd88f6281APcacInfoBoardDeCsInfo,
35804+ RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
35805+ rd88f6281APcacInfoBoardTwsiDev,
35806+ RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
35807+ rd88f6281APcacInfoBoardMacInfo,
35808+ RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
35809+ 0,
35810+ RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
35811+ NULL,
35812+ 0, /* ledsPolarity */
35813+ RD_88F6281A_PCAC_OE_LOW, /* gppOutEnLow */
35814+ RD_88F6281A_PCAC_OE_HIGH, /* gppOutEnHigh */
35815+ RD_88F6281A_PCAC_OE_VAL_LOW, /* gppOutValLow */
35816+ RD_88F6281A_PCAC_OE_VAL_HIGH, /* gppOutValHigh */
35817+ 0, /* gppPolarityValLow */
35818+ 0, /* gppPolarityValHigh */
35819+ NULL /* pSwitchInfo */
35820+};
35821+
35822+
35823+/* 6281 Sheeva Plug*/
35824+
35825+#define SHEEVA_PLUG_BOARD_PCI_IF_NUM 0x0
35826+#define SHEEVA_PLUG_BOARD_TWSI_DEF_NUM 0x0
35827+#define SHEEVA_PLUG_BOARD_MAC_INFO_NUM 0x1
35828+#define SHEEVA_PLUG_BOARD_GPP_INFO_NUM 0x0
35829+#define SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN 0x1
35830+#define SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM 0x1
35831+#define SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM 0x1
35832+#define SHEEVA_PLUG_BOARD_DEBUG_LED_NUM 0x1
35833+
35834+MV_U8 sheevaPlugInfoBoardDebugLedIf[] =
35835+ {49};
35836+
35837+MV_BOARD_MAC_INFO sheevaPlugInfoBoardMacInfo[] =
35838+ /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
35839+ {{BOARD_MAC_SPEED_AUTO, 0x0}};
35840+
35841+MV_BOARD_TWSI_INFO sheevaPlugInfoBoardTwsiDev[] =
35842+ /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
35843+ {{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};
35844+
35845+MV_BOARD_MPP_TYPE_INFO sheevaPlugInfoBoardMppTypeInfo[] =
35846+ {{MV_BOARD_OTHER, MV_BOARD_OTHER}
35847+ };
35848+
35849+MV_DEV_CS_INFO sheevaPlugInfoBoardDeCsInfo[] =
35850+ /*{deviceCS, params, devType, devWidth}*/
35851+ {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
35852+
35853+MV_BOARD_MPP_INFO sheevaPlugInfoBoardMppConfigValue[] =
35854+ {{{
35855+ RD_SHEEVA_PLUG_MPP0_7,
35856+ RD_SHEEVA_PLUG_MPP8_15,
35857+ RD_SHEEVA_PLUG_MPP16_23,
35858+ RD_SHEEVA_PLUG_MPP24_31,
35859+ RD_SHEEVA_PLUG_MPP32_39,
35860+ RD_SHEEVA_PLUG_MPP40_47,
35861+ RD_SHEEVA_PLUG_MPP48_55
35862+ }}};
35863+
35864+MV_BOARD_INFO sheevaPlugInfo = {
35865+ "SHEEVA PLUG", /* boardName[MAX_BOARD_NAME_LEN] */
35866+ SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN, /* numBoardMppGroupType */
35867+ sheevaPlugInfoBoardMppTypeInfo,
35868+ SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
35869+ sheevaPlugInfoBoardMppConfigValue,
35870+ 0, /* intsGppMaskLow */
35871+ 0, /* intsGppMaskHigh */
35872+ SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
35873+ sheevaPlugInfoBoardDeCsInfo,
35874+ SHEEVA_PLUG_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
35875+ sheevaPlugInfoBoardTwsiDev,
35876+ SHEEVA_PLUG_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
35877+ sheevaPlugInfoBoardMacInfo,
35878+ SHEEVA_PLUG_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
35879+ 0,
35880+ SHEEVA_PLUG_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
35881+ sheevaPlugInfoBoardDebugLedIf,
35882+ 0, /* ledsPolarity */
35883+ RD_SHEEVA_PLUG_OE_LOW, /* gppOutEnLow */
35884+ RD_SHEEVA_PLUG_OE_HIGH, /* gppOutEnHigh */
35885+ RD_SHEEVA_PLUG_OE_VAL_LOW, /* gppOutValLow */
35886+ RD_SHEEVA_PLUG_OE_VAL_HIGH, /* gppOutValHigh */
35887+ 0, /* gppPolarityValLow */
35888+ 0, /* gppPolarityValHigh */
35889+ NULL /* pSwitchInfo */
35890+};
35891+
35892+/* Customer specific board place holder*/
35893+
35894+#define DB_CUSTOMER_BOARD_PCI_IF_NUM 0x0
35895+#define DB_CUSTOMER_BOARD_TWSI_DEF_NUM 0x0
35896+#define DB_CUSTOMER_BOARD_MAC_INFO_NUM 0x0
35897+#define DB_CUSTOMER_BOARD_GPP_INFO_NUM 0x0
35898+#define DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN 0x0
35899+#define DB_CUSTOMER_BOARD_MPP_CONFIG_NUM 0x0
35900+#if defined(MV_NAND) && defined(MV_NAND_BOOT)
35901+ #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
35902+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
35903+ #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
35904+#else
35905+ #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
35906+#endif
35907+#define DB_CUSTOMER_BOARD_DEBUG_LED_NUM 0x0
35908+
35909+MV_U8 dbCustomerInfoBoardDebugLedIf[] =
35910+ {0};
35911+
35912+MV_BOARD_MAC_INFO dbCustomerInfoBoardMacInfo[] =
35913+ /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
35914+ {{BOARD_MAC_SPEED_AUTO, 0x0}};
35915+
35916+MV_BOARD_TWSI_INFO dbCustomerInfoBoardTwsiDev[] =
35917+ /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
35918+ {{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};
35919+
35920+MV_BOARD_MPP_TYPE_INFO dbCustomerInfoBoardMppTypeInfo[] =
35921+ {{MV_BOARD_OTHER, MV_BOARD_OTHER}
35922+ };
35923+
35924+MV_DEV_CS_INFO dbCustomerInfoBoardDeCsInfo[] =
35925+ /*{deviceCS, params, devType, devWidth}*/
35926+#if defined(MV_NAND) && defined(MV_NAND_BOOT)
35927+ {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
35928+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
35929+ {
35930+ {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
35931+ {2, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
35932+ };
35933+#else
35934+ {{2, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
35935+#endif
35936+
35937+MV_BOARD_MPP_INFO dbCustomerInfoBoardMppConfigValue[] =
35938+ {{{
35939+ DB_CUSTOMER_MPP0_7,
35940+ DB_CUSTOMER_MPP8_15,
35941+ DB_CUSTOMER_MPP16_23,
35942+ DB_CUSTOMER_MPP24_31,
35943+ DB_CUSTOMER_MPP32_39,
35944+ DB_CUSTOMER_MPP40_47,
35945+ DB_CUSTOMER_MPP48_55
35946+ }}};
35947+
35948+MV_BOARD_INFO dbCustomerInfo = {
35949+ "DB-CUSTOMER", /* boardName[MAX_BOARD_NAME_LEN] */
35950+ DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN, /* numBoardMppGroupType */
35951+ dbCustomerInfoBoardMppTypeInfo,
35952+ DB_CUSTOMER_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
35953+ dbCustomerInfoBoardMppConfigValue,
35954+ 0, /* intsGppMaskLow */
35955+ 0, /* intsGppMaskHigh */
35956+ DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
35957+ dbCustomerInfoBoardDeCsInfo,
35958+ DB_CUSTOMER_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
35959+ dbCustomerInfoBoardTwsiDev,
35960+ DB_CUSTOMER_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
35961+ dbCustomerInfoBoardMacInfo,
35962+ DB_CUSTOMER_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
35963+ 0,
35964+ DB_CUSTOMER_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
35965+ NULL,
35966+ 0, /* ledsPolarity */
35967+ DB_CUSTOMER_OE_LOW, /* gppOutEnLow */
35968+ DB_CUSTOMER_OE_HIGH, /* gppOutEnHigh */
35969+ DB_CUSTOMER_OE_VAL_LOW, /* gppOutValLow */
35970+ DB_CUSTOMER_OE_VAL_HIGH, /* gppOutValHigh */
35971+ 0, /* gppPolarityValLow */
35972+ 0, /* gppPolarityValHigh */
35973+ NULL /* pSwitchInfo */
35974+};
35975+
35976+MV_BOARD_INFO* boardInfoTbl[] = {
35977+ &db88f6281AInfo,
35978+ &rd88f6281AInfo,
35979+ &db88f6192AInfo,
35980+ &rd88f6192AInfo,
35981+ &db88f6180AInfo,
35982+ &db88f6190AInfo,
35983+ &rd88f6190AInfo,
35984+ &rd88f6281APcacInfo,
35985+ &dbCustomerInfo,
35986+ &sheevaPlugInfo
35987+ };
35988+
35989+
35990diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h b/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h
35991new file mode 100644
35992index 0000000..b11dafb
35993--- /dev/null
35994+++ b/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h
35995@@ -0,0 +1,262 @@
35996+/*******************************************************************************
35997+Copyright (C) Marvell International Ltd. and its affiliates
35998+
35999+This software file (the "File") is owned and distributed by Marvell
36000+International Ltd. and/or its affiliates ("Marvell") under the following
36001+alternative licensing terms. Once you have made an election to distribute the
36002+File under one of the following license alternatives, please (i) delete this
36003+introductory statement regarding license alternatives, (ii) delete the two
36004+license alternatives that you have not elected to use and (iii) preserve the
36005+Marvell copyright notice above.
36006+
36007+********************************************************************************
36008+Marvell Commercial License Option
36009+
36010+If you received this File from Marvell and you have entered into a commercial
36011+license agreement (a "Commercial License") with Marvell, the File is licensed
36012+to you under the terms of the applicable Commercial License.
36013+
36014+********************************************************************************
36015+Marvell GPL License Option
36016+
36017+If you received this File from Marvell, you may opt to use, redistribute and/or
36018+modify this File in accordance with the terms and conditions of the General
36019+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
36020+available along with the File in the license.txt file or by writing to the Free
36021+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
36022+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
36023+
36024+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
36025+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
36026+DISCLAIMED. The GPL License provides additional details about this warranty
36027+disclaimer.
36028+********************************************************************************
36029+Marvell BSD License Option
36030+
36031+If you received this File from Marvell, you may opt to use, redistribute and/or
36032+modify this File under the following licensing terms.
36033+Redistribution and use in source and binary forms, with or without modification,
36034+are permitted provided that the following conditions are met:
36035+
36036+ * Redistributions of source code must retain the above copyright notice,
36037+ this list of conditions and the following disclaimer.
36038+
36039+ * Redistributions in binary form must reproduce the above copyright
36040+ notice, this list of conditions and the following disclaimer in the
36041+ documentation and/or other materials provided with the distribution.
36042+
36043+ * Neither the name of Marvell nor the names of its contributors may be
36044+ used to endorse or promote products derived from this software without
36045+ specific prior written permission.
36046+
36047+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
36048+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
36049+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36050+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
36051+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36052+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36053+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
36054+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36055+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36056+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36057+
36058+*******************************************************************************/
36059+
36060+
36061+#ifndef __INCmvBoardEnvSpech
36062+#define __INCmvBoardEnvSpech
36063+
36064+#include "mvSysHwConfig.h"
36065+
36066+
36067+/* For future use */
36068+#define BD_ID_DATA_START_OFFS 0x0
36069+#define BD_DETECT_SEQ_OFFS 0x0
36070+#define BD_SYS_NUM_OFFS 0x4
36071+#define BD_NAME_OFFS 0x8
36072+
36073+/* I2C bus addresses */
36074+#define MV_BOARD_CTRL_I2C_ADDR 0x0 /* Controller slave addr */
36075+#define MV_BOARD_CTRL_I2C_ADDR_TYPE ADDR7_BIT
36076+#define MV_BOARD_DIMM0_I2C_ADDR 0x56
36077+#define MV_BOARD_DIMM0_I2C_ADDR_TYPE ADDR7_BIT
36078+#define MV_BOARD_DIMM1_I2C_ADDR 0x54
36079+#define MV_BOARD_DIMM1_I2C_ADDR_TYPE ADDR7_BIT
36080+#define MV_BOARD_EEPROM_I2C_ADDR 0x51
36081+#define MV_BOARD_EEPROM_I2C_ADDR_TYPE ADDR7_BIT
36082+#define MV_BOARD_MAIN_EEPROM_I2C_ADDR 0x50
36083+#define MV_BOARD_MAIN_EEPROM_I2C_ADDR_TYPE ADDR7_BIT
36084+#define MV_BOARD_MUX_I2C_ADDR_ENTRY 0x2
36085+#define MV_BOARD_DIMM_I2C_CHANNEL 0x0
36086+
36087+#define BOOT_FLASH_INDEX 0
36088+#define MAIN_FLASH_INDEX 1
36089+
36090+#define BOARD_ETH_START_PORT_NUM 0
36091+
36092+/* Supported clocks */
36093+#define MV_BOARD_TCLK_100MHZ 100000000
36094+#define MV_BOARD_TCLK_125MHZ 125000000
36095+#define MV_BOARD_TCLK_133MHZ 133333333
36096+#define MV_BOARD_TCLK_150MHZ 150000000
36097+#define MV_BOARD_TCLK_166MHZ 166666667
36098+#define MV_BOARD_TCLK_200MHZ 200000000
36099+
36100+#define MV_BOARD_SYSCLK_100MHZ 100000000
36101+#define MV_BOARD_SYSCLK_125MHZ 125000000
36102+#define MV_BOARD_SYSCLK_133MHZ 133333333
36103+#define MV_BOARD_SYSCLK_150MHZ 150000000
36104+#define MV_BOARD_SYSCLK_166MHZ 166666667
36105+#define MV_BOARD_SYSCLK_200MHZ 200000000
36106+#define MV_BOARD_SYSCLK_233MHZ 233333333
36107+#define MV_BOARD_SYSCLK_250MHZ 250000000
36108+#define MV_BOARD_SYSCLK_267MHZ 266666667
36109+#define MV_BOARD_SYSCLK_300MHZ 300000000
36110+#define MV_BOARD_SYSCLK_333MHZ 333333334
36111+#define MV_BOARD_SYSCLK_400MHZ 400000000
36112+
36113+#define MV_BOARD_REFCLK_25MHZ 25000000
36114+
36115+/* Board specific */
36116+/* =============================== */
36117+
36118+/* boards ID numbers */
36119+
36120+#define BOARD_ID_BASE 0x0
36121+
36122+/* New board ID numbers */
36123+#define DB_88F6281A_BP_ID (BOARD_ID_BASE)
36124+#define DB_88F6281_BP_MLL_ID 1680
36125+#define RD_88F6281A_ID (BOARD_ID_BASE+0x1)
36126+#define RD_88F6281_MLL_ID 1682
36127+#define DB_88F6192A_BP_ID (BOARD_ID_BASE+0x2)
36128+#define RD_88F6192A_ID (BOARD_ID_BASE+0x3)
36129+#define RD_88F6192_MLL_ID 1681
36130+#define DB_88F6180A_BP_ID (BOARD_ID_BASE+0x4)
36131+#define DB_88F6190A_BP_ID (BOARD_ID_BASE+0x5)
36132+#define RD_88F6190A_ID (BOARD_ID_BASE+0x6)
36133+#define RD_88F6281A_PCAC_ID (BOARD_ID_BASE+0x7)
36134+#define DB_CUSTOMER_ID (BOARD_ID_BASE+0x8)
36135+#define SHEEVA_PLUG_ID (BOARD_ID_BASE+0x9)
36136+#define MV_MAX_BOARD_ID (SHEEVA_PLUG_ID + 1)
36137+
36138+/* DB-88F6281A-BP */
36139+#if defined(MV_NAND)
36140+ #define DB_88F6281A_MPP0_7 0x21111111
36141+#else
36142+ #define DB_88F6281A_MPP0_7 0x21112220
36143+#endif
36144+#define DB_88F6281A_MPP8_15 0x11113311
36145+#define DB_88F6281A_MPP16_23 0x00551111
36146+#define DB_88F6281A_MPP24_31 0x00000000
36147+#define DB_88F6281A_MPP32_39 0x00000000
36148+#define DB_88F6281A_MPP40_47 0x00000000
36149+#define DB_88F6281A_MPP48_55 0x00000000
36150+#define DB_88F6281A_OE_LOW 0x0
36151+#if defined(MV_TDM_5CHANNELS)
36152+ #define DB_88F6281A_OE_HIGH (BIT6)
36153+#else
36154+#define DB_88F6281A_OE_HIGH 0x0
36155+#endif
36156+#define DB_88F6281A_OE_VAL_LOW 0x0
36157+#define DB_88F6281A_OE_VAL_HIGH 0x0
36158+
36159+/* RD-88F6281A */
36160+#if defined(MV_NAND)
36161+ #define RD_88F6281A_MPP0_7 0x21111111
36162+#else
36163+ #define RD_88F6281A_MPP0_7 0x21112220
36164+#endif
36165+#define RD_88F6281A_MPP8_15 0x11113311
36166+#define RD_88F6281A_MPP16_23 0x33331111
36167+#define RD_88F6281A_MPP24_31 0x33003333
36168+#define RD_88F6281A_MPP32_39 0x20440533
36169+#define RD_88F6281A_MPP40_47 0x22202222
36170+#define RD_88F6281A_MPP48_55 0x00000002
36171+#define RD_88F6281A_OE_LOW (BIT28 | BIT29)
36172+#define RD_88F6281A_OE_HIGH (BIT3 | BIT6 | BIT17)
36173+#define RD_88F6281A_OE_VAL_LOW 0x0
36174+#define RD_88F6281A_OE_VAL_HIGH 0x0
36175+
36176+/* DB-88F6192A-BP */
36177+#if defined(MV_NAND)
36178+ #define DB_88F6192A_MPP0_7 0x21111111
36179+#else
36180+ #define DB_88F6192A_MPP0_7 0x21112220
36181+#endif
36182+#define DB_88F6192A_MPP8_15 0x11113311
36183+#define DB_88F6192A_MPP16_23 0x00501111
36184+#define DB_88F6192A_MPP24_31 0x00000000
36185+#define DB_88F6192A_MPP32_35 0x00000000
36186+#define DB_88F6192A_OE_LOW (BIT22 | BIT23)
36187+#define DB_88F6192A_OE_HIGH 0x0
36188+#define DB_88F6192A_OE_VAL_LOW 0x0
36189+#define DB_88F6192A_OE_VAL_HIGH 0x0
36190+
36191+/* RD-88F6192A */
36192+#define RD_88F6192A_MPP0_7 0x01222222
36193+#define RD_88F6192A_MPP8_15 0x00000011
36194+#define RD_88F6192A_MPP16_23 0x05550000
36195+#define RD_88F6192A_MPP24_31 0x0
36196+#define RD_88F6192A_MPP32_35 0x0
36197+#define RD_88F6192A_OE_LOW (BIT11 | BIT14 | BIT24 | BIT25 | BIT26 | BIT27 | BIT30 | BIT31)
36198+#define RD_88F6192A_OE_HIGH (BIT0 | BIT2)
36199+#define RD_88F6192A_OE_VAL_LOW 0x18400
36200+#define RD_88F6192A_OE_VAL_HIGH 0x8
36201+
36202+/* DB-88F6180A-BP */
36203+#if defined(MV_NAND)
36204+ #define DB_88F6180A_MPP0_7 0x21111111
36205+#else
36206+ #define DB_88F6180A_MPP0_7 0x01112222
36207+#endif
36208+#define DB_88F6180A_MPP8_15 0x11113311
36209+#define DB_88F6180A_MPP16_23 0x00001111
36210+#define DB_88F6180A_MPP24_31 0x0
36211+#define DB_88F6180A_MPP32_39 0x4444c000
36212+#define DB_88F6180A_MPP40_44 0x00044444
36213+#define DB_88F6180A_OE_LOW 0x0
36214+#define DB_88F6180A_OE_HIGH 0x0
36215+#define DB_88F6180A_OE_VAL_LOW 0x0
36216+#define DB_88F6180A_OE_VAL_HIGH 0x0
36217+
36218+/* RD-88F6281A_PCAC */
36219+#define RD_88F6281A_PCAC_MPP0_7 0x21111111
36220+#define RD_88F6281A_PCAC_MPP8_15 0x00003311
36221+#define RD_88F6281A_PCAC_MPP16_23 0x00001100
36222+#define RD_88F6281A_PCAC_MPP24_31 0x00000000
36223+#define RD_88F6281A_PCAC_MPP32_39 0x00000000
36224+#define RD_88F6281A_PCAC_MPP40_47 0x00000000
36225+#define RD_88F6281A_PCAC_MPP48_55 0x00000000
36226+#define RD_88F6281A_PCAC_OE_LOW 0x0
36227+#define RD_88F6281A_PCAC_OE_HIGH 0x0
36228+#define RD_88F6281A_PCAC_OE_VAL_LOW 0x0
36229+#define RD_88F6281A_PCAC_OE_VAL_HIGH 0x0
36230+
36231+/* SHEEVA PLUG */
36232+#define RD_SHEEVA_PLUG_MPP0_7 0x01111111
36233+#define RD_SHEEVA_PLUG_MPP8_15 0x11113322
36234+#define RD_SHEEVA_PLUG_MPP16_23 0x00001111
36235+#define RD_SHEEVA_PLUG_MPP24_31 0x00100000
36236+#define RD_SHEEVA_PLUG_MPP32_39 0x00000000
36237+#define RD_SHEEVA_PLUG_MPP40_47 0x00000000
36238+#define RD_SHEEVA_PLUG_MPP48_55 0x00000000
36239+#define RD_SHEEVA_PLUG_OE_LOW 0x0
36240+#define RD_SHEEVA_PLUG_OE_HIGH 0x0
36241+#define RD_SHEEVA_PLUG_OE_VAL_LOW (BIT29)
36242+#define RD_SHEEVA_PLUG_OE_VAL_HIGH ((~(BIT17 | BIT16 | BIT15)) | BIT14)
36243+
36244+/* DB-CUSTOMER */
36245+#define DB_CUSTOMER_MPP0_7 0x21111111
36246+#define DB_CUSTOMER_MPP8_15 0x00003311
36247+#define DB_CUSTOMER_MPP16_23 0x00001100
36248+#define DB_CUSTOMER_MPP24_31 0x00000000
36249+#define DB_CUSTOMER_MPP32_39 0x00000000
36250+#define DB_CUSTOMER_MPP40_47 0x00000000
36251+#define DB_CUSTOMER_MPP48_55 0x00000000
36252+#define DB_CUSTOMER_OE_LOW 0x0
36253+#define DB_CUSTOMER_OE_HIGH (~((BIT6) | (BIT7) | (BIT8) | (BIT9)))
36254+#define DB_CUSTOMER_OE_VAL_LOW 0x0
36255+#define DB_CUSTOMER_OE_VAL_HIGH 0x0
36256+
36257+#endif /* __INCmvBoardEnvSpech */
36258diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c b/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c
36259new file mode 100644
36260index 0000000..9e39354
36261--- /dev/null
36262+++ b/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c
36263@@ -0,0 +1,320 @@
36264+/*******************************************************************************
36265+Copyright (C) Marvell International Ltd. and its affiliates
36266+
36267+This software file (the "File") is owned and distributed by Marvell
36268+International Ltd. and/or its affiliates ("Marvell") under the following
36269+alternative licensing terms. Once you have made an election to distribute the
36270+File under one of the following license alternatives, please (i) delete this
36271+introductory statement regarding license alternatives, (ii) delete the two
36272+license alternatives that you have not elected to use and (iii) preserve the
36273+Marvell copyright notice above.
36274+
36275+********************************************************************************
36276+Marvell Commercial License Option
36277+
36278+If you received this File from Marvell and you have entered into a commercial
36279+license agreement (a "Commercial License") with Marvell, the File is licensed
36280+to you under the terms of the applicable Commercial License.
36281+
36282+********************************************************************************
36283+Marvell GPL License Option
36284+
36285+If you received this File from Marvell, you may opt to use, redistribute and/or
36286+modify this File in accordance with the terms and conditions of the General
36287+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
36288+available along with the File in the license.txt file or by writing to the Free
36289+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
36290+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
36291+
36292+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
36293+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
36294+DISCLAIMED. The GPL License provides additional details about this warranty
36295+disclaimer.
36296+********************************************************************************
36297+Marvell BSD License Option
36298+
36299+If you received this File from Marvell, you may opt to use, redistribute and/or
36300+modify this File under the following licensing terms.
36301+Redistribution and use in source and binary forms, with or without modification,
36302+are permitted provided that the following conditions are met:
36303+
36304+ * Redistributions of source code must retain the above copyright notice,
36305+ this list of conditions and the following disclaimer.
36306+
36307+ * Redistributions in binary form must reproduce the above copyright
36308+ notice, this list of conditions and the following disclaimer in the
36309+ documentation and/or other materials provided with the distribution.
36310+
36311+ * Neither the name of Marvell nor the names of its contributors may be
36312+ used to endorse or promote products derived from this software without
36313+ specific prior written permission.
36314+
36315+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
36316+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
36317+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36318+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
36319+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36320+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36321+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
36322+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36323+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36324+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36325+
36326+*******************************************************************************/
36327+
36328+
36329+#include "cpu/mvCpu.h"
36330+#include "ctrlEnv/mvCtrlEnvLib.h"
36331+#include "ctrlEnv/mvCtrlEnvRegs.h"
36332+#include "ctrlEnv/sys/mvCpuIfRegs.h"
36333+
36334+/* defines */
36335+#ifdef MV_DEBUG
36336+ #define DB(x) x
36337+#else
36338+ #define DB(x)
36339+#endif
36340+
36341+/* locals */
36342+
36343+/*******************************************************************************
36344+* mvCpuPclkGet - Get the CPU pClk (pipe clock)
36345+*
36346+* DESCRIPTION:
36347+* This routine extract the CPU core clock.
36348+*
36349+* INPUT:
36350+* None.
36351+*
36352+* OUTPUT:
36353+* None.
36354+*
36355+* RETURN:
36356+* 32bit clock cycles in MHertz.
36357+*
36358+*******************************************************************************/
36359+/* 6180 have different clk reset sampling */
36360+
36361+static MV_U32 mvCpu6180PclkGet(MV_VOID)
36362+{
36363+ MV_U32 tmpPClkRate=0;
36364+ MV_CPU_ARM_CLK cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
36365+
36366+ tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
36367+ tmpPClkRate = tmpPClkRate & MSAR_CPUCLCK_MASK_6180;
36368+ tmpPClkRate = tmpPClkRate >> MSAR_CPUCLCK_OFFS_6180;
36369+
36370+ tmpPClkRate = cpu6180_ddr_l2_CLK[tmpPClkRate].cpuClk;
36371+
36372+ return tmpPClkRate;
36373+}
36374+
36375+
36376+MV_U32 mvCpuPclkGet(MV_VOID)
36377+{
36378+#if defined(PCLCK_AUTO_DETECT)
36379+ MV_U32 tmpPClkRate=0;
36380+ MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;
36381+
36382+ if(mvCtrlModelGet() == MV_6180_DEV_ID)
36383+ return mvCpu6180PclkGet();
36384+
36385+ tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
36386+ tmpPClkRate = MSAR_CPUCLCK_EXTRACT(tmpPClkRate);
36387+ tmpPClkRate = cpuCLK[tmpPClkRate];
36388+
36389+ return tmpPClkRate;
36390+#else
36391+ return MV_DEFAULT_PCLK
36392+#endif
36393+}
36394+
36395+/*******************************************************************************
36396+* mvCpuL2ClkGet - Get the CPU L2 (CPU bus clock)
36397+*
36398+* DESCRIPTION:
36399+* This routine extract the CPU L2 clock.
36400+*
36401+* RETURN:
36402+* 32bit clock cycles in Hertz.
36403+*
36404+*******************************************************************************/
36405+static MV_U32 mvCpu6180L2ClkGet(MV_VOID)
36406+{
36407+ MV_U32 L2ClkRate=0;
36408+ MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
36409+
36410+ L2ClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
36411+ L2ClkRate = L2ClkRate & MSAR_CPUCLCK_MASK_6180;
36412+ L2ClkRate = L2ClkRate >> MSAR_CPUCLCK_OFFS_6180;
36413+
36414+ L2ClkRate = _cpu6180_ddr_l2_CLK[L2ClkRate].l2Clk;
36415+
36416+ return L2ClkRate;
36417+
36418+}
36419+
36420+MV_U32 mvCpuL2ClkGet(MV_VOID)
36421+{
36422+#ifdef L2CLK_AUTO_DETECT
36423+ MV_U32 L2ClkRate, tmp, pClkRate, indexL2Rtio;
36424+ MV_U32 L2Rtio[][2] = MV_L2_CLCK_RTIO_TBL;
36425+
36426+ if(mvCtrlModelGet() == MV_6180_DEV_ID)
36427+ return mvCpu6180L2ClkGet();
36428+
36429+ pClkRate = mvCpuPclkGet();
36430+
36431+ tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);
36432+ indexL2Rtio = MSAR_L2CLCK_EXTRACT(tmp);
36433+
36434+ L2ClkRate = ((pClkRate * L2Rtio[indexL2Rtio][1]) / L2Rtio[indexL2Rtio][0]);
36435+
36436+ return L2ClkRate;
36437+#else
36438+ return MV_BOARD_DEFAULT_L2CLK;
36439+#endif
36440+}
36441+
36442+
36443+/*******************************************************************************
36444+* mvCpuNameGet - Get CPU name
36445+*
36446+* DESCRIPTION:
36447+* This function returns a string describing the CPU model and revision.
36448+*
36449+* INPUT:
36450+* None.
36451+*
36452+* OUTPUT:
36453+* pNameBuff - Buffer to contain board name string. Minimum size 32 chars.
36454+*
36455+* RETURN:
36456+* None.
36457+*******************************************************************************/
36458+MV_VOID mvCpuNameGet(char *pNameBuff)
36459+{
36460+ MV_U32 cpuModel;
36461+
36462+ cpuModel = mvOsCpuPartGet();
36463+
36464+ /* The CPU module is indicated in the Processor Version Register (PVR) */
36465+ switch(cpuModel)
36466+ {
36467+ case CPU_PART_MRVL131:
36468+ mvOsSPrintf(pNameBuff, "%s (Rev %d)", "Marvell Feroceon",mvOsCpuRevGet());
36469+ break;
36470+ case CPU_PART_ARM926:
36471+ mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM926",mvOsCpuRevGet());
36472+ break;
36473+ case CPU_PART_ARM946:
36474+ mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM946",mvOsCpuRevGet());
36475+ break;
36476+ default:
36477+ mvOsSPrintf(pNameBuff,"??? (0x%04x) (Rev %d)",cpuModel,mvOsCpuRevGet());
36478+ break;
36479+ } /* switch */
36480+
36481+ return;
36482+}
36483+
36484+
36485+#define MV_PROC_STR_SIZE 50
36486+
36487+static void mvCpuIfGetL2EccMode(MV_8 *buf)
36488+{
36489+ MV_U32 regVal = MV_REG_READ(CPU_L2_CONFIG_REG);
36490+ if (regVal & BIT2)
36491+ mvOsSPrintf(buf, "L2 ECC Enabled");
36492+ else
36493+ mvOsSPrintf(buf, "L2 ECC Disabled");
36494+}
36495+
36496+static void mvCpuIfGetL2Mode(MV_8 *buf)
36497+{
36498+ MV_U32 regVal = 0;
36499+ __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
36500+ if (regVal & BIT22)
36501+ mvOsSPrintf(buf, "L2 Enabled");
36502+ else
36503+ mvOsSPrintf(buf, "L2 Disabled");
36504+}
36505+
36506+static void mvCpuIfGetL2PrefetchMode(MV_8 *buf)
36507+{
36508+ MV_U32 regVal = 0;
36509+ __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
36510+ if (regVal & BIT24)
36511+ mvOsSPrintf(buf, "L2 Prefetch Disabled");
36512+ else
36513+ mvOsSPrintf(buf, "L2 Prefetch Enabled");
36514+}
36515+
36516+static void mvCpuIfGetWriteAllocMode(MV_8 *buf)
36517+{
36518+ MV_U32 regVal = 0;
36519+ __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
36520+ if (regVal & BIT28)
36521+ mvOsSPrintf(buf, "Write Allocate Enabled");
36522+ else
36523+ mvOsSPrintf(buf, "Write Allocate Disabled");
36524+}
36525+
36526+static void mvCpuIfGetCpuStreamMode(MV_8 *buf)
36527+{
36528+ MV_U32 regVal = 0;
36529+ __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
36530+ if (regVal & BIT29)
36531+ mvOsSPrintf(buf, "CPU Streaming Enabled");
36532+ else
36533+ mvOsSPrintf(buf, "CPU Streaming Disabled");
36534+}
36535+
36536+static void mvCpuIfPrintCpuRegs(void)
36537+{
36538+ MV_U32 regVal = 0;
36539+
36540+ __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
36541+ mvOsPrintf("Extra Feature Reg = 0x%x\n",regVal);
36542+
36543+ __asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (regVal)); /* Read Control register */
36544+ mvOsPrintf("Control Reg = 0x%x\n",regVal);
36545+
36546+ __asm volatile ("mrc p15, 0, %0, c0, c0, 0" : "=r" (regVal)); /* Read ID Code register */
36547+ mvOsPrintf("ID Code Reg = 0x%x\n",regVal);
36548+
36549+ __asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r" (regVal)); /* Read Cache Type register */
36550+ mvOsPrintf("Cache Type Reg = 0x%x\n",regVal);
36551+
36552+}
36553+
36554+MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index)
36555+{
36556+ MV_U32 count = 0;
36557+
36558+ MV_8 L2_ECC_str[MV_PROC_STR_SIZE];
36559+ MV_8 L2_En_str[MV_PROC_STR_SIZE];
36560+ MV_8 L2_Prefetch_str[MV_PROC_STR_SIZE];
36561+ MV_8 Write_Alloc_str[MV_PROC_STR_SIZE];
36562+ MV_8 Cpu_Stream_str[MV_PROC_STR_SIZE];
36563+
36564+ mvCpuIfGetL2Mode(L2_En_str);
36565+ mvCpuIfGetL2EccMode(L2_ECC_str);
36566+ mvCpuIfGetL2PrefetchMode(L2_Prefetch_str);
36567+ mvCpuIfGetWriteAllocMode(Write_Alloc_str);
36568+ mvCpuIfGetCpuStreamMode(Cpu_Stream_str);
36569+ mvCpuIfPrintCpuRegs();
36570+
36571+ count += mvOsSPrintf(buffer + count + index, "%s\n", L2_En_str);
36572+ count += mvOsSPrintf(buffer + count + index, "%s\n", L2_ECC_str);
36573+ count += mvOsSPrintf(buffer + count + index, "%s\n", L2_Prefetch_str);
36574+ count += mvOsSPrintf(buffer + count + index, "%s\n", Write_Alloc_str);
36575+ count += mvOsSPrintf(buffer + count + index, "%s\n", Cpu_Stream_str);
36576+ return count;
36577+}
36578+
36579+MV_U32 whoAmI(MV_VOID)
36580+{
36581+ return 0;
36582+}
36583+
36584diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h b/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h
36585new file mode 100644
36586index 0000000..dd3a70e
36587--- /dev/null
36588+++ b/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h
36589@@ -0,0 +1,99 @@
36590+/*******************************************************************************
36591+Copyright (C) Marvell International Ltd. and its affiliates
36592+
36593+This software file (the "File") is owned and distributed by Marvell
36594+International Ltd. and/or its affiliates ("Marvell") under the following
36595+alternative licensing terms. Once you have made an election to distribute the
36596+File under one of the following license alternatives, please (i) delete this
36597+introductory statement regarding license alternatives, (ii) delete the two
36598+license alternatives that you have not elected to use and (iii) preserve the
36599+Marvell copyright notice above.
36600+
36601+********************************************************************************
36602+Marvell Commercial License Option
36603+
36604+If you received this File from Marvell and you have entered into a commercial
36605+license agreement (a "Commercial License") with Marvell, the File is licensed
36606+to you under the terms of the applicable Commercial License.
36607+
36608+********************************************************************************
36609+Marvell GPL License Option
36610+
36611+If you received this File from Marvell, you may opt to use, redistribute and/or
36612+modify this File in accordance with the terms and conditions of the General
36613+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
36614+available along with the File in the license.txt file or by writing to the Free
36615+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
36616+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
36617+
36618+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
36619+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
36620+DISCLAIMED. The GPL License provides additional details about this warranty
36621+disclaimer.
36622+********************************************************************************
36623+Marvell BSD License Option
36624+
36625+If you received this File from Marvell, you may opt to use, redistribute and/or
36626+modify this File under the following licensing terms.
36627+Redistribution and use in source and binary forms, with or without modification,
36628+are permitted provided that the following conditions are met:
36629+
36630+ * Redistributions of source code must retain the above copyright notice,
36631+ this list of conditions and the following disclaimer.
36632+
36633+ * Redistributions in binary form must reproduce the above copyright
36634+ notice, this list of conditions and the following disclaimer in the
36635+ documentation and/or other materials provided with the distribution.
36636+
36637+ * Neither the name of Marvell nor the names of its contributors may be
36638+ used to endorse or promote products derived from this software without
36639+ specific prior written permission.
36640+
36641+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
36642+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
36643+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36644+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
36645+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36646+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36647+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
36648+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36649+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36650+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36651+
36652+*******************************************************************************/
36653+
36654+
36655+#ifndef __INCmvCpuh
36656+#define __INCmvCpuh
36657+
36658+#include "mvCommon.h"
36659+#include "mvOs.h"
36660+#include "ctrlEnv/mvCtrlEnvSpec.h"
36661+
36662+/* defines */
36663+#define CPU_PART_MRVL131 0x131
36664+#define CPU_PART_ARM926 0x926
36665+#define CPU_PART_ARM946 0x946
36666+#define MV_CPU_ARM_CLK_ELM_SIZE 12
36667+#define MV_CPU_ARM_CLK_RATIO_OFF 8
36668+#define MV_CPU_ARM_CLK_DDR_OFF 4
36669+
36670+#ifndef MV_ASMLANGUAGE
36671+typedef struct _mvCpuArmClk
36672+{
36673+ MV_U32 cpuClk; /* CPU clock in MHz */
36674+ MV_U32 ddrClk; /* DDR clock in MHz */
36675+ MV_U32 l2Clk; /* CPU DDR clock ratio */
36676+
36677+}MV_CPU_ARM_CLK;
36678+
36679+MV_U32 mvCpuPclkGet(MV_VOID);
36680+MV_VOID mvCpuNameGet(char *pNameBuff);
36681+MV_U32 mvCpuL2ClkGet(MV_VOID);
36682+MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index);
36683+MV_U32 whoAmI(MV_VOID);
36684+
36685+#endif /* MV_ASMLANGUAGE */
36686+
36687+
36688+#endif /* __INCmvCpuh */
36689diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c
36690new file mode 100644
36691index 0000000..2e6226b
36692--- /dev/null
36693+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c
36694@@ -0,0 +1,296 @@
36695+/*******************************************************************************
36696+Copyright (C) Marvell International Ltd. and its affiliates
36697+
36698+This software file (the "File") is owned and distributed by Marvell
36699+International Ltd. and/or its affiliates ("Marvell") under the following
36700+alternative licensing terms. Once you have made an election to distribute the
36701+File under one of the following license alternatives, please (i) delete this
36702+introductory statement regarding license alternatives, (ii) delete the two
36703+license alternatives that you have not elected to use and (iii) preserve the
36704+Marvell copyright notice above.
36705+
36706+********************************************************************************
36707+Marvell Commercial License Option
36708+
36709+If you received this File from Marvell and you have entered into a commercial
36710+license agreement (a "Commercial License") with Marvell, the File is licensed
36711+to you under the terms of the applicable Commercial License.
36712+
36713+********************************************************************************
36714+Marvell GPL License Option
36715+
36716+If you received this File from Marvell, you may opt to use, redistribute and/or
36717+modify this File in accordance with the terms and conditions of the General
36718+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
36719+available along with the File in the license.txt file or by writing to the Free
36720+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
36721+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
36722+
36723+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
36724+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
36725+DISCLAIMED. The GPL License provides additional details about this warranty
36726+disclaimer.
36727+********************************************************************************
36728+Marvell BSD License Option
36729+
36730+If you received this File from Marvell, you may opt to use, redistribute and/or
36731+modify this File under the following licensing terms.
36732+Redistribution and use in source and binary forms, with or without modification,
36733+are permitted provided that the following conditions are met:
36734+
36735+ * Redistributions of source code must retain the above copyright notice,
36736+ this list of conditions and the following disclaimer.
36737+
36738+ * Redistributions in binary form must reproduce the above copyright
36739+ notice, this list of conditions and the following disclaimer in the
36740+ documentation and/or other materials provided with the distribution.
36741+
36742+ * Neither the name of Marvell nor the names of its contributors may be
36743+ used to endorse or promote products derived from this software without
36744+ specific prior written permission.
36745+
36746+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
36747+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
36748+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36749+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
36750+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36751+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36752+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
36753+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36754+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36755+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36756+
36757+*******************************************************************************/
36758+
36759+/*******************************************************************************
36760+* mvCtrlEnvAddrDec.h - Marvell controller address decode library
36761+*
36762+* DESCRIPTION:
36763+*
36764+* DEPENDENCIES:
36765+* None.
36766+*
36767+*******************************************************************************/
36768+
36769+/* includes */
36770+#include "ctrlEnv/mvCtrlEnvAddrDec.h"
36771+#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
36772+#include "ddr2/mvDramIfRegs.h"
36773+#include "pex/mvPexRegs.h"
36774+
36775+#define MV_DEBUG
36776+
36777+/* defines */
36778+#ifdef MV_DEBUG
36779+ #define DB(x) x
36780+#else
36781+ #define DB(x)
36782+#endif
36783+
36784+/* Default Attributes array */
36785+MV_TARGET_ATTRIB mvTargetDefaultsArray[] = TARGETS_DEF_ARRAY;
36786+extern MV_TARGET *sampleAtResetTargetArray;
36787+/* Dram\AHBToMbus\PEX share regsiter */
36788+
36789+#define CTRL_DEC_BASE_OFFS 16
36790+#define CTRL_DEC_BASE_MASK (0xffff << CTRL_DEC_BASE_OFFS)
36791+#define CTRL_DEC_BASE_ALIGNMENT 0x10000
36792+
36793+#define CTRL_DEC_SIZE_OFFS 16
36794+#define CTRL_DEC_SIZE_MASK (0xffff << CTRL_DEC_SIZE_OFFS)
36795+#define CTRL_DEC_SIZE_ALIGNMENT 0x10000
36796+
36797+#define CTRL_DEC_WIN_EN BIT0
36798+
36799+
36800+
36801+/*******************************************************************************
36802+* mvCtrlAddrDecToReg - Get address decode register format values
36803+*
36804+* DESCRIPTION:
36805+*
36806+* INPUT:
36807+*
36808+* OUTPUT:
36809+*
36810+* RETURN:
36811+*
36812+*******************************************************************************/
36813+MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin, MV_DEC_REGS *pAddrDecRegs)
36814+{
36815+
36816+ MV_U32 baseToReg=0 , sizeToReg=0;
36817+
36818+ /* BaseLow[31:16] => base register [31:16] */
36819+ baseToReg = pAddrDecWin->baseLow & CTRL_DEC_BASE_MASK;
36820+
36821+ /* Write to address decode Base Address Register */
36822+ pAddrDecRegs->baseReg &= ~CTRL_DEC_BASE_MASK;
36823+ pAddrDecRegs->baseReg |= baseToReg;
36824+
36825+ /* Get size register value according to window size */
36826+ sizeToReg = ctrlSizeToReg(pAddrDecWin->size, CTRL_DEC_SIZE_ALIGNMENT);
36827+
36828+ /* Size parameter validity check. */
36829+ if (-1 == sizeToReg)
36830+ {
36831+ return MV_BAD_PARAM;
36832+ }
36833+
36834+ /* set size */
36835+ pAddrDecRegs->sizeReg &= ~CTRL_DEC_SIZE_MASK;
36836+ pAddrDecRegs->sizeReg |= (sizeToReg << CTRL_DEC_SIZE_OFFS);
36837+
36838+
36839+ return MV_OK;
36840+
36841+}
36842+
36843+/*******************************************************************************
36844+* mvCtrlRegToAddrDec - Extract address decode struct from registers.
36845+*
36846+* DESCRIPTION:
36847+* This function extract address decode struct from address decode
36848+* registers given as parameters.
36849+*
36850+* INPUT:
36851+* pAddrDecRegs - Address decode register struct.
36852+*
36853+* OUTPUT:
36854+* pAddrDecWin - Target window data structure.
36855+*
36856+* RETURN:
36857+* MV_BAD_PARAM if address decode registers data is invalid.
36858+*
36859+*******************************************************************************/
36860+MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs, MV_ADDR_WIN *pAddrDecWin)
36861+{
36862+ MV_U32 sizeRegVal;
36863+
36864+ sizeRegVal = (pAddrDecRegs->sizeReg & CTRL_DEC_SIZE_MASK) >>
36865+ CTRL_DEC_SIZE_OFFS;
36866+
36867+ pAddrDecWin->size = ctrlRegToSize(sizeRegVal, CTRL_DEC_SIZE_ALIGNMENT);
36868+
36869+
36870+ /* Extract base address */
36871+ /* Base register [31:16] ==> baseLow[31:16] */
36872+ pAddrDecWin->baseLow = pAddrDecRegs->baseReg & CTRL_DEC_BASE_MASK;
36873+
36874+ pAddrDecWin->baseHigh = 0;
36875+
36876+ return MV_OK;
36877+
36878+}
36879+
36880+/*******************************************************************************
36881+* mvCtrlAttribGet -
36882+*
36883+* DESCRIPTION:
36884+*
36885+* INPUT:
36886+*
36887+* OUTPUT:
36888+*
36889+* RETURN:
36890+*
36891+*******************************************************************************/
36892+
36893+MV_STATUS mvCtrlAttribGet(MV_TARGET target,
36894+ MV_TARGET_ATTRIB *targetAttrib)
36895+{
36896+
36897+ targetAttrib->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].attrib;
36898+ targetAttrib->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId;
36899+
36900+ return MV_OK;
36901+
36902+}
36903+
36904+/*******************************************************************************
36905+* mvCtrlGetAttrib -
36906+*
36907+* DESCRIPTION:
36908+*
36909+* INPUT:
36910+*
36911+* OUTPUT:
36912+*
36913+* RETURN:
36914+*
36915+*******************************************************************************/
36916+MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib)
36917+{
36918+ MV_TARGET target;
36919+ MV_TARGET x;
36920+ for (target = SDRAM_CS0; target < MAX_TARGETS ; target ++)
36921+ {
36922+ x = MV_CHANGE_BOOT_CS(target);
36923+ if ((mvTargetDefaultsArray[x].attrib == targetAttrib->attrib) &&
36924+ (mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId == targetAttrib->targetId))
36925+ {
36926+ /* found it */
36927+ break;
36928+ }
36929+ }
36930+
36931+ return target;
36932+}
36933+
36934+MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin,
36935+ MV_DEC_WIN_PARAMS *pWinParam)
36936+{
36937+ MV_U32 baseToReg=0, sizeToReg=0;
36938+
36939+ /* BaseLow[31:16] => base register [31:16] */
36940+ baseToReg = pAddrDecWin->addrWin.baseLow & CTRL_DEC_BASE_MASK;
36941+
36942+ /* Write to address decode Base Address Register */
36943+ pWinParam->baseAddr &= ~CTRL_DEC_BASE_MASK;
36944+ pWinParam->baseAddr |= baseToReg;
36945+
36946+ /* Get size register value according to window size */
36947+ sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, CTRL_DEC_SIZE_ALIGNMENT);
36948+
36949+ /* Size parameter validity check. */
36950+ if (-1 == sizeToReg)
36951+ {
36952+ mvOsPrintf("mvCtrlAddrDecToParams: ERR. ctrlSizeToReg failed.\n");
36953+ return MV_BAD_PARAM;
36954+ }
36955+ pWinParam->size = sizeToReg;
36956+
36957+ pWinParam->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].attrib;
36958+ pWinParam->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].targetId;
36959+
36960+ return MV_OK;
36961+}
36962+
36963+MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam,
36964+ MV_DEC_WIN *pAddrDecWin)
36965+{
36966+ MV_TARGET_ATTRIB targetAttrib;
36967+
36968+ pAddrDecWin->addrWin.baseLow = pWinParam->baseAddr;
36969+
36970+ /* Upper 32bit address base is supported under PCI High Address remap */
36971+ pAddrDecWin->addrWin.baseHigh = 0;
36972+
36973+ /* Prepare sizeReg to ctrlRegToSize function */
36974+ pAddrDecWin->addrWin.size = ctrlRegToSize(pWinParam->size, CTRL_DEC_SIZE_ALIGNMENT);
36975+
36976+ if (-1 == pAddrDecWin->addrWin.size)
36977+ {
36978+ DB(mvOsPrintf("mvCtrlParamsToAddrDec: ERR. ctrlRegToSize failed.\n"));
36979+ return MV_BAD_PARAM;
36980+ }
36981+ targetAttrib.targetId = pWinParam->targetId;
36982+ targetAttrib.attrib = pWinParam->attrib;
36983+
36984+ pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
36985+
36986+ return MV_OK;
36987+}
36988+
36989+
36990+
36991diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h
36992new file mode 100644
36993index 0000000..fcb5a31
36994--- /dev/null
36995+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h
36996@@ -0,0 +1,203 @@
36997+/*******************************************************************************
36998+Copyright (C) Marvell International Ltd. and its affiliates
36999+
37000+This software file (the "File") is owned and distributed by Marvell
37001+International Ltd. and/or its affiliates ("Marvell") under the following
37002+alternative licensing terms. Once you have made an election to distribute the
37003+File under one of the following license alternatives, please (i) delete this
37004+introductory statement regarding license alternatives, (ii) delete the two
37005+license alternatives that you have not elected to use and (iii) preserve the
37006+Marvell copyright notice above.
37007+
37008+********************************************************************************
37009+Marvell Commercial License Option
37010+
37011+If you received this File from Marvell and you have entered into a commercial
37012+license agreement (a "Commercial License") with Marvell, the File is licensed
37013+to you under the terms of the applicable Commercial License.
37014+
37015+********************************************************************************
37016+Marvell GPL License Option
37017+
37018+If you received this File from Marvell, you may opt to use, redistribute and/or
37019+modify this File in accordance with the terms and conditions of the General
37020+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
37021+available along with the File in the license.txt file or by writing to the Free
37022+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
37023+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
37024+
37025+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
37026+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
37027+DISCLAIMED. The GPL License provides additional details about this warranty
37028+disclaimer.
37029+********************************************************************************
37030+Marvell BSD License Option
37031+
37032+If you received this File from Marvell, you may opt to use, redistribute and/or
37033+modify this File under the following licensing terms.
37034+Redistribution and use in source and binary forms, with or without modification,
37035+are permitted provided that the following conditions are met:
37036+
37037+ * Redistributions of source code must retain the above copyright notice,
37038+ this list of conditions and the following disclaimer.
37039+
37040+ * Redistributions in binary form must reproduce the above copyright
37041+ notice, this list of conditions and the following disclaimer in the
37042+ documentation and/or other materials provided with the distribution.
37043+
37044+ * Neither the name of Marvell nor the names of its contributors may be
37045+ used to endorse or promote products derived from this software without
37046+ specific prior written permission.
37047+
37048+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
37049+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37050+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37051+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
37052+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37053+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37054+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
37055+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37056+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37057+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37058+
37059+*******************************************************************************/
37060+
37061+
37062+#ifndef __INCmvCtrlEnvAddrDech
37063+#define __INCmvCtrlEnvAddrDech
37064+
37065+/* includes */
37066+#include "ctrlEnv/mvCtrlEnvLib.h"
37067+#include "ctrlEnv/mvCtrlEnvRegs.h"
37068+
37069+
37070+/* defines */
37071+/* DUnit attributes */
37072+#define ATMWCR_WIN_DUNIT_CS0_OFFS 0
37073+#define ATMWCR_WIN_DUNIT_CS0_MASK BIT0
37074+#define ATMWCR_WIN_DUNIT_CS0_REQ (0 << ATMWCR_WIN_DUNIT_CS0_OFFS)
37075+
37076+#define ATMWCR_WIN_DUNIT_CS1_OFFS 1
37077+#define ATMWCR_WIN_DUNIT_CS1_MASK BIT1
37078+#define ATMWCR_WIN_DUNIT_CS1_REQ (0 << ATMWCR_WIN_DUNIT_CS1_OFFS)
37079+
37080+#define ATMWCR_WIN_DUNIT_CS2_OFFS 2
37081+#define ATMWCR_WIN_DUNIT_CS2_MASK BIT2
37082+#define ATMWCR_WIN_DUNIT_CS2_REQ (0 << ATMWCR_WIN_DUNIT_CS2_OFFS)
37083+
37084+#define ATMWCR_WIN_DUNIT_CS3_OFFS 3
37085+#define ATMWCR_WIN_DUNIT_CS3_MASK BIT3
37086+#define ATMWCR_WIN_DUNIT_CS3_REQ (0 << ATMWCR_WIN_DUNIT_CS3_OFFS)
37087+
37088+/* RUnit (Device) attributes */
37089+#define ATMWCR_WIN_RUNIT_DEVCS0_OFFS 0
37090+#define ATMWCR_WIN_RUNIT_DEVCS0_MASK BIT0
37091+#define ATMWCR_WIN_RUNIT_DEVCS0_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS0_OFFS)
37092+
37093+#define ATMWCR_WIN_RUNIT_DEVCS1_OFFS 1
37094+#define ATMWCR_WIN_RUNIT_DEVCS1_MASK BIT1
37095+#define ATMWCR_WIN_RUNIT_DEVCS1_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS1_OFFS)
37096+
37097+#define ATMWCR_WIN_RUNIT_DEVCS2_OFFS 2
37098+#define ATMWCR_WIN_RUNIT_DEVCS2_MASK BIT2
37099+#define ATMWCR_WIN_RUNIT_DEVCS2_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS2_OFFS)
37100+
37101+#define ATMWCR_WIN_RUNIT_BOOTCS_OFFS 4
37102+#define ATMWCR_WIN_RUNIT_BOOTCS_MASK BIT4
37103+#define ATMWCR_WIN_RUNIT_BOOTCS_REQ (0 << ATMWCR_WIN_RUNIT_BOOTCS_OFFS)
37104+
37105+/* LMaster (PCI) attributes */
37106+#define ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS 0
37107+#define ATMWCR_WIN_LUNIT_BYTE_SWP_MASK BIT0
37108+#define ATMWCR_WIN_LUNIT_BYTE_SWP (0 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)
37109+#define ATMWCR_WIN_LUNIT_BYTE_NO_SWP (1 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)
37110+
37111+
37112+#define ATMWCR_WIN_LUNIT_WORD_SWP_OFFS 1
37113+#define ATMWCR_WIN_LUNIT_WORD_SWP_MASK BIT1
37114+#define ATMWCR_WIN_LUNIT_WORD_SWP (0 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)
37115+#define ATMWCR_WIN_LUNIT_WORD_NO_SWP (1 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)
37116+
37117+#define ATMWCR_WIN_LUNIT_NO_SNOOP BIT2
37118+
37119+#define ATMWCR_WIN_LUNIT_TYPE_OFFS 3
37120+#define ATMWCR_WIN_LUNIT_TYPE_MASK BIT3
37121+#define ATMWCR_WIN_LUNIT_TYPE_IO (0 << ATMWCR_WIN_LUNIT_TYPE_OFFS)
37122+#define ATMWCR_WIN_LUNIT_TYPE_MEM (1 << ATMWCR_WIN_LUNIT_TYPE_OFFS)
37123+
37124+#define ATMWCR_WIN_LUNIT_FORCE64_OFFS 4
37125+#define ATMWCR_WIN_LUNIT_FORCE64_MASK BIT4
37126+#define ATMWCR_WIN_LUNIT_FORCE64 (0 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)
37127+
37128+#define ATMWCR_WIN_LUNIT_ORDERING_OFFS 6
37129+#define ATMWCR_WIN_LUNIT_ORDERING_MASK BIT6
37130+#define ATMWCR_WIN_LUNIT_ORDERING (1 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)
37131+
37132+/* PEX Attributes */
37133+#define ATMWCR_WIN_PEX_TYPE_OFFS 3
37134+#define ATMWCR_WIN_PEX_TYPE_MASK BIT3
37135+#define ATMWCR_WIN_PEX_TYPE_IO (0 << ATMWCR_WIN_PEX_TYPE_OFFS)
37136+#define ATMWCR_WIN_PEX_TYPE_MEM (1 << ATMWCR_WIN_PEX_TYPE_OFFS)
37137+
37138+/* typedefs */
37139+
37140+/* Unsupported attributes for address decode: */
37141+/* 2) PCI0/1_REQ64n control */
37142+
37143+typedef struct _mvDecRegs
37144+{
37145+ MV_U32 baseReg;
37146+ MV_U32 baseRegHigh;
37147+ MV_U32 sizeReg;
37148+
37149+}MV_DEC_REGS;
37150+
37151+typedef struct _mvTargetAttrib
37152+{
37153+ MV_U8 attrib; /* chip select attributes */
37154+ MV_TARGET_ID targetId; /* Target Id of this MV_TARGET */
37155+
37156+}MV_TARGET_ATTRIB;
37157+
37158+
37159+/* This structure describes address decode window */
37160+typedef struct _mvDecWin
37161+{
37162+ MV_TARGET target; /* Target for addr decode window */
37163+ MV_ADDR_WIN addrWin; /* Address window of target */
37164+ MV_BOOL enable; /* Window enable/disable */
37165+}MV_DEC_WIN;
37166+
37167+typedef struct _mvDecWinParams
37168+{
37169+ MV_TARGET_ID targetId; /* Target ID field */
37170+ MV_U8 attrib; /* Attribute field */
37171+ MV_U32 baseAddr; /* Base address in register format */
37172+ MV_U32 size; /* Size in register format */
37173+}MV_DEC_WIN_PARAMS;
37174+
37175+
37176+/* mvCtrlEnvAddrDec API list */
37177+
37178+MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin,
37179+ MV_DEC_REGS *pAddrDecRegs);
37180+
37181+MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs,
37182+ MV_ADDR_WIN *pAddrDecWin);
37183+
37184+MV_STATUS mvCtrlAttribGet(MV_TARGET target,
37185+ MV_TARGET_ATTRIB *targetAttrib);
37186+
37187+MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib);
37188+
37189+
37190+MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin,
37191+ MV_DEC_WIN_PARAMS *pWinParam);
37192+
37193+MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam,
37194+ MV_DEC_WIN *pAddrDecWin);
37195+
37196+
37197+
37198+
37199+#endif /* __INCmvCtrlEnvAddrDech */
37200diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h
37201new file mode 100644
37202index 0000000..14a5ac4
37203--- /dev/null
37204+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h
37205@@ -0,0 +1,98 @@
37206+/*******************************************************************************
37207+Copyright (C) Marvell International Ltd. and its affiliates
37208+
37209+This software file (the "File") is owned and distributed by Marvell
37210+International Ltd. and/or its affiliates ("Marvell") under the following
37211+alternative licensing terms. Once you have made an election to distribute the
37212+File under one of the following license alternatives, please (i) delete this
37213+introductory statement regarding license alternatives, (ii) delete the two
37214+license alternatives that you have not elected to use and (iii) preserve the
37215+Marvell copyright notice above.
37216+
37217+********************************************************************************
37218+Marvell Commercial License Option
37219+
37220+If you received this File from Marvell and you have entered into a commercial
37221+license agreement (a "Commercial License") with Marvell, the File is licensed
37222+to you under the terms of the applicable Commercial License.
37223+
37224+********************************************************************************
37225+Marvell GPL License Option
37226+
37227+If you received this File from Marvell, you may opt to use, redistribute and/or
37228+modify this File in accordance with the terms and conditions of the General
37229+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
37230+available along with the File in the license.txt file or by writing to the Free
37231+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
37232+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
37233+
37234+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
37235+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
37236+DISCLAIMED. The GPL License provides additional details about this warranty
37237+disclaimer.
37238+********************************************************************************
37239+Marvell BSD License Option
37240+
37241+If you received this File from Marvell, you may opt to use, redistribute and/or
37242+modify this File under the following licensing terms.
37243+Redistribution and use in source and binary forms, with or without modification,
37244+are permitted provided that the following conditions are met:
37245+
37246+ * Redistributions of source code must retain the above copyright notice,
37247+ this list of conditions and the following disclaimer.
37248+
37249+ * Redistributions in binary form must reproduce the above copyright
37250+ notice, this list of conditions and the following disclaimer in the
37251+ documentation and/or other materials provided with the distribution.
37252+
37253+ * Neither the name of Marvell nor the names of its contributors may be
37254+ used to endorse or promote products derived from this software without
37255+ specific prior written permission.
37256+
37257+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
37258+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37259+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37260+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
37261+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37262+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37263+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
37264+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37265+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37266+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37267+
37268+*******************************************************************************/
37269+
37270+
37271+#ifndef __INCmvCtrlEnvAsmh
37272+#define __INCmvCtrlEnvAsmh
37273+#include "pex/mvPexRegs.h"
37274+
37275+#define CHIP_BOND_REG 0x10034
37276+#define PCKG_OPT_MASK_AS #3
37277+#define PXCCARI_REVID_MASK_AS #PXCCARI_REVID_MASK
37278+
37279+/* Read device ID into toReg bits 15:0 from 0xd0000000 */
37280+/* defines */
37281+#define MV_DV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \
37282+ MV_DV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\
37283+ and toReg, toReg, PCKG_OPT_MASK_AS /* Mask for package ID */
37284+
37285+/* Read device ID into toReg bits 15:0 from 0xf1000000*/
37286+#define MV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \
37287+ MV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\
37288+ and toReg, toReg, PCKG_OPT_MASK_AS /* Mask for package ID */
37289+
37290+/* Read Revision into toReg bits 7:0 0xd0000000*/
37291+#define MV_DV_CTRL_REV_GET_ASM(toReg, tmpReg) \
37292+ /* Read device revision */ \
37293+ MV_DV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\
37294+ and toReg, toReg, PXCCARI_REVID_MASK_AS /* Mask for calss ID */
37295+
37296+/* Read Revision into toReg bits 7:0 0xf1000000*/
37297+#define MV_CTRL_REV_GET_ASM(toReg, tmpReg) \
37298+ /* Read device revision */ \
37299+ MV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\
37300+ and toReg, toReg, PXCCARI_REVID_MASK_AS /* Mask for calss ID */
37301+
37302+
37303+#endif /* __INCmvCtrlEnvAsmh */
37304diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c
37305new file mode 100644
37306index 0000000..fa097a2
37307--- /dev/null
37308+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c
37309@@ -0,0 +1,1825 @@
37310+/*******************************************************************************
37311+Copyright (C) Marvell International Ltd. and its affiliates
37312+
37313+This software file (the "File") is owned and distributed by Marvell
37314+International Ltd. and/or its affiliates ("Marvell") under the following
37315+alternative licensing terms. Once you have made an election to distribute the
37316+File under one of the following license alternatives, please (i) delete this
37317+introductory statement regarding license alternatives, (ii) delete the two
37318+license alternatives that you have not elected to use and (iii) preserve the
37319+Marvell copyright notice above.
37320+
37321+********************************************************************************
37322+Marvell Commercial License Option
37323+
37324+If you received this File from Marvell and you have entered into a commercial
37325+license agreement (a "Commercial License") with Marvell, the File is licensed
37326+to you under the terms of the applicable Commercial License.
37327+
37328+********************************************************************************
37329+Marvell GPL License Option
37330+
37331+If you received this File from Marvell, you may opt to use, redistribute and/or
37332+modify this File in accordance with the terms and conditions of the General
37333+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
37334+available along with the File in the license.txt file or by writing to the Free
37335+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
37336+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
37337+
37338+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
37339+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
37340+DISCLAIMED. The GPL License provides additional details about this warranty
37341+disclaimer.
37342+********************************************************************************
37343+Marvell BSD License Option
37344+
37345+If you received this File from Marvell, you may opt to use, redistribute and/or
37346+modify this File under the following licensing terms.
37347+Redistribution and use in source and binary forms, with or without modification,
37348+are permitted provided that the following conditions are met:
37349+
37350+ * Redistributions of source code must retain the above copyright notice,
37351+ this list of conditions and the following disclaimer.
37352+
37353+ * Redistributions in binary form must reproduce the above copyright
37354+ notice, this list of conditions and the following disclaimer in the
37355+ documentation and/or other materials provided with the distribution.
37356+
37357+ * Neither the name of Marvell nor the names of its contributors may be
37358+ used to endorse or promote products derived from this software without
37359+ specific prior written permission.
37360+
37361+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
37362+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37363+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37364+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
37365+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37366+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37367+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
37368+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37369+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37370+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37371+
37372+*******************************************************************************/
37373+
37374+
37375+/* includes */
37376+#include "mvCommon.h"
37377+#include "mvCtrlEnvLib.h"
37378+#include "ctrlEnv/sys/mvCpuIf.h"
37379+
37380+#if defined(MV_INCLUDE_PEX)
37381+#include "pex/mvPex.h"
37382+#include "ctrlEnv/sys/mvSysPex.h"
37383+#endif
37384+
37385+#if defined(MV_INCLUDE_GIG_ETH)
37386+#include "ctrlEnv/sys/mvSysGbe.h"
37387+#endif
37388+
37389+#if defined(MV_INCLUDE_XOR)
37390+#include "ctrlEnv/sys/mvSysXor.h"
37391+#endif
37392+
37393+#if defined(MV_INCLUDE_SATA)
37394+#include "ctrlEnv/sys/mvSysSata.h"
37395+#endif
37396+
37397+#if defined(MV_INCLUDE_USB)
37398+#include "ctrlEnv/sys/mvSysUsb.h"
37399+#endif
37400+
37401+#if defined(MV_INCLUDE_AUDIO)
37402+#include "ctrlEnv/sys/mvSysAudio.h"
37403+#endif
37404+
37405+#if defined(MV_INCLUDE_CESA)
37406+#include "ctrlEnv/sys/mvSysCesa.h"
37407+#endif
37408+
37409+#if defined(MV_INCLUDE_TS)
37410+#include "ctrlEnv/sys/mvSysTs.h"
37411+#endif
37412+
37413+/* defines */
37414+#ifdef MV_DEBUG
37415+ #define DB(x) x
37416+#else
37417+ #define DB(x)
37418+#endif
37419+
37420+/*******************************************************************************
37421+* mvCtrlEnvInit - Initialize Marvell controller environment.
37422+*
37423+* DESCRIPTION:
37424+* This function get environment information and initialize controller
37425+* internal/external environment. For example
37426+* 1) MPP settings according to board MPP macros.
37427+* NOTE: It is the user responsibility to shut down all DMA channels
37428+* in device and disable controller sub units interrupts during
37429+* boot process.
37430+*
37431+* INPUT:
37432+* None.
37433+*
37434+* OUTPUT:
37435+* None.
37436+*
37437+* RETURN:
37438+* None.
37439+*
37440+*******************************************************************************/
37441+MV_STATUS mvCtrlEnvInit(MV_VOID)
37442+{
37443+ MV_U32 mppGroup;
37444+ MV_U32 devId;
37445+ MV_U32 boardId;
37446+ MV_U32 i;
37447+ MV_U32 maxMppGrp = 1;
37448+ MV_U32 mppVal = 0;
37449+ MV_U32 bootVal = 0;
37450+ MV_U32 mppGroupType = 0;
37451+ MV_U32 mppGroup1[][3] = MPP_GROUP_1_TYPE;
37452+ MV_U32 mppGroup2[][3] = MPP_GROUP_2_TYPE;
37453+
37454+ devId = mvCtrlModelGet();
37455+ boardId= mvBoardIdGet();
37456+
37457+ switch(devId){
37458+ case MV_6281_DEV_ID:
37459+ maxMppGrp = MV_6281_MPP_MAX_GROUP;
37460+ break;
37461+ case MV_6192_DEV_ID:
37462+ maxMppGrp = MV_6192_MPP_MAX_GROUP;
37463+ break;
37464+ case MV_6190_DEV_ID:
37465+ maxMppGrp = MV_6190_MPP_MAX_GROUP;
37466+ break;
37467+ case MV_6180_DEV_ID:
37468+ maxMppGrp = MV_6180_MPP_MAX_GROUP;
37469+ break;
37470+ }
37471+
37472+ /* MPP Init */
37473+ /* We split mpp init to 3 phases:
37474+ * 1. We init mpp[19:0] from the board info. mpp[23:20] will be over write
37475+ * in phase 2.
37476+ * 2. We detect the mpp group type and according the mpp values [35:20].
37477+ * 3. We detect the mpp group type and according the mpp values [49:36].
37478+ */
37479+ /* Mpp phase 1 mpp[19:0] */
37480+ /* Read MPP group from board level and assign to MPP register */
37481+ for (mppGroup = 0; mppGroup < 3; mppGroup++)
37482+ {
37483+ mppVal = mvBoardMppGet(mppGroup);
37484+ if (mppGroup == 0)
37485+ {
37486+ bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
37487+ if (mvCtrlIsBootFromSPI())
37488+ {
37489+ mppVal &= ~0xffff;
37490+ bootVal &= 0xffff;
37491+ mppVal |= bootVal;
37492+ }
37493+ else if (mvCtrlIsBootFromSPIUseNAND())
37494+ {
37495+ mppVal &= ~0xf0000000;
37496+ bootVal &= 0xf0000000;
37497+ mppVal |= bootVal;
37498+ }
37499+ else if (mvCtrlIsBootFromNAND())
37500+ {
37501+ mppVal &= ~0xffffff;
37502+ bootVal &= 0xffffff;
37503+ mppVal |= bootVal;
37504+ }
37505+ }
37506+
37507+ if (mppGroup == 2)
37508+ {
37509+ bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
37510+ if (mvCtrlIsBootFromNAND())
37511+ {
37512+ mppVal &= ~0xff00;
37513+ bootVal &= 0xff00;
37514+ mppVal |= bootVal;
37515+ }
37516+ }
37517+
37518+ MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
37519+ }
37520+
37521+ /* Identify MPPs group */
37522+ mvBoardMppGroupIdUpdate();
37523+
37524+ /* Update MPPs mux relevent only on Marvell DB */
37525+ if ((boardId == DB_88F6281A_BP_ID) ||
37526+ (boardId == DB_88F6180A_BP_ID))
37527+ mvBoardMppMuxSet();
37528+
37529+ mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_1);
37530+
37531+ /* Mpp phase 2 */
37532+ /* Read MPP group from board level and assign to MPP register */
37533+ if (devId != MV_6180_DEV_ID)
37534+ {
37535+ i = 0;
37536+ for (mppGroup = 2; mppGroup < 5; mppGroup++)
37537+ {
37538+ if ((mppGroupType == MV_BOARD_OTHER) ||
37539+ (boardId == RD_88F6281A_ID) ||
37540+ (boardId == RD_88F6192A_ID) ||
37541+ (boardId == RD_88F6190A_ID) ||
37542+ (boardId == RD_88F6281A_PCAC_ID) ||
37543+ (boardId == SHEEVA_PLUG_ID))
37544+ mppVal = mvBoardMppGet(mppGroup);
37545+ else
37546+ {
37547+ mppVal = mppGroup1[mppGroupType][i];
37548+ i++;
37549+ }
37550+
37551+ /* Group 2 is shared mpp[23:16] */
37552+ if (mppGroup == 2)
37553+ {
37554+ bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
37555+ mppVal &= ~0xffff;
37556+ bootVal &= 0xffff;
37557+ mppVal |= bootVal;
37558+ }
37559+
37560+ MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
37561+ }
37562+ }
37563+
37564+ if ((devId == MV_6192_DEV_ID) || (devId == MV_6190_DEV_ID))
37565+ return MV_OK;
37566+
37567+ /* Mpp phase 3 */
37568+ mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_2);
37569+ /* Read MPP group from board level and assign to MPP register */
37570+ i = 0;
37571+ for (mppGroup = 4; mppGroup < 7; mppGroup++)
37572+ {
37573+ if ((mppGroupType == MV_BOARD_OTHER) ||
37574+ (boardId == RD_88F6281A_ID) ||
37575+ (boardId == RD_88F6281A_PCAC_ID) ||
37576+ (boardId == SHEEVA_PLUG_ID))
37577+ mppVal = mvBoardMppGet(mppGroup);
37578+ else
37579+ {
37580+ mppVal = mppGroup2[mppGroupType][i];
37581+ i++;
37582+ }
37583+
37584+ /* Group 4 is shared mpp[35:32] */
37585+ if (mppGroup == 4)
37586+ {
37587+ bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
37588+ mppVal &= ~0xffff;
37589+ bootVal &= 0xffff;
37590+ mppVal |= bootVal;
37591+ }
37592+
37593+ MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
37594+ }
37595+ /* Update SSCG configuration register*/
37596+ if(mvBoardIdGet() == DB_88F6281A_BP_ID || mvBoardIdGet() == DB_88F6192A_BP_ID ||
37597+ mvBoardIdGet() == DB_88F6190A_BP_ID || mvBoardIdGet() == DB_88F6180A_BP_ID)
37598+ MV_REG_WRITE(0x100d8, 0x53);
37599+
37600+ return MV_OK;
37601+}
37602+
37603+/*******************************************************************************
37604+* mvCtrlMppRegGet - return reg address of mpp group
37605+*
37606+* DESCRIPTION:
37607+*
37608+* INPUT:
37609+* mppGroup - MPP group.
37610+*
37611+* OUTPUT:
37612+* None.
37613+*
37614+* RETURN:
37615+* MV_U32 - Register address.
37616+*
37617+*******************************************************************************/
37618+MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup)
37619+{
37620+ MV_U32 ret;
37621+
37622+ switch(mppGroup){
37623+ case (0): ret = MPP_CONTROL_REG0;
37624+ break;
37625+ case (1): ret = MPP_CONTROL_REG1;
37626+ break;
37627+ case (2): ret = MPP_CONTROL_REG2;
37628+ break;
37629+ case (3): ret = MPP_CONTROL_REG3;
37630+ break;
37631+ case (4): ret = MPP_CONTROL_REG4;
37632+ break;
37633+ case (5): ret = MPP_CONTROL_REG5;
37634+ break;
37635+ case (6): ret = MPP_CONTROL_REG6;
37636+ break;
37637+ default: ret = MPP_CONTROL_REG0;
37638+ break;
37639+ }
37640+ return ret;
37641+}
37642+#if defined(MV_INCLUDE_PEX)
37643+/*******************************************************************************
37644+* mvCtrlPexMaxIfGet - Get Marvell controller number of PEX interfaces.
37645+*
37646+* DESCRIPTION:
37647+* This function returns Marvell controller number of PEX interfaces.
37648+*
37649+* INPUT:
37650+* None.
37651+*
37652+* OUTPUT:
37653+* None.
37654+*
37655+* RETURN:
37656+* Marvell controller number of PEX interfaces. If controller
37657+* ID is undefined the function returns '0'.
37658+*
37659+*******************************************************************************/
37660+MV_U32 mvCtrlPexMaxIfGet(MV_VOID)
37661+{
37662+
37663+ return MV_PEX_MAX_IF;
37664+}
37665+#endif
37666+
37667+#if defined(MV_INCLUDE_GIG_ETH)
37668+/*******************************************************************************
37669+* mvCtrlEthMaxPortGet - Get Marvell controller number of etherent ports.
37670+*
37671+* DESCRIPTION:
37672+* This function returns Marvell controller number of etherent port.
37673+*
37674+* INPUT:
37675+* None.
37676+*
37677+* OUTPUT:
37678+* None.
37679+*
37680+* RETURN:
37681+* Marvell controller number of etherent port.
37682+*
37683+*******************************************************************************/
37684+MV_U32 mvCtrlEthMaxPortGet(MV_VOID)
37685+{
37686+ MV_U32 devId;
37687+
37688+ devId = mvCtrlModelGet();
37689+
37690+ switch(devId){
37691+ case MV_6281_DEV_ID:
37692+ return MV_6281_ETH_MAX_PORTS;
37693+ break;
37694+ case MV_6192_DEV_ID:
37695+ return MV_6192_ETH_MAX_PORTS;
37696+ break;
37697+ case MV_6190_DEV_ID:
37698+ return MV_6190_ETH_MAX_PORTS;
37699+ break;
37700+ case MV_6180_DEV_ID:
37701+ return MV_6180_ETH_MAX_PORTS;
37702+ break;
37703+ }
37704+ return 0;
37705+
37706+}
37707+#endif
37708+
37709+#if defined(MV_INCLUDE_XOR)
37710+/*******************************************************************************
37711+* mvCtrlXorMaxChanGet - Get Marvell controller number of XOR channels.
37712+*
37713+* DESCRIPTION:
37714+* This function returns Marvell controller number of XOR channels.
37715+*
37716+* INPUT:
37717+* None.
37718+*
37719+* OUTPUT:
37720+* None.
37721+*
37722+* RETURN:
37723+* Marvell controller number of XOR channels.
37724+*
37725+*******************************************************************************/
37726+MV_U32 mvCtrlXorMaxChanGet(MV_VOID)
37727+{
37728+ return MV_XOR_MAX_CHAN;
37729+}
37730+#endif
37731+
37732+#if defined(MV_INCLUDE_USB)
37733+/*******************************************************************************
37734+* mvCtrlUsbHostMaxGet - Get number of Marvell Usb controllers
37735+*
37736+* DESCRIPTION:
37737+*
37738+* INPUT:
37739+* None.
37740+*
37741+* OUTPUT:
37742+* None.
37743+*
37744+* RETURN:
37745+* returns number of Marvell USB controllers.
37746+*
37747+*******************************************************************************/
37748+MV_U32 mvCtrlUsbMaxGet(void)
37749+{
37750+ return MV_USB_MAX_PORTS;
37751+}
37752+#endif
37753+
37754+
37755+#if defined(MV_INCLUDE_NAND)
37756+/*******************************************************************************
37757+* mvCtrlNandSupport - Return if this controller has integrated NAND flash support
37758+*
37759+* DESCRIPTION:
37760+*
37761+* INPUT:
37762+* None.
37763+*
37764+* OUTPUT:
37765+* None.
37766+*
37767+* RETURN:
37768+* MV_TRUE if NAND is supported and MV_FALSE otherwise
37769+*
37770+*******************************************************************************/
37771+MV_U32 mvCtrlNandSupport(MV_VOID)
37772+{
37773+ MV_U32 devId;
37774+
37775+ devId = mvCtrlModelGet();
37776+
37777+ switch(devId){
37778+ case MV_6281_DEV_ID:
37779+ return MV_6281_NAND;
37780+ break;
37781+ case MV_6192_DEV_ID:
37782+ return MV_6192_NAND;
37783+ break;
37784+ case MV_6190_DEV_ID:
37785+ return MV_6190_NAND;
37786+ break;
37787+ case MV_6180_DEV_ID:
37788+ return MV_6180_NAND;
37789+ break;
37790+ }
37791+ return 0;
37792+
37793+}
37794+#endif
37795+
37796+#if defined(MV_INCLUDE_SDIO)
37797+/*******************************************************************************
37798+* mvCtrlSdioSupport - Return if this controller has integrated SDIO flash support
37799+*
37800+* DESCRIPTION:
37801+*
37802+* INPUT:
37803+* None.
37804+*
37805+* OUTPUT:
37806+* None.
37807+*
37808+* RETURN:
37809+* MV_TRUE if SDIO is supported and MV_FALSE otherwise
37810+*
37811+*******************************************************************************/
37812+MV_U32 mvCtrlSdioSupport(MV_VOID)
37813+{
37814+ MV_U32 devId;
37815+
37816+ devId = mvCtrlModelGet();
37817+
37818+ switch(devId){
37819+ case MV_6281_DEV_ID:
37820+ return MV_6281_SDIO;
37821+ break;
37822+ case MV_6192_DEV_ID:
37823+ return MV_6192_SDIO;
37824+ break;
37825+ case MV_6190_DEV_ID:
37826+ return MV_6190_SDIO;
37827+ break;
37828+ case MV_6180_DEV_ID:
37829+ return MV_6180_SDIO;
37830+ break;
37831+ }
37832+ return 0;
37833+
37834+}
37835+#endif
37836+
37837+#if defined(MV_INCLUDE_TS)
37838+/*******************************************************************************
37839+* mvCtrlTsSupport - Return if this controller has integrated TS flash support
37840+*
37841+* DESCRIPTION:
37842+*
37843+* INPUT:
37844+* None.
37845+*
37846+* OUTPUT:
37847+* None.
37848+*
37849+* RETURN:
37850+* MV_TRUE if TS is supported and MV_FALSE otherwise
37851+*
37852+*******************************************************************************/
37853+MV_U32 mvCtrlTsSupport(MV_VOID)
37854+{
37855+ MV_U32 devId;
37856+
37857+ devId = mvCtrlModelGet();
37858+
37859+ switch(devId){
37860+ case MV_6281_DEV_ID:
37861+ return MV_6281_TS;
37862+ break;
37863+ case MV_6192_DEV_ID:
37864+ return MV_6192_TS;
37865+ break;
37866+ case MV_6190_DEV_ID:
37867+ return MV_6190_TS;
37868+ break;
37869+ case MV_6180_DEV_ID:
37870+ return MV_6180_TS;
37871+ break;
37872+ }
37873+ return 0;
37874+}
37875+#endif
37876+
37877+#if defined(MV_INCLUDE_AUDIO)
37878+/*******************************************************************************
37879+* mvCtrlAudioSupport - Return if this controller has integrated AUDIO flash support
37880+*
37881+* DESCRIPTION:
37882+*
37883+* INPUT:
37884+* None.
37885+*
37886+* OUTPUT:
37887+* None.
37888+*
37889+* RETURN:
37890+* MV_TRUE if AUDIO is supported and MV_FALSE otherwise
37891+*
37892+*******************************************************************************/
37893+MV_U32 mvCtrlAudioSupport(MV_VOID)
37894+{
37895+ MV_U32 devId;
37896+
37897+ devId = mvCtrlModelGet();
37898+
37899+ switch(devId){
37900+ case MV_6281_DEV_ID:
37901+ return MV_6281_AUDIO;
37902+ break;
37903+ case MV_6192_DEV_ID:
37904+ return MV_6192_AUDIO;
37905+ break;
37906+ case MV_6190_DEV_ID:
37907+ return MV_6190_AUDIO;
37908+ break;
37909+ case MV_6180_DEV_ID:
37910+ return MV_6180_AUDIO;
37911+ break;
37912+ }
37913+ return 0;
37914+
37915+}
37916+#endif
37917+
37918+#if defined(MV_INCLUDE_TDM)
37919+/*******************************************************************************
37920+* mvCtrlTdmSupport - Return if this controller has integrated TDM flash support
37921+*
37922+* DESCRIPTION:
37923+*
37924+* INPUT:
37925+* None.
37926+*
37927+* OUTPUT:
37928+* None.
37929+*
37930+* RETURN:
37931+* MV_TRUE if TDM is supported and MV_FALSE otherwise
37932+*
37933+*******************************************************************************/
37934+MV_U32 mvCtrlTdmSupport(MV_VOID)
37935+{
37936+ MV_U32 devId;
37937+
37938+ devId = mvCtrlModelGet();
37939+
37940+ switch(devId){
37941+ case MV_6281_DEV_ID:
37942+ return MV_6281_TDM;
37943+ break;
37944+ case MV_6192_DEV_ID:
37945+ return MV_6192_TDM;
37946+ break;
37947+ case MV_6190_DEV_ID:
37948+ return MV_6190_TDM;
37949+ break;
37950+ case MV_6180_DEV_ID:
37951+ return MV_6180_TDM;
37952+ break;
37953+ }
37954+ return 0;
37955+
37956+}
37957+#endif
37958+
37959+/*******************************************************************************
37960+* mvCtrlModelGet - Get Marvell controller device model (Id)
37961+*
37962+* DESCRIPTION:
37963+* This function returns 16bit describing the device model (ID) as defined
37964+* in PCI Device and Vendor ID configuration register offset 0x0.
37965+*
37966+* INPUT:
37967+* None.
37968+*
37969+* OUTPUT:
37970+* None.
37971+*
37972+* RETURN:
37973+* 16bit desscribing Marvell controller ID
37974+*
37975+*******************************************************************************/
37976+MV_U16 mvCtrlModelGet(MV_VOID)
37977+{
37978+ MV_U32 devId;
37979+
37980+ devId = MV_REG_READ(CHIP_BOND_REG);
37981+ devId &= PCKG_OPT_MASK;
37982+
37983+ switch(devId){
37984+ case 2:
37985+ return MV_6281_DEV_ID;
37986+ break;
37987+ case 1:
37988+ if (((MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PEX_DEVICE_AND_VENDOR_ID))& 0xffff0000) >> 16)
37989+ == MV_6190_DEV_ID)
37990+ return MV_6190_DEV_ID;
37991+ else
37992+ return MV_6192_DEV_ID;
37993+ break;
37994+ case 0:
37995+ return MV_6180_DEV_ID;
37996+ break;
37997+ }
37998+
37999+ return 0;
38000+}
38001+/*******************************************************************************
38002+* mvCtrlRevGet - Get Marvell controller device revision number
38003+*
38004+* DESCRIPTION:
38005+* This function returns 8bit describing the device revision as defined
38006+* in PCI Express Class Code and Revision ID Register.
38007+*
38008+* INPUT:
38009+* None.
38010+*
38011+* OUTPUT:
38012+* None.
38013+*
38014+* RETURN:
38015+* 8bit desscribing Marvell controller revision number
38016+*
38017+*******************************************************************************/
38018+MV_U8 mvCtrlRevGet(MV_VOID)
38019+{
38020+ MV_U8 revNum;
38021+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
38022+ /* Check pex power state */
38023+ MV_U32 pexPower;
38024+ pexPower = mvCtrlPwrClckGet(PEX_UNIT_ID,0);
38025+ if (pexPower == MV_FALSE)
38026+ mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_TRUE);
38027+#endif
38028+ revNum = (MV_U8)MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PCI_CLASS_CODE_AND_REVISION_ID));
38029+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
38030+ /* Return to power off state */
38031+ if (pexPower == MV_FALSE)
38032+ mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_FALSE);
38033+#endif
38034+ return ((revNum & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS);
38035+}
38036+
38037+/*******************************************************************************
38038+* mvCtrlNameGet - Get Marvell controller name
38039+*
38040+* DESCRIPTION:
38041+* This function returns a string describing the device model and revision.
38042+*
38043+* INPUT:
38044+* None.
38045+*
38046+* OUTPUT:
38047+* pNameBuff - Buffer to contain device name string. Minimum size 30 chars.
38048+*
38049+* RETURN:
38050+*
38051+* MV_ERROR if informantion can not be read.
38052+*******************************************************************************/
38053+MV_STATUS mvCtrlNameGet(char *pNameBuff)
38054+{
38055+ mvOsSPrintf (pNameBuff, "%s%x Rev %d", SOC_NAME_PREFIX,
38056+ mvCtrlModelGet(), mvCtrlRevGet());
38057+
38058+ return MV_OK;
38059+}
38060+
38061+/*******************************************************************************
38062+* mvCtrlModelRevGet - Get Controller Model (Device ID) and Revision
38063+*
38064+* DESCRIPTION:
38065+* This function returns 32bit value describing both Device ID and Revision
38066+* as defined in PCI Express Device and Vendor ID Register and device revision
38067+* as defined in PCI Express Class Code and Revision ID Register.
38068+
38069+*
38070+* INPUT:
38071+* None.
38072+*
38073+* OUTPUT:
38074+* None.
38075+*
38076+* RETURN:
38077+* 32bit describing both controller device ID and revision number
38078+*
38079+*******************************************************************************/
38080+MV_U32 mvCtrlModelRevGet(MV_VOID)
38081+{
38082+ return ((mvCtrlModelGet() << 16) | mvCtrlRevGet());
38083+}
38084+
38085+/*******************************************************************************
38086+* mvCtrlModelRevNameGet - Get Marvell controller name
38087+*
38088+* DESCRIPTION:
38089+* This function returns a string describing the device model and revision.
38090+*
38091+* INPUT:
38092+* None.
38093+*
38094+* OUTPUT:
38095+* pNameBuff - Buffer to contain device name string. Minimum size 30 chars.
38096+*
38097+* RETURN:
38098+*
38099+* MV_ERROR if informantion can not be read.
38100+*******************************************************************************/
38101+
38102+MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff)
38103+{
38104+
38105+ switch (mvCtrlModelRevGet())
38106+ {
38107+ case MV_6281_A0_ID:
38108+ mvOsSPrintf (pNameBuff, "%s",MV_6281_A0_NAME);
38109+ break;
38110+ case MV_6192_A0_ID:
38111+ mvOsSPrintf (pNameBuff, "%s",MV_6192_A0_NAME);
38112+ break;
38113+ case MV_6180_A0_ID:
38114+ mvOsSPrintf (pNameBuff, "%s",MV_6180_A0_NAME);
38115+ break;
38116+ case MV_6190_A0_ID:
38117+ mvOsSPrintf (pNameBuff, "%s",MV_6190_A0_NAME);
38118+ break;
38119+ case MV_6281_A1_ID:
38120+ mvOsSPrintf (pNameBuff, "%s",MV_6281_A1_NAME);
38121+ break;
38122+ case MV_6192_A1_ID:
38123+ mvOsSPrintf (pNameBuff, "%s",MV_6192_A1_NAME);
38124+ break;
38125+ case MV_6180_A1_ID:
38126+ mvOsSPrintf (pNameBuff, "%s",MV_6180_A1_NAME);
38127+ break;
38128+ case MV_6190_A1_ID:
38129+ mvOsSPrintf (pNameBuff, "%s",MV_6190_A1_NAME);
38130+ break;
38131+ default:
38132+ mvCtrlNameGet(pNameBuff);
38133+ break;
38134+ }
38135+
38136+ return MV_OK;
38137+}
38138+
38139+
38140+/*******************************************************************************
38141+* ctrlWinOverlapTest - Test address windows for overlaping.
38142+*
38143+* DESCRIPTION:
38144+* This function checks the given two address windows for overlaping.
38145+*
38146+* INPUT:
38147+* pAddrWin1 - Address window 1.
38148+* pAddrWin2 - Address window 2.
38149+*
38150+* OUTPUT:
38151+* None.
38152+*
38153+* RETURN:
38154+*
38155+* MV_TRUE if address window overlaps, MV_FALSE otherwise.
38156+*******************************************************************************/
38157+MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)
38158+{
38159+ MV_U32 winBase1, winBase2;
38160+ MV_U32 winTop1, winTop2;
38161+
38162+ /* check if we have overflow than 4G*/
38163+ if (((0xffffffff - pAddrWin1->baseLow) < pAddrWin1->size-1)||
38164+ ((0xffffffff - pAddrWin2->baseLow) < pAddrWin2->size-1))
38165+ {
38166+ return MV_TRUE;
38167+ }
38168+
38169+ winBase1 = pAddrWin1->baseLow;
38170+ winBase2 = pAddrWin2->baseLow;
38171+ winTop1 = winBase1 + pAddrWin1->size-1;
38172+ winTop2 = winBase2 + pAddrWin2->size-1;
38173+
38174+
38175+ if (((winBase1 <= winTop2 ) && ( winTop2 <= winTop1)) ||
38176+ ((winBase1 <= winBase2) && (winBase2 <= winTop1)))
38177+ {
38178+ return MV_TRUE;
38179+ }
38180+ else
38181+ {
38182+ return MV_FALSE;
38183+ }
38184+}
38185+
38186+/*******************************************************************************
38187+* ctrlWinWithinWinTest - Test address windows for overlaping.
38188+*
38189+* DESCRIPTION:
38190+* This function checks the given win1 boundries is within
38191+* win2 boundries.
38192+*
38193+* INPUT:
38194+* pAddrWin1 - Address window 1.
38195+* pAddrWin2 - Address window 2.
38196+*
38197+* OUTPUT:
38198+* None.
38199+*
38200+* RETURN:
38201+*
38202+* MV_TRUE if found win1 inside win2, MV_FALSE otherwise.
38203+*******************************************************************************/
38204+MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)
38205+{
38206+ MV_U32 winBase1, winBase2;
38207+ MV_U32 winTop1, winTop2;
38208+
38209+ winBase1 = pAddrWin1->baseLow;
38210+ winBase2 = pAddrWin2->baseLow;
38211+ winTop1 = winBase1 + pAddrWin1->size -1;
38212+ winTop2 = winBase2 + pAddrWin2->size -1;
38213+
38214+ if (((winBase1 >= winBase2 ) && ( winBase1 <= winTop2)) ||
38215+ ((winTop1 >= winBase2) && (winTop1 <= winTop2)))
38216+ {
38217+ return MV_TRUE;
38218+ }
38219+ else
38220+ {
38221+ return MV_FALSE;
38222+ }
38223+}
38224+
38225+static const char* cntrlName[] = TARGETS_NAME_ARRAY;
38226+
38227+/*******************************************************************************
38228+* mvCtrlTargetNameGet - Get Marvell controller target name
38229+*
38230+* DESCRIPTION:
38231+* This function convert the trget enumeration to string.
38232+*
38233+* INPUT:
38234+* None.
38235+*
38236+* OUTPUT:
38237+* None.
38238+*
38239+* RETURN:
38240+* Target name (const MV_8 *)
38241+*******************************************************************************/
38242+const MV_8* mvCtrlTargetNameGet( MV_TARGET target )
38243+{
38244+
38245+ if (target >= MAX_TARGETS)
38246+ {
38247+ return "target unknown";
38248+ }
38249+
38250+ return cntrlName[target];
38251+}
38252+
38253+/*******************************************************************************
38254+* mvCtrlAddrDecShow - Print the Controller units address decode map.
38255+*
38256+* DESCRIPTION:
38257+* This function the Controller units address decode map.
38258+*
38259+* INPUT:
38260+* None.
38261+*
38262+* OUTPUT:
38263+* None.
38264+*
38265+* RETURN:
38266+* None.
38267+*
38268+*******************************************************************************/
38269+MV_VOID mvCtrlAddrDecShow(MV_VOID)
38270+{
38271+ mvCpuIfAddDecShow();
38272+ mvAhbToMbusAddDecShow();
38273+#if defined(MV_INCLUDE_PEX)
38274+ mvPexAddrDecShow();
38275+#endif
38276+#if defined(MV_INCLUDE_USB)
38277+ mvUsbAddrDecShow();
38278+#endif
38279+#if defined(MV_INCLUDE_GIG_ETH)
38280+ mvEthAddrDecShow();
38281+#endif
38282+#if defined(MV_INCLUDE_XOR)
38283+ mvXorAddrDecShow();
38284+#endif
38285+#if defined(MV_INCLUDE_SATA)
38286+ mvSataAddrDecShow();
38287+#endif
38288+#if defined(MV_INCLUDE_AUDIO)
38289+ mvAudioAddrDecShow();
38290+#endif
38291+#if defined(MV_INCLUDE_TS)
38292+ mvTsuAddrDecShow();
38293+#endif
38294+}
38295+
38296+/*******************************************************************************
38297+* ctrlSizeToReg - Extract size value for register assignment.
38298+*
38299+* DESCRIPTION:
38300+* Address decode size parameter must be programed from LSB to MSB as
38301+* sequence of 1's followed by sequence of 0's. The number of 1's
38302+* specifies the size of the window in 64 KB granularity (e.g. a
38303+* value of 0x00ff specifies 256x64k = 16 MB).
38304+* This function extract the size value from the size parameter according
38305+* to given aligment paramter. For example for size 0x1000000 (16MB) and
38306+* aligment 0x10000 (64KB) the function will return 0x00FF.
38307+*
38308+* INPUT:
38309+* size - Size.
38310+* alignment - Size alignment. Note that alignment must be power of 2!
38311+*
38312+* OUTPUT:
38313+* None.
38314+*
38315+* RETURN:
38316+* 32bit describing size register value correspond to size parameter.
38317+* If value is '-1' size parameter or aligment are invalid.
38318+*******************************************************************************/
38319+MV_U32 ctrlSizeToReg(MV_U32 size, MV_U32 alignment)
38320+{
38321+ MV_U32 retVal;
38322+
38323+ /* Check size parameter alignment */
38324+ if ((0 == size) || (MV_IS_NOT_ALIGN(size, alignment)))
38325+ {
38326+ DB(mvOsPrintf("ctrlSizeToReg: ERR. Size is zero or not aligned.\n"));
38327+ return -1;
38328+ }
38329+
38330+ /* Take out the "alignment" portion out of the size parameter */
38331+ alignment--; /* Now the alignmet is a sequance of '1' (e.g. 0xffff) */
38332+ /* and size is 0x1000000 (16MB) for example */
38333+ while(alignment & 1) /* Check that alignmet LSB is set */
38334+ {
38335+ size = (size >> 1); /* If LSB is set, move 'size' one bit to right */
38336+ alignment = (alignment >> 1);
38337+ }
38338+
38339+ /* If after the alignment first '0' was met we still have '1' in */
38340+ /* it then aligment is invalid (not power of 2) */
38341+ if (alignment)
38342+ {
38343+ DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n",
38344+ (MV_U32)alignment));
38345+ return -1;
38346+ }
38347+
38348+ /* Now the size is shifted right according to aligment: 0x0100 */
38349+ size--; /* Now the size is a sequance of '1': 0x00ff */
38350+
38351+ retVal = size ;
38352+
38353+ /* Check that LSB to MSB is sequence of 1's followed by sequence of 0's */
38354+ while(size & 1) /* Check that LSB is set */
38355+ {
38356+ size = (size >> 1); /* If LSB is set, move one bit to the right */
38357+ }
38358+
38359+ if (size) /* Sequance of 1's is over. Check that we have no other 1's */
38360+ {
38361+ DB(mvOsPrintf("ctrlSizeToReg: ERR. Size parameter 0x%x invalid.\n",
38362+ size));
38363+ return -1;
38364+ }
38365+
38366+ return retVal;
38367+
38368+}
38369+
38370+/*******************************************************************************
38371+* ctrlRegToSize - Extract size value from register value.
38372+*
38373+* DESCRIPTION:
38374+* This function extract a size value from the register size parameter
38375+* according to given aligment paramter. For example for register size
38376+* value 0xff and aligment 0x10000 the function will return 0x01000000.
38377+*
38378+* INPUT:
38379+* regSize - Size as in register format. See ctrlSizeToReg.
38380+* alignment - Size alignment. Note that alignment must be power of 2!
38381+*
38382+* OUTPUT:
38383+* None.
38384+*
38385+* RETURN:
38386+* 32bit describing size.
38387+* If value is '-1' size parameter or aligment are invalid.
38388+*******************************************************************************/
38389+MV_U32 ctrlRegToSize(MV_U32 regSize, MV_U32 alignment)
38390+{
38391+ MV_U32 temp;
38392+
38393+ /* Check that LSB to MSB is sequence of 1's followed by sequence of 0's */
38394+ temp = regSize; /* Now the size is a sequance of '1': 0x00ff */
38395+
38396+ while(temp & 1) /* Check that LSB is set */
38397+ {
38398+ temp = (temp >> 1); /* If LSB is set, move one bit to the right */
38399+ }
38400+
38401+ if (temp) /* Sequance of 1's is over. Check that we have no other 1's */
38402+ {
38403+ DB(mvOsPrintf("ctrlRegToSize: ERR. Size parameter 0x%x invalid.\n",
38404+ regSize));
38405+ return -1;
38406+ }
38407+
38408+
38409+ /* Check that aligment is a power of two */
38410+ temp = alignment - 1;/* Now the alignmet is a sequance of '1' (0xffff) */
38411+
38412+ while(temp & 1) /* Check that alignmet LSB is set */
38413+ {
38414+ temp = (temp >> 1); /* If LSB is set, move 'size' one bit to right */
38415+ }
38416+
38417+ /* If after the 'temp' first '0' was met we still have '1' in 'temp' */
38418+ /* then 'temp' is invalid (not power of 2) */
38419+ if (temp)
38420+ {
38421+ DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n",
38422+ alignment));
38423+ return -1;
38424+ }
38425+
38426+ regSize++; /* Now the size is 0x0100 */
38427+
38428+ /* Add in the "alignment" portion to the register size parameter */
38429+ alignment--; /* Now the alignmet is a sequance of '1' (e.g. 0xffff) */
38430+
38431+ while(alignment & 1) /* Check that alignmet LSB is set */
38432+ {
38433+ regSize = (regSize << 1); /* LSB is set, move 'size' one bit left */
38434+ alignment = (alignment >> 1);
38435+ }
38436+
38437+ return regSize;
38438+}
38439+
38440+
38441+/*******************************************************************************
38442+* ctrlSizeRegRoundUp - Round up given size
38443+*
38444+* DESCRIPTION:
38445+* This function round up a given size to a size that fits the
38446+* restrictions of size format given an aligment parameter.
38447+* to given aligment paramter. For example for size parameter 0xa1000 and
38448+* aligment 0x1000 the function will return 0xFF000.
38449+*
38450+* INPUT:
38451+* size - Size.
38452+* alignment - Size alignment. Note that alignment must be power of 2!
38453+*
38454+* OUTPUT:
38455+* None.
38456+*
38457+* RETURN:
38458+* 32bit describing size value correspond to size in register.
38459+*******************************************************************************/
38460+MV_U32 ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment)
38461+{
38462+ MV_U32 msbBit = 0;
38463+ MV_U32 retSize;
38464+
38465+ /* Check if size parameter is already comply with restriction */
38466+ if (!(-1 == ctrlSizeToReg(size, alignment)))
38467+ {
38468+ return size;
38469+ }
38470+
38471+ while(size)
38472+ {
38473+ size = (size >> 1);
38474+ msbBit++;
38475+ }
38476+
38477+ retSize = (1 << msbBit);
38478+
38479+ if (retSize < alignment)
38480+ {
38481+ return alignment;
38482+ }
38483+ else
38484+ {
38485+ return retSize;
38486+ }
38487+}
38488+/*******************************************************************************
38489+* mvCtrlSysRstLengthCounterGet - Return number of milliseconds the reset button
38490+* was pressed and clear counter
38491+*
38492+* DESCRIPTION:
38493+*
38494+* INPUT:
38495+*
38496+* OUTPUT:
38497+*
38498+* RETURN: number of milliseconds the reset button was pressed
38499+*******************************************************************************/
38500+MV_U32 mvCtrlSysRstLengthCounterGet(MV_VOID)
38501+{
38502+ static volatile MV_U32 Count = 0;
38503+
38504+ if(!Count) {
38505+ Count = (MV_REG_READ(SYSRST_LENGTH_COUNTER_REG) & SLCR_COUNT_MASK);
38506+ Count = (Count / (MV_BOARD_REFCLK_25MHZ / 1000));
38507+ /* clear counter for next boot */
38508+ MV_REG_BIT_SET(SYSRST_LENGTH_COUNTER_REG, SLCR_CLR_MASK);
38509+ }
38510+
38511+ DB(mvOsPrintf("mvCtrlSysRstLengthCounterGet: Reset button was pressed for %u milliseconds\n", Count));
38512+
38513+ return Count;
38514+}
38515+
38516+MV_BOOL mvCtrlIsBootFromSPI(MV_VOID)
38517+{
38518+ MV_U32 satr = 0;
38519+ satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
38520+ if(mvCtrlModelGet() == MV_6180_DEV_ID)
38521+ {
38522+ if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_SPI_WITH_BOOTROM_6180)
38523+ return MV_TRUE;
38524+ else
38525+ return MV_FALSE;
38526+ }
38527+ satr = satr & MSAR_BOOT_MODE_MASK;
38528+ if (satr == MSAR_BOOT_SPI_WITH_BOOTROM)
38529+ return MV_TRUE;
38530+ else
38531+ return MV_FALSE;
38532+}
38533+
38534+MV_BOOL mvCtrlIsBootFromSPIUseNAND(MV_VOID)
38535+{
38536+ MV_U32 satr = 0;
38537+ if(mvCtrlModelGet() == MV_6180_DEV_ID)
38538+ return MV_FALSE;
38539+ satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
38540+ satr = satr & MSAR_BOOT_MODE_MASK;
38541+
38542+ if (satr == MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM)
38543+ return MV_TRUE;
38544+ else
38545+ return MV_FALSE;
38546+}
38547+
38548+MV_BOOL mvCtrlIsBootFromNAND(MV_VOID)
38549+{
38550+ MV_U32 satr = 0;
38551+ satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
38552+ if(mvCtrlModelGet() == MV_6180_DEV_ID)
38553+ {
38554+ if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_NAND_WITH_BOOTROM_6180)
38555+ return MV_TRUE;
38556+ else
38557+ return MV_FALSE;
38558+ }
38559+ satr = satr & MSAR_BOOT_MODE_MASK;
38560+ if ((satr == MSAR_BOOT_NAND_WITH_BOOTROM))
38561+ return MV_TRUE;
38562+ else
38563+ return MV_FALSE;
38564+}
38565+
38566+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
38567+/*******************************************************************************
38568+* mvCtrlPwrSaveOn - Set Power save mode
38569+*
38570+* DESCRIPTION:
38571+*
38572+* INPUT:
38573+*
38574+* OUTPUT:
38575+*
38576+* RETURN:
38577+*******************************************************************************/
38578+MV_VOID mvCtrlPwrSaveOn(MV_VOID)
38579+{
38580+ unsigned long old,temp;
38581+ /* Disable int */
38582+ __asm__ __volatile__("mrs %0, cpsr\n"
38583+ "orr %1, %0, #0xc0\n"
38584+ "msr cpsr_c, %1"
38585+ : "=r" (old), "=r" (temp)
38586+ :
38587+ : "memory");
38588+
38589+ /* Set SoC in power save */
38590+ MV_REG_BIT_SET(POWER_MNG_CTRL_REG, BIT11);
38591+ /* Wait for int */
38592+ __asm__ __volatile__("mcr p15, 0, r0, c7, c0, 4");
38593+
38594+ /* Enabled int */
38595+ __asm__ __volatile__("msr cpsr_c, %0"
38596+ :
38597+ : "r" (old)
38598+ : "memory");
38599+}
38600+
38601+
38602+
38603+/*******************************************************************************
38604+* mvCtrlPwrSaveOff - Go out of power save mode
38605+*
38606+* DESCRIPTION:
38607+*
38608+* INPUT:
38609+*
38610+* OUTPUT:
38611+*
38612+* RETURN:
38613+*******************************************************************************/
38614+MV_VOID mvCtrlPwrSaveOff(MV_VOID)
38615+{
38616+ unsigned long old,temp;
38617+ /* Disable int */
38618+ __asm__ __volatile__("mrs %0, cpsr\n"
38619+ "orr %1, %0, #0xc0\n"
38620+ "msr cpsr_c, %1"
38621+ : "=r" (old), "=r" (temp)
38622+ :
38623+ : "memory");
38624+
38625+ /* Set SoC in power save */
38626+ MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, BIT11);
38627+ /* Wait for int */
38628+ __asm__ __volatile__("mcr p15, 0, r0, c7, c0, 4");
38629+
38630+ /* Enabled int */
38631+ __asm__ __volatile__("msr cpsr_c, %0"
38632+ :
38633+ : "r" (old)
38634+ : "memory");
38635+}
38636+
38637+/*******************************************************************************
38638+* mvCtrlPwrClckSet - Set Power State for specific Unit
38639+*
38640+* DESCRIPTION:
38641+*
38642+* INPUT:
38643+*
38644+* OUTPUT:
38645+*
38646+* RETURN:
38647+*******************************************************************************/
38648+MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)
38649+{
38650+ switch (unitId)
38651+ {
38652+#if defined(MV_INCLUDE_PEX)
38653+ case PEX_UNIT_ID:
38654+ if (enable == MV_FALSE)
38655+ {
38656+ MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
38657+ }
38658+ else
38659+ {
38660+ MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
38661+ }
38662+ break;
38663+#endif
38664+#if defined(MV_INCLUDE_GIG_ETH)
38665+ case ETH_GIG_UNIT_ID:
38666+ if (enable == MV_FALSE)
38667+ {
38668+ MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
38669+ }
38670+ else
38671+ {
38672+ MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
38673+ }
38674+ break;
38675+#endif
38676+#if defined(MV_INCLUDE_INTEG_SATA)
38677+ case SATA_UNIT_ID:
38678+ if (enable == MV_FALSE)
38679+ {
38680+ MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));
38681+ }
38682+ else
38683+ {
38684+ MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));
38685+ }
38686+ break;
38687+#endif
38688+#if defined(MV_INCLUDE_CESA)
38689+ case CESA_UNIT_ID:
38690+ if (enable == MV_FALSE)
38691+ {
38692+ MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);
38693+ }
38694+ else
38695+ {
38696+ MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);
38697+ }
38698+ break;
38699+#endif
38700+#if defined(MV_INCLUDE_USB)
38701+ case USB_UNIT_ID:
38702+ if (enable == MV_FALSE)
38703+ {
38704+ MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);
38705+ }
38706+ else
38707+ {
38708+ MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);
38709+ }
38710+ break;
38711+#endif
38712+#if defined(MV_INCLUDE_AUDIO)
38713+ case AUDIO_UNIT_ID:
38714+ if (enable == MV_FALSE)
38715+ {
38716+ MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);
38717+ }
38718+ else
38719+ {
38720+ MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);
38721+ }
38722+ break;
38723+#endif
38724+#if defined(MV_INCLUDE_TS)
38725+ case TS_UNIT_ID:
38726+ if (enable == MV_FALSE)
38727+ {
38728+ MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);
38729+ }
38730+ else
38731+ {
38732+ MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);
38733+ }
38734+ break;
38735+#endif
38736+#if defined(MV_INCLUDE_SDIO)
38737+ case SDIO_UNIT_ID:
38738+ if (enable == MV_FALSE)
38739+ {
38740+ MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
38741+ }
38742+ else
38743+ {
38744+ MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
38745+ }
38746+ break;
38747+#endif
38748+#if defined(MV_INCLUDE_TDM)
38749+ case TDM_UNIT_ID:
38750+ if (enable == MV_FALSE)
38751+ {
38752+ MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);
38753+ }
38754+ else
38755+ {
38756+ MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);
38757+ }
38758+ break;
38759+#endif
38760+
38761+ default:
38762+
38763+ break;
38764+
38765+ }
38766+}
38767+
38768+/*******************************************************************************
38769+* mvCtrlPwrClckGet - Get Power State of specific Unit
38770+*
38771+* DESCRIPTION:
38772+*
38773+* INPUT:
38774+*
38775+* OUTPUT:
38776+*
38777+* RETURN:
38778+******************************************************************************/
38779+MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index)
38780+{
38781+ MV_U32 reg = MV_REG_READ(POWER_MNG_CTRL_REG);
38782+ MV_BOOL state = MV_TRUE;
38783+
38784+ switch (unitId)
38785+ {
38786+#if defined(MV_INCLUDE_PEX)
38787+ case PEX_UNIT_ID:
38788+ if ((reg & PMC_PEXSTOPCLOCK_MASK) == PMC_PEXSTOPCLOCK_STOP)
38789+ {
38790+ state = MV_FALSE;
38791+ }
38792+ else state = MV_TRUE;
38793+
38794+ break;
38795+#endif
38796+#if defined(MV_INCLUDE_GIG_ETH)
38797+ case ETH_GIG_UNIT_ID:
38798+ if ((reg & PMC_GESTOPCLOCK_MASK(index)) == PMC_GESTOPCLOCK_STOP(index))
38799+ {
38800+ state = MV_FALSE;
38801+ }
38802+ else state = MV_TRUE;
38803+ break;
38804+#endif
38805+#if defined(MV_INCLUDE_SATA)
38806+ case SATA_UNIT_ID:
38807+ if ((reg & PMC_SATASTOPCLOCK_MASK(index)) == PMC_SATASTOPCLOCK_STOP(index))
38808+ {
38809+ state = MV_FALSE;
38810+ }
38811+ else state = MV_TRUE;
38812+ break;
38813+#endif
38814+#if defined(MV_INCLUDE_CESA)
38815+ case CESA_UNIT_ID:
38816+ if ((reg & PMC_SESTOPCLOCK_MASK) == PMC_SESTOPCLOCK_STOP)
38817+ {
38818+ state = MV_FALSE;
38819+ }
38820+ else state = MV_TRUE;
38821+ break;
38822+#endif
38823+#if defined(MV_INCLUDE_USB)
38824+ case USB_UNIT_ID:
38825+ if ((reg & PMC_USBSTOPCLOCK_MASK) == PMC_USBSTOPCLOCK_STOP)
38826+ {
38827+ state = MV_FALSE;
38828+ }
38829+ else state = MV_TRUE;
38830+ break;
38831+#endif
38832+#if defined(MV_INCLUDE_AUDIO)
38833+ case AUDIO_UNIT_ID:
38834+ if ((reg & PMC_AUDIOSTOPCLOCK_MASK) == PMC_AUDIOSTOPCLOCK_STOP)
38835+ {
38836+ state = MV_FALSE;
38837+ }
38838+ else state = MV_TRUE;
38839+ break;
38840+#endif
38841+#if defined(MV_INCLUDE_TS)
38842+ case TS_UNIT_ID:
38843+ if ((reg & PMC_TSSTOPCLOCK_MASK) == PMC_TSSTOPCLOCK_STOP)
38844+ {
38845+ state = MV_FALSE;
38846+ }
38847+ else state = MV_TRUE;
38848+ break;
38849+#endif
38850+#if defined(MV_INCLUDE_SDIO)
38851+ case SDIO_UNIT_ID:
38852+ if ((reg & PMC_SDIOSTOPCLOCK_MASK)== PMC_SDIOSTOPCLOCK_STOP)
38853+ {
38854+ state = MV_FALSE;
38855+ }
38856+ else state = MV_TRUE;
38857+ break;
38858+#endif
38859+#if defined(MV_INCLUDE_TDM)
38860+ case TDM_UNIT_ID:
38861+ if ((reg & PMC_TDMSTOPCLOCK_MASK) == PMC_TDMSTOPCLOCK_STOP)
38862+ {
38863+ state = MV_FALSE;
38864+ }
38865+ else state = MV_TRUE;
38866+ break;
38867+#endif
38868+
38869+ default:
38870+ state = MV_TRUE;
38871+ break;
38872+ }
38873+
38874+
38875+ return state;
38876+}
38877+/*******************************************************************************
38878+* mvCtrlPwrMemSet - Set Power State for memory on specific Unit
38879+*
38880+* DESCRIPTION:
38881+*
38882+* INPUT:
38883+*
38884+* OUTPUT:
38885+*
38886+* RETURN:
38887+*******************************************************************************/
38888+MV_VOID mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)
38889+{
38890+ switch (unitId)
38891+ {
38892+#if defined(MV_INCLUDE_PEX)
38893+ case PEX_UNIT_ID:
38894+ if (enable == MV_FALSE)
38895+ {
38896+ MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);
38897+ }
38898+ else
38899+ {
38900+ MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);
38901+ }
38902+ break;
38903+#endif
38904+#if defined(MV_INCLUDE_GIG_ETH)
38905+ case ETH_GIG_UNIT_ID:
38906+ if (enable == MV_FALSE)
38907+ {
38908+ MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));
38909+ }
38910+ else
38911+ {
38912+ MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));
38913+ }
38914+ break;
38915+#endif
38916+#if defined(MV_INCLUDE_INTEG_SATA)
38917+ case SATA_UNIT_ID:
38918+ if (enable == MV_FALSE)
38919+ {
38920+ MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));
38921+ }
38922+ else
38923+ {
38924+ MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));
38925+ }
38926+ break;
38927+#endif
38928+#if defined(MV_INCLUDE_CESA)
38929+ case CESA_UNIT_ID:
38930+ if (enable == MV_FALSE)
38931+ {
38932+ MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);
38933+ }
38934+ else
38935+ {
38936+ MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);
38937+ }
38938+ break;
38939+#endif
38940+#if defined(MV_INCLUDE_USB)
38941+ case USB_UNIT_ID:
38942+ if (enable == MV_FALSE)
38943+ {
38944+ MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);
38945+ }
38946+ else
38947+ {
38948+ MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);
38949+ }
38950+ break;
38951+#endif
38952+#if defined(MV_INCLUDE_AUDIO)
38953+ case AUDIO_UNIT_ID:
38954+ if (enable == MV_FALSE)
38955+ {
38956+ MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);
38957+ }
38958+ else
38959+ {
38960+ MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);
38961+ }
38962+ break;
38963+#endif
38964+#if defined(MV_INCLUDE_XOR)
38965+ case XOR_UNIT_ID:
38966+ if (enable == MV_FALSE)
38967+ {
38968+ MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));
38969+ }
38970+ else
38971+ {
38972+ MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));
38973+ }
38974+ break;
38975+#endif
38976+ default:
38977+
38978+ break;
38979+
38980+ }
38981+}
38982+
38983+/*******************************************************************************
38984+* mvCtrlPwrMemGet - Get Power State of memory on specific Unit
38985+*
38986+* DESCRIPTION:
38987+*
38988+* INPUT:
38989+*
38990+* OUTPUT:
38991+*
38992+* RETURN:
38993+******************************************************************************/
38994+MV_BOOL mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index)
38995+{
38996+ MV_U32 reg = MV_REG_READ(POWER_MNG_MEM_CTRL_REG);
38997+ MV_BOOL state = MV_TRUE;
38998+
38999+ switch (unitId)
39000+ {
39001+#if defined(MV_INCLUDE_PEX)
39002+ case PEX_UNIT_ID:
39003+ if ((reg & PMC_PEXSTOPMEM_MASK) == PMC_PEXSTOPMEM_STOP)
39004+ {
39005+ state = MV_FALSE;
39006+ }
39007+ else state = MV_TRUE;
39008+
39009+ break;
39010+#endif
39011+#if defined(MV_INCLUDE_GIG_ETH)
39012+ case ETH_GIG_UNIT_ID:
39013+ if ((reg & PMC_GESTOPMEM_MASK(index)) == PMC_GESTOPMEM_STOP(index))
39014+ {
39015+ state = MV_FALSE;
39016+ }
39017+ else state = MV_TRUE;
39018+ break;
39019+#endif
39020+#if defined(MV_INCLUDE_SATA)
39021+ case SATA_UNIT_ID:
39022+ if ((reg & PMC_SATASTOPMEM_MASK(index)) == PMC_SATASTOPMEM_STOP(index))
39023+ {
39024+ state = MV_FALSE;
39025+ }
39026+ else state = MV_TRUE;
39027+ break;
39028+#endif
39029+#if defined(MV_INCLUDE_CESA)
39030+ case CESA_UNIT_ID:
39031+ if ((reg & PMC_SESTOPMEM_MASK) == PMC_SESTOPMEM_STOP)
39032+ {
39033+ state = MV_FALSE;
39034+ }
39035+ else state = MV_TRUE;
39036+ break;
39037+#endif
39038+#if defined(MV_INCLUDE_USB)
39039+ case USB_UNIT_ID:
39040+ if ((reg & PMC_USBSTOPMEM_MASK) == PMC_USBSTOPMEM_STOP)
39041+ {
39042+ state = MV_FALSE;
39043+ }
39044+ else state = MV_TRUE;
39045+ break;
39046+#endif
39047+#if defined(MV_INCLUDE_AUDIO)
39048+ case AUDIO_UNIT_ID:
39049+ if ((reg & PMC_AUDIOSTOPMEM_MASK) == PMC_AUDIOSTOPMEM_STOP)
39050+ {
39051+ state = MV_FALSE;
39052+ }
39053+ else state = MV_TRUE;
39054+ break;
39055+#endif
39056+#if defined(MV_INCLUDE_XOR)
39057+ case XOR_UNIT_ID:
39058+ if ((reg & PMC_XORSTOPMEM_MASK(index)) == PMC_XORSTOPMEM_STOP(index))
39059+ {
39060+ state = MV_FALSE;
39061+ }
39062+ else state = MV_TRUE;
39063+ break;
39064+#endif
39065+
39066+ default:
39067+ state = MV_TRUE;
39068+ break;
39069+ }
39070+
39071+
39072+ return state;
39073+}
39074+#else
39075+MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable) {return;}
39076+MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index) {return MV_TRUE;}
39077+#endif /* #if defined(MV_INCLUDE_CLK_PWR_CNTRL) */
39078+
39079+
39080+/*******************************************************************************
39081+* mvMPPConfigToSPI - Change MPP[3:0] configuration to SPI mode
39082+*
39083+* DESCRIPTION:
39084+*
39085+* INPUT:
39086+*
39087+* OUTPUT:
39088+*
39089+* RETURN:
39090+******************************************************************************/
39091+MV_VOID mvMPPConfigToSPI(MV_VOID)
39092+{
39093+ MV_U32 mppVal = 0;
39094+ MV_U32 bootVal = 0;
39095+
39096+ if(!mvCtrlIsBootFromSPIUseNAND())
39097+ return;
39098+ mppVal = 0x00002220; /* Set MPP [3:1] to SPI mode */
39099+ bootVal = MV_REG_READ(mvCtrlMppRegGet(0));
39100+ bootVal &= 0xffff000f;
39101+ mppVal |= bootVal;
39102+
39103+ MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);
39104+}
39105+
39106+
39107+/*******************************************************************************
39108+* mvMPPConfigToDefault - Change MPP[7:0] configuration to default configuration
39109+*
39110+* DESCRIPTION:
39111+*
39112+* INPUT:
39113+*
39114+* OUTPUT:
39115+*
39116+* RETURN:
39117+******************************************************************************/
39118+MV_VOID mvMPPConfigToDefault(MV_VOID)
39119+{
39120+ MV_U32 mppVal = 0;
39121+ MV_U32 bootVal = 0;
39122+
39123+ if(!mvCtrlIsBootFromSPIUseNAND())
39124+ return;
39125+ mppVal = mvBoardMppGet(0);
39126+ bootVal = MV_REG_READ(mvCtrlMppRegGet(0));
39127+ mppVal &= ~0xffff000f;
39128+ bootVal &= 0xffff000f;
39129+ mppVal |= bootVal;
39130+
39131+ MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);
39132+}
39133+
39134+
39135diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h
39136new file mode 100644
39137index 0000000..0f8d2b4
39138--- /dev/null
39139+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h
39140@@ -0,0 +1,185 @@
39141+/*******************************************************************************
39142+Copyright (C) Marvell International Ltd. and its affiliates
39143+
39144+This software file (the "File") is owned and distributed by Marvell
39145+International Ltd. and/or its affiliates ("Marvell") under the following
39146+alternative licensing terms. Once you have made an election to distribute the
39147+File under one of the following license alternatives, please (i) delete this
39148+introductory statement regarding license alternatives, (ii) delete the two
39149+license alternatives that you have not elected to use and (iii) preserve the
39150+Marvell copyright notice above.
39151+
39152+********************************************************************************
39153+Marvell Commercial License Option
39154+
39155+If you received this File from Marvell and you have entered into a commercial
39156+license agreement (a "Commercial License") with Marvell, the File is licensed
39157+to you under the terms of the applicable Commercial License.
39158+
39159+********************************************************************************
39160+Marvell GPL License Option
39161+
39162+If you received this File from Marvell, you may opt to use, redistribute and/or
39163+modify this File in accordance with the terms and conditions of the General
39164+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
39165+available along with the File in the license.txt file or by writing to the Free
39166+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
39167+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
39168+
39169+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
39170+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
39171+DISCLAIMED. The GPL License provides additional details about this warranty
39172+disclaimer.
39173+********************************************************************************
39174+Marvell BSD License Option
39175+
39176+If you received this File from Marvell, you may opt to use, redistribute and/or
39177+modify this File under the following licensing terms.
39178+Redistribution and use in source and binary forms, with or without modification,
39179+are permitted provided that the following conditions are met:
39180+
39181+ * Redistributions of source code must retain the above copyright notice,
39182+ this list of conditions and the following disclaimer.
39183+
39184+ * Redistributions in binary form must reproduce the above copyright
39185+ notice, this list of conditions and the following disclaimer in the
39186+ documentation and/or other materials provided with the distribution.
39187+
39188+ * Neither the name of Marvell nor the names of its contributors may be
39189+ used to endorse or promote products derived from this software without
39190+ specific prior written permission.
39191+
39192+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
39193+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39194+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39195+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
39196+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39197+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39198+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
39199+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39200+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39201+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39202+
39203+*******************************************************************************/
39204+
39205+
39206+#ifndef __INCmvCtrlEnvLibh
39207+#define __INCmvCtrlEnvLibh
39208+
39209+/* includes */
39210+#include "mvSysHwConfig.h"
39211+#include "mvCommon.h"
39212+#include "mvTypes.h"
39213+#include "mvOs.h"
39214+#include "boardEnv/mvBoardEnvLib.h"
39215+#include "ctrlEnv/mvCtrlEnvSpec.h"
39216+#include "ctrlEnv/mvCtrlEnvRegs.h"
39217+#include "ctrlEnv/mvCtrlEnvAddrDec.h"
39218+
39219+
39220+/* typedefs */
39221+
39222+/* This enumerator describes the possible HW cache coherency policies the */
39223+/* controllers supports. */
39224+typedef enum _mvCachePolicy
39225+{
39226+ NO_COHERENCY, /* No HW cache coherency support */
39227+ WT_COHERENCY, /* HW cache coherency supported in Write Through policy */
39228+ WB_COHERENCY /* HW cache coherency supported in Write Back policy */
39229+}MV_CACHE_POLICY;
39230+
39231+
39232+/* The swapping is referred to a 64-bit words (as this is the controller */
39233+/* internal data path width). This enumerator describes the possible */
39234+/* data swap types. Below is an example of the data 0x0011223344556677 */
39235+typedef enum _mvSwapType
39236+{
39237+ MV_BYTE_SWAP, /* Byte Swap 77 66 55 44 33 22 11 00 */
39238+ MV_NO_SWAP, /* No swapping 00 11 22 33 44 55 66 77 */
39239+ MV_BYTE_WORD_SWAP, /* Both byte and word swap 33 22 11 00 77 66 55 44 */
39240+ MV_WORD_SWAP, /* Word swap 44 55 66 77 00 11 22 33 */
39241+ SWAP_TYPE_MAX /* Delimiter for this enumerator */
39242+}MV_SWAP_TYPE;
39243+
39244+/* This structure describes access rights for Access protection windows */
39245+/* that can be found in IDMA, XOR, Ethernet and MPSC units. */
39246+/* Note that the permission enumerator coresponds to its register format. */
39247+/* For example, Read only premission is presented as "1" in register field. */
39248+typedef enum _mvAccessRights
39249+{
39250+ NO_ACCESS_ALLOWED = 0, /* No access allowed */
39251+ READ_ONLY = 1, /* Read only permission */
39252+ ACC_RESERVED = 2, /* Reserved access right */
39253+ FULL_ACCESS = 3, /* Read and Write permission */
39254+ MAX_ACC_RIGHTS
39255+}MV_ACCESS_RIGHTS;
39256+
39257+
39258+/* mcspLib.h API list */
39259+
39260+MV_STATUS mvCtrlEnvInit(MV_VOID);
39261+MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup);
39262+
39263+#if defined(MV_INCLUDE_PEX)
39264+MV_U32 mvCtrlPexMaxIfGet(MV_VOID);
39265+#else
39266+#define mvCtrlPexMaxIfGet() (0)
39267+#endif
39268+
39269+#define mvCtrlPciIfMaxIfGet() (0)
39270+
39271+#if defined(MV_INCLUDE_GIG_ETH)
39272+MV_U32 mvCtrlEthMaxPortGet(MV_VOID);
39273+#endif
39274+#if defined(MV_INCLUDE_XOR)
39275+MV_U32 mvCtrlXorMaxChanGet(MV_VOID);
39276+#endif
39277+#if defined(MV_INCLUDE_USB)
39278+MV_U32 mvCtrlUsbMaxGet(MV_VOID);
39279+#endif
39280+#if defined(MV_INCLUDE_NAND)
39281+MV_U32 mvCtrlNandSupport(MV_VOID);
39282+#endif
39283+#if defined(MV_INCLUDE_SDIO)
39284+MV_U32 mvCtrlSdioSupport(MV_VOID);
39285+#endif
39286+#if defined(MV_INCLUDE_TS)
39287+MV_U32 mvCtrlTsSupport(MV_VOID);
39288+#endif
39289+#if defined(MV_INCLUDE_AUDIO)
39290+MV_U32 mvCtrlAudioSupport(MV_VOID);
39291+#endif
39292+#if defined(MV_INCLUDE_TDM)
39293+MV_U32 mvCtrlTdmSupport(MV_VOID);
39294+#endif
39295+
39296+MV_U16 mvCtrlModelGet(MV_VOID);
39297+MV_U8 mvCtrlRevGet(MV_VOID);
39298+MV_STATUS mvCtrlNameGet(char *pNameBuff);
39299+MV_U32 mvCtrlModelRevGet(MV_VOID);
39300+MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff);
39301+MV_VOID mvCtrlAddrDecShow(MV_VOID);
39302+const MV_8* mvCtrlTargetNameGet(MV_TARGET target);
39303+MV_U32 ctrlSizeToReg(MV_U32 size, MV_U32 alignment);
39304+MV_U32 ctrlRegToSize(MV_U32 regSize, MV_U32 alignment);
39305+MV_U32 ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment);
39306+MV_U32 mvCtrlSysRstLengthCounterGet(MV_VOID);
39307+MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);
39308+MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);
39309+
39310+MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);
39311+MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index);
39312+MV_VOID mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);
39313+MV_BOOL mvCtrlIsBootFromSPI(MV_VOID);
39314+MV_BOOL mvCtrlIsBootFromSPIUseNAND(MV_VOID);
39315+MV_BOOL mvCtrlIsBootFromNAND(MV_VOID);
39316+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
39317+MV_VOID mvCtrlPwrSaveOn(MV_VOID);
39318+MV_VOID mvCtrlPwrSaveOff(MV_VOID);
39319+#endif
39320+MV_BOOL mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index);
39321+MV_VOID mvMPPConfigToSPI(MV_VOID);
39322+MV_VOID mvMPPConfigToDefault(MV_VOID);
39323+
39324+
39325+#endif /* __INCmvCtrlEnvLibh */
39326diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h
39327new file mode 100644
39328index 0000000..b889e24
39329--- /dev/null
39330+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h
39331@@ -0,0 +1,419 @@
39332+/*******************************************************************************
39333+Copyright (C) Marvell International Ltd. and its affiliates
39334+
39335+This software file (the "File") is owned and distributed by Marvell
39336+International Ltd. and/or its affiliates ("Marvell") under the following
39337+alternative licensing terms. Once you have made an election to distribute the
39338+File under one of the following license alternatives, please (i) delete this
39339+introductory statement regarding license alternatives, (ii) delete the two
39340+license alternatives that you have not elected to use and (iii) preserve the
39341+Marvell copyright notice above.
39342+
39343+********************************************************************************
39344+Marvell Commercial License Option
39345+
39346+If you received this File from Marvell and you have entered into a commercial
39347+license agreement (a "Commercial License") with Marvell, the File is licensed
39348+to you under the terms of the applicable Commercial License.
39349+
39350+********************************************************************************
39351+Marvell GPL License Option
39352+
39353+If you received this File from Marvell, you may opt to use, redistribute and/or
39354+modify this File in accordance with the terms and conditions of the General
39355+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
39356+available along with the File in the license.txt file or by writing to the Free
39357+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
39358+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
39359+
39360+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
39361+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
39362+DISCLAIMED. The GPL License provides additional details about this warranty
39363+disclaimer.
39364+********************************************************************************
39365+Marvell BSD License Option
39366+
39367+If you received this File from Marvell, you may opt to use, redistribute and/or
39368+modify this File under the following licensing terms.
39369+Redistribution and use in source and binary forms, with or without modification,
39370+are permitted provided that the following conditions are met:
39371+
39372+ * Redistributions of source code must retain the above copyright notice,
39373+ this list of conditions and the following disclaimer.
39374+
39375+ * Redistributions in binary form must reproduce the above copyright
39376+ notice, this list of conditions and the following disclaimer in the
39377+ documentation and/or other materials provided with the distribution.
39378+
39379+ * Neither the name of Marvell nor the names of its contributors may be
39380+ used to endorse or promote products derived from this software without
39381+ specific prior written permission.
39382+
39383+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
39384+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39385+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39386+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
39387+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39388+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39389+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
39390+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39391+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39392+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39393+
39394+*******************************************************************************/
39395+
39396+#ifndef __INCmvCtrlEnvRegsh
39397+#define __INCmvCtrlEnvRegsh
39398+
39399+#ifdef __cplusplus
39400+extern "C" {
39401+#endif /* __cplusplus */
39402+
39403+/* CV Support */
39404+#define PEX0_MEM0 PEX0_MEM
39405+#define PCI0_MEM0 PEX0_MEM
39406+
39407+/* Controller revision info */
39408+#define PCI_CLASS_CODE_AND_REVISION_ID 0x008
39409+#define PCCRIR_REVID_OFFS 0 /* Revision ID */
39410+#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS)
39411+
39412+/* Controler environment registers offsets */
39413+
39414+/* Power Managment Control */
39415+#define POWER_MNG_MEM_CTRL_REG 0x20118
39416+
39417+#define PMC_GESTOPMEM_OFFS(port) ((port)? 13 : 0)
39418+#define PMC_GESTOPMEM_MASK(port) (1 << PMC_GESTOPMEM_OFFS(port))
39419+#define PMC_GESTOPMEM_EN(port) (0 << PMC_GESTOPMEM_OFFS(port))
39420+#define PMC_GESTOPMEM_STOP(port) (1 << PMC_GESTOPMEM_OFFS(port))
39421+
39422+#define PMC_PEXSTOPMEM_OFFS 1
39423+#define PMC_PEXSTOPMEM_MASK (1 << PMC_PEXSTOPMEM_OFFS)
39424+#define PMC_PEXSTOPMEM_EN (0 << PMC_PEXSTOPMEM_OFFS)
39425+#define PMC_PEXSTOPMEM_STOP (1 << PMC_PEXSTOPMEM_OFFS)
39426+
39427+#define PMC_USBSTOPMEM_OFFS 2
39428+#define PMC_USBSTOPMEM_MASK (1 << PMC_USBSTOPMEM_OFFS)
39429+#define PMC_USBSTOPMEM_EN (0 << PMC_USBSTOPMEM_OFFS)
39430+#define PMC_USBSTOPMEM_STOP (1 << PMC_USBSTOPMEM_OFFS)
39431+
39432+#define PMC_DUNITSTOPMEM_OFFS 3
39433+#define PMC_DUNITSTOPMEM_MASK (1 << PMC_DUNITSTOPMEM_OFFS)
39434+#define PMC_DUNITSTOPMEM_EN (0 << PMC_DUNITSTOPMEM_OFFS)
39435+#define PMC_DUNITSTOPMEM_STOP (1 << PMC_DUNITSTOPMEM_OFFS)
39436+
39437+#define PMC_RUNITSTOPMEM_OFFS 4
39438+#define PMC_RUNITSTOPMEM_MASK (1 << PMC_RUNITSTOPMEM_OFFS)
39439+#define PMC_RUNITSTOPMEM_EN (0 << PMC_RUNITSTOPMEM_OFFS)
39440+#define PMC_RUNITSTOPMEM_STOP (1 << PMC_RUNITSTOPMEM_OFFS)
39441+
39442+#define PMC_XORSTOPMEM_OFFS(port) (5+(port*2))
39443+#define PMC_XORSTOPMEM_MASK(port) (1 << PMC_XORSTOPMEM_OFFS(port))
39444+#define PMC_XORSTOPMEM_EN(port) (0 << PMC_XORSTOPMEM_OFFS(port))
39445+#define PMC_XORSTOPMEM_STOP(port) (1 << PMC_XORSTOPMEM_OFFS(port))
39446+
39447+#define PMC_SATASTOPMEM_OFFS(port) (6+(port*5))
39448+#define PMC_SATASTOPMEM_MASK(port) (1 << PMC_SATASTOPMEM_OFFS(port))
39449+#define PMC_SATASTOPMEM_EN(port) (0 << PMC_SATASTOPMEM_OFFS(port))
39450+#define PMC_SATASTOPMEM_STOP(port) (1 << PMC_SATASTOPMEM_OFFS(port))
39451+
39452+#define PMC_SESTOPMEM_OFFS 8
39453+#define PMC_SESTOPMEM_MASK (1 << PMC_SESTOPMEM_OFFS)
39454+#define PMC_SESTOPMEM_EN (0 << PMC_SESTOPMEM_OFFS)
39455+#define PMC_SESTOPMEM_STOP (1 << PMC_SESTOPMEM_OFFS)
39456+
39457+#define PMC_AUDIOSTOPMEM_OFFS 9
39458+#define PMC_AUDIOSTOPMEM_MASK (1 << PMC_AUDIOSTOPMEM_OFFS)
39459+#define PMC_AUDIOSTOPMEM_EN (0 << PMC_AUDIOSTOPMEM_OFFS)
39460+#define PMC_AUDIOSTOPMEM_STOP (1 << PMC_AUDIOSTOPMEM_OFFS)
39461+
39462+#define POWER_MNG_CTRL_REG 0x2011C
39463+
39464+#define PMC_GESTOPCLOCK_OFFS(port) ((port)? 19 : 0)
39465+#define PMC_GESTOPCLOCK_MASK(port) (1 << PMC_GESTOPCLOCK_OFFS(port))
39466+#define PMC_GESTOPCLOCK_EN(port) (1 << PMC_GESTOPCLOCK_OFFS(port))
39467+#define PMC_GESTOPCLOCK_STOP(port) (0 << PMC_GESTOPCLOCK_OFFS(port))
39468+
39469+#define PMC_PEXPHYSTOPCLOCK_OFFS 1
39470+#define PMC_PEXPHYSTOPCLOCK_MASK (1 << PMC_PEXPHYSTOPCLOCK_OFFS)
39471+#define PMC_PEXPHYSTOPCLOCK_EN (1 << PMC_PEXPHYSTOPCLOCK_OFFS)
39472+#define PMC_PEXPHYSTOPCLOCK_STOP (0 << PMC_PEXPHYSTOPCLOCK_OFFS)
39473+
39474+#define PMC_PEXSTOPCLOCK_OFFS 2
39475+#define PMC_PEXSTOPCLOCK_MASK (1 << PMC_PEXSTOPCLOCK_OFFS)
39476+#define PMC_PEXSTOPCLOCK_EN (1 << PMC_PEXSTOPCLOCK_OFFS)
39477+#define PMC_PEXSTOPCLOCK_STOP (0 << PMC_PEXSTOPCLOCK_OFFS)
39478+
39479+#define PMC_USBSTOPCLOCK_OFFS 3
39480+#define PMC_USBSTOPCLOCK_MASK (1 << PMC_USBSTOPCLOCK_OFFS)
39481+#define PMC_USBSTOPCLOCK_EN (1 << PMC_USBSTOPCLOCK_OFFS)
39482+#define PMC_USBSTOPCLOCK_STOP (0 << PMC_USBSTOPCLOCK_OFFS)
39483+
39484+#define PMC_SDIOSTOPCLOCK_OFFS 4
39485+#define PMC_SDIOSTOPCLOCK_MASK (1 << PMC_SDIOSTOPCLOCK_OFFS)
39486+#define PMC_SDIOSTOPCLOCK_EN (1 << PMC_SDIOSTOPCLOCK_OFFS)
39487+#define PMC_SDIOSTOPCLOCK_STOP (0 << PMC_SDIOSTOPCLOCK_OFFS)
39488+
39489+#define PMC_TSSTOPCLOCK_OFFS 5
39490+#define PMC_TSSTOPCLOCK_MASK (1 << PMC_TSSTOPCLOCK_OFFS)
39491+#define PMC_TSSTOPCLOCK_EN (1 << PMC_TSSTOPCLOCK_OFFS)
39492+#define PMC_TSSTOPCLOCK_STOP (0 << PMC_TSSTOPCLOCK_OFFS)
39493+
39494+#define PMC_AUDIOSTOPCLOCK_OFFS 9
39495+#define PMC_AUDIOSTOPCLOCK_MASK (1 << PMC_AUDIOSTOPCLOCK_OFFS)
39496+#define PMC_AUDIOSTOPCLOCK_EN (1 << PMC_AUDIOSTOPCLOCK_OFFS)
39497+#define PMC_AUDIOSTOPCLOCK_STOP (0 << PMC_AUDIOSTOPCLOCK_OFFS)
39498+
39499+#define PMC_POWERSAVE_OFFS 11
39500+#define PMC_POWERSAVE_MASK (1 << PMC_POWERSAVE_OFFS)
39501+#define PMC_POWERSAVE_EN (1 << PMC_POWERSAVE_OFFS)
39502+#define PMC_POWERSAVE_STOP (0 << PMC_POWERSAVE_OFFS)
39503+
39504+
39505+
39506+
39507+#define PMC_SATASTOPCLOCK_OFFS(port) (14+(port))
39508+#define PMC_SATASTOPCLOCK_MASK(port) (1 << PMC_SATASTOPCLOCK_OFFS(port))
39509+#define PMC_SATASTOPCLOCK_EN(port) (1 << PMC_SATASTOPCLOCK_OFFS(port))
39510+#define PMC_SATASTOPCLOCK_STOP(port) (0 << PMC_SATASTOPCLOCK_OFFS(port))
39511+
39512+#define PMC_SESTOPCLOCK_OFFS 17
39513+#define PMC_SESTOPCLOCK_MASK (1 << PMC_SESTOPCLOCK_OFFS)
39514+#define PMC_SESTOPCLOCK_EN (1 << PMC_SESTOPCLOCK_OFFS)
39515+#define PMC_SESTOPCLOCK_STOP (0 << PMC_SESTOPCLOCK_OFFS)
39516+
39517+#define PMC_TDMSTOPCLOCK_OFFS 20
39518+#define PMC_TDMSTOPCLOCK_MASK (1 << PMC_TDMSTOPCLOCK_OFFS)
39519+#define PMC_TDMSTOPCLOCK_EN (1 << PMC_TDMSTOPCLOCK_OFFS)
39520+#define PMC_TDMSTOPCLOCK_STOP (0 << PMC_TDMSTOPCLOCK_OFFS)
39521+
39522+
39523+/* Controler environment registers offsets */
39524+#define MPP_CONTROL_REG0 0x10000
39525+#define MPP_CONTROL_REG1 0x10004
39526+#define MPP_CONTROL_REG2 0x10008
39527+#define MPP_CONTROL_REG3 0x1000C
39528+#define MPP_CONTROL_REG4 0x10010
39529+#define MPP_CONTROL_REG5 0x10014
39530+#define MPP_CONTROL_REG6 0x10018
39531+#define MPP_SAMPLE_AT_RESET 0x10030
39532+#define CHIP_BOND_REG 0x10034
39533+#define SYSRST_LENGTH_COUNTER_REG 0x10050
39534+#define SLCR_COUNT_OFFS 0
39535+#define SLCR_COUNT_MASK (0x1FFFFFFF << SLCR_COUNT_OFFS)
39536+#define SLCR_CLR_OFFS 31
39537+#define SLCR_CLR_MASK (1 << SLCR_CLR_OFFS)
39538+#define PCKG_OPT_MASK 0x3
39539+#define MPP_OUTPUT_DRIVE_REG 0x100E0
39540+#define MPP_RGMII0_OUTPUT_DRIVE_OFFS 7
39541+#define MPP_3_3_RGMII0_OUTPUT_DRIVE (0x0 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)
39542+#define MPP_1_8_RGMII0_OUTPUT_DRIVE (0x1 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)
39543+#define MPP_RGMII1_OUTPUT_DRIVE_OFFS 15
39544+#define MPP_3_3_RGMII1_OUTPUT_DRIVE (0x0 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)
39545+#define MPP_1_8_RGMII1_OUTPUT_DRIVE (0x1 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)
39546+
39547+#define MSAR_BOOT_MODE_OFFS 12
39548+#define MSAR_BOOT_MODE_MASK (0x7 << MSAR_BOOT_MODE_OFFS)
39549+#define MSAR_BOOT_NAND_WITH_BOOTROM (0x5 << MSAR_BOOT_MODE_OFFS)
39550+#define MSAR_BOOT_SPI_WITH_BOOTROM (0x4 << MSAR_BOOT_MODE_OFFS)
39551+#define MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM (0x2 << MSAR_BOOT_MODE_OFFS)
39552+
39553+#define MSAR_BOOT_MODE_6180(X) (((X & 0x3000) >> 12) | \
39554+ ((X & 0x2) << 1))
39555+#define MSAR_BOOT_SPI_WITH_BOOTROM_6180 0x1
39556+#define MSAR_BOOT_NAND_WITH_BOOTROM_6180 0x5
39557+
39558+#define MSAR_TCLCK_OFFS 21
39559+#define MSAR_TCLCK_MASK (0x1 << MSAR_TCLCK_OFFS)
39560+#define MSAR_TCLCK_166 (0x1 << MSAR_TCLCK_OFFS)
39561+#define MSAR_TCLCK_200 (0x0 << MSAR_TCLCK_OFFS)
39562+
39563+
39564+#define MSAR_CPUCLCK_EXTRACT(X) (((X & 0x2) >> 1) | ((X & 0x400000) >> 21) | \
39565+ ((X & 0x18) >> 1))
39566+
39567+#define MSAR_CPUCLCK_OFFS_6180 2
39568+#define MSAR_CPUCLCK_MASK_6180 (0x7 << MSAR_CPUCLCK_OFFS_6180)
39569+
39570+#define MSAR_DDRCLCK_RTIO_OFFS 5
39571+#define MSAR_DDRCLCK_RTIO_MASK (0xF << MSAR_DDRCLCK_RTIO_OFFS)
39572+
39573+#define MSAR_L2CLCK_EXTRACT(X) (((X & 0x600) >> 9) | ((X & 0x80000) >> 17))
39574+
39575+#ifndef MV_ASMLANGUAGE
39576+/* CPU clock for 6281,6192 0->Resereved */
39577+#define MV_CPU_CLCK_TBL { 0, 0, 0, 0, \
39578+ 600000000, 0, 800000000, 1000000000, \
39579+ 0, 1200000000, 0, 0, \
39580+ 1500000000, 0, 0, 0}
39581+
39582+/* DDR clock RATIO for 6281,6192 {0,0}->Reserved */
39583+#define MV_DDR_CLCK_RTIO_TBL {\
39584+ {0, 0}, {0, 0}, {2, 1}, {0, 0}, \
39585+ {3, 1}, {0, 0}, {4, 1}, {9, 2}, \
39586+ {5, 1}, {6, 1}, {0, 0}, {0, 0}, \
39587+ {0, 0}, {0, 0}, {0, 0}, {0, 0} \
39588+}
39589+
39590+/* L2 clock RATIO for 6281,6192 {1,1}->Reserved */
39591+#define MV_L2_CLCK_RTIO_TBL {\
39592+ {0, 0}, {2, 1}, {0, 0}, {3, 1}, \
39593+ {0, 0}, {0, 0}, {0, 0}, {0, 0} \
39594+}
39595+
39596+/* 6180 have different clk reset sampling */
39597+/* ARM CPU, DDR, L2 clock for 6180 {0,0,0}->Reserved */
39598+#define MV_CPU6180_DDR_L2_CLCK_TBL { \
39599+ {0, 0, 0 },\
39600+ {0, 0, 0 },\
39601+ {0, 0, 0 },\
39602+ {0, 0, 0 },\
39603+ {0, 0, 0 },\
39604+ {600000000, 200000000, 300000000 },\
39605+ {800000000, 200000000, 400000000 },\
39606+ {0, 0, 0 }\
39607+}
39608+
39609+
39610+
39611+/* These macros help units to identify a target Mbus Arbiter group */
39612+#define MV_TARGET_IS_DRAM(target) \
39613+ ((target >= SDRAM_CS0) && (target <= SDRAM_CS3))
39614+
39615+#define MV_TARGET_IS_PEX0(target) \
39616+ ((target >= PEX0_MEM) && (target <= PEX0_IO))
39617+
39618+#define MV_TARGET_IS_PEX1(target) 0
39619+
39620+#define MV_TARGET_IS_PEX(target) (MV_TARGET_IS_PEX0(target) || MV_TARGET_IS_PEX1(target))
39621+
39622+#define MV_TARGET_IS_DEVICE(target) \
39623+ ((target >= DEVICE_CS0) && (target <= DEVICE_CS3))
39624+
39625+#define MV_PCI_DRAM_BAR_TO_DRAM_TARGET(bar) 0
39626+
39627+#define MV_TARGET_IS_AS_BOOT(target) ((target) == (sampleAtResetTargetArray[ \
39628+ (mvCtrlModelGet() == MV_6180_DEV_ID)? MSAR_BOOT_MODE_6180 \
39629+ (MV_REG_READ(MPP_SAMPLE_AT_RESET)):((MV_REG_READ(MPP_SAMPLE_AT_RESET)\
39630+ & MSAR_BOOT_MODE_MASK) >> MSAR_BOOT_MODE_OFFS)]))
39631+
39632+
39633+#define MV_CHANGE_BOOT_CS(target) (((target) == DEV_BOOCS)?\
39634+ sampleAtResetTargetArray[(mvCtrlModelGet() == MV_6180_DEV_ID)? \
39635+ MSAR_BOOT_MODE_6180(MV_REG_READ(MPP_SAMPLE_AT_RESET)): \
39636+ ((MV_REG_READ(MPP_SAMPLE_AT_RESET) & MSAR_BOOT_MODE_MASK)\
39637+ >> MSAR_BOOT_MODE_OFFS)]:(target))
39638+
39639+#define TCLK_TO_COUNTER_RATIO 1 /* counters running in Tclk */
39640+
39641+#define BOOT_TARGETS_NAME_ARRAY { \
39642+ TBL_TERM, \
39643+ TBL_TERM, \
39644+ BOOT_ROM_CS, \
39645+ TBL_TERM, \
39646+ BOOT_ROM_CS, \
39647+ BOOT_ROM_CS, \
39648+ TBL_TERM, \
39649+ TBL_TERM \
39650+}
39651+
39652+#define BOOT_TARGETS_NAME_ARRAY_6180 { \
39653+ TBL_TERM, \
39654+ BOOT_ROM_CS, \
39655+ TBL_TERM, \
39656+ TBL_TERM, \
39657+ TBL_TERM, \
39658+ BOOT_ROM_CS, \
39659+ TBL_TERM, \
39660+ TBL_TERM \
39661+}
39662+
39663+
39664+/* For old competability */
39665+#define DEVICE_CS0 NFLASH_CS
39666+#define DEVICE_CS1 SPI_CS
39667+#define DEVICE_CS2 BOOT_ROM_CS
39668+#define DEVICE_CS3 DEV_BOOCS
39669+#define MV_BOOTDEVICE_INDEX 0
39670+
39671+#define START_DEV_CS DEV_CS0
39672+#define DEV_TO_TARGET(dev) ((dev) + DEVICE_CS0)
39673+
39674+#define PCI_IF0_MEM0 PEX0_MEM
39675+#define PCI_IF0_IO PEX0_IO
39676+
39677+
39678+/* This enumerator defines the Marvell controller target ID */
39679+typedef enum _mvTargetId
39680+{
39681+ DRAM_TARGET_ID = 0 , /* Port 0 -> DRAM interface */
39682+ DEV_TARGET_ID = 1, /* Port 1 -> Nand/SPI */
39683+ PEX0_TARGET_ID = 4 , /* Port 4 -> PCI Express0 */
39684+ CRYPT_TARGET_ID = 3 , /* Port 3 --> Crypto Engine */
39685+ SAGE_TARGET_ID = 12 , /* Port 12 -> SAGE Unit */
39686+ MAX_TARGETS_ID
39687+}MV_TARGET_ID;
39688+
39689+
39690+/* This enumerator described the possible Controller paripheral targets. */
39691+/* Controller peripherals are designated memory/IO address spaces that the */
39692+/* controller can access. They are also refered as "targets" */
39693+typedef enum _mvTarget
39694+{
39695+ TBL_TERM = -1, /* none valid target, used as targets list terminator*/
39696+ SDRAM_CS0, /* SDRAM chip select 0 */
39697+ SDRAM_CS1, /* SDRAM chip select 1 */
39698+ SDRAM_CS2, /* SDRAM chip select 2 */
39699+ SDRAM_CS3, /* SDRAM chip select 3 */
39700+ PEX0_MEM, /* PCI Express 0 Memory */
39701+ PEX0_IO, /* PCI Express 0 IO */
39702+ INTER_REGS, /* Internal registers */
39703+ NFLASH_CS, /* NFLASH_CS */
39704+ SPI_CS, /* SPI_CS */
39705+ BOOT_ROM_CS, /* BOOT_ROM_CS */
39706+ DEV_BOOCS, /* DEV_BOOCS */
39707+ CRYPT_ENG, /* Crypto Engine */
39708+#ifdef MV_INCLUDE_SAGE
39709+ SAGE_UNIT, /* SAGE Unit */
39710+#endif
39711+ MAX_TARGETS
39712+
39713+}MV_TARGET;
39714+
39715+#define TARGETS_DEF_ARRAY { \
39716+ {0x0E, DRAM_TARGET_ID }, /* SDRAM_CS0 */ \
39717+ {0x0D, DRAM_TARGET_ID }, /* SDRAM_CS1 */ \
39718+ {0x0B, DRAM_TARGET_ID }, /* SDRAM_CS0 */ \
39719+ {0x07, DRAM_TARGET_ID }, /* SDRAM_CS1 */ \
39720+ {0xE8, PEX0_TARGET_ID }, /* PEX0_MEM */ \
39721+ {0xE0, PEX0_TARGET_ID }, /* PEX0_IO */ \
39722+ {0xFF, 0xFF }, /* INTER_REGS */ \
39723+ {0x2F, DEV_TARGET_ID }, /* NFLASH_CS */ \
39724+ {0x1E, DEV_TARGET_ID }, /* SPI_CS */ \
39725+ {0x1D, DEV_TARGET_ID }, /* BOOT_ROM_CS */ \
39726+ {0x1E, DEV_TARGET_ID }, /* DEV_BOOCS */ \
39727+ {0x01, CRYPT_TARGET_ID}, /* CRYPT_ENG */ \
39728+ {0x00, SAGE_TARGET_ID } \
39729+}
39730+
39731+
39732+#define TARGETS_NAME_ARRAY { \
39733+ "SDRAM_CS0", /* SDRAM_CS0 */ \
39734+ "SDRAM_CS1", /* SDRAM_CS1 */ \
39735+ "SDRAM_CS2", /* SDRAM_CS2 */ \
39736+ "SDRAM_CS3", /* SDRAM_CS3 */ \
39737+ "PEX0_MEM", /* PEX0_MEM */ \
39738+ "PEX0_IO", /* PEX0_IO */ \
39739+ "INTER_REGS", /* INTER_REGS */ \
39740+ "NFLASH_CS", /* NFLASH_CS */ \
39741+ "SPI_CS", /* SPI_CS */ \
39742+ "BOOT_ROM_CS", /* BOOT_ROM_CS */ \
39743+ "DEV_BOOTCS", /* DEV_BOOCS */ \
39744+ "CRYPT_ENG", /* CRYPT_ENG */ \
39745+ "SAGE_UNIT" /* SAGE_UNIT */ \
39746+}
39747+#endif /* MV_ASMLANGUAGE */
39748+
39749+
39750+#endif
39751diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h
39752new file mode 100644
39753index 0000000..12d2066
39754--- /dev/null
39755+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h
39756@@ -0,0 +1,257 @@
39757+/*******************************************************************************
39758+Copyright (C) Marvell International Ltd. and its affiliates
39759+
39760+This software file (the "File") is owned and distributed by Marvell
39761+International Ltd. and/or its affiliates ("Marvell") under the following
39762+alternative licensing terms. Once you have made an election to distribute the
39763+File under one of the following license alternatives, please (i) delete this
39764+introductory statement regarding license alternatives, (ii) delete the two
39765+license alternatives that you have not elected to use and (iii) preserve the
39766+Marvell copyright notice above.
39767+
39768+********************************************************************************
39769+Marvell Commercial License Option
39770+
39771+If you received this File from Marvell and you have entered into a commercial
39772+license agreement (a "Commercial License") with Marvell, the File is licensed
39773+to you under the terms of the applicable Commercial License.
39774+
39775+********************************************************************************
39776+Marvell GPL License Option
39777+
39778+If you received this File from Marvell, you may opt to use, redistribute and/or
39779+modify this File in accordance with the terms and conditions of the General
39780+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
39781+available along with the File in the license.txt file or by writing to the Free
39782+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
39783+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
39784+
39785+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
39786+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
39787+DISCLAIMED. The GPL License provides additional details about this warranty
39788+disclaimer.
39789+********************************************************************************
39790+Marvell BSD License Option
39791+
39792+If you received this File from Marvell, you may opt to use, redistribute and/or
39793+modify this File under the following licensing terms.
39794+Redistribution and use in source and binary forms, with or without modification,
39795+are permitted provided that the following conditions are met:
39796+
39797+ * Redistributions of source code must retain the above copyright notice,
39798+ this list of conditions and the following disclaimer.
39799+
39800+ * Redistributions in binary form must reproduce the above copyright
39801+ notice, this list of conditions and the following disclaimer in the
39802+ documentation and/or other materials provided with the distribution.
39803+
39804+ * Neither the name of Marvell nor the names of its contributors may be
39805+ used to endorse or promote products derived from this software without
39806+ specific prior written permission.
39807+
39808+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
39809+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39810+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39811+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
39812+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39813+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39814+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
39815+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39816+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39817+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39818+
39819+*******************************************************************************/
39820+
39821+#ifndef __INCmvCtrlEnvSpech
39822+#define __INCmvCtrlEnvSpech
39823+
39824+#include "mvDeviceId.h"
39825+#include "mvSysHwConfig.h"
39826+
39827+#ifdef __cplusplus
39828+extern "C" {
39829+#endif /* __cplusplus */
39830+
39831+#define MV_ARM_SOC
39832+#define SOC_NAME_PREFIX "MV88F"
39833+
39834+
39835+/* units base and port numbers */
39836+#ifdef MV_ASMLANGUAGE
39837+#define XOR_UNIT_BASE(unit) 0x60800
39838+#else
39839+#define MV_XOR_REG_BASE 0x60000
39840+#define XOR_UNIT_BASE(unit) ((unit)? 0x60900:0x60800)
39841+#endif
39842+
39843+#define TDM_REG_BASE 0xD0000
39844+#define USB_REG_BASE(dev) 0x50000
39845+#define AUDIO_REG_BASE 0xA0000
39846+#define SATA_REG_BASE 0x80000
39847+#define MV_CESA_REG_BASE 0x3D000
39848+#define MV_CESA_TDMA_REG_BASE 0x30000
39849+#define MV_SDIO_REG_BASE 0x90000
39850+#define MV_ETH_REG_BASE(port) (((port) == 0) ? 0x72000 : 0x76000)
39851+#define MV_UART_CHAN_BASE(chanNum) (0x12000 + (chanNum * 0x100))
39852+#define DRAM_BASE 0x0
39853+#define CNTMR_BASE 0x20300
39854+#define TWSI_SLAVE_BASE(chanNum) 0x11000
39855+#define PEX_IF_BASE(pexIf) 0x40000
39856+#define MPP_REG_BASE 0x10000
39857+#define TSU_GLOBAL_REG_BASE 0xB4000
39858+#define MAX_AHB_TO_MBUS_REG_BASE 0x20000
39859+
39860+#define INTER_REGS_SIZE _1M
39861+/* This define describes the TWSI interrupt bit and location */
39862+#define TWSI_CPU_MAIN_INT_CAUSE_REG 0x20200
39863+#define TWSI0_CPU_MAIN_INT_BIT (1<<29)
39864+#define TWSI_SPEED 100000
39865+
39866+#define MV_GPP_MAX_GROUP 2
39867+#define MV_CNTMR_MAX_COUNTER 2
39868+#define MV_UART_MAX_CHAN 2
39869+#define MV_XOR_MAX_UNIT 2
39870+#define MV_XOR_MAX_CHAN 4 /* total channels for all units together*/
39871+#define MV_XOR_MAX_CHAN_PER_UNIT 2 /* channels for units */
39872+#define MV_SATA_MAX_CHAN 2
39873+
39874+#define MV_6281_MPP_MAX_MODULE 2
39875+#define MV_6192_MPP_MAX_MODULE 1
39876+#define MV_6190_MPP_MAX_MODULE 1
39877+#define MV_6180_MPP_MAX_MODULE 2
39878+#define MV_6281_MPP_MAX_GROUP 7
39879+#define MV_6192_MPP_MAX_GROUP 4
39880+#define MV_6190_MPP_MAX_GROUP 4
39881+#define MV_6180_MPP_MAX_GROUP 3
39882+
39883+#define MV_DRAM_MAX_CS 4
39884+
39885+/* This define describes the maximum number of supported PCI\PCIX Interfaces*/
39886+#define MV_PCI_MAX_IF 0
39887+#define MV_PCI_START_IF 0
39888+
39889+/* This define describes the maximum number of supported PEX Interfaces */
39890+#define MV_INCLUDE_PEX0
39891+#define MV_DISABLE_PEX_DEVICE_BAR
39892+#define MV_PEX_MAX_IF 1
39893+#define MV_PEX_START_IF MV_PCI_MAX_IF
39894+
39895+/* This define describes the maximum number of supported PCI Interfaces */
39896+#define MV_PCI_IF_MAX_IF (MV_PEX_MAX_IF+MV_PCI_MAX_IF)
39897+
39898+#define MV_ETH_MAX_PORTS 2
39899+#define MV_6281_ETH_MAX_PORTS 2
39900+#define MV_6192_ETH_MAX_PORTS 2
39901+#define MV_6190_ETH_MAX_PORTS 1
39902+#define MV_6180_ETH_MAX_PORTS 1
39903+
39904+#define MV_IDMA_MAX_CHAN 0
39905+
39906+#define MV_USB_MAX_PORTS 1
39907+
39908+#define MV_USB_VERSION 1
39909+
39910+
39911+#define MV_6281_NAND 1
39912+#define MV_6192_NAND 1
39913+#define MV_6190_NAND 1
39914+#define MV_6180_NAND 0
39915+
39916+#define MV_6281_SDIO 1
39917+#define MV_6192_SDIO 1
39918+#define MV_6190_SDIO 1
39919+#define MV_6180_SDIO 1
39920+
39921+#define MV_6281_TS 1
39922+#define MV_6192_TS 1
39923+#define MV_6190_TS 0
39924+#define MV_6180_TS 0
39925+
39926+#define MV_6281_AUDIO 1
39927+#define MV_6192_AUDIO 1
39928+#define MV_6190_AUDIO 0
39929+#define MV_6180_AUDIO 1
39930+
39931+#define MV_6281_TDM 1
39932+#define MV_6192_TDM 1
39933+#define MV_6190_TDM 0
39934+#define MV_6180_TDM 0
39935+
39936+#define MV_DEVICE_MAX_CS 4
39937+
39938+/* Others */
39939+#define PEX_HOST_BUS_NUM(pciIf) (pciIf)
39940+#define PEX_HOST_DEV_NUM(pciIf) 0
39941+
39942+#define PCI_IO(pciIf) (PEX0_IO)
39943+#define PCI_MEM(pciIf, memNum) (PEX0_MEM0)
39944+/* CESA version #2: One channel, 2KB SRAM, TDMA */
39945+#if defined(MV_CESA_CHAIN_MODE_SUPPORT)
39946+ #define MV_CESA_VERSION 3
39947+#else
39948+#define MV_CESA_VERSION 2
39949+#endif
39950+#define MV_CESA_SRAM_SIZE 2*1024
39951+/* This define describes the maximum number of supported Ethernet ports */
39952+#define MV_ETH_VERSION 4
39953+#define MV_ETH_MAX_RXQ 8
39954+#define MV_ETH_MAX_TXQ 8
39955+#define MV_ETH_PORT_SGMII { MV_FALSE, MV_FALSE }
39956+/* This define describes the the support of USB */
39957+#define MV_USB_VERSION 1
39958+
39959+#define MV_INCLUDE_SDRAM_CS0
39960+#define MV_INCLUDE_SDRAM_CS1
39961+#define MV_INCLUDE_SDRAM_CS2
39962+#define MV_INCLUDE_SDRAM_CS3
39963+
39964+#define MV_INCLUDE_DEVICE_CS0
39965+#define MV_INCLUDE_DEVICE_CS1
39966+#define MV_INCLUDE_DEVICE_CS2
39967+#define MV_INCLUDE_DEVICE_CS3
39968+
39969+#define MPP_GROUP_1_TYPE {\
39970+ {0, 0, 0}, /* Reserved for AUTO */ \
39971+ {0x22220000, 0x22222222, 0x2222}, /* TDM */ \
39972+ {0x44440000, 0x00044444, 0x0000}, /* AUDIO */ \
39973+ {0x33330000, 0x33003333, 0x0033}, /* RGMII */ \
39974+ {0x33330000, 0x03333333, 0x0033}, /* GMII */ \
39975+ {0x11110000, 0x11111111, 0x0001}, /* TS */ \
39976+ {0x33330000, 0x33333333, 0x3333} /* MII */ \
39977+}
39978+
39979+#define MPP_GROUP_2_TYPE {\
39980+ {0, 0, 0}, /* Reserved for AUTO */ \
39981+ {0x22220000, 0x22222222, 0x22}, /* TDM */ \
39982+ {0x44440000, 0x00044444, 0x0}, /* AUDIO */ \
39983+ {0, 0, 0}, /* N_A */ \
39984+ {0, 0, 0}, /* N_A */ \
39985+ {0x11110000, 0x11111111, 0x01} /* TS */ \
39986+}
39987+
39988+#ifndef MV_ASMLANGUAGE
39989+
39990+/* This enumerator defines the Marvell Units ID */
39991+typedef enum _mvUnitId
39992+{
39993+ DRAM_UNIT_ID,
39994+ PEX_UNIT_ID,
39995+ ETH_GIG_UNIT_ID,
39996+ USB_UNIT_ID,
39997+ IDMA_UNIT_ID,
39998+ XOR_UNIT_ID,
39999+ SATA_UNIT_ID,
40000+ TDM_UNIT_ID,
40001+ UART_UNIT_ID,
40002+ CESA_UNIT_ID,
40003+ SPI_UNIT_ID,
40004+ AUDIO_UNIT_ID,
40005+ SDIO_UNIT_ID,
40006+ TS_UNIT_ID,
40007+ MAX_UNITS_ID
40008+
40009+}MV_UNIT_ID;
40010+
40011+#endif
40012+
40013+#endif /* __INCmvCtrlEnvSpech */
40014diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c
40015new file mode 100644
40016index 0000000..d22c4fc
40017--- /dev/null
40018+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c
40019@@ -0,0 +1,1048 @@
40020+/*******************************************************************************
40021+Copyright (C) Marvell International Ltd. and its affiliates
40022+
40023+This software file (the "File") is owned and distributed by Marvell
40024+International Ltd. and/or its affiliates ("Marvell") under the following
40025+alternative licensing terms. Once you have made an election to distribute the
40026+File under one of the following license alternatives, please (i) delete this
40027+introductory statement regarding license alternatives, (ii) delete the two
40028+license alternatives that you have not elected to use and (iii) preserve the
40029+Marvell copyright notice above.
40030+
40031+********************************************************************************
40032+Marvell Commercial License Option
40033+
40034+If you received this File from Marvell and you have entered into a commercial
40035+license agreement (a "Commercial License") with Marvell, the File is licensed
40036+to you under the terms of the applicable Commercial License.
40037+
40038+********************************************************************************
40039+Marvell GPL License Option
40040+
40041+If you received this File from Marvell, you may opt to use, redistribute and/or
40042+modify this File in accordance with the terms and conditions of the General
40043+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
40044+available along with the File in the license.txt file or by writing to the Free
40045+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
40046+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
40047+
40048+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
40049+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
40050+DISCLAIMED. The GPL License provides additional details about this warranty
40051+disclaimer.
40052+********************************************************************************
40053+Marvell BSD License Option
40054+
40055+If you received this File from Marvell, you may opt to use, redistribute and/or
40056+modify this File under the following licensing terms.
40057+Redistribution and use in source and binary forms, with or without modification,
40058+are permitted provided that the following conditions are met:
40059+
40060+ * Redistributions of source code must retain the above copyright notice,
40061+ this list of conditions and the following disclaimer.
40062+
40063+ * Redistributions in binary form must reproduce the above copyright
40064+ notice, this list of conditions and the following disclaimer in the
40065+ documentation and/or other materials provided with the distribution.
40066+
40067+ * Neither the name of Marvell nor the names of its contributors may be
40068+ used to endorse or promote products derived from this software without
40069+ specific prior written permission.
40070+
40071+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
40072+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
40073+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40074+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
40075+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40076+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
40077+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
40078+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40079+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40080+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40081+
40082+*******************************************************************************/
40083+
40084+
40085+/* includes */
40086+#include "ctrlEnv/sys/mvAhbToMbus.h"
40087+#include "ctrlEnv/mvCtrlEnvAddrDec.h"
40088+
40089+#undef MV_DEBUG
40090+/* defines */
40091+#ifdef MV_DEBUG
40092+ #define DB(x) x
40093+#else
40094+ #define DB(x)
40095+#endif
40096+
40097+/* typedefs */
40098+
40099+
40100+/* CPU address remap registers offsets are inconsecutive. This struct */
40101+/* describes address remap register offsets */
40102+typedef struct _ahbToMbusRemapRegOffs
40103+{
40104+ MV_U32 lowRegOffs; /* Low 32-bit remap register offset */
40105+ MV_U32 highRegOffs; /* High 32 bit remap register offset */
40106+}AHB_TO_MBUS_REMAP_REG_OFFS;
40107+
40108+/* locals */
40109+static MV_STATUS ahbToMbusRemapRegOffsGet (MV_U32 winNum,
40110+ AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs);
40111+
40112+/*******************************************************************************
40113+* mvAhbToMbusInit - Initialize Ahb To Mbus Address Map !
40114+*
40115+* DESCRIPTION:
40116+*
40117+* INPUT:
40118+* None.
40119+*
40120+* OUTPUT:
40121+* None.
40122+*
40123+* RETURN:
40124+* MV_OK laways.
40125+*
40126+*******************************************************************************/
40127+MV_STATUS mvAhbToMbusInit(void)
40128+{
40129+ return MV_OK;
40130+
40131+}
40132+
40133+/*******************************************************************************
40134+* mvAhbToMbusWinSet - Set CPU-to-peripheral winNum address window
40135+*
40136+* DESCRIPTION:
40137+* This function sets
40138+* address window, also known as address decode window.
40139+* A new address decode window is set for specified winNum address window.
40140+* If address decode window parameter structure enables the window,
40141+* the routine will also enable the winNum window, allowing CPU to access
40142+* the winNum window.
40143+*
40144+* INPUT:
40145+* winNum - Windows number.
40146+* pAddrDecWin - CPU winNum window data structure.
40147+*
40148+* OUTPUT:
40149+* N/A
40150+*
40151+* RETURN:
40152+* MV_OK if CPU winNum window was set correctly, MV_ERROR in case of
40153+* address window overlapps with other active CPU winNum window or
40154+* trying to assign 36bit base address while CPU does not support that.
40155+* The function returns MV_NOT_SUPPORTED, if the winNum is unsupported.
40156+*
40157+*******************************************************************************/
40158+MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
40159+{
40160+ MV_TARGET_ATTRIB targetAttribs;
40161+ MV_DEC_REGS decRegs;
40162+
40163+ /* Parameter checking */
40164+ if (winNum >= MAX_AHB_TO_MBUS_WINS)
40165+ {
40166+ mvOsPrintf("mvAhbToMbusWinSet: ERR. Invalid winNum %d\n", winNum);
40167+ return MV_NOT_SUPPORTED;
40168+ }
40169+
40170+
40171+ /* read base register*/
40172+ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
40173+ {
40174+ decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
40175+ }
40176+ else
40177+ {
40178+ decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
40179+ }
40180+
40181+ /* check if address is aligned to the size */
40182+ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
40183+ {
40184+ mvOsPrintf("mvAhbToMbusWinSet:Error setting AHB to MBUS window %d to "\
40185+ "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
40186+ winNum,
40187+ mvCtrlTargetNameGet(pAddrDecWin->target),
40188+ pAddrDecWin->addrWin.baseLow,
40189+ pAddrDecWin->addrWin.size);
40190+ return MV_ERROR;
40191+ }
40192+
40193+ /* read control register*/
40194+ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
40195+ {
40196+ decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
40197+ }
40198+
40199+ if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
40200+ {
40201+ mvOsPrintf("mvAhbToMbusWinSet:mvCtrlAddrDecToReg Failed\n");
40202+ return MV_ERROR;
40203+ }
40204+
40205+ /* enable\Disable */
40206+ if (MV_TRUE == pAddrDecWin->enable)
40207+ {
40208+ decRegs.sizeReg |= ATMWCR_WIN_ENABLE;
40209+ }
40210+ else
40211+ {
40212+ decRegs.sizeReg &= ~ATMWCR_WIN_ENABLE;
40213+ }
40214+
40215+ mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
40216+
40217+ /* set attributes */
40218+ decRegs.sizeReg &= ~ATMWCR_WIN_ATTR_MASK;
40219+ decRegs.sizeReg |= targetAttribs.attrib << ATMWCR_WIN_ATTR_OFFS;
40220+ /* set target ID */
40221+ decRegs.sizeReg &= ~ATMWCR_WIN_TARGET_MASK;
40222+ decRegs.sizeReg |= targetAttribs.targetId << ATMWCR_WIN_TARGET_OFFS;
40223+
40224+#if !defined(MV_RUN_FROM_FLASH)
40225+ /* To be on the safe side we disable the window before writing the */
40226+ /* new values. */
40227+ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
40228+ {
40229+ mvAhbToMbusWinEnable(winNum,MV_FALSE);
40230+ }
40231+#endif
40232+
40233+ /* 3) Write to address decode Base Address Register */
40234+ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
40235+ {
40236+ MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum), decRegs.baseReg);
40237+ }
40238+ else
40239+ {
40240+ MV_REG_WRITE(AHB_TO_MBUS_WIN_INTEREG_REG, decRegs.baseReg);
40241+ }
40242+
40243+
40244+ /* Internal register space have no size */
40245+ /* register. Do not perform size register assigment for those targets */
40246+ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
40247+ {
40248+ /* Write to address decode Size Register */
40249+ MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), decRegs.sizeReg);
40250+ }
40251+
40252+ return MV_OK;
40253+}
40254+
40255+/*******************************************************************************
40256+* mvAhbToMbusWinGet - Get CPU-to-peripheral winNum address window
40257+*
40258+* DESCRIPTION:
40259+* Get the CPU peripheral winNum address window.
40260+*
40261+* INPUT:
40262+* winNum - Peripheral winNum enumerator
40263+*
40264+* OUTPUT:
40265+* pAddrDecWin - CPU winNum window information data structure.
40266+*
40267+* RETURN:
40268+* MV_OK if winNum exist, MV_ERROR otherwise.
40269+*
40270+*******************************************************************************/
40271+MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
40272+{
40273+ MV_DEC_REGS decRegs;
40274+ MV_TARGET_ATTRIB targetAttrib;
40275+
40276+
40277+ /* Parameter checking */
40278+ if (winNum >= MAX_AHB_TO_MBUS_WINS)
40279+ {
40280+ mvOsPrintf("mvAhbToMbusWinGet: ERR. Invalid winNum %d\n", winNum);
40281+ return MV_NOT_SUPPORTED;
40282+ }
40283+
40284+
40285+ /* Internal register space size have no size register*/
40286+ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
40287+ {
40288+ decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
40289+ }
40290+ else
40291+ {
40292+ decRegs.sizeReg = 0;
40293+ }
40294+
40295+
40296+ /* Read base and size */
40297+ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
40298+ {
40299+ decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
40300+ }
40301+ else
40302+ {
40303+ decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
40304+ }
40305+
40306+
40307+
40308+ if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
40309+ {
40310+ mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");
40311+ return MV_ERROR;
40312+ }
40313+
40314+ if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
40315+ {
40316+ pAddrDecWin->addrWin.size = INTER_REGS_SIZE;
40317+ pAddrDecWin->target = INTER_REGS;
40318+ pAddrDecWin->enable = MV_TRUE;
40319+
40320+ return MV_OK;
40321+ }
40322+
40323+
40324+ if (decRegs.sizeReg & ATMWCR_WIN_ENABLE)
40325+ {
40326+ pAddrDecWin->enable = MV_TRUE;
40327+ }
40328+ else
40329+ {
40330+ pAddrDecWin->enable = MV_FALSE;
40331+
40332+ }
40333+
40334+
40335+
40336+ if (-1 == pAddrDecWin->addrWin.size)
40337+ {
40338+ return MV_ERROR;
40339+ }
40340+
40341+ /* attrib and targetId */
40342+ targetAttrib.attrib = (decRegs.sizeReg & ATMWCR_WIN_ATTR_MASK) >>
40343+ ATMWCR_WIN_ATTR_OFFS;
40344+ targetAttrib.targetId = (decRegs.sizeReg & ATMWCR_WIN_TARGET_MASK) >>
40345+ ATMWCR_WIN_TARGET_OFFS;
40346+
40347+ pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
40348+
40349+ return MV_OK;
40350+}
40351+
40352+/*******************************************************************************
40353+* mvAhbToMbusWinTargetGet - Get Window number associated with target
40354+*
40355+* DESCRIPTION:
40356+*
40357+* INPUT:
40358+*
40359+* OUTPUT:
40360+*
40361+* RETURN:
40362+*
40363+*******************************************************************************/
40364+MV_U32 mvAhbToMbusWinTargetGet(MV_TARGET target)
40365+{
40366+ MV_AHB_TO_MBUS_DEC_WIN decWin;
40367+ MV_U32 winNum;
40368+
40369+ /* Check parameters */
40370+ if (target >= MAX_TARGETS)
40371+ {
40372+ mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);
40373+ return 0xffffffff;
40374+ }
40375+
40376+ if (INTER_REGS == target)
40377+ {
40378+ return MV_AHB_TO_MBUS_INTREG_WIN;
40379+ }
40380+
40381+ for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)
40382+ {
40383+ if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
40384+ continue;
40385+
40386+ if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)
40387+ {
40388+ mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");
40389+ return 0xffffffff;
40390+
40391+ }
40392+
40393+ if (decWin.enable == MV_TRUE)
40394+ {
40395+ if (decWin.target == target)
40396+ {
40397+ return winNum;
40398+ }
40399+
40400+ }
40401+
40402+ }
40403+
40404+ return 0xFFFFFFFF;
40405+
40406+
40407+}
40408+
40409+/*******************************************************************************
40410+* mvAhbToMbusWinAvailGet - Get First Available window number.
40411+*
40412+* DESCRIPTION:
40413+*
40414+* INPUT:
40415+*
40416+* OUTPUT:
40417+*
40418+* RETURN:
40419+*
40420+*******************************************************************************/
40421+MV_U32 mvAhbToMbusWinAvailGet(MV_VOID)
40422+{
40423+ MV_AHB_TO_MBUS_DEC_WIN decWin;
40424+ MV_U32 winNum;
40425+
40426+ for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)
40427+ {
40428+ if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
40429+ continue;
40430+
40431+ if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)
40432+ {
40433+ mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");
40434+ return 0xffffffff;
40435+
40436+ }
40437+
40438+ if (decWin.enable == MV_FALSE)
40439+ {
40440+ return winNum;
40441+ }
40442+
40443+ }
40444+
40445+ return 0xFFFFFFFF;
40446+}
40447+
40448+
40449+/*******************************************************************************
40450+* mvAhbToMbusWinEnable - Enable/disable a CPU address decode window
40451+*
40452+* DESCRIPTION:
40453+* This function enable/disable a CPU address decode window.
40454+* if parameter 'enable' == MV_TRUE the routine will enable the
40455+* window, thus enabling CPU accesses (before enabling the window it is
40456+* tested for overlapping). Otherwise, the window will be disabled.
40457+*
40458+* INPUT:
40459+* winNum - Peripheral winNum enumerator.
40460+* enable - Enable/disable parameter.
40461+*
40462+* OUTPUT:
40463+* N/A
40464+*
40465+* RETURN:
40466+* MV_ERROR if protection window number was wrong, or the window
40467+* overlapps other winNum window.
40468+*
40469+*******************************************************************************/
40470+MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum, MV_BOOL enable)
40471+{
40472+
40473+ /* Parameter checking */
40474+ if (winNum >= MAX_AHB_TO_MBUS_WINS)
40475+ {
40476+ mvOsPrintf("mvAhbToMbusWinEnable: ERR. Invalid winNum %d\n", winNum);
40477+ return MV_NOT_SUPPORTED;
40478+ }
40479+
40480+ /* Internal registers bar can't be disable or enabled */
40481+ if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
40482+ {
40483+ return (enable ? MV_OK : MV_ERROR);
40484+ }
40485+
40486+ if (enable == MV_TRUE)
40487+ {
40488+ /* enable the window */
40489+ MV_REG_BIT_SET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
40490+ }
40491+ else
40492+ { /* Disable address decode winNum window */
40493+ MV_REG_BIT_RESET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
40494+ }
40495+
40496+ return MV_OK;
40497+}
40498+
40499+
40500+/*******************************************************************************
40501+* mvAhbToMbusWinRemap - Set CPU remap register for address windows.
40502+*
40503+* DESCRIPTION:
40504+* After a CPU address hits one of PCI address decode windows there is an
40505+* option to remap the address to a different one. For example, CPU
40506+* executes a read from PCI winNum window address 0x1200.0000. This
40507+* can be modified so the address on the PCI bus would be 0x1400.0000
40508+* Using the PCI address remap mechanism.
40509+*
40510+* INPUT:
40511+* winNum - Peripheral winNum enumerator. Must be a PCI winNum.
40512+* pAddrDecWin - CPU winNum window information data structure.
40513+* Note that caller has to fill in the base field only. The
40514+* size field is ignored.
40515+*
40516+* OUTPUT:
40517+* None.
40518+*
40519+* RETURN:
40520+* MV_ERROR if winNum is not a PCI one, MV_OK otherwise.
40521+*
40522+*******************************************************************************/
40523+MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
40524+{
40525+ MV_U32 baseAddr;
40526+ AHB_TO_MBUS_REMAP_REG_OFFS remapRegOffs;
40527+
40528+ MV_U32 effectiveBaseAddress=0,
40529+ baseAddrValue=0,windowSizeValue=0;
40530+
40531+
40532+ /* Get registers offsets of given winNum */
40533+ if (MV_NO_SUCH == ahbToMbusRemapRegOffsGet(winNum, &remapRegOffs))
40534+ {
40535+ return 0xffffffff;
40536+ }
40537+
40538+ /* 1) Set address remap low */
40539+ baseAddr = pAddrWin->baseLow;
40540+
40541+ /* Check base address aligment */
40542+ /*
40543+ if (MV_IS_NOT_ALIGN(baseAddr, ATMWRLR_REMAP_LOW_ALIGNMENT))
40544+ {
40545+ mvOsPrintf("mvAhbToMbusPciRemap: Warning. Target base 0x%x unaligned\n",
40546+ baseAddr);
40547+ return MV_ERROR;
40548+ }
40549+ */
40550+
40551+ /* BaseLow[31:16] => base register [31:16] */
40552+ baseAddr = baseAddr & ATMWRLR_REMAP_LOW_MASK;
40553+
40554+ MV_REG_WRITE(remapRegOffs.lowRegOffs, baseAddr);
40555+
40556+ MV_REG_WRITE(remapRegOffs.highRegOffs, pAddrWin->baseHigh);
40557+
40558+
40559+ baseAddrValue = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
40560+ windowSizeValue = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
40561+
40562+ baseAddrValue &= ATMWBR_BASE_MASK;
40563+ windowSizeValue &=ATMWCR_WIN_SIZE_MASK;
40564+
40565+ /* Start calculating the effective Base Address */
40566+ effectiveBaseAddress = baseAddrValue ;
40567+
40568+ /* The effective base address will be combined from the chopped (if any)
40569+ remap value (according to the size value and remap mechanism) and the
40570+ window's base address */
40571+ effectiveBaseAddress |= (((windowSizeValue) | 0xffff) & pAddrWin->baseLow);
40572+ /* If the effectiveBaseAddress exceed the window boundaries return an
40573+ invalid value. */
40574+
40575+ if (effectiveBaseAddress > (baseAddrValue + (windowSizeValue | 0xffff)))
40576+ {
40577+ mvOsPrintf("mvAhbToMbusPciRemap: Error\n");
40578+ return 0xffffffff;
40579+ }
40580+
40581+ return effectiveBaseAddress;
40582+
40583+
40584+}
40585+/*******************************************************************************
40586+* mvAhbToMbusWinTargetSwap - Swap AhbToMbus windows between targets
40587+*
40588+* DESCRIPTION:
40589+*
40590+* INPUT:
40591+* target1 - CPU Interface target 1
40592+* target2 - CPU Interface target 2
40593+*
40594+* OUTPUT:
40595+* None.
40596+*
40597+* RETURN:
40598+* MV_ERROR if targets are illigal, or if one of the targets is not
40599+* associated to a valid window .
40600+* MV_OK otherwise.
40601+*
40602+*******************************************************************************/
40603+
40604+
40605+MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2)
40606+{
40607+ MV_U32 winNum1,winNum2;
40608+ MV_AHB_TO_MBUS_DEC_WIN winDec1,winDec2,winDecTemp;
40609+ AHB_TO_MBUS_REMAP_REG_OFFS remapRegs1,remapRegs2;
40610+ MV_U32 remapBaseLow1=0,remapBaseLow2=0;
40611+ MV_U32 remapBaseHigh1=0,remapBaseHigh2=0;
40612+
40613+
40614+ /* Check parameters */
40615+ if (target1 >= MAX_TARGETS)
40616+ {
40617+ mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);
40618+ return MV_ERROR;
40619+ }
40620+
40621+ if (target2 >= MAX_TARGETS)
40622+ {
40623+ mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);
40624+ return MV_ERROR;
40625+ }
40626+
40627+
40628+ /* get window associated with this target */
40629+ winNum1 = mvAhbToMbusWinTargetGet(target1);
40630+
40631+ if (winNum1 == 0xffffffff)
40632+ {
40633+ mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",
40634+ target1,winNum1);
40635+ return MV_ERROR;
40636+
40637+ }
40638+
40639+ /* get window associated with this target */
40640+ winNum2 = mvAhbToMbusWinTargetGet(target2);
40641+
40642+ if (winNum2 == 0xffffffff)
40643+ {
40644+ mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",
40645+ target2,winNum2);
40646+ return MV_ERROR;
40647+
40648+ }
40649+
40650+ /* now Get original values of both Windows */
40651+ if (MV_OK != mvAhbToMbusWinGet(winNum1,&winDec1))
40652+ {
40653+ mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",
40654+ winNum1);
40655+ return MV_ERROR;
40656+
40657+ }
40658+ if (MV_OK != mvAhbToMbusWinGet(winNum2,&winDec2))
40659+ {
40660+ mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",
40661+ winNum2);
40662+ return MV_ERROR;
40663+
40664+ }
40665+
40666+
40667+ /* disable both windows */
40668+ if (MV_OK != mvAhbToMbusWinEnable(winNum1,MV_FALSE))
40669+ {
40670+ mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable window %d\n",
40671+ winNum1);
40672+ return MV_ERROR;
40673+
40674+ }
40675+ if (MV_OK != mvAhbToMbusWinEnable(winNum2,MV_FALSE))
40676+ {
40677+ mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable windo %d\n",
40678+ winNum2);
40679+ return MV_ERROR;
40680+
40681+ }
40682+
40683+
40684+ /* now swap targets */
40685+
40686+ /* first save winDec2 values */
40687+ winDecTemp.addrWin.baseHigh = winDec2.addrWin.baseHigh;
40688+ winDecTemp.addrWin.baseLow = winDec2.addrWin.baseLow;
40689+ winDecTemp.addrWin.size = winDec2.addrWin.size;
40690+ winDecTemp.enable = winDec2.enable;
40691+ winDecTemp.target = winDec2.target;
40692+
40693+ /* winDec2 = winDec1 */
40694+ winDec2.addrWin.baseHigh = winDec1.addrWin.baseHigh;
40695+ winDec2.addrWin.baseLow = winDec1.addrWin.baseLow;
40696+ winDec2.addrWin.size = winDec1.addrWin.size;
40697+ winDec2.enable = winDec1.enable;
40698+ winDec2.target = winDec1.target;
40699+
40700+
40701+ /* winDec1 = winDecTemp */
40702+ winDec1.addrWin.baseHigh = winDecTemp.addrWin.baseHigh;
40703+ winDec1.addrWin.baseLow = winDecTemp.addrWin.baseLow;
40704+ winDec1.addrWin.size = winDecTemp.addrWin.size;
40705+ winDec1.enable = winDecTemp.enable;
40706+ winDec1.target = winDecTemp.target;
40707+
40708+
40709+ /* now set the new values */
40710+
40711+
40712+ mvAhbToMbusWinSet(winNum1,&winDec1);
40713+ mvAhbToMbusWinSet(winNum2,&winDec2);
40714+
40715+
40716+
40717+
40718+
40719+ /* now we will treat the remap windows if exist */
40720+
40721+
40722+ /* now check if one or both windows has a remap window
40723+ as well after the swap ! */
40724+
40725+ /* if a window had a remap value differnt than the base value
40726+ before the swap , then after the swap the remap value will be
40727+ equal to the base value unless both windows has a remap windows*/
40728+
40729+ /* first get old values */
40730+ if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))
40731+ {
40732+ remapBaseLow1 = MV_REG_READ(remapRegs1.lowRegOffs);
40733+ remapBaseHigh1 = MV_REG_READ(remapRegs1.highRegOffs);
40734+
40735+ }
40736+ if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
40737+ {
40738+ remapBaseLow2 = MV_REG_READ(remapRegs2.lowRegOffs);
40739+ remapBaseHigh2 = MV_REG_READ(remapRegs2.highRegOffs);
40740+
40741+
40742+ }
40743+
40744+ /* now do the swap */
40745+ if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))
40746+ {
40747+ if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
40748+ {
40749+ /* Two windows has a remap !!! so swap */
40750+
40751+ MV_REG_WRITE(remapRegs2.highRegOffs,remapBaseHigh1);
40752+ MV_REG_WRITE(remapRegs2.lowRegOffs,remapBaseLow1);
40753+
40754+ MV_REG_WRITE(remapRegs1.highRegOffs,remapBaseHigh2);
40755+ MV_REG_WRITE(remapRegs1.lowRegOffs,remapBaseLow2);
40756+
40757+
40758+
40759+ }
40760+ else
40761+ {
40762+ /* remap == base */
40763+ MV_REG_WRITE(remapRegs1.highRegOffs,winDec1.addrWin.baseHigh);
40764+ MV_REG_WRITE(remapRegs1.lowRegOffs,winDec1.addrWin.baseLow);
40765+
40766+ }
40767+
40768+ }
40769+ else if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
40770+ {
40771+ /* remap == base */
40772+ MV_REG_WRITE(remapRegs2.highRegOffs,winDec2.addrWin.baseHigh);
40773+ MV_REG_WRITE(remapRegs2.lowRegOffs,winDec2.addrWin.baseLow);
40774+
40775+ }
40776+
40777+
40778+
40779+ return MV_OK;
40780+
40781+
40782+}
40783+
40784+
40785+
40786+#if defined(MV_88F1181)
40787+
40788+/*******************************************************************************
40789+* mvAhbToMbusXbarCtrlSet - Set The CPU master Xbar arbitration.
40790+*
40791+* DESCRIPTION:
40792+* This function sets CPU Mbus Arbiter
40793+*
40794+* INPUT:
40795+* pPizzaArbArray - A priority Structure describing 16 "pizza slices". At
40796+* each clock cycle, the crossbar arbiter samples all
40797+* requests and gives the bus to the next agent according
40798+* to the "pizza".
40799+*
40800+* OUTPUT:
40801+* N/A
40802+*
40803+* RETURN:
40804+* MV_ERROR if paramers to function invalid.
40805+*
40806+*******************************************************************************/
40807+MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray)
40808+{
40809+ MV_U32 sliceNum;
40810+ MV_U32 xbarCtrl = 0;
40811+ MV_MBUS_ARB_TARGET xbarTarget;
40812+
40813+ /* 1) Set crossbar control low register */
40814+ for (sliceNum = 0; sliceNum < MRLR_SLICE_NUM; sliceNum++)
40815+ {
40816+ xbarTarget = pPizzaArbArray[sliceNum];
40817+
40818+ /* sliceNum parameter check */
40819+ if (xbarTarget > MAX_MBUS_ARB_TARGETS)
40820+ {
40821+ mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",
40822+ xbarTarget);
40823+ return MV_ERROR;
40824+ }
40825+ xbarCtrl |= (xbarTarget << MRLR_LOW_ARB_OFFS(sliceNum));
40826+ }
40827+ /* Write to crossbar control low register */
40828+ MV_REG_WRITE(MBUS_ARBITER_LOW_REG, xbarCtrl);
40829+
40830+ xbarCtrl = 0;
40831+
40832+ /* 2) Set crossbar control high register */
40833+ for (sliceNum = MRLR_SLICE_NUM;
40834+ sliceNum < MRLR_SLICE_NUM+MRHR_SLICE_NUM;
40835+ sliceNum++)
40836+ {
40837+
40838+ xbarTarget = pPizzaArbArray[sliceNum];
40839+
40840+ /* sliceNum parameter check */
40841+ if (xbarTarget > MAX_MBUS_ARB_TARGETS)
40842+ {
40843+ mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",
40844+ xbarTarget);
40845+ return MV_ERROR;
40846+ }
40847+ xbarCtrl |= (xbarTarget << MRHR_HIGH_ARB_OFFS(sliceNum));
40848+ }
40849+ /* Write to crossbar control high register */
40850+ MV_REG_WRITE(MBUS_ARBITER_HIGH_REG, xbarCtrl);
40851+
40852+ return MV_OK;
40853+}
40854+
40855+/*******************************************************************************
40856+* mvMbusArbCtrlSet - Set MBus Arbiter control register
40857+*
40858+* DESCRIPTION:
40859+*
40860+* INPUT:
40861+* ctrl - pointer to MV_MBUS_ARB_CTRL register
40862+*
40863+* OUTPUT:
40864+* N/A
40865+*
40866+* RETURN:
40867+* MV_ERROR if paramers to function invalid.
40868+*
40869+*******************************************************************************/
40870+MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl)
40871+{
40872+
40873+ if (ctrl->highPrio == MV_FALSE)
40874+ {
40875+ MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);
40876+ }
40877+ else
40878+ {
40879+ MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);
40880+ }
40881+
40882+ if (ctrl->fixedRoundRobin == MV_FALSE)
40883+ {
40884+ MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);
40885+ }
40886+ else
40887+ {
40888+ MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);
40889+ }
40890+
40891+ if (ctrl->starvEn == MV_FALSE)
40892+ {
40893+ MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);
40894+ }
40895+ else
40896+ {
40897+ MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);
40898+ }
40899+
40900+ return MV_OK;
40901+}
40902+
40903+/*******************************************************************************
40904+* mvMbusArbCtrlGet - Get MBus Arbiter control register
40905+*
40906+* DESCRIPTION:
40907+*
40908+* INPUT:
40909+* ctrl - pointer to MV_MBUS_ARB_CTRL register
40910+*
40911+* OUTPUT:
40912+* ctrl - pointer to MV_MBUS_ARB_CTRL register
40913+*
40914+* RETURN:
40915+* MV_ERROR if paramers to function invalid.
40916+*
40917+*******************************************************************************/
40918+MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl)
40919+{
40920+
40921+ MV_U32 ctrlReg = MV_REG_READ(MBUS_ARBITER_CTRL_REG);
40922+
40923+ if (ctrlReg & MACR_ARB_ARM_TOP)
40924+ {
40925+ ctrl->highPrio = MV_TRUE;
40926+ }
40927+ else
40928+ {
40929+ ctrl->highPrio = MV_FALSE;
40930+ }
40931+
40932+ if (ctrlReg & MACR_ARB_TARGET_FIXED)
40933+ {
40934+ ctrl->fixedRoundRobin = MV_TRUE;
40935+ }
40936+ else
40937+ {
40938+ ctrl->fixedRoundRobin = MV_FALSE;
40939+ }
40940+
40941+ if (ctrlReg & MACR_ARB_REQ_CTRL_EN)
40942+ {
40943+ ctrl->starvEn = MV_TRUE;
40944+ }
40945+ else
40946+ {
40947+ ctrl->starvEn = MV_FALSE;
40948+ }
40949+
40950+
40951+ return MV_OK;
40952+}
40953+
40954+#endif /* #if defined(MV_88F1181) */
40955+
40956+
40957+
40958+/*******************************************************************************
40959+* ahbToMbusRemapRegOffsGet - Get CPU address remap register offsets
40960+*
40961+* DESCRIPTION:
40962+* CPU to PCI address remap registers offsets are inconsecutive.
40963+* This function returns PCI address remap registers offsets.
40964+*
40965+* INPUT:
40966+* winNum - Address decode window number. See MV_U32 enumerator.
40967+*
40968+* OUTPUT:
40969+* None.
40970+*
40971+* RETURN:
40972+* MV_ERROR if winNum is not a PCI one.
40973+*
40974+*******************************************************************************/
40975+static MV_STATUS ahbToMbusRemapRegOffsGet(MV_U32 winNum,
40976+ AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs)
40977+{
40978+ switch (winNum)
40979+ {
40980+ case 0:
40981+ case 1:
40982+ pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);
40983+ pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);
40984+ break;
40985+ case 2:
40986+ case 3:
40987+ if((mvCtrlModelGet() == MV_5281_DEV_ID) ||
40988+ (mvCtrlModelGet() == MV_1281_DEV_ID) ||
40989+ (mvCtrlModelGet() == MV_6183_DEV_ID) ||
40990+ (mvCtrlModelGet() == MV_6183L_DEV_ID))
40991+ {
40992+ pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);
40993+ pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);
40994+ break;
40995+ }
40996+ else
40997+ {
40998+ pRemapRegs->lowRegOffs = 0;
40999+ pRemapRegs->highRegOffs = 0;
41000+
41001+ DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",
41002+ winNum));
41003+ return MV_NO_SUCH;
41004+ }
41005+ default:
41006+ {
41007+ pRemapRegs->lowRegOffs = 0;
41008+ pRemapRegs->highRegOffs = 0;
41009+
41010+ DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",
41011+ winNum));
41012+ return MV_NO_SUCH;
41013+ }
41014+ }
41015+
41016+ return MV_OK;
41017+}
41018+
41019+/*******************************************************************************
41020+* mvAhbToMbusAddDecShow - Print the AHB to MBus bridge address decode map.
41021+*
41022+* DESCRIPTION:
41023+* This function print the CPU address decode map.
41024+*
41025+* INPUT:
41026+* None.
41027+*
41028+* OUTPUT:
41029+* None.
41030+*
41031+* RETURN:
41032+* None.
41033+*
41034+*******************************************************************************/
41035+MV_VOID mvAhbToMbusAddDecShow(MV_VOID)
41036+{
41037+ MV_AHB_TO_MBUS_DEC_WIN win;
41038+ MV_U32 winNum;
41039+ mvOsOutput( "\n" );
41040+ mvOsOutput( "AHB To MBUS Bridge:\n" );
41041+ mvOsOutput( "-------------------\n" );
41042+
41043+ for( winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS; winNum++ )
41044+ {
41045+ memset( &win, 0, sizeof(MV_AHB_TO_MBUS_DEC_WIN) );
41046+
41047+ mvOsOutput( "win%d - ", winNum );
41048+
41049+ if( mvAhbToMbusWinGet( winNum, &win ) == MV_OK )
41050+ {
41051+ if( win.enable )
41052+ {
41053+ mvOsOutput( "%s base %08x, ",
41054+ mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
41055+ mvOsOutput( "...." );
41056+ mvSizePrint( win.addrWin.size );
41057+
41058+ mvOsOutput( "\n" );
41059+
41060+ }
41061+ else
41062+ mvOsOutput( "disable\n" );
41063+ }
41064+ }
41065+
41066+}
41067+
41068diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h
41069new file mode 100644
41070index 0000000..a1d93b7
41071--- /dev/null
41072+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h
41073@@ -0,0 +1,130 @@
41074+/*******************************************************************************
41075+Copyright (C) Marvell International Ltd. and its affiliates
41076+
41077+This software file (the "File") is owned and distributed by Marvell
41078+International Ltd. and/or its affiliates ("Marvell") under the following
41079+alternative licensing terms. Once you have made an election to distribute the
41080+File under one of the following license alternatives, please (i) delete this
41081+introductory statement regarding license alternatives, (ii) delete the two
41082+license alternatives that you have not elected to use and (iii) preserve the
41083+Marvell copyright notice above.
41084+
41085+********************************************************************************
41086+Marvell Commercial License Option
41087+
41088+If you received this File from Marvell and you have entered into a commercial
41089+license agreement (a "Commercial License") with Marvell, the File is licensed
41090+to you under the terms of the applicable Commercial License.
41091+
41092+********************************************************************************
41093+Marvell GPL License Option
41094+
41095+If you received this File from Marvell, you may opt to use, redistribute and/or
41096+modify this File in accordance with the terms and conditions of the General
41097+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
41098+available along with the File in the license.txt file or by writing to the Free
41099+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
41100+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
41101+
41102+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
41103+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
41104+DISCLAIMED. The GPL License provides additional details about this warranty
41105+disclaimer.
41106+********************************************************************************
41107+Marvell BSD License Option
41108+
41109+If you received this File from Marvell, you may opt to use, redistribute and/or
41110+modify this File under the following licensing terms.
41111+Redistribution and use in source and binary forms, with or without modification,
41112+are permitted provided that the following conditions are met:
41113+
41114+ * Redistributions of source code must retain the above copyright notice,
41115+ this list of conditions and the following disclaimer.
41116+
41117+ * Redistributions in binary form must reproduce the above copyright
41118+ notice, this list of conditions and the following disclaimer in the
41119+ documentation and/or other materials provided with the distribution.
41120+
41121+ * Neither the name of Marvell nor the names of its contributors may be
41122+ used to endorse or promote products derived from this software without
41123+ specific prior written permission.
41124+
41125+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
41126+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
41127+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41128+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
41129+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41130+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
41131+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41132+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41133+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41134+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41135+
41136+*******************************************************************************/
41137+
41138+
41139+#ifndef __INCmvAhbToMbush
41140+#define __INCmvAhbToMbush
41141+
41142+/* includes */
41143+#include "ctrlEnv/mvCtrlEnvLib.h"
41144+#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
41145+#include "ctrlEnv/mvCtrlEnvAddrDec.h"
41146+
41147+/* defines */
41148+
41149+#if defined(MV_88F1181)
41150+/* This enumerator defines the Marvell controller possible MBUS arbiter */
41151+/* target ports. It is used to define crossbar priority scheame (pizza) */
41152+typedef enum _mvMBusArbTargetId
41153+{
41154+ DRAM_MBUS_ARB_TARGET = 0, /* Port 0 -> DRAM interface */
41155+ TWSI_MBUS_ARB_TARGET = 1, /* Port 1 -> TWSI */
41156+ ARM_MBUS_ARB_TARGET = 2, /* Port 2 -> ARM */
41157+ PEX1_MBUS_ARB_TARGET = 3, /* Port 3 -> PCI Express 1 */
41158+ PEX0_MBUS_ARB_TARGET = 4, /* Port 4 -> PCI Express0 */
41159+ MAX_MBUS_ARB_TARGETS
41160+}MV_MBUS_ARB_TARGET;
41161+
41162+typedef struct _mvMBusArbCtrl
41163+{
41164+ MV_BOOL starvEn;
41165+ MV_BOOL highPrio;
41166+ MV_BOOL fixedRoundRobin;
41167+
41168+}MV_MBUS_ARB_CTRL;
41169+
41170+#endif /* #if defined(MV_88F1181) */
41171+
41172+typedef struct _mvAhbtoMbusDecWin
41173+{
41174+ MV_TARGET target;
41175+ MV_ADDR_WIN addrWin; /* An address window*/
41176+ MV_BOOL enable; /* Address decode window is enabled/disabled */
41177+
41178+}MV_AHB_TO_MBUS_DEC_WIN;
41179+
41180+/* mvAhbToMbus.h API list */
41181+
41182+MV_STATUS mvAhbToMbusInit(MV_VOID);
41183+MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);
41184+MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);
41185+MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum,MV_BOOL enable);
41186+MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrDecWin);
41187+MV_U32 mvAhbToMbusWinTargetGet(MV_TARGET target);
41188+MV_U32 mvAhbToMbusWinAvailGet(MV_VOID);
41189+MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2);
41190+
41191+#if defined(MV_88F1181)
41192+
41193+MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray);
41194+MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl);
41195+MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl);
41196+
41197+#endif /* #if defined(MV_88F1181) */
41198+
41199+
41200+MV_VOID mvAhbToMbusAddDecShow(MV_VOID);
41201+
41202+
41203+#endif /* __INCmvAhbToMbush */
41204diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h
41205new file mode 100644
41206index 0000000..c5682e8
41207--- /dev/null
41208+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h
41209@@ -0,0 +1,143 @@
41210+/*******************************************************************************
41211+Copyright (C) Marvell International Ltd. and its affiliates
41212+
41213+This software file (the "File") is owned and distributed by Marvell
41214+International Ltd. and/or its affiliates ("Marvell") under the following
41215+alternative licensing terms. Once you have made an election to distribute the
41216+File under one of the following license alternatives, please (i) delete this
41217+introductory statement regarding license alternatives, (ii) delete the two
41218+license alternatives that you have not elected to use and (iii) preserve the
41219+Marvell copyright notice above.
41220+
41221+********************************************************************************
41222+Marvell Commercial License Option
41223+
41224+If you received this File from Marvell and you have entered into a commercial
41225+license agreement (a "Commercial License") with Marvell, the File is licensed
41226+to you under the terms of the applicable Commercial License.
41227+
41228+********************************************************************************
41229+Marvell GPL License Option
41230+
41231+If you received this File from Marvell, you may opt to use, redistribute and/or
41232+modify this File in accordance with the terms and conditions of the General
41233+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
41234+available along with the File in the license.txt file or by writing to the Free
41235+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
41236+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
41237+
41238+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
41239+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
41240+DISCLAIMED. The GPL License provides additional details about this warranty
41241+disclaimer.
41242+********************************************************************************
41243+Marvell BSD License Option
41244+
41245+If you received this File from Marvell, you may opt to use, redistribute and/or
41246+modify this File under the following licensing terms.
41247+Redistribution and use in source and binary forms, with or without modification,
41248+are permitted provided that the following conditions are met:
41249+
41250+ * Redistributions of source code must retain the above copyright notice,
41251+ this list of conditions and the following disclaimer.
41252+
41253+ * Redistributions in binary form must reproduce the above copyright
41254+ notice, this list of conditions and the following disclaimer in the
41255+ documentation and/or other materials provided with the distribution.
41256+
41257+ * Neither the name of Marvell nor the names of its contributors may be
41258+ used to endorse or promote products derived from this software without
41259+ specific prior written permission.
41260+
41261+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
41262+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
41263+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41264+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
41265+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41266+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
41267+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41268+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41269+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41270+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41271+
41272+*******************************************************************************/
41273+
41274+
41275+#ifndef __INCmvAhbToMbusRegsh
41276+#define __INCmvAhbToMbusRegsh
41277+
41278+/******************************/
41279+/* ARM Address Map Registers */
41280+/******************************/
41281+
41282+#define MAX_AHB_TO_MBUS_WINS 9
41283+#define MV_AHB_TO_MBUS_INTREG_WIN 8
41284+
41285+
41286+#define AHB_TO_MBUS_WIN_CTRL_REG(winNum) (0x20000 + (winNum)*0x10)
41287+#define AHB_TO_MBUS_WIN_BASE_REG(winNum) (0x20004 + (winNum)*0x10)
41288+#define AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum) (0x20008 + (winNum)*0x10)
41289+#define AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum) (0x2000C + (winNum)*0x10)
41290+#define AHB_TO_MBUS_WIN_INTEREG_REG 0x20080
41291+
41292+/* Window Control Register */
41293+/* AHB_TO_MBUS_WIN_CTRL_REG (ATMWCR)*/
41294+#define ATMWCR_WIN_ENABLE BIT0 /* Window Enable */
41295+
41296+#define ATMWCR_WIN_TARGET_OFFS 4 /* The target interface associated
41297+ with this window*/
41298+#define ATMWCR_WIN_TARGET_MASK (0xf << ATMWCR_WIN_TARGET_OFFS)
41299+
41300+#define ATMWCR_WIN_ATTR_OFFS 8 /* The target interface attributes
41301+ Associated with this window */
41302+#define ATMWCR_WIN_ATTR_MASK (0xff << ATMWCR_WIN_ATTR_OFFS)
41303+
41304+
41305+/*
41306+Used with the Base register to set the address window size and location
41307+Must be programed from LSB to MSB as sequence of 1’s followed
41308+by sequence of 0’s. The number of 1’s specifies the size of the window
41309+in 64 KB granularity (e.g. a value of 0x00FF specifies 256 = 16 MB).
41310+
41311+NOTE: A value of 0x0 specifies 64KB size.
41312+*/
41313+#define ATMWCR_WIN_SIZE_OFFS 16 /* Window Size */
41314+#define ATMWCR_WIN_SIZE_MASK (0xffff << ATMWCR_WIN_SIZE_OFFS)
41315+#define ATMWCR_WIN_SIZE_ALIGNMENT 0x10000
41316+
41317+/* Window Base Register */
41318+/* AHB_TO_MBUS_WIN_BASE_REG (ATMWBR) */
41319+
41320+/*
41321+Used with the size field to set the address window size and location.
41322+Corresponds to transaction address[31:16]
41323+*/
41324+#define ATMWBR_BASE_OFFS 16 /* Base Address */
41325+#define ATMWBR_BASE_MASK (0xffff << ATMWBR_BASE_OFFS)
41326+#define ATMWBR_BASE_ALIGNMENT 0x10000
41327+
41328+/* Window Remap Low Register */
41329+/* AHB_TO_MBUS_WIN_REMAP_LOW_REG (ATMWRLR) */
41330+
41331+/*
41332+Used with the size field to specifies address bits[31:0] to be driven to
41333+the target interface.:
41334+target_addr[31:16] = (addr[31:16] & size[15:0]) | (remap[31:16] & ~size[15:0])
41335+*/
41336+#define ATMWRLR_REMAP_LOW_OFFS 16 /* Remap Address */
41337+#define ATMWRLR_REMAP_LOW_MASK (0xffff << ATMWRLR_REMAP_LOW_OFFS)
41338+#define ATMWRLR_REMAP_LOW_ALIGNMENT 0x10000
41339+
41340+/* Window Remap High Register */
41341+/* AHB_TO_MBUS_WIN_REMAP_HIGH_REG (ATMWRHR) */
41342+
41343+/*
41344+Specifies address bits[63:32] to be driven to the target interface.
41345+target_addr[63:32] = (RemapHigh[31:0]
41346+*/
41347+#define ATMWRHR_REMAP_HIGH_OFFS 0 /* Remap Address */
41348+#define ATMWRHR_REMAP_HIGH_MASK (0xffffffff << ATMWRHR_REMAP_HIGH_OFFS)
41349+
41350+
41351+#endif /* __INCmvAhbToMbusRegsh */
41352+
41353diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c
41354new file mode 100644
41355index 0000000..396f003
41356--- /dev/null
41357+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c
41358@@ -0,0 +1,1036 @@
41359+/*******************************************************************************
41360+Copyright (C) Marvell International Ltd. and its affiliates
41361+
41362+This software file (the "File") is owned and distributed by Marvell
41363+International Ltd. and/or its affiliates ("Marvell") under the following
41364+alternative licensing terms. Once you have made an election to distribute the
41365+File under one of the following license alternatives, please (i) delete this
41366+introductory statement regarding license alternatives, (ii) delete the two
41367+license alternatives that you have not elected to use and (iii) preserve the
41368+Marvell copyright notice above.
41369+
41370+********************************************************************************
41371+Marvell Commercial License Option
41372+
41373+If you received this File from Marvell and you have entered into a commercial
41374+license agreement (a "Commercial License") with Marvell, the File is licensed
41375+to you under the terms of the applicable Commercial License.
41376+
41377+********************************************************************************
41378+Marvell GPL License Option
41379+
41380+If you received this File from Marvell, you may opt to use, redistribute and/or
41381+modify this File in accordance with the terms and conditions of the General
41382+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
41383+available along with the File in the license.txt file or by writing to the Free
41384+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
41385+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
41386+
41387+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
41388+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
41389+DISCLAIMED. The GPL License provides additional details about this warranty
41390+disclaimer.
41391+********************************************************************************
41392+Marvell BSD License Option
41393+
41394+If you received this File from Marvell, you may opt to use, redistribute and/or
41395+modify this File under the following licensing terms.
41396+Redistribution and use in source and binary forms, with or without modification,
41397+are permitted provided that the following conditions are met:
41398+
41399+ * Redistributions of source code must retain the above copyright notice,
41400+ this list of conditions and the following disclaimer.
41401+
41402+ * Redistributions in binary form must reproduce the above copyright
41403+ notice, this list of conditions and the following disclaimer in the
41404+ documentation and/or other materials provided with the distribution.
41405+
41406+ * Neither the name of Marvell nor the names of its contributors may be
41407+ used to endorse or promote products derived from this software without
41408+ specific prior written permission.
41409+
41410+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
41411+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
41412+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41413+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
41414+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41415+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
41416+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41417+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41418+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41419+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41420+
41421+*******************************************************************************/
41422+
41423+
41424+/* includes */
41425+#include "ctrlEnv/sys/mvCpuIf.h"
41426+#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
41427+#include "cpu/mvCpu.h"
41428+#include "ctrlEnv/mvCtrlEnvLib.h"
41429+#include "mvSysHwConfig.h"
41430+#include "mvSysDram.h"
41431+
41432+/*#define MV_DEBUG*/
41433+/* defines */
41434+
41435+#ifdef MV_DEBUG
41436+ #define DB(x) x
41437+#else
41438+ #define DB(x)
41439+#endif
41440+
41441+/* locals */
41442+/* static functions */
41443+static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
41444+
41445+MV_TARGET * sampleAtResetTargetArray;
41446+MV_TARGET sampleAtResetTargetArrayP[] = BOOT_TARGETS_NAME_ARRAY;
41447+MV_TARGET sampleAtResetTargetArray6180P[] = BOOT_TARGETS_NAME_ARRAY_6180;
41448+/*******************************************************************************
41449+* mvCpuIfInit - Initialize Controller CPU interface
41450+*
41451+* DESCRIPTION:
41452+* This function initialize Controller CPU interface:
41453+* 1. Set CPU interface configuration registers.
41454+* 2. Set CPU master Pizza arbiter control according to static
41455+* configuration described in configuration file.
41456+* 3. Opens CPU address decode windows. DRAM windows are assumed to be
41457+* already set (auto detection).
41458+*
41459+* INPUT:
41460+* None.
41461+*
41462+* OUTPUT:
41463+* None.
41464+*
41465+* RETURN:
41466+* None.
41467+*
41468+*******************************************************************************/
41469+MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap)
41470+{
41471+ MV_U32 regVal;
41472+ MV_TARGET target;
41473+ MV_ADDR_WIN addrWin;
41474+
41475+ if (cpuAddrWinMap == NULL)
41476+ {
41477+ DB(mvOsPrintf("mvCpuIfInit:ERR. cpuAddrWinMap == NULL\n"));
41478+ return MV_ERROR;
41479+ }
41480+
41481+ /*Initialize the boot target array according to device type*/
41482+ if(mvCtrlModelGet() == MV_6180_DEV_ID)
41483+ sampleAtResetTargetArray = sampleAtResetTargetArray6180P;
41484+ else
41485+ sampleAtResetTargetArray = sampleAtResetTargetArrayP;
41486+
41487+ /* Set ARM Configuration register */
41488+ regVal = MV_REG_READ(CPU_CONFIG_REG);
41489+ regVal &= ~CPU_CONFIG_DEFAULT_MASK;
41490+ regVal |= CPU_CONFIG_DEFAULT;
41491+ MV_REG_WRITE(CPU_CONFIG_REG,regVal);
41492+
41493+ /* First disable all CPU target windows */
41494+ for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
41495+ {
41496+ if ((MV_TARGET_IS_DRAM(target))||(target == INTER_REGS))
41497+ {
41498+ continue;
41499+ }
41500+
41501+#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
41502+ /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
41503+ if (MV_TARGET_IS_PCI(target))
41504+ {
41505+ continue;
41506+ }
41507+#endif
41508+
41509+#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
41510+ /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
41511+ if (MV_TARGET_IS_PEX(target))
41512+ {
41513+ continue;
41514+ }
41515+#endif
41516+#if defined(MV_RUN_FROM_FLASH)
41517+ /* Don't disable the boot device. */
41518+ if (target == DEV_BOOCS)
41519+ {
41520+ continue;
41521+ }
41522+#endif /* MV_RUN_FROM_FLASH */
41523+ mvCpuIfTargetWinEnable(MV_CHANGE_BOOT_CS(target),MV_FALSE);
41524+ }
41525+
41526+#if defined(MV_RUN_FROM_FLASH)
41527+ /* Resize the bootcs windows before other windows, because this */
41528+ /* window is enabled and will cause an overlap if not resized. */
41529+ target = DEV_BOOCS;
41530+
41531+ if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
41532+ {
41533+ DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
41534+ return MV_ERROR;
41535+ }
41536+
41537+ addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
41538+ addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
41539+ if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
41540+ {
41541+ DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
41542+ cpuAddrWinMap[target].winNum));
41543+ }
41544+
41545+#endif /* MV_RUN_FROM_FLASH */
41546+
41547+ /* Go through all targets in user table until table terminator */
41548+ for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
41549+ {
41550+
41551+#if defined(MV_RUN_FROM_FLASH)
41552+ if (target == DEV_BOOCS)
41553+ {
41554+ continue;
41555+ }
41556+#endif /* MV_RUN_FROM_FLASH */
41557+
41558+ /* if DRAM auto sizing is used do not initialized DRAM target windows, */
41559+ /* assuming this already has been done earlier. */
41560+#ifdef MV_DRAM_AUTO_SIZE
41561+ if (MV_TARGET_IS_DRAM(target))
41562+ {
41563+ continue;
41564+ }
41565+#endif
41566+
41567+#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
41568+ /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
41569+ if (MV_TARGET_IS_PCI(target))
41570+ {
41571+ continue;
41572+ }
41573+#endif
41574+
41575+#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
41576+ /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
41577+ if (MV_TARGET_IS_PEX(target))
41578+ {
41579+ continue;
41580+ }
41581+#endif
41582+ /* If the target attribute is the same as the boot device attribute */
41583+ /* then it's stays disable */
41584+ if (MV_TARGET_IS_AS_BOOT(target))
41585+ {
41586+ continue;
41587+ }
41588+
41589+ if((0 == cpuAddrWinMap[target].addrWin.size) ||
41590+ (DIS == cpuAddrWinMap[target].enable))
41591+
41592+ {
41593+ if (MV_OK != mvCpuIfTargetWinEnable(target, MV_FALSE))
41594+ {
41595+ DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinEnable fail\n"));
41596+ return MV_ERROR;
41597+ }
41598+
41599+ }
41600+ else
41601+ {
41602+ if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
41603+ {
41604+ DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
41605+ return MV_ERROR;
41606+ }
41607+
41608+ addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
41609+ addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
41610+ if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
41611+ {
41612+ DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
41613+ cpuAddrWinMap[target].winNum));
41614+ }
41615+
41616+
41617+ }
41618+ }
41619+
41620+ return MV_OK;
41621+
41622+
41623+}
41624+
41625+
41626+/*******************************************************************************
41627+* mvCpuIfTargetWinSet - Set CPU-to-peripheral target address window
41628+*
41629+* DESCRIPTION:
41630+* This function sets a peripheral target (e.g. SDRAM bank0, PCI0_MEM0)
41631+* address window, also known as address decode window.
41632+* A new address decode window is set for specified target address window.
41633+* If address decode window parameter structure enables the window,
41634+* the routine will also enable the target window, allowing CPU to access
41635+* the target window.
41636+*
41637+* INPUT:
41638+* target - Peripheral target enumerator.
41639+* pAddrDecWin - CPU target window data structure.
41640+*
41641+* OUTPUT:
41642+* N/A
41643+*
41644+* RETURN:
41645+* MV_OK if CPU target window was set correctly, MV_ERROR in case of
41646+* address window overlapps with other active CPU target window or
41647+* trying to assign 36bit base address while CPU does not support that.
41648+* The function returns MV_NOT_SUPPORTED, if the target is unsupported.
41649+*
41650+*******************************************************************************/
41651+MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)
41652+{
41653+ MV_AHB_TO_MBUS_DEC_WIN decWin;
41654+ MV_U32 existingWinNum;
41655+ MV_DRAM_DEC_WIN addrDecWin;
41656+
41657+ target = MV_CHANGE_BOOT_CS(target);
41658+
41659+ /* Check parameters */
41660+ if (target >= MAX_TARGETS)
41661+ {
41662+ mvOsPrintf("mvCpuIfTargetWinSet: target %d is Illigal\n", target);
41663+ return MV_ERROR;
41664+ }
41665+
41666+ /* 2) Check if the requested window overlaps with current windows */
41667+ if (MV_TRUE == cpuTargetWinOverlap(target, &pAddrDecWin->addrWin))
41668+ {
41669+ mvOsPrintf("mvCpuIfTargetWinSet: ERR. Target %d overlap\n", target);
41670+ return MV_BAD_PARAM;
41671+ }
41672+
41673+ if (MV_TARGET_IS_DRAM(target))
41674+ {
41675+ /* copy relevant data to MV_DRAM_DEC_WIN structure */
41676+ addrDecWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
41677+ addrDecWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
41678+ addrDecWin.addrWin.size = pAddrDecWin->addrWin.size;
41679+ addrDecWin.enable = pAddrDecWin->enable;
41680+
41681+
41682+ if (mvDramIfWinSet(target,&addrDecWin) != MV_OK);
41683+ {
41684+ mvOsPrintf("mvCpuIfTargetWinSet: mvDramIfWinSet Failed\n");
41685+ return MV_ERROR;
41686+ }
41687+
41688+ }
41689+ else
41690+ {
41691+ /* copy relevant data to MV_AHB_TO_MBUS_DEC_WIN structure */
41692+ decWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
41693+ decWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
41694+ decWin.addrWin.size = pAddrDecWin->addrWin.size;
41695+ decWin.enable = pAddrDecWin->enable;
41696+ decWin.target = target;
41697+
41698+ existingWinNum = mvAhbToMbusWinTargetGet(target);
41699+
41700+ /* check if there is already another Window configured
41701+ for this target */
41702+ if ((existingWinNum < MAX_AHB_TO_MBUS_WINS )&&
41703+ (existingWinNum != pAddrDecWin->winNum))
41704+ {
41705+ /* if we want to enable the new winow number
41706+ passed by the user , then the old one should
41707+ be disabled */
41708+ if (MV_TRUE == pAddrDecWin->enable)
41709+ {
41710+ /* be sure it is disabled */
41711+ mvAhbToMbusWinEnable(existingWinNum , MV_FALSE);
41712+ }
41713+ }
41714+
41715+ if (mvAhbToMbusWinSet(pAddrDecWin->winNum,&decWin) != MV_OK)
41716+ {
41717+ mvOsPrintf("mvCpuIfTargetWinSet: mvAhbToMbusWinSet Failed\n");
41718+ return MV_ERROR;
41719+ }
41720+
41721+ }
41722+
41723+ return MV_OK;
41724+}
41725+
41726+/*******************************************************************************
41727+* mvCpuIfTargetWinGet - Get CPU-to-peripheral target address window
41728+*
41729+* DESCRIPTION:
41730+* Get the CPU peripheral target address window.
41731+*
41732+* INPUT:
41733+* target - Peripheral target enumerator
41734+*
41735+* OUTPUT:
41736+* pAddrDecWin - CPU target window information data structure.
41737+*
41738+* RETURN:
41739+* MV_OK if target exist, MV_ERROR otherwise.
41740+*
41741+*******************************************************************************/
41742+MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)
41743+{
41744+
41745+ MV_U32 winNum=0xffffffff;
41746+ MV_AHB_TO_MBUS_DEC_WIN decWin;
41747+ MV_DRAM_DEC_WIN addrDecWin;
41748+
41749+ target = MV_CHANGE_BOOT_CS(target);
41750+
41751+ /* Check parameters */
41752+ if (target >= MAX_TARGETS)
41753+ {
41754+ mvOsPrintf("mvCpuIfTargetWinGet: target %d is Illigal\n", target);
41755+ return MV_ERROR;
41756+ }
41757+
41758+ if (MV_TARGET_IS_DRAM(target))
41759+ {
41760+ if (mvDramIfWinGet(target,&addrDecWin) != MV_OK)
41761+ {
41762+ mvOsPrintf("mvCpuIfTargetWinGet: Failed to get window target %d\n",
41763+ target);
41764+ return MV_ERROR;
41765+ }
41766+
41767+ /* copy relevant data to MV_CPU_DEC_WIN structure */
41768+ pAddrDecWin->addrWin.baseLow = addrDecWin.addrWin.baseLow;
41769+ pAddrDecWin->addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
41770+ pAddrDecWin->addrWin.size = addrDecWin.addrWin.size;
41771+ pAddrDecWin->enable = addrDecWin.enable;
41772+ pAddrDecWin->winNum = 0xffffffff;
41773+
41774+ }
41775+ else
41776+ {
41777+ /* get the Window number associated with this target */
41778+
41779+ winNum = mvAhbToMbusWinTargetGet(target);
41780+ if (winNum >= MAX_AHB_TO_MBUS_WINS)
41781+ {
41782+ return MV_NO_SUCH;
41783+
41784+ }
41785+
41786+ if (mvAhbToMbusWinGet(winNum , &decWin) != MV_OK)
41787+ {
41788+ mvOsPrintf("%s: mvAhbToMbusWinGet Failed at winNum = %d\n",
41789+ __FUNCTION__, winNum);
41790+ return MV_ERROR;
41791+
41792+ }
41793+
41794+ /* copy relevant data to MV_CPU_DEC_WIN structure */
41795+ pAddrDecWin->addrWin.baseLow = decWin.addrWin.baseLow;
41796+ pAddrDecWin->addrWin.baseHigh = decWin.addrWin.baseHigh;
41797+ pAddrDecWin->addrWin.size = decWin.addrWin.size;
41798+ pAddrDecWin->enable = decWin.enable;
41799+ pAddrDecWin->winNum = winNum;
41800+
41801+ }
41802+
41803+
41804+
41805+
41806+ return MV_OK;
41807+}
41808+
41809+
41810+/*******************************************************************************
41811+* mvCpuIfTargetWinEnable - Enable/disable a CPU address decode window
41812+*
41813+* DESCRIPTION:
41814+* This function enable/disable a CPU address decode window.
41815+* if parameter 'enable' == MV_TRUE the routine will enable the
41816+* window, thus enabling CPU accesses (before enabling the window it is
41817+* tested for overlapping). Otherwise, the window will be disabled.
41818+*
41819+* INPUT:
41820+* target - Peripheral target enumerator.
41821+* enable - Enable/disable parameter.
41822+*
41823+* OUTPUT:
41824+* N/A
41825+*
41826+* RETURN:
41827+* MV_ERROR if protection window number was wrong, or the window
41828+* overlapps other target window.
41829+*
41830+*******************************************************************************/
41831+MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable)
41832+{
41833+ MV_U32 winNum, temp;
41834+ MV_CPU_DEC_WIN addrDecWin;
41835+
41836+ target = MV_CHANGE_BOOT_CS(target);
41837+
41838+ /* Check parameters */
41839+ if (target >= MAX_TARGETS)
41840+ {
41841+ mvOsPrintf("mvCpuIfTargetWinEnable: target %d is Illigal\n", target);
41842+ return MV_ERROR;
41843+ }
41844+
41845+ /* get the window and check if it exist */
41846+ temp = mvCpuIfTargetWinGet(target, &addrDecWin);
41847+ if (MV_NO_SUCH == temp)
41848+ {
41849+ return (enable? MV_ERROR: MV_OK);
41850+ }
41851+ else if( MV_OK != temp)
41852+ {
41853+ mvOsPrintf("%s: ERR. Getting target %d failed.\n",__FUNCTION__, target);
41854+ return MV_ERROR;
41855+ }
41856+
41857+
41858+ /* check overlap */
41859+
41860+ if (MV_TRUE == enable)
41861+ {
41862+ if (MV_TRUE == cpuTargetWinOverlap(target, &addrDecWin.addrWin))
41863+ {
41864+ DB(mvOsPrintf("%s: ERR. Target %d overlap\n",__FUNCTION__, target));
41865+ return MV_ERROR;
41866+ }
41867+
41868+ }
41869+
41870+
41871+ if (MV_TARGET_IS_DRAM(target))
41872+ {
41873+ if (mvDramIfWinEnable(target , enable) != MV_OK)
41874+ {
41875+ mvOsPrintf("mvCpuIfTargetWinGet: mvDramIfWinEnable Failed at \n");
41876+ return MV_ERROR;
41877+
41878+ }
41879+
41880+ }
41881+ else
41882+ {
41883+ /* get the Window number associated with this target */
41884+
41885+ winNum = mvAhbToMbusWinTargetGet(target);
41886+
41887+ if (winNum >= MAX_AHB_TO_MBUS_WINS)
41888+ {
41889+ return (enable? MV_ERROR: MV_OK);
41890+ }
41891+
41892+ if (mvAhbToMbusWinEnable(winNum , enable) != MV_OK)
41893+ {
41894+ mvOsPrintf("mvCpuIfTargetWinGet: Failed to enable window = %d\n",
41895+ winNum);
41896+ return MV_ERROR;
41897+
41898+ }
41899+
41900+ }
41901+
41902+ return MV_OK;
41903+}
41904+
41905+
41906+/*******************************************************************************
41907+* mvCpuIfTargetWinSizeGet - Get CPU target address window size
41908+*
41909+* DESCRIPTION:
41910+* Get the size of CPU-to-peripheral target window.
41911+*
41912+* INPUT:
41913+* target - Peripheral target enumerator
41914+*
41915+* OUTPUT:
41916+* None.
41917+*
41918+* RETURN:
41919+* 32bit size. Function also returns '0' if window is closed.
41920+* Function returns 0xFFFFFFFF in case of an error.
41921+*
41922+*******************************************************************************/
41923+MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target)
41924+{
41925+ MV_CPU_DEC_WIN addrDecWin;
41926+
41927+ target = MV_CHANGE_BOOT_CS(target);
41928+
41929+ /* Check parameters */
41930+ if (target >= MAX_TARGETS)
41931+ {
41932+ mvOsPrintf("mvCpuIfTargetWinSizeGet: target %d is Illigal\n", target);
41933+ return 0;
41934+ }
41935+
41936+ /* Get the winNum window */
41937+ if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
41938+ {
41939+ mvOsPrintf("mvCpuIfTargetWinSizeGet:ERR. Getting target %d failed.\n",
41940+ target);
41941+ return 0;
41942+ }
41943+
41944+ /* Check if window is enabled */
41945+ if (addrDecWin.enable == MV_TRUE)
41946+ {
41947+ return (addrDecWin.addrWin.size);
41948+ }
41949+ else
41950+ {
41951+ return 0; /* Window disabled. return 0 */
41952+ }
41953+}
41954+
41955+/*******************************************************************************
41956+* mvCpuIfTargetWinBaseLowGet - Get CPU target address window base low
41957+*
41958+* DESCRIPTION:
41959+* CPU-to-peripheral target address window base is constructed of
41960+* two parts: Low and high.
41961+* This function gets the CPU peripheral target low base address.
41962+*
41963+* INPUT:
41964+* target - Peripheral target enumerator
41965+*
41966+* OUTPUT:
41967+* None.
41968+*
41969+* RETURN:
41970+* 32bit low base address.
41971+*
41972+*******************************************************************************/
41973+MV_U32 mvCpuIfTargetWinBaseLowGet(MV_TARGET target)
41974+{
41975+ MV_CPU_DEC_WIN addrDecWin;
41976+
41977+ target = MV_CHANGE_BOOT_CS(target);
41978+
41979+ /* Check parameters */
41980+ if (target >= MAX_TARGETS)
41981+ {
41982+ mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);
41983+ return 0xffffffff;
41984+ }
41985+
41986+ /* Get the target window */
41987+ if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
41988+ {
41989+ mvOsPrintf("mvCpuIfTargetWinBaseLowGet:ERR. Getting target %d failed.\n",
41990+ target);
41991+ return 0xffffffff;
41992+ }
41993+
41994+ if (MV_FALSE == addrDecWin.enable)
41995+ {
41996+ return 0xffffffff;
41997+ }
41998+ return (addrDecWin.addrWin.baseLow);
41999+}
42000+
42001+/*******************************************************************************
42002+* mvCpuIfTargetWinBaseHighGet - Get CPU target address window base high
42003+*
42004+* DESCRIPTION:
42005+* CPU-to-peripheral target address window base is constructed of
42006+* two parts: Low and high.
42007+* This function gets the CPU peripheral target high base address.
42008+*
42009+* INPUT:
42010+* target - Peripheral target enumerator
42011+*
42012+* OUTPUT:
42013+* None.
42014+*
42015+* RETURN:
42016+* 32bit high base address.
42017+*
42018+*******************************************************************************/
42019+MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target)
42020+{
42021+ MV_CPU_DEC_WIN addrDecWin;
42022+
42023+ target = MV_CHANGE_BOOT_CS(target);
42024+
42025+ /* Check parameters */
42026+ if (target >= MAX_TARGETS)
42027+ {
42028+ mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);
42029+ return 0xffffffff;
42030+ }
42031+
42032+ /* Get the target window */
42033+ if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
42034+ {
42035+ mvOsPrintf("mvCpuIfTargetWinBaseHighGet:ERR. Getting target %d failed.\n",
42036+ target);
42037+ return 0xffffffff;
42038+ }
42039+
42040+ if (MV_FALSE == addrDecWin.enable)
42041+ {
42042+ return 0;
42043+ }
42044+
42045+ return (addrDecWin.addrWin.baseHigh);
42046+}
42047+
42048+#if defined(MV_INCLUDE_PEX)
42049+/*******************************************************************************
42050+* mvCpuIfPexRemap - Set CPU remap register for address windows.
42051+*
42052+* DESCRIPTION:
42053+*
42054+* INPUT:
42055+* pexTarget - Peripheral target enumerator. Must be a PEX target.
42056+* pAddrDecWin - CPU target window information data structure.
42057+* Note that caller has to fill in the base field only. The
42058+* size field is ignored.
42059+*
42060+* OUTPUT:
42061+* None.
42062+*
42063+* RETURN:
42064+* MV_ERROR if target is not a PEX one, MV_OK otherwise.
42065+*
42066+*******************************************************************************/
42067+MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin)
42068+{
42069+ MV_U32 winNum;
42070+
42071+ /* Check parameters */
42072+
42073+ if (mvCtrlPexMaxIfGet() > 1)
42074+ {
42075+ if ((!MV_TARGET_IS_PEX1(pexTarget))&&(!MV_TARGET_IS_PEX0(pexTarget)))
42076+ {
42077+ mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);
42078+ return 0xffffffff;
42079+ }
42080+
42081+ }
42082+ else
42083+ {
42084+ if (!MV_TARGET_IS_PEX0(pexTarget))
42085+ {
42086+ mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);
42087+ return 0xffffffff;
42088+ }
42089+
42090+ }
42091+
42092+ /* get the Window number associated with this target */
42093+ winNum = mvAhbToMbusWinTargetGet(pexTarget);
42094+
42095+ if (winNum >= MAX_AHB_TO_MBUS_WINS)
42096+ {
42097+ mvOsPrintf("mvCpuIfPexRemap: mvAhbToMbusWinTargetGet Failed\n");
42098+ return 0xffffffff;
42099+
42100+ }
42101+
42102+ return mvAhbToMbusWinRemap(winNum , pAddrDecWin);
42103+}
42104+
42105+#endif
42106+
42107+#if defined(MV_INCLUDE_PCI)
42108+/*******************************************************************************
42109+* mvCpuIfPciRemap - Set CPU remap register for address windows.
42110+*
42111+* DESCRIPTION:
42112+*
42113+* INPUT:
42114+* pciTarget - Peripheral target enumerator. Must be a PCI target.
42115+* pAddrDecWin - CPU target window information data structure.
42116+* Note that caller has to fill in the base field only. The
42117+* size field is ignored.
42118+*
42119+* OUTPUT:
42120+* None.
42121+*
42122+* RETURN:
42123+* MV_ERROR if target is not a PCI one, MV_OK otherwise.
42124+*
42125+*******************************************************************************/
42126+MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin)
42127+{
42128+ MV_U32 winNum;
42129+
42130+ /* Check parameters */
42131+ if (!MV_TARGET_IS_PCI(pciTarget))
42132+ {
42133+ mvOsPrintf("mvCpuIfPciRemap: target %d is Illigal\n",pciTarget);
42134+ return 0xffffffff;
42135+ }
42136+
42137+ /* get the Window number associated with this target */
42138+ winNum = mvAhbToMbusWinTargetGet(pciTarget);
42139+
42140+ if (winNum >= MAX_AHB_TO_MBUS_WINS)
42141+ {
42142+ mvOsPrintf("mvCpuIfPciRemap: mvAhbToMbusWinTargetGet Failed\n");
42143+ return 0xffffffff;
42144+
42145+ }
42146+
42147+ return mvAhbToMbusWinRemap(winNum , pAddrDecWin);
42148+}
42149+#endif /* MV_INCLUDE_PCI */
42150+
42151+
42152+/*******************************************************************************
42153+* mvCpuIfPciIfRemap - Set CPU remap register for address windows.
42154+*
42155+* DESCRIPTION:
42156+*
42157+* INPUT:
42158+* pciTarget - Peripheral target enumerator. Must be a PCI target.
42159+* pAddrDecWin - CPU target window information data structure.
42160+* Note that caller has to fill in the base field only. The
42161+* size field is ignored.
42162+*
42163+* OUTPUT:
42164+* None.
42165+*
42166+* RETURN:
42167+* MV_ERROR if target is not a PCI one, MV_OK otherwise.
42168+*
42169+*******************************************************************************/
42170+MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciIfTarget, MV_ADDR_WIN *pAddrDecWin)
42171+{
42172+#if defined(MV_INCLUDE_PEX)
42173+ if (MV_TARGET_IS_PEX(pciIfTarget))
42174+ {
42175+ return mvCpuIfPexRemap(pciIfTarget,pAddrDecWin);
42176+ }
42177+#endif
42178+#if defined(MV_INCLUDE_PCI)
42179+
42180+ if (MV_TARGET_IS_PCI(pciIfTarget))
42181+ {
42182+ return mvCpuIfPciRemap(pciIfTarget,pAddrDecWin);
42183+ }
42184+#endif
42185+ return 0;
42186+}
42187+
42188+
42189+
42190+/*******************************************************************************
42191+* mvCpuIfTargetOfBaseAddressGet - Get the target according to base address
42192+*
42193+* DESCRIPTION:
42194+*
42195+* INPUT:
42196+* baseAddress - base address to be checked
42197+*
42198+* OUTPUT:
42199+* None.
42200+*
42201+* RETURN:
42202+* the target number that baseAddress belongs to or MAX_TARGETS is not
42203+* found
42204+*
42205+*******************************************************************************/
42206+
42207+MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress)
42208+{
42209+ MV_CPU_DEC_WIN win;
42210+ MV_U32 target;
42211+
42212+ for( target = 0; target < MAX_TARGETS; target++ )
42213+ {
42214+ if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )
42215+ {
42216+ if( win.enable )
42217+ {
42218+ if ((baseAddress >= win.addrWin.baseLow) &&
42219+ (baseAddress < win.addrWin.baseLow + win.addrWin.size)) break;
42220+ }
42221+ }
42222+ else return MAX_TARGETS;
42223+
42224+ }
42225+
42226+ return target;
42227+}
42228+/*******************************************************************************
42229+* cpuTargetWinOverlap - Detect CPU address decode windows overlapping
42230+*
42231+* DESCRIPTION:
42232+* An unpredicted behaviur is expected in case CPU address decode
42233+* windows overlapps.
42234+* This function detects CPU address decode windows overlapping of a
42235+* specified target. The function does not check the target itself for
42236+* overlapping. The function also skipps disabled address decode windows.
42237+*
42238+* INPUT:
42239+* target - Peripheral target enumerator.
42240+* pAddrDecWin - An address decode window struct.
42241+*
42242+* OUTPUT:
42243+* None.
42244+*
42245+* RETURN:
42246+* MV_TRUE if the given address window overlaps current address
42247+* decode map, MV_FALSE otherwise.
42248+*
42249+*******************************************************************************/
42250+static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
42251+{
42252+ MV_U32 targetNum;
42253+ MV_CPU_DEC_WIN addrDecWin;
42254+ MV_STATUS status;
42255+
42256+
42257+ for(targetNum = 0; targetNum < MAX_TARGETS; targetNum++)
42258+ {
42259+#if defined(MV_RUN_FROM_FLASH)
42260+ if(MV_TARGET_IS_AS_BOOT(target))
42261+ {
42262+ if (MV_CHANGE_BOOT_CS(targetNum) == target)
42263+ continue;
42264+ }
42265+#endif /* MV_RUN_FROM_FLASH */
42266+
42267+ /* don't check our target or illegal targets */
42268+ if (targetNum == target)
42269+ {
42270+ continue;
42271+ }
42272+
42273+ /* Get window parameters */
42274+ status = mvCpuIfTargetWinGet(targetNum, &addrDecWin);
42275+ if(MV_NO_SUCH == status)
42276+ {
42277+ continue;
42278+ }
42279+ if(MV_OK != status)
42280+ {
42281+ DB(mvOsPrintf("cpuTargetWinOverlap: ERR. TargetWinGet failed\n"));
42282+ return MV_TRUE;
42283+ }
42284+
42285+ /* Do not check disabled windows */
42286+ if (MV_FALSE == addrDecWin.enable)
42287+ {
42288+ continue;
42289+ }
42290+
42291+ if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
42292+ {
42293+ DB(mvOsPrintf(
42294+ "cpuTargetWinOverlap: Required target %d overlap current %d\n",
42295+ target, targetNum));
42296+ return MV_TRUE;
42297+ }
42298+ }
42299+
42300+ return MV_FALSE;
42301+
42302+}
42303+
42304+/*******************************************************************************
42305+* mvCpuIfAddDecShow - Print the CPU address decode map.
42306+*
42307+* DESCRIPTION:
42308+* This function print the CPU address decode map.
42309+*
42310+* INPUT:
42311+* None.
42312+*
42313+* OUTPUT:
42314+* None.
42315+*
42316+* RETURN:
42317+* None.
42318+*
42319+*******************************************************************************/
42320+MV_VOID mvCpuIfAddDecShow(MV_VOID)
42321+{
42322+ MV_CPU_DEC_WIN win;
42323+ MV_U32 target;
42324+ mvOsOutput( "\n" );
42325+ mvOsOutput( "CPU Interface\n" );
42326+ mvOsOutput( "-------------\n" );
42327+
42328+ for( target = 0; target < MAX_TARGETS; target++ )
42329+ {
42330+
42331+ memset( &win, 0, sizeof(MV_CPU_DEC_WIN) );
42332+
42333+ mvOsOutput( "%s ",mvCtrlTargetNameGet(target));
42334+ mvOsOutput( "...." );
42335+
42336+ if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )
42337+ {
42338+ if( win.enable )
42339+ {
42340+ mvOsOutput( "base %08x, ", win.addrWin.baseLow );
42341+ mvSizePrint( win.addrWin.size );
42342+ mvOsOutput( "\n" );
42343+
42344+ }
42345+ else
42346+ mvOsOutput( "disable\n" );
42347+ }
42348+ else if( mvCpuIfTargetWinGet( target, &win ) == MV_NO_SUCH )
42349+ {
42350+ mvOsOutput( "no such\n" );
42351+ }
42352+ }
42353+}
42354+
42355+/*******************************************************************************
42356+* mvCpuIfEnablePex - Enable PCI Express.
42357+*
42358+* DESCRIPTION:
42359+* This function Enable PCI Express.
42360+*
42361+* INPUT:
42362+* pexIf - PEX interface number.
42363+* pexType - MV_PEX_ROOT_COMPLEX - root complex device
42364+* MV_PEX_END_POINT - end point device
42365+* OUTPUT:
42366+* None.
42367+*
42368+* RETURN:
42369+* None.
42370+*
42371+*******************************************************************************/
42372+#if defined(MV_INCLUDE_PEX)
42373+MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType)
42374+{
42375+ /* Set pex mode incase S@R not exist */
42376+ if( pexType == MV_PEX_END_POINT)
42377+ {
42378+ MV_REG_BIT_RESET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
42379+ /* Change pex mode in capability reg */
42380+ MV_REG_BIT_RESET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT22);
42381+ MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT20);
42382+
42383+ }
42384+ else
42385+ {
42386+ MV_REG_BIT_SET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
42387+ }
42388+
42389+ /* CPU config register Pex enable */
42390+ MV_REG_BIT_SET(CPU_CTRL_STAT_REG,CCSR_PCI_ACCESS_MASK);
42391+}
42392+#endif
42393+
42394+
42395diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h
42396new file mode 100644
42397index 0000000..5755a40
42398--- /dev/null
42399+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h
42400@@ -0,0 +1,120 @@
42401+/*******************************************************************************
42402+Copyright (C) Marvell International Ltd. and its affiliates
42403+
42404+This software file (the "File") is owned and distributed by Marvell
42405+International Ltd. and/or its affiliates ("Marvell") under the following
42406+alternative licensing terms. Once you have made an election to distribute the
42407+File under one of the following license alternatives, please (i) delete this
42408+introductory statement regarding license alternatives, (ii) delete the two
42409+license alternatives that you have not elected to use and (iii) preserve the
42410+Marvell copyright notice above.
42411+
42412+********************************************************************************
42413+Marvell Commercial License Option
42414+
42415+If you received this File from Marvell and you have entered into a commercial
42416+license agreement (a "Commercial License") with Marvell, the File is licensed
42417+to you under the terms of the applicable Commercial License.
42418+
42419+********************************************************************************
42420+Marvell GPL License Option
42421+
42422+If you received this File from Marvell, you may opt to use, redistribute and/or
42423+modify this File in accordance with the terms and conditions of the General
42424+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
42425+available along with the File in the license.txt file or by writing to the Free
42426+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
42427+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
42428+
42429+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
42430+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
42431+DISCLAIMED. The GPL License provides additional details about this warranty
42432+disclaimer.
42433+********************************************************************************
42434+Marvell BSD License Option
42435+
42436+If you received this File from Marvell, you may opt to use, redistribute and/or
42437+modify this File under the following licensing terms.
42438+Redistribution and use in source and binary forms, with or without modification,
42439+are permitted provided that the following conditions are met:
42440+
42441+ * Redistributions of source code must retain the above copyright notice,
42442+ this list of conditions and the following disclaimer.
42443+
42444+ * Redistributions in binary form must reproduce the above copyright
42445+ notice, this list of conditions and the following disclaimer in the
42446+ documentation and/or other materials provided with the distribution.
42447+
42448+ * Neither the name of Marvell nor the names of its contributors may be
42449+ used to endorse or promote products derived from this software without
42450+ specific prior written permission.
42451+
42452+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
42453+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
42454+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42455+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
42456+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42457+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42458+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
42459+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42460+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42461+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42462+
42463+*******************************************************************************/
42464+
42465+
42466+#ifndef __INCmvCpuIfh
42467+#define __INCmvCpuIfh
42468+
42469+/* includes */
42470+#include "ctrlEnv/mvCtrlEnvLib.h"
42471+#include "ctrlEnv/sys/mvCpuIfRegs.h"
42472+#include "ctrlEnv/sys/mvAhbToMbus.h"
42473+#include "ddr2/mvDramIf.h"
42474+#include "ctrlEnv/sys/mvSysDram.h"
42475+#if defined(MV_INCLUDE_PEX)
42476+#include "pex/mvPex.h"
42477+#endif
42478+
42479+/* defines */
42480+
42481+/* typedefs */
42482+/* This structure describes CPU interface address decode window */
42483+typedef struct _mvCpuIfDecWin
42484+{
42485+ MV_ADDR_WIN addrWin; /* An address window*/
42486+ MV_U32 winNum; /* Window Number in the AHB To Mbus bridge */
42487+ MV_BOOL enable; /* Address decode window is enabled/disabled */
42488+
42489+}MV_CPU_DEC_WIN;
42490+
42491+
42492+
42493+/* mvCpuIfLib.h API list */
42494+
42495+/* mvCpuIfLib.h API list */
42496+
42497+MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap);
42498+MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);
42499+MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);
42500+MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable);
42501+MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target);
42502+MV_U32 mvCpuIfTargetWinBaseLowGet(MV_TARGET target);
42503+MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target);
42504+MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress);
42505+#if defined(MV_INCLUDE_PEX)
42506+MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin);
42507+MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType);
42508+#endif
42509+#if defined(MV_INCLUDE_PCI)
42510+MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);
42511+#endif
42512+MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);
42513+
42514+MV_VOID mvCpuIfAddDecShow(MV_VOID);
42515+
42516+#if defined(MV88F6281)
42517+MV_STATUS mvCpuIfBridgeReorderWAInit(void);
42518+#endif
42519+
42520+#endif /* __INCmvCpuIfh */
42521diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h
42522new file mode 100644
42523index 0000000..58c04c0
42524--- /dev/null
42525+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h
42526@@ -0,0 +1,304 @@
42527+/*******************************************************************************
42528+Copyright (C) Marvell International Ltd. and its affiliates
42529+
42530+This software file (the "File") is owned and distributed by Marvell
42531+International Ltd. and/or its affiliates ("Marvell") under the following
42532+alternative licensing terms. Once you have made an election to distribute the
42533+File under one of the following license alternatives, please (i) delete this
42534+introductory statement regarding license alternatives, (ii) delete the two
42535+license alternatives that you have not elected to use and (iii) preserve the
42536+Marvell copyright notice above.
42537+
42538+********************************************************************************
42539+Marvell Commercial License Option
42540+
42541+If you received this File from Marvell and you have entered into a commercial
42542+license agreement (a "Commercial License") with Marvell, the File is licensed
42543+to you under the terms of the applicable Commercial License.
42544+
42545+********************************************************************************
42546+Marvell GPL License Option
42547+
42548+If you received this File from Marvell, you may opt to use, redistribute and/or
42549+modify this File in accordance with the terms and conditions of the General
42550+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
42551+available along with the File in the license.txt file or by writing to the Free
42552+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
42553+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
42554+
42555+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
42556+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
42557+DISCLAIMED. The GPL License provides additional details about this warranty
42558+disclaimer.
42559+********************************************************************************
42560+Marvell BSD License Option
42561+
42562+If you received this File from Marvell, you may opt to use, redistribute and/or
42563+modify this File under the following licensing terms.
42564+Redistribution and use in source and binary forms, with or without modification,
42565+are permitted provided that the following conditions are met:
42566+
42567+ * Redistributions of source code must retain the above copyright notice,
42568+ this list of conditions and the following disclaimer.
42569+
42570+ * Redistributions in binary form must reproduce the above copyright
42571+ notice, this list of conditions and the following disclaimer in the
42572+ documentation and/or other materials provided with the distribution.
42573+
42574+ * Neither the name of Marvell nor the names of its contributors may be
42575+ used to endorse or promote products derived from this software without
42576+ specific prior written permission.
42577+
42578+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
42579+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
42580+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42581+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
42582+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42583+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42584+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
42585+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42586+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42587+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42588+
42589+*******************************************************************************/
42590+
42591+
42592+#ifndef __INCmvCpuIfRegsh
42593+#define __INCmvCpuIfRegsh
42594+
42595+/****************************************/
42596+/* ARM Control and Status Registers Map */
42597+/****************************************/
42598+
42599+#define CPU_CONFIG_REG 0x20100
42600+#define CPU_CTRL_STAT_REG 0x20104
42601+#define CPU_RSTOUTN_MASK_REG 0x20108
42602+#define CPU_SYS_SOFT_RST_REG 0x2010C
42603+#define CPU_AHB_MBUS_CAUSE_INT_REG 0x20110
42604+#define CPU_AHB_MBUS_MASK_INT_REG 0x20114
42605+#define CPU_FTDLL_CONFIG_REG 0x20120
42606+#define CPU_L2_CONFIG_REG 0x20128
42607+
42608+
42609+
42610+/* ARM Configuration register */
42611+/* CPU_CONFIG_REG (CCR) */
42612+
42613+
42614+/* Reset vector location */
42615+#define CCR_VEC_INIT_LOC_OFFS 1
42616+#define CCR_VEC_INIT_LOC_MASK BIT1
42617+/* reset at 0x00000000 */
42618+#define CCR_VEC_INIT_LOC_0000 (0 << CCR_VEC_INIT_LOC_OFFS)
42619+/* reset at 0xFFFF0000 */
42620+#define CCR_VEC_INIT_LOC_FF00 (1 << CCR_VEC_INIT_LOC_OFFS)
42621+
42622+
42623+#define CCR_AHB_ERROR_PROP_OFFS 2
42624+#define CCR_AHB_ERROR_PROP_MASK BIT2
42625+/* Erros are not propogated to AHB */
42626+#define CCR_AHB_ERROR_PROP_NO_INDICATE (0 << CCR_AHB_ERROR_PROP_OFFS)
42627+/* Erros are propogated to AHB */
42628+#define CCR_AHB_ERROR_PROP_INDICATE (1 << CCR_AHB_ERROR_PROP_OFFS)
42629+
42630+
42631+#define CCR_ENDIAN_INIT_OFFS 3
42632+#define CCR_ENDIAN_INIT_MASK BIT3
42633+#define CCR_ENDIAN_INIT_LITTLE (0 << CCR_ENDIAN_INIT_OFFS)
42634+#define CCR_ENDIAN_INIT_BIG (1 << CCR_ENDIAN_INIT_OFFS)
42635+
42636+
42637+#define CCR_INCR_EN_OFFS 4
42638+#define CCR_INCR_EN_MASK BIT4
42639+#define CCR_INCR_EN BIT4
42640+
42641+
42642+#define CCR_NCB_BLOCKING_OFFS 5
42643+#define CCR_NCB_BLOCKING_MASK (1 << CCR_NCB_BLOCKING_OFFS)
42644+#define CCR_NCB_BLOCKING_NON (0 << CCR_NCB_BLOCKING_OFFS)
42645+#define CCR_NCB_BLOCKING_EN (1 << CCR_NCB_BLOCKING_OFFS)
42646+
42647+#define CCR_CPU_2_MBUSL_TICK_DRV_OFFS 8
42648+#define CCR_CPU_2_MBUSL_TICK_DRV_MASK (0xF << CCR_CPU_2_MBUSL_TICK_DRV_OFFS)
42649+#define CCR_CPU_2_MBUSL_TICK_SMPL_OFFS 12
42650+#define CCR_CPU_2_MBUSL_TICK_SMPL_MASK (0xF << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS)
42651+#define CCR_ICACH_PREF_BUF_ENABLE BIT16
42652+#define CCR_DCACH_PREF_BUF_ENABLE BIT17
42653+
42654+/* Ratio options for CPU to DDR for 6281/6192/6190 */
42655+#define CPU_2_DDR_CLK_1x3 4
42656+#define CPU_2_DDR_CLK_1x4 6
42657+
42658+/* Ratio options for CPU to DDR for 6281 only */
42659+#define CPU_2_DDR_CLK_2x9 7
42660+#define CPU_2_DDR_CLK_1x5 8
42661+#define CPU_2_DDR_CLK_1x6 9
42662+
42663+/* Ratio options for CPU to DDR for 6180 only */
42664+#define CPU_2_DDR_CLK_1x3_1 0x5
42665+#define CPU_2_DDR_CLK_1x4_1 0x6
42666+
42667+/* Default values for CPU to Mbus-L DDR Interface Tick Driver and */
42668+/* CPU to Mbus-L Tick Sample fields in CPU config register */
42669+
42670+#define TICK_DRV_1x1 0
42671+#define TICK_DRV_1x2 0
42672+#define TICK_DRV_1x3 1
42673+#define TICK_DRV_1x4 2
42674+#define TICK_SMPL_1x1 0
42675+#define TICK_SMPL_1x2 1
42676+#define TICK_SMPL_1x3 0
42677+#define TICK_SMPL_1x4 0
42678+
42679+#define CPU_2_MBUSL_DDR_CLK_1x2 \
42680+ ((TICK_DRV_1x2 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
42681+ (TICK_SMPL_1x2 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
42682+#define CPU_2_MBUSL_DDR_CLK_1x3 \
42683+ ((TICK_DRV_1x3 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
42684+ (TICK_SMPL_1x3 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
42685+#define CPU_2_MBUSL_DDR_CLK_1x4 \
42686+ ((TICK_DRV_1x4 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
42687+ (TICK_SMPL_1x4 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
42688+
42689+/* ARM Control and Status register */
42690+/* CPU_CTRL_STAT_REG (CCSR) */
42691+
42692+
42693+/*
42694+This is used to block PCI express\PCI from access Socrates/Feroceon GP
42695+while ARM boot is still in progress
42696+*/
42697+
42698+#define CCSR_PCI_ACCESS_OFFS 0
42699+#define CCSR_PCI_ACCESS_MASK BIT0
42700+#define CCSR_PCI_ACCESS_ENABLE (0 << CCSR_PCI_ACCESS_OFFS)
42701+#define CCSR_PCI_ACCESS_DISBALE (1 << CCSR_PCI_ACCESS_OFFS)
42702+
42703+#define CCSR_ARM_RESET BIT1
42704+#define CCSR_SELF_INT BIT2
42705+#define CCSR_BIG_ENDIAN BIT15
42706+
42707+
42708+/* RSTOUTn Mask Register */
42709+/* CPU_RSTOUTN_MASK_REG (CRMR) */
42710+
42711+#define CRMR_PEX_RST_OUT_OFFS 0
42712+#define CRMR_PEX_RST_OUT_MASK BIT0
42713+#define CRMR_PEX_RST_OUT_ENABLE (1 << CRMR_PEX_RST_OUT_OFFS)
42714+#define CRMR_PEX_RST_OUT_DISABLE (0 << CRMR_PEX_RST_OUT_OFFS)
42715+
42716+#define CRMR_WD_RST_OUT_OFFS 1
42717+#define CRMR_WD_RST_OUT_MASK BIT1
42718+#define CRMR_WD_RST_OUT_ENABLE (1 << CRMR_WD_RST_OUT_OFFS)
42719+#define CRMR_WD_RST_OUT_DISBALE (0 << CRMR_WD_RST_OUT_OFFS)
42720+
42721+#define CRMR_SOFT_RST_OUT_OFFS 2
42722+#define CRMR_SOFT_RST_OUT_MASK BIT2
42723+#define CRMR_SOFT_RST_OUT_ENABLE (1 << CRMR_SOFT_RST_OUT_OFFS)
42724+#define CRMR_SOFT_RST_OUT_DISBALE (0 << CRMR_SOFT_RST_OUT_OFFS)
42725+
42726+/* System Software Reset Register */
42727+/* CPU_SYS_SOFT_RST_REG (CSSRR) */
42728+
42729+#define CSSRR_SYSTEM_SOFT_RST BIT0
42730+
42731+/* AHB to Mbus Bridge Interrupt Cause Register*/
42732+/* CPU_AHB_MBUS_CAUSE_INT_REG (CAMCIR) */
42733+
42734+#define CAMCIR_ARM_SELF_INT BIT0
42735+#define CAMCIR_ARM_TIMER0_INT_REQ BIT1
42736+#define CAMCIR_ARM_TIMER1_INT_REQ BIT2
42737+#define CAMCIR_ARM_WD_TIMER_INT_REQ BIT3
42738+
42739+
42740+/* AHB to Mbus Bridge Interrupt Mask Register*/
42741+/* CPU_AHB_MBUS_MASK_INT_REG (CAMMIR) */
42742+
42743+#define CAMCIR_ARM_SELF_INT_OFFS 0
42744+#define CAMCIR_ARM_SELF_INT_MASK BIT0
42745+#define CAMCIR_ARM_SELF_INT_EN (1 << CAMCIR_ARM_SELF_INT_OFFS)
42746+#define CAMCIR_ARM_SELF_INT_DIS (0 << CAMCIR_ARM_SELF_INT_OFFS)
42747+
42748+
42749+#define CAMCIR_ARM_TIMER0_INT_REQ_OFFS 1
42750+#define CAMCIR_ARM_TIMER0_INT_REQ_MASK BIT1
42751+#define CAMCIR_ARM_TIMER0_INT_REQ_EN (1 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS)
42752+#define CAMCIR_ARM_TIMER0_INT_REQ_DIS (0 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS)
42753+
42754+#define CAMCIR_ARM_TIMER1_INT_REQ_OFFS 2
42755+#define CAMCIR_ARM_TIMER1_INT_REQ_MASK BIT2
42756+#define CAMCIR_ARM_TIMER1_INT_REQ_EN (1 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS)
42757+#define CAMCIR_ARM_TIMER1_INT_REQ_DIS (0 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS)
42758+
42759+#define CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS 3
42760+#define CAMCIR_ARM_WD_TIMER_INT_REQ_MASK BIT3
42761+#define CAMCIR_ARM_WD_TIMER_INT_REQ_EN (1 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS)
42762+#define CAMCIR_ARM_WD_TIMER_INT_REQ_DIS (0 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS)
42763+
42764+/* CPU FTDLL Config register (CFCR) fields */
42765+#define CFCR_FTDLL_ICACHE_TAG_OFFS 0
42766+#define CFCR_FTDLL_ICACHE_TAG_MASK (0x7F << CFCR_FTDLL_ICACHE_TAG_OFFS)
42767+#define CFCR_FTDLL_DCACHE_TAG_OFFS 8
42768+#define CFCR_FTDLL_DCACHE_TAG_MASK (0x7F << CFCR_FTDLL_DCACHE_TAG_OFFS)
42769+#define CFCR_FTDLL_OVERWRITE_ENABLE (1 << 15)
42770+/* For Orion 2 D2 only */
42771+#define CFCR_MRVL_CPU_ID_OFFS 16
42772+#define CFCR_MRVL_CPU_ID_MASK (0x1 << CFCR_MRVL_CPU_ID_OFFS)
42773+#define CFCR_ARM_CPU_ID (0x0 << CFCR_MRVL_CPU_ID_OFFS)
42774+#define CFCR_MRVL_CPU_ID (0x1 << CFCR_MRVL_CPU_ID_OFFS)
42775+#define CFCR_VFP_SUB_ARC_NUM_OFFS 7
42776+#define CFCR_VFP_SUB_ARC_NUM_MASK (0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)
42777+#define CFCR_VFP_SUB_ARC_NUM_1 (0x0 << CFCR_VFP_SUB_ARC_NUM_OFFS)
42778+#define CFCR_VFP_SUB_ARC_NUM_2 (0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)
42779+
42780+/* CPU_L2_CONFIG_REG fields */
42781+#ifdef MV_CPU_LE
42782+#define CL2CR_L2_ECC_EN_OFFS 2
42783+#define CL2CR_L2_WT_MODE_OFFS 4
42784+#else
42785+#define CL2CR_L2_ECC_EN_OFFS 26
42786+#define CL2CR_L2_WT_MODE_OFFS 28
42787+#endif
42788+
42789+#define CL2CR_L2_ECC_EN_MASK (1 << CL2CR_L2_ECC_EN_OFFS)
42790+#define CL2CR_L2_WT_MODE_MASK (1 << CL2CR_L2_WT_MODE_OFFS)
42791+
42792+/*******************************************/
42793+/* Main Interrupt Controller Registers Map */
42794+/*******************************************/
42795+
42796+#define CPU_MAIN_INT_CAUSE_REG 0x20200
42797+#define CPU_MAIN_IRQ_MASK_REG 0x20204
42798+#define CPU_MAIN_FIQ_MASK_REG 0x20208
42799+#define CPU_ENPOINT_MASK_REG 0x2020C
42800+#define CPU_MAIN_INT_CAUSE_HIGH_REG 0x20210
42801+#define CPU_MAIN_IRQ_MASK_HIGH_REG 0x20214
42802+#define CPU_MAIN_FIQ_MASK_HIGH_REG 0x20218
42803+#define CPU_ENPOINT_MASK_HIGH_REG 0x2021C
42804+
42805+
42806+/*******************************************/
42807+/* ARM Doorbell Registers Map */
42808+/*******************************************/
42809+
42810+#define CPU_HOST_TO_ARM_DRBL_REG 0x20400
42811+#define CPU_HOST_TO_ARM_MASK_REG 0x20404
42812+#define CPU_ARM_TO_HOST_DRBL_REG 0x20408
42813+#define CPU_ARM_TO_HOST_MASK_REG 0x2040C
42814+
42815+
42816+
42817+/* CPU control register map */
42818+/* Set bits means value is about to change according to new value */
42819+#define CPU_CONFIG_DEFAULT_MASK (CCR_VEC_INIT_LOC_MASK | CCR_AHB_ERROR_PROP_MASK)
42820+
42821+#define CPU_CONFIG_DEFAULT (CCR_VEC_INIT_LOC_FF00)
42822+
42823+/* CPU Control and status defaults */
42824+#define CPU_CTRL_STAT_DEFAULT_MASK (CCSR_PCI_ACCESS_MASK)
42825+
42826+
42827+#define CPU_CTRL_STAT_DEFAULT (CCSR_PCI_ACCESS_ENABLE)
42828+
42829+#endif /* __INCmvCpuIfRegsh */
42830+
42831diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c
42832new file mode 100644
42833index 0000000..8475956
42834--- /dev/null
42835+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c
42836@@ -0,0 +1,324 @@
42837+/*******************************************************************************
42838+Copyright (C) Marvell International Ltd. and its affiliates
42839+
42840+This software file (the "File") is owned and distributed by Marvell
42841+International Ltd. and/or its affiliates ("Marvell") under the following
42842+alternative licensing terms. Once you have made an election to distribute the
42843+File under one of the following license alternatives, please (i) delete this
42844+introductory statement regarding license alternatives, (ii) delete the two
42845+license alternatives that you have not elected to use and (iii) preserve the
42846+Marvell copyright notice above.
42847+
42848+********************************************************************************
42849+Marvell Commercial License Option
42850+
42851+If you received this File from Marvell and you have entered into a commercial
42852+license agreement (a "Commercial License") with Marvell, the File is licensed
42853+to you under the terms of the applicable Commercial License.
42854+
42855+********************************************************************************
42856+Marvell GPL License Option
42857+
42858+If you received this File from Marvell, you may opt to use, redistribute and/or
42859+modify this File in accordance with the terms and conditions of the General
42860+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
42861+available along with the File in the license.txt file or by writing to the Free
42862+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
42863+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
42864+
42865+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
42866+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
42867+DISCLAIMED. The GPL License provides additional details about this warranty
42868+disclaimer.
42869+********************************************************************************
42870+Marvell BSD License Option
42871+
42872+If you received this File from Marvell, you may opt to use, redistribute and/or
42873+modify this File under the following licensing terms.
42874+Redistribution and use in source and binary forms, with or without modification,
42875+are permitted provided that the following conditions are met:
42876+
42877+ * Redistributions of source code must retain the above copyright notice,
42878+ this list of conditions and the following disclaimer.
42879+
42880+ * Redistributions in binary form must reproduce the above copyright
42881+ notice, this list of conditions and the following disclaimer in the
42882+ documentation and/or other materials provided with the distribution.
42883+
42884+ * Neither the name of Marvell nor the names of its contributors may be
42885+ used to endorse or promote products derived from this software without
42886+ specific prior written permission.
42887+
42888+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
42889+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
42890+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42891+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
42892+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42893+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42894+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
42895+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42896+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42897+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42898+
42899+*******************************************************************************/
42900+#include "mvSysAudio.h"
42901+
42902+/*******************************************************************************
42903+* mvAudioWinSet - Set AUDIO target address window
42904+*
42905+* DESCRIPTION:
42906+* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
42907+* address window, also known as address decode window.
42908+* After setting this target window, the AUDIO will be able to access the
42909+* target within the address window.
42910+*
42911+* INPUT:
42912+* winNum - AUDIO target address decode window number.
42913+* pAddrDecWin - AUDIO target window data structure.
42914+*
42915+* OUTPUT:
42916+* None.
42917+*
42918+* RETURN:
42919+* MV_ERROR if address window overlapps with other address decode windows.
42920+* MV_BAD_PARAM if base address is invalid parameter or target is
42921+* unknown.
42922+*
42923+*******************************************************************************/
42924+MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)
42925+{
42926+ MV_TARGET_ATTRIB targetAttribs;
42927+ MV_DEC_REGS decRegs;
42928+
42929+ /* Parameter checking */
42930+ if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)
42931+ {
42932+ mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
42933+ return MV_BAD_PARAM;
42934+ }
42935+
42936+ /* check if address is aligned to the size */
42937+ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
42938+ {
42939+ mvOsPrintf("mvAudioWinSet:Error setting AUDIO window %d to "\
42940+ "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
42941+ winNum,
42942+ mvCtrlTargetNameGet(pAddrDecWin->target),
42943+ pAddrDecWin->addrWin.baseLow,
42944+ pAddrDecWin->addrWin.size);
42945+ return MV_ERROR;
42946+ }
42947+
42948+ decRegs.baseReg = 0;
42949+ decRegs.sizeReg = 0;
42950+
42951+ if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
42952+ {
42953+ mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
42954+ return MV_ERROR;
42955+ }
42956+
42957+ mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
42958+
42959+ /* set attributes */
42960+ decRegs.sizeReg &= ~MV_AUDIO_WIN_ATTR_MASK;
42961+ decRegs.sizeReg |= (targetAttribs.attrib << MV_AUDIO_WIN_ATTR_OFFSET);
42962+
42963+ /* set target ID */
42964+ decRegs.sizeReg &= ~MV_AUDIO_WIN_TARGET_MASK;
42965+ decRegs.sizeReg |= (targetAttribs.targetId << MV_AUDIO_WIN_TARGET_OFFSET);
42966+
42967+ if (pAddrDecWin->enable == MV_TRUE)
42968+ {
42969+ decRegs.sizeReg |= MV_AUDIO_WIN_ENABLE_MASK;
42970+ }
42971+ else
42972+ {
42973+ decRegs.sizeReg &= ~MV_AUDIO_WIN_ENABLE_MASK;
42974+ }
42975+
42976+ MV_REG_WRITE( MV_AUDIO_WIN_CTRL_REG(winNum), decRegs.sizeReg);
42977+ MV_REG_WRITE( MV_AUDIO_WIN_BASE_REG(winNum), decRegs.baseReg);
42978+
42979+ return MV_OK;
42980+}
42981+
42982+/*******************************************************************************
42983+* mvAudioWinGet - Get AUDIO peripheral target address window.
42984+*
42985+* DESCRIPTION:
42986+* Get AUDIO peripheral target address window.
42987+*
42988+* INPUT:
42989+* winNum - AUDIO target address decode window number.
42990+*
42991+* OUTPUT:
42992+* pAddrDecWin - AUDIO target window data structure.
42993+*
42994+* RETURN:
42995+* MV_ERROR if register parameters are invalid.
42996+*
42997+*******************************************************************************/
42998+MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)
42999+{
43000+ MV_DEC_REGS decRegs;
43001+ MV_TARGET_ATTRIB targetAttrib;
43002+
43003+ /* Parameter checking */
43004+ if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)
43005+ {
43006+ mvOsPrintf("%s : ERR. Invalid winNum %d\n",
43007+ __FUNCTION__, winNum);
43008+ return MV_NOT_SUPPORTED;
43009+ }
43010+
43011+ decRegs.baseReg = MV_REG_READ( MV_AUDIO_WIN_BASE_REG(winNum) );
43012+ decRegs.sizeReg = MV_REG_READ( MV_AUDIO_WIN_CTRL_REG(winNum) );
43013+
43014+ if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
43015+ {
43016+ mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
43017+ return MV_ERROR;
43018+ }
43019+
43020+ /* attrib and targetId */
43021+ targetAttrib.attrib = (decRegs.sizeReg & MV_AUDIO_WIN_ATTR_MASK) >>
43022+ MV_AUDIO_WIN_ATTR_OFFSET;
43023+ targetAttrib.targetId = (decRegs.sizeReg & MV_AUDIO_WIN_TARGET_MASK) >>
43024+ MV_AUDIO_WIN_TARGET_OFFSET;
43025+
43026+ pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
43027+
43028+ /* Check if window is enabled */
43029+ if(decRegs.sizeReg & MV_AUDIO_WIN_ENABLE_MASK)
43030+ {
43031+ pAddrDecWin->enable = MV_TRUE;
43032+ }
43033+ else
43034+ {
43035+ pAddrDecWin->enable = MV_FALSE;
43036+ }
43037+ return MV_OK;
43038+}
43039+/*******************************************************************************
43040+* mvAudioAddrDecShow - Print the AUDIO address decode map.
43041+*
43042+* DESCRIPTION:
43043+* This function print the AUDIO address decode map.
43044+*
43045+* INPUT:
43046+* None.
43047+*
43048+* OUTPUT:
43049+* None.
43050+*
43051+* RETURN:
43052+* None.
43053+*
43054+*******************************************************************************/
43055+MV_VOID mvAudioAddrDecShow(MV_VOID)
43056+{
43057+
43058+ MV_AUDIO_DEC_WIN win;
43059+ int i;
43060+
43061+ if (MV_FALSE == mvCtrlPwrClckGet(AUDIO_UNIT_ID, 0))
43062+ return;
43063+
43064+
43065+ mvOsOutput( "\n" );
43066+ mvOsOutput( "AUDIO:\n" );
43067+ mvOsOutput( "----\n" );
43068+
43069+ for( i = 0; i < MV_AUDIO_MAX_ADDR_DECODE_WIN; i++ )
43070+ {
43071+ memset( &win, 0, sizeof(MV_AUDIO_DEC_WIN) );
43072+
43073+ mvOsOutput( "win%d - ", i );
43074+
43075+ if( mvAudioWinGet( i, &win ) == MV_OK )
43076+ {
43077+ if( win.enable )
43078+ {
43079+ mvOsOutput( "%s base %08x, ",
43080+ mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
43081+ mvOsOutput( "...." );
43082+
43083+ mvSizePrint( win.addrWin.size );
43084+
43085+ mvOsOutput( "\n" );
43086+ }
43087+ else
43088+ mvOsOutput( "disable\n" );
43089+ }
43090+ }
43091+}
43092+
43093+
43094+/*******************************************************************************
43095+* mvAudioWinInit - Initialize the integrated AUDIO target address window.
43096+*
43097+* DESCRIPTION:
43098+* Initialize the AUDIO peripheral target address window.
43099+*
43100+* INPUT:
43101+*
43102+*
43103+* OUTPUT:
43104+*
43105+*
43106+* RETURN:
43107+* MV_ERROR if register parameters are invalid.
43108+*
43109+*******************************************************************************/
43110+MV_STATUS mvAudioInit(MV_VOID)
43111+{
43112+ int winNum;
43113+ MV_AUDIO_DEC_WIN audioWin;
43114+ MV_CPU_DEC_WIN cpuAddrDecWin;
43115+ MV_U32 status;
43116+
43117+ mvAudioHalInit();
43118+
43119+ /* Initiate Audio address decode */
43120+
43121+ /* First disable all address decode windows */
43122+ for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)
43123+ {
43124+ MV_U32 regVal = MV_REG_READ(MV_AUDIO_WIN_CTRL_REG(winNum));
43125+ regVal &= ~MV_AUDIO_WIN_ENABLE_MASK;
43126+ MV_REG_WRITE(MV_AUDIO_WIN_CTRL_REG(winNum), regVal);
43127+ }
43128+
43129+ for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)
43130+ {
43131+
43132+ /* We will set the Window to DRAM_CS0 in default */
43133+ /* first get attributes from CPU If */
43134+ status = mvCpuIfTargetWinGet(SDRAM_CS0,
43135+ &cpuAddrDecWin);
43136+
43137+ if (MV_OK != status)
43138+ {
43139+ mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
43140+ return MV_ERROR;
43141+ }
43142+
43143+ if (cpuAddrDecWin.enable == MV_TRUE)
43144+ {
43145+ audioWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
43146+ audioWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
43147+ audioWin.addrWin.size = cpuAddrDecWin.addrWin.size;
43148+ audioWin.enable = MV_TRUE;
43149+ audioWin.target = SDRAM_CS0;
43150+
43151+ if(MV_OK != mvAudioWinSet(winNum, &audioWin))
43152+ {
43153+ return MV_ERROR;
43154+ }
43155+ }
43156+ }
43157+
43158+ return MV_OK;
43159+}
43160+
43161diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h
43162new file mode 100644
43163index 0000000..7e078ff
43164--- /dev/null
43165+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h
43166@@ -0,0 +1,123 @@
43167+/*******************************************************************************
43168+Copyright (C) Marvell International Ltd. and its affiliates
43169+
43170+This software file (the "File") is owned and distributed by Marvell
43171+International Ltd. and/or its affiliates ("Marvell") under the following
43172+alternative licensing terms. Once you have made an election to distribute the
43173+File under one of the following license alternatives, please (i) delete this
43174+introductory statement regarding license alternatives, (ii) delete the two
43175+license alternatives that you have not elected to use and (iii) preserve the
43176+Marvell copyright notice above.
43177+
43178+********************************************************************************
43179+Marvell Commercial License Option
43180+
43181+If you received this File from Marvell and you have entered into a commercial
43182+license agreement (a "Commercial License") with Marvell, the File is licensed
43183+to you under the terms of the applicable Commercial License.
43184+
43185+********************************************************************************
43186+Marvell GPL License Option
43187+
43188+If you received this File from Marvell, you may opt to use, redistribute and/or
43189+modify this File in accordance with the terms and conditions of the General
43190+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
43191+available along with the File in the license.txt file or by writing to the Free
43192+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
43193+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
43194+
43195+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
43196+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
43197+DISCLAIMED. The GPL License provides additional details about this warranty
43198+disclaimer.
43199+********************************************************************************
43200+Marvell BSD License Option
43201+
43202+If you received this File from Marvell, you may opt to use, redistribute and/or
43203+modify this File under the following licensing terms.
43204+Redistribution and use in source and binary forms, with or without modification,
43205+are permitted provided that the following conditions are met:
43206+
43207+ * Redistributions of source code must retain the above copyright notice,
43208+ this list of conditions and the following disclaimer.
43209+
43210+ * Redistributions in binary form must reproduce the above copyright
43211+ notice, this list of conditions and the following disclaimer in the
43212+ documentation and/or other materials provided with the distribution.
43213+
43214+ * Neither the name of Marvell nor the names of its contributors may be
43215+ used to endorse or promote products derived from this software without
43216+ specific prior written permission.
43217+
43218+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
43219+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43220+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43221+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
43222+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43223+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43224+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
43225+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43226+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43227+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43228+
43229+*******************************************************************************/
43230+#ifndef __INCMVSysAudioH
43231+#define __INCMVSysAudioH
43232+
43233+#include "mvCommon.h"
43234+#include "audio/mvAudio.h"
43235+#include "ctrlEnv/mvCtrlEnvSpec.h"
43236+#include "ctrlEnv/sys/mvCpuIf.h"
43237+
43238+/***********************************/
43239+/* Audio Address Decoding registers*/
43240+/***********************************/
43241+
43242+#define MV_AUDIO_MAX_ADDR_DECODE_WIN 2
43243+#define MV_AUDIO_RECORD_WIN_NUM 0
43244+#define MV_AUDIO_PLAYBACK_WIN_NUM 1
43245+
43246+#define MV_AUDIO_WIN_CTRL_REG(win) (AUDIO_REG_BASE + 0xA04 + ((win)<<3))
43247+#define MV_AUDIO_WIN_BASE_REG(win) (AUDIO_REG_BASE + 0xA00 + ((win)<<3))
43248+
43249+#define MV_AUDIO_RECORD_WIN_CTRL_REG MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_RECORD_WIN_NUM)
43250+#define MV_AUDIO_RECORD_WIN_BASE_REG MV_AUDIO_WIN_BASE_REG(MV_AUDIO_RECORD_WIN_NUM)
43251+#define MV_AUDIO_PLAYBACK_WIN_CTRL_REG MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_PLAYBACK_WIN_NUM)
43252+#define MV_AUDIO_PLAYBACK_WIN_BASE_REG MV_AUDIO_WIN_BASE_REG(MV_AUDIO_PLAYBACK_WIN_NUM)
43253+
43254+
43255+/* BITs in Windows 0-3 Control and Base Registers */
43256+#define MV_AUDIO_WIN_ENABLE_BIT 0
43257+#define MV_AUDIO_WIN_ENABLE_MASK (1<<MV_AUDIO_WIN_ENABLE_BIT)
43258+
43259+#define MV_AUDIO_WIN_TARGET_OFFSET 4
43260+#define MV_AUDIO_WIN_TARGET_MASK (0xF<<MV_AUDIO_WIN_TARGET_OFFSET)
43261+
43262+#define MV_AUDIO_WIN_ATTR_OFFSET 8
43263+#define MV_AUDIO_WIN_ATTR_MASK (0xFF<<MV_AUDIO_WIN_ATTR_OFFSET)
43264+
43265+#define MV_AUDIO_WIN_SIZE_OFFSET 16
43266+#define MV_AUDIO_WIN_SIZE_MASK (0xFFFF<<MV_AUDIO_WIN_SIZE_OFFSET)
43267+
43268+#define MV_AUDIO_WIN_BASE_OFFSET 16
43269+#define MV_AUDIO_WIN_BASE_MASK (0xFFFF<<MV_AUDIO_WIN_BASE_OFFSET)
43270+
43271+
43272+typedef struct _mvAudioDecWin
43273+{
43274+ MV_TARGET target;
43275+ MV_ADDR_WIN addrWin; /* An address window*/
43276+ MV_BOOL enable; /* Address decode window is enabled/disabled */
43277+
43278+} MV_AUDIO_DEC_WIN;
43279+
43280+
43281+MV_STATUS mvAudioInit(MV_VOID);
43282+MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);
43283+MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);
43284+MV_STATUS mvAudioWinInit(MV_VOID);
43285+MV_VOID mvAudioAddrDecShow(MV_VOID);
43286+
43287+
43288+#endif
43289+
43290diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c
43291new file mode 100644
43292index 0000000..9b50bae
43293--- /dev/null
43294+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c
43295@@ -0,0 +1,382 @@
43296+/*******************************************************************************
43297+Copyright (C) Marvell International Ltd. and its affiliates
43298+
43299+This software file (the "File") is owned and distributed by Marvell
43300+International Ltd. and/or its affiliates ("Marvell") under the following
43301+alternative licensing terms. Once you have made an election to distribute the
43302+File under one of the following license alternatives, please (i) delete this
43303+introductory statement regarding license alternatives, (ii) delete the two
43304+license alternatives that you have not elected to use and (iii) preserve the
43305+Marvell copyright notice above.
43306+
43307+********************************************************************************
43308+Marvell Commercial License Option
43309+
43310+If you received this File from Marvell and you have entered into a commercial
43311+license agreement (a "Commercial License") with Marvell, the File is licensed
43312+to you under the terms of the applicable Commercial License.
43313+
43314+********************************************************************************
43315+Marvell GPL License Option
43316+
43317+If you received this File from Marvell, you may opt to use, redistribute and/or
43318+modify this File in accordance with the terms and conditions of the General
43319+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
43320+available along with the File in the license.txt file or by writing to the Free
43321+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
43322+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
43323+
43324+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
43325+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
43326+DISCLAIMED. The GPL License provides additional details about this warranty
43327+disclaimer.
43328+********************************************************************************
43329+Marvell BSD License Option
43330+
43331+If you received this File from Marvell, you may opt to use, redistribute and/or
43332+modify this File under the following licensing terms.
43333+Redistribution and use in source and binary forms, with or without modification,
43334+are permitted provided that the following conditions are met:
43335+
43336+ * Redistributions of source code must retain the above copyright notice,
43337+ this list of conditions and the following disclaimer.
43338+
43339+ * Redistributions in binary form must reproduce the above copyright
43340+ notice, this list of conditions and the following disclaimer in the
43341+ documentation and/or other materials provided with the distribution.
43342+
43343+ * Neither the name of Marvell nor the names of its contributors may be
43344+ used to endorse or promote products derived from this software without
43345+ specific prior written permission.
43346+
43347+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
43348+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43349+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43350+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
43351+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43352+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43353+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
43354+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43355+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43356+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43357+
43358+*******************************************************************************/
43359+
43360+#include "mvSysCesa.h"
43361+
43362+#if (MV_CESA_VERSION >= 2)
43363+MV_TARGET tdmaAddrDecPrioTable[] =
43364+{
43365+#if defined(MV_INCLUDE_SDRAM_CS0)
43366+ SDRAM_CS0,
43367+#endif
43368+#if defined(MV_INCLUDE_SDRAM_CS1)
43369+ SDRAM_CS1,
43370+#endif
43371+#if defined(MV_INCLUDE_SDRAM_CS2)
43372+ SDRAM_CS2,
43373+#endif
43374+#if defined(MV_INCLUDE_SDRAM_CS3)
43375+ SDRAM_CS3,
43376+#endif
43377+#if defined(MV_INCLUDE_PEX)
43378+ PEX0_MEM,
43379+#endif
43380+
43381+ TBL_TERM
43382+};
43383+
43384+/*******************************************************************************
43385+* mvCesaWinGet - Get TDMA target address window.
43386+*
43387+* DESCRIPTION:
43388+* Get TDMA target address window.
43389+*
43390+* INPUT:
43391+* winNum - TDMA target address decode window number.
43392+*
43393+* OUTPUT:
43394+* pDecWin - TDMA target window data structure.
43395+*
43396+* RETURN:
43397+* MV_ERROR if register parameters are invalid.
43398+*
43399+*******************************************************************************/
43400+static MV_STATUS mvCesaWinGet(MV_U32 winNum, MV_DEC_WIN *pDecWin)
43401+{
43402+ MV_DEC_WIN_PARAMS winParam;
43403+ MV_U32 sizeReg, baseReg;
43404+
43405+ /* Parameter checking */
43406+ if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)
43407+ {
43408+ mvOsPrintf("%s : ERR. Invalid winNum %d\n",
43409+ __FUNCTION__, winNum);
43410+ return MV_NOT_SUPPORTED;
43411+ }
43412+
43413+ baseReg = MV_REG_READ( MV_CESA_TDMA_BASE_ADDR_REG(winNum) );
43414+ sizeReg = MV_REG_READ( MV_CESA_TDMA_WIN_CTRL_REG(winNum) );
43415+
43416+ /* Check if window is enabled */
43417+ if(sizeReg & MV_CESA_TDMA_WIN_ENABLE_MASK)
43418+ {
43419+ pDecWin->enable = MV_TRUE;
43420+
43421+ /* Extract window parameters from registers */
43422+ winParam.targetId = (sizeReg & MV_CESA_TDMA_WIN_TARGET_MASK) >> MV_CESA_TDMA_WIN_TARGET_OFFSET;
43423+ winParam.attrib = (sizeReg & MV_CESA_TDMA_WIN_ATTR_MASK) >> MV_CESA_TDMA_WIN_ATTR_OFFSET;
43424+ winParam.size = (sizeReg & MV_CESA_TDMA_WIN_SIZE_MASK) >> MV_CESA_TDMA_WIN_SIZE_OFFSET;
43425+ winParam.baseAddr = (baseReg & MV_CESA_TDMA_WIN_BASE_MASK);
43426+
43427+ /* Translate the decode window parameters to address decode struct */
43428+ if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))
43429+ {
43430+ mvOsPrintf("Failed to translate register parameters to CESA address" \
43431+ " decode window structure\n");
43432+ return MV_ERROR;
43433+ }
43434+ }
43435+ else
43436+ {
43437+ pDecWin->enable = MV_FALSE;
43438+ }
43439+ return MV_OK;
43440+}
43441+
43442+/*******************************************************************************
43443+* cesaWinOverlapDetect - Detect CESA TDMA address windows overlapping
43444+*
43445+* DESCRIPTION:
43446+* An unpredicted behaviur is expected in case TDMA address decode
43447+* windows overlapps.
43448+* This function detects TDMA address decode windows overlapping of a
43449+* specified window. The function does not check the window itself for
43450+* overlapping. The function also skipps disabled address decode windows.
43451+*
43452+* INPUT:
43453+* winNum - address decode window number.
43454+* pAddrDecWin - An address decode window struct.
43455+*
43456+* OUTPUT:
43457+* None.
43458+*
43459+* RETURN:
43460+* MV_TRUE - if the given address window overlap current address
43461+* decode map,
43462+* MV_FALSE - otherwise, MV_ERROR if reading invalid data
43463+* from registers.
43464+*
43465+*******************************************************************************/
43466+static MV_STATUS cesaWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
43467+{
43468+ MV_U32 winNumIndex;
43469+ MV_DEC_WIN addrDecWin;
43470+
43471+ for(winNumIndex=0; winNumIndex<MV_CESA_TDMA_ADDR_DEC_WIN; winNumIndex++)
43472+ {
43473+ /* Do not check window itself */
43474+ if (winNumIndex == winNum)
43475+ {
43476+ continue;
43477+ }
43478+
43479+ /* Get window parameters */
43480+ if (MV_OK != mvCesaWinGet(winNumIndex, &addrDecWin))
43481+ {
43482+ mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
43483+ return MV_ERROR;
43484+ }
43485+
43486+ /* Do not check disabled windows */
43487+ if(addrDecWin.enable == MV_FALSE)
43488+ {
43489+ continue;
43490+ }
43491+
43492+ if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
43493+ {
43494+ return MV_TRUE;
43495+ }
43496+ }
43497+ return MV_FALSE;
43498+}
43499+
43500+/*******************************************************************************
43501+* mvCesaTdmaWinSet - Set CESA TDMA target address window
43502+*
43503+* DESCRIPTION:
43504+* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
43505+* address window, also known as address decode window.
43506+* After setting this target window, the CESA TDMA will be able to access the
43507+* target within the address window.
43508+*
43509+* INPUT:
43510+* winNum - CESA TDMA target address decode window number.
43511+* pAddrDecWin - CESA TDMA target window data structure.
43512+*
43513+* OUTPUT:
43514+* None.
43515+*
43516+* RETURN:
43517+* MV_ERROR - if address window overlapps with other address decode windows.
43518+* MV_BAD_PARAM - if base address is invalid parameter or target is
43519+* unknown.
43520+*
43521+*******************************************************************************/
43522+static MV_STATUS mvCesaTdmaWinSet(MV_U32 winNum, MV_DEC_WIN *pDecWin)
43523+{
43524+ MV_DEC_WIN_PARAMS winParams;
43525+ MV_U32 sizeReg, baseReg;
43526+
43527+ /* Parameter checking */
43528+ if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)
43529+ {
43530+ mvOsPrintf("mvCesaTdmaWinSet: ERR. Invalid win num %d\n",winNum);
43531+ return MV_BAD_PARAM;
43532+ }
43533+
43534+ /* Check if the requested window overlapps with current windows */
43535+ if (MV_TRUE == cesaWinOverlapDetect(winNum, &pDecWin->addrWin))
43536+ {
43537+ mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
43538+ return MV_ERROR;
43539+ }
43540+
43541+ /* check if address is aligned to the size */
43542+ if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))
43543+ {
43544+ mvOsPrintf("mvCesaTdmaWinSet: Error setting CESA TDMA window %d to "\
43545+ "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
43546+ winNum,
43547+ mvCtrlTargetNameGet(pDecWin->target),
43548+ pDecWin->addrWin.baseLow,
43549+ pDecWin->addrWin.size);
43550+ return MV_ERROR;
43551+ }
43552+
43553+ if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))
43554+ {
43555+ mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);
43556+ return MV_ERROR;
43557+ }
43558+
43559+ /* set Size, Attributes and TargetID */
43560+ sizeReg = (((winParams.targetId << MV_CESA_TDMA_WIN_TARGET_OFFSET) & MV_CESA_TDMA_WIN_TARGET_MASK) |
43561+ ((winParams.attrib << MV_CESA_TDMA_WIN_ATTR_OFFSET) & MV_CESA_TDMA_WIN_ATTR_MASK) |
43562+ ((winParams.size << MV_CESA_TDMA_WIN_SIZE_OFFSET) & MV_CESA_TDMA_WIN_SIZE_MASK));
43563+
43564+ if (pDecWin->enable == MV_TRUE)
43565+ {
43566+ sizeReg |= MV_CESA_TDMA_WIN_ENABLE_MASK;
43567+ }
43568+ else
43569+ {
43570+ sizeReg &= ~MV_CESA_TDMA_WIN_ENABLE_MASK;
43571+ }
43572+
43573+ /* Update Base value */
43574+ baseReg = (winParams.baseAddr & MV_CESA_TDMA_WIN_BASE_MASK);
43575+
43576+ MV_REG_WRITE( MV_CESA_TDMA_WIN_CTRL_REG(winNum), sizeReg);
43577+ MV_REG_WRITE( MV_CESA_TDMA_BASE_ADDR_REG(winNum), baseReg);
43578+
43579+ return MV_OK;
43580+}
43581+
43582+
43583+static MV_STATUS mvCesaTdmaAddrDecInit (void)
43584+{
43585+ MV_U32 winNum;
43586+ MV_STATUS status;
43587+ MV_CPU_DEC_WIN cpuAddrDecWin;
43588+ MV_DEC_WIN cesaWin;
43589+ MV_U32 winPrioIndex = 0;
43590+
43591+ /* First disable all address decode windows */
43592+ for(winNum=0; winNum<MV_CESA_TDMA_ADDR_DEC_WIN; winNum++)
43593+ {
43594+ MV_REG_BIT_RESET(MV_CESA_TDMA_WIN_CTRL_REG(winNum), MV_CESA_TDMA_WIN_ENABLE_MASK);
43595+ }
43596+
43597+ /* Go through all windows in user table until table terminator */
43598+ winNum = 0;
43599+ while( (tdmaAddrDecPrioTable[winPrioIndex] != TBL_TERM) &&
43600+ (winNum < MV_CESA_TDMA_ADDR_DEC_WIN) ) {
43601+
43602+ /* first get attributes from CPU If */
43603+ status = mvCpuIfTargetWinGet(tdmaAddrDecPrioTable[winPrioIndex],
43604+ &cpuAddrDecWin);
43605+ if(MV_NO_SUCH == status){
43606+ winPrioIndex++;
43607+ continue;
43608+ }
43609+
43610+ if (MV_OK != status)
43611+ {
43612+ mvOsPrintf("cesaInit: TargetWinGet failed. winNum=%d, winIdx=%d, target=%d, status=0x%x\n",
43613+ winNum, winPrioIndex, tdmaAddrDecPrioTable[winPrioIndex], status);
43614+ return MV_ERROR;
43615+ }
43616+ if (cpuAddrDecWin.enable == MV_TRUE)
43617+ {
43618+ cesaWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
43619+ cesaWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
43620+ cesaWin.addrWin.size = cpuAddrDecWin.addrWin.size;
43621+ cesaWin.enable = MV_TRUE;
43622+ cesaWin.target = tdmaAddrDecPrioTable[winPrioIndex];
43623+
43624+#if defined(MV646xx)
43625+ /* Get the default attributes for that target window */
43626+ mvCtrlDefAttribGet(cesaWin.target, &cesaWin.addrWinAttr);
43627+#endif /* MV646xx */
43628+
43629+ if(MV_OK != mvCesaTdmaWinSet(winNum, &cesaWin))
43630+ {
43631+ mvOsPrintf("mvCesaTdmaWinSet FAILED: winNum=%d\n",
43632+ winNum);
43633+ return MV_ERROR;
43634+ }
43635+ winNum++;
43636+ }
43637+ winPrioIndex++;
43638+ }
43639+ return MV_OK;
43640+}
43641+#endif /* MV_CESA_VERSION >= 2 */
43642+
43643+
43644+
43645+
43646+MV_STATUS mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle)
43647+{
43648+ MV_U32 cesaCryptEngBase;
43649+ MV_CPU_DEC_WIN addrDecWin;
43650+
43651+ if(sizeof(MV_CESA_SRAM_MAP) > MV_CESA_SRAM_SIZE)
43652+ {
43653+ mvOsPrintf("mvCesaInit: Wrong SRAM map - %ld > %d\n",
43654+ sizeof(MV_CESA_SRAM_MAP), MV_CESA_SRAM_SIZE);
43655+ return MV_FAIL;
43656+ }
43657+#if 0
43658+ if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)
43659+ cesaCryptEngBase = addrDecWin.addrWin.baseLow;
43660+ else
43661+ {
43662+ mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");
43663+ return MV_ERROR;
43664+ }
43665+#else
43666+ cesaCryptEngBase = (MV_U32)pSramBase;
43667+#endif
43668+
43669+#if 0 /* Already done in the platform init */
43670+#if (MV_CESA_VERSION >= 2)
43671+ mvCesaTdmaAddrDecInit();
43672+#endif /* MV_CESA_VERSION >= 2 */
43673+#endif
43674+ return mvCesaHalInit(numOfSession, queueDepth, pSramBase, cesaCryptEngBase,
43675+ osHandle);
43676+
43677+}
43678diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h
43679new file mode 100644
43680index 0000000..9bc3fee
43681--- /dev/null
43682+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h
43683@@ -0,0 +1,100 @@
43684+/*******************************************************************************
43685+Copyright (C) Marvell International Ltd. and its affiliates
43686+
43687+This software file (the "File") is owned and distributed by Marvell
43688+International Ltd. and/or its affiliates ("Marvell") under the following
43689+alternative licensing terms. Once you have made an election to distribute the
43690+File under one of the following license alternatives, please (i) delete this
43691+introductory statement regarding license alternatives, (ii) delete the two
43692+license alternatives that you have not elected to use and (iii) preserve the
43693+Marvell copyright notice above.
43694+
43695+********************************************************************************
43696+Marvell Commercial License Option
43697+
43698+If you received this File from Marvell and you have entered into a commercial
43699+license agreement (a "Commercial License") with Marvell, the File is licensed
43700+to you under the terms of the applicable Commercial License.
43701+
43702+********************************************************************************
43703+Marvell GPL License Option
43704+
43705+If you received this File from Marvell, you may opt to use, redistribute and/or
43706+modify this File in accordance with the terms and conditions of the General
43707+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
43708+available along with the File in the license.txt file or by writing to the Free
43709+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
43710+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
43711+
43712+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
43713+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
43714+DISCLAIMED. The GPL License provides additional details about this warranty
43715+disclaimer.
43716+********************************************************************************
43717+Marvell BSD License Option
43718+
43719+If you received this File from Marvell, you may opt to use, redistribute and/or
43720+modify this File under the following licensing terms.
43721+Redistribution and use in source and binary forms, with or without modification,
43722+are permitted provided that the following conditions are met:
43723+
43724+ * Redistributions of source code must retain the above copyright notice,
43725+ this list of conditions and the following disclaimer.
43726+
43727+ * Redistributions in binary form must reproduce the above copyright
43728+ notice, this list of conditions and the following disclaimer in the
43729+ documentation and/or other materials provided with the distribution.
43730+
43731+ * Neither the name of Marvell nor the names of its contributors may be
43732+ used to endorse or promote products derived from this software without
43733+ specific prior written permission.
43734+
43735+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
43736+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43737+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43738+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
43739+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43740+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43741+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
43742+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43743+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43744+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43745+
43746+*******************************************************************************/
43747+
43748+#ifndef __mvSysCesa_h__
43749+#define __mvSysCesa_h__
43750+
43751+
43752+#include "mvCommon.h"
43753+#include "cesa/mvCesa.h"
43754+#include "ctrlEnv/mvCtrlEnvSpec.h"
43755+#include "ctrlEnv/sys/mvCpuIf.h"
43756+
43757+/***************************** TDMA Registers *************************************/
43758+
43759+#define MV_CESA_TDMA_ADDR_DEC_WIN 4
43760+
43761+#define MV_CESA_TDMA_BASE_ADDR_REG(win) (MV_CESA_TDMA_REG_BASE + 0xa00 + (win<<3))
43762+
43763+#define MV_CESA_TDMA_WIN_CTRL_REG(win) (MV_CESA_TDMA_REG_BASE + 0xa04 + (win<<3))
43764+
43765+#define MV_CESA_TDMA_WIN_ENABLE_BIT 0
43766+#define MV_CESA_TDMA_WIN_ENABLE_MASK (1 << MV_CESA_TDMA_WIN_ENABLE_BIT)
43767+
43768+#define MV_CESA_TDMA_WIN_TARGET_OFFSET 4
43769+#define MV_CESA_TDMA_WIN_TARGET_MASK (0xf << MV_CESA_TDMA_WIN_TARGET_OFFSET)
43770+
43771+#define MV_CESA_TDMA_WIN_ATTR_OFFSET 8
43772+#define MV_CESA_TDMA_WIN_ATTR_MASK (0xff << MV_CESA_TDMA_WIN_ATTR_OFFSET)
43773+
43774+#define MV_CESA_TDMA_WIN_SIZE_OFFSET 16
43775+#define MV_CESA_TDMA_WIN_SIZE_MASK (0xFFFF << MV_CESA_TDMA_WIN_SIZE_OFFSET)
43776+
43777+#define MV_CESA_TDMA_WIN_BASE_OFFSET 16
43778+#define MV_CESA_TDMA_WIN_BASE_MASK (0xFFFF << MV_CESA_TDMA_WIN_BASE_OFFSET)
43779+
43780+
43781+MV_STATUS mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle);
43782+
43783+#endif
43784diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c
43785new file mode 100644
43786index 0000000..7df47b3
43787--- /dev/null
43788+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c
43789@@ -0,0 +1,348 @@
43790+/*******************************************************************************
43791+Copyright (C) Marvell International Ltd. and its affiliates
43792+
43793+This software file (the "File") is owned and distributed by Marvell
43794+International Ltd. and/or its affiliates ("Marvell") under the following
43795+alternative licensing terms. Once you have made an election to distribute the
43796+File under one of the following license alternatives, please (i) delete this
43797+introductory statement regarding license alternatives, (ii) delete the two
43798+license alternatives that you have not elected to use and (iii) preserve the
43799+Marvell copyright notice above.
43800+
43801+********************************************************************************
43802+Marvell Commercial License Option
43803+
43804+If you received this File from Marvell and you have entered into a commercial
43805+license agreement (a "Commercial License") with Marvell, the File is licensed
43806+to you under the terms of the applicable Commercial License.
43807+
43808+********************************************************************************
43809+Marvell GPL License Option
43810+
43811+If you received this File from Marvell, you may opt to use, redistribute and/or
43812+modify this File in accordance with the terms and conditions of the General
43813+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
43814+available along with the File in the license.txt file or by writing to the Free
43815+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
43816+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
43817+
43818+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
43819+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
43820+DISCLAIMED. The GPL License provides additional details about this warranty
43821+disclaimer.
43822+********************************************************************************
43823+Marvell BSD License Option
43824+
43825+If you received this File from Marvell, you may opt to use, redistribute and/or
43826+modify this File under the following licensing terms.
43827+Redistribution and use in source and binary forms, with or without modification,
43828+are permitted provided that the following conditions are met:
43829+
43830+ * Redistributions of source code must retain the above copyright notice,
43831+ this list of conditions and the following disclaimer.
43832+
43833+ * Redistributions in binary form must reproduce the above copyright
43834+ notice, this list of conditions and the following disclaimer in the
43835+ documentation and/or other materials provided with the distribution.
43836+
43837+ * Neither the name of Marvell nor the names of its contributors may be
43838+ used to endorse or promote products derived from this software without
43839+ specific prior written permission.
43840+
43841+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
43842+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43843+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43844+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
43845+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43846+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43847+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
43848+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43849+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43850+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43851+
43852+*******************************************************************************/
43853+
43854+
43855+/* includes */
43856+
43857+#include "ddr2/mvDramIf.h"
43858+#include "ctrlEnv/sys/mvCpuIf.h"
43859+#include "ctrlEnv/sys/mvSysDram.h"
43860+
43861+/* #define MV_DEBUG */
43862+#ifdef MV_DEBUG
43863+#define DB(x) x
43864+#else
43865+#define DB(x)
43866+#endif
43867+
43868+static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
43869+
43870+/*******************************************************************************
43871+* mvDramIfWinSet - Set DRAM interface address decode window
43872+*
43873+* DESCRIPTION:
43874+* This function sets DRAM interface address decode window.
43875+*
43876+* INPUT:
43877+* target - System target. Use only SDRAM targets.
43878+* pAddrDecWin - SDRAM address window structure.
43879+*
43880+* OUTPUT:
43881+* None
43882+*
43883+* RETURN:
43884+* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
43885+* otherwise.
43886+*******************************************************************************/
43887+MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
43888+{
43889+ MV_U32 baseReg=0,sizeReg=0;
43890+ MV_U32 baseToReg=0 , sizeToReg=0;
43891+
43892+ /* Check parameters */
43893+ if (!MV_TARGET_IS_DRAM(target))
43894+ {
43895+ mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
43896+ return MV_BAD_PARAM;
43897+ }
43898+
43899+ /* Check if the requested window overlaps with current enabled windows */
43900+ if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
43901+ {
43902+ mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
43903+ return MV_BAD_PARAM;
43904+ }
43905+
43906+ /* check if address is aligned to the size */
43907+ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
43908+ {
43909+ mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
43910+ "\nAddress 0x%08x is unaligned to size 0x%x.\n",
43911+ target,
43912+ pAddrDecWin->addrWin.baseLow,
43913+ pAddrDecWin->addrWin.size);
43914+ return MV_ERROR;
43915+ }
43916+
43917+ /* read base register*/
43918+ baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));
43919+
43920+ /* read size register */
43921+ sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));
43922+
43923+ /* BaseLow[31:16] => base register [31:16] */
43924+ baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;
43925+
43926+ /* Write to address decode Base Address Register */
43927+ baseReg &= ~SCBAR_BASE_MASK;
43928+ baseReg |= baseToReg;
43929+
43930+ /* Translate the given window size to register format */
43931+ sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);
43932+
43933+ /* Size parameter validity check. */
43934+ if (-1 == sizeToReg)
43935+ {
43936+ mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
43937+ return MV_BAD_PARAM;
43938+ }
43939+
43940+ /* set size */
43941+ sizeReg &= ~SCSR_SIZE_MASK;
43942+ /* Size is located at upper 16 bits */
43943+ sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);
43944+
43945+ /* enable/Disable */
43946+ if (MV_TRUE == pAddrDecWin->enable)
43947+ {
43948+ sizeReg |= SCSR_WIN_EN;
43949+ }
43950+ else
43951+ {
43952+ sizeReg &= ~SCSR_WIN_EN;
43953+ }
43954+
43955+ /* 3) Write to address decode Base Address Register */
43956+ MV_REG_WRITE(SDRAM_BASE_ADDR_REG(0,target), baseReg);
43957+
43958+ /* Write to address decode Size Register */
43959+ MV_REG_WRITE(SDRAM_SIZE_REG(0,target), sizeReg);
43960+
43961+ return MV_OK;
43962+}
43963+/*******************************************************************************
43964+* mvDramIfWinGet - Get DRAM interface address decode window
43965+*
43966+* DESCRIPTION:
43967+* This function gets DRAM interface address decode window.
43968+*
43969+* INPUT:
43970+* target - System target. Use only SDRAM targets.
43971+*
43972+* OUTPUT:
43973+* pAddrDecWin - SDRAM address window structure.
43974+*
43975+* RETURN:
43976+* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
43977+* otherwise.
43978+*******************************************************************************/
43979+MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
43980+{
43981+ MV_U32 baseReg,sizeReg;
43982+ MV_U32 sizeRegVal;
43983+ /* Check parameters */
43984+ if (!MV_TARGET_IS_DRAM(target))
43985+ {
43986+ mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);
43987+ return MV_ERROR;
43988+ }
43989+
43990+ /* Read base and size registers */
43991+ sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));
43992+ baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));
43993+
43994+ sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;
43995+
43996+ pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,
43997+ SCSR_SIZE_ALIGNMENT);
43998+
43999+ /* Check if ctrlRegToSize returned OK */
44000+ if (-1 == pAddrDecWin->addrWin.size)
44001+ {
44002+ mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);
44003+ return MV_ERROR;
44004+ }
44005+
44006+ /* Extract base address */
44007+ /* Base register [31:16] ==> baseLow[31:16] */
44008+ pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;
44009+
44010+ pAddrDecWin->addrWin.baseHigh = 0;
44011+
44012+
44013+ if (sizeReg & SCSR_WIN_EN)
44014+ {
44015+ pAddrDecWin->enable = MV_TRUE;
44016+ }
44017+ else
44018+ {
44019+ pAddrDecWin->enable = MV_FALSE;
44020+ }
44021+
44022+ return MV_OK;
44023+}
44024+/*******************************************************************************
44025+* mvDramIfWinEnable - Enable/Disable SDRAM address decode window
44026+*
44027+* DESCRIPTION:
44028+* This function enable/Disable SDRAM address decode window.
44029+*
44030+* INPUT:
44031+* target - System target. Use only SDRAM targets.
44032+*
44033+* OUTPUT:
44034+* None.
44035+*
44036+* RETURN:
44037+* MV_ERROR in case function parameter are invalid, MV_OK otherewise.
44038+*
44039+*******************************************************************************/
44040+MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable)
44041+{
44042+ MV_DRAM_DEC_WIN addrDecWin;
44043+
44044+ /* Check parameters */
44045+ if (!MV_TARGET_IS_DRAM(target))
44046+ {
44047+ mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
44048+ return MV_ERROR;
44049+ }
44050+
44051+ if (enable == MV_TRUE)
44052+ { /* First check for overlap with other enabled windows */
44053+ if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
44054+ {
44055+ mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n",
44056+ target);
44057+ return MV_ERROR;
44058+ }
44059+ /* Check for overlapping */
44060+ if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
44061+ {
44062+ /* No Overlap. Enable address decode winNum window */
44063+ MV_REG_BIT_SET(SDRAM_SIZE_REG(0,target), SCSR_WIN_EN);
44064+ }
44065+ else
44066+ { /* Overlap detected */
44067+ mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
44068+ target);
44069+ return MV_ERROR;
44070+ }
44071+ }
44072+ else
44073+ { /* Disable address decode winNum window */
44074+ MV_REG_BIT_RESET(SDRAM_SIZE_REG(0, target), SCSR_WIN_EN);
44075+ }
44076+
44077+ return MV_OK;
44078+}
44079+
44080+/*******************************************************************************
44081+* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window
44082+*
44083+* DESCRIPTION:
44084+* This function scan each SDRAM address decode window to test if it
44085+* overlapps the given address windoow
44086+*
44087+* INPUT:
44088+* target - SDRAM target where the function skips checking.
44089+* pAddrDecWin - The tested address window for overlapping with
44090+* SDRAM windows.
44091+*
44092+* OUTPUT:
44093+* None.
44094+*
44095+* RETURN:
44096+* MV_TRUE if the given address window overlaps any enabled address
44097+* decode map, MV_FALSE otherwise.
44098+*
44099+*******************************************************************************/
44100+static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
44101+{
44102+ MV_TARGET targetNum;
44103+ MV_DRAM_DEC_WIN addrDecWin;
44104+
44105+ for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)
44106+ {
44107+ /* don't check our winNum or illegal targets */
44108+ if (targetNum == target)
44109+ {
44110+ continue;
44111+ }
44112+
44113+ /* Get window parameters */
44114+ if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))
44115+ {
44116+ mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
44117+ return MV_ERROR;
44118+ }
44119+
44120+ /* Do not check disabled windows */
44121+ if (MV_FALSE == addrDecWin.enable)
44122+ {
44123+ continue;
44124+ }
44125+
44126+ if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
44127+ {
44128+ mvOsPrintf(
44129+ "sdramIfWinOverlap: Required target %d overlap winNum %d\n",
44130+ target, targetNum);
44131+ return MV_TRUE;
44132+ }
44133+ }
44134+
44135+ return MV_FALSE;
44136+}
44137+
44138diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h
44139new file mode 100644
44140index 0000000..f16b947
44141--- /dev/null
44142+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h
44143@@ -0,0 +1,80 @@
44144+/*******************************************************************************
44145+Copyright (C) Marvell International Ltd. and its affiliates
44146+
44147+This software file (the "File") is owned and distributed by Marvell
44148+International Ltd. and/or its affiliates ("Marvell") under the following
44149+alternative licensing terms. Once you have made an election to distribute the
44150+File under one of the following license alternatives, please (i) delete this
44151+introductory statement regarding license alternatives, (ii) delete the two
44152+license alternatives that you have not elected to use and (iii) preserve the
44153+Marvell copyright notice above.
44154+
44155+********************************************************************************
44156+Marvell Commercial License Option
44157+
44158+If you received this File from Marvell and you have entered into a commercial
44159+license agreement (a "Commercial License") with Marvell, the File is licensed
44160+to you under the terms of the applicable Commercial License.
44161+
44162+********************************************************************************
44163+Marvell GPL License Option
44164+
44165+If you received this File from Marvell, you may opt to use, redistribute and/or
44166+modify this File in accordance with the terms and conditions of the General
44167+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
44168+available along with the File in the license.txt file or by writing to the Free
44169+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
44170+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
44171+
44172+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
44173+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
44174+DISCLAIMED. The GPL License provides additional details about this warranty
44175+disclaimer.
44176+********************************************************************************
44177+Marvell BSD License Option
44178+
44179+If you received this File from Marvell, you may opt to use, redistribute and/or
44180+modify this File under the following licensing terms.
44181+Redistribution and use in source and binary forms, with or without modification,
44182+are permitted provided that the following conditions are met:
44183+
44184+ * Redistributions of source code must retain the above copyright notice,
44185+ this list of conditions and the following disclaimer.
44186+
44187+ * Redistributions in binary form must reproduce the above copyright
44188+ notice, this list of conditions and the following disclaimer in the
44189+ documentation and/or other materials provided with the distribution.
44190+
44191+ * Neither the name of Marvell nor the names of its contributors may be
44192+ used to endorse or promote products derived from this software without
44193+ specific prior written permission.
44194+
44195+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
44196+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
44197+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44198+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
44199+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
44200+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44201+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
44202+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44203+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44204+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44205+
44206+*******************************************************************************/
44207+
44208+
44209+#ifndef __sysDram
44210+#define __sysDram
44211+
44212+/* This structure describes CPU interface address decode window */
44213+typedef struct _mvDramIfDecWin
44214+{
44215+ MV_ADDR_WIN addrWin; /* An address window*/
44216+ MV_BOOL enable; /* Address decode window is enabled/disabled */
44217+}MV_DRAM_DEC_WIN;
44218+
44219+MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
44220+MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
44221+MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable);
44222+
44223+#endif
44224diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c
44225new file mode 100644
44226index 0000000..663acd3
44227--- /dev/null
44228+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c
44229@@ -0,0 +1,658 @@
44230+/*******************************************************************************
44231+Copyright (C) Marvell International Ltd. and its affiliates
44232+
44233+This software file (the "File") is owned and distributed by Marvell
44234+International Ltd. and/or its affiliates ("Marvell") under the following
44235+alternative licensing terms. Once you have made an election to distribute the
44236+File under one of the following license alternatives, please (i) delete this
44237+introductory statement regarding license alternatives, (ii) delete the two
44238+license alternatives that you have not elected to use and (iii) preserve the
44239+Marvell copyright notice above.
44240+
44241+********************************************************************************
44242+Marvell Commercial License Option
44243+
44244+If you received this File from Marvell and you have entered into a commercial
44245+license agreement (a "Commercial License") with Marvell, the File is licensed
44246+to you under the terms of the applicable Commercial License.
44247+
44248+********************************************************************************
44249+Marvell GPL License Option
44250+
44251+If you received this File from Marvell, you may opt to use, redistribute and/or
44252+modify this File in accordance with the terms and conditions of the General
44253+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
44254+available along with the File in the license.txt file or by writing to the Free
44255+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
44256+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
44257+
44258+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
44259+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
44260+DISCLAIMED. The GPL License provides additional details about this warranty
44261+disclaimer.
44262+********************************************************************************
44263+Marvell BSD License Option
44264+
44265+If you received this File from Marvell, you may opt to use, redistribute and/or
44266+modify this File under the following licensing terms.
44267+Redistribution and use in source and binary forms, with or without modification,
44268+are permitted provided that the following conditions are met:
44269+
44270+ * Redistributions of source code must retain the above copyright notice,
44271+ this list of conditions and the following disclaimer.
44272+
44273+ * Redistributions in binary form must reproduce the above copyright
44274+ notice, this list of conditions and the following disclaimer in the
44275+ documentation and/or other materials provided with the distribution.
44276+
44277+ * Neither the name of Marvell nor the names of its contributors may be
44278+ used to endorse or promote products derived from this software without
44279+ specific prior written permission.
44280+
44281+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
44282+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
44283+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44284+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
44285+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
44286+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44287+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
44288+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44289+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44290+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44291+
44292+*******************************************************************************/
44293+
44294+
44295+#include "ctrlEnv/sys/mvSysGbe.h"
44296+
44297+
44298+
44299+typedef struct _mvEthDecWin
44300+{
44301+ MV_TARGET target;
44302+ MV_ADDR_WIN addrWin; /* An address window*/
44303+ MV_BOOL enable; /* Address decode window is enabled/disabled */
44304+
44305+}MV_ETH_DEC_WIN;
44306+
44307+MV_TARGET ethAddrDecPrioTap[] =
44308+{
44309+#if defined(MV_INCLUDE_SDRAM_CS0)
44310+ SDRAM_CS0,
44311+#endif
44312+#if defined(MV_INCLUDE_SDRAM_CS1)
44313+ SDRAM_CS1,
44314+#endif
44315+#if defined(MV_INCLUDE_SDRAM_CS2)
44316+ SDRAM_CS2,
44317+#endif
44318+#if defined(MV_INCLUDE_SDRAM_CS3)
44319+ SDRAM_CS3,
44320+#endif
44321+#if defined(MV_INCLUDE_DEVICE_CS0)
44322+ DEVICE_CS0,
44323+#endif
44324+#if defined(MV_INCLUDE_DEVICE_CS1)
44325+ DEVICE_CS1,
44326+#endif
44327+#if defined(MV_INCLUDE_DEVICE_CS2)
44328+ DEVICE_CS2,
44329+#endif
44330+#if defined(MV_INCLUDE_DEVICE_CS3)
44331+ DEVICE_CS3,
44332+#endif
44333+#if defined(MV_INCLUDE_PEX)
44334+ PEX0_IO,
44335+#endif
44336+ TBL_TERM
44337+};
44338+
44339+static MV_STATUS ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
44340+static MV_STATUS mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);
44341+static MV_STATUS mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);
44342+
44343+
44344+/*******************************************************************************
44345+* mvEthWinInit - Initialize ETH address decode windows
44346+*
44347+* DESCRIPTION:
44348+* This function initialize ETH window decode unit. It set the
44349+* default address decode windows of the unit.
44350+*
44351+* INPUT:
44352+* None.
44353+*
44354+* OUTPUT:
44355+* None.
44356+*
44357+* RETURN:
44358+* MV_ERROR if setting fail.
44359+*******************************************************************************/
44360+/* Configure EthDrv memory map registes. */
44361+MV_STATUS mvEthWinInit (int port)
44362+{
44363+ MV_U32 winNum, status, winPrioIndex=0, i, regVal=0;
44364+ MV_ETH_DEC_WIN ethWin;
44365+ MV_CPU_DEC_WIN cpuAddrDecWin;
44366+ static MV_U32 accessProtReg = 0;
44367+
44368+#if (MV_ETH_VERSION <= 1)
44369+ static MV_BOOL isFirst = MV_TRUE;
44370+
44371+ if(isFirst == MV_FALSE)
44372+ {
44373+ MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);
44374+ return MV_OK;
44375+ }
44376+ isFirst = MV_FALSE;
44377+#endif /* MV_GIGA_ETH_VERSION */
44378+
44379+ /* Initiate Ethernet address decode */
44380+
44381+ /* First disable all address decode windows */
44382+ for(winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)
44383+ {
44384+ regVal |= MV_BIT_MASK(winNum);
44385+ }
44386+ MV_REG_WRITE(ETH_BASE_ADDR_ENABLE_REG(port), regVal);
44387+
44388+ /* Go through all windows in user table until table terminator */
44389+ for (winNum=0; ((ethAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
44390+ (winNum < ETH_MAX_DECODE_WIN)); )
44391+ {
44392+ /* first get attributes from CPU If */
44393+ status = mvCpuIfTargetWinGet(ethAddrDecPrioTap[winPrioIndex],
44394+ &cpuAddrDecWin);
44395+
44396+ if(MV_NO_SUCH == status)
44397+ {
44398+ winPrioIndex++;
44399+ continue;
44400+ }
44401+ if (MV_OK != status)
44402+ {
44403+ mvOsPrintf("mvEthWinInit: ERR. mvCpuIfTargetWinGet failed\n");
44404+ return MV_ERROR;
44405+ }
44406+
44407+ if (cpuAddrDecWin.enable == MV_TRUE)
44408+ {
44409+ ethWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
44410+ ethWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
44411+ ethWin.addrWin.size = cpuAddrDecWin.addrWin.size;
44412+ ethWin.enable = MV_TRUE;
44413+ ethWin.target = ethAddrDecPrioTap[winPrioIndex];
44414+
44415+ if(MV_OK != mvEthWinSet(port, winNum, &ethWin))
44416+ {
44417+ mvOsPrintf("mvEthWinInit: ERR. mvEthWinSet failed winNum=%d\n",
44418+ winNum);
44419+ return MV_ERROR;
44420+ }
44421+ winNum++;
44422+ }
44423+ winPrioIndex ++;
44424+ }
44425+
44426+ /* set full access to all windows. */
44427+ for(i=0; i<winNum; i++)
44428+ {
44429+ accessProtReg |= (FULL_ACCESS << (i*2));
44430+ }
44431+ MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);
44432+
44433+ return MV_OK;
44434+}
44435+
44436+/*******************************************************************************
44437+* mvEthWinSet - Set ETH target address window
44438+*
44439+* DESCRIPTION:
44440+* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
44441+* address window, also known as address decode window.
44442+* After setting this target window, the ETH will be able to access the
44443+* target within the address window.
44444+*
44445+* INPUT:
44446+* winNum - ETH to target address decode window number.
44447+* pAddrDecWin - ETH target window data structure.
44448+*
44449+* OUTPUT:
44450+* None.
44451+*
44452+* RETURN:
44453+* MV_ERROR if address window overlapps with other address decode windows.
44454+* MV_BAD_PARAM if base address is invalid parameter or target is
44455+* unknown.
44456+*
44457+*******************************************************************************/
44458+MV_STATUS mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)
44459+{
44460+ MV_TARGET_ATTRIB targetAttribs;
44461+ MV_DEC_REGS decRegs;
44462+
44463+ /* Parameter checking */
44464+ if (winNum >= ETH_MAX_DECODE_WIN)
44465+ {
44466+ mvOsPrintf("mvEthWinSet: ERR. Invalid win num %d\n",winNum);
44467+ return MV_BAD_PARAM;
44468+ }
44469+
44470+ /* Check if the requested window overlapps with current windows */
44471+ if (MV_TRUE == ethWinOverlapDetect(port, winNum, &pAddrDecWin->addrWin))
44472+ {
44473+ mvOsPrintf("mvEthWinSet: ERR. Window %d overlap\n", winNum);
44474+ return MV_ERROR;
44475+ }
44476+
44477+ /* check if address is aligned to the size */
44478+ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
44479+ {
44480+ mvOsPrintf("mvEthWinSet: Error setting Ethernet window %d to "\
44481+ "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
44482+ winNum,
44483+ mvCtrlTargetNameGet(pAddrDecWin->target),
44484+ pAddrDecWin->addrWin.baseLow,
44485+ pAddrDecWin->addrWin.size);
44486+ return MV_ERROR;
44487+ }
44488+
44489+
44490+ decRegs.baseReg = MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));
44491+ decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));
44492+
44493+ if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
44494+ {
44495+ mvOsPrintf("mvEthWinSet:mvCtrlAddrDecToReg Failed\n");
44496+ return MV_ERROR;
44497+ }
44498+
44499+ mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
44500+
44501+ /* set attributes */
44502+ decRegs.baseReg &= ~ETH_WIN_ATTR_MASK;
44503+ decRegs.baseReg |= targetAttribs.attrib << ETH_WIN_ATTR_OFFS;
44504+ /* set target ID */
44505+ decRegs.baseReg &= ~ETH_WIN_TARGET_MASK;
44506+ decRegs.baseReg |= targetAttribs.targetId << ETH_WIN_TARGET_OFFS;
44507+
44508+ /* for the safe side we disable the window before writing the new
44509+ values */
44510+ mvEthWinEnable(port, winNum, MV_FALSE);
44511+ MV_REG_WRITE(ETH_WIN_BASE_REG(port, winNum), decRegs.baseReg);
44512+
44513+ /* Write to address decode Size Register */
44514+ MV_REG_WRITE(ETH_WIN_SIZE_REG(port, winNum), decRegs.sizeReg);
44515+
44516+ /* Enable address decode target window */
44517+ if (pAddrDecWin->enable == MV_TRUE)
44518+ {
44519+ mvEthWinEnable(port, winNum, MV_TRUE);
44520+ }
44521+
44522+ return MV_OK;
44523+}
44524+
44525+/*******************************************************************************
44526+* mvETHWinGet - Get dma peripheral target address window.
44527+*
44528+* DESCRIPTION:
44529+* Get ETH peripheral target address window.
44530+*
44531+* INPUT:
44532+* winNum - ETH to target address decode window number.
44533+*
44534+* OUTPUT:
44535+* pAddrDecWin - ETH target window data structure.
44536+*
44537+* RETURN:
44538+* MV_ERROR if register parameters are invalid.
44539+*
44540+*******************************************************************************/
44541+MV_STATUS mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)
44542+{
44543+ MV_DEC_REGS decRegs;
44544+ MV_TARGET_ATTRIB targetAttrib;
44545+
44546+ /* Parameter checking */
44547+ if (winNum >= ETH_MAX_DECODE_WIN)
44548+ {
44549+ mvOsPrintf("mvEthWinGet: ERR. Invalid winNum %d\n", winNum);
44550+ return MV_NOT_SUPPORTED;
44551+ }
44552+
44553+ decRegs.baseReg = MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));
44554+ decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));
44555+
44556+ if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
44557+ {
44558+ mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");
44559+ return MV_ERROR;
44560+ }
44561+
44562+ /* attrib and targetId */
44563+ targetAttrib.attrib =
44564+ (decRegs.baseReg & ETH_WIN_ATTR_MASK) >> ETH_WIN_ATTR_OFFS;
44565+ targetAttrib.targetId =
44566+ (decRegs.baseReg & ETH_WIN_TARGET_MASK) >> ETH_WIN_TARGET_OFFS;
44567+
44568+ pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
44569+
44570+ /* Check if window is enabled */
44571+ if (~(MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port))) & (1 << winNum) )
44572+ {
44573+ pAddrDecWin->enable = MV_TRUE;
44574+ }
44575+ else
44576+ {
44577+ pAddrDecWin->enable = MV_FALSE;
44578+ }
44579+
44580+ return MV_OK;
44581+}
44582+
44583+/*******************************************************************************
44584+* mvEthWinEnable - Enable/disable a ETH to target address window
44585+*
44586+* DESCRIPTION:
44587+* This function enable/disable a ETH to target address window.
44588+* According to parameter 'enable' the routine will enable the
44589+* window, thus enabling ETH accesses (before enabling the window it is
44590+* tested for overlapping). Otherwise, the window will be disabled.
44591+*
44592+* INPUT:
44593+* winNum - ETH to target address decode window number.
44594+* enable - Enable/disable parameter.
44595+*
44596+* OUTPUT:
44597+* N/A
44598+*
44599+* RETURN:
44600+* MV_ERROR if decode window number was wrong or enabled window overlapps.
44601+*
44602+*******************************************************************************/
44603+MV_STATUS mvEthWinEnable(int port, MV_U32 winNum,MV_BOOL enable)
44604+{
44605+ MV_ETH_DEC_WIN addrDecWin;
44606+
44607+ /* Parameter checking */
44608+ if (winNum >= ETH_MAX_DECODE_WIN)
44609+ {
44610+ mvOsPrintf("mvEthTargetWinEnable:ERR. Invalid winNum%d\n",winNum);
44611+ return MV_ERROR;
44612+ }
44613+
44614+ if (enable == MV_TRUE)
44615+ { /* First check for overlap with other enabled windows */
44616+ /* Get current window */
44617+ if (MV_OK != mvEthWinGet(port, winNum, &addrDecWin))
44618+ {
44619+ mvOsPrintf("mvEthTargetWinEnable:ERR. targetWinGet fail\n");
44620+ return MV_ERROR;
44621+ }
44622+ /* Check for overlapping */
44623+ if (MV_FALSE == ethWinOverlapDetect(port, winNum, &(addrDecWin.addrWin)))
44624+ {
44625+ /* No Overlap. Enable address decode target window */
44626+ MV_REG_BIT_RESET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));
44627+ }
44628+ else
44629+ { /* Overlap detected */
44630+ mvOsPrintf("mvEthTargetWinEnable:ERR. Overlap detected\n");
44631+ return MV_ERROR;
44632+ }
44633+ }
44634+ else
44635+ { /* Disable address decode target window */
44636+ MV_REG_BIT_SET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));
44637+ }
44638+ return MV_OK;
44639+}
44640+
44641+/*******************************************************************************
44642+* mvEthWinTargetGet - Get Window number associated with target
44643+*
44644+* DESCRIPTION:
44645+*
44646+* INPUT:
44647+*
44648+* OUTPUT:
44649+*
44650+* RETURN:
44651+* window number
44652+*
44653+*******************************************************************************/
44654+MV_U32 mvEthWinTargetGet(int port, MV_TARGET target)
44655+{
44656+ MV_ETH_DEC_WIN decWin;
44657+ MV_U32 winNum;
44658+
44659+ /* Check parameters */
44660+ if (target >= MAX_TARGETS)
44661+ {
44662+ mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);
44663+ return 0xffffffff;
44664+ }
44665+
44666+ for (winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)
44667+ {
44668+ if (mvEthWinGet(port, winNum,&decWin) != MV_OK)
44669+ {
44670+ mvOsPrintf("mvAhbToMbusWinTargetGet: window returned error\n");
44671+ return 0xffffffff;
44672+ }
44673+
44674+ if (decWin.enable == MV_TRUE)
44675+ {
44676+ if (decWin.target == target)
44677+ {
44678+ return winNum;
44679+ }
44680+ }
44681+ }
44682+ return 0xFFFFFFFF;
44683+}
44684+
44685+/*******************************************************************************
44686+* mvEthProtWinSet - Set access protection of Ethernet to target window.
44687+*
44688+* DESCRIPTION:
44689+* Each Ethernet port can be configured with access attributes for each
44690+* of the Ethenret to target windows (address decode windows). This
44691+* function sets access attributes to a given window for the given channel.
44692+*
44693+* INPUTS:
44694+* ethPort - ETH channel number. See MV_ETH_CHANNEL enumerator.
44695+* winNum - IETH to target address decode window number.
44696+* access - IETH access rights. See MV_ACCESS_RIGHTS enumerator.
44697+*
44698+* OUTPUT:
44699+* None.
44700+*
44701+* RETURN:
44702+* MV_ERROR in case window number is invalid or access right reserved.
44703+*
44704+*******************************************************************************/
44705+MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS access)
44706+{
44707+ MV_U32 protReg;
44708+
44709+ /* Parameter checking */
44710+ if(portNo >= mvCtrlEthMaxPortGet())
44711+ {
44712+ mvOsPrintf("mvEthProtWinSet:ERR. Invalid port number %d\n", portNo);
44713+ return MV_ERROR;
44714+ }
44715+
44716+ if (winNum >= ETH_MAX_DECODE_WIN)
44717+ {
44718+ mvOsPrintf("mvEthProtWinSet:ERR. Invalid winNum%d\n",winNum);
44719+ return MV_ERROR;
44720+ }
44721+
44722+ if((access == ACC_RESERVED) || (access >= MAX_ACC_RIGHTS))
44723+ {
44724+ mvOsPrintf("mvEthProtWinSet:ERR. Inv access param %d\n", access);
44725+ return MV_ERROR;
44726+ }
44727+ /* Read current protection register */
44728+ protReg = MV_REG_READ(ETH_ACCESS_PROTECT_REG(portNo));
44729+
44730+ /* Clear protection window field */
44731+ protReg &= ~(ETH_PROT_WIN_MASK(winNum));
44732+
44733+ /* Set new protection field value */
44734+ protReg |= (access << (ETH_PROT_WIN_OFFS(winNum)));
44735+
44736+ /* Write protection register back */
44737+ MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(portNo), protReg);
44738+
44739+ return MV_OK;
44740+}
44741+
44742+/*******************************************************************************
44743+* ethWinOverlapDetect - Detect ETH address windows overlapping
44744+*
44745+* DESCRIPTION:
44746+* An unpredicted behaviur is expected in case ETH address decode
44747+* windows overlapps.
44748+* This function detects ETH address decode windows overlapping of a
44749+* specified window. The function does not check the window itself for
44750+* overlapping. The function also skipps disabled address decode windows.
44751+*
44752+* INPUT:
44753+* winNum - address decode window number.
44754+* pAddrDecWin - An address decode window struct.
44755+*
44756+* OUTPUT:
44757+* None.
44758+*
44759+* RETURN:
44760+* MV_TRUE if the given address window overlap current address
44761+* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
44762+* from registers.
44763+*
44764+*******************************************************************************/
44765+static MV_STATUS ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
44766+{
44767+ MV_U32 baseAddrEnableReg;
44768+ MV_U32 winNumIndex;
44769+ MV_ETH_DEC_WIN addrDecWin;
44770+
44771+ /* Read base address enable register. Do not check disabled windows */
44772+ baseAddrEnableReg = MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port));
44773+
44774+ for (winNumIndex=0; winNumIndex<ETH_MAX_DECODE_WIN; winNumIndex++)
44775+ {
44776+ /* Do not check window itself */
44777+ if (winNumIndex == winNum)
44778+ {
44779+ continue;
44780+ }
44781+
44782+ /* Do not check disabled windows */
44783+ if (baseAddrEnableReg & (1 << winNumIndex))
44784+ {
44785+ continue;
44786+ }
44787+
44788+ /* Get window parameters */
44789+ if (MV_OK != mvEthWinGet(port, winNumIndex, &addrDecWin))
44790+ {
44791+ mvOsPrintf("ethWinOverlapDetect: ERR. TargetWinGet failed\n");
44792+ return MV_ERROR;
44793+ }
44794+/*
44795+ mvOsPrintf("ethWinOverlapDetect:\n
44796+ winNumIndex =%d baseHigh =0x%x baseLow=0x%x size=0x%x enable=0x%x\n",
44797+ winNumIndex,
44798+ addrDecWin.addrWin.baseHigh,
44799+ addrDecWin.addrWin.baseLow,
44800+ addrDecWin.addrWin.size,
44801+ addrDecWin.enable);
44802+*/
44803+ if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
44804+ {
44805+ return MV_TRUE;
44806+ }
44807+ }
44808+ return MV_FALSE;
44809+}
44810+
44811+/*******************************************************************************
44812+* mvEthAddrDecShow - Print the Etherent address decode map.
44813+*
44814+* DESCRIPTION:
44815+* This function print the Etherent address decode map.
44816+*
44817+* INPUT:
44818+* None.
44819+*
44820+* OUTPUT:
44821+* None.
44822+*
44823+* RETURN:
44824+* None.
44825+*
44826+*******************************************************************************/
44827+void mvEthPortAddrDecShow(int port)
44828+{
44829+ MV_ETH_DEC_WIN win;
44830+ int i;
44831+
44832+ mvOsOutput( "\n" );
44833+ mvOsOutput( "ETH %d:\n", port );
44834+ mvOsOutput( "----\n" );
44835+
44836+ for( i = 0; i < ETH_MAX_DECODE_WIN; i++ )
44837+ {
44838+ memset( &win, 0, sizeof(ETH_MAX_DECODE_WIN) );
44839+
44840+ mvOsOutput( "win%d - ", i );
44841+
44842+ if( mvEthWinGet(port, i, &win ) == MV_OK )
44843+ {
44844+ if( win.enable )
44845+ {
44846+ mvOsOutput( "%s base %08x, ",
44847+ mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
44848+ mvOsOutput( "...." );
44849+ mvSizePrint( win.addrWin.size );
44850+
44851+ mvOsOutput( "\n" );
44852+ }
44853+ else
44854+ mvOsOutput( "disable\n" );
44855+ }
44856+ }
44857+ return;
44858+}
44859+
44860+void mvEthAddrDecShow(void)
44861+{
44862+ int port;
44863+
44864+ for(port=0; port<mvCtrlEthMaxPortGet(); port++)
44865+ {
44866+ if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;
44867+
44868+ mvEthPortAddrDecShow(port);
44869+ }
44870+}
44871+
44872+
44873+void mvEthInit(void)
44874+{
44875+ MV_U32 port;
44876+
44877+ /* Power down all existing ports */
44878+ for(port=0; port<mvCtrlEthMaxPortGet(); port++)
44879+ {
44880+ if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port))
44881+ continue;
44882+
44883+ mvEthPortPowerUp(port);
44884+ mvEthWinInit(port);
44885+ }
44886+ mvEthHalInit();
44887+}
44888diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h
44889new file mode 100644
44890index 0000000..aac5517
44891--- /dev/null
44892+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h
44893@@ -0,0 +1,113 @@
44894+/*******************************************************************************
44895+Copyright (C) Marvell International Ltd. and its affiliates
44896+
44897+This software file (the "File") is owned and distributed by Marvell
44898+International Ltd. and/or its affiliates ("Marvell") under the following
44899+alternative licensing terms. Once you have made an election to distribute the
44900+File under one of the following license alternatives, please (i) delete this
44901+introductory statement regarding license alternatives, (ii) delete the two
44902+license alternatives that you have not elected to use and (iii) preserve the
44903+Marvell copyright notice above.
44904+
44905+********************************************************************************
44906+Marvell Commercial License Option
44907+
44908+If you received this File from Marvell and you have entered into a commercial
44909+license agreement (a "Commercial License") with Marvell, the File is licensed
44910+to you under the terms of the applicable Commercial License.
44911+
44912+********************************************************************************
44913+Marvell GPL License Option
44914+
44915+If you received this File from Marvell, you may opt to use, redistribute and/or
44916+modify this File in accordance with the terms and conditions of the General
44917+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
44918+available along with the File in the license.txt file or by writing to the Free
44919+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
44920+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
44921+
44922+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
44923+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
44924+DISCLAIMED. The GPL License provides additional details about this warranty
44925+disclaimer.
44926+********************************************************************************
44927+Marvell BSD License Option
44928+
44929+If you received this File from Marvell, you may opt to use, redistribute and/or
44930+modify this File under the following licensing terms.
44931+Redistribution and use in source and binary forms, with or without modification,
44932+are permitted provided that the following conditions are met:
44933+
44934+ * Redistributions of source code must retain the above copyright notice,
44935+ this list of conditions and the following disclaimer.
44936+
44937+ * Redistributions in binary form must reproduce the above copyright
44938+ notice, this list of conditions and the following disclaimer in the
44939+ documentation and/or other materials provided with the distribution.
44940+
44941+ * Neither the name of Marvell nor the names of its contributors may be
44942+ used to endorse or promote products derived from this software without
44943+ specific prior written permission.
44944+
44945+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
44946+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
44947+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44948+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
44949+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
44950+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44951+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
44952+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44953+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44954+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44955+
44956+*******************************************************************************/
44957+
44958+#ifndef __INCmvSysGbeh
44959+#define __INCmvSysGbeh
44960+
44961+#include "mvCommon.h"
44962+#include "eth/mvEth.h"
44963+#include "ctrlEnv/mvCtrlEnvSpec.h"
44964+#include "ctrlEnv/sys/mvCpuIf.h"
44965+
44966+#define ETH_WIN_BASE_REG(port, win) (MV_ETH_REG_BASE(port) + 0x200 + ((win)<<3))
44967+#define ETH_WIN_SIZE_REG(port, win) (MV_ETH_REG_BASE(port) + 0x204 + ((win)<<3))
44968+#define ETH_WIN_REMAP_REG(port, win) (MV_ETH_REG_BASE(port) + 0x280 + ((win)<<2))
44969+#define ETH_BASE_ADDR_ENABLE_REG(port) (MV_ETH_REG_BASE(port) + 0x290)
44970+#define ETH_ACCESS_PROTECT_REG(port) (MV_ETH_REG_BASE(port) + 0x294)
44971+
44972+/**** Address decode parameters ****/
44973+
44974+/* Ethernet Base Address Register bits */
44975+#define ETH_MAX_DECODE_WIN 6
44976+#define ETH_MAX_HIGH_ADDR_REMAP_WIN 4
44977+
44978+/* Ethernet Port Access Protect (EPAP) register */
44979+
44980+/* The target associated with this window*/
44981+#define ETH_WIN_TARGET_OFFS 0
44982+#define ETH_WIN_TARGET_MASK (0xf << ETH_WIN_TARGET_OFFS)
44983+/* The target attributes Associated with window */
44984+#define ETH_WIN_ATTR_OFFS 8
44985+#define ETH_WIN_ATTR_MASK (0xff << ETH_WIN_ATTR_OFFS)
44986+
44987+/* Ethernet Port Access Protect Register (EPAPR) */
44988+#define ETH_PROT_NO_ACCESS NO_ACCESS_ALLOWED
44989+#define ETH_PROT_READ_ONLY READ_ONLY
44990+#define ETH_PROT_FULL_ACCESS FULL_ACCESS
44991+#define ETH_PROT_WIN_OFFS(winNum) (2 * (winNum))
44992+#define ETH_PROT_WIN_MASK(winNum) (0x3 << ETH_PROT_WIN_OFFS(winNum))
44993+
44994+MV_STATUS mvEthWinInit (int port);
44995+MV_STATUS mvEthWinEnable(int port, MV_U32 winNum, MV_BOOL enable);
44996+MV_U32 mvEthWinTargetGet(int port, MV_TARGET target);
44997+MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS
44998+ access);
44999+
45000+void mvEthPortAddrDecShow(int port);
45001+
45002+MV_VOID mvEthAddrDecShow(MV_VOID);
45003+
45004+void mvEthInit(void);
45005+
45006+#endif
45007diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c
45008new file mode 100644
45009index 0000000..9576acb
45010--- /dev/null
45011+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c
45012@@ -0,0 +1,1697 @@
45013+/*******************************************************************************
45014+Copyright (C) Marvell International Ltd. and its affiliates
45015+
45016+This software file (the "File") is owned and distributed by Marvell
45017+International Ltd. and/or its affiliates ("Marvell") under the following
45018+alternative licensing terms. Once you have made an election to distribute the
45019+File under one of the following license alternatives, please (i) delete this
45020+introductory statement regarding license alternatives, (ii) delete the two
45021+license alternatives that you have not elected to use and (iii) preserve the
45022+Marvell copyright notice above.
45023+
45024+********************************************************************************
45025+Marvell Commercial License Option
45026+
45027+If you received this File from Marvell and you have entered into a commercial
45028+license agreement (a "Commercial License") with Marvell, the File is licensed
45029+to you under the terms of the applicable Commercial License.
45030+
45031+********************************************************************************
45032+Marvell GPL License Option
45033+
45034+If you received this File from Marvell, you may opt to use, redistribute and/or
45035+modify this File in accordance with the terms and conditions of the General
45036+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
45037+available along with the File in the license.txt file or by writing to the Free
45038+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
45039+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
45040+
45041+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
45042+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
45043+DISCLAIMED. The GPL License provides additional details about this warranty
45044+disclaimer.
45045+********************************************************************************
45046+Marvell BSD License Option
45047+
45048+If you received this File from Marvell, you may opt to use, redistribute and/or
45049+modify this File under the following licensing terms.
45050+Redistribution and use in source and binary forms, with or without modification,
45051+are permitted provided that the following conditions are met:
45052+
45053+ * Redistributions of source code must retain the above copyright notice,
45054+ this list of conditions and the following disclaimer.
45055+
45056+ * Redistributions in binary form must reproduce the above copyright
45057+ notice, this list of conditions and the following disclaimer in the
45058+ documentation and/or other materials provided with the distribution.
45059+
45060+ * Neither the name of Marvell nor the names of its contributors may be
45061+ used to endorse or promote products derived from this software without
45062+ specific prior written permission.
45063+
45064+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
45065+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45066+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45067+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
45068+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
45069+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45070+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
45071+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45072+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45073+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45074+
45075+*******************************************************************************/
45076+
45077+#include "ctrlEnv/sys/mvSysPex.h"
45078+
45079+/* this structure describes the mapping between a Pex Window and a CPU target*/
45080+typedef struct _pexWinToTarget
45081+{
45082+ MV_TARGET target;
45083+ MV_BOOL enable;
45084+
45085+}PEX_WIN_TO_TARGET;
45086+
45087+/* this array is a priority array that define How Pex windows should be
45088+configured , We have only 6 Pex Windows that can be configured , but we
45089+have maximum of 9 CPU target windows ! the following array is a priority
45090+array where the lowest index has the highest priotiy and the highest
45091+index has the lowest priority of being cnfigured */
45092+
45093+MV_U32 pexDevBarPrioTable[] =
45094+{
45095+#if defined(MV_INCLUDE_DEVICE_CS0)
45096+ DEVICE_CS0,
45097+#endif
45098+#if defined(MV_INCLUDE_DEVICE_CS1)
45099+ DEVICE_CS1,
45100+#endif
45101+#if defined(MV_INCLUDE_DEVICE_CS2)
45102+ DEVICE_CS2,
45103+#endif
45104+#if defined(MV_INCLUDE_DEVICE_CS3)
45105+ DEVICE_CS3,
45106+#endif
45107+/*
45108+#if defined(MV_INCLUDE_DEVICE_CS4)
45109+ DEVICE_CS4,
45110+#endif
45111+*/
45112+ TBL_TERM
45113+};
45114+
45115+
45116+/* PEX Wins registers offsets are inconsecutive. This struct describes WIN */
45117+/* register offsets and its function where its is located. */
45118+/* Also, PEX address remap registers offsets are inconsecutive. This struct */
45119+/* describes address remap register offsets */
45120+typedef struct _pexWinRegInfo
45121+{
45122+ MV_U32 baseLowRegOffs;
45123+ MV_U32 baseHighRegOffs;
45124+ MV_U32 sizeRegOffs;
45125+ MV_U32 remapLowRegOffs;
45126+ MV_U32 remapHighRegOffs;
45127+
45128+}PEX_WIN_REG_INFO;
45129+
45130+static MV_STATUS pexWinOverlapDetect(MV_U32 pexIf, MV_U32 winNum,
45131+ MV_ADDR_WIN *pAddrWin);
45132+static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf, MV_U32 winNum,
45133+ PEX_WIN_REG_INFO *pWinRegInfo);
45134+
45135+static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size);
45136+
45137+static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,MV_ADDR_WIN *pAddrWin);
45138+static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,MV_U32 barNum,
45139+ MV_ADDR_WIN *pAddrWin);
45140+const MV_8* pexBarNameGet( MV_U32 bar );
45141+
45142+
45143+/*******************************************************************************
45144+* mvPexInit - Initialize PEX interfaces
45145+*
45146+* DESCRIPTION:
45147+*
45148+* This function is responsible of intialization of the Pex Interface , It
45149+* configure the Pex Bars and Windows in the following manner:
45150+*
45151+* Assumptions :
45152+* Bar0 is always internal registers bar
45153+* Bar1 is always the DRAM bar
45154+* Bar2 is always the Device bar
45155+*
45156+* 1) Sets the Internal registers bar base by obtaining the base from
45157+* the CPU Interface
45158+* 2) Sets the DRAM bar base and size by getting the base and size from
45159+* the CPU Interface when the size is the sum of all enabled DRAM
45160+* chip selects and the base is the base of CS0 .
45161+* 3) Sets the Device bar base and size by getting these values from the
45162+* CPU Interface when the base is the base of the lowest base of the
45163+* Device chip selects, and the
45164+*
45165+*
45166+* INPUT:
45167+*
45168+* pexIf - PEX interface number.
45169+*
45170+*
45171+* OUTPUT:
45172+* None.
45173+*
45174+* RETURN:
45175+* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
45176+*
45177+*******************************************************************************/
45178+MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
45179+{
45180+ MV_U32 bar;
45181+ MV_U32 winNum;
45182+ MV_PEX_BAR pexBar;
45183+ MV_PEX_DEC_WIN pexWin;
45184+ MV_CPU_DEC_WIN addrDecWin;
45185+ MV_TARGET target;
45186+ MV_U32 pexCurrWin=0;
45187+ MV_U32 status;
45188+ /* default and exapntion rom
45189+ are always configured */
45190+
45191+#ifndef MV_DISABLE_PEX_DEVICE_BAR
45192+ MV_U32 winIndex;
45193+ MV_U32 maxBase=0, sizeOfMaxBase=0;
45194+ MV_U32 pexStartWindow;
45195+#endif
45196+
45197+ /* Parameter checking */
45198+ if(pexIf >= mvCtrlPexMaxIfGet())
45199+ {
45200+ mvOsPrintf("mvPexInit: ERR. Invalid PEX interface %d\n", pexIf);
45201+ return MV_BAD_PARAM;
45202+ }
45203+
45204+ /* Enabled CPU access to PCI-Express */
45205+ mvCpuIfEnablePex(pexIf, pexType);
45206+
45207+ /* Start with bars */
45208+ /* First disable all PEX bars*/
45209+ for (bar = 0; bar < PEX_MAX_BARS; bar++)
45210+ {
45211+ if (PEX_INTER_REGS_BAR != bar)
45212+ {
45213+ if (MV_OK != mvPexBarEnable(pexIf, bar, MV_FALSE))
45214+ {
45215+ mvOsPrintf("mvPexInit:mvPexBarEnable bar =%d failed \n",bar);
45216+ return MV_ERROR;
45217+ }
45218+
45219+ }
45220+
45221+ }
45222+
45223+ /* and disable all PEX target windows */
45224+ for (winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
45225+ {
45226+ if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_FALSE))
45227+ {
45228+ mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
45229+ winNum);
45230+ return MV_ERROR;
45231+
45232+ }
45233+ }
45234+
45235+ /* Now, go through all bars*/
45236+
45237+
45238+
45239+/******************************************************************************/
45240+/* Internal registers bar */
45241+/******************************************************************************/
45242+ bar = PEX_INTER_REGS_BAR;
45243+
45244+ /* we only open the bar , no need to open windows for this bar */
45245+
45246+ /* first get the CS attribute from the CPU Interface */
45247+ if (MV_OK !=mvCpuIfTargetWinGet(INTER_REGS,&addrDecWin))
45248+ {
45249+ mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",INTER_REGS);
45250+ return MV_ERROR;
45251+ }
45252+
45253+ pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
45254+ pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
45255+ pexBar.addrWin.size = addrDecWin.addrWin.size;
45256+ pexBar.enable = MV_TRUE;
45257+
45258+ if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
45259+ {
45260+ mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
45261+ return MV_ERROR;
45262+ }
45263+
45264+/******************************************************************************/
45265+/* DRAM bar */
45266+/******************************************************************************/
45267+
45268+ bar = PEX_DRAM_BAR;
45269+
45270+ pexBar.addrWin.size = 0;
45271+
45272+ for (target = SDRAM_CS0;target < MV_DRAM_MAX_CS; target++ )
45273+ {
45274+
45275+ status = mvCpuIfTargetWinGet(target,&addrDecWin);
45276+
45277+ if((MV_NO_SUCH == status)&&(target != SDRAM_CS0))
45278+ {
45279+ continue;
45280+ }
45281+
45282+ /* first get attributes from CPU If */
45283+ if (MV_OK != status)
45284+ {
45285+ mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
45286+ return MV_ERROR;
45287+ }
45288+ if (addrDecWin.enable == MV_TRUE)
45289+ {
45290+ /* the base is the base of DRAM CS0 always */
45291+ if (SDRAM_CS0 == target )
45292+ {
45293+ pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
45294+ pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
45295+
45296+ }
45297+
45298+ /* increment the bar size to be the sum of the size of all
45299+ DRAM chips selecs */
45300+ pexBar.addrWin.size += addrDecWin.addrWin.size;
45301+
45302+ /* set a Pex window for this target !
45303+ DRAM CS always will have a Pex Window , and is not a
45304+ part of the priority table */
45305+ pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
45306+ pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
45307+ pexWin.addrWin.size = addrDecWin.addrWin.size;
45308+
45309+ /* we disable the windows at first because we are not
45310+ sure that it is witihin bar boundries */
45311+ pexWin.enable =MV_FALSE;
45312+ pexWin.target = target;
45313+ pexWin.targetBar = bar;
45314+
45315+ if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,&pexWin))
45316+ {
45317+ mvOsPrintf("mvPexInit: ERR. mvPexTargetWinSet failed\n");
45318+ return MV_ERROR;
45319+ }
45320+ }
45321+ }
45322+
45323+ /* check if the size of the bar is illeggal */
45324+ if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
45325+ {
45326+ /* try to get a good size */
45327+ pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
45328+ PXBCR_BAR_SIZE_ALIGNMENT);
45329+ }
45330+
45331+ /* check if the size and base are valid */
45332+ if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
45333+ {
45334+ mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
45335+ mvOsPrintf("it will be disabled\n");
45336+ mvOsPrintf("please check Pex and CPU windows configuration\n");
45337+ }
45338+ else
45339+ {
45340+ pexBar.enable = MV_TRUE;
45341+
45342+ /* configure the bar */
45343+ if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
45344+ {
45345+ mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
45346+ return MV_ERROR;
45347+ }
45348+
45349+ /* after the bar was configured then we enable the Pex windows*/
45350+ for (winNum = 0;winNum < pexCurrWin ;winNum++)
45351+ {
45352+ if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
45353+ {
45354+ mvOsPrintf("mvPexInit: Can't enable window =%d\n",winNum);
45355+ return MV_ERROR;
45356+ }
45357+
45358+ }
45359+ }
45360+
45361+/******************************************************************************/
45362+/* DEVICE bar */
45363+/******************************************************************************/
45364+
45365+/* Open the Device BAR for non linux only */
45366+#ifndef MV_DISABLE_PEX_DEVICE_BAR
45367+
45368+ /* then device bar*/
45369+ bar = PEX_DEVICE_BAR;
45370+
45371+ /* save the starting window */
45372+ pexStartWindow = pexCurrWin;
45373+ pexBar.addrWin.size = 0;
45374+ pexBar.addrWin.baseLow = 0xffffffff;
45375+ pexBar.addrWin.baseHigh = 0;
45376+ maxBase = 0;
45377+
45378+ for (target = DEV_TO_TARGET(START_DEV_CS);target < DEV_TO_TARGET(MV_DEV_MAX_CS); target++ )
45379+ {
45380+ status = mvCpuIfTargetWinGet(target,&addrDecWin);
45381+
45382+ if (MV_NO_SUCH == status)
45383+ {
45384+ continue;
45385+ }
45386+
45387+ if (MV_OK != status)
45388+ {
45389+ mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
45390+ return MV_ERROR;
45391+ }
45392+
45393+ if (addrDecWin.enable == MV_TRUE)
45394+ {
45395+ /* get the minimum base */
45396+ if (addrDecWin.addrWin.baseLow < pexBar.addrWin.baseLow)
45397+ {
45398+ pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
45399+ }
45400+
45401+ /* get the maximum base */
45402+ if (addrDecWin.addrWin.baseLow > maxBase)
45403+ {
45404+ maxBase = addrDecWin.addrWin.baseLow;
45405+ sizeOfMaxBase = addrDecWin.addrWin.size;
45406+ }
45407+
45408+ /* search in the priority table for this target */
45409+ for (winIndex = 0; pexDevBarPrioTable[winIndex] != TBL_TERM;
45410+ winIndex++)
45411+ {
45412+ if (pexDevBarPrioTable[winIndex] != target)
45413+ {
45414+ continue;
45415+ }
45416+ else if (pexDevBarPrioTable[winIndex] == target)
45417+ {
45418+ /*found it */
45419+
45420+ /* if the index of this target in the prio table is valid
45421+ then we set the Pex window for this target, a valid index is
45422+ an index that is lower than the number of the windows that
45423+ was not configured yet */
45424+
45425+ /* we subtract 2 always because the default and expantion
45426+ rom windows are always configured */
45427+ if ( pexCurrWin < PEX_MAX_TARGET_WIN - 2)
45428+ {
45429+ /* set a Pex window for this target ! */
45430+ pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
45431+ pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
45432+ pexWin.addrWin.size = addrDecWin.addrWin.size;
45433+
45434+ /* we disable the windows at first because we are not
45435+ sure that it is witihin bar boundries */
45436+ pexWin.enable = MV_FALSE;
45437+ pexWin.target = target;
45438+ pexWin.targetBar = bar;
45439+
45440+ if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,
45441+ &pexWin))
45442+ {
45443+ mvOsPrintf("mvPexInit: ERR. Window Set failed\n");
45444+ return MV_ERROR;
45445+ }
45446+ }
45447+ }
45448+ }
45449+ }
45450+ }
45451+
45452+ pexBar.addrWin.size = maxBase - pexBar.addrWin.baseLow + sizeOfMaxBase;
45453+ pexBar.enable = MV_TRUE;
45454+
45455+ /* check if the size of the bar is illegal */
45456+ if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
45457+ {
45458+ /* try to get a good size */
45459+ pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
45460+ PXBCR_BAR_SIZE_ALIGNMENT);
45461+ }
45462+
45463+ /* check if the size and base are valid */
45464+ if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
45465+ {
45466+ mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
45467+ mvOsPrintf("it will be disabled\n");
45468+ mvOsPrintf("please check Pex and CPU windows configuration\n");
45469+ }
45470+ else
45471+ {
45472+ if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
45473+ {
45474+ mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
45475+ return MV_ERROR;
45476+ }
45477+
45478+ /* now enable the windows */
45479+ for (winNum = pexStartWindow; winNum < pexCurrWin ; winNum++)
45480+ {
45481+ if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
45482+ {
45483+ mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
45484+ winNum);
45485+ return MV_ERROR;
45486+ }
45487+ }
45488+ }
45489+
45490+#endif
45491+
45492+ return mvPexHalInit(pexIf, pexType);
45493+
45494+}
45495+
45496+/*******************************************************************************
45497+* mvPexTargetWinSet - Set PEX to peripheral target address window BAR
45498+*
45499+* DESCRIPTION:
45500+*
45501+* INPUT:
45502+*
45503+* OUTPUT:
45504+* N/A
45505+*
45506+* RETURN:
45507+* MV_OK if PEX BAR target window was set correctly,
45508+* MV_BAD_PARAM on bad params
45509+* MV_ERROR otherwise
45510+* (e.g. address window overlapps with other active PEX target window).
45511+*
45512+*******************************************************************************/
45513+MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum,
45514+ MV_PEX_DEC_WIN *pAddrDecWin)
45515+{
45516+
45517+ MV_DEC_REGS decRegs;
45518+ PEX_WIN_REG_INFO winRegInfo;
45519+ MV_TARGET_ATTRIB targetAttribs;
45520+
45521+ /* Parameter checking */
45522+ if(pexIf >= mvCtrlPexMaxIfGet())
45523+ {
45524+ mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX interface %d\n", pexIf);
45525+ return MV_BAD_PARAM;
45526+ }
45527+
45528+ if (winNum >= PEX_MAX_TARGET_WIN)
45529+ {
45530+ mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX winNum %d\n", winNum);
45531+ return MV_BAD_PARAM;
45532+
45533+ }
45534+
45535+ /* get the pex Window registers offsets */
45536+ pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
45537+
45538+
45539+ if (MV_TRUE == pAddrDecWin->enable)
45540+ {
45541+
45542+ /* 2) Check if the requested window overlaps with current windows */
45543+ if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &pAddrDecWin->addrWin))
45544+ {
45545+ mvOsPrintf("mvPexTargetWinSet: ERR. Target %d overlap\n", winNum);
45546+ return MV_BAD_PARAM;
45547+ }
45548+
45549+ /* 2) Check if the requested window overlaps with current windows */
45550+ if (MV_FALSE == pexIsWinWithinBar(pexIf,&pAddrDecWin->addrWin))
45551+ {
45552+ mvOsPrintf("mvPexTargetWinSet: Win %d should be in bar boundries\n",
45553+ winNum);
45554+ return MV_BAD_PARAM;
45555+ }
45556+
45557+ }
45558+
45559+
45560+
45561+ /* read base register*/
45562+
45563+ if (winRegInfo.baseLowRegOffs)
45564+ {
45565+ decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
45566+ }
45567+ else
45568+ {
45569+ decRegs.baseReg = 0;
45570+ }
45571+
45572+ if (winRegInfo.sizeRegOffs)
45573+ {
45574+ decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
45575+ }
45576+ else
45577+ {
45578+ decRegs.sizeReg =0;
45579+ }
45580+
45581+ if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
45582+ {
45583+ mvOsPrintf("mvPexTargetWinSet:mvCtrlAddrDecToReg Failed\n");
45584+ return MV_ERROR;
45585+ }
45586+
45587+ /* enable\Disable */
45588+ if (MV_TRUE == pAddrDecWin->enable)
45589+ {
45590+ decRegs.sizeReg |= PXWCR_WIN_EN;
45591+ }
45592+ else
45593+ {
45594+ decRegs.sizeReg &= ~PXWCR_WIN_EN;
45595+ }
45596+
45597+
45598+ /* clear bit location */
45599+ decRegs.sizeReg &= ~PXWCR_WIN_BAR_MAP_MASK;
45600+
45601+ /* set bar Mapping */
45602+ if (pAddrDecWin->targetBar == 1)
45603+ {
45604+ decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR1;
45605+ }
45606+ else if (pAddrDecWin->targetBar == 2)
45607+ {
45608+ decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR2;
45609+ }
45610+
45611+ mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
45612+
45613+ /* set attributes */
45614+ decRegs.sizeReg &= ~PXWCR_ATTRIB_MASK;
45615+ decRegs.sizeReg |= targetAttribs.attrib << PXWCR_ATTRIB_OFFS;
45616+ /* set target ID */
45617+ decRegs.sizeReg &= ~PXWCR_TARGET_MASK;
45618+ decRegs.sizeReg |= targetAttribs.targetId << PXWCR_TARGET_OFFS;
45619+
45620+
45621+ /* 3) Write to address decode Base Address Register */
45622+
45623+ if (winRegInfo.baseLowRegOffs)
45624+ {
45625+ MV_REG_WRITE(winRegInfo.baseLowRegOffs, decRegs.baseReg);
45626+ }
45627+
45628+ /* write size reg */
45629+ if (winRegInfo.sizeRegOffs)
45630+ {
45631+ if ((MV_PEX_WIN_DEFAULT == winNum)||
45632+ (MV_PEX_WIN_EXP_ROM == winNum))
45633+ {
45634+ /* clear size because there is no size field*/
45635+ decRegs.sizeReg &= ~PXWCR_SIZE_MASK;
45636+
45637+ /* clear enable because there is no enable field*/
45638+ decRegs.sizeReg &= ~PXWCR_WIN_EN;
45639+
45640+ }
45641+
45642+ MV_REG_WRITE(winRegInfo.sizeRegOffs, decRegs.sizeReg);
45643+ }
45644+
45645+
45646+ return MV_OK;
45647+
45648+}
45649+
45650+/*******************************************************************************
45651+* mvPexTargetWinGet - Get PEX to peripheral target address window
45652+*
45653+* DESCRIPTION:
45654+* Get the PEX to peripheral target address window BAR.
45655+*
45656+* INPUT:
45657+* pexIf - PEX interface number.
45658+* bar - BAR to be accessed by slave.
45659+*
45660+* OUTPUT:
45661+* pAddrBarWin - PEX target window information data structure.
45662+*
45663+* RETURN:
45664+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
45665+*
45666+*******************************************************************************/
45667+MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum,
45668+ MV_PEX_DEC_WIN *pAddrDecWin)
45669+{
45670+ MV_TARGET_ATTRIB targetAttrib;
45671+ MV_DEC_REGS decRegs;
45672+
45673+ PEX_WIN_REG_INFO winRegInfo;
45674+
45675+ /* Parameter checking */
45676+ if(pexIf >= mvCtrlPexMaxIfGet())
45677+ {
45678+ mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX interface %d\n", pexIf);
45679+ return MV_BAD_PARAM;
45680+ }
45681+
45682+ if (winNum >= PEX_MAX_TARGET_WIN)
45683+ {
45684+ mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX winNum %d\n", winNum);
45685+ return MV_BAD_PARAM;
45686+
45687+ }
45688+
45689+ /* get the pex Window registers offsets */
45690+ pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
45691+
45692+ /* read base register*/
45693+ if (winRegInfo.baseLowRegOffs)
45694+ {
45695+ decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
45696+ }
45697+ else
45698+ {
45699+ decRegs.baseReg = 0;
45700+ }
45701+
45702+ /* read size reg */
45703+ if (winRegInfo.sizeRegOffs)
45704+ {
45705+ decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
45706+ }
45707+ else
45708+ {
45709+ decRegs.sizeReg =0;
45710+ }
45711+
45712+ if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
45713+ {
45714+ mvOsPrintf("mvPexTargetWinGet: mvCtrlRegToAddrDec Failed \n");
45715+ return MV_ERROR;
45716+
45717+ }
45718+
45719+ if (decRegs.sizeReg & PXWCR_WIN_EN)
45720+ {
45721+ pAddrDecWin->enable = MV_TRUE;
45722+ }
45723+ else
45724+ {
45725+ pAddrDecWin->enable = MV_FALSE;
45726+
45727+ }
45728+
45729+
45730+ #if 0
45731+ if (-1 == pAddrDecWin->addrWin.size)
45732+ {
45733+ return MV_ERROR;
45734+ }
45735+ #endif
45736+
45737+
45738+ /* get target bar */
45739+ if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) == PXWCR_WIN_BAR_MAP_BAR1 )
45740+ {
45741+ pAddrDecWin->targetBar = 1;
45742+ }
45743+ else if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) ==
45744+ PXWCR_WIN_BAR_MAP_BAR2 )
45745+ {
45746+ pAddrDecWin->targetBar = 2;
45747+ }
45748+
45749+ /* attrib and targetId */
45750+ pAddrDecWin->attrib = (decRegs.sizeReg & PXWCR_ATTRIB_MASK) >>
45751+ PXWCR_ATTRIB_OFFS;
45752+ pAddrDecWin->targetId = (decRegs.sizeReg & PXWCR_TARGET_MASK) >>
45753+ PXWCR_TARGET_OFFS;
45754+
45755+ targetAttrib.attrib = pAddrDecWin->attrib;
45756+ targetAttrib.targetId = pAddrDecWin->targetId;
45757+
45758+ pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
45759+
45760+ return MV_OK;
45761+
45762+}
45763+
45764+
45765+/*******************************************************************************
45766+* mvPexTargetWinEnable - Enable/disable a PEX BAR window
45767+*
45768+* DESCRIPTION:
45769+* This function enable/disable a PEX BAR window.
45770+* if parameter 'enable' == MV_TRUE the routine will enable the
45771+* window, thus enabling PEX accesses for that BAR (before enabling the
45772+* window it is tested for overlapping). Otherwise, the window will
45773+* be disabled.
45774+*
45775+* INPUT:
45776+* pexIf - PEX interface number.
45777+* bar - BAR to be accessed by slave.
45778+* enable - Enable/disable parameter.
45779+*
45780+* OUTPUT:
45781+* None.
45782+*
45783+* RETURN:
45784+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
45785+*
45786+*******************************************************************************/
45787+MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable)
45788+{
45789+ PEX_WIN_REG_INFO winRegInfo;
45790+ MV_PEX_DEC_WIN addrDecWin;
45791+
45792+ /* Parameter checking */
45793+ if(pexIf >= mvCtrlPexMaxIfGet())
45794+ {
45795+ mvOsPrintf("mvPexTargetWinEnable: ERR. Invalid PEX If %d\n", pexIf);
45796+ return MV_BAD_PARAM;
45797+ }
45798+
45799+ if (winNum >= PEX_MAX_TARGET_WIN)
45800+ {
45801+ mvOsPrintf("mvPexTargetWinEnable ERR. Invalid PEX winNum %d\n", winNum);
45802+ return MV_BAD_PARAM;
45803+
45804+ }
45805+
45806+
45807+ /* get the pex Window registers offsets */
45808+ pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
45809+
45810+
45811+ /* if the address windows is disabled , we only disable the appropriare
45812+ pex window and ignore other settings */
45813+
45814+ if (MV_FALSE == enable)
45815+ {
45816+
45817+ /* this is not relevant to default and expantion rom
45818+ windows */
45819+ if (winRegInfo.sizeRegOffs)
45820+ {
45821+ if ((MV_PEX_WIN_DEFAULT != winNum)&&
45822+ (MV_PEX_WIN_EXP_ROM != winNum))
45823+ {
45824+ MV_REG_BIT_RESET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
45825+ }
45826+ }
45827+
45828+ }
45829+ else
45830+ {
45831+ if (MV_OK != mvPexTargetWinGet(pexIf,winNum, &addrDecWin))
45832+ {
45833+ mvOsPrintf("mvPexTargetWinEnable: mvPexTargetWinGet Failed\n");
45834+ return MV_ERROR;
45835+ }
45836+
45837+ /* Check if the requested window overlaps with current windows */
45838+ if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &addrDecWin.addrWin))
45839+ {
45840+ mvOsPrintf("mvPexTargetWinEnable: ERR. Target %d overlap\n", winNum);
45841+ return MV_BAD_PARAM;
45842+ }
45843+
45844+ if (MV_FALSE == pexIsWinWithinBar(pexIf,&addrDecWin.addrWin))
45845+ {
45846+ mvOsPrintf("mvPexTargetWinEnable: Win %d should be in bar boundries\n",
45847+ winNum);
45848+ return MV_BAD_PARAM;
45849+ }
45850+
45851+
45852+ /* this is not relevant to default and expantion rom
45853+ windows */
45854+ if (winRegInfo.sizeRegOffs)
45855+ {
45856+ if ((MV_PEX_WIN_DEFAULT != winNum)&&
45857+ (MV_PEX_WIN_EXP_ROM != winNum))
45858+ {
45859+ MV_REG_BIT_SET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
45860+ }
45861+ }
45862+
45863+
45864+ }
45865+
45866+ return MV_OK;
45867+
45868+}
45869+
45870+
45871+
45872+/*******************************************************************************
45873+* mvPexTargetWinRemap - Set PEX to target address window remap.
45874+*
45875+* DESCRIPTION:
45876+* The PEX interface supports remap of the BAR original address window.
45877+* For each BAR it is possible to define a remap address. For example
45878+* an address 0x12345678 that hits BAR 0x10 (SDRAM CS[0]) will be modified
45879+* according to remap register but will also be targeted to the
45880+* SDRAM CS[0].
45881+*
45882+* INPUT:
45883+* pexIf - PEX interface number.
45884+* bar - Peripheral target enumerator accessed by slave.
45885+* pAddrWin - Address window to be checked.
45886+*
45887+* OUTPUT:
45888+* None.
45889+*
45890+* RETURN:
45891+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
45892+*
45893+*******************************************************************************/
45894+MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum,
45895+ MV_PEX_REMAP_WIN *pAddrWin)
45896+{
45897+
45898+ PEX_WIN_REG_INFO winRegInfo;
45899+
45900+ /* Parameter checking */
45901+ if (pexIf >= mvCtrlPexMaxIfGet())
45902+ {
45903+ mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
45904+ pexIf);
45905+ return MV_BAD_PARAM;
45906+ }
45907+ if (MV_PEX_WIN_DEFAULT == winNum)
45908+ {
45909+ mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
45910+ winNum);
45911+ return MV_BAD_PARAM;
45912+
45913+ }
45914+
45915+ if (MV_IS_NOT_ALIGN(pAddrWin->addrWin.baseLow, PXWRR_REMAP_ALIGNMENT))
45916+ {
45917+ mvOsPrintf("mvPexTargetWinRemap: Error remap PEX interface %d win %d."\
45918+ "\nAddress 0x%08x is unaligned to size 0x%x.\n",
45919+ pexIf,
45920+ winNum,
45921+ pAddrWin->addrWin.baseLow,
45922+ pAddrWin->addrWin.size);
45923+
45924+ return MV_ERROR;
45925+ }
45926+
45927+ pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
45928+
45929+ /* Set remap low register value */
45930+ MV_REG_WRITE(winRegInfo.remapLowRegOffs, pAddrWin->addrWin.baseLow);
45931+
45932+ /* Skip base high settings if the BAR has only base low (32-bit) */
45933+ if (0 != winRegInfo.remapHighRegOffs)
45934+ {
45935+ MV_REG_WRITE(winRegInfo.remapHighRegOffs, pAddrWin->addrWin.baseHigh);
45936+ }
45937+
45938+
45939+ if (pAddrWin->enable == MV_TRUE)
45940+ {
45941+ MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
45942+ }
45943+ else
45944+ {
45945+ MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
45946+ }
45947+
45948+ return MV_OK;
45949+}
45950+
45951+/*******************************************************************************
45952+* mvPexTargetWinRemapEnable -
45953+*
45954+* DESCRIPTION:
45955+*
45956+* INPUT:
45957+*
45958+* OUTPUT:
45959+*
45960+* RETURN:
45961+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
45962+*
45963+*******************************************************************************/
45964+
45965+MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum,
45966+ MV_BOOL enable)
45967+{
45968+ PEX_WIN_REG_INFO winRegInfo;
45969+
45970+ /* Parameter checking */
45971+ if (pexIf >= mvCtrlPexMaxIfGet())
45972+ {
45973+ mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
45974+ pexIf);
45975+ return MV_BAD_PARAM;
45976+ }
45977+ if (MV_PEX_WIN_DEFAULT == winNum)
45978+ {
45979+ mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
45980+ winNum);
45981+ return MV_BAD_PARAM;
45982+
45983+ }
45984+
45985+
45986+ pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
45987+
45988+ if (enable == MV_TRUE)
45989+ {
45990+ MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
45991+ }
45992+ else
45993+ {
45994+ MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
45995+ }
45996+
45997+ return MV_OK;
45998+
45999+}
46000+
46001+/*******************************************************************************
46002+* mvPexBarSet - Set PEX bar address and size
46003+*
46004+* DESCRIPTION:
46005+*
46006+* INPUT:
46007+*
46008+* OUTPUT:
46009+* None.
46010+*
46011+* RETURN:
46012+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
46013+*
46014+*******************************************************************************/
46015+MV_STATUS mvPexBarSet(MV_U32 pexIf,
46016+ MV_U32 barNum,
46017+ MV_PEX_BAR *pAddrWin)
46018+{
46019+ MV_U32 regBaseLow;
46020+ MV_U32 regSize,sizeToReg;
46021+
46022+
46023+ /* check parameters */
46024+ if(pexIf >= mvCtrlPexMaxIfGet())
46025+ {
46026+ mvOsPrintf("mvPexBarSet: ERR. Invalid PEX interface %d\n", pexIf);
46027+ return MV_BAD_PARAM;
46028+ }
46029+
46030+ if(barNum >= PEX_MAX_BARS)
46031+ {
46032+ mvOsPrintf("mvPexBarSet: ERR. Invalid bar number %d\n", barNum);
46033+ return MV_BAD_PARAM;
46034+ }
46035+
46036+
46037+ if (pAddrWin->addrWin.size == 0)
46038+ {
46039+ mvOsPrintf("mvPexBarSet: Size zero is Illigal\n" );
46040+ return MV_BAD_PARAM;
46041+ }
46042+
46043+
46044+ /* Check if the window complies with PEX spec */
46045+ if (MV_TRUE != pexBarIsValid(pAddrWin->addrWin.baseLow,
46046+ pAddrWin->addrWin.size))
46047+ {
46048+ mvOsPrintf("mvPexBarSet: ERR. Target %d window invalid\n", barNum);
46049+ return MV_BAD_PARAM;
46050+ }
46051+
46052+ /* 2) Check if the requested bar overlaps with current bars */
46053+ if (MV_TRUE == pexBarOverlapDetect(pexIf,barNum, &pAddrWin->addrWin))
46054+ {
46055+ mvOsPrintf("mvPexBarSet: ERR. Target %d overlap\n", barNum);
46056+ return MV_BAD_PARAM;
46057+ }
46058+
46059+ /* Get size register value according to window size */
46060+ sizeToReg = ctrlSizeToReg(pAddrWin->addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT);
46061+
46062+ /* Read bar size */
46063+ if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
46064+ {
46065+ regSize = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
46066+
46067+ /* Size parameter validity check. */
46068+ if (-1 == sizeToReg)
46069+ {
46070+ mvOsPrintf("mvPexBarSet: ERR. Target BAR %d size invalid.\n",barNum);
46071+ return MV_BAD_PARAM;
46072+ }
46073+
46074+ regSize &= ~PXBCR_BAR_SIZE_MASK;
46075+ regSize |= (sizeToReg << PXBCR_BAR_SIZE_OFFS) ;
46076+
46077+ MV_REG_WRITE(PEX_BAR_CTRL_REG(pexIf,barNum),regSize);
46078+
46079+ }
46080+
46081+ /* set size */
46082+
46083+
46084+
46085+ /* Read base address low */
46086+ regBaseLow = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
46087+ PEX_MV_BAR_BASE(barNum)));
46088+
46089+ /* clear current base */
46090+ if (PEX_INTER_REGS_BAR == barNum)
46091+ {
46092+ regBaseLow &= ~PXBIR_BASE_MASK;
46093+ regBaseLow |= (pAddrWin->addrWin.baseLow & PXBIR_BASE_MASK);
46094+ }
46095+ else
46096+ {
46097+ regBaseLow &= ~PXBR_BASE_MASK;
46098+ regBaseLow |= (pAddrWin->addrWin.baseLow & PXBR_BASE_MASK);
46099+ }
46100+
46101+ /* if we had a previous value that contain the bar type (MeM\IO), we want to
46102+ restore it */
46103+ regBaseLow |= PEX_BAR_DEFAULT_ATTRIB;
46104+
46105+
46106+
46107+ /* write base low */
46108+ MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)),
46109+ regBaseLow);
46110+
46111+ if (pAddrWin->addrWin.baseHigh != 0)
46112+ {
46113+ /* Read base address high */
46114+ MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)),
46115+ pAddrWin->addrWin.baseHigh);
46116+
46117+ }
46118+
46119+ /* lastly enable the Bar */
46120+ if (pAddrWin->enable == MV_TRUE)
46121+ {
46122+ if (PEX_INTER_REGS_BAR != barNum) /* internal registers
46123+ are enabled always */
46124+ {
46125+ MV_REG_BIT_SET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
46126+ }
46127+ }
46128+ else if (MV_FALSE == pAddrWin->enable)
46129+ {
46130+ if (PEX_INTER_REGS_BAR != barNum) /* internal registers
46131+ are enabled always */
46132+ {
46133+ MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
46134+ }
46135+
46136+ }
46137+
46138+
46139+
46140+ return MV_OK;
46141+}
46142+
46143+
46144+/*******************************************************************************
46145+* mvPexBarGet - Get PEX bar address and size
46146+*
46147+* DESCRIPTION:
46148+*
46149+* INPUT:
46150+*
46151+* OUTPUT:
46152+* None.
46153+*
46154+* RETURN:
46155+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
46156+*
46157+*******************************************************************************/
46158+
46159+MV_STATUS mvPexBarGet(MV_U32 pexIf,
46160+ MV_U32 barNum,
46161+ MV_PEX_BAR *pAddrWin)
46162+{
46163+ /* check parameters */
46164+ if(pexIf >= mvCtrlPexMaxIfGet())
46165+ {
46166+ mvOsPrintf("mvPexBarGet: ERR. Invalid PEX interface %d\n", pexIf);
46167+ return MV_BAD_PARAM;
46168+ }
46169+
46170+ if(barNum >= PEX_MAX_BARS)
46171+ {
46172+ mvOsPrintf("mvPexBarGet: ERR. Invalid bar number %d\n", barNum);
46173+ return MV_BAD_PARAM;
46174+ }
46175+
46176+ /* read base low */
46177+ pAddrWin->addrWin.baseLow =
46178+ MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)));
46179+
46180+
46181+ if (PEX_INTER_REGS_BAR == barNum)
46182+ {
46183+ pAddrWin->addrWin.baseLow &= PXBIR_BASE_MASK;
46184+ }
46185+ else
46186+ {
46187+ pAddrWin->addrWin.baseLow &= PXBR_BASE_MASK;
46188+ }
46189+
46190+
46191+ /* read base high */
46192+ pAddrWin->addrWin.baseHigh =
46193+ MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)));
46194+
46195+
46196+ /* Read bar size */
46197+ if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
46198+ {
46199+ pAddrWin->addrWin.size = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
46200+
46201+ /* check if enable or not */
46202+ if (pAddrWin->addrWin.size & PXBCR_BAR_EN)
46203+ {
46204+ pAddrWin->enable = MV_TRUE;
46205+ }
46206+ else
46207+ {
46208+ pAddrWin->enable = MV_FALSE;
46209+ }
46210+
46211+ /* now get the size */
46212+ pAddrWin->addrWin.size &= PXBCR_BAR_SIZE_MASK;
46213+ pAddrWin->addrWin.size >>= PXBCR_BAR_SIZE_OFFS;
46214+
46215+ pAddrWin->addrWin.size = ctrlRegToSize(pAddrWin->addrWin.size,
46216+ PXBCR_BAR_SIZE_ALIGNMENT);
46217+
46218+ }
46219+ else /* PEX_INTER_REGS_BAR */
46220+ {
46221+ pAddrWin->addrWin.size = INTER_REGS_SIZE;
46222+ pAddrWin->enable = MV_TRUE;
46223+ }
46224+
46225+
46226+ return MV_OK;
46227+}
46228+
46229+/*******************************************************************************
46230+* mvPexBarEnable -
46231+*
46232+* DESCRIPTION:
46233+*
46234+* INPUT:
46235+*
46236+* OUTPUT:
46237+* None.
46238+*
46239+* RETURN:
46240+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
46241+*
46242+*******************************************************************************/
46243+
46244+
46245+MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable)
46246+{
46247+
46248+ MV_PEX_BAR pexBar;
46249+
46250+ /* check parameters */
46251+ if(pexIf >= mvCtrlPexMaxIfGet())
46252+ {
46253+ mvOsPrintf("mvPexBarEnable: ERR. Invalid PEX interface %d\n", pexIf);
46254+ return MV_BAD_PARAM;
46255+ }
46256+
46257+
46258+ if(barNum >= PEX_MAX_BARS)
46259+ {
46260+ mvOsPrintf("mvPexBarEnable: ERR. Invalid bar number %d\n", barNum);
46261+ return MV_BAD_PARAM;
46262+ }
46263+
46264+ if (PEX_INTER_REGS_BAR == barNum)
46265+ {
46266+ if (MV_TRUE == enable)
46267+ {
46268+ return MV_OK;
46269+ }
46270+ else
46271+ {
46272+ return MV_ERROR;
46273+ }
46274+ }
46275+
46276+
46277+ if (MV_FALSE == enable)
46278+ {
46279+ /* disable bar and quit */
46280+ MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
46281+ return MV_OK;
46282+ }
46283+
46284+ /* else */
46285+
46286+ if (mvPexBarGet(pexIf,barNum,&pexBar) != MV_OK)
46287+ {
46288+ mvOsPrintf("mvPexBarEnable: mvPexBarGet Failed\n");
46289+ return MV_ERROR;
46290+
46291+ }
46292+
46293+ if (MV_TRUE == pexBar.enable)
46294+ {
46295+ /* it is already enabled !!! */
46296+ return MV_OK;
46297+ }
46298+
46299+ /* else enable the bar*/
46300+
46301+ pexBar.enable = MV_TRUE;
46302+
46303+ if (mvPexBarSet(pexIf,barNum,&pexBar) != MV_OK)
46304+ {
46305+ mvOsPrintf("mvPexBarEnable: mvPexBarSet Failed\n");
46306+ return MV_ERROR;
46307+
46308+ }
46309+
46310+ return MV_OK;
46311+}
46312+
46313+
46314+/*******************************************************************************
46315+* pexWinOverlapDetect - Detect address windows overlapping
46316+*
46317+* DESCRIPTION:
46318+* This function detects address window overlapping of a given address
46319+* window in PEX BARs.
46320+*
46321+* INPUT:
46322+* pAddrWin - Address window to be checked.
46323+* bar - BAR to be accessed by slave.
46324+*
46325+* OUTPUT:
46326+* None.
46327+*
46328+* RETURN:
46329+* MV_TRUE if the given address window overlap current address
46330+* decode map, MV_FALSE otherwise.
46331+*
46332+*******************************************************************************/
46333+static MV_BOOL pexWinOverlapDetect(MV_U32 pexIf,
46334+ MV_U32 winNum,
46335+ MV_ADDR_WIN *pAddrWin)
46336+{
46337+ MV_U32 win;
46338+ MV_PEX_DEC_WIN addrDecWin;
46339+
46340+
46341+ for(win = 0; win < PEX_MAX_TARGET_WIN -2 ; win++)
46342+ {
46343+ /* don't check our target or illegal targets */
46344+ if (winNum == win)
46345+ {
46346+ continue;
46347+ }
46348+
46349+ /* Get window parameters */
46350+ if (MV_OK != mvPexTargetWinGet(pexIf, win, &addrDecWin))
46351+ {
46352+ mvOsPrintf("pexWinOverlapDetect: ERR. TargetWinGet failed win=%x\n",
46353+ win);
46354+ return MV_ERROR;
46355+ }
46356+
46357+ /* Do not check disabled windows */
46358+ if (MV_FALSE == addrDecWin.enable)
46359+ {
46360+ continue;
46361+ }
46362+
46363+
46364+ if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
46365+ {
46366+ mvOsPrintf("pexWinOverlapDetect: winNum %d overlap current %d\n",
46367+ winNum, win);
46368+ return MV_TRUE;
46369+ }
46370+ }
46371+
46372+ return MV_FALSE;
46373+}
46374+
46375+/*******************************************************************************
46376+* pexIsWinWithinBar - Detect if address is within PEX bar boundries
46377+*
46378+* DESCRIPTION:
46379+*
46380+* INPUT:
46381+*
46382+* OUTPUT:
46383+* None.
46384+*
46385+* RETURN:
46386+* MV_TRUE if the given address window overlap current address
46387+* decode map, MV_FALSE otherwise.
46388+*
46389+*******************************************************************************/
46390+static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,
46391+ MV_ADDR_WIN *pAddrWin)
46392+{
46393+ MV_U32 bar;
46394+ MV_PEX_BAR addrDecWin;
46395+
46396+ for(bar = 0; bar < PEX_MAX_BARS; bar++)
46397+ {
46398+
46399+ /* Get window parameters */
46400+ if (MV_OK != mvPexBarGet(pexIf, bar, &addrDecWin))
46401+ {
46402+ mvOsPrintf("pexIsWinWithinBar: ERR. mvPexBarGet failed\n");
46403+ return MV_ERROR;
46404+ }
46405+
46406+ /* Do not check disabled bars */
46407+ if (MV_FALSE == addrDecWin.enable)
46408+ {
46409+ continue;
46410+ }
46411+
46412+
46413+ if(MV_TRUE == ctrlWinWithinWinTest(pAddrWin, &addrDecWin.addrWin))
46414+ {
46415+ return MV_TRUE;
46416+ }
46417+ }
46418+
46419+ return MV_FALSE;
46420+
46421+}
46422+
46423+/*******************************************************************************
46424+* pexBarOverlapDetect - Detect address windows overlapping
46425+*
46426+* DESCRIPTION:
46427+* This function detects address window overlapping of a given address
46428+* window in PEX BARs.
46429+*
46430+* INPUT:
46431+* pAddrWin - Address window to be checked.
46432+* bar - BAR to be accessed by slave.
46433+*
46434+* OUTPUT:
46435+* None.
46436+*
46437+* RETURN:
46438+* MV_TRUE if the given address window overlap current address
46439+* decode map, MV_FALSE otherwise.
46440+*
46441+*******************************************************************************/
46442+static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,
46443+ MV_U32 barNum,
46444+ MV_ADDR_WIN *pAddrWin)
46445+{
46446+ MV_U32 bar;
46447+ MV_PEX_BAR barDecWin;
46448+
46449+
46450+ for(bar = 0; bar < PEX_MAX_BARS; bar++)
46451+ {
46452+ /* don't check our target or illegal targets */
46453+ if (barNum == bar)
46454+ {
46455+ continue;
46456+ }
46457+
46458+ /* Get window parameters */
46459+ if (MV_OK != mvPexBarGet(pexIf, bar, &barDecWin))
46460+ {
46461+ mvOsPrintf("pexBarOverlapDetect: ERR. TargetWinGet failed\n");
46462+ return MV_ERROR;
46463+ }
46464+
46465+ /* don'nt check disabled bars */
46466+ if (barDecWin.enable == MV_FALSE)
46467+ {
46468+ continue;
46469+ }
46470+
46471+
46472+ if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &barDecWin.addrWin))
46473+ {
46474+ mvOsPrintf("pexBarOverlapDetect: winNum %d overlap current %d\n",
46475+ barNum, bar);
46476+ return MV_TRUE;
46477+ }
46478+ }
46479+
46480+ return MV_FALSE;
46481+}
46482+
46483+/*******************************************************************************
46484+* pexBarIsValid - Check if the given address window is valid
46485+*
46486+* DESCRIPTION:
46487+* PEX spec restrict BAR base to be aligned to BAR size.
46488+* This function checks if the given address window is valid.
46489+*
46490+* INPUT:
46491+* baseLow - 32bit low base address.
46492+* size - Window size.
46493+*
46494+* OUTPUT:
46495+* None.
46496+*
46497+* RETURN:
46498+* MV_TRUE if the address window is valid, MV_FALSE otherwise.
46499+*
46500+*******************************************************************************/
46501+static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size)
46502+{
46503+
46504+ /* PCI spec restrict BAR base to be aligned to BAR size */
46505+ if(MV_IS_NOT_ALIGN(baseLow, size))
46506+ {
46507+ return MV_ERROR;
46508+ }
46509+ else
46510+ {
46511+ return MV_TRUE;
46512+ }
46513+
46514+ return MV_TRUE;
46515+}
46516+
46517+/*******************************************************************************
46518+* pexBarRegInfoGet - Get BAR register information
46519+*
46520+* DESCRIPTION:
46521+* PEX BARs registers offsets are inconsecutive.
46522+* This function gets a PEX BAR register information like register offsets
46523+* and function location of the BAR.
46524+*
46525+* INPUT:
46526+* pexIf - PEX interface number.
46527+* bar - The PEX BAR in question.
46528+*
46529+* OUTPUT:
46530+* pBarRegInfo - BAR register info struct.
46531+*
46532+* RETURN:
46533+* MV_BAD_PARAM when bad parameters ,MV_ERROR on error ,othewise MV_OK
46534+*
46535+*******************************************************************************/
46536+static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf,
46537+ MV_U32 winNum,
46538+ PEX_WIN_REG_INFO *pWinRegInfo)
46539+{
46540+
46541+ if ((winNum >= 0)&&(winNum <=3))
46542+ {
46543+ pWinRegInfo->baseLowRegOffs = PEX_WIN0_3_BASE_REG(pexIf,winNum);
46544+ pWinRegInfo->baseHighRegOffs = 0;
46545+ pWinRegInfo->sizeRegOffs = PEX_WIN0_3_CTRL_REG(pexIf,winNum);
46546+ pWinRegInfo->remapLowRegOffs = PEX_WIN0_3_REMAP_REG(pexIf,winNum);
46547+ pWinRegInfo->remapHighRegOffs = 0;
46548+ }
46549+ else if ((winNum >= 4)&&(winNum <=5))
46550+ {
46551+ pWinRegInfo->baseLowRegOffs = PEX_WIN4_5_BASE_REG(pexIf,winNum);
46552+ pWinRegInfo->baseHighRegOffs = 0;
46553+ pWinRegInfo->sizeRegOffs = PEX_WIN4_5_CTRL_REG(pexIf,winNum);
46554+ pWinRegInfo->remapLowRegOffs = PEX_WIN4_5_REMAP_REG(pexIf,winNum);
46555+ pWinRegInfo->remapHighRegOffs = PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum);
46556+
46557+ }
46558+ else if (MV_PEX_WIN_DEFAULT == winNum)
46559+ {
46560+ pWinRegInfo->baseLowRegOffs = 0;
46561+ pWinRegInfo->baseHighRegOffs = 0;
46562+ pWinRegInfo->sizeRegOffs = PEX_WIN_DEFAULT_CTRL_REG(pexIf);
46563+ pWinRegInfo->remapLowRegOffs = 0;
46564+ pWinRegInfo->remapHighRegOffs = 0;
46565+ }
46566+ else if (MV_PEX_WIN_EXP_ROM == winNum)
46567+ {
46568+ pWinRegInfo->baseLowRegOffs = 0;
46569+ pWinRegInfo->baseHighRegOffs = 0;
46570+ pWinRegInfo->sizeRegOffs = PEX_WIN_EXP_ROM_CTRL_REG(pexIf);
46571+ pWinRegInfo->remapLowRegOffs = PEX_WIN_EXP_ROM_REMAP_REG(pexIf);
46572+ pWinRegInfo->remapHighRegOffs = 0;
46573+
46574+ }
46575+
46576+ return MV_OK;
46577+}
46578+
46579+/*******************************************************************************
46580+* pexBarNameGet - Get the string name of PEX BAR.
46581+*
46582+* DESCRIPTION:
46583+* This function get the string name of PEX BAR.
46584+*
46585+* INPUT:
46586+* bar - PEX bar number.
46587+*
46588+* OUTPUT:
46589+* None.
46590+*
46591+* RETURN:
46592+* pointer to the string name of PEX BAR.
46593+*
46594+*******************************************************************************/
46595+const MV_8* pexBarNameGet( MV_U32 bar )
46596+{
46597+ switch( bar )
46598+ {
46599+ case PEX_INTER_REGS_BAR:
46600+ return "Internal Regs Bar0....";
46601+ case PEX_DRAM_BAR:
46602+ return "DRAM Bar1.............";
46603+ case PEX_DEVICE_BAR:
46604+ return "Devices Bar2..........";
46605+ default:
46606+ return "Bar unknown";
46607+ }
46608+}
46609+/*******************************************************************************
46610+* mvPexAddrDecShow - Print the PEX address decode map (BARs and windows).
46611+*
46612+* DESCRIPTION:
46613+* This function print the PEX address decode map (BARs and windows).
46614+*
46615+* INPUT:
46616+* None.
46617+*
46618+* OUTPUT:
46619+* None.
46620+*
46621+* RETURN:
46622+* None.
46623+*
46624+*******************************************************************************/
46625+MV_VOID mvPexAddrDecShow(MV_VOID)
46626+{
46627+ MV_PEX_BAR pexBar;
46628+ MV_PEX_DEC_WIN win;
46629+ MV_U32 pexIf;
46630+ MV_U32 bar,winNum;
46631+
46632+ for( pexIf = 0; pexIf < mvCtrlPexMaxIfGet(); pexIf++ )
46633+ {
46634+ if (MV_FALSE == mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf)) continue;
46635+ mvOsOutput( "\n" );
46636+ mvOsOutput( "PEX%d:\n", pexIf );
46637+ mvOsOutput( "-----\n" );
46638+
46639+ mvOsOutput( "\nPex Bars \n\n");
46640+
46641+ for( bar = 0; bar < PEX_MAX_BARS; bar++ )
46642+ {
46643+ memset( &pexBar, 0, sizeof(MV_PEX_BAR) );
46644+
46645+ mvOsOutput( "%s ", pexBarNameGet(bar) );
46646+
46647+ if( mvPexBarGet( pexIf, bar, &pexBar ) == MV_OK )
46648+ {
46649+ if( pexBar.enable )
46650+ {
46651+ mvOsOutput( "base %08x, ", pexBar.addrWin.baseLow );
46652+ mvSizePrint( pexBar.addrWin.size );
46653+ mvOsOutput( "\n" );
46654+ }
46655+ else
46656+ mvOsOutput( "disable\n" );
46657+ }
46658+ }
46659+ mvOsOutput( "\nPex Decode Windows\n\n");
46660+
46661+ for( winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
46662+ {
46663+ memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
46664+
46665+ mvOsOutput( "win%d - ", winNum );
46666+
46667+ if ( mvPexTargetWinGet(pexIf,winNum,&win) == MV_OK)
46668+ {
46669+ if (win.enable)
46670+ {
46671+ mvOsOutput( "%s base %08x, ",
46672+ mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
46673+ mvOsOutput( "...." );
46674+ mvSizePrint( win.addrWin.size );
46675+
46676+ mvOsOutput( "\n" );
46677+ }
46678+ else
46679+ mvOsOutput( "disable\n" );
46680+
46681+
46682+ }
46683+ }
46684+
46685+ memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
46686+
46687+ mvOsOutput( "default win - " );
46688+
46689+ if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_DEFAULT, &win) == MV_OK)
46690+ {
46691+ mvOsOutput( "%s ",
46692+ mvCtrlTargetNameGet(win.target) );
46693+ mvOsOutput( "\n" );
46694+ }
46695+ memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
46696+
46697+ mvOsOutput( "Expansion ROM - " );
46698+
46699+ if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_EXP_ROM, &win) == MV_OK)
46700+ {
46701+ mvOsOutput( "%s ",
46702+ mvCtrlTargetNameGet(win.target) );
46703+ mvOsOutput( "\n" );
46704+ }
46705+
46706+ }
46707+}
46708+
46709+
46710diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h
46711new file mode 100644
46712index 0000000..c1555f6
46713--- /dev/null
46714+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h
46715@@ -0,0 +1,348 @@
46716+/*******************************************************************************
46717+Copyright (C) Marvell International Ltd. and its affiliates
46718+
46719+This software file (the "File") is owned and distributed by Marvell
46720+International Ltd. and/or its affiliates ("Marvell") under the following
46721+alternative licensing terms. Once you have made an election to distribute the
46722+File under one of the following license alternatives, please (i) delete this
46723+introductory statement regarding license alternatives, (ii) delete the two
46724+license alternatives that you have not elected to use and (iii) preserve the
46725+Marvell copyright notice above.
46726+
46727+********************************************************************************
46728+Marvell Commercial License Option
46729+
46730+If you received this File from Marvell and you have entered into a commercial
46731+license agreement (a "Commercial License") with Marvell, the File is licensed
46732+to you under the terms of the applicable Commercial License.
46733+
46734+********************************************************************************
46735+Marvell GPL License Option
46736+
46737+If you received this File from Marvell, you may opt to use, redistribute and/or
46738+modify this File in accordance with the terms and conditions of the General
46739+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
46740+available along with the File in the license.txt file or by writing to the Free
46741+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
46742+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
46743+
46744+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
46745+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
46746+DISCLAIMED. The GPL License provides additional details about this warranty
46747+disclaimer.
46748+********************************************************************************
46749+Marvell BSD License Option
46750+
46751+If you received this File from Marvell, you may opt to use, redistribute and/or
46752+modify this File under the following licensing terms.
46753+Redistribution and use in source and binary forms, with or without modification,
46754+are permitted provided that the following conditions are met:
46755+
46756+ * Redistributions of source code must retain the above copyright notice,
46757+ this list of conditions and the following disclaimer.
46758+
46759+ * Redistributions in binary form must reproduce the above copyright
46760+ notice, this list of conditions and the following disclaimer in the
46761+ documentation and/or other materials provided with the distribution.
46762+
46763+ * Neither the name of Marvell nor the names of its contributors may be
46764+ used to endorse or promote products derived from this software without
46765+ specific prior written permission.
46766+
46767+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
46768+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46769+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46770+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
46771+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46772+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46773+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
46774+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46775+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46776+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46777+
46778+*******************************************************************************/
46779+
46780+#ifndef __INCSysPEXH
46781+#define __INCSysPEXH
46782+
46783+#include "mvCommon.h"
46784+#include "ctrlEnv/sys/mvCpuIf.h"
46785+#include "ctrlEnv/mvCtrlEnvLib.h"
46786+#include "ctrlEnv/mvCtrlEnvAddrDec.h"
46787+
46788+/* 4KB granularity */
46789+#define MINIMUM_WINDOW_SIZE 0x1000
46790+#define MINIMUM_BAR_SIZE 0x1000
46791+#define MINIMUM_BAR_SIZE_MASK 0xFFFFF000
46792+#define BAR_SIZE_OFFS 12
46793+#define BAR_SIZE_MASK (0xFFFFF << BAR_SIZE_OFFS)
46794+
46795+
46796+
46797+#define MV_PEX_WIN_DEFAULT 6
46798+#define MV_PEX_WIN_EXP_ROM 7
46799+#define PEX_MAX_TARGET_WIN 8
46800+
46801+
46802+#define PEX_MAX_BARS 3
46803+#define PEX_INTER_REGS_BAR 0
46804+#define PEX_DRAM_BAR 1
46805+#define PEX_DEVICE_BAR 2
46806+
46807+/*************************************/
46808+/* PCI Express BAR Control Registers */
46809+/*************************************/
46810+#define PEX_BAR_CTRL_REG(pexIf,bar) (0x41804 + (bar-1)*4- (pexIf)*0x10000)
46811+#define PEX_EXP_ROM_BAR_CTRL_REG(pexIf) (0x4180C - (pexIf)*0x10000)
46812+
46813+
46814+/* PCI Express BAR Control Register */
46815+/* PEX_BAR_CTRL_REG (PXBCR) */
46816+
46817+#define PXBCR_BAR_EN BIT0
46818+#define PXBCR_BAR_SIZE_OFFS 16
46819+#define PXBCR_BAR_SIZE_MASK (0xffff << PXBCR_BAR_SIZE_OFFS)
46820+#define PXBCR_BAR_SIZE_ALIGNMENT 0x10000
46821+
46822+
46823+
46824+/* PCI Express Expansion ROM BAR Control Register */
46825+/* PEX_EXP_ROM_BAR_CTRL_REG (PXERBCR) */
46826+
46827+#define PXERBCR_EXPROM_EN BIT0
46828+#define PXERBCR_EXPROMSZ_OFFS 19
46829+#define PXERBCR_EXPROMSZ_MASK (0xf << PXERBCR_EXPROMSZ_OFFS)
46830+#define PXERBCR_EXPROMSZ_512KB (0x0 << PXERBCR_EXPROMSZ_OFFS)
46831+#define PXERBCR_EXPROMSZ_1024KB (0x1 << PXERBCR_EXPROMSZ_OFFS)
46832+#define PXERBCR_EXPROMSZ_2048KB (0x3 << PXERBCR_EXPROMSZ_OFFS)
46833+#define PXERBCR_EXPROMSZ_4096KB (0x7 << PXERBCR_EXPROMSZ_OFFS)
46834+
46835+/************************************************/
46836+/* PCI Express Address Window Control Registers */
46837+/************************************************/
46838+#define PEX_WIN0_3_CTRL_REG(pexIf,winNum) \
46839+ (0x41820 + (winNum) * 0x10 - (pexIf) * 0x10000)
46840+#define PEX_WIN0_3_BASE_REG(pexIf,winNum) \
46841+ (0x41824 + (winNum) * 0x10 - (pexIf) * 0x10000)
46842+#define PEX_WIN0_3_REMAP_REG(pexIf,winNum) \
46843+ (0x4182C + (winNum) * 0x10 - (pexIf) * 0x10000)
46844+#define PEX_WIN4_5_CTRL_REG(pexIf,winNum) \
46845+ (0x41860 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
46846+#define PEX_WIN4_5_BASE_REG(pexIf,winNum) \
46847+ (0x41864 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
46848+#define PEX_WIN4_5_REMAP_REG(pexIf,winNum) \
46849+ (0x4186C + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
46850+#define PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum) \
46851+ (0x41870 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
46852+
46853+#define PEX_WIN_DEFAULT_CTRL_REG(pexIf) (0x418B0 - (pexIf) * 0x10000)
46854+#define PEX_WIN_EXP_ROM_CTRL_REG(pexIf) (0x418C0 - (pexIf) * 0x10000)
46855+#define PEX_WIN_EXP_ROM_REMAP_REG(pexIf) (0x418C4 - (pexIf) * 0x10000)
46856+
46857+/* PCI Express Window Control Register */
46858+/* PEX_WIN_CTRL_REG (PXWCR) */
46859+
46860+#define PXWCR_WIN_EN BIT0 /* Window Enable.*/
46861+
46862+#define PXWCR_WIN_BAR_MAP_OFFS 1 /* Mapping to BAR.*/
46863+#define PXWCR_WIN_BAR_MAP_MASK BIT1
46864+#define PXWCR_WIN_BAR_MAP_BAR1 (0 << PXWCR_WIN_BAR_MAP_OFFS)
46865+#define PXWCR_WIN_BAR_MAP_BAR2 (1 << PXWCR_WIN_BAR_MAP_OFFS)
46866+
46867+#define PXWCR_TARGET_OFFS 4 /*Unit ID */
46868+#define PXWCR_TARGET_MASK (0xf << PXWCR_TARGET_OFFS)
46869+
46870+#define PXWCR_ATTRIB_OFFS 8 /* target attributes */
46871+#define PXWCR_ATTRIB_MASK (0xff << PXWCR_ATTRIB_OFFS)
46872+
46873+#define PXWCR_SIZE_OFFS 16 /* size */
46874+#define PXWCR_SIZE_MASK (0xffff << PXWCR_SIZE_OFFS)
46875+#define PXWCR_SIZE_ALIGNMENT 0x10000
46876+
46877+/* PCI Express Window Base Register */
46878+/* PEX_WIN_BASE_REG (PXWBR)*/
46879+
46880+#define PXWBR_BASE_OFFS 16 /* address[31:16] */
46881+#define PXWBR_BASE_MASK (0xffff << PXWBR_BASE_OFFS)
46882+#define PXWBR_BASE_ALIGNMENT 0x10000
46883+
46884+/* PCI Express Window Remap Register */
46885+/* PEX_WIN_REMAP_REG (PXWRR)*/
46886+
46887+#define PXWRR_REMAP_EN BIT0
46888+#define PXWRR_REMAP_OFFS 16
46889+#define PXWRR_REMAP_MASK (0xffff << PXWRR_REMAP_OFFS)
46890+#define PXWRR_REMAP_ALIGNMENT 0x10000
46891+
46892+/* PCI Express Window Remap (High) Register */
46893+/* PEX_WIN_REMAP_HIGH_REG (PXWRHR)*/
46894+
46895+#define PXWRHR_REMAP_HIGH_OFFS 0
46896+#define PXWRHR_REMAP_HIGH_MASK (0xffffffff << PXWRHR_REMAP_HIGH_OFFS)
46897+
46898+/* PCI Express Default Window Control Register */
46899+/* PEX_WIN_DEFAULT_CTRL_REG (PXWDCR) */
46900+
46901+#define PXWDCR_TARGET_OFFS 4 /*Unit ID */
46902+#define PXWDCR_TARGET_MASK (0xf << PXWDCR_TARGET_OFFS)
46903+#define PXWDCR_ATTRIB_OFFS 8 /* target attributes */
46904+#define PXWDCR_ATTRIB_MASK (0xff << PXWDCR_ATTRIB_OFFS)
46905+
46906+/* PCI Express Expansion ROM Window Control Register */
46907+/* PEX_WIN_EXP_ROM_CTRL_REG (PXWERCR)*/
46908+
46909+#define PXWERCR_TARGET_OFFS 4 /*Unit ID */
46910+#define PXWERCR_TARGET_MASK (0xf << PXWERCR_TARGET_OFFS)
46911+#define PXWERCR_ATTRIB_OFFS 8 /* target attributes */
46912+#define PXWERCR_ATTRIB_MASK (0xff << PXWERCR_ATTRIB_OFFS)
46913+
46914+/* PCI Express Expansion ROM Window Remap Register */
46915+/* PEX_WIN_EXP_ROM_REMAP_REG (PXWERRR)*/
46916+
46917+#define PXWERRR_REMAP_EN BIT0
46918+#define PXWERRR_REMAP_OFFS 16
46919+#define PXWERRR_REMAP_MASK (0xffff << PXWERRR_REMAP_OFFS)
46920+#define PXWERRR_REMAP_ALIGNMENT 0x10000
46921+
46922+
46923+
46924+/*PEX_MEMORY_BAR_BASE_ADDR(barNum) (PXMBBA)*/
46925+/* PCI Express BAR0 Internal Register*/
46926+/*PEX BAR0_INTER_REG (PXBIR)*/
46927+
46928+#define PXBIR_IOSPACE BIT0 /* Memory Space Indicator */
46929+
46930+#define PXBIR_TYPE_OFFS 1 /* BAR Type/Init Val. */
46931+#define PXBIR_TYPE_MASK (0x3 << PXBIR_TYPE_OFFS)
46932+#define PXBIR_TYPE_32BIT_ADDR (0x0 << PXBIR_TYPE_OFFS)
46933+#define PXBIR_TYPE_64BIT_ADDR (0x2 << PXBIR_TYPE_OFFS)
46934+
46935+#define PXBIR_PREFETCH_EN BIT3 /* Prefetch Enable */
46936+
46937+#define PXBIR_BASE_OFFS 20 /* Base address. Address bits [31:20] */
46938+#define PXBIR_BASE_MASK (0xfff << PXBIR_BASE_OFFS)
46939+#define PXBIR_BASE_ALIGNMET (1 << PXBIR_BASE_OFFS)
46940+
46941+
46942+/* PCI Express BAR0 Internal (High) Register*/
46943+/*PEX BAR0_INTER_REG_HIGH (PXBIRH)*/
46944+
46945+#define PXBIRH_BASE_OFFS 0 /* Base address. Bits [63:32] */
46946+#define PXBIRH_BASE_MASK (0xffffffff << PBBHR_BASE_OFFS)
46947+
46948+
46949+#define PEX_BAR_DEFAULT_ATTRIB 0xc /* Memory - Prefetch - 64 bit address */
46950+#define PEX_BAR0_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
46951+#define PEX_BAR1_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
46952+#define PEX_BAR2_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
46953+
46954+
46955+/* PCI Express BAR1 Register */
46956+/* PCI Express BAR2 Register*/
46957+/*PEX BAR1_REG (PXBR)*/
46958+/*PEX BAR2_REG (PXBR)*/
46959+
46960+#define PXBR_IOSPACE BIT0 /* Memory Space Indicator */
46961+
46962+#define PXBR_TYPE_OFFS 1 /* BAR Type/Init Val. */
46963+#define PXBR_TYPE_MASK (0x3 << PXBR_TYPE_OFFS)
46964+#define PXBR_TYPE_32BIT_ADDR (0x0 << PXBR_TYPE_OFFS)
46965+#define PXBR_TYPE_64BIT_ADDR (0x2 << PXBR_TYPE_OFFS)
46966+
46967+#define PXBR_PREFETCH_EN BIT3 /* Prefetch Enable */
46968+
46969+#define PXBR_BASE_OFFS 16 /* Base address. Address bits [31:16] */
46970+#define PXBR_BASE_MASK (0xffff << PXBR_BASE_OFFS)
46971+#define PXBR_BASE_ALIGNMET (1 << PXBR_BASE_OFFS)
46972+
46973+
46974+/* PCI Express BAR1 (High) Register*/
46975+/* PCI Express BAR2 (High) Register*/
46976+/*PEX BAR1_REG_HIGH (PXBRH)*/
46977+/*PEX BAR2_REG_HIGH (PXBRH)*/
46978+
46979+#define PXBRH_BASE_OFFS 0 /* Base address. Address bits [63:32] */
46980+#define PXBRH_BASE_MASK (0xffffffff << PXBRH_BASE_OFFS)
46981+
46982+/* PCI Express Expansion ROM BAR Register*/
46983+/*PEX_EXPANSION_ROM_BASE_ADDR_REG (PXERBAR)*/
46984+
46985+#define PXERBAR_EXPROMEN BIT0 /* Expansion ROM Enable */
46986+
46987+#define PXERBAR_BASE_512K_OFFS 19 /* Expansion ROM Base Address */
46988+#define PXERBAR_BASE_512K_MASK (0x1fff << PXERBAR_BASE_512K_OFFS)
46989+
46990+#define PXERBAR_BASE_1MB_OFFS 20 /* Expansion ROM Base Address */
46991+#define PXERBAR_BASE_1MB_MASK (0xfff << PXERBAR_BASE_1MB_OFFS)
46992+
46993+#define PXERBAR_BASE_2MB_OFFS 21 /* Expansion ROM Base Address */
46994+#define PXERBAR_BASE_2MB_MASK (0x7ff << PXERBAR_BASE_2MB_OFFS)
46995+
46996+#define PXERBAR_BASE_4MB_OFFS 22 /* Expansion ROM Base Address */
46997+#define PXERBAR_BASE_4MB_MASK (0x3ff << PXERBAR_BASE_4MB_OFFS)
46998+
46999+/* PEX Bar attributes */
47000+typedef struct _mvPexBar
47001+{
47002+ MV_ADDR_WIN addrWin; /* An address window*/
47003+ MV_BOOL enable; /* Address decode window is enabled/disabled */
47004+
47005+}MV_PEX_BAR;
47006+
47007+/* PEX Remap Window attributes */
47008+typedef struct _mvPexRemapWin
47009+{
47010+ MV_ADDR_WIN addrWin; /* An address window*/
47011+ MV_BOOL enable; /* Address decode window is enabled/disabled */
47012+
47013+}MV_PEX_REMAP_WIN;
47014+
47015+/* PEX Remap Window attributes */
47016+typedef struct _mvPexDecWin
47017+{
47018+ MV_TARGET target;
47019+ MV_ADDR_WIN addrWin; /* An address window*/
47020+ MV_U32 targetBar;
47021+ MV_U8 attrib; /* chip select attributes */
47022+ MV_TARGET_ID targetId; /* Target Id of this MV_TARGET */
47023+ MV_BOOL enable; /* Address decode window is enabled/disabled */
47024+
47025+}MV_PEX_DEC_WIN;
47026+
47027+/* Global Functions prototypes */
47028+/* mvPexHalInit - Initialize PEX interfaces*/
47029+MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType);
47030+
47031+
47032+/* mvPexTargetWinSet - Set PEX to peripheral target address window BAR*/
47033+MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum,
47034+ MV_PEX_DEC_WIN *pAddrDecWin);
47035+
47036+/* mvPexTargetWinGet - Get PEX to peripheral target address window*/
47037+MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum,
47038+ MV_PEX_DEC_WIN *pAddrDecWin);
47039+
47040+/* mvPexTargetWinEnable - Enable/disable a PEX BAR window*/
47041+MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable);
47042+
47043+/* mvPexTargetWinRemap - Set PEX to target address window remap.*/
47044+MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum,
47045+ MV_PEX_REMAP_WIN *pAddrWin);
47046+
47047+/* mvPexTargetWinRemapEnable -enable\disable a PEX Window remap.*/
47048+MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum,
47049+ MV_BOOL enable);
47050+
47051+/* mvPexBarSet - Set PEX bar address and size */
47052+MV_STATUS mvPexBarSet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);
47053+
47054+/* mvPexBarGet - Get PEX bar address and size */
47055+MV_STATUS mvPexBarGet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);
47056+
47057+/* mvPexBarEnable - enable\disable a PEX bar*/
47058+MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable);
47059+
47060+/* mvPexAddrDecShow - Display address decode windows attributes */
47061+MV_VOID mvPexAddrDecShow(MV_VOID);
47062+
47063+#endif
47064diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c
47065new file mode 100644
47066index 0000000..4c0485f
47067--- /dev/null
47068+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c
47069@@ -0,0 +1,430 @@
47070+/*******************************************************************************
47071+Copyright (C) Marvell International Ltd. and its affiliates
47072+
47073+This software file (the "File") is owned and distributed by Marvell
47074+International Ltd. and/or its affiliates ("Marvell") under the following
47075+alternative licensing terms. Once you have made an election to distribute the
47076+File under one of the following license alternatives, please (i) delete this
47077+introductory statement regarding license alternatives, (ii) delete the two
47078+license alternatives that you have not elected to use and (iii) preserve the
47079+Marvell copyright notice above.
47080+
47081+********************************************************************************
47082+Marvell Commercial License Option
47083+
47084+If you received this File from Marvell and you have entered into a commercial
47085+license agreement (a "Commercial License") with Marvell, the File is licensed
47086+to you under the terms of the applicable Commercial License.
47087+
47088+********************************************************************************
47089+Marvell GPL License Option
47090+
47091+If you received this File from Marvell, you may opt to use, redistribute and/or
47092+modify this File in accordance with the terms and conditions of the General
47093+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
47094+available along with the File in the license.txt file or by writing to the Free
47095+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
47096+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
47097+
47098+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
47099+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
47100+DISCLAIMED. The GPL License provides additional details about this warranty
47101+disclaimer.
47102+********************************************************************************
47103+Marvell BSD License Option
47104+
47105+If you received this File from Marvell, you may opt to use, redistribute and/or
47106+modify this File under the following licensing terms.
47107+Redistribution and use in source and binary forms, with or without modification,
47108+are permitted provided that the following conditions are met:
47109+
47110+ * Redistributions of source code must retain the above copyright notice,
47111+ this list of conditions and the following disclaimer.
47112+
47113+ * Redistributions in binary form must reproduce the above copyright
47114+ notice, this list of conditions and the following disclaimer in the
47115+ documentation and/or other materials provided with the distribution.
47116+
47117+ * Neither the name of Marvell nor the names of its contributors may be
47118+ used to endorse or promote products derived from this software without
47119+ specific prior written permission.
47120+
47121+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
47122+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47123+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47124+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
47125+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
47126+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47127+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
47128+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47129+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47130+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47131+
47132+*******************************************************************************/
47133+
47134+
47135+#include "mvTypes.h"
47136+#include "mvCommon.h"
47137+#include "mvOs.h"
47138+#include "ctrlEnv/mvCtrlEnvLib.h"
47139+#include "cpu/mvCpu.h"
47140+#include "ctrlEnv/sys/mvCpuIf.h"
47141+#include "sata/CoreDriver/mvRegs.h"
47142+#include "ctrlEnv/sys/mvSysSata.h"
47143+
47144+MV_TARGET sataAddrDecPrioTab[] =
47145+{
47146+#if defined(MV_INCLUDE_SDRAM_CS0)
47147+ SDRAM_CS0,
47148+#endif
47149+#if defined(MV_INCLUDE_SDRAM_CS1)
47150+ SDRAM_CS1,
47151+#endif
47152+#if defined(MV_INCLUDE_SDRAM_CS2)
47153+ SDRAM_CS2,
47154+#endif
47155+#if defined(MV_INCLUDE_SDRAM_CS3)
47156+ SDRAM_CS3,
47157+#endif
47158+#if defined(MV_INCLUDE_PEX)
47159+ PEX0_MEM,
47160+#endif
47161+ TBL_TERM
47162+};
47163+
47164+
47165+/*******************************************************************************
47166+* sataWinOverlapDetect - Detect SATA address windows overlapping
47167+*
47168+* DESCRIPTION:
47169+* An unpredicted behaviur is expected in case SATA address decode
47170+* windows overlapps.
47171+* This function detects SATA address decode windows overlapping of a
47172+* specified window. The function does not check the window itself for
47173+* overlapping. The function also skipps disabled address decode windows.
47174+*
47175+* INPUT:
47176+* winNum - address decode window number.
47177+* pAddrDecWin - An address decode window struct.
47178+*
47179+* OUTPUT:
47180+* None.
47181+*
47182+* RETURN:
47183+* MV_TRUE if the given address window overlap current address
47184+* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
47185+* from registers.
47186+*
47187+*******************************************************************************/
47188+static MV_STATUS sataWinOverlapDetect(int dev, MV_U32 winNum,
47189+ MV_ADDR_WIN *pAddrWin)
47190+{
47191+ MV_U32 winNumIndex;
47192+ MV_SATA_DEC_WIN addrDecWin;
47193+
47194+ for(winNumIndex=0; winNumIndex<MV_SATA_MAX_ADDR_DECODE_WIN; winNumIndex++)
47195+ {
47196+ /* Do not check window itself */
47197+ if (winNumIndex == winNum)
47198+ {
47199+ continue;
47200+ }
47201+
47202+ /* Get window parameters */
47203+ if (MV_OK != mvSataWinGet(dev, winNumIndex, &addrDecWin))
47204+ {
47205+ mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
47206+ return MV_ERROR;
47207+ }
47208+
47209+ /* Do not check disabled windows */
47210+ if(addrDecWin.enable == MV_FALSE)
47211+ {
47212+ continue;
47213+ }
47214+
47215+ if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
47216+ {
47217+ return MV_TRUE;
47218+ }
47219+ }
47220+ return MV_FALSE;
47221+}
47222+
47223+
47224+/*******************************************************************************
47225+* mvSataWinSet - Set SATA target address window
47226+*
47227+* DESCRIPTION:
47228+* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
47229+* address window, also known as address decode window.
47230+* After setting this target window, the SATA will be able to access the
47231+* target within the address window.
47232+*
47233+* INPUT:
47234+* winNum - SATA target address decode window number.
47235+* pAddrDecWin - SATA target window data structure.
47236+*
47237+* OUTPUT:
47238+* None.
47239+*
47240+* RETURN:
47241+* MV_ERROR if address window overlapps with other address decode windows.
47242+* MV_BAD_PARAM if base address is invalid parameter or target is
47243+* unknown.
47244+*
47245+*******************************************************************************/
47246+MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)
47247+{
47248+ MV_TARGET_ATTRIB targetAttribs;
47249+ MV_DEC_REGS decRegs;
47250+
47251+ /* Parameter checking */
47252+ if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)
47253+ {
47254+ mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
47255+ return MV_BAD_PARAM;
47256+ }
47257+
47258+ /* Check if the requested window overlapps with current windows */
47259+ if (MV_TRUE == sataWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))
47260+ {
47261+ mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
47262+ return MV_ERROR;
47263+ }
47264+
47265+ /* check if address is aligned to the size */
47266+ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
47267+ {
47268+ mvOsPrintf("mvSataWinSet:Error setting SATA window %d to "\
47269+ "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
47270+ winNum,
47271+ mvCtrlTargetNameGet(pAddrDecWin->target),
47272+ pAddrDecWin->addrWin.baseLow,
47273+ pAddrDecWin->addrWin.size);
47274+ return MV_ERROR;
47275+ }
47276+
47277+ decRegs.baseReg = 0;
47278+ decRegs.sizeReg = 0;
47279+
47280+ if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
47281+ {
47282+ mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
47283+ return MV_ERROR;
47284+ }
47285+
47286+ mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
47287+
47288+ /* set attributes */
47289+ decRegs.sizeReg &= ~MV_SATA_WIN_ATTR_MASK;
47290+ decRegs.sizeReg |= (targetAttribs.attrib << MV_SATA_WIN_ATTR_OFFSET);
47291+
47292+ /* set target ID */
47293+ decRegs.sizeReg &= ~MV_SATA_WIN_TARGET_MASK;
47294+ decRegs.sizeReg |= (targetAttribs.targetId << MV_SATA_WIN_TARGET_OFFSET);
47295+
47296+ if (pAddrDecWin->enable == MV_TRUE)
47297+ {
47298+ decRegs.sizeReg |= MV_SATA_WIN_ENABLE_MASK;
47299+ }
47300+ else
47301+ {
47302+ decRegs.sizeReg &= ~MV_SATA_WIN_ENABLE_MASK;
47303+ }
47304+
47305+ MV_REG_WRITE( MV_SATA_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);
47306+ MV_REG_WRITE( MV_SATA_WIN_BASE_REG(dev, winNum), decRegs.baseReg);
47307+
47308+ return MV_OK;
47309+}
47310+
47311+/*******************************************************************************
47312+* mvSataWinGet - Get SATA peripheral target address window.
47313+*
47314+* DESCRIPTION:
47315+* Get SATA peripheral target address window.
47316+*
47317+* INPUT:
47318+* winNum - SATA target address decode window number.
47319+*
47320+* OUTPUT:
47321+* pAddrDecWin - SATA target window data structure.
47322+*
47323+* RETURN:
47324+* MV_ERROR if register parameters are invalid.
47325+*
47326+*******************************************************************************/
47327+MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)
47328+{
47329+ MV_DEC_REGS decRegs;
47330+ MV_TARGET_ATTRIB targetAttrib;
47331+
47332+ /* Parameter checking */
47333+ if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)
47334+ {
47335+ mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
47336+ __FUNCTION__, dev, winNum);
47337+ return MV_NOT_SUPPORTED;
47338+ }
47339+
47340+ decRegs.baseReg = MV_REG_READ( MV_SATA_WIN_BASE_REG(dev, winNum) );
47341+ decRegs.sizeReg = MV_REG_READ( MV_SATA_WIN_CTRL_REG(dev, winNum) );
47342+
47343+ if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
47344+ {
47345+ mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
47346+ return MV_ERROR;
47347+ }
47348+
47349+ /* attrib and targetId */
47350+ targetAttrib.attrib = (decRegs.sizeReg & MV_SATA_WIN_ATTR_MASK) >>
47351+ MV_SATA_WIN_ATTR_OFFSET;
47352+ targetAttrib.targetId = (decRegs.sizeReg & MV_SATA_WIN_TARGET_MASK) >>
47353+ MV_SATA_WIN_TARGET_OFFSET;
47354+
47355+ pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
47356+
47357+ /* Check if window is enabled */
47358+ if(decRegs.sizeReg & MV_SATA_WIN_ENABLE_MASK)
47359+ {
47360+ pAddrDecWin->enable = MV_TRUE;
47361+ }
47362+ else
47363+ {
47364+ pAddrDecWin->enable = MV_FALSE;
47365+ }
47366+ return MV_OK;
47367+}
47368+/*******************************************************************************
47369+* mvSataAddrDecShow - Print the SATA address decode map.
47370+*
47371+* DESCRIPTION:
47372+* This function print the SATA address decode map.
47373+*
47374+* INPUT:
47375+* None.
47376+*
47377+* OUTPUT:
47378+* None.
47379+*
47380+* RETURN:
47381+* None.
47382+*
47383+*******************************************************************************/
47384+MV_VOID mvSataAddrDecShow(MV_VOID)
47385+{
47386+
47387+ MV_SATA_DEC_WIN win;
47388+ int i,j;
47389+
47390+
47391+
47392+ for( j = 0; j < MV_SATA_MAX_CHAN; j++ )
47393+ {
47394+ if (MV_FALSE == mvCtrlPwrClckGet(SATA_UNIT_ID, j))
47395+ return;
47396+
47397+ mvOsOutput( "\n" );
47398+ mvOsOutput( "SATA %d:\n", j );
47399+ mvOsOutput( "----\n" );
47400+
47401+ for( i = 0; i < MV_SATA_MAX_ADDR_DECODE_WIN; i++ )
47402+ {
47403+ memset( &win, 0, sizeof(MV_SATA_DEC_WIN) );
47404+
47405+ mvOsOutput( "win%d - ", i );
47406+
47407+ if( mvSataWinGet(j, i, &win ) == MV_OK )
47408+ {
47409+ if( win.enable )
47410+ {
47411+ mvOsOutput( "%s base %08x, ",
47412+ mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
47413+ mvOsOutput( "...." );
47414+
47415+ mvSizePrint( win.addrWin.size );
47416+
47417+ mvOsOutput( "\n" );
47418+ }
47419+ else
47420+ mvOsOutput( "disable\n" );
47421+ }
47422+ }
47423+ }
47424+}
47425+
47426+
47427+/*******************************************************************************
47428+* mvSataWinInit - Initialize the integrated SATA target address window.
47429+*
47430+* DESCRIPTION:
47431+* Initialize the SATA peripheral target address window.
47432+*
47433+* INPUT:
47434+*
47435+*
47436+* OUTPUT:
47437+*
47438+*
47439+* RETURN:
47440+* MV_ERROR if register parameters are invalid.
47441+*
47442+*******************************************************************************/
47443+MV_STATUS mvSataWinInit(MV_VOID)
47444+{
47445+ int winNum;
47446+ MV_SATA_DEC_WIN sataWin;
47447+ MV_CPU_DEC_WIN cpuAddrDecWin;
47448+ MV_U32 status, winPrioIndex = 0;
47449+
47450+ /* Initiate Sata address decode */
47451+
47452+ /* First disable all address decode windows */
47453+ for(winNum = 0; winNum < MV_SATA_MAX_ADDR_DECODE_WIN; winNum++)
47454+ {
47455+ MV_U32 regVal = MV_REG_READ(MV_SATA_WIN_CTRL_REG(0, winNum));
47456+ regVal &= ~MV_SATA_WIN_ENABLE_MASK;
47457+ MV_REG_WRITE(MV_SATA_WIN_CTRL_REG(0, winNum), regVal);
47458+ }
47459+
47460+ winNum = 0;
47461+ while( (sataAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
47462+ (winNum < MV_SATA_MAX_ADDR_DECODE_WIN) )
47463+ {
47464+ /* first get attributes from CPU If */
47465+ status = mvCpuIfTargetWinGet(sataAddrDecPrioTab[winPrioIndex],
47466+ &cpuAddrDecWin);
47467+
47468+ if(MV_NO_SUCH == status)
47469+ {
47470+ winPrioIndex++;
47471+ continue;
47472+ }
47473+ if (MV_OK != status)
47474+ {
47475+ mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
47476+ return MV_ERROR;
47477+ }
47478+
47479+ if (cpuAddrDecWin.enable == MV_TRUE)
47480+ {
47481+ sataWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
47482+ sataWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
47483+ sataWin.addrWin.size = cpuAddrDecWin.addrWin.size;
47484+ sataWin.enable = MV_TRUE;
47485+ sataWin.target = sataAddrDecPrioTab[winPrioIndex];
47486+
47487+ if(MV_OK != mvSataWinSet(0/*dev*/, winNum, &sataWin))
47488+ {
47489+ return MV_ERROR;
47490+ }
47491+ winNum++;
47492+ }
47493+ winPrioIndex++;
47494+ }
47495+ return MV_OK;
47496+}
47497+
47498+
47499+
47500diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h
47501new file mode 100644
47502index 0000000..e401992
47503--- /dev/null
47504+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h
47505@@ -0,0 +1,128 @@
47506+
47507+/*******************************************************************************
47508+Copyright (C) Marvell International Ltd. and its affiliates
47509+
47510+This software file (the "File") is owned and distributed by Marvell
47511+International Ltd. and/or its affiliates ("Marvell") under the following
47512+alternative licensing terms. Once you have made an election to distribute the
47513+File under one of the following license alternatives, please (i) delete this
47514+introductory statement regarding license alternatives, (ii) delete the two
47515+license alternatives that you have not elected to use and (iii) preserve the
47516+Marvell copyright notice above.
47517+
47518+********************************************************************************
47519+Marvell Commercial License Option
47520+
47521+If you received this File from Marvell and you have entered into a commercial
47522+license agreement (a "Commercial License") with Marvell, the File is licensed
47523+to you under the terms of the applicable Commercial License.
47524+
47525+********************************************************************************
47526+Marvell GPL License Option
47527+
47528+If you received this File from Marvell, you may opt to use, redistribute and/or
47529+modify this File in accordance with the terms and conditions of the General
47530+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
47531+available along with the File in the license.txt file or by writing to the Free
47532+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
47533+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
47534+
47535+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
47536+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
47537+DISCLAIMED. The GPL License provides additional details about this warranty
47538+disclaimer.
47539+********************************************************************************
47540+Marvell BSD License Option
47541+
47542+If you received this File from Marvell, you may opt to use, redistribute and/or
47543+modify this File under the following licensing terms.
47544+Redistribution and use in source and binary forms, with or without modification,
47545+are permitted provided that the following conditions are met:
47546+
47547+ * Redistributions of source code must retain the above copyright notice,
47548+ this list of conditions and the following disclaimer.
47549+
47550+ * Redistributions in binary form must reproduce the above copyright
47551+ notice, this list of conditions and the following disclaimer in the
47552+ documentation and/or other materials provided with the distribution.
47553+
47554+ * Neither the name of Marvell nor the names of its contributors may be
47555+ used to endorse or promote products derived from this software without
47556+ specific prior written permission.
47557+
47558+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
47559+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47560+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47561+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
47562+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
47563+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47564+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
47565+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47566+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47567+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47568+
47569+*******************************************************************************/
47570+#ifndef __INCMVSysSataAddrDech
47571+#define __INCMVSysSataAddrDech
47572+
47573+#include "mvCommon.h"
47574+#include "ctrlEnv/mvCtrlEnvLib.h"
47575+#include "ctrlEnv/sys/mvCpuIf.h"
47576+
47577+
47578+#ifdef __cplusplus
47579+extern "C" {
47580+#endif
47581+
47582+typedef struct _mvSataDecWin
47583+{
47584+ MV_TARGET target;
47585+ MV_ADDR_WIN addrWin; /* An address window*/
47586+ MV_BOOL enable; /* Address decode window is enabled/disabled */
47587+
47588+} MV_SATA_DEC_WIN;
47589+
47590+
47591+#define MV_SATA_MAX_ADDR_DECODE_WIN 4
47592+
47593+#define MV_SATA_WIN_CTRL_REG(dev, win) (SATA_REG_BASE + 0x30 + ((win)<<4))
47594+#define MV_SATA_WIN_BASE_REG(dev, win) (SATA_REG_BASE + 0x34 + ((win)<<4))
47595+
47596+/* BITs in Bridge Interrupt Cause and Mask registers */
47597+#define MV_SATA_ADDR_DECODE_ERROR_BIT 0
47598+#define MV_SATA_ADDR_DECODE_ERROR_MASK (1<<MV_SATA_ADDR_DECODE_ERROR_BIT)
47599+
47600+/* BITs in Windows 0-3 Control and Base Registers */
47601+#define MV_SATA_WIN_ENABLE_BIT 0
47602+#define MV_SATA_WIN_ENABLE_MASK (1<<MV_SATA_WIN_ENABLE_BIT)
47603+
47604+#define MV_SATA_WIN_TARGET_OFFSET 4
47605+#define MV_SATA_WIN_TARGET_MASK (0xF<<MV_SATA_WIN_TARGET_OFFSET)
47606+
47607+#define MV_SATA_WIN_ATTR_OFFSET 8
47608+#define MV_SATA_WIN_ATTR_MASK (0xFF<<MV_SATA_WIN_ATTR_OFFSET)
47609+
47610+#define MV_SATA_WIN_SIZE_OFFSET 16
47611+#define MV_SATA_WIN_SIZE_MASK (0xFFFF<<MV_SATA_WIN_SIZE_OFFSET)
47612+
47613+#define MV_SATA_WIN_BASE_OFFSET 16
47614+#define MV_SATA_WIN_BASE_MASK (0xFFFF<<MV_SATA_WIN_BASE_OFFSET)
47615+
47616+MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);
47617+MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);
47618+MV_STATUS mvSataWinByTargetGet(MV_TARGET target, MV_SATA_DEC_WIN *pAddrDecWin);
47619+MV_STATUS mvSataWinInit(MV_VOID);
47620+MV_VOID mvSataAddrDecShow(MV_VOID);
47621+
47622+
47623+#ifdef __cplusplus
47624+}
47625+#endif
47626+
47627+
47628+#endif
47629+
47630+
47631+
47632+
47633+
47634diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c
47635new file mode 100644
47636index 0000000..682f6f1
47637--- /dev/null
47638+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c
47639@@ -0,0 +1,427 @@
47640+/*******************************************************************************
47641+Copyright (C) Marvell International Ltd. and its affiliates
47642+
47643+This software file (the "File") is owned and distributed by Marvell
47644+International Ltd. and/or its affiliates ("Marvell") under the following
47645+alternative licensing terms. Once you have made an election to distribute the
47646+File under one of the following license alternatives, please (i) delete this
47647+introductory statement regarding license alternatives, (ii) delete the two
47648+license alternatives that you have not elected to use and (iii) preserve the
47649+Marvell copyright notice above.
47650+
47651+********************************************************************************
47652+Marvell Commercial License Option
47653+
47654+If you received this File from Marvell and you have entered into a commercial
47655+license agreement (a "Commercial License") with Marvell, the File is licensed
47656+to you under the terms of the applicable Commercial License.
47657+
47658+********************************************************************************
47659+Marvell GPL License Option
47660+
47661+If you received this File from Marvell, you may opt to use, redistribute and/or
47662+modify this File in accordance with the terms and conditions of the General
47663+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
47664+available along with the File in the license.txt file or by writing to the Free
47665+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
47666+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
47667+
47668+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
47669+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
47670+DISCLAIMED. The GPL License provides additional details about this warranty
47671+disclaimer.
47672+********************************************************************************
47673+Marvell BSD License Option
47674+
47675+If you received this File from Marvell, you may opt to use, redistribute and/or
47676+modify this File under the following licensing terms.
47677+Redistribution and use in source and binary forms, with or without modification,
47678+are permitted provided that the following conditions are met:
47679+
47680+ * Redistributions of source code must retain the above copyright notice,
47681+ this list of conditions and the following disclaimer.
47682+
47683+ * Redistributions in binary form must reproduce the above copyright
47684+ notice, this list of conditions and the following disclaimer in the
47685+ documentation and/or other materials provided with the distribution.
47686+
47687+ * Neither the name of Marvell nor the names of its contributors may be
47688+ used to endorse or promote products derived from this software without
47689+ specific prior written permission.
47690+
47691+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
47692+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47693+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47694+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
47695+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
47696+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47697+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
47698+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47699+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47700+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47701+
47702+*******************************************************************************/
47703+
47704+
47705+#include "mvTypes.h"
47706+#include "mvCommon.h"
47707+#include "mvOs.h"
47708+#include "ctrlEnv/mvCtrlEnvLib.h"
47709+#include "cpu/mvCpu.h"
47710+#include "ctrlEnv/sys/mvCpuIf.h"
47711+#include "mvRegs.h"
47712+#include "ctrlEnv/sys/mvSysSdmmc.h"
47713+
47714+MV_TARGET sdmmcAddrDecPrioTab[] =
47715+{
47716+#if defined(MV_INCLUDE_SDRAM_CS0)
47717+ SDRAM_CS0,
47718+#endif
47719+#if defined(MV_INCLUDE_SDRAM_CS1)
47720+ SDRAM_CS1,
47721+#endif
47722+#if defined(MV_INCLUDE_SDRAM_CS2)
47723+ SDRAM_CS2,
47724+#endif
47725+#if defined(MV_INCLUDE_SDRAM_CS3)
47726+ SDRAM_CS3,
47727+#endif
47728+#if defined(MV_INCLUDE_PEX)
47729+ PEX0_MEM,
47730+#endif
47731+ TBL_TERM
47732+};
47733+
47734+
47735+/*******************************************************************************
47736+* sdmmcWinOverlapDetect - Detect SDMMC address windows overlapping
47737+*
47738+* DESCRIPTION:
47739+* An unpredicted behaviur is expected in case SDMMC address decode
47740+* windows overlapps.
47741+* This function detects SDMMC address decode windows overlapping of a
47742+* specified window. The function does not check the window itself for
47743+* overlapping. The function also skipps disabled address decode windows.
47744+*
47745+* INPUT:
47746+* winNum - address decode window number.
47747+* pAddrDecWin - An address decode window struct.
47748+*
47749+* OUTPUT:
47750+* None.
47751+*
47752+* RETURN:
47753+* MV_TRUE if the given address window overlap current address
47754+* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
47755+* from registers.
47756+*
47757+*******************************************************************************/
47758+static MV_STATUS sdmmcWinOverlapDetect(int dev, MV_U32 winNum,
47759+ MV_ADDR_WIN *pAddrWin)
47760+{
47761+ MV_U32 winNumIndex;
47762+ MV_SDMMC_DEC_WIN addrDecWin;
47763+
47764+ for(winNumIndex=0; winNumIndex<MV_SDMMC_MAX_ADDR_DECODE_WIN; winNumIndex++)
47765+ {
47766+ /* Do not check window itself */
47767+ if (winNumIndex == winNum)
47768+ {
47769+ continue;
47770+ }
47771+
47772+ /* Get window parameters */
47773+ if (MV_OK != mvSdmmcWinGet(dev, winNumIndex, &addrDecWin))
47774+ {
47775+ mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
47776+ return MV_ERROR;
47777+ }
47778+
47779+ /* Do not check disabled windows */
47780+ if(addrDecWin.enable == MV_FALSE)
47781+ {
47782+ continue;
47783+ }
47784+
47785+ if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
47786+ {
47787+ return MV_TRUE;
47788+ }
47789+ }
47790+ return MV_FALSE;
47791+}
47792+
47793+
47794+/*******************************************************************************
47795+* mvSdmmcWinSet - Set SDMMC target address window
47796+*
47797+* DESCRIPTION:
47798+* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
47799+* address window, also known as address decode window.
47800+* After setting this target window, the SDMMC will be able to access the
47801+* target within the address window.
47802+*
47803+* INPUT:
47804+* winNum - SDMMC target address decode window number.
47805+* pAddrDecWin - SDMMC target window data structure.
47806+*
47807+* OUTPUT:
47808+* None.
47809+*
47810+* RETURN:
47811+* MV_ERROR if address window overlapps with other address decode windows.
47812+* MV_BAD_PARAM if base address is invalid parameter or target is
47813+* unknown.
47814+*
47815+*******************************************************************************/
47816+MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
47817+{
47818+ MV_TARGET_ATTRIB targetAttribs;
47819+ MV_DEC_REGS decRegs;
47820+
47821+ /* Parameter checking */
47822+ if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
47823+ {
47824+ mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
47825+ return MV_BAD_PARAM;
47826+ }
47827+
47828+ /* Check if the requested window overlapps with current windows */
47829+ if (MV_TRUE == sdmmcWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))
47830+ {
47831+ mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
47832+ return MV_ERROR;
47833+ }
47834+
47835+ /* check if address is aligned to the size */
47836+ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
47837+ {
47838+ mvOsPrintf("mvSdmmcWinSet:Error setting SDMMC window %d to "\
47839+ "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
47840+ winNum,
47841+ mvCtrlTargetNameGet(pAddrDecWin->target),
47842+ pAddrDecWin->addrWin.baseLow,
47843+ pAddrDecWin->addrWin.size);
47844+ return MV_ERROR;
47845+ }
47846+
47847+ decRegs.baseReg = 0;
47848+ decRegs.sizeReg = 0;
47849+
47850+ if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
47851+ {
47852+ mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
47853+ return MV_ERROR;
47854+ }
47855+
47856+ mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
47857+
47858+ /* set attributes */
47859+ decRegs.sizeReg &= ~MV_SDMMC_WIN_ATTR_MASK;
47860+ decRegs.sizeReg |= (targetAttribs.attrib << MV_SDMMC_WIN_ATTR_OFFSET);
47861+
47862+ /* set target ID */
47863+ decRegs.sizeReg &= ~MV_SDMMC_WIN_TARGET_MASK;
47864+ decRegs.sizeReg |= (targetAttribs.targetId << MV_SDMMC_WIN_TARGET_OFFSET);
47865+
47866+ if (pAddrDecWin->enable == MV_TRUE)
47867+ {
47868+ decRegs.sizeReg |= MV_SDMMC_WIN_ENABLE_MASK;
47869+ }
47870+ else
47871+ {
47872+ decRegs.sizeReg &= ~MV_SDMMC_WIN_ENABLE_MASK;
47873+ }
47874+
47875+ MV_REG_WRITE( MV_SDMMC_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);
47876+ MV_REG_WRITE( MV_SDMMC_WIN_BASE_REG(dev, winNum), decRegs.baseReg);
47877+
47878+ return MV_OK;
47879+}
47880+
47881+/*******************************************************************************
47882+* mvSdmmcWinGet - Get SDMMC peripheral target address window.
47883+*
47884+* DESCRIPTION:
47885+* Get SDMMC peripheral target address window.
47886+*
47887+* INPUT:
47888+* winNum - SDMMC target address decode window number.
47889+*d
47890+* OUTPUT:
47891+* pAddrDecWin - SDMMC target window data structure.
47892+*
47893+* RETURN:
47894+* MV_ERROR if register parameters are invalid.
47895+*
47896+*******************************************************************************/
47897+MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
47898+{
47899+ MV_DEC_REGS decRegs;
47900+ MV_TARGET_ATTRIB targetAttrib;
47901+
47902+ /* Parameter checking */
47903+ if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
47904+ {
47905+ mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
47906+ __FUNCTION__, dev, winNum);
47907+ return MV_NOT_SUPPORTED;
47908+ }
47909+
47910+ decRegs.baseReg = MV_REG_READ( MV_SDMMC_WIN_BASE_REG(dev, winNum) );
47911+ decRegs.sizeReg = MV_REG_READ( MV_SDMMC_WIN_CTRL_REG(dev, winNum) );
47912+
47913+ if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
47914+ {
47915+ mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
47916+ return MV_ERROR;
47917+ }
47918+
47919+ /* attrib and targetId */
47920+ targetAttrib.attrib = (decRegs.sizeReg & MV_SDMMC_WIN_ATTR_MASK) >>
47921+ MV_SDMMC_WIN_ATTR_OFFSET;
47922+ targetAttrib.targetId = (decRegs.sizeReg & MV_SDMMC_WIN_TARGET_MASK) >>
47923+ MV_SDMMC_WIN_TARGET_OFFSET;
47924+
47925+ pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
47926+
47927+ /* Check if window is enabled */
47928+ if(decRegs.sizeReg & MV_SDMMC_WIN_ENABLE_MASK)
47929+ {
47930+ pAddrDecWin->enable = MV_TRUE;
47931+ }
47932+ else
47933+ {
47934+ pAddrDecWin->enable = MV_FALSE;
47935+ }
47936+ return MV_OK;
47937+}
47938+/*******************************************************************************
47939+* mvSdmmcAddrDecShow - Print the SDMMC address decode map.
47940+*
47941+* DESCRIPTION:
47942+* This function print the SDMMC address decode map.
47943+*
47944+* INPUT:
47945+* None.
47946+*
47947+* OUTPUT:
47948+* None.
47949+*
47950+* RETURN:
47951+* None.
47952+*
47953+*******************************************************************************/
47954+MV_VOID mvSdmmcAddrDecShow(MV_VOID)
47955+{
47956+
47957+ MV_SDMMC_DEC_WIN win;
47958+ int i,j=0;
47959+
47960+
47961+
47962+ if (MV_FALSE == mvCtrlPwrClckGet(SDIO_UNIT_ID, 0))
47963+ return;
47964+
47965+ mvOsOutput( "\n" );
47966+ mvOsOutput( "SDMMC %d:\n", j );
47967+ mvOsOutput( "----\n" );
47968+
47969+ for( i = 0; i < MV_SDMMC_MAX_ADDR_DECODE_WIN; i++ )
47970+ {
47971+ memset( &win, 0, sizeof(MV_SDMMC_DEC_WIN) );
47972+
47973+ mvOsOutput( "win%d - ", i );
47974+
47975+ if( mvSdmmcWinGet(j, i, &win ) == MV_OK )
47976+ {
47977+ if( win.enable )
47978+ {
47979+ mvOsOutput( "%s base %08x, ",
47980+ mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
47981+ mvOsOutput( "...." );
47982+
47983+ mvSizePrint( win.addrWin.size );
47984+
47985+ mvOsOutput( "\n" );
47986+ }
47987+ else
47988+ mvOsOutput( "disable\n" );
47989+ }
47990+ }
47991+}
47992+
47993+
47994+/*******************************************************************************
47995+* mvSdmmcWinInit - Initialize the integrated SDMMC target address window.
47996+*
47997+* DESCRIPTION:
47998+* Initialize the SDMMC peripheral target address window.
47999+*
48000+* INPUT:
48001+*
48002+*
48003+* OUTPUT:
48004+*
48005+*
48006+* RETURN:
48007+* MV_ERROR if register parameters are invalid.
48008+*
48009+*******************************************************************************/
48010+MV_STATUS mvSdmmcWinInit(MV_VOID)
48011+{
48012+ int winNum;
48013+ MV_SDMMC_DEC_WIN sdmmcWin;
48014+ MV_CPU_DEC_WIN cpuAddrDecWin;
48015+ MV_U32 status, winPrioIndex = 0;
48016+
48017+ /* Initiate Sdmmc address decode */
48018+
48019+ /* First disable all address decode windows */
48020+ for(winNum = 0; winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN; winNum++)
48021+ {
48022+ MV_U32 regVal = MV_REG_READ(MV_SDMMC_WIN_CTRL_REG(0, winNum));
48023+ regVal &= ~MV_SDMMC_WIN_ENABLE_MASK;
48024+ MV_REG_WRITE(MV_SDMMC_WIN_CTRL_REG(0, winNum), regVal);
48025+ }
48026+
48027+ winNum = 0;
48028+ while( (sdmmcAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
48029+ (winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN) )
48030+ {
48031+ /* first get attributes from CPU If */
48032+ status = mvCpuIfTargetWinGet(sdmmcAddrDecPrioTab[winPrioIndex],
48033+ &cpuAddrDecWin);
48034+
48035+ if(MV_NO_SUCH == status)
48036+ {
48037+ winPrioIndex++;
48038+ continue;
48039+ }
48040+ if (MV_OK != status)
48041+ {
48042+ mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
48043+ return MV_ERROR;
48044+ }
48045+
48046+ if (cpuAddrDecWin.enable == MV_TRUE)
48047+ {
48048+ sdmmcWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
48049+ sdmmcWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
48050+ sdmmcWin.addrWin.size = cpuAddrDecWin.addrWin.size;
48051+ sdmmcWin.enable = MV_TRUE;
48052+ sdmmcWin.target = sdmmcAddrDecPrioTab[winPrioIndex];
48053+
48054+ if(MV_OK != mvSdmmcWinSet(0/*dev*/, winNum, &sdmmcWin))
48055+ {
48056+ return MV_ERROR;
48057+ }
48058+ winNum++;
48059+ }
48060+ winPrioIndex++;
48061+ }
48062+ return MV_OK;
48063+}
48064+
48065+
48066+
48067diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h
48068new file mode 100644
48069index 0000000..f8357c1
48070--- /dev/null
48071+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h
48072@@ -0,0 +1,125 @@
48073+
48074+/*******************************************************************************
48075+Copyright (C) Marvell International Ltd. and its affiliates
48076+
48077+This software file (the "File") is owned and distributed by Marvell
48078+International Ltd. and/or its affiliates ("Marvell") under the following
48079+alternative licensing terms. Once you have made an election to distribute the
48080+File under one of the following license alternatives, please (i) delete this
48081+introductory statement regarding license alternatives, (ii) delete the two
48082+license alternatives that you have not elected to use and (iii) preserve the
48083+Marvell copyright notice above.
48084+
48085+********************************************************************************
48086+Marvell Commercial License Option
48087+
48088+If you received this File from Marvell and you have entered into a commercial
48089+license agreement (a "Commercial License") with Marvell, the File is licensed
48090+to you under the terms of the applicable Commercial License.
48091+
48092+********************************************************************************
48093+Marvell GPL License Option
48094+
48095+If you received this File from Marvell, you may opt to use, redistribute and/or
48096+modify this File in accordance with the terms and conditions of the General
48097+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
48098+available along with the File in the license.txt file or by writing to the Free
48099+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
48100+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
48101+
48102+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
48103+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
48104+DISCLAIMED. The GPL License provides additional details about this warranty
48105+disclaimer.
48106+********************************************************************************
48107+Marvell BSD License Option
48108+
48109+If you received this File from Marvell, you may opt to use, redistribute and/or
48110+modify this File under the following licensing terms.
48111+Redistribution and use in source and binary forms, with or without modification,
48112+are permitted provided that the following conditions are met:
48113+
48114+ * Redistributions of source code must retain the above copyright notice,
48115+ this list of conditions and the following disclaimer.
48116+
48117+ * Redistributions in binary form must reproduce the above copyright
48118+ notice, this list of conditions and the following disclaimer in the
48119+ documentation and/or other materials provided with the distribution.
48120+
48121+ * Neither the name of Marvell nor the names of its contributors may be
48122+ used to endorse or promote products derived from this software without
48123+ specific prior written permission.
48124+
48125+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
48126+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48127+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48128+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
48129+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48130+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48131+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
48132+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48133+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48134+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48135+
48136+*******************************************************************************/
48137+#ifndef __INCMVSysSdmmcAddrDech
48138+#define __INCMVSysSdmmcAddrDech
48139+
48140+#include "mvCommon.h"
48141+#include "ctrlEnv/mvCtrlEnvLib.h"
48142+#include "ctrlEnv/sys/mvCpuIf.h"
48143+
48144+
48145+#ifdef __cplusplus
48146+extern "C" {
48147+#endif
48148+
48149+typedef struct _mvSdmmcDecWin
48150+{
48151+ MV_TARGET target;
48152+ MV_ADDR_WIN addrWin; /* An address window*/
48153+ MV_BOOL enable; /* Address decode window is enabled/disabled */
48154+
48155+} MV_SDMMC_DEC_WIN;
48156+
48157+
48158+#define MV_SDMMC_MAX_ADDR_DECODE_WIN 4
48159+
48160+#define MV_SDMMC_WIN_CTRL_REG(dev, win) (MV_SDIO_REG_BASE + 0x108 + ((win)<<3))
48161+#define MV_SDMMC_WIN_BASE_REG(dev, win) (MV_SDIO_REG_BASE + 0x10c + ((win)<<3))
48162+
48163+
48164+/* BITs in Windows 0-3 Control and Base Registers */
48165+#define MV_SDMMC_WIN_ENABLE_BIT 0
48166+#define MV_SDMMC_WIN_ENABLE_MASK (1<<MV_SDMMC_WIN_ENABLE_BIT)
48167+
48168+#define MV_SDMMC_WIN_TARGET_OFFSET 4
48169+#define MV_SDMMC_WIN_TARGET_MASK (0xF<<MV_SDMMC_WIN_TARGET_OFFSET)
48170+
48171+#define MV_SDMMC_WIN_ATTR_OFFSET 8
48172+#define MV_SDMMC_WIN_ATTR_MASK (0xFF<<MV_SDMMC_WIN_ATTR_OFFSET)
48173+
48174+#define MV_SDMMC_WIN_SIZE_OFFSET 16
48175+#define MV_SDMMC_WIN_SIZE_MASK (0xFFFF<<MV_SDMMC_WIN_SIZE_OFFSET)
48176+
48177+#define MV_SDMMC_WIN_BASE_OFFSET 16
48178+#define MV_SDMMC_WIN_BASE_MASK (0xFFFF<<MV_SDMMC_WIN_BASE_OFFSET)
48179+
48180+MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);
48181+MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);
48182+MV_STATUS mvSdmmcWinByTargetGet(MV_TARGET target, MV_SDMMC_DEC_WIN *pAddrDecWin);
48183+MV_STATUS mvSdmmcWinInit(MV_VOID);
48184+MV_VOID mvSdmmcAddrDecShow(MV_VOID);
48185+
48186+
48187+#ifdef __cplusplus
48188+}
48189+#endif
48190+
48191+
48192+#endif
48193+
48194+
48195+
48196+
48197+
48198diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c
48199new file mode 100644
48200index 0000000..159d79f
48201--- /dev/null
48202+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c
48203@@ -0,0 +1,462 @@
48204+/*******************************************************************************
48205+Copyright (C) Marvell International Ltd. and its affiliates
48206+
48207+This software file (the "File") is owned and distributed by Marvell
48208+International Ltd. and/or its affiliates ("Marvell") under the following
48209+alternative licensing terms. Once you have made an election to distribute the
48210+File under one of the following license alternatives, please (i) delete this
48211+introductory statement regarding license alternatives, (ii) delete the two
48212+license alternatives that you have not elected to use and (iii) preserve the
48213+Marvell copyright notice above.
48214+
48215+********************************************************************************
48216+Marvell Commercial License Option
48217+
48218+If you received this File from Marvell and you have entered into a commercial
48219+license agreement (a "Commercial License") with Marvell, the File is licensed
48220+to you under the terms of the applicable Commercial License.
48221+
48222+********************************************************************************
48223+Marvell GPL License Option
48224+
48225+If you received this File from Marvell, you may opt to use, redistribute and/or
48226+modify this File in accordance with the terms and conditions of the General
48227+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
48228+available along with the File in the license.txt file or by writing to the Free
48229+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
48230+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
48231+
48232+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
48233+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
48234+DISCLAIMED. The GPL License provides additional details about this warranty
48235+disclaimer.
48236+********************************************************************************
48237+Marvell BSD License Option
48238+
48239+If you received this File from Marvell, you may opt to use, redistribute and/or
48240+modify this File under the following licensing terms.
48241+Redistribution and use in source and binary forms, with or without modification,
48242+are permitted provided that the following conditions are met:
48243+
48244+ * Redistributions of source code must retain the above copyright notice,
48245+ this list of conditions and the following disclaimer.
48246+
48247+ * Redistributions in binary form must reproduce the above copyright
48248+ notice, this list of conditions and the following disclaimer in the
48249+ documentation and/or other materials provided with the distribution.
48250+
48251+ * Neither the name of Marvell nor the names of its contributors may be
48252+ used to endorse or promote products derived from this software without
48253+ specific prior written permission.
48254+
48255+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
48256+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48257+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48258+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
48259+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48260+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48261+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
48262+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48263+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48264+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48265+
48266+*******************************************************************************/
48267+
48268+#include "mvSysTdm.h"
48269+
48270+
48271+/* defines */
48272+#ifdef MV_DEBUG
48273+ #define DB(x) x
48274+#else
48275+ #define DB(x)
48276+#endif
48277+
48278+static MV_TARGET tdmAddrDecPrioTap[] =
48279+{
48280+ PEX0_MEM,
48281+ SDRAM_CS0,
48282+ SDRAM_CS1,
48283+ SDRAM_CS2,
48284+ SDRAM_CS3,
48285+ DEVICE_CS0,
48286+ DEVICE_CS1,
48287+ DEVICE_CS2,
48288+ DEV_BOOCS,
48289+ PEX0_IO,
48290+ TBL_TERM
48291+};
48292+
48293+static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
48294+
48295+/*******************************************************************************
48296+* mvTdmWinInit - Initialize TDM address decode windows
48297+*
48298+* DESCRIPTION:
48299+* This function initialize TDM window decode unit. It set the
48300+* default address decode
48301+* windows of the unit.
48302+*
48303+* INPUT:
48304+* None.
48305+*
48306+* OUTPUT:
48307+* None.
48308+*
48309+* RETURN:
48310+* MV_ERROR if setting fail.
48311+*******************************************************************************/
48312+
48313+MV_STATUS mvTdmWinInit(void)
48314+{
48315+ MV_U32 winNum;
48316+ MV_U32 winPrioIndex = 0;
48317+ MV_CPU_DEC_WIN cpuAddrDecWin;
48318+ MV_TDM_DEC_WIN tdmWin;
48319+ MV_STATUS status;
48320+
48321+ /*Disable all windows*/
48322+ for (winNum = 0; winNum < TDM_MBUS_MAX_WIN; winNum++)
48323+ {
48324+ mvTdmWinEnable(winNum, MV_FALSE);
48325+ }
48326+
48327+ for (winNum = 0; ((tdmAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
48328+ (winNum < TDM_MBUS_MAX_WIN)); )
48329+ {
48330+ status = mvCpuIfTargetWinGet(tdmAddrDecPrioTap[winPrioIndex],
48331+ &cpuAddrDecWin);
48332+ if (MV_NO_SUCH == status)
48333+ {
48334+ winPrioIndex++;
48335+ continue;
48336+ }
48337+ if (MV_OK != status)
48338+ {
48339+ mvOsPrintf("mvTdmInit: ERR. mvCpuIfTargetWinGet failed\n");
48340+ return MV_ERROR;
48341+ }
48342+
48343+ if (cpuAddrDecWin.enable == MV_TRUE)
48344+ {
48345+ tdmWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
48346+ tdmWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
48347+ tdmWin.addrWin.size = cpuAddrDecWin.addrWin.size;
48348+ tdmWin.enable = MV_TRUE;
48349+ tdmWin.target = tdmAddrDecPrioTap[winPrioIndex];
48350+ if (MV_OK != mvTdmWinSet(winNum, &tdmWin))
48351+ {
48352+ return MV_ERROR;
48353+ }
48354+ winNum++;
48355+ }
48356+ winPrioIndex++;
48357+ }
48358+ return MV_OK;
48359+}
48360+
48361+/*******************************************************************************
48362+* mvTdmWinSet - Set TDM target address window
48363+*
48364+* DESCRIPTION:
48365+* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
48366+* address window, also known as address decode window.
48367+* After setting this target window, the TDM will be able to access the
48368+* target within the address window.
48369+*
48370+* INPUT:
48371+* winNum - TDM to target address decode window number.
48372+* pAddrDecWin - TDM target window data structure.
48373+*
48374+* OUTPUT:
48375+* None.
48376+*
48377+* RETURN:
48378+* MV_ERROR if address window overlapps with other address decode windows.
48379+* MV_BAD_PARAM if base address is invalid parameter or target is
48380+* unknown.
48381+*
48382+*******************************************************************************/
48383+
48384+MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
48385+{
48386+ MV_TARGET_ATTRIB targetAttribs;
48387+ MV_DEC_REGS decRegs;
48388+ MV_U32 ctrlReg = 0;
48389+
48390+ /* Parameter checking */
48391+ if (winNum >= TDM_MBUS_MAX_WIN)
48392+ {
48393+ mvOsPrintf("mvTdmWinSet: ERR. Invalid win num %d\n",winNum);
48394+ return MV_BAD_PARAM;
48395+ }
48396+
48397+ /* Check if the requested window overlapps with current windows */
48398+ if (MV_TRUE == tdmWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
48399+ {
48400+ mvOsPrintf("mvTdmWinSet: ERR. Window %d overlap\n", winNum);
48401+ return MV_ERROR;
48402+ }
48403+
48404+ /* check if address is aligned to the size */
48405+ if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
48406+ {
48407+ mvOsPrintf("mvTdmWinSet: Error setting TDM window %d to "\
48408+ "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
48409+ winNum,
48410+ mvCtrlTargetNameGet(pAddrDecWin->target),
48411+ pAddrDecWin->addrWin.baseLow,
48412+ pAddrDecWin->addrWin.size);
48413+ return MV_ERROR;
48414+ }
48415+
48416+ decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
48417+ decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
48418+
48419+ if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
48420+ {
48421+ mvOsPrintf("mvTdmWinSet: mvCtrlAddrDecToReg Failed\n");
48422+ return MV_ERROR;
48423+ }
48424+
48425+ mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
48426+
48427+ /* for the safe side we disable the window before writing the new
48428+ values */
48429+ mvTdmWinEnable(winNum, MV_FALSE);
48430+
48431+ ctrlReg |= (targetAttribs.attrib << TDM_WIN_ATTRIB_OFFS);
48432+ ctrlReg |= (targetAttribs.targetId << TDM_WIN_TARGET_OFFS);
48433+ ctrlReg |= (decRegs.sizeReg & TDM_WIN_SIZE_MASK);
48434+
48435+ /* Write to address base and control registers */
48436+ MV_REG_WRITE(TDM_WIN_BASE_REG(winNum), decRegs.baseReg);
48437+ MV_REG_WRITE(TDM_WIN_CTRL_REG(winNum), ctrlReg);
48438+ /* Enable address decode target window */
48439+ if (pAddrDecWin->enable == MV_TRUE)
48440+ {
48441+ mvTdmWinEnable(winNum, MV_TRUE);
48442+ }
48443+ return MV_OK;
48444+}
48445+
48446+/*******************************************************************************
48447+* mvTdmWinGet - Get peripheral target address window.
48448+*
48449+* DESCRIPTION:
48450+* Get TDM peripheral target address window.
48451+*
48452+* INPUT:
48453+* winNum - TDM to target address decode window number.
48454+*
48455+* OUTPUT:
48456+* pAddrDecWin - TDM target window data structure.
48457+*
48458+* RETURN:
48459+* MV_ERROR if register parameters are invalid.
48460+*
48461+*******************************************************************************/
48462+
48463+MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
48464+{
48465+
48466+ MV_DEC_REGS decRegs;
48467+ MV_TARGET_ATTRIB targetAttrib;
48468+
48469+ /* Parameter checking */
48470+ if (winNum >= TDM_MBUS_MAX_WIN)
48471+ {
48472+ mvOsPrintf("mvTdmWinGet: ERR. Invalid winNum %d\n", winNum);
48473+ return MV_NOT_SUPPORTED;
48474+ }
48475+
48476+ decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
48477+ decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
48478+
48479+ if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
48480+ {
48481+ mvOsPrintf("mvTdmWinGet: mvCtrlRegToAddrDec Failed \n");
48482+ return MV_ERROR;
48483+ }
48484+
48485+ /* attrib and targetId */
48486+ targetAttrib.attrib =
48487+ (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ATTRIB_MASK) >> TDM_WIN_ATTRIB_OFFS;
48488+ targetAttrib.targetId =
48489+ (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_TARGET_MASK) >> TDM_WIN_TARGET_OFFS;
48490+
48491+ pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
48492+
48493+ /* Check if window is enabled */
48494+ if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
48495+ {
48496+ pAddrDecWin->enable = MV_TRUE;
48497+ }
48498+ else
48499+ {
48500+ pAddrDecWin->enable = MV_FALSE;
48501+ }
48502+
48503+ return MV_OK;
48504+}
48505+
48506+/*******************************************************************************
48507+* mvTdmWinEnable - Enable/disable a TDM to target address window
48508+*
48509+* DESCRIPTION:
48510+* This function enable/disable a TDM to target address window.
48511+* According to parameter 'enable' the routine will enable the
48512+* window, thus enabling TDM accesses (before enabling the window it is
48513+* tested for overlapping). Otherwise, the window will be disabled.
48514+*
48515+* INPUT:
48516+* winNum - TDM to target address decode window number.
48517+* enable - Enable/disable parameter.
48518+*
48519+* OUTPUT:
48520+* N/A
48521+*
48522+* RETURN:
48523+* MV_ERROR if decode window number was wrong or enabled window overlapps.
48524+*
48525+*******************************************************************************/
48526+MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable)
48527+{
48528+ MV_TDM_DEC_WIN addrDecWin;
48529+
48530+ if (MV_TRUE == enable)
48531+ {
48532+ if (winNum >= TDM_MBUS_MAX_WIN)
48533+ {
48534+ mvOsPrintf("mvTdmWinEnable:ERR. Invalid winNum%d\n",winNum);
48535+ return MV_ERROR;
48536+ }
48537+
48538+ /* First check for overlap with other enabled windows */
48539+ /* Get current window */
48540+ if (MV_OK != mvTdmWinGet(winNum, &addrDecWin))
48541+ {
48542+ mvOsPrintf("mvTdmWinEnable:ERR. targetWinGet fail\n");
48543+ return MV_ERROR;
48544+ }
48545+ /* Check for overlapping */
48546+ if (MV_FALSE == tdmWinOverlapDetect(winNum, &(addrDecWin.addrWin)))
48547+ {
48548+ /* No Overlap. Enable address decode target window */
48549+ MV_REG_BIT_SET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
48550+ }
48551+ else
48552+ { /* Overlap detected */
48553+ mvOsPrintf("mvTdmWinEnable:ERR. Overlap detected\n");
48554+ return MV_ERROR;
48555+ }
48556+ }
48557+ else
48558+ {
48559+ MV_REG_BIT_RESET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
48560+ }
48561+ return MV_OK;
48562+}
48563+
48564+
48565+/*******************************************************************************
48566+* tdmWinOverlapDetect - Detect TDM address windows overlapping
48567+*
48568+* DESCRIPTION:
48569+* An unpredicted behaviour is expected in case TDM address decode
48570+* windows overlapps.
48571+* This function detects TDM address decode windows overlapping of a
48572+* specified window. The function does not check the window itself for
48573+* overlapping. The function also skipps disabled address decode windows.
48574+*
48575+* INPUT:
48576+* winNum - address decode window number.
48577+* pAddrDecWin - An address decode window struct.
48578+*
48579+* OUTPUT:
48580+* None.
48581+*
48582+* RETURN:
48583+* MV_TRUE if the given address window overlap current address
48584+* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
48585+* from registers.
48586+*
48587+*******************************************************************************/
48588+static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
48589+{
48590+ MV_U32 winNumIndex;
48591+ MV_TDM_DEC_WIN addrDecWin;
48592+
48593+ for (winNumIndex = 0; winNumIndex < TDM_MBUS_MAX_WIN; winNumIndex++)
48594+ {
48595+ /* Do not check window itself */
48596+ if (winNumIndex == winNum)
48597+ {
48598+ continue;
48599+ }
48600+ /* Do not check disabled windows */
48601+ if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
48602+ {
48603+ /* Get window parameters */
48604+ if (MV_OK != mvTdmWinGet(winNumIndex, &addrDecWin))
48605+ {
48606+ DB(mvOsPrintf("dmaWinOverlapDetect: ERR. TargetWinGet failed\n"));
48607+ return MV_ERROR;
48608+ }
48609+
48610+ if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
48611+ {
48612+ return MV_TRUE;
48613+ }
48614+ }
48615+ }
48616+ return MV_FALSE;
48617+}
48618+
48619+/*******************************************************************************
48620+* mvTdmAddrDecShow - Print the TDM address decode map.
48621+*
48622+* DESCRIPTION:
48623+* This function print the TDM address decode map.
48624+*
48625+* INPUT:
48626+* None.
48627+*
48628+* OUTPUT:
48629+* None.
48630+*
48631+* RETURN:
48632+* None.
48633+*
48634+*******************************************************************************/
48635+MV_VOID mvTdmAddrDecShow(MV_VOID)
48636+{
48637+ MV_TDM_DEC_WIN win;
48638+ int i;
48639+
48640+ mvOsOutput( "\n" );
48641+ mvOsOutput( "TDM:\n" );
48642+ mvOsOutput( "----\n" );
48643+
48644+ for( i = 0; i < TDM_MBUS_MAX_WIN; i++ )
48645+ {
48646+ memset( &win, 0, sizeof(MV_TDM_DEC_WIN) );
48647+
48648+ mvOsOutput( "win%d - ", i );
48649+
48650+ if (mvTdmWinGet(i, &win ) == MV_OK )
48651+ {
48652+ if( win.enable )
48653+ {
48654+ mvOsOutput( "%s base %08x, ",
48655+ mvCtrlTargetNameGet(win.target), win.addrWin.baseLow);
48656+ mvOsOutput( "...." );
48657+ mvSizePrint( win.addrWin.size );
48658+ mvOsOutput( "\n" );
48659+ }
48660+ else
48661+ mvOsOutput( "disable\n" );
48662+ }
48663+ }
48664+}
48665+
48666diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h
48667new file mode 100644
48668index 0000000..3603095
48669--- /dev/null
48670+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h
48671@@ -0,0 +1,106 @@
48672+/*******************************************************************************
48673+Copyright (C) Marvell International Ltd. and its affiliates
48674+
48675+This software file (the "File") is owned and distributed by Marvell
48676+International Ltd. and/or its affiliates ("Marvell") under the following
48677+alternative licensing terms. Once you have made an election to distribute the
48678+File under one of the following license alternatives, please (i) delete this
48679+introductory statement regarding license alternatives, (ii) delete the two
48680+license alternatives that you have not elected to use and (iii) preserve the
48681+Marvell copyright notice above.
48682+
48683+********************************************************************************
48684+Marvell Commercial License Option
48685+
48686+If you received this File from Marvell and you have entered into a commercial
48687+license agreement (a "Commercial License") with Marvell, the File is licensed
48688+to you under the terms of the applicable Commercial License.
48689+
48690+********************************************************************************
48691+Marvell GPL License Option
48692+
48693+If you received this File from Marvell, you may opt to use, redistribute and/or
48694+modify this File in accordance with the terms and conditions of the General
48695+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
48696+available along with the File in the license.txt file or by writing to the Free
48697+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
48698+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
48699+
48700+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
48701+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
48702+DISCLAIMED. The GPL License provides additional details about this warranty
48703+disclaimer.
48704+********************************************************************************
48705+Marvell BSD License Option
48706+
48707+If you received this File from Marvell, you may opt to use, redistribute and/or
48708+modify this File under the following licensing terms.
48709+Redistribution and use in source and binary forms, with or without modification,
48710+are permitted provided that the following conditions are met:
48711+
48712+ * Redistributions of source code must retain the above copyright notice,
48713+ this list of conditions and the following disclaimer.
48714+
48715+ * Redistributions in binary form must reproduce the above copyright
48716+ notice, this list of conditions and the following disclaimer in the
48717+ documentation and/or other materials provided with the distribution.
48718+
48719+ * Neither the name of Marvell nor the names of its contributors may be
48720+ used to endorse or promote products derived from this software without
48721+ specific prior written permission.
48722+
48723+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
48724+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48725+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48726+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
48727+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48728+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48729+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
48730+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48731+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48732+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48733+
48734+*******************************************************************************/
48735+
48736+#ifndef __INCmvSysTdmh
48737+#define __INCmvSysTdmh
48738+
48739+#include "ctrlEnv/sys/mvCpuIf.h"
48740+#include "ctrlEnv/mvCtrlEnvLib.h"
48741+#include "ctrlEnv/mvCtrlEnvAddrDec.h"
48742+
48743+typedef struct _mvTdmDecWin
48744+{
48745+ MV_TARGET target;
48746+ MV_ADDR_WIN addrWin; /* An address window*/
48747+ MV_BOOL enable; /* Address decode window is enabled/disabled */
48748+} MV_TDM_DEC_WIN;
48749+
48750+MV_STATUS mvTdmWinInit(MV_VOID);
48751+MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);
48752+MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);
48753+MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable);
48754+MV_VOID mvTdmAddrDecShow(MV_VOID);
48755+
48756+
48757+#define TDM_MBUS_MAX_WIN 4
48758+#define TDM_WIN_CTRL_REG(win) ((TDM_REG_BASE + 0x4030) + (win<<4))
48759+#define TDM_WIN_BASE_REG(win) ((TDM_REG_BASE +0x4034) + (win<<4))
48760+
48761+/* TDM_WIN_CTRL_REG bits */
48762+#define TDM_WIN_ENABLE_OFFS 0
48763+#define TDM_WIN_ENABLE_MASK (1<<TDM_WIN_ENABLE_OFFS)
48764+#define TDM_WIN_ENABLE 1
48765+#define TDM_WIN_TARGET_OFFS 4
48766+#define TDM_WIN_TARGET_MASK (0xf<<TDM_WIN_TARGET_OFFS)
48767+#define TDM_WIN_ATTRIB_OFFS 8
48768+#define TDM_WIN_ATTRIB_MASK (0xff<<TDM_WIN_ATTRIB_OFFS)
48769+#define TDM_WIN_SIZE_OFFS 16
48770+#define TDM_WIN_SIZE_MASK (0xffff<<TDM_WIN_SIZE_OFFS)
48771+
48772+/* TDM_WIN_BASE_REG bits */
48773+#define TDM_BASE_OFFS 16
48774+#define TDM_BASE_MASK (0xffff<<TDM_BASE_OFFS)
48775+
48776+#endif /*__INCmvSysTdmh*/
48777+
48778diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c
48779new file mode 100644
48780index 0000000..8cd0018
48781--- /dev/null
48782+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c
48783@@ -0,0 +1,591 @@
48784+/*******************************************************************************
48785+Copyright (C) Marvell International Ltd. and its affiliates
48786+
48787+This software file (the "File") is owned and distributed by Marvell
48788+International Ltd. and/or its affiliates ("Marvell") under the following
48789+alternative licensing terms. Once you have made an election to distribute the
48790+File under one of the following license alternatives, please (i) delete this
48791+introductory statement regarding license alternatives, (ii) delete the two
48792+license alternatives that you have not elected to use and (iii) preserve the
48793+Marvell copyright notice above.
48794+
48795+********************************************************************************
48796+Marvell Commercial License Option
48797+
48798+If you received this File from Marvell and you have entered into a commercial
48799+license agreement (a "Commercial License") with Marvell, the File is licensed
48800+to you under the terms of the applicable Commercial License.
48801+
48802+********************************************************************************
48803+Marvell GPL License Option
48804+
48805+If you received this File from Marvell, you may opt to use, redistribute and/or
48806+modify this File in accordance with the terms and conditions of the General
48807+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
48808+available along with the File in the license.txt file or by writing to the Free
48809+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
48810+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
48811+
48812+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
48813+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
48814+DISCLAIMED. The GPL License provides additional details about this warranty
48815+disclaimer.
48816+********************************************************************************
48817+Marvell BSD License Option
48818+
48819+If you received this File from Marvell, you may opt to use, redistribute and/or
48820+modify this File under the following licensing terms.
48821+Redistribution and use in source and binary forms, with or without modification,
48822+are permitted provided that the following conditions are met:
48823+
48824+ * Redistributions of source code must retain the above copyright notice,
48825+ this list of conditions and the following disclaimer.
48826+
48827+ * Redistributions in binary form must reproduce the above copyright
48828+ notice, this list of conditions and the following disclaimer in the
48829+ documentation and/or other materials provided with the distribution.
48830+
48831+ * Neither the name of Marvell nor the names of its contributors may be
48832+ used to endorse or promote products derived from this software without
48833+ specific prior written permission.
48834+
48835+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
48836+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48837+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48838+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
48839+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48840+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48841+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
48842+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48843+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48844+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48845+
48846+*******************************************************************************/
48847+
48848+
48849+#include "ctrlEnv/sys/mvSysTs.h"
48850+
48851+
48852+typedef struct _mvTsuDecWin
48853+{
48854+ MV_TARGET target;
48855+ MV_ADDR_WIN addrWin; /* An address window*/
48856+ MV_BOOL enable; /* Address decode window is enabled/disabled */
48857+
48858+}MV_TSU_DEC_WIN;
48859+
48860+
48861+MV_TARGET tsuAddrDecPrioTap[] =
48862+{
48863+#if defined(MV_INCLUDE_PEX)
48864+ PEX0_MEM,
48865+#endif
48866+#if defined(MV_INCLUDE_PCI)
48867+ PCI0_MEM,
48868+#endif
48869+#if defined(MV_INCLUDE_SDRAM_CS0)
48870+ SDRAM_CS0,
48871+#endif
48872+#if defined(MV_INCLUDE_SDRAM_CS1)
48873+ SDRAM_CS1,
48874+#endif
48875+#if defined(MV_INCLUDE_SDRAM_CS2)
48876+ SDRAM_CS2,
48877+#endif
48878+#if defined(MV_INCLUDE_SDRAM_CS3)
48879+ SDRAM_CS3,
48880+#endif
48881+#if defined(MV_INCLUDE_DEVICE_CS0)
48882+ DEVICE_CS0,
48883+#endif
48884+#if defined(MV_INCLUDE_DEVICE_CS1)
48885+ DEVICE_CS1,
48886+#endif
48887+#if defined(MV_INCLUDE_DEVICE_CS2)
48888+ DEVICE_CS2,
48889+#endif
48890+#if defined(MV_INCLUDE_DEVICE_CS3)
48891+ DEVICE_CS3,
48892+#endif
48893+#if defined(MV_INCLUDE_PEX)
48894+ PEX0_IO,
48895+#endif
48896+#if defined(MV_INCLUDE_PCI)
48897+ PCI0_IO,
48898+#endif
48899+ TBL_TERM
48900+};
48901+
48902+static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
48903+static MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);
48904+static MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);
48905+MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable);
48906+
48907+/*******************************************************************************
48908+* mvTsuWinInit
48909+*
48910+* DESCRIPTION:
48911+* Initialize the TSU unit address decode windows.
48912+*
48913+* INPUT:
48914+* None.
48915+* OUTPUT:
48916+* None.
48917+* RETURN:
48918+* MV_OK - on success,
48919+*
48920+*******************************************************************************/
48921+MV_STATUS mvTsuWinInit(void)
48922+{
48923+ MV_U32 winNum, status, winPrioIndex=0;
48924+ MV_TSU_DEC_WIN tsuWin;
48925+ MV_CPU_DEC_WIN cpuAddrDecWin;
48926+
48927+ /* First disable all address decode windows */
48928+ for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)
48929+ {
48930+ MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),
48931+ TSU_WIN_CTRL_EN_MASK);
48932+ }
48933+
48934+ /* Go through all windows in user table until table terminator */
48935+ for(winNum = 0; ((tsuAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
48936+ (winNum < TSU_MAX_DECODE_WIN));)
48937+ {
48938+ /* first get attributes from CPU If */
48939+ status = mvCpuIfTargetWinGet(tsuAddrDecPrioTap[winPrioIndex],
48940+ &cpuAddrDecWin);
48941+
48942+ if(MV_NO_SUCH == status)
48943+ {
48944+ winPrioIndex++;
48945+ continue;
48946+ }
48947+ if(MV_OK != status)
48948+ {
48949+ mvOsPrintf("mvTsuWinInit: ERR. mvCpuIfTargetWinGet failed\n");
48950+ return MV_ERROR;
48951+ }
48952+
48953+ if (cpuAddrDecWin.enable == MV_TRUE)
48954+ {
48955+ tsuWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
48956+ tsuWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
48957+ tsuWin.addrWin.size = cpuAddrDecWin.addrWin.size;
48958+ tsuWin.enable = MV_TRUE;
48959+ tsuWin.target = tsuAddrDecPrioTap[winPrioIndex];
48960+
48961+ if(MV_OK != mvTsuWinSet(winNum, &tsuWin))
48962+ {
48963+ mvOsPrintf("mvTsuWinInit: ERR. mvTsuWinSet failed winNum=%d\n",
48964+ winNum);
48965+ return MV_ERROR;
48966+ }
48967+ winNum++;
48968+ }
48969+ winPrioIndex ++;
48970+ }
48971+
48972+ return MV_OK;
48973+}
48974+
48975+
48976+/*******************************************************************************
48977+* mvTsuWinSet
48978+*
48979+* DESCRIPTION:
48980+* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
48981+* address window, also known as address decode window.
48982+* After setting this target window, the TSU will be able to access the
48983+* target within the address window.
48984+*
48985+* INPUT:
48986+* winNum - TSU to target address decode window number.
48987+* pAddrDecWin - TSU target window data structure.
48988+*
48989+* OUTPUT:
48990+* None.
48991+*
48992+* RETURN:
48993+* MV_ERROR - if address window overlapps with other address decode
48994+* windows.
48995+* MV_BAD_PARAM - if base address is invalid parameter or target is
48996+* unknown.
48997+*
48998+*******************************************************************************/
48999+MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)
49000+{
49001+ MV_TARGET_ATTRIB targetAttribs;
49002+ MV_DEC_REGS decRegs;
49003+
49004+ /* Parameter checking */
49005+ if(winNum >= TSU_MAX_DECODE_WIN)
49006+ {
49007+ mvOsPrintf("mvTsuWinSet: ERR. Invalid win num %d\n",winNum);
49008+ return MV_BAD_PARAM;
49009+ }
49010+
49011+ /* Check if the requested window overlapps with current windows */
49012+ if(MV_TRUE == tsuWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
49013+ {
49014+ mvOsPrintf("mvTsuWinSet: ERR. Window %d overlap\n", winNum);
49015+ return MV_ERROR;
49016+ }
49017+
49018+ /* check if address is aligned to the size */
49019+ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow,pAddrDecWin->addrWin.size))
49020+ {
49021+ mvOsPrintf("mvTsuWinSet: Error setting TSU window %d to target "
49022+ "%s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
49023+ winNum, mvCtrlTargetNameGet(pAddrDecWin->target),
49024+ pAddrDecWin->addrWin.baseLow,
49025+ pAddrDecWin->addrWin.size);
49026+ return MV_ERROR;
49027+ }
49028+
49029+ decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));
49030+ decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));
49031+
49032+ if(MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
49033+ {
49034+ mvOsPrintf("mvTsuWinSet: mvCtrlAddrDecToReg Failed\n");
49035+ return MV_ERROR;
49036+ }
49037+
49038+ mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
49039+
49040+ /* set attributes */
49041+ decRegs.sizeReg &= ~TSU_WIN_CTRL_ATTR_MASK;
49042+ decRegs.sizeReg |= targetAttribs.attrib << TSU_WIN_CTRL_ATTR_OFFS;
49043+ /* set target ID */
49044+ decRegs.sizeReg &= ~TSU_WIN_CTRL_TARGET_MASK;
49045+ decRegs.sizeReg |= targetAttribs.targetId << TSU_WIN_CTRL_TARGET_OFFS;
49046+
49047+ /* for the safe side we disable the window before writing the new */
49048+ /* values */
49049+ mvTsuWinEnable(winNum, MV_FALSE);
49050+ MV_REG_WRITE(MV_TSU_WIN_CTRL_REG(winNum),decRegs.sizeReg);
49051+
49052+ /* Write to address decode Size Register */
49053+ MV_REG_WRITE(MV_TSU_WIN_BASE_REG(winNum), decRegs.baseReg);
49054+
49055+ /* Enable address decode target window */
49056+ if(pAddrDecWin->enable == MV_TRUE)
49057+ {
49058+ mvTsuWinEnable(winNum,MV_TRUE);
49059+ }
49060+
49061+ return MV_OK;
49062+}
49063+
49064+
49065+/*******************************************************************************
49066+* mvTsuWinGet
49067+*
49068+* DESCRIPTION:
49069+* Get TSU peripheral target address window.
49070+*
49071+* INPUT:
49072+* winNum - TSU to target address decode window number.
49073+*
49074+* OUTPUT:
49075+* pAddrDecWin - TSU target window data structure.
49076+*
49077+* RETURN:
49078+* MV_ERROR if register parameters are invalid.
49079+*
49080+*******************************************************************************/
49081+MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)
49082+{
49083+ MV_DEC_REGS decRegs;
49084+ MV_TARGET_ATTRIB targetAttrib;
49085+
49086+ /* Parameter checking */
49087+ if(winNum >= TSU_MAX_DECODE_WIN)
49088+ {
49089+ mvOsPrintf("mvTsuWinGet: ERR. Invalid winNum %d\n", winNum);
49090+ return MV_NOT_SUPPORTED;
49091+ }
49092+
49093+ decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));
49094+ decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));
49095+
49096+ if(MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
49097+ {
49098+ mvOsPrintf("mvTsuWinGet: mvCtrlRegToAddrDec Failed \n");
49099+ return MV_ERROR;
49100+ }
49101+
49102+ /* attrib and targetId */
49103+ targetAttrib.attrib =
49104+ (decRegs.sizeReg & TSU_WIN_CTRL_ATTR_MASK) >> TSU_WIN_CTRL_ATTR_OFFS;
49105+ targetAttrib.targetId =
49106+ (decRegs.sizeReg & TSU_WIN_CTRL_TARGET_MASK) >> TSU_WIN_CTRL_TARGET_OFFS;
49107+
49108+ pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
49109+
49110+ /* Check if window is enabled */
49111+ if((MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum)) & TSU_WIN_CTRL_EN_MASK))
49112+ {
49113+ pAddrDecWin->enable = MV_TRUE;
49114+ }
49115+ else
49116+ {
49117+ pAddrDecWin->enable = MV_FALSE;
49118+ }
49119+
49120+ return MV_OK;
49121+}
49122+
49123+
49124+/*******************************************************************************
49125+* mvTsuWinEnable
49126+*
49127+* DESCRIPTION:
49128+* This function enable/disable a TSU to target address window.
49129+* According to parameter 'enable' the routine will enable the
49130+* window, thus enabling TSU accesses (before enabling the window it is
49131+* tested for overlapping). Otherwise, the window will be disabled.
49132+*
49133+* INPUT:
49134+* winNum - TSU to target address decode window number.
49135+* enable - Enable / disable parameter.
49136+*
49137+* OUTPUT:
49138+* N/A
49139+*
49140+* RETURN:
49141+* MV_ERROR if decode window number was wrong or enabled window overlapps.
49142+*
49143+*******************************************************************************/
49144+MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable)
49145+{
49146+ MV_TSU_DEC_WIN addrDecWin;
49147+
49148+ /* Parameter checking */
49149+ if(winNum >= TSU_MAX_DECODE_WIN)
49150+ {
49151+ mvOsPrintf("mvTsuWinEnable: ERR. Invalid winNum%d\n",winNum);
49152+ return MV_ERROR;
49153+ }
49154+
49155+ if(enable == MV_TRUE)
49156+ {
49157+ /* First check for overlap with other enabled windows */
49158+ /* Get current window. */
49159+ if(MV_OK != mvTsuWinGet(winNum,&addrDecWin))
49160+ {
49161+ mvOsPrintf("mvTsuWinEnable: ERR. targetWinGet fail\n");
49162+ return MV_ERROR;
49163+ }
49164+ /* Check for overlapping. */
49165+ if(MV_FALSE == tsuWinOverlapDetect(winNum,&(addrDecWin.addrWin)))
49166+ {
49167+ /* No Overlap. Enable address decode target window */
49168+ MV_REG_BIT_SET(MV_TSU_WIN_CTRL_REG(winNum),
49169+ TSU_WIN_CTRL_EN_MASK);
49170+ }
49171+ else
49172+ {
49173+ /* Overlap detected */
49174+ mvOsPrintf("mvTsuWinEnable: ERR. Overlap detected\n");
49175+ return MV_ERROR;
49176+ }
49177+ }
49178+ else
49179+ {
49180+ /* Disable address decode target window */
49181+ MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),
49182+ TSU_WIN_CTRL_EN_MASK);
49183+ }
49184+ return MV_OK;
49185+}
49186+
49187+/*******************************************************************************
49188+* mvTsuWinTargetGet
49189+*
49190+* DESCRIPTION:
49191+* Get Window number associated with target
49192+*
49193+* INPUT:
49194+* target - Target ID to get the window number for.
49195+* OUTPUT:
49196+*
49197+* RETURN:
49198+* window number or 0xFFFFFFFF on error.
49199+*
49200+*******************************************************************************/
49201+MV_U32 mvTsuWinTargetGet(MV_TARGET target)
49202+{
49203+ MV_TSU_DEC_WIN decWin;
49204+ MV_U32 winNum;
49205+
49206+ /* Check parameters */
49207+ if(target >= MAX_TARGETS)
49208+ {
49209+ mvOsPrintf("mvTsuWinTargetGet: target %d is Illigal\n", target);
49210+ return 0xffffffff;
49211+ }
49212+
49213+ for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)
49214+ {
49215+ if(mvTsuWinGet(winNum,&decWin) != MV_OK)
49216+ {
49217+ mvOsPrintf("mvTsuWinGet: window returned error\n");
49218+ return 0xffffffff;
49219+ }
49220+
49221+ if (decWin.enable == MV_TRUE)
49222+ {
49223+ if(decWin.target == target)
49224+ {
49225+ return winNum;
49226+ }
49227+ }
49228+ }
49229+ return 0xFFFFFFFF;
49230+}
49231+
49232+
49233+/*******************************************************************************
49234+* tsuWinOverlapDetect
49235+*
49236+* DESCRIPTION:
49237+* Detect TSU address windows overlapping
49238+* An unpredicted behaviur is expected in case TSU address decode
49239+* windows overlapps.
49240+* This function detects TSU address decode windows overlapping of a
49241+* specified window. The function does not check the window itself for
49242+* overlapping. The function also skipps disabled address decode windows.
49243+*
49244+* INPUT:
49245+* winNum - address decode window number.
49246+* pAddrDecWin - An address decode window struct.
49247+*
49248+* OUTPUT:
49249+* None.
49250+*
49251+* RETURN:
49252+* MV_TRUE if the given address window overlap current address
49253+* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
49254+* from registers.
49255+*
49256+*******************************************************************************/
49257+static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
49258+{
49259+ MV_U32 ctrlReg;
49260+ MV_U32 winNumIndex;
49261+ MV_TSU_DEC_WIN addrDecWin;
49262+
49263+ for(winNumIndex = 0; winNumIndex < TSU_MAX_DECODE_WIN; winNumIndex++)
49264+ {
49265+ /* Do not check window itself */
49266+ if(winNumIndex == winNum)
49267+ {
49268+ continue;
49269+ }
49270+
49271+ /* Do not check disabled windows */
49272+ ctrlReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNumIndex));
49273+ if((ctrlReg & TSU_WIN_CTRL_EN_MASK) == 0)
49274+ {
49275+ continue;
49276+ }
49277+
49278+ /* Get window parameters */
49279+ if (MV_OK != mvTsuWinGet(winNumIndex, &addrDecWin))
49280+ {
49281+ mvOsPrintf("tsuWinOverlapDetect: ERR. mvTsuWinGet failed\n");
49282+ return MV_ERROR;
49283+ }
49284+
49285+ if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
49286+ {
49287+ return MV_TRUE;
49288+ }
49289+ }
49290+ return MV_FALSE;
49291+}
49292+
49293+
49294+/*******************************************************************************
49295+* mvTsuAddrDecShow
49296+*
49297+* DESCRIPTION:
49298+* Print the TSU address decode map.
49299+*
49300+* INPUT:
49301+* None.
49302+*
49303+* OUTPUT:
49304+* None.
49305+*
49306+* RETURN:
49307+* None.
49308+*
49309+*******************************************************************************/
49310+void mvTsuAddrDecShow(void)
49311+{
49312+ MV_TSU_DEC_WIN win;
49313+ int i;
49314+
49315+ if (MV_FALSE == mvCtrlPwrClckGet(TS_UNIT_ID, 0))
49316+ return;
49317+
49318+ mvOsOutput( "\n" );
49319+ mvOsOutput( "TSU:\n");
49320+ mvOsOutput( "----\n" );
49321+
49322+ for(i = 0; i < TSU_MAX_DECODE_WIN; i++)
49323+ {
49324+ memset(&win, 0, sizeof(TSU_MAX_DECODE_WIN));
49325+ mvOsOutput( "win%d - ", i );
49326+
49327+ if(mvTsuWinGet(i, &win ) == MV_OK )
49328+ {
49329+ if(win.enable == MV_TRUE)
49330+ {
49331+ mvOsOutput("%s base %08x, ",
49332+ mvCtrlTargetNameGet(win.target),
49333+ win.addrWin.baseLow);
49334+ mvOsOutput( "...." );
49335+ mvSizePrint(win.addrWin.size );
49336+ mvOsOutput( "\n" );
49337+ }
49338+ else
49339+ {
49340+ mvOsOutput( "disable\n" );
49341+ }
49342+ }
49343+ }
49344+ return;
49345+}
49346+
49347+
49348+/*******************************************************************************
49349+* mvTsuInit
49350+*
49351+* DESCRIPTION:
49352+* Initialize the TSU unit, and get unit out of reset.
49353+*
49354+* INPUT:
49355+* coreClock - The core clock at which the TSU should operate.
49356+* mode - The mode on configure the unit into (serial/parallel).
49357+* memHandle - Memory handle used for memory allocations.
49358+* OUTPUT:
49359+* None.
49360+* RETURN:
49361+* MV_OK - on success,
49362+*
49363+*******************************************************************************/
49364+MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,
49365+ void *osHandle)
49366+{
49367+ MV_STATUS status;
49368+
49369+ status = mvTsuWinInit();
49370+ if(status == MV_OK)
49371+ status = mvTsuHalInit(coreClock,mode,osHandle);
49372+
49373+ return status;
49374+}
49375diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h
49376new file mode 100644
49377index 0000000..1478b09
49378--- /dev/null
49379+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h
49380@@ -0,0 +1,110 @@
49381+/*******************************************************************************
49382+Copyright (C) Marvell International Ltd. and its affiliates
49383+
49384+This software file (the "File") is owned and distributed by Marvell
49385+International Ltd. and/or its affiliates ("Marvell") under the following
49386+alternative licensing terms. Once you have made an election to distribute the
49387+File under one of the following license alternatives, please (i) delete this
49388+introductory statement regarding license alternatives, (ii) delete the two
49389+license alternatives that you have not elected to use and (iii) preserve the
49390+Marvell copyright notice above.
49391+
49392+********************************************************************************
49393+Marvell Commercial License Option
49394+
49395+If you received this File from Marvell and you have entered into a commercial
49396+license agreement (a "Commercial License") with Marvell, the File is licensed
49397+to you under the terms of the applicable Commercial License.
49398+
49399+********************************************************************************
49400+Marvell GPL License Option
49401+
49402+If you received this File from Marvell, you may opt to use, redistribute and/or
49403+modify this File in accordance with the terms and conditions of the General
49404+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
49405+available along with the File in the license.txt file or by writing to the Free
49406+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
49407+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
49408+
49409+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
49410+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
49411+DISCLAIMED. The GPL License provides additional details about this warranty
49412+disclaimer.
49413+********************************************************************************
49414+Marvell BSD License Option
49415+
49416+If you received this File from Marvell, you may opt to use, redistribute and/or
49417+modify this File under the following licensing terms.
49418+Redistribution and use in source and binary forms, with or without modification,
49419+are permitted provided that the following conditions are met:
49420+
49421+ * Redistributions of source code must retain the above copyright notice,
49422+ this list of conditions and the following disclaimer.
49423+
49424+ * Redistributions in binary form must reproduce the above copyright
49425+ notice, this list of conditions and the following disclaimer in the
49426+ documentation and/or other materials provided with the distribution.
49427+
49428+ * Neither the name of Marvell nor the names of its contributors may be
49429+ used to endorse or promote products derived from this software without
49430+ specific prior written permission.
49431+
49432+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
49433+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49434+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49435+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
49436+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49437+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49438+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
49439+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49440+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49441+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49442+
49443+*******************************************************************************/
49444+
49445+#ifndef __INCmvSysTsh
49446+#define __INCmvSysTsh
49447+
49448+#ifdef __cplusplus
49449+extern "C" {
49450+#endif /* __cplusplus */
49451+
49452+/* includes */
49453+#include "ts/mvTsu.h"
49454+#include "ctrlEnv/sys/mvCpuIf.h"
49455+#include "ctrlEnv/mvCtrlEnvLib.h"
49456+#include "ctrlEnv/mvCtrlEnvAddrDec.h"
49457+
49458+#define TSU_MAX_DECODE_WIN 4
49459+
49460+
49461+/*******************************************/
49462+/* TSU Windows Registers */
49463+/*******************************************/
49464+#define MV_TSU_WIN_CTRL_REG(win) (TSU_GLOBAL_REG_BASE +0x30 + 0x10 * win)
49465+#define MV_TSU_WIN_BASE_REG(win) (TSU_GLOBAL_REG_BASE +0x34 + 0x10 * win)
49466+
49467+/* TSU windows control register. */
49468+#define TSU_WIN_CTRL_EN_MASK (0x1 << 0)
49469+#define TSU_WIN_CTRL_TARGET_OFFS 4
49470+#define TSU_WIN_CTRL_TARGET_MASK (0xF << TSU_WIN_CTRL_TARGET_OFFS)
49471+#define TSU_WIN_CTRL_ATTR_OFFS 8
49472+#define TSU_WIN_CTRL_ATTR_MASK (0xFF << TSU_WIN_CTRL_ATTR_OFFS)
49473+#define TSU_WIN_CTRL_SIZE_OFFS 16
49474+#define TSU_WIN_CTRL_SIZE_MASK (0xFFFF << TSU_WIN_CTRL_SIZE_OFFS)
49475+
49476+/* TSU windows base register. */
49477+#define TSU_WIN_BASE_OFFS 16
49478+#define TSU_WIN_BASE_MASK (0xFFFF << TSU_WIN_BASE_OFFS)
49479+
49480+MV_STATUS mvTsuWinInit(void);
49481+
49482+void mvTsuAddrDecShow(void);
49483+MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,
49484+ void *osHandle);
49485+
49486+#ifdef __cplusplus
49487+}
49488+#endif /* __cplusplus */
49489+
49490+#endif /* __INCmvTsh */
49491diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c
49492new file mode 100644
49493index 0000000..195b5e1
49494--- /dev/null
49495+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c
49496@@ -0,0 +1,497 @@
49497+/*******************************************************************************
49498+Copyright (C) Marvell International Ltd. and its affiliates
49499+
49500+This software file (the "File") is owned and distributed by Marvell
49501+International Ltd. and/or its affiliates ("Marvell") under the following
49502+alternative licensing terms. Once you have made an election to distribute the
49503+File under one of the following license alternatives, please (i) delete this
49504+introductory statement regarding license alternatives, (ii) delete the two
49505+license alternatives that you have not elected to use and (iii) preserve the
49506+Marvell copyright notice above.
49507+
49508+********************************************************************************
49509+Marvell Commercial License Option
49510+
49511+If you received this File from Marvell and you have entered into a commercial
49512+license agreement (a "Commercial License") with Marvell, the File is licensed
49513+to you under the terms of the applicable Commercial License.
49514+
49515+********************************************************************************
49516+Marvell GPL License Option
49517+
49518+If you received this File from Marvell, you may opt to use, redistribute and/or
49519+modify this File in accordance with the terms and conditions of the General
49520+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
49521+available along with the File in the license.txt file or by writing to the Free
49522+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
49523+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
49524+
49525+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
49526+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
49527+DISCLAIMED. The GPL License provides additional details about this warranty
49528+disclaimer.
49529+********************************************************************************
49530+Marvell BSD License Option
49531+
49532+If you received this File from Marvell, you may opt to use, redistribute and/or
49533+modify this File under the following licensing terms.
49534+Redistribution and use in source and binary forms, with or without modification,
49535+are permitted provided that the following conditions are met:
49536+
49537+ * Redistributions of source code must retain the above copyright notice,
49538+ this list of conditions and the following disclaimer.
49539+
49540+ * Redistributions in binary form must reproduce the above copyright
49541+ notice, this list of conditions and the following disclaimer in the
49542+ documentation and/or other materials provided with the distribution.
49543+
49544+ * Neither the name of Marvell nor the names of its contributors may be
49545+ used to endorse or promote products derived from this software without
49546+ specific prior written permission.
49547+
49548+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
49549+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49550+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49551+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
49552+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49553+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49554+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
49555+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49556+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49557+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49558+
49559+*******************************************************************************/
49560+
49561+#include "ctrlEnv/sys/mvSysUsb.h"
49562+
49563+MV_TARGET usbAddrDecPrioTab[] =
49564+{
49565+#if defined(MV_INCLUDE_SDRAM_CS0)
49566+ SDRAM_CS0,
49567+#endif
49568+#if defined(MV_INCLUDE_SDRAM_CS1)
49569+ SDRAM_CS1,
49570+#endif
49571+#if defined(MV_INCLUDE_SDRAM_CS2)
49572+ SDRAM_CS2,
49573+#endif
49574+#if defined(MV_INCLUDE_SDRAM_CS3)
49575+ SDRAM_CS3,
49576+#endif
49577+#if defined(MV_INCLUDE_CESA) && defined(USB_UNDERRUN_WA)
49578+ CRYPT_ENG,
49579+#endif
49580+#if defined(MV_INCLUDE_PEX)
49581+ PEX0_MEM,
49582+#endif
49583+ TBL_TERM
49584+};
49585+
49586+
49587+
49588+MV_STATUS mvUsbInit(int dev, MV_BOOL isHost)
49589+{
49590+ MV_STATUS status;
49591+
49592+ status = mvUsbWinInit(dev);
49593+ if(status != MV_OK)
49594+ return status;
49595+
49596+ return mvUsbHalInit(dev, isHost);
49597+}
49598+
49599+
49600+/*******************************************************************************
49601+* usbWinOverlapDetect - Detect USB address windows overlapping
49602+*
49603+* DESCRIPTION:
49604+* An unpredicted behaviur is expected in case USB address decode
49605+* windows overlapps.
49606+* This function detects USB address decode windows overlapping of a
49607+* specified window. The function does not check the window itself for
49608+* overlapping. The function also skipps disabled address decode windows.
49609+*
49610+* INPUT:
49611+* winNum - address decode window number.
49612+* pAddrDecWin - An address decode window struct.
49613+*
49614+* OUTPUT:
49615+* None.
49616+*
49617+* RETURN:
49618+* MV_TRUE if the given address window overlap current address
49619+* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
49620+* from registers.
49621+*
49622+*******************************************************************************/
49623+static MV_STATUS usbWinOverlapDetect(int dev, MV_U32 winNum,
49624+ MV_ADDR_WIN *pAddrWin)
49625+{
49626+ MV_U32 winNumIndex;
49627+ MV_DEC_WIN addrDecWin;
49628+
49629+ for(winNumIndex=0; winNumIndex<MV_USB_MAX_ADDR_DECODE_WIN; winNumIndex++)
49630+ {
49631+ /* Do not check window itself */
49632+ if (winNumIndex == winNum)
49633+ {
49634+ continue;
49635+ }
49636+
49637+ /* Get window parameters */
49638+ if (MV_OK != mvUsbWinGet(dev, winNumIndex, &addrDecWin))
49639+ {
49640+ mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
49641+ return MV_ERROR;
49642+ }
49643+
49644+ /* Do not check disabled windows */
49645+ if(addrDecWin.enable == MV_FALSE)
49646+ {
49647+ continue;
49648+ }
49649+
49650+ if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
49651+ {
49652+ return MV_TRUE;
49653+ }
49654+ }
49655+ return MV_FALSE;
49656+}
49657+
49658+/*******************************************************************************
49659+* mvUsbWinSet - Set USB target address window
49660+*
49661+* DESCRIPTION:
49662+* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
49663+* address window, also known as address decode window.
49664+* After setting this target window, the USB will be able to access the
49665+* target within the address window.
49666+*
49667+* INPUT:
49668+* winNum - USB target address decode window number.
49669+* pAddrDecWin - USB target window data structure.
49670+*
49671+* OUTPUT:
49672+* None.
49673+*
49674+* RETURN:
49675+* MV_ERROR if address window overlapps with other address decode windows.
49676+* MV_BAD_PARAM if base address is invalid parameter or target is
49677+* unknown.
49678+*
49679+*******************************************************************************/
49680+MV_STATUS mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)
49681+{
49682+ MV_DEC_WIN_PARAMS winParams;
49683+ MV_U32 sizeReg, baseReg;
49684+
49685+ /* Parameter checking */
49686+ if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)
49687+ {
49688+ mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
49689+ return MV_BAD_PARAM;
49690+ }
49691+
49692+ /* Check if the requested window overlapps with current windows */
49693+ if (MV_TRUE == usbWinOverlapDetect(dev, winNum, &pDecWin->addrWin))
49694+ {
49695+ mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
49696+ return MV_ERROR;
49697+ }
49698+
49699+ /* check if address is aligned to the size */
49700+ if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))
49701+ {
49702+ mvOsPrintf("mvUsbWinSet:Error setting USB window %d to "\
49703+ "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
49704+ winNum,
49705+ mvCtrlTargetNameGet(pDecWin->target),
49706+ pDecWin->addrWin.baseLow,
49707+ pDecWin->addrWin.size);
49708+ return MV_ERROR;
49709+ }
49710+
49711+ if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))
49712+ {
49713+ mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);
49714+ return MV_ERROR;
49715+ }
49716+
49717+ /* set Size, Attributes and TargetID */
49718+ sizeReg = (((winParams.targetId << MV_USB_WIN_TARGET_OFFSET) & MV_USB_WIN_TARGET_MASK) |
49719+ ((winParams.attrib << MV_USB_WIN_ATTR_OFFSET) & MV_USB_WIN_ATTR_MASK) |
49720+ ((winParams.size << MV_USB_WIN_SIZE_OFFSET) & MV_USB_WIN_SIZE_MASK));
49721+
49722+#if defined(MV645xx) || defined(MV646xx)
49723+ /* If window is DRAM with HW cache coherency, make sure bit2 is set */
49724+ sizeReg &= ~MV_USB_WIN_BURST_WR_LIMIT_MASK;
49725+
49726+ if((MV_TARGET_IS_DRAM(pDecWin->target)) &&
49727+ (pDecWin->addrWinAttr.cachePolicy != NO_COHERENCY))
49728+ {
49729+ sizeReg |= MV_USB_WIN_BURST_WR_32BIT_LIMIT;
49730+ }
49731+ else
49732+ {
49733+ sizeReg |= MV_USB_WIN_BURST_WR_NO_LIMIT;
49734+ }
49735+#endif /* MV645xx || MV646xx */
49736+
49737+ if (pDecWin->enable == MV_TRUE)
49738+ {
49739+ sizeReg |= MV_USB_WIN_ENABLE_MASK;
49740+ }
49741+ else
49742+ {
49743+ sizeReg &= ~MV_USB_WIN_ENABLE_MASK;
49744+ }
49745+
49746+ /* Update Base value */
49747+ baseReg = (winParams.baseAddr & MV_USB_WIN_BASE_MASK);
49748+
49749+ MV_REG_WRITE( MV_USB_WIN_CTRL_REG(dev, winNum), sizeReg);
49750+ MV_REG_WRITE( MV_USB_WIN_BASE_REG(dev, winNum), baseReg);
49751+
49752+ return MV_OK;
49753+}
49754+
49755+/*******************************************************************************
49756+* mvUsbWinGet - Get USB peripheral target address window.
49757+*
49758+* DESCRIPTION:
49759+* Get USB peripheral target address window.
49760+*
49761+* INPUT:
49762+* winNum - USB target address decode window number.
49763+*
49764+* OUTPUT:
49765+* pDecWin - USB target window data structure.
49766+*
49767+* RETURN:
49768+* MV_ERROR if register parameters are invalid.
49769+*
49770+*******************************************************************************/
49771+MV_STATUS mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)
49772+{
49773+ MV_DEC_WIN_PARAMS winParam;
49774+ MV_U32 sizeReg, baseReg;
49775+
49776+ /* Parameter checking */
49777+ if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)
49778+ {
49779+ mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
49780+ __FUNCTION__, dev, winNum);
49781+ return MV_NOT_SUPPORTED;
49782+ }
49783+
49784+ baseReg = MV_REG_READ( MV_USB_WIN_BASE_REG(dev, winNum) );
49785+ sizeReg = MV_REG_READ( MV_USB_WIN_CTRL_REG(dev, winNum) );
49786+
49787+ /* Check if window is enabled */
49788+ if(sizeReg & MV_USB_WIN_ENABLE_MASK)
49789+ {
49790+ pDecWin->enable = MV_TRUE;
49791+
49792+ /* Extract window parameters from registers */
49793+ winParam.targetId = (sizeReg & MV_USB_WIN_TARGET_MASK) >> MV_USB_WIN_TARGET_OFFSET;
49794+ winParam.attrib = (sizeReg & MV_USB_WIN_ATTR_MASK) >> MV_USB_WIN_ATTR_OFFSET;
49795+ winParam.size = (sizeReg & MV_USB_WIN_SIZE_MASK) >> MV_USB_WIN_SIZE_OFFSET;
49796+ winParam.baseAddr = (baseReg & MV_USB_WIN_BASE_MASK);
49797+
49798+ /* Translate the decode window parameters to address decode struct */
49799+ if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))
49800+ {
49801+ mvOsPrintf("Failed to translate register parameters to USB address" \
49802+ " decode window structure\n");
49803+ return MV_ERROR;
49804+ }
49805+ }
49806+ else
49807+ {
49808+ pDecWin->enable = MV_FALSE;
49809+ }
49810+ return MV_OK;
49811+}
49812+
49813+/*******************************************************************************
49814+* mvUsbWinInit -
49815+*
49816+* INPUT:
49817+*
49818+* OUTPUT:
49819+*
49820+* RETURN:
49821+* MV_ERROR if register parameters are invalid.
49822+*
49823+*******************************************************************************/
49824+MV_STATUS mvUsbWinInit(int dev)
49825+{
49826+ MV_STATUS status;
49827+ MV_DEC_WIN usbWin;
49828+ MV_CPU_DEC_WIN cpuAddrDecWin;
49829+ int winNum;
49830+ MV_U32 winPrioIndex = 0;
49831+
49832+ /* First disable all address decode windows */
49833+ for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)
49834+ {
49835+ MV_REG_BIT_RESET(MV_USB_WIN_CTRL_REG(dev, winNum), MV_USB_WIN_ENABLE_MASK);
49836+ }
49837+
49838+ /* Go through all windows in user table until table terminator */
49839+ winNum = 0;
49840+ while( (usbAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
49841+ (winNum < MV_USB_MAX_ADDR_DECODE_WIN) )
49842+ {
49843+ /* first get attributes from CPU If */
49844+ status = mvCpuIfTargetWinGet(usbAddrDecPrioTab[winPrioIndex],
49845+ &cpuAddrDecWin);
49846+
49847+ if(MV_NO_SUCH == status)
49848+ {
49849+ winPrioIndex++;
49850+ continue;
49851+ }
49852+ if (MV_OK != status)
49853+ {
49854+ mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
49855+ return MV_ERROR;
49856+ }
49857+
49858+ if (cpuAddrDecWin.enable == MV_TRUE)
49859+ {
49860+ usbWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
49861+ usbWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
49862+ usbWin.addrWin.size = cpuAddrDecWin.addrWin.size;
49863+ usbWin.enable = MV_TRUE;
49864+ usbWin.target = usbAddrDecPrioTab[winPrioIndex];
49865+
49866+#if defined(MV645xx) || defined(MV646xx)
49867+ /* Get the default attributes for that target window */
49868+ mvCtrlDefAttribGet(usbWin.target, &usbWin.addrWinAttr);
49869+#endif /* MV645xx || MV646xx */
49870+
49871+ if(MV_OK != mvUsbWinSet(dev, winNum, &usbWin))
49872+ {
49873+ return MV_ERROR;
49874+ }
49875+ winNum++;
49876+ }
49877+ winPrioIndex++;
49878+ }
49879+ return MV_OK;
49880+}
49881+
49882+/*******************************************************************************
49883+* mvUsbAddrDecShow - Print the USB address decode map.
49884+*
49885+* DESCRIPTION:
49886+* This function print the USB address decode map.
49887+*
49888+* INPUT:
49889+* None.
49890+*
49891+* OUTPUT:
49892+* None.
49893+*
49894+* RETURN:
49895+* None.
49896+*
49897+*******************************************************************************/
49898+MV_VOID mvUsbAddrDecShow(MV_VOID)
49899+{
49900+ MV_DEC_WIN addrDecWin;
49901+ int i, winNum;
49902+
49903+ mvOsOutput( "\n" );
49904+ mvOsOutput( "USB:\n" );
49905+ mvOsOutput( "----\n" );
49906+
49907+ for(i=0; i<mvCtrlUsbMaxGet(); i++)
49908+ {
49909+ mvOsOutput( "Device %d:\n", i);
49910+
49911+ for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)
49912+ {
49913+ memset(&addrDecWin, 0, sizeof(MV_DEC_WIN) );
49914+
49915+ mvOsOutput( "win%d - ", winNum );
49916+
49917+ if( mvUsbWinGet(i, winNum, &addrDecWin ) == MV_OK )
49918+ {
49919+ if( addrDecWin.enable )
49920+ {
49921+ mvOsOutput( "%s base %08x, ",
49922+ mvCtrlTargetNameGet(addrDecWin.target), addrDecWin.addrWin.baseLow );
49923+
49924+ mvSizePrint( addrDecWin.addrWin.size );
49925+
49926+#if defined(MV645xx) || defined(MV646xx)
49927+ switch( addrDecWin.addrWinAttr.swapType)
49928+ {
49929+ case MV_BYTE_SWAP:
49930+ mvOsOutput( "BYTE_SWAP, " );
49931+ break;
49932+ case MV_NO_SWAP:
49933+ mvOsOutput( "NO_SWAP , " );
49934+ break;
49935+ case MV_BYTE_WORD_SWAP:
49936+ mvOsOutput( "BYTE_WORD_SWAP, " );
49937+ break;
49938+ case MV_WORD_SWAP:
49939+ mvOsOutput( "WORD_SWAP, " );
49940+ break;
49941+ default:
49942+ mvOsOutput( "SWAP N/A , " );
49943+ }
49944+
49945+ switch( addrDecWin.addrWinAttr.cachePolicy )
49946+ {
49947+ case NO_COHERENCY:
49948+ mvOsOutput( "NO_COHERENCY , " );
49949+ break;
49950+ case WT_COHERENCY:
49951+ mvOsOutput( "WT_COHERENCY , " );
49952+ break;
49953+ case WB_COHERENCY:
49954+ mvOsOutput( "WB_COHERENCY , " );
49955+ break;
49956+ default:
49957+ mvOsOutput( "COHERENCY N/A, " );
49958+ }
49959+
49960+ switch( addrDecWin.addrWinAttr.pcixNoSnoop )
49961+ {
49962+ case 0:
49963+ mvOsOutput( "PCI-X NS inactive, " );
49964+ break;
49965+ case 1:
49966+ mvOsOutput( "PCI-X NS active , " );
49967+ break;
49968+ default:
49969+ mvOsOutput( "PCI-X NS N/A , " );
49970+ }
49971+
49972+ switch( addrDecWin.addrWinAttr.p2pReq64 )
49973+ {
49974+ case 0:
49975+ mvOsOutput( "REQ64 force" );
49976+ break;
49977+ case 1:
49978+ mvOsOutput( "REQ64 detect" );
49979+ break;
49980+ default:
49981+ mvOsOutput( "REQ64 N/A" );
49982+ }
49983+#endif /* MV645xx || MV646xx */
49984+ mvOsOutput( "\n" );
49985+ }
49986+ else
49987+ mvOsOutput( "disable\n" );
49988+ }
49989+ }
49990+ }
49991+}
49992+
49993+
49994diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h
49995new file mode 100644
49996index 0000000..b712900
49997--- /dev/null
49998+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h
49999@@ -0,0 +1,125 @@
50000+/*******************************************************************************
50001+Copyright (C) Marvell International Ltd. and its affiliates
50002+
50003+This software file (the "File") is owned and distributed by Marvell
50004+International Ltd. and/or its affiliates ("Marvell") under the following
50005+alternative licensing terms. Once you have made an election to distribute the
50006+File under one of the following license alternatives, please (i) delete this
50007+introductory statement regarding license alternatives, (ii) delete the two
50008+license alternatives that you have not elected to use and (iii) preserve the
50009+Marvell copyright notice above.
50010+
50011+********************************************************************************
50012+Marvell Commercial License Option
50013+
50014+If you received this File from Marvell and you have entered into a commercial
50015+license agreement (a "Commercial License") with Marvell, the File is licensed
50016+to you under the terms of the applicable Commercial License.
50017+
50018+********************************************************************************
50019+Marvell GPL License Option
50020+
50021+If you received this File from Marvell, you may opt to use, redistribute and/or
50022+modify this File in accordance with the terms and conditions of the General
50023+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
50024+available along with the File in the license.txt file or by writing to the Free
50025+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
50026+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
50027+
50028+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
50029+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
50030+DISCLAIMED. The GPL License provides additional details about this warranty
50031+disclaimer.
50032+********************************************************************************
50033+Marvell BSD License Option
50034+
50035+If you received this File from Marvell, you may opt to use, redistribute and/or
50036+modify this File under the following licensing terms.
50037+Redistribution and use in source and binary forms, with or without modification,
50038+are permitted provided that the following conditions are met:
50039+
50040+ * Redistributions of source code must retain the above copyright notice,
50041+ this list of conditions and the following disclaimer.
50042+
50043+ * Redistributions in binary form must reproduce the above copyright
50044+ notice, this list of conditions and the following disclaimer in the
50045+ documentation and/or other materials provided with the distribution.
50046+
50047+ * Neither the name of Marvell nor the names of its contributors may be
50048+ used to endorse or promote products derived from this software without
50049+ specific prior written permission.
50050+
50051+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
50052+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50053+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50054+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
50055+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50056+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50057+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
50058+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50059+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50060+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50061+
50062+*******************************************************************************/
50063+
50064+#ifndef __INCmvSysUsbh
50065+#define __INCmvSysUsbh
50066+
50067+#ifdef __cplusplus
50068+extern "C" {
50069+#endif /* __cplusplus */
50070+
50071+/* includes */
50072+#include "usb/mvUsb.h"
50073+#include "ctrlEnv/sys/mvCpuIf.h"
50074+#include "ctrlEnv/mvCtrlEnvLib.h"
50075+#include "ctrlEnv/mvCtrlEnvAddrDec.h"
50076+
50077+#define MV_USB_MAX_ADDR_DECODE_WIN 4
50078+
50079+/*******************************************/
50080+/* USB Bridge Registers */
50081+/*******************************************/
50082+#define MV_USB_BRIDGE_CTRL_REG(dev) (USB_REG_BASE(dev) + 0x300)
50083+
50084+#define MV_USB_WIN_CTRL_REG(dev, win) (USB_REG_BASE(dev) + 0x320 + ((win)<<4))
50085+#define MV_USB_WIN_BASE_REG(dev, win) (USB_REG_BASE(dev) + 0x324 + ((win)<<4))
50086+
50087+/* BITs in Windows 0-3 Control and Base Registers */
50088+#define MV_USB_WIN_ENABLE_BIT 0
50089+#define MV_USB_WIN_ENABLE_MASK (1 << MV_USB_WIN_ENABLE_BIT)
50090+
50091+#define MV_USB_WIN_BURST_WR_LIMIT_BIT 1
50092+#define MV_USB_WIN_BURST_WR_LIMIT_MASK (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
50093+#define MV_USB_WIN_BURST_WR_NO_LIMIT (0 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
50094+#define MV_USB_WIN_BURST_WR_32BIT_LIMIT (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
50095+
50096+#define MV_USB_WIN_TARGET_OFFSET 4
50097+#define MV_USB_WIN_TARGET_MASK (0xF << MV_USB_WIN_TARGET_OFFSET)
50098+
50099+#define MV_USB_WIN_ATTR_OFFSET 8
50100+#define MV_USB_WIN_ATTR_MASK (0xFF << MV_USB_WIN_ATTR_OFFSET)
50101+
50102+#define MV_USB_WIN_SIZE_OFFSET 16
50103+#define MV_USB_WIN_SIZE_MASK (0xFFFF << MV_USB_WIN_SIZE_OFFSET)
50104+
50105+#define MV_USB_WIN_BASE_OFFSET 16
50106+#define MV_USB_WIN_BASE_MASK (0xFFFF << MV_USB_WIN_BASE_OFFSET)
50107+
50108+
50109+#define MV_USB_BRIDGE_IPG_REG(dev) (USB_REG_BASE(dev) + 0x360)
50110+
50111+
50112+MV_STATUS mvUsbInit(int dev, MV_BOOL isHost);
50113+
50114+MV_STATUS mvUsbWinInit(int dev);
50115+MV_STATUS mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);
50116+MV_STATUS mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);
50117+
50118+void mvUsbAddrDecShow(void);
50119+
50120+#ifdef __cplusplus
50121+}
50122+#endif /* __cplusplus */
50123+
50124+#endif /* __INCmvUsbh */
50125diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c
50126new file mode 100644
50127index 0000000..1e1da8f
50128--- /dev/null
50129+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c
50130@@ -0,0 +1,662 @@
50131+/*******************************************************************************
50132+Copyright (C) Marvell International Ltd. and its affiliates
50133+
50134+This software file (the "File") is owned and distributed by Marvell
50135+International Ltd. and/or its affiliates ("Marvell") under the following
50136+alternative licensing terms. Once you have made an election to distribute the
50137+File under one of the following license alternatives, please (i) delete this
50138+introductory statement regarding license alternatives, (ii) delete the two
50139+license alternatives that you have not elected to use and (iii) preserve the
50140+Marvell copyright notice above.
50141+
50142+********************************************************************************
50143+Marvell Commercial License Option
50144+
50145+If you received this File from Marvell and you have entered into a commercial
50146+license agreement (a "Commercial License") with Marvell, the File is licensed
50147+to you under the terms of the applicable Commercial License.
50148+
50149+********************************************************************************
50150+Marvell GPL License Option
50151+
50152+If you received this File from Marvell, you may opt to use, redistribute and/or
50153+modify this File in accordance with the terms and conditions of the General
50154+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
50155+available along with the File in the license.txt file or by writing to the Free
50156+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
50157+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
50158+
50159+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
50160+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
50161+DISCLAIMED. The GPL License provides additional details about this warranty
50162+disclaimer.
50163+********************************************************************************
50164+Marvell BSD License Option
50165+
50166+If you received this File from Marvell, you may opt to use, redistribute and/or
50167+modify this File under the following licensing terms.
50168+Redistribution and use in source and binary forms, with or without modification,
50169+are permitted provided that the following conditions are met:
50170+
50171+ * Redistributions of source code must retain the above copyright notice,
50172+ this list of conditions and the following disclaimer.
50173+
50174+ * Redistributions in binary form must reproduce the above copyright
50175+ notice, this list of conditions and the following disclaimer in the
50176+ documentation and/or other materials provided with the distribution.
50177+
50178+ * Neither the name of Marvell nor the names of its contributors may be
50179+ used to endorse or promote products derived from this software without
50180+ specific prior written permission.
50181+
50182+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
50183+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50184+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50185+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
50186+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50187+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50188+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
50189+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50190+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50191+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50192+
50193+*******************************************************************************/
50194+
50195+#include "xor/mvXor.h"
50196+#include "mvSysXor.h"
50197+
50198+/* defines */
50199+#ifdef MV_DEBUG
50200+ #define DB(x) x
50201+#else
50202+ #define DB(x)
50203+#endif
50204+
50205+
50206+static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
50207+
50208+MV_TARGET xorAddrDecPrioTap[] =
50209+{
50210+#if defined(MV_INCLUDE_DEVICE_CS0)
50211+ DEVICE_CS0,
50212+#endif
50213+#if defined(MV_INCLUDE_PEX)
50214+ PEX0_MEM,
50215+#endif
50216+#if defined(MV_INCLUDE_SDRAM_CS0)
50217+ SDRAM_CS0,
50218+#endif
50219+#if defined(MV_INCLUDE_SDRAM_CS1)
50220+ SDRAM_CS1,
50221+#endif
50222+#if defined(MV_INCLUDE_SDRAM_CS2)
50223+ SDRAM_CS2,
50224+#endif
50225+#if defined(MV_INCLUDE_SDRAM_CS3)
50226+ SDRAM_CS3,
50227+#endif
50228+#if defined(MV_INCLUDE_DEVICE_CS1)
50229+ DEVICE_CS1,
50230+#endif
50231+#if defined(MV_INCLUDE_CESA)
50232+ CRYPT_ENG,
50233+#endif
50234+ TBL_TERM
50235+};
50236+static MV_STATUS mvXorInitWinsUnit (MV_U32 unit)
50237+{
50238+ MV_U32 winNum;
50239+ MV_XOR_DEC_WIN addrDecWin;
50240+ MV_CPU_DEC_WIN cpuAddrDecWin;
50241+ MV_U32 status;
50242+ MV_U32 winPrioIndex=0;
50243+
50244+ /* Initiate XOR address decode */
50245+
50246+ /* First disable all address decode windows */
50247+ for(winNum = 0; winNum < XOR_MAX_ADDR_DEC_WIN; winNum++)
50248+ {
50249+ mvXorTargetWinEnable(unit,winNum, MV_FALSE);
50250+ }
50251+
50252+ /* Go through all windows in user table until table terminator */
50253+ for (winNum = 0; ((xorAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
50254+ (winNum < XOR_MAX_ADDR_DEC_WIN));)
50255+ {
50256+ /* first get attributes from CPU If */
50257+ status = mvCpuIfTargetWinGet(xorAddrDecPrioTap[winPrioIndex],
50258+ &cpuAddrDecWin);
50259+
50260+ if(MV_NO_SUCH == status)
50261+ {
50262+ winPrioIndex++;
50263+ continue;
50264+ }
50265+ if (MV_OK != status)
50266+ {
50267+ mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
50268+ return MV_ERROR;
50269+ }
50270+
50271+
50272+ if (cpuAddrDecWin.enable == MV_TRUE)
50273+ {
50274+
50275+ addrDecWin.target = xorAddrDecPrioTap[winPrioIndex];
50276+ addrDecWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
50277+ addrDecWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
50278+ addrDecWin.addrWin.size = cpuAddrDecWin.addrWin.size;
50279+ addrDecWin.enable = MV_TRUE;
50280+
50281+ if (MV_OK != mvXorTargetWinSet(unit,winNum, &addrDecWin))
50282+ {
50283+ DB(mvOsPrintf("mvXorInit: ERR. mvDmaTargetWinSet failed\n"));
50284+ return MV_ERROR;
50285+ }
50286+ winNum++;
50287+ }
50288+ winPrioIndex++;
50289+
50290+ }
50291+
50292+ return MV_OK;
50293+}
50294+
50295+
50296+/*******************************************************************************
50297+* mvXorInit - Initialize XOR engine
50298+*
50299+* DESCRIPTION:
50300+* This function initialize XOR unit. It set the default address decode
50301+* windows of the unit.
50302+* Note that if the address window is disabled in xorAddrDecMap, the
50303+* window parameters will be set but the window will remain disabled.
50304+*
50305+* INPUT:
50306+* None.
50307+*
50308+* OUTPUT:
50309+* None.
50310+*
50311+* RETURN:
50312+* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
50313+*******************************************************************************/
50314+MV_STATUS mvXorInit (MV_VOID)
50315+{
50316+ MV_U32 i;
50317+
50318+ /* Initiate XOR address decode */
50319+ for(i = 0; i < MV_XOR_MAX_UNIT; i++)
50320+ mvXorInitWinsUnit(i);
50321+
50322+ mvXorHalInit(MV_XOR_MAX_CHAN);
50323+
50324+ return MV_OK;
50325+}
50326+
50327+/*******************************************************************************
50328+* mvXorTargetWinSet - Set XOR target address window
50329+*
50330+* DESCRIPTION:
50331+* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
50332+* address window. After setting this target window, the XOR will be
50333+* able to access the target within the address window.
50334+*
50335+* INPUT:
50336+* winNum - One of the possible XOR memory decode windows.
50337+* target - Peripheral target enumerator.
50338+* base - Window base address.
50339+* size - Window size.
50340+* enable - Window enable/disable.
50341+*
50342+* OUTPUT:
50343+* None.
50344+*
50345+* RETURN:
50346+* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
50347+*
50348+*******************************************************************************/
50349+MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)
50350+{
50351+ MV_DEC_REGS xorDecRegs;
50352+ MV_TARGET_ATTRIB targetAttribs;
50353+ MV_U32 chan;
50354+
50355+ /* Parameter checking */
50356+ if (winNum >= XOR_MAX_ADDR_DEC_WIN)
50357+ {
50358+ DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum));
50359+ return MV_BAD_PARAM;
50360+ }
50361+ if (pAddrDecWin == NULL)
50362+ {
50363+ DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));
50364+ return MV_BAD_PTR;
50365+ }
50366+ /* Check if the requested window overlaps with current windows */
50367+ if (MV_TRUE == xorWinOverlapDetect(unit, winNum, &pAddrDecWin->addrWin))
50368+ {
50369+ DB(mvOsPrintf("%s: ERR. Window %d overlap\n",__FUNCTION__,winNum));
50370+ return MV_ERROR;
50371+ }
50372+
50373+ xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));
50374+ xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));
50375+
50376+ /* Get Base Address and size registers values */
50377+ if(MV_OK != mvCtrlAddrDecToReg(&pAddrDecWin->addrWin, &xorDecRegs))
50378+ {
50379+ DB(mvOsPrintf("%s: ERR. Invalid addr dec window\n",__FUNCTION__));
50380+ return MV_BAD_PARAM;
50381+ }
50382+
50383+
50384+ mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
50385+
50386+ /* set attributes */
50387+ xorDecRegs.baseReg &= ~XEBARX_ATTR_MASK;
50388+ xorDecRegs.baseReg |= targetAttribs.attrib << XEBARX_ATTR_OFFS;
50389+ /* set target ID */
50390+ xorDecRegs.baseReg &= ~XEBARX_TARGET_MASK;
50391+ xorDecRegs.baseReg |= targetAttribs.targetId << XEBARX_TARGET_OFFS;
50392+
50393+
50394+ /* Write to address decode Base Address Register */
50395+ MV_REG_WRITE(XOR_BASE_ADDR_REG(unit,winNum), xorDecRegs.baseReg);
50396+
50397+ /* Write to Size Register */
50398+ MV_REG_WRITE(XOR_SIZE_MASK_REG(unit,winNum), xorDecRegs.sizeReg);
50399+
50400+ for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
50401+ {
50402+ if (pAddrDecWin->enable)
50403+ {
50404+ MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
50405+ XEXWCR_WIN_EN_MASK(winNum));
50406+ }
50407+ else
50408+ {
50409+ MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
50410+ XEXWCR_WIN_EN_MASK(winNum));
50411+ }
50412+ }
50413+ return MV_OK;
50414+}
50415+
50416+/*******************************************************************************
50417+* mvXorTargetWinGet - Get xor peripheral target address window.
50418+*
50419+* DESCRIPTION:
50420+* Get xor peripheral target address window.
50421+*
50422+* INPUT:
50423+* winNum - One of the possible XOR memory decode windows.
50424+*
50425+* OUTPUT:
50426+* base - Window base address.
50427+* size - Window size.
50428+* enable - window enable/disable.
50429+*
50430+* RETURN:
50431+* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
50432+*
50433+*******************************************************************************/
50434+MV_STATUS mvXorTargetWinGet(MV_U32 unit,MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)
50435+{
50436+ MV_DEC_REGS xorDecRegs;
50437+ MV_TARGET_ATTRIB targetAttrib;
50438+ MV_U32 chan=0,chanWinEn;
50439+
50440+ /* Parameter checking */
50441+ if (winNum >= XOR_MAX_ADDR_DEC_WIN)
50442+ {
50443+ DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__ , winNum));
50444+ return MV_ERROR;
50445+ }
50446+
50447+ if (NULL == pAddrDecWin)
50448+ {
50449+ DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));
50450+ return MV_BAD_PTR;
50451+ }
50452+
50453+ chanWinEn = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,0)) & XEXWCR_WIN_EN_MASK(winNum);
50454+
50455+ for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++) /* we should scan here all channels per unit */
50456+ {
50457+ /* Check if enable bit is equal for all channels */
50458+ if ((MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) &
50459+ XEXWCR_WIN_EN_MASK(winNum)) != chanWinEn)
50460+ {
50461+ mvOsPrintf("%s: ERR. Window enable field must be equal in "
50462+ "all channels(chan=%d)\n",__FUNCTION__, chan);
50463+ return MV_ERROR;
50464+ }
50465+ }
50466+
50467+
50468+
50469+ xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));
50470+ xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));
50471+
50472+ if (MV_OK != mvCtrlRegToAddrDec(&xorDecRegs, &pAddrDecWin->addrWin))
50473+ {
50474+ mvOsPrintf("%s: ERR. mvCtrlRegToAddrDec failed\n", __FUNCTION__);
50475+ return MV_ERROR;
50476+ }
50477+
50478+ /* attrib and targetId */
50479+ targetAttrib.attrib =
50480+ (xorDecRegs.baseReg & XEBARX_ATTR_MASK) >> XEBARX_ATTR_OFFS;
50481+ targetAttrib.targetId =
50482+ (xorDecRegs.baseReg & XEBARX_TARGET_MASK) >> XEBARX_TARGET_OFFS;
50483+
50484+
50485+ pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
50486+
50487+ if(chanWinEn)
50488+ {
50489+ pAddrDecWin->enable = MV_TRUE;
50490+ }
50491+ else pAddrDecWin->enable = MV_FALSE;
50492+
50493+ return MV_OK;
50494+}
50495+
50496+/*******************************************************************************
50497+* mvXorTargetWinEnable - Enable/disable a Xor address decode window
50498+*
50499+* DESCRIPTION:
50500+* This function enable/disable a XOR address decode window.
50501+* if parameter 'enable' == MV_TRUE the routine will enable the
50502+* window, thus enabling XOR accesses (before enabling the window it is
50503+* tested for overlapping). Otherwise, the window will be disabled.
50504+*
50505+* INPUT:
50506+* winNum - Decode window number.
50507+* enable - Enable/disable parameter.
50508+*
50509+* OUTPUT:
50510+* None.
50511+*
50512+* RETURN:
50513+* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
50514+*
50515+*******************************************************************************/
50516+MV_STATUS mvXorTargetWinEnable(MV_U32 unit,MV_U32 winNum, MV_BOOL enable)
50517+{
50518+ MV_XOR_DEC_WIN addrDecWin;
50519+ MV_U32 chan;
50520+
50521+ /* Parameter checking */
50522+ if (winNum >= XOR_MAX_ADDR_DEC_WIN)
50523+ {
50524+ DB(mvOsPrintf("%s: ERR. Invalid winNum%d\n", __FUNCTION__, winNum));
50525+ return MV_ERROR;
50526+ }
50527+
50528+ if (enable == MV_TRUE)
50529+ {
50530+ /* Get current window */
50531+ if (MV_OK != mvXorTargetWinGet(unit,winNum, &addrDecWin))
50532+ {
50533+ DB(mvOsPrintf("%s: ERR. targetWinGet fail\n", __FUNCTION__));
50534+ return MV_ERROR;
50535+ }
50536+
50537+ /* Check for overlapping */
50538+ if (MV_TRUE == xorWinOverlapDetect(unit,winNum, &(addrDecWin.addrWin)))
50539+ {
50540+ /* Overlap detected */
50541+ DB(mvOsPrintf("%s: ERR. Overlap detected\n", __FUNCTION__));
50542+ return MV_ERROR;
50543+ }
50544+
50545+ /* No Overlap. Enable address decode target window */
50546+ for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
50547+ {
50548+ MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
50549+ XEXWCR_WIN_EN_MASK(winNum));
50550+ }
50551+
50552+ }
50553+ else
50554+ {
50555+ /* Disable address decode target window */
50556+
50557+ for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
50558+ {
50559+ MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
50560+ XEXWCR_WIN_EN_MASK(winNum));
50561+ }
50562+
50563+ }
50564+
50565+ return MV_OK;
50566+}
50567+
50568+/*******************************************************************************
50569+* mvXorSetProtWinSet - Configure access attributes of a XOR engine
50570+* to one of the XOR memory windows.
50571+*
50572+* DESCRIPTION:
50573+* Each engine can be configured with access attributes for each of the
50574+* memory spaces. This function sets access attributes
50575+* to a given window for the given engine
50576+*
50577+* INPUTS:
50578+* chan - One of the possible engines.
50579+* winNum - One of the possible XOR memory spaces.
50580+* access - Protection access rights.
50581+* write - Write rights.
50582+*
50583+* OUTPUT:
50584+* None.
50585+*
50586+* RETURN:
50587+* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
50588+*
50589+*******************************************************************************/
50590+MV_STATUS mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access,
50591+ MV_BOOL write)
50592+{
50593+ MV_U32 temp;
50594+
50595+ /* Parameter checking */
50596+ if (chan >= MV_XOR_MAX_CHAN_PER_UNIT)
50597+ {
50598+ DB(mvOsPrintf("%s: ERR. Invalid chan num %d\n", __FUNCTION__ , chan));
50599+ return MV_BAD_PARAM;
50600+ }
50601+ if (winNum >= XOR_MAX_ADDR_DEC_WIN)
50602+ {
50603+ DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));
50604+ return MV_BAD_PARAM;
50605+ }
50606+
50607+ temp = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) &
50608+ (~XEXWCR_WIN_ACC_MASK(winNum));
50609+
50610+ /* if access is disable */
50611+ if (!access)
50612+ {
50613+ /* disable access */
50614+ temp |= XEXWCR_WIN_ACC_NO_ACC(winNum);
50615+ }
50616+ /* if access is enable */
50617+ else
50618+ {
50619+ /* if write is enable */
50620+ if (write)
50621+ {
50622+ /* enable write */
50623+ temp |= XEXWCR_WIN_ACC_RW(winNum);
50624+ }
50625+ /* if write is disable */
50626+ else
50627+ {
50628+ /* disable write */
50629+ temp |= XEXWCR_WIN_ACC_RO(winNum);
50630+ }
50631+ }
50632+ MV_REG_WRITE(XOR_WINDOW_CTRL_REG(unit,chan),temp);
50633+ return MV_OK;
50634+}
50635+
50636+/*******************************************************************************
50637+* mvXorPciRemap - Set XOR remap register for PCI address windows.
50638+*
50639+* DESCRIPTION:
50640+* only Windows 0-3 can be remapped.
50641+*
50642+* INPUT:
50643+* winNum - window number
50644+* pAddrDecWin - pointer to address space window structure
50645+* OUTPUT:
50646+* None.
50647+*
50648+* RETURN:
50649+* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
50650+*
50651+*******************************************************************************/
50652+MV_STATUS mvXorPciRemap(MV_U32 unit,MV_U32 winNum, MV_U32 addrHigh)
50653+{
50654+ /* Parameter checking */
50655+ if (winNum >= XOR_MAX_REMAP_WIN)
50656+ {
50657+ DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));
50658+ return MV_BAD_PARAM;
50659+ }
50660+
50661+ MV_REG_WRITE(XOR_HIGH_ADDR_REMAP_REG(unit,winNum), addrHigh);
50662+
50663+ return MV_OK;
50664+}
50665+
50666+/*******************************************************************************
50667+* xorWinOverlapDetect - Detect XOR address windows overlaping
50668+*
50669+* DESCRIPTION:
50670+* An unpredicted behaviour is expected in case XOR address decode
50671+* windows overlaps.
50672+* This function detects XOR address decode windows overlaping of a
50673+* specified window. The function does not check the window itself for
50674+* overlaping. The function also skipps disabled address decode windows.
50675+*
50676+* INPUT:
50677+* winNum - address decode window number.
50678+* pAddrDecWin - An address decode window struct.
50679+*
50680+* OUTPUT:
50681+* None.
50682+*
50683+* RETURN:
50684+* MV_TRUE if the given address window overlap current address
50685+* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
50686+* from registers.
50687+*
50688+*******************************************************************************/
50689+static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
50690+{
50691+ MV_U32 baseAddrEnableReg;
50692+ MV_U32 winNumIndex,chan;
50693+ MV_XOR_DEC_WIN addrDecWin;
50694+
50695+ if (pAddrWin == NULL)
50696+ {
50697+ DB(mvOsPrintf("%s: ERR. pAddrWin is NULL pointer\n", __FUNCTION__ ));
50698+ return MV_BAD_PTR;
50699+ }
50700+
50701+ for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
50702+ {
50703+ /* Read base address enable register. Do not check disabled windows */
50704+ baseAddrEnableReg = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan));
50705+
50706+ for (winNumIndex = 0; winNumIndex < XOR_MAX_ADDR_DEC_WIN; winNumIndex++)
50707+ {
50708+ /* Do not check window itself */
50709+ if (winNumIndex == winNum)
50710+ {
50711+ continue;
50712+ }
50713+
50714+ /* Do not check disabled windows */
50715+ if ((baseAddrEnableReg & XEXWCR_WIN_EN_MASK(winNumIndex)) == 0)
50716+ {
50717+ continue;
50718+ }
50719+
50720+ /* Get window parameters */
50721+ if (MV_OK != mvXorTargetWinGet(unit,winNumIndex, &addrDecWin))
50722+ {
50723+ DB(mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__ ));
50724+ return MV_ERROR;
50725+ }
50726+
50727+ if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
50728+ {
50729+ return MV_TRUE;
50730+ }
50731+ }
50732+ }
50733+
50734+ return MV_FALSE;
50735+}
50736+
50737+static MV_VOID mvXorAddrDecShowUnit(MV_U32 unit)
50738+{
50739+ MV_XOR_DEC_WIN win;
50740+ int i;
50741+
50742+ mvOsOutput( "\n" );
50743+ mvOsOutput( "XOR %d:\n", unit );
50744+ mvOsOutput( "----\n" );
50745+
50746+ for( i = 0; i < XOR_MAX_ADDR_DEC_WIN; i++ )
50747+ {
50748+ memset( &win, 0, sizeof(MV_XOR_DEC_WIN) );
50749+
50750+ mvOsOutput( "win%d - ", i );
50751+
50752+ if( mvXorTargetWinGet(unit, i, &win ) == MV_OK )
50753+ {
50754+ if( win.enable )
50755+ {
50756+ mvOsOutput( "%s base %x, ",
50757+ mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
50758+
50759+ mvSizePrint( win.addrWin.size );
50760+
50761+ mvOsOutput( "\n" );
50762+ }
50763+ else
50764+ mvOsOutput( "disable\n" );
50765+ }
50766+ }
50767+}
50768+
50769+/*******************************************************************************
50770+* mvXorAddrDecShow - Print the XOR address decode map.
50771+*
50772+* DESCRIPTION:
50773+* This function print the XOR address decode map.
50774+*
50775+* INPUT:
50776+* None.
50777+*
50778+* OUTPUT:
50779+* None.
50780+*
50781+* RETURN:
50782+* None.
50783+*
50784+*******************************************************************************/
50785+MV_VOID mvXorAddrDecShow(MV_VOID)
50786+{
50787+ int i;
50788+
50789+ for( i = 0; i < MV_XOR_MAX_UNIT; i++ )
50790+ mvXorAddrDecShowUnit(i);
50791+
50792+}
50793diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h
50794new file mode 100644
50795index 0000000..0a7be8f
50796--- /dev/null
50797+++ b/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h
50798@@ -0,0 +1,140 @@
50799+/*******************************************************************************
50800+Copyright (C) Marvell International Ltd. and its affiliates
50801+
50802+This software file (the "File") is owned and distributed by Marvell
50803+International Ltd. and/or its affiliates ("Marvell") under the following
50804+alternative licensing terms. Once you have made an election to distribute the
50805+File under one of the following license alternatives, please (i) delete this
50806+introductory statement regarding license alternatives, (ii) delete the two
50807+license alternatives that you have not elected to use and (iii) preserve the
50808+Marvell copyright notice above.
50809+
50810+********************************************************************************
50811+Marvell Commercial License Option
50812+
50813+If you received this File from Marvell and you have entered into a commercial
50814+license agreement (a "Commercial License") with Marvell, the File is licensed
50815+to you under the terms of the applicable Commercial License.
50816+
50817+********************************************************************************
50818+Marvell GPL License Option
50819+
50820+If you received this File from Marvell, you may opt to use, redistribute and/or
50821+modify this File in accordance with the terms and conditions of the General
50822+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
50823+available along with the File in the license.txt file or by writing to the Free
50824+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
50825+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
50826+
50827+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
50828+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
50829+DISCLAIMED. The GPL License provides additional details about this warranty
50830+disclaimer.
50831+********************************************************************************
50832+Marvell BSD License Option
50833+
50834+If you received this File from Marvell, you may opt to use, redistribute and/or
50835+modify this File under the following licensing terms.
50836+Redistribution and use in source and binary forms, with or without modification,
50837+are permitted provided that the following conditions are met:
50838+
50839+ * Redistributions of source code must retain the above copyright notice,
50840+ this list of conditions and the following disclaimer.
50841+
50842+ * Redistributions in binary form must reproduce the above copyright
50843+ notice, this list of conditions and the following disclaimer in the
50844+ documentation and/or other materials provided with the distribution.
50845+
50846+ * Neither the name of Marvell nor the names of its contributors may be
50847+ used to endorse or promote products derived from this software without
50848+ specific prior written permission.
50849+
50850+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
50851+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50852+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50853+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
50854+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50855+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50856+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
50857+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50858+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50859+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50860+
50861+*******************************************************************************/
50862+
50863+#ifndef __INCMVSysXorh
50864+#define __INCMVSysXorh
50865+
50866+
50867+#ifdef __cplusplus
50868+extern "C" {
50869+#endif
50870+
50871+#include "ctrlEnv/sys/mvCpuIf.h"
50872+
50873+#include "ctrlEnv/mvCtrlEnvLib.h"
50874+#include "ctrlEnv/mvCtrlEnvAddrDec.h"
50875+
50876+#define XOR_MAX_ADDR_DEC_WIN 8 /* Maximum address decode windows */
50877+#define XOR_MAX_REMAP_WIN 4 /* Maximum address arbiter windows */
50878+
50879+/* XOR Engine Address Decoding Register Map */
50880+#define XOR_WINDOW_CTRL_REG(unit,chan) (XOR_UNIT_BASE(unit)+(0x240 + ((chan) * 4)))
50881+#define XOR_BASE_ADDR_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x250 + ((winNum) * 4)))
50882+#define XOR_SIZE_MASK_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x270 + ((winNum) * 4)))
50883+#define XOR_HIGH_ADDR_REMAP_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x290 + ((winNum) * 4)))
50884+
50885+/* XOR Engine [0..1] Window Control Registers (XExWCR) */
50886+#define XEXWCR_WIN_EN_OFFS(winNum) (winNum)
50887+#define XEXWCR_WIN_EN_MASK(winNum) (1 << (XEXWCR_WIN_EN_OFFS(winNum)))
50888+#define XEXWCR_WIN_EN_ENABLE(winNum) (1 << (XEXWCR_WIN_EN_OFFS(winNum)))
50889+#define XEXWCR_WIN_EN_DISABLE(winNum) (0 << (XEXWCR_WIN_EN_OFFS(winNum)))
50890+
50891+#define XEXWCR_WIN_ACC_OFFS(winNum) ((2 * winNum) + 16)
50892+#define XEXWCR_WIN_ACC_MASK(winNum) (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))
50893+#define XEXWCR_WIN_ACC_NO_ACC(winNum) (0 << (XEXWCR_WIN_ACC_OFFS(winNum)))
50894+#define XEXWCR_WIN_ACC_RO(winNum) (1 << (XEXWCR_WIN_ACC_OFFS(winNum)))
50895+#define XEXWCR_WIN_ACC_RW(winNum) (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))
50896+
50897+/* XOR Engine Base Address Registers (XEBARx) */
50898+#define XEBARX_TARGET_OFFS (0)
50899+#define XEBARX_TARGET_MASK (0xF << XEBARX_TARGET_OFFS)
50900+#define XEBARX_ATTR_OFFS (8)
50901+#define XEBARX_ATTR_MASK (0xFF << XEBARX_ATTR_OFFS)
50902+#define XEBARX_BASE_OFFS (16)
50903+#define XEBARX_BASE_MASK (0xFFFF << XEBARX_BASE_OFFS)
50904+
50905+/* XOR Engine Size Mask Registers (XESMRx) */
50906+#define XESMRX_SIZE_MASK_OFFS (16)
50907+#define XESMRX_SIZE_MASK_MASK (0xFFFF << XESMRX_SIZE_MASK_OFFS)
50908+
50909+/* XOR Engine High Address Remap Register (XEHARRx1) */
50910+#define XEHARRX_REMAP_OFFS (0)
50911+#define XEHARRX_REMAP_MASK (0xFFFFFFFF << XEHARRX_REMAP_OFFS)
50912+
50913+typedef struct _mvXorDecWin
50914+{
50915+ MV_TARGET target;
50916+ MV_ADDR_WIN addrWin; /* An address window*/
50917+ MV_BOOL enable; /* Address decode window is enabled/disabled */
50918+
50919+}MV_XOR_DEC_WIN;
50920+
50921+MV_STATUS mvXorInit (MV_VOID);
50922+MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum,
50923+ MV_XOR_DEC_WIN *pAddrDecWin);
50924+MV_STATUS mvXorTargetWinGet(MV_U32 unit, MV_U32 winNum,
50925+ MV_XOR_DEC_WIN *pAddrDecWin);
50926+MV_STATUS mvXorTargetWinEnable(MV_U32 unit,
50927+ MV_U32 winNum, MV_BOOL enable);
50928+MV_STATUS mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access,
50929+ MV_BOOL write);
50930+MV_STATUS mvXorPciRemap(MV_U32 unit, MV_U32 winNum, MV_U32 addrHigh);
50931+
50932+MV_VOID mvXorAddrDecShow(MV_VOID);
50933+
50934+#ifdef __cplusplus
50935+}
50936+#endif
50937+
50938+#endif
50939diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c b/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c
50940new file mode 100644
50941index 0000000..a327944
50942--- /dev/null
50943+++ b/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c
50944@@ -0,0 +1,75 @@
50945+/*******************************************************************************
50946+Copyright (C) Marvell International Ltd. and its affiliates
50947+
50948+This software file (the "File") is owned and distributed by Marvell
50949+International Ltd. and/or its affiliates ("Marvell") under the following
50950+alternative licensing terms. Once you have made an election to distribute the
50951+File under one of the following license alternatives, please (i) delete this
50952+introductory statement regarding license alternatives, (ii) delete the two
50953+license alternatives that you have not elected to use and (iii) preserve the
50954+Marvell copyright notice above.
50955+
50956+********************************************************************************
50957+Marvell Commercial License Option
50958+
50959+If you received this File from Marvell and you have entered into a commercial
50960+license agreement (a "Commercial License") with Marvell, the File is licensed
50961+to you under the terms of the applicable Commercial License.
50962+
50963+********************************************************************************
50964+Marvell GPL License Option
50965+
50966+If you received this File from Marvell, you may opt to use, redistribute and/or
50967+modify this File in accordance with the terms and conditions of the General
50968+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
50969+available along with the File in the license.txt file or by writing to the Free
50970+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
50971+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
50972+
50973+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
50974+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
50975+DISCLAIMED. The GPL License provides additional details about this warranty
50976+disclaimer.
50977+********************************************************************************
50978+Marvell BSD License Option
50979+
50980+If you received this File from Marvell, you may opt to use, redistribute and/or
50981+modify this File under the following licensing terms.
50982+Redistribution and use in source and binary forms, with or without modification,
50983+are permitted provided that the following conditions are met:
50984+
50985+ * Redistributions of source code must retain the above copyright notice,
50986+ this list of conditions and the following disclaimer.
50987+
50988+ * Redistributions in binary form must reproduce the above copyright
50989+ notice, this list of conditions and the following disclaimer in the
50990+ documentation and/or other materials provided with the distribution.
50991+
50992+ * Neither the name of Marvell nor the names of its contributors may be
50993+ used to endorse or promote products derived from this software without
50994+ specific prior written permission.
50995+
50996+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
50997+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50998+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50999+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
51000+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51001+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51002+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
51003+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51004+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51005+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51006+
51007+*******************************************************************************/
51008+
51009+#include "device/mvDevice.h"
51010+
51011+/* defines */
51012+#ifdef MV_DEBUG
51013+ #define DB(x) x
51014+#else
51015+ #define DB(x)
51016+#endif
51017+
51018+
51019+
51020diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h b/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h
51021new file mode 100644
51022index 0000000..a8a382b
51023--- /dev/null
51024+++ b/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h
51025@@ -0,0 +1,74 @@
51026+/*******************************************************************************
51027+Copyright (C) Marvell International Ltd. and its affiliates
51028+
51029+This software file (the "File") is owned and distributed by Marvell
51030+International Ltd. and/or its affiliates ("Marvell") under the following
51031+alternative licensing terms. Once you have made an election to distribute the
51032+File under one of the following license alternatives, please (i) delete this
51033+introductory statement regarding license alternatives, (ii) delete the two
51034+license alternatives that you have not elected to use and (iii) preserve the
51035+Marvell copyright notice above.
51036+
51037+********************************************************************************
51038+Marvell Commercial License Option
51039+
51040+If you received this File from Marvell and you have entered into a commercial
51041+license agreement (a "Commercial License") with Marvell, the File is licensed
51042+to you under the terms of the applicable Commercial License.
51043+
51044+********************************************************************************
51045+Marvell GPL License Option
51046+
51047+If you received this File from Marvell, you may opt to use, redistribute and/or
51048+modify this File in accordance with the terms and conditions of the General
51049+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
51050+available along with the File in the license.txt file or by writing to the Free
51051+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
51052+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
51053+
51054+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
51055+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
51056+DISCLAIMED. The GPL License provides additional details about this warranty
51057+disclaimer.
51058+********************************************************************************
51059+Marvell BSD License Option
51060+
51061+If you received this File from Marvell, you may opt to use, redistribute and/or
51062+modify this File under the following licensing terms.
51063+Redistribution and use in source and binary forms, with or without modification,
51064+are permitted provided that the following conditions are met:
51065+
51066+ * Redistributions of source code must retain the above copyright notice,
51067+ this list of conditions and the following disclaimer.
51068+
51069+ * Redistributions in binary form must reproduce the above copyright
51070+ notice, this list of conditions and the following disclaimer in the
51071+ documentation and/or other materials provided with the distribution.
51072+
51073+ * Neither the name of Marvell nor the names of its contributors may be
51074+ used to endorse or promote products derived from this software without
51075+ specific prior written permission.
51076+
51077+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
51078+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51079+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51080+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
51081+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51082+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51083+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
51084+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51085+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51086+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51087+
51088+*******************************************************************************/
51089+
51090+#ifndef __INCmvDeviceH
51091+#define __INCmvDeviceH
51092+
51093+#include "mvCommon.h"
51094+#include "mvOs.h"
51095+#include "ctrlEnv/mvCtrlEnvSpec.h"
51096+#include "device/mvDeviceRegs.h"
51097+
51098+
51099+#endif /* #ifndef __INCmvDeviceH */
51100diff --git a/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h b/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h
51101new file mode 100644
51102index 0000000..599dfe3
51103--- /dev/null
51104+++ b/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h
51105@@ -0,0 +1,101 @@
51106+/*******************************************************************************
51107+Copyright (C) Marvell International Ltd. and its affiliates
51108+
51109+This software file (the "File") is owned and distributed by Marvell
51110+International Ltd. and/or its affiliates ("Marvell") under the following
51111+alternative licensing terms. Once you have made an election to distribute the
51112+File under one of the following license alternatives, please (i) delete this
51113+introductory statement regarding license alternatives, (ii) delete the two
51114+license alternatives that you have not elected to use and (iii) preserve the
51115+Marvell copyright notice above.
51116+
51117+********************************************************************************
51118+Marvell Commercial License Option
51119+
51120+If you received this File from Marvell and you have entered into a commercial
51121+license agreement (a "Commercial License") with Marvell, the File is licensed
51122+to you under the terms of the applicable Commercial License.
51123+
51124+********************************************************************************
51125+Marvell GPL License Option
51126+
51127+If you received this File from Marvell, you may opt to use, redistribute and/or
51128+modify this File in accordance with the terms and conditions of the General
51129+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
51130+available along with the File in the license.txt file or by writing to the Free
51131+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
51132+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
51133+
51134+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
51135+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
51136+DISCLAIMED. The GPL License provides additional details about this warranty
51137+disclaimer.
51138+********************************************************************************
51139+Marvell BSD License Option
51140+
51141+If you received this File from Marvell, you may opt to use, redistribute and/or
51142+modify this File under the following licensing terms.
51143+Redistribution and use in source and binary forms, with or without modification,
51144+are permitted provided that the following conditions are met:
51145+
51146+ * Redistributions of source code must retain the above copyright notice,
51147+ this list of conditions and the following disclaimer.
51148+
51149+ * Redistributions in binary form must reproduce the above copyright
51150+ notice, this list of conditions and the following disclaimer in the
51151+ documentation and/or other materials provided with the distribution.
51152+
51153+ * Neither the name of Marvell nor the names of its contributors may be
51154+ used to endorse or promote products derived from this software without
51155+ specific prior written permission.
51156+
51157+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
51158+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51159+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51160+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
51161+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51162+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51163+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
51164+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51165+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51166+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51167+
51168+*******************************************************************************/
51169+
51170+#ifndef __INCmvDeviceRegsH
51171+#define __INCmvDeviceRegsH
51172+
51173+#ifndef MV_ASMLANGUAGE
51174+#include "ctrlEnv/mvCtrlEnvLib.h"
51175+/* This enumerator describes the Marvell controller possible devices that */
51176+/* can be connected to its device interface. */
51177+typedef enum _mvDevice
51178+{
51179+#if defined(MV_INCLUDE_DEVICE_CS0)
51180+ DEV_CS0 = 0, /* Device connected to dev CS[0] */
51181+#endif
51182+#if defined(MV_INCLUDE_DEVICE_CS1)
51183+ DEV_CS1 = 1, /* Device connected to dev CS[1] */
51184+#endif
51185+#if defined(MV_INCLUDE_DEVICE_CS2)
51186+ DEV_CS2 = 2, /* Device connected to dev CS[2] */
51187+#endif
51188+#if defined(MV_INCLUDE_DEVICE_CS3)
51189+ DEV_CS3 = 3, /* Device connected to dev CS[2] */
51190+#endif
51191+#if defined(MV_INCLUDE_DEVICE_CS4)
51192+ DEV_CS4 = 4, /* Device connected to BOOT dev */
51193+#endif
51194+ MV_DEV_MAX_CS = MV_DEVICE_MAX_CS
51195+}MV_DEVICE;
51196+
51197+
51198+#endif /* MV_ASMLANGUAGE */
51199+
51200+
51201+#define NAND_CTRL_REG 0x10470
51202+
51203+#define NAND_ACTCEBOOT_BIT BIT1
51204+
51205+
51206+#endif /* #ifndef __INCmvDeviceRegsH */
51207diff --git a/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c b/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c
51208new file mode 100644
51209index 0000000..749b885
51210--- /dev/null
51211+++ b/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c
51212@@ -0,0 +1,211 @@
51213+/*******************************************************************************
51214+Copyright (C) Marvell International Ltd. and its affiliates
51215+
51216+This software file (the "File") is owned and distributed by Marvell
51217+International Ltd. and/or its affiliates ("Marvell") under the following
51218+alternative licensing terms. Once you have made an election to distribute the
51219+File under one of the following license alternatives, please (i) delete this
51220+introductory statement regarding license alternatives, (ii) delete the two
51221+license alternatives that you have not elected to use and (iii) preserve the
51222+Marvell copyright notice above.
51223+
51224+
51225+********************************************************************************
51226+Marvell GPL License Option
51227+
51228+If you received this File from Marvell, you may opt to use, redistribute and/or
51229+modify this File in accordance with the terms and conditions of the General
51230+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
51231+available along with the File in the license.txt file or by writing to the Free
51232+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
51233+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
51234+
51235+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
51236+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
51237+DISCLAIMED. The GPL License provides additional details about this warranty
51238+disclaimer.
51239+*******************************************************************************/
51240+/*******************************************************************************
51241+* mvOsCpuArchLib.c - Marvell CPU architecture library
51242+*
51243+* DESCRIPTION:
51244+* This library introduce Marvell API for OS dependent CPU architecture
51245+* APIs. This library introduce single CPU architecture services APKI
51246+* cross OS.
51247+*
51248+* DEPENDENCIES:
51249+* None.
51250+*
51251+*******************************************************************************/
51252+
51253+/* includes */
51254+#include <asm/processor.h>
51255+#include "mvOs.h"
51256+
51257+static MV_U32 read_p15_c0 (void);
51258+
51259+/* defines */
51260+#define ARM_ID_REVISION_OFFS 0
51261+#define ARM_ID_REVISION_MASK (0xf << ARM_ID_REVISION_OFFS)
51262+
51263+#define ARM_ID_PART_NUM_OFFS 4
51264+#define ARM_ID_PART_NUM_MASK (0xfff << ARM_ID_PART_NUM_OFFS)
51265+
51266+#define ARM_ID_ARCH_OFFS 16
51267+#define ARM_ID_ARCH_MASK (0xf << ARM_ID_ARCH_OFFS)
51268+
51269+#define ARM_ID_VAR_OFFS 20
51270+#define ARM_ID_VAR_MASK (0xf << ARM_ID_VAR_OFFS)
51271+
51272+#define ARM_ID_ASCII_OFFS 24
51273+#define ARM_ID_ASCII_MASK (0xff << ARM_ID_ASCII_OFFS)
51274+
51275+
51276+
51277+void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,
51278+ MV_U32 *memHandle)
51279+{
51280+ void *p = kmalloc( size, GFP_KERNEL );
51281+ *pPhyAddr = pci_map_single( osHandle, p, 0, PCI_DMA_BIDIRECTIONAL );
51282+ return p;
51283+}
51284+void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,
51285+ MV_U32 *memHandle)
51286+{
51287+ return pci_alloc_consistent( osHandle, size, (dma_addr_t *)pPhyAddr );
51288+}
51289+
51290+void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,
51291+ MV_U32 memHandle)
51292+{
51293+ return pci_free_consistent( osHandle, size, pVirtAddr, (dma_addr_t)phyAddr );
51294+}
51295+
51296+void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,
51297+ MV_U32 memHandle )
51298+{
51299+ return kfree( pVirtAddr );
51300+}
51301+
51302+int mvOsRand(void)
51303+{
51304+ int rand;
51305+ get_random_bytes(&rand, sizeof(rand) );
51306+ return rand;
51307+}
51308+
51309+/*******************************************************************************
51310+* mvOsCpuVerGet() -
51311+*
51312+* DESCRIPTION:
51313+*
51314+* INPUT:
51315+* None.
51316+*
51317+* OUTPUT:
51318+* None.
51319+*
51320+* RETURN:
51321+* 32bit CPU Revision
51322+*
51323+*******************************************************************************/
51324+MV_U32 mvOsCpuRevGet( MV_VOID )
51325+{
51326+ return ((read_p15_c0() & ARM_ID_REVISION_MASK ) >> ARM_ID_REVISION_OFFS);
51327+}
51328+/*******************************************************************************
51329+* mvOsCpuPartGet() -
51330+*
51331+* DESCRIPTION:
51332+*
51333+* INPUT:
51334+* None.
51335+*
51336+* OUTPUT:
51337+* None.
51338+*
51339+* RETURN:
51340+* 32bit CPU Part number
51341+*
51342+*******************************************************************************/
51343+MV_U32 mvOsCpuPartGet( MV_VOID )
51344+{
51345+ return ((read_p15_c0() & ARM_ID_PART_NUM_MASK ) >> ARM_ID_PART_NUM_OFFS);
51346+}
51347+/*******************************************************************************
51348+* mvOsCpuArchGet() -
51349+*
51350+* DESCRIPTION:
51351+*
51352+* INPUT:
51353+* None.
51354+*
51355+* OUTPUT:
51356+* None.
51357+*
51358+* RETURN:
51359+* 32bit CPU Architicture number
51360+*
51361+*******************************************************************************/
51362+MV_U32 mvOsCpuArchGet( MV_VOID )
51363+{
51364+ return ((read_p15_c0() & ARM_ID_ARCH_MASK ) >> ARM_ID_ARCH_OFFS);
51365+}
51366+/*******************************************************************************
51367+* mvOsCpuVarGet() -
51368+*
51369+* DESCRIPTION:
51370+*
51371+* INPUT:
51372+* None.
51373+*
51374+* OUTPUT:
51375+* None.
51376+*
51377+* RETURN:
51378+* 32bit CPU Variant number
51379+*
51380+*******************************************************************************/
51381+MV_U32 mvOsCpuVarGet( MV_VOID )
51382+{
51383+ return ((read_p15_c0() & ARM_ID_VAR_MASK ) >> ARM_ID_VAR_OFFS);
51384+}
51385+/*******************************************************************************
51386+* mvOsCpuAsciiGet() -
51387+*
51388+* DESCRIPTION:
51389+*
51390+* INPUT:
51391+* None.
51392+*
51393+* OUTPUT:
51394+* None.
51395+*
51396+* RETURN:
51397+* 32bit CPU Variant number
51398+*
51399+*******************************************************************************/
51400+MV_U32 mvOsCpuAsciiGet( MV_VOID )
51401+{
51402+ return ((read_p15_c0() & ARM_ID_ASCII_MASK ) >> ARM_ID_ASCII_OFFS);
51403+}
51404+
51405+
51406+
51407+/*
51408+static unsigned long read_p15_c0 (void)
51409+*/
51410+/* read co-processor 15, register #0 (ID register) */
51411+static MV_U32 read_p15_c0 (void)
51412+{
51413+ MV_U32 value;
51414+
51415+ __asm__ __volatile__(
51416+ "mrc p15, 0, %0, c0, c0, 0 @ read control reg\n"
51417+ : "=r" (value)
51418+ :
51419+ : "memory");
51420+
51421+ return value;
51422+}
51423+
51424diff --git a/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h b/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h
51425new file mode 100644
51426index 0000000..9122a52
51427--- /dev/null
51428+++ b/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h
51429@@ -0,0 +1,423 @@
51430+/*******************************************************************************
51431+Copyright (C) Marvell International Ltd. and its affiliates
51432+
51433+This software file (the "File") is owned and distributed by Marvell
51434+International Ltd. and/or its affiliates ("Marvell") under the following
51435+alternative licensing terms. Once you have made an election to distribute the
51436+File under one of the following license alternatives, please (i) delete this
51437+introductory statement regarding license alternatives, (ii) delete the two
51438+license alternatives that you have not elected to use and (iii) preserve the
51439+Marvell copyright notice above.
51440+
51441+
51442+********************************************************************************
51443+Marvell GPL License Option
51444+
51445+If you received this File from Marvell, you may opt to use, redistribute and/or
51446+modify this File in accordance with the terms and conditions of the General
51447+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
51448+available along with the File in the license.txt file or by writing to the Free
51449+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
51450+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
51451+
51452+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
51453+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
51454+DISCLAIMED. The GPL License provides additional details about this warranty
51455+disclaimer.
51456+*******************************************************************************/
51457+#ifndef _MV_OS_LNX_H_
51458+#define _MV_OS_LNX_H_
51459+
51460+
51461+#ifdef __KERNEL__
51462+/* for kernel space */
51463+#include <linux/autoconf.h>
51464+#include <linux/interrupt.h>
51465+#include <linux/stddef.h>
51466+#include <linux/kernel.h>
51467+#include <linux/init.h>
51468+#include <linux/errno.h>
51469+#include <linux/reboot.h>
51470+#include <linux/pci.h>
51471+#include <linux/kdev_t.h>
51472+#include <linux/major.h>
51473+#include <linux/blkdev.h>
51474+#include <linux/console.h>
51475+#include <linux/delay.h>
51476+#include <linux/seq_file.h>
51477+#include <linux/string.h>
51478+#include <linux/slab.h>
51479+#include <linux/kernel.h>
51480+#include <linux/string.h>
51481+#include <linux/slab.h>
51482+#include <linux/mm.h>
51483+
51484+#include <asm/system.h>
51485+#include <asm/pgtable.h>
51486+#include <asm/page.h>
51487+#include <asm/hardirq.h>
51488+#include <asm/dma.h>
51489+#include <asm/io.h>
51490+
51491+#include <linux/random.h>
51492+
51493+#include "dbg-trace.h"
51494+
51495+extern void mv_early_printk(char *fmt,...);
51496+
51497+#define MV_ASM __asm__ __volatile__
51498+#define INLINE inline
51499+#define MV_TRC_REC TRC_REC
51500+#define mvOsPrintf printk
51501+#define mvOsEarlyPrintf mv_early_printk
51502+#define mvOsOutput printk
51503+#define mvOsSPrintf sprintf
51504+#define mvOsMalloc(_size_) kmalloc(_size_,GFP_ATOMIC)
51505+#define mvOsFree kfree
51506+#define mvOsMemcpy memcpy
51507+#define mvOsSleep(_mils_) mdelay(_mils_)
51508+#define mvOsTaskLock()
51509+#define mvOsTaskUnlock()
51510+#define strtol simple_strtoul
51511+#define mvOsDelay(x) mdelay(x)
51512+#define mvOsUDelay(x) udelay(x)
51513+#define mvCopyFromOs copy_from_user
51514+#define mvCopyToOs copy_to_user
51515+
51516+
51517+#include "mvTypes.h"
51518+#include "mvCommon.h"
51519+
51520+#ifdef MV_NDEBUG
51521+#define mvOsAssert(cond)
51522+#else
51523+#define mvOsAssert(cond) { do { if(!(cond)) { BUG(); } }while(0); }
51524+#endif /* MV_NDEBUG */
51525+
51526+#else /* __KERNEL__ */
51527+
51528+/* for user space applications */
51529+#include <stdlib.h>
51530+#include <stdio.h>
51531+#include <assert.h>
51532+#include <string.h>
51533+
51534+#define INLINE inline
51535+#define mvOsPrintf printf
51536+#define mvOsOutput printf
51537+#define mvOsMalloc(_size_) malloc(_size_)
51538+#define mvOsFree free
51539+#define mvOsAssert(cond) assert(cond)
51540+
51541+#endif /* __KERNEL__ */
51542+#define mvOsIoVirtToPhy(pDev, pVirtAddr) \
51543+ pci_map_single( (pDev), (pVirtAddr), 0, PCI_DMA_BIDIRECTIONAL )
51544+
51545+#define mvOsCacheClear(pDev, p, size ) \
51546+ pci_map_single( (pDev), (p), (size), PCI_DMA_BIDIRECTIONAL)
51547+
51548+#define mvOsCacheFlush(pDev, p, size ) \
51549+ pci_map_single( (pDev), (p), (size), PCI_DMA_TODEVICE)
51550+
51551+#define mvOsCacheInvalidate(pDev, p, size) \
51552+ pci_map_single( (pDev), (p), (size), PCI_DMA_FROMDEVICE )
51553+
51554+#define mvOsCacheUnmap(pDev, phys, size) \
51555+ pci_unmap_single( (pDev), (dma_addr_t)(phys), (size), PCI_DMA_FROMDEVICE )
51556+
51557+
51558+#define CPU_PHY_MEM(x) (MV_U32)x
51559+#define CPU_MEMIO_CACHED_ADDR(x) (void*)x
51560+#define CPU_MEMIO_UNCACHED_ADDR(x) (void*)x
51561+
51562+
51563+/* CPU architecture dependent 32, 16, 8 bit read/write IO addresses */
51564+#define MV_MEMIO32_WRITE(addr, data) \
51565+ ((*((volatile unsigned int*)(addr))) = ((unsigned int)(data)))
51566+
51567+#define MV_MEMIO32_READ(addr) \
51568+ ((*((volatile unsigned int*)(addr))))
51569+
51570+#define MV_MEMIO16_WRITE(addr, data) \
51571+ ((*((volatile unsigned short*)(addr))) = ((unsigned short)(data)))
51572+
51573+#define MV_MEMIO16_READ(addr) \
51574+ ((*((volatile unsigned short*)(addr))))
51575+
51576+#define MV_MEMIO8_WRITE(addr, data) \
51577+ ((*((volatile unsigned char*)(addr))) = ((unsigned char)(data)))
51578+
51579+#define MV_MEMIO8_READ(addr) \
51580+ ((*((volatile unsigned char*)(addr))))
51581+
51582+
51583+/* No Fast Swap implementation (in assembler) for ARM */
51584+#define MV_32BIT_LE_FAST(val) MV_32BIT_LE(val)
51585+#define MV_16BIT_LE_FAST(val) MV_16BIT_LE(val)
51586+#define MV_32BIT_BE_FAST(val) MV_32BIT_BE(val)
51587+#define MV_16BIT_BE_FAST(val) MV_16BIT_BE(val)
51588+
51589+/* 32 and 16 bit read/write in big/little endian mode */
51590+
51591+/* 16bit write in little endian mode */
51592+#define MV_MEMIO_LE16_WRITE(addr, data) \
51593+ MV_MEMIO16_WRITE(addr, MV_16BIT_LE_FAST(data))
51594+
51595+/* 16bit read in little endian mode */
51596+static __inline MV_U16 MV_MEMIO_LE16_READ(MV_U32 addr)
51597+{
51598+ MV_U16 data;
51599+
51600+ data= (MV_U16)MV_MEMIO16_READ(addr);
51601+
51602+ return (MV_U16)MV_16BIT_LE_FAST(data);
51603+}
51604+
51605+/* 32bit write in little endian mode */
51606+#define MV_MEMIO_LE32_WRITE(addr, data) \
51607+ MV_MEMIO32_WRITE(addr, MV_32BIT_LE_FAST(data))
51608+
51609+/* 32bit read in little endian mode */
51610+static __inline MV_U32 MV_MEMIO_LE32_READ(MV_U32 addr)
51611+{
51612+ MV_U32 data;
51613+
51614+ data= (MV_U32)MV_MEMIO32_READ(addr);
51615+
51616+ return (MV_U32)MV_32BIT_LE_FAST(data);
51617+}
51618+
51619+static __inline void mvOsBCopy(char* srcAddr, char* dstAddr, int byteCount)
51620+{
51621+ while(byteCount != 0)
51622+ {
51623+ *dstAddr = *srcAddr;
51624+ dstAddr++;
51625+ srcAddr++;
51626+ byteCount--;
51627+ }
51628+}
51629+
51630+static INLINE MV_U64 mvOsDivMod64(MV_U64 divided, MV_U64 divisor, MV_U64* modulu)
51631+{
51632+ MV_U64 division = 0;
51633+
51634+ if(divisor == 1)
51635+ return divided;
51636+
51637+ while(divided >= divisor)
51638+ {
51639+ division++;
51640+ divided -= divisor;
51641+ }
51642+ if (modulu != NULL)
51643+ *modulu = divided;
51644+
51645+ return division;
51646+}
51647+
51648+#if defined(MV_BRIDGE_SYNC_REORDER)
51649+extern MV_U32 *mvUncachedParam;
51650+
51651+static __inline void mvOsBridgeReorderWA(void)
51652+{
51653+ volatile MV_U32 val = 0;
51654+
51655+ val = mvUncachedParam[0];
51656+}
51657+#endif
51658+
51659+
51660+/* Flash APIs */
51661+#define MV_FL_8_READ MV_MEMIO8_READ
51662+#define MV_FL_16_READ MV_MEMIO_LE16_READ
51663+#define MV_FL_32_READ MV_MEMIO_LE32_READ
51664+#define MV_FL_8_DATA_READ MV_MEMIO8_READ
51665+#define MV_FL_16_DATA_READ MV_MEMIO16_READ
51666+#define MV_FL_32_DATA_READ MV_MEMIO32_READ
51667+#define MV_FL_8_WRITE MV_MEMIO8_WRITE
51668+#define MV_FL_16_WRITE MV_MEMIO_LE16_WRITE
51669+#define MV_FL_32_WRITE MV_MEMIO_LE32_WRITE
51670+#define MV_FL_8_DATA_WRITE MV_MEMIO8_WRITE
51671+#define MV_FL_16_DATA_WRITE MV_MEMIO16_WRITE
51672+#define MV_FL_32_DATA_WRITE MV_MEMIO32_WRITE
51673+
51674+
51675+/* CPU cache information */
51676+#define CPU_I_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
51677+#define CPU_D_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
51678+
51679+#ifdef CONFIG_L2_CACHE_ENABLE
51680+/* Data cache flush one line */
51681+#define mvOsCacheLineFlushInv(handle, addr) \
51682+{ \
51683+ __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\
51684+ __asm__ __volatile__ ("mcr p15, 1, %0, c15, c10, 1" : : "r" (addr));\
51685+ __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4"); \
51686+}
51687+
51688+#else
51689+
51690+/* Data cache flush one line */
51691+#define mvOsCacheLineFlushInv(handle, addr) \
51692+{ \
51693+ __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\
51694+ __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \
51695+}
51696+#endif
51697+
51698+#ifdef CONFIG_L2_CACHE_ENABLE
51699+#define mvOsCacheLineInv(handle,addr) \
51700+{ \
51701+ __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \
51702+ __asm__ __volatile__ ("mcr p15, 1, %0, c15, c11, 1" : : "r" (addr)); \
51703+}
51704+#else
51705+#define mvOsCacheLineInv(handle,addr) \
51706+{ \
51707+ __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \
51708+}
51709+#endif
51710+
51711+#ifdef CONFIG_L2_CACHE_ENABLE
51712+/* Data cache flush one line */
51713+#define mvOsCacheLineFlush(handle, addr) \
51714+{ \
51715+ __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\
51716+ __asm__ __volatile__ ("mcr p15, 1, %0, c15, c9, 1" : : "r" (addr));\
51717+ __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4"); \
51718+}
51719+
51720+#else
51721+/* Data cache flush one line */
51722+#define mvOsCacheLineFlush(handle, addr) \
51723+{ \
51724+ __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\
51725+ __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \
51726+}
51727+#endif
51728+
51729+static __inline void mvOsPrefetch(const void *ptr)
51730+{
51731+#ifdef CONFIG_USE_DSP
51732+ __asm__ __volatile__(
51733+ "pld\t%0"
51734+ :
51735+ : "o" (*(char *)ptr)
51736+ : "cc");
51737+#else
51738+ return;
51739+#endif
51740+}
51741+
51742+
51743+/* Flush CPU pipe */
51744+#define CPU_PIPE_FLUSH
51745+
51746+
51747+
51748+
51749+
51750+/* register manipulations */
51751+
51752+/******************************************************************************
51753+* This debug function enable the write of each register that u-boot access to
51754+* to an array in the DRAM, the function record only MV_REG_WRITE access.
51755+* The function could not be operate when booting from flash.
51756+* In order to print the array we use the printreg command.
51757+******************************************************************************/
51758+/* #define REG_DEBUG */
51759+#if defined(REG_DEBUG)
51760+extern int reg_arry[2048][2];
51761+extern int reg_arry_index;
51762+#endif
51763+
51764+/* Marvell controller register read/write macros */
51765+#define MV_REG_VALUE(offset) \
51766+ (MV_MEMIO32_READ((INTER_REGS_BASE | (offset))))
51767+
51768+#define MV_REG_READ(offset) \
51769+ (MV_MEMIO_LE32_READ(INTER_REGS_BASE | (offset)))
51770+
51771+#if defined(REG_DEBUG)
51772+#define MV_REG_WRITE(offset, val) \
51773+ MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val)); \
51774+ { \
51775+ reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
51776+ reg_arry[reg_arry_index][1] = (val);\
51777+ reg_arry_index++;\
51778+ }
51779+#else
51780+#define MV_REG_WRITE(offset, val) \
51781+ MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val));
51782+#endif
51783+
51784+#define MV_REG_BYTE_READ(offset) \
51785+ (MV_MEMIO8_READ((INTER_REGS_BASE | (offset))))
51786+
51787+#if defined(REG_DEBUG)
51788+#define MV_REG_BYTE_WRITE(offset, val) \
51789+ MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val)); \
51790+ { \
51791+ reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
51792+ reg_arry[reg_arry_index][1] = (val);\
51793+ reg_arry_index++;\
51794+ }
51795+#else
51796+#define MV_REG_BYTE_WRITE(offset, val) \
51797+ MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val))
51798+#endif
51799+
51800+#if defined(REG_DEBUG)
51801+#define MV_REG_BIT_SET(offset, bitMask) \
51802+ (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
51803+ (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \
51804+ MV_32BIT_LE_FAST(bitMask)))); \
51805+ { \
51806+ reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
51807+ reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\
51808+ reg_arry_index++;\
51809+ }
51810+#else
51811+#define MV_REG_BIT_SET(offset, bitMask) \
51812+ (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
51813+ (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \
51814+ MV_32BIT_LE_FAST(bitMask))))
51815+#endif
51816+
51817+#if defined(REG_DEBUG)
51818+#define MV_REG_BIT_RESET(offset,bitMask) \
51819+ (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
51820+ (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \
51821+ MV_32BIT_LE_FAST(~bitMask)))); \
51822+ { \
51823+ reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
51824+ reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\
51825+ reg_arry_index++;\
51826+ }
51827+#else
51828+#define MV_REG_BIT_RESET(offset,bitMask) \
51829+ (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
51830+ (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \
51831+ MV_32BIT_LE_FAST(~bitMask))))
51832+#endif
51833+
51834+
51835+
51836+/* ARM architecture APIs */
51837+MV_U32 mvOsCpuRevGet (MV_VOID);
51838+MV_U32 mvOsCpuPartGet (MV_VOID);
51839+MV_U32 mvOsCpuArchGet (MV_VOID);
51840+MV_U32 mvOsCpuVarGet (MV_VOID);
51841+MV_U32 mvOsCpuAsciiGet (MV_VOID);
51842+
51843+/* Other APIs */
51844+void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle);
51845+void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle );
51846+void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );
51847+void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );
51848+int mvOsRand(void);
51849+
51850+#endif /* _MV_OS_LNX_H_ */
51851+
51852+
51853diff --git a/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h b/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h
51854new file mode 100644
51855index 0000000..170481a
51856--- /dev/null
51857+++ b/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h
51858@@ -0,0 +1,158 @@
51859+/*******************************************************************************
51860+Copyright (C) Marvell International Ltd. and its affiliates
51861+
51862+This software file (the "File") is owned and distributed by Marvell
51863+International Ltd. and/or its affiliates ("Marvell") under the following
51864+alternative licensing terms. Once you have made an election to distribute the
51865+File under one of the following license alternatives, please (i) delete this
51866+introductory statement regarding license alternatives, (ii) delete the two
51867+license alternatives that you have not elected to use and (iii) preserve the
51868+Marvell copyright notice above.
51869+
51870+
51871+********************************************************************************
51872+Marvell GPL License Option
51873+
51874+If you received this File from Marvell, you may opt to use, redistribute and/or
51875+modify this File in accordance with the terms and conditions of the General
51876+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
51877+available along with the File in the license.txt file or by writing to the Free
51878+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
51879+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
51880+
51881+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
51882+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
51883+DISCLAIMED. The GPL License provides additional details about this warranty
51884+disclaimer.
51885+*******************************************************************************/
51886+/*******************************************************************************
51887+* mvOsLinux.h - O.S. interface header file for Linux
51888+*
51889+* DESCRIPTION:
51890+* This header file contains OS dependent definition under Linux
51891+*
51892+* DEPENDENCIES:
51893+* Linux kernel header files.
51894+*
51895+* FILE REVISION NUMBER:
51896+* $Revision: 1.1 $
51897+*******************************************************************************/
51898+
51899+#ifndef __INCmvOsLinuxh
51900+#define __INCmvOsLinuxh
51901+
51902+/* Includes */
51903+#include <linux/autoconf.h>
51904+#include <linux/module.h>
51905+#include <linux/types.h>
51906+#include <linux/string.h>
51907+#include <linux/kernel.h>
51908+#include <linux/timer.h>
51909+#include <linux/mm.h>
51910+#include <linux/interrupt.h>
51911+#include <linux/major.h>
51912+#include <linux/errno.h>
51913+#include <linux/genhd.h>
51914+#include <linux/slab.h>
51915+#include <linux/delay.h>
51916+#include <linux/ide.h>
51917+#include <linux/pci.h>
51918+
51919+#include <asm/byteorder.h>
51920+#include <asm/irq.h>
51921+#include <asm/uaccess.h>
51922+#include <asm/io.h>
51923+#include "mvOs.h"
51924+
51925+
51926+/* Definitions */
51927+#define MV_DEFAULT_QUEUE_DEPTH 2
51928+#define MV_SATA_SUPPORT_EDMA_SINGLE_DATA_REGION
51929+#define MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN
51930+
51931+#ifdef CONFIG_MV88F6082
51932+ #define MV_SATA_OVERRIDE_SW_QUEUE_SIZE
51933+ #define MV_SATA_REQUESTED_SW_QUEUE_SIZE 2
51934+ #undef MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN
51935+#endif
51936+
51937+/* System dependent macro for flushing CPU write cache */
51938+#if defined (MV_BRIDGE_SYNC_REORDER)
51939+#define MV_CPU_WRITE_BUFFER_FLUSH() do { \
51940+ wmb(); \
51941+ mvOsBridgeReorderWA(); \
51942+ } while (0)
51943+#else
51944+#define MV_CPU_WRITE_BUFFER_FLUSH() wmb()
51945+#endif /* CONFIG_MV78XX0 */
51946+
51947+/* System dependent little endian from / to CPU conversions */
51948+#define MV_CPU_TO_LE16(x) cpu_to_le16(x)
51949+#define MV_CPU_TO_LE32(x) cpu_to_le32(x)
51950+
51951+#define MV_LE16_TO_CPU(x) le16_to_cpu(x)
51952+#define MV_LE32_TO_CPU(x) le32_to_cpu(x)
51953+
51954+#ifdef __BIG_ENDIAN_BITFIELD
51955+#define MV_BIG_ENDIAN_BITFIELD
51956+#endif
51957+
51958+/* System dependent register read / write in byte/word/dword variants */
51959+#define MV_REG_WRITE_BYTE(base, offset, val) writeb(val, base + offset)
51960+#define MV_REG_WRITE_WORD(base, offset, val) writew(val, base + offset)
51961+#define MV_REG_WRITE_DWORD(base, offset, val) writel(val, base + offset)
51962+#define MV_REG_READ_BYTE(base, offset) readb(base + offset)
51963+#define MV_REG_READ_WORD(base, offset) readw(base + offset)
51964+#define MV_REG_READ_DWORD(base, offset) readl(base + offset)
51965+
51966+
51967+/* Typedefs */
51968+
51969+/* System dependant typedefs */
51970+typedef void *MV_VOID_PTR;
51971+typedef u32 *MV_U32_PTR;
51972+typedef u16 *MV_U16_PTR;
51973+typedef u8 *MV_U8_PTR;
51974+typedef char *MV_CHAR_PTR;
51975+typedef void *MV_BUS_ADDR_T;
51976+typedef unsigned long MV_CPU_FLAGS;
51977+
51978+
51979+/* Structures */
51980+/* System dependent structure */
51981+typedef struct mvOsSemaphore
51982+{
51983+ int notUsed;
51984+} MV_OS_SEMAPHORE;
51985+
51986+
51987+/* Functions (User implemented)*/
51988+
51989+/* Semaphore init, take and release */
51990+#define mvOsSemInit(x) MV_TRUE
51991+#define mvOsSemTake(x)
51992+#define mvOsSemRelease(x)
51993+
51994+/* Interrupt masking and unmasking functions */
51995+MV_CPU_FLAGS mvOsSaveFlagsAndMaskCPUInterrupts(MV_VOID);
51996+MV_VOID mvOsRestoreFlags(MV_CPU_FLAGS);
51997+
51998+/* Delay function in micro seconds resolution */
51999+void mvMicroSecondsDelay(MV_VOID_PTR, MV_U32);
52000+
52001+/* Typedefs */
52002+typedef enum mvBoolean
52003+{
52004+ MV_SFALSE, MV_STRUE
52005+} MV_BOOLEAN;
52006+
52007+/* System logging function */
52008+#include "mvLog.h"
52009+/* Enable READ/WRITE Long SCSI command only when driver is compiled for debugging */
52010+#ifdef MV_LOGGER
52011+#define MV_SATA_SUPPORT_READ_WRITE_LONG
52012+#endif
52013+
52014+#define MV_IAL_LOG_ID 3
52015+
52016+#endif /* __INCmvOsLinuxh */
52017diff --git a/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h b/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h
52018new file mode 100644
52019index 0000000..8352290
52020--- /dev/null
52021+++ b/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h
52022@@ -0,0 +1,375 @@
52023+/*******************************************************************************
52024+Copyright (C) Marvell International Ltd. and its affiliates
52025+
52026+********************************************************************************
52027+Marvell GPL License Option
52028+
52029+If you received this File from Marvell, you may opt to use, redistribute and/or
52030+modify this File in accordance with the terms and conditions of the General
52031+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
52032+available along with the File in the license.txt file or by writing to the Free
52033+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
52034+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
52035+
52036+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
52037+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
52038+DISCLAIMED. The GPL License provides additional details about this warranty
52039+disclaimer.
52040+
52041+*******************************************************************************/
52042+/*******************************************************************************
52043+* mvSysHwCfg.h - Marvell system HW configuration file
52044+*
52045+* DESCRIPTION:
52046+* None.
52047+*
52048+* DEPENDENCIES:
52049+* None.
52050+*
52051+*******************************************************************************/
52052+
52053+#ifndef __INCmvSysHwConfigh
52054+#define __INCmvSysHwConfigh
52055+
52056+#include "../../../../include/linux/autoconf.h"
52057+
52058+#define CONFIG_MARVELL 1
52059+
52060+/* includes */
52061+#define _1K 0x00000400
52062+#define _4K 0x00001000
52063+#define _8K 0x00002000
52064+#define _16K 0x00004000
52065+#define _32K 0x00008000
52066+#define _64K 0x00010000
52067+#define _128K 0x00020000
52068+#define _256K 0x00040000
52069+#define _512K 0x00080000
52070+
52071+#define _1M 0x00100000
52072+#define _2M 0x00200000
52073+#define _4M 0x00400000
52074+#define _8M 0x00800000
52075+#define _16M 0x01000000
52076+#define _32M 0x02000000
52077+#define _64M 0x04000000
52078+#define _128M 0x08000000
52079+#define _256M 0x10000000
52080+#define _512M 0x20000000
52081+
52082+#define _1G 0x40000000
52083+#define _2G 0x80000000
52084+
52085+/****************************************/
52086+/* Soc supporeted Units definitions */
52087+/****************************************/
52088+
52089+#ifdef CONFIG_MV_INCLUDE_PEX
52090+#define MV_INCLUDE_PEX
52091+#endif
52092+#ifdef CONFIG_MV_INCLUDE_TWSI
52093+#define MV_INCLUDE_TWSI
52094+#endif
52095+#ifdef CONFIG_MV_INCLUDE_CESA
52096+#define MV_INCLUDE_CESA
52097+#endif
52098+#ifdef CONFIG_MV_INCLUDE_GIG_ETH
52099+#define MV_INCLUDE_GIG_ETH
52100+#endif
52101+#ifdef CONFIG_MV_INCLUDE_INTEG_SATA
52102+#define MV_INCLUDE_INTEG_SATA
52103+#define MV_INCLUDE_SATA
52104+#endif
52105+#ifdef CONFIG_MV_INCLUDE_USB
52106+#define MV_INCLUDE_USB
52107+#define MV_USB_VOLTAGE_FIX
52108+#endif
52109+#ifdef CONFIG_MV_INCLUDE_NAND
52110+#define MV_INCLUDE_NAND
52111+#endif
52112+#ifdef CONFIG_MV_INCLUDE_TDM
52113+#define MV_INCLUDE_TDM
52114+#endif
52115+#ifdef CONFIG_MV_INCLUDE_XOR
52116+#define MV_INCLUDE_XOR
52117+#endif
52118+#ifdef CONFIG_MV_INCLUDE_TWSI
52119+#define MV_INCLUDE_TWSI
52120+#endif
52121+#ifdef CONFIG_MV_INCLUDE_UART
52122+#define MV_INCLUDE_UART
52123+#endif
52124+#ifdef CONFIG_MV_INCLUDE_SPI
52125+#define MV_INCLUDE_SPI
52126+#endif
52127+#ifdef CONFIG_MV_INCLUDE_SFLASH_MTD
52128+#define MV_INCLUDE_SFLASH_MTD
52129+#endif
52130+#ifdef CONFIG_MV_INCLUDE_AUDIO
52131+#define MV_INCLUDE_AUDIO
52132+#endif
52133+#ifdef CONFIG_MV_INCLUDE_TS
52134+#define MV_INCLUDE_TS
52135+#endif
52136+#ifdef CONFIG_MV_INCLUDE_SDIO
52137+#define MV_INCLUDE_SDIO
52138+#endif
52139+
52140+
52141+/* NAND flash stuff */
52142+#ifdef CONFIG_MV_NAND_BOOT
52143+#define MV_NAND_BOOT
52144+#endif
52145+#ifdef CONFIG_MV_NAND
52146+#define MV_NAND
52147+#endif
52148+
52149+/* SPI flash stuff */
52150+#ifdef CONFIG_MV_SPI_BOOT
52151+#define MV_SPI_BOOT
52152+#endif
52153+
52154+
52155+/****************************************************************/
52156+/************* General configuration ********************/
52157+/****************************************************************/
52158+
52159+/* Enable Clock Power Control */
52160+#define MV_INCLUDE_CLK_PWR_CNTRL
52161+
52162+/* Disable the DEVICE BAR in the PEX */
52163+#define MV_DISABLE_PEX_DEVICE_BAR
52164+
52165+/* Allow the usage of early printings during initialization */
52166+#define MV_INCLUDE_EARLY_PRINTK
52167+
52168+/****************************************************************/
52169+/************* NFP configuration ********************************/
52170+/****************************************************************/
52171+#define MV_NFP_SEC_Q_SIZE 64
52172+#define MV_NFP_SEC_REQ_Q_SIZE 1000
52173+
52174+
52175+
52176+/****************************************************************/
52177+/************* CESA configuration ********************/
52178+/****************************************************************/
52179+
52180+#ifdef MV_INCLUDE_CESA
52181+
52182+#define MV_CESA_MAX_CHAN 4
52183+
52184+/* Use 2K of SRAM */
52185+#define MV_CESA_MAX_BUF_SIZE 1600
52186+
52187+#endif /* MV_INCLUDE_CESA */
52188+
52189+#if defined(CONFIG_MV_INCLUDE_GIG_ETH)
52190+
52191+#ifdef CONFIG_MV_NFP_STATS
52192+#define MV_FP_STATISTICS
52193+#else
52194+#undef MV_FP_STATISTICS
52195+#endif
52196+/* Default configuration for SKB_REUSE: 0 - Disabled, 1 - Enabled */
52197+#define MV_ETH_SKB_REUSE_DEFAULT 1
52198+/* Default configuration for TX_EN workaround: 0 - Disabled, 1 - Enabled */
52199+#define MV_ETH_TX_EN_DEFAULT 0
52200+
52201+/* un-comment if you want to perform tx_done from within the poll function */
52202+/* #define ETH_TX_DONE_ISR */
52203+
52204+/* put descriptors in uncached memory */
52205+/* #define ETH_DESCR_UNCACHED */
52206+
52207+/* Descriptors location: DRAM/internal-SRAM */
52208+#define ETH_DESCR_IN_SDRAM
52209+#undef ETH_DESCR_IN_SRAM /* No integrated SRAM in 88Fxx81 devices */
52210+
52211+#if defined(ETH_DESCR_IN_SRAM)
52212+#if defined(ETH_DESCR_UNCACHED)
52213+ #define ETH_DESCR_CONFIG_STR "Uncached descriptors in integrated SRAM"
52214+#else
52215+ #define ETH_DESCR_CONFIG_STR "Cached descriptors in integrated SRAM"
52216+#endif
52217+#elif defined(ETH_DESCR_IN_SDRAM)
52218+#if defined(ETH_DESCR_UNCACHED)
52219+ #define ETH_DESCR_CONFIG_STR "Uncached descriptors in DRAM"
52220+#else
52221+ #define ETH_DESCR_CONFIG_STR "Cached descriptors in DRAM"
52222+#endif
52223+#else
52224+ #error "Ethernet descriptors location undefined"
52225+#endif /* ETH_DESCR_IN_SRAM or ETH_DESCR_IN_SDRAM*/
52226+
52227+/* SW Sync-Barrier: not relevant for 88fxx81*/
52228+/* Reasnable to define this macro when descriptors in SRAM and buffers in DRAM */
52229+/* In RX the CPU theoretically might see himself as the descriptor owner, */
52230+/* although the buffer hadn't been written to DRAM yet. Performance cost. */
52231+/* #define INCLUDE_SYNC_BARR */
52232+
52233+/* Buffers cache coherency method (buffers in DRAM) */
52234+#ifndef MV_CACHE_COHER_SW
52235+/* Taken from mvCommon.h */
52236+/* Memory uncached, HW or SW cache coherency is not needed */
52237+#define MV_UNCACHED 0
52238+/* Memory cached, HW cache coherency supported in WriteThrough mode */
52239+#define MV_CACHE_COHER_HW_WT 1
52240+/* Memory cached, HW cache coherency supported in WriteBack mode */
52241+#define MV_CACHE_COHER_HW_WB 2
52242+/* Memory cached, No HW cache coherency, Cache coherency must be in SW */
52243+#define MV_CACHE_COHER_SW 3
52244+
52245+#endif
52246+
52247+/* DRAM cache coherency configuration */
52248+#define MV_CACHE_COHERENCY MV_CACHE_COHER_SW
52249+
52250+
52251+#define ETHER_DRAM_COHER MV_CACHE_COHER_SW /* No HW coherency in 88Fxx81 devices */
52252+
52253+#if (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB)
52254+ #define ETH_SDRAM_CONFIG_STR "DRAM HW cache coherency (write-back)"
52255+#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT)
52256+ #define ETH_SDRAM_CONFIG_STR "DRAM HW cache coherency (write-through)"
52257+#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_SW)
52258+ #define ETH_SDRAM_CONFIG_STR "DRAM SW cache-coherency"
52259+#elif (ETHER_DRAM_COHER == MV_UNCACHED)
52260+# define ETH_SDRAM_CONFIG_STR "DRAM uncached"
52261+#else
52262+ #error "Ethernet-DRAM undefined"
52263+#endif /* ETHER_DRAM_COHER */
52264+
52265+
52266+/****************************************************************/
52267+/************* Ethernet driver configuration ********************/
52268+/****************************************************************/
52269+
52270+/* port's default queueus */
52271+#define ETH_DEF_TXQ 0
52272+#define ETH_DEF_RXQ 0
52273+
52274+#define MV_ETH_RX_Q_NUM CONFIG_MV_ETH_RX_Q_NUM
52275+#define MV_ETH_TX_Q_NUM CONFIG_MV_ETH_TX_Q_NUM
52276+
52277+/* interrupt coalescing setting */
52278+#define ETH_TX_COAL 200
52279+#define ETH_RX_COAL 200
52280+
52281+/* Checksum offloading */
52282+#define TX_CSUM_OFFLOAD
52283+#define RX_CSUM_OFFLOAD
52284+
52285+#endif /* CONFIG_MV_INCLUDE_GIG_ETH */
52286+
52287+/****************************************************************/
52288+/*************** Telephony configuration ************************/
52289+/****************************************************************/
52290+#if defined(CONFIG_MV_TDM_LINEAR_MODE)
52291+ #define MV_TDM_LINEAR_MODE
52292+#elif defined(CONFIG_MV_TDM_ULAW_MODE)
52293+ #define MV_TDM_ULAW_MODE
52294+#endif
52295+
52296+#if defined(CONFIG_MV_TDM_5CHANNELS)
52297+ #define MV_TDM_5CHANNELS
52298+#endif
52299+
52300+#if defined(CONFIG_MV_TDM_USE_EXTERNAL_PCLK_SOURCE)
52301+ #define MV_TDM_USE_EXTERNAL_PCLK_SOURCE
52302+#endif
52303+
52304+/* We use the following registers to store DRAM interface pre configuration */
52305+/* auto-detection results */
52306+/* IMPORTANT: We are using mask register for that purpose. Before writing */
52307+/* to units mask register, make sure main maks register is set to disable */
52308+/* all interrupts. */
52309+#define DRAM_BUF_REG0 0x30810 /* sdram bank 0 size */
52310+#define DRAM_BUF_REG1 0x30820 /* sdram config */
52311+#define DRAM_BUF_REG2 0x30830 /* sdram mode */
52312+#define DRAM_BUF_REG3 0x308c4 /* dunit control low */
52313+#define DRAM_BUF_REG4 0x60a90 /* sdram address control */
52314+#define DRAM_BUF_REG5 0x60a94 /* sdram timing control low */
52315+#define DRAM_BUF_REG6 0x60a98 /* sdram timing control high */
52316+#define DRAM_BUF_REG7 0x60a9c /* sdram ODT control low */
52317+#define DRAM_BUF_REG8 0x60b90 /* sdram ODT control high */
52318+#define DRAM_BUF_REG9 0x60b94 /* sdram Dunit ODT control */
52319+#define DRAM_BUF_REG10 0x60b98 /* sdram Extended Mode */
52320+#define DRAM_BUF_REG11 0x60b9c /* sdram Ddr2 Time Low Reg */
52321+#define DRAM_BUF_REG12 0x60a00 /* sdram Ddr2 Time High Reg */
52322+#define DRAM_BUF_REG13 0x60a04 /* dunit Ctrl High */
52323+#define DRAM_BUF_REG14 0x60b00 /* sdram second DIMM exist */
52324+
52325+/* Following the pre-configuration registers default values restored after */
52326+/* auto-detection is done */
52327+#define DRAM_BUF_REG_DV 0
52328+
52329+/* System Mapping */
52330+#define SDRAM_CS0_BASE 0x00000000
52331+#define SDRAM_CS0_SIZE _256M
52332+
52333+#define SDRAM_CS1_BASE 0x10000000
52334+#define SDRAM_CS1_SIZE _256M
52335+
52336+#define SDRAM_CS2_BASE 0x20000000
52337+#define SDRAM_CS2_SIZE _256M
52338+
52339+#define SDRAM_CS3_BASE 0x30000000
52340+#define SDRAM_CS3_SIZE _256M
52341+
52342+/* PEX */
52343+#define PEX0_MEM_BASE 0xe8000000
52344+#define PEX0_MEM_SIZE _128M
52345+
52346+#define PEX0_IO_BASE 0xf2000000
52347+#define PEX0_IO_SIZE _1M
52348+
52349+/* Device Chip Selects */
52350+#define NFLASH_CS_BASE 0xfa000000
52351+#define NFLASH_CS_SIZE _2M
52352+
52353+#define SPI_CS_BASE 0xf4000000
52354+#define SPI_CS_SIZE _16M
52355+
52356+#define CRYPT_ENG_BASE 0xf0000000
52357+#define CRYPT_ENG_SIZE _2M
52358+
52359+#define BOOTDEV_CS_BASE 0xff800000
52360+#define BOOTDEV_CS_SIZE _8M
52361+
52362+/* CS2 - BOOTROM */
52363+#define DEVICE_CS2_BASE 0xff900000
52364+#define DEVICE_CS2_SIZE _1M
52365+
52366+/* PEX Work arround */
52367+/* the target we will use for the workarround */
52368+#define PEX_CONFIG_RW_WA_TARGET PEX0_MEM
52369+/*a flag that indicates if we are going to use the
52370+size and base of the target we using for the workarround
52371+window */
52372+#define PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES 1
52373+/* if the above flag is 0 then the following values
52374+will be used for the workarround window base and size,
52375+otherwise the following defines will be ignored */
52376+#define PEX_CONFIG_RW_WA_BASE 0xF3000000
52377+#define PEX_CONFIG_RW_WA_SIZE _16M
52378+
52379+/* Internal registers: size is defined in Controllerenvironment */
52380+#define INTER_REGS_BASE 0xFEE00000
52381+
52382+/* DRAM detection stuff */
52383+#define MV_DRAM_AUTO_SIZE
52384+
52385+/* Board clock detection */
52386+#define TCLK_AUTO_DETECT /* Use Tclk auto detection */
52387+#define SYSCLK_AUTO_DETECT /* Use SysClk auto detection */
52388+#define PCLCK_AUTO_DETECT /* Use PClk auto detection */
52389+#define L2CLK_AUTO_DETECT /* Use L2Clk auto detection */
52390+
52391+/* PEX-PCI\PCI-PCI Bridge*/
52392+#define PCI0_IF_PTP 0 /* Bridge exist on pciIf0*/
52393+
52394+
52395+
52396+#endif /* __INCmvSysHwConfigh */
52397+
52398diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c b/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c
52399new file mode 100644
52400index 0000000..6be5ea8
52401--- /dev/null
52402+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c
52403@@ -0,0 +1,376 @@
52404+/*******************************************************************************
52405+Copyright (C) Marvell International Ltd. and its affiliates
52406+
52407+This software file (the "File") is owned and distributed by Marvell
52408+International Ltd. and/or its affiliates ("Marvell") under the following
52409+alternative licensing terms. Once you have made an election to distribute the
52410+File under one of the following license alternatives, please (i) delete this
52411+introductory statement regarding license alternatives, (ii) delete the two
52412+license alternatives that you have not elected to use and (iii) preserve the
52413+Marvell copyright notice above.
52414+
52415+********************************************************************************
52416+Marvell Commercial License Option
52417+
52418+If you received this File from Marvell and you have entered into a commercial
52419+license agreement (a "Commercial License") with Marvell, the File is licensed
52420+to you under the terms of the applicable Commercial License.
52421+
52422+********************************************************************************
52423+Marvell GPL License Option
52424+
52425+If you received this File from Marvell, you may opt to use, redistribute and/or
52426+modify this File in accordance with the terms and conditions of the General
52427+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
52428+available along with the File in the license.txt file or by writing to the Free
52429+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
52430+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
52431+
52432+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
52433+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
52434+DISCLAIMED. The GPL License provides additional details about this warranty
52435+disclaimer.
52436+********************************************************************************
52437+Marvell BSD License Option
52438+
52439+If you received this File from Marvell, you may opt to use, redistribute and/or
52440+modify this File under the following licensing terms.
52441+Redistribution and use in source and binary forms, with or without modification,
52442+are permitted provided that the following conditions are met:
52443+
52444+ * Redistributions of source code must retain the above copyright notice,
52445+ this list of conditions and the following disclaimer.
52446+
52447+ * Redistributions in binary form must reproduce the above copyright
52448+ notice, this list of conditions and the following disclaimer in the
52449+ documentation and/or other materials provided with the distribution.
52450+
52451+ * Neither the name of Marvell nor the names of its contributors may be
52452+ used to endorse or promote products derived from this software without
52453+ specific prior written permission.
52454+
52455+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
52456+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52457+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52458+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
52459+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52460+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52461+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
52462+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52463+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52464+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52465+
52466+*******************************************************************************/
52467+
52468+#include "mvCntmr.h"
52469+#include "cpu/mvCpu.h"
52470+
52471+/* defines */
52472+#ifdef MV_DEBUG
52473+ #define DB(x) x
52474+#else
52475+ #define DB(x)
52476+#endif
52477+
52478+extern unsigned int whoAmI(void);
52479+
52480+/*******************************************************************************
52481+* mvCntmrLoad -
52482+*
52483+* DESCRIPTION:
52484+* Load an init Value to a given counter/timer
52485+*
52486+* INPUT:
52487+* countNum - counter number
52488+* value - value to be loaded
52489+*
52490+* OUTPUT:
52491+* None.
52492+*
52493+* RETURN:
52494+* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
52495+*******************************************************************************/
52496+MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value)
52497+{
52498+ if (countNum >= MV_CNTMR_MAX_COUNTER )
52499+ {
52500+
52501+ mvOsPrintf(("mvCntmrLoad: Err. Illigal counter number \n"));
52502+ return MV_BAD_PARAM;;
52503+
52504+ }
52505+
52506+ MV_REG_WRITE(CNTMR_RELOAD_REG(countNum),value);
52507+ MV_REG_WRITE(CNTMR_VAL_REG(countNum),value);
52508+
52509+ return MV_OK;
52510+}
52511+
52512+/*******************************************************************************
52513+* mvCntmrRead -
52514+*
52515+* DESCRIPTION:
52516+* Returns the value of the given Counter/Timer
52517+*
52518+* INPUT:
52519+* countNum - counter number
52520+*
52521+* OUTPUT:
52522+* None.
52523+*
52524+* RETURN:
52525+* MV_U32 counter value
52526+*******************************************************************************/
52527+MV_U32 mvCntmrRead(MV_U32 countNum)
52528+{
52529+ return MV_REG_READ(CNTMR_VAL_REG(countNum));
52530+}
52531+
52532+/*******************************************************************************
52533+* mvCntmrWrite -
52534+*
52535+* DESCRIPTION:
52536+* Returns the value of the given Counter/Timer
52537+*
52538+* INPUT:
52539+* countNum - counter number
52540+* countVal - value to write
52541+*
52542+* OUTPUT:
52543+* None.
52544+*
52545+* RETURN:
52546+* None
52547+*******************************************************************************/
52548+void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal)
52549+{
52550+ MV_REG_WRITE(CNTMR_VAL_REG(countNum),countVal);
52551+}
52552+
52553+/*******************************************************************************
52554+* mvCntmrCtrlSet -
52555+*
52556+* DESCRIPTION:
52557+* Set the Control to a given counter/timer
52558+*
52559+* INPUT:
52560+* countNum - counter number
52561+* pCtrl - pointer to MV_CNTMR_CTRL structure
52562+*
52563+* OUTPUT:
52564+* None.
52565+*
52566+* RETURN:
52567+* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
52568+*******************************************************************************/
52569+MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)
52570+{
52571+ MV_U32 cntmrCtrl;
52572+
52573+ if (countNum >= MV_CNTMR_MAX_COUNTER )
52574+ {
52575+
52576+ DB(mvOsPrintf(("mvCntmrCtrlSet: Err. Illigal counter number \n")));
52577+ return MV_BAD_PARAM;;
52578+
52579+ }
52580+
52581+ /* read control register */
52582+ cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
52583+
52584+
52585+ if (pCtrl->enable) /* enable counter\timer */
52586+ {
52587+ cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);
52588+ }
52589+ else /* disable counter\timer */
52590+ {
52591+ cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);
52592+ }
52593+
52594+ if ( pCtrl->autoEnable ) /* Auto mode */
52595+ {
52596+ cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(countNum);
52597+
52598+ }
52599+ else /* no auto mode */
52600+ {
52601+ cntmrCtrl &= ~CTCR_ARM_TIMER_AUTO_EN(countNum);
52602+ }
52603+
52604+ MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
52605+
52606+ return MV_OK;
52607+
52608+}
52609+
52610+/*******************************************************************************
52611+* mvCntmrCtrlGet -
52612+*
52613+* DESCRIPTION:
52614+* Get the Control value of a given counter/timer
52615+*
52616+* INPUT:
52617+* countNum - counter number
52618+* pCtrl - pointer to MV_CNTMR_CTRL structure
52619+*
52620+* OUTPUT:
52621+* Counter\Timer control value
52622+*
52623+* RETURN:
52624+* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
52625+*******************************************************************************/
52626+MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)
52627+{
52628+ MV_U32 cntmrCtrl;
52629+
52630+ if (countNum >= MV_CNTMR_MAX_COUNTER )
52631+ {
52632+ DB(mvOsPrintf(("mvCntmrCtrlGet: Err. Illigal counter number \n")));
52633+ return MV_BAD_PARAM;;
52634+ }
52635+
52636+ /* read control register */
52637+ cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
52638+
52639+ /* enable counter\timer */
52640+ if (cntmrCtrl & CTCR_ARM_TIMER_EN(countNum))
52641+ {
52642+ pCtrl->enable = MV_TRUE;
52643+ }
52644+ else
52645+ {
52646+ pCtrl->enable = MV_FALSE;
52647+ }
52648+
52649+ /* counter mode */
52650+ if (cntmrCtrl & CTCR_ARM_TIMER_AUTO_EN(countNum))
52651+ {
52652+ pCtrl->autoEnable = MV_TRUE;
52653+ }
52654+ else
52655+ {
52656+ pCtrl->autoEnable = MV_FALSE;
52657+ }
52658+
52659+ return MV_OK;
52660+}
52661+
52662+/*******************************************************************************
52663+* mvCntmrEnable -
52664+*
52665+* DESCRIPTION:
52666+* Set the Enable-Bit to logic '1' ==> starting the counter
52667+*
52668+* INPUT:
52669+* countNum - counter number
52670+*
52671+* OUTPUT:
52672+* None.
52673+*
52674+* RETURN:
52675+* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
52676+*******************************************************************************/
52677+MV_STATUS mvCntmrEnable(MV_U32 countNum)
52678+{
52679+ MV_U32 cntmrCtrl;
52680+
52681+ if (countNum >= MV_CNTMR_MAX_COUNTER )
52682+ {
52683+
52684+ DB(mvOsPrintf(("mvCntmrEnable: Err. Illigal counter number \n")));
52685+ return MV_BAD_PARAM;;
52686+
52687+ }
52688+
52689+ /* read control register */
52690+ cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
52691+
52692+ /* enable counter\timer */
52693+ cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);
52694+
52695+
52696+ MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
52697+
52698+ return MV_OK;
52699+}
52700+
52701+/*******************************************************************************
52702+* mvCntmrDisable -
52703+*
52704+* DESCRIPTION:
52705+* Stop the counter/timer running, and returns its Value
52706+*
52707+* INPUT:
52708+* countNum - counter number
52709+*
52710+* OUTPUT:
52711+* None.
52712+*
52713+* RETURN:
52714+* MV_U32 counter\timer value
52715+*******************************************************************************/
52716+MV_STATUS mvCntmrDisable(MV_U32 countNum)
52717+{
52718+ MV_U32 cntmrCtrl;
52719+
52720+ if (countNum >= MV_CNTMR_MAX_COUNTER )
52721+ {
52722+
52723+ DB(mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n")));
52724+ return MV_BAD_PARAM;;
52725+
52726+ }
52727+
52728+ /* read control register */
52729+ cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
52730+
52731+ /* disable counter\timer */
52732+ cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);
52733+
52734+ MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
52735+
52736+ return MV_OK;
52737+}
52738+
52739+/*******************************************************************************
52740+* mvCntmrStart -
52741+*
52742+* DESCRIPTION:
52743+* Combined all the sub-operations above to one function: Load,setMode,Enable
52744+*
52745+* INPUT:
52746+* countNum - counter number
52747+* value - value of the counter\timer to be set
52748+* pCtrl - pointer to MV_CNTMR_CTRL structure
52749+*
52750+* OUTPUT:
52751+* None.
52752+*
52753+* RETURN:
52754+* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
52755+*******************************************************************************/
52756+MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,
52757+ MV_CNTMR_CTRL *pCtrl)
52758+{
52759+
52760+ if (countNum >= MV_CNTMR_MAX_COUNTER )
52761+ {
52762+
52763+ mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n"));
52764+ return MV_BAD_PARAM;;
52765+
52766+ }
52767+
52768+ /* load value onto counter\timer */
52769+ mvCntmrLoad(countNum,value);
52770+
52771+ /* set the counter to load in the first time */
52772+ mvCntmrWrite(countNum,value);
52773+
52774+ /* set control for timer \ cunter and enable */
52775+ mvCntmrCtrlSet(countNum,pCtrl);
52776+
52777+ return MV_OK;
52778+}
52779+
52780diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h b/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h
52781new file mode 100644
52782index 0000000..b4b1a9d
52783--- /dev/null
52784+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h
52785@@ -0,0 +1,121 @@
52786+/*******************************************************************************
52787+Copyright (C) Marvell International Ltd. and its affiliates
52788+
52789+This software file (the "File") is owned and distributed by Marvell
52790+International Ltd. and/or its affiliates ("Marvell") under the following
52791+alternative licensing terms. Once you have made an election to distribute the
52792+File under one of the following license alternatives, please (i) delete this
52793+introductory statement regarding license alternatives, (ii) delete the two
52794+license alternatives that you have not elected to use and (iii) preserve the
52795+Marvell copyright notice above.
52796+
52797+********************************************************************************
52798+Marvell Commercial License Option
52799+
52800+If you received this File from Marvell and you have entered into a commercial
52801+license agreement (a "Commercial License") with Marvell, the File is licensed
52802+to you under the terms of the applicable Commercial License.
52803+
52804+********************************************************************************
52805+Marvell GPL License Option
52806+
52807+If you received this File from Marvell, you may opt to use, redistribute and/or
52808+modify this File in accordance with the terms and conditions of the General
52809+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
52810+available along with the File in the license.txt file or by writing to the Free
52811+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
52812+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
52813+
52814+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
52815+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
52816+DISCLAIMED. The GPL License provides additional details about this warranty
52817+disclaimer.
52818+********************************************************************************
52819+Marvell BSD License Option
52820+
52821+If you received this File from Marvell, you may opt to use, redistribute and/or
52822+modify this File under the following licensing terms.
52823+Redistribution and use in source and binary forms, with or without modification,
52824+are permitted provided that the following conditions are met:
52825+
52826+ * Redistributions of source code must retain the above copyright notice,
52827+ this list of conditions and the following disclaimer.
52828+
52829+ * Redistributions in binary form must reproduce the above copyright
52830+ notice, this list of conditions and the following disclaimer in the
52831+ documentation and/or other materials provided with the distribution.
52832+
52833+ * Neither the name of Marvell nor the names of its contributors may be
52834+ used to endorse or promote products derived from this software without
52835+ specific prior written permission.
52836+
52837+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
52838+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52839+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52840+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
52841+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52842+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52843+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
52844+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52845+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52846+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52847+
52848+*******************************************************************************/
52849+
52850+#ifndef __INCmvTmrWtdgh
52851+#define __INCmvTmrWtdgh
52852+
52853+/* includes */
52854+#include "mvCommon.h"
52855+#include "mvOs.h"
52856+#include "cntmr/mvCntmrRegs.h"
52857+#include "ctrlEnv/mvCtrlEnvSpec.h"
52858+
52859+
52860+/* This enumerator describe counters\watchdog numbers */
52861+typedef enum _mvCntmrID
52862+{
52863+ TIMER0 = 0,
52864+ TIMER1,
52865+ WATCHDOG,
52866+ TIMER2,
52867+ TIMER3,
52868+}MV_CNTMR_ID;
52869+
52870+
52871+/* Counter / Timer control structure */
52872+typedef struct _mvCntmrCtrl
52873+{
52874+ MV_BOOL enable; /* enable */
52875+ MV_BOOL autoEnable; /* counter/Timer */
52876+}MV_CNTMR_CTRL;
52877+
52878+
52879+/* Functions */
52880+
52881+/* Load an init Value to a given counter/timer */
52882+MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value);
52883+
52884+/* Returns the value of the given Counter/Timer */
52885+MV_U32 mvCntmrRead(MV_U32 countNum);
52886+
52887+/* Write a value of the given Counter/Timer */
52888+void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal);
52889+
52890+/* Set the Control to a given counter/timer */
52891+MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);
52892+
52893+/* Get the value of a given counter/timer */
52894+MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);
52895+
52896+/* Set the Enable-Bit to logic '1' ==> starting the counter. */
52897+MV_STATUS mvCntmrEnable(MV_U32 countNum);
52898+
52899+/* Stop the counter/timer running, and returns its Value. */
52900+MV_STATUS mvCntmrDisable(MV_U32 countNum);
52901+
52902+/* Combined all the sub-operations above to one function: Load,setMode,Enable */
52903+MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,
52904+ MV_CNTMR_CTRL *pCtrl);
52905+
52906+#endif /* __INCmvTmrWtdgh */
52907diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h b/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h
52908new file mode 100644
52909index 0000000..1cd9041
52910--- /dev/null
52911+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h
52912@@ -0,0 +1,121 @@
52913+/*******************************************************************************
52914+Copyright (C) Marvell International Ltd. and its affiliates
52915+
52916+This software file (the "File") is owned and distributed by Marvell
52917+International Ltd. and/or its affiliates ("Marvell") under the following
52918+alternative licensing terms. Once you have made an election to distribute the
52919+File under one of the following license alternatives, please (i) delete this
52920+introductory statement regarding license alternatives, (ii) delete the two
52921+license alternatives that you have not elected to use and (iii) preserve the
52922+Marvell copyright notice above.
52923+
52924+********************************************************************************
52925+Marvell Commercial License Option
52926+
52927+If you received this File from Marvell and you have entered into a commercial
52928+license agreement (a "Commercial License") with Marvell, the File is licensed
52929+to you under the terms of the applicable Commercial License.
52930+
52931+********************************************************************************
52932+Marvell GPL License Option
52933+
52934+If you received this File from Marvell, you may opt to use, redistribute and/or
52935+modify this File in accordance with the terms and conditions of the General
52936+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
52937+available along with the File in the license.txt file or by writing to the Free
52938+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
52939+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
52940+
52941+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
52942+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
52943+DISCLAIMED. The GPL License provides additional details about this warranty
52944+disclaimer.
52945+********************************************************************************
52946+Marvell BSD License Option
52947+
52948+If you received this File from Marvell, you may opt to use, redistribute and/or
52949+modify this File under the following licensing terms.
52950+Redistribution and use in source and binary forms, with or without modification,
52951+are permitted provided that the following conditions are met:
52952+
52953+ * Redistributions of source code must retain the above copyright notice,
52954+ this list of conditions and the following disclaimer.
52955+
52956+ * Redistributions in binary form must reproduce the above copyright
52957+ notice, this list of conditions and the following disclaimer in the
52958+ documentation and/or other materials provided with the distribution.
52959+
52960+ * Neither the name of Marvell nor the names of its contributors may be
52961+ used to endorse or promote products derived from this software without
52962+ specific prior written permission.
52963+
52964+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
52965+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52966+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52967+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
52968+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52969+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52970+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
52971+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52972+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52973+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52974+
52975+*******************************************************************************/
52976+
52977+#ifndef __INCmvTmrwtdgRegsh
52978+#define __INCmvTmrwtdgRegsh
52979+
52980+/*******************************************/
52981+/* ARM Timers Registers Map */
52982+/*******************************************/
52983+
52984+#define CNTMR_RELOAD_REG(tmrNum) (CNTMR_BASE + 0x10 + (tmrNum)*8 + \
52985+ (((tmrNum) <= 3)?0:8))
52986+#define CNTMR_VAL_REG(tmrNum) (CNTMR_BASE + 0x14 + (tmrNum)*8 + \
52987+ (((tmrNum) <= 3)?0:8))
52988+#define CNTMR_CTRL_REG (CNTMR_BASE)
52989+
52990+/*For MV78XX0*/
52991+#define CNTMR_CAUSE_REG (CPU_AHB_MBUS_CAUSE_INT_REG(whoAmI()))
52992+#define CNTMR_MASK_REG (CPU_AHB_MBUS_MASK_INT_REG(whoAmI()))
52993+
52994+/* ARM Timers Registers Map */
52995+/*******************************************/
52996+
52997+
52998+/* ARM Timers Control Register */
52999+/* CPU_TIMERS_CTRL_REG (CTCR) */
53000+
53001+#define TIMER0_NUM 0
53002+#define TIMER1_NUM 1
53003+#define WATCHDOG_NUM 2
53004+#define TIMER2_NUM 3
53005+#define TIMER3_NUM 4
53006+
53007+#define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2)
53008+#define CTCR_ARM_TIMER_EN_MASK(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS)
53009+#define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr))
53010+#define CTCR_ARM_TIMER_DIS(cntr) (0 << CTCR_ARM_TIMER_EN_OFFS(cntr))
53011+
53012+#define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1)
53013+#define CTCR_ARM_TIMER_AUTO_MASK(cntr) BIT1
53014+#define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
53015+#define CTCR_ARM_TIMER_AUTO_DIS(cntr) (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
53016+
53017+
53018+/* ARM Timer\Watchdog Reload Register */
53019+/* CNTMR_RELOAD_REG (TRR) */
53020+
53021+#define TRG_ARM_TIMER_REL_OFFS 0
53022+#define TRG_ARM_TIMER_REL_MASK 0xffffffff
53023+
53024+/* ARM Timer\Watchdog Register */
53025+/* CNTMR_VAL_REG (TVRG) */
53026+
53027+#define TVR_ARM_TIMER_OFFS 0
53028+#define TVR_ARM_TIMER_MASK 0xffffffff
53029+#define TVR_ARM_TIMER_MAX 0xffffffff
53030+
53031+
53032+
53033+#endif /* __INCmvTmrwtdgRegsh */
53034diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c b/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c
53035new file mode 100644
53036index 0000000..03d6d09
53037--- /dev/null
53038+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c
53039@@ -0,0 +1,207 @@
53040+/*
53041+ * This program is free software; you can redistribute it and/or modify
53042+ * it under the terms of the GNU General Public License as published by
53043+ * the Free Software Foundation; either version 2 of the License, or
53044+ * (at your option) any later version.
53045+ *
53046+ * This program is distributed in the hope that it will be useful,
53047+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
53048+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53049+ * GNU General Public License for more details.
53050+ *
53051+ * You should have received a copy of the GNU General Public License
53052+ * along with this program; if not, write to the Free Software
53053+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
53054+ */
53055+
53056+#include "mvOs.h"
53057+#include "mvCpuCntrs.h"
53058+
53059+
53060+const static MV_CPU_CNTRS_OPS mvCpuCntrsOpsTbl[MV_CPU_CNTRS_NUM][MV_CPU_CNTRS_OPS_NUM] =
53061+{
53062+ /*0*/
53063+ {
53064+ MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_DCACHE_READ_HIT, MV_CPU_CNTRS_DCACHE_READ_MISS,
53065+ MV_CPU_CNTRS_DCACHE_WRITE_HIT, MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_INSTRUCTIONS,
53066+ MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
53067+ MV_CPU_CNTRS_MMU_READ_LATENCY, MV_CPU_CNTRS_ICACHE_READ_LATENCY, MV_CPU_CNTRS_WB_WRITE_LATENCY,
53068+ MV_CPU_CNTRS_LDM_STM_HOLD, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
53069+ MV_CPU_CNTRS_DATA_WRITE_ACCESS, MV_CPU_CNTRS_DATA_READ_ACCESS, MV_CPU_CNTRS_INVALID,
53070+ MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,
53071+ },
53072+ /*1*/
53073+ {
53074+ MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_ICACHE_READ_MISS, MV_CPU_CNTRS_DCACHE_READ_MISS,
53075+ MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_ITLB_MISS, MV_CPU_CNTRS_SINGLE_ISSUE,
53076+ MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_RETIRED, MV_CPU_CNTRS_INVALID,
53077+ MV_CPU_CNTRS_MMU_READ_BEAT, MV_CPU_CNTRS_ICACHE_READ_LATENCY, MV_CPU_CNTRS_WB_WRITE_BEAT,
53078+ MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_IS_HOLD, MV_CPU_CNTRS_DATA_READ_ACCESS,
53079+ MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
53080+ MV_CPU_CNTRS_INVALID,
53081+ },
53082+ /*2*/
53083+ {
53084+ MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_ACCESS,
53085+ MV_CPU_CNTRS_DTLB_MISS, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
53086+ MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_PREDICT_MISS, MV_CPU_CNTRS_WB_WRITE_BEAT,
53087+ MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_READ_LATENCY, MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,
53088+ MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BIU_SIMULT_ACCESS,
53089+ MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
53090+ MV_CPU_CNTRS_INVALID,
53091+ },
53092+ /*3*/
53093+ {
53094+ MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_DCACHE_READ_MISS, MV_CPU_CNTRS_DCACHE_WRITE_MISS,
53095+ MV_CPU_CNTRS_TLB_MISS, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
53096+ MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_TAKEN, MV_CPU_CNTRS_WB_FULL_CYCLES,
53097+ MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_READ_BEAT, MV_CPU_CNTRS_DCACHE_WRITE_BEAT,
53098+ MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BIU_ANY_ACCESS,
53099+ MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DATA_WRITE_ACCESS,
53100+ MV_CPU_CNTRS_INVALID,
53101+ }
53102+};
53103+
53104+MV_CPU_CNTRS_ENTRY mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];
53105+
53106+MV_CPU_CNTRS_EVENT* mvCpuCntrsEventTbl[128];
53107+
53108+void mvCpuCntrsReset(void)
53109+{
53110+ MV_U32 reg = 0;
53111+
53112+ MV_ASM ("mcr p15, 0, %0, c15, c13, 0" : : "r" (reg));
53113+ MV_ASM ("mcr p15, 0, %0, c15, c13, 1" : : "r" (reg));
53114+ MV_ASM ("mcr p15, 0, %0, c15, c13, 2" : : "r" (reg));
53115+ MV_ASM ("mcr p15, 0, %0, c15, c13, 3" : : "r" (reg));
53116+ MV_ASM ("mcr p15, 0, %0, c15, c13, 4" : : "r" (reg));
53117+ MV_ASM ("mcr p15, 0, %0, c15, c13, 5" : : "r" (reg));
53118+ MV_ASM ("mcr p15, 0, %0, c15, c13, 6" : : "r" (reg));
53119+ MV_ASM ("mcr p15, 0, %0, c15, c13, 7" : : "r" (reg));
53120+}
53121+
53122+void program_counter(int counter, int op)
53123+{
53124+ MV_U32 reg = (1 << op) | 0x1; /*enable*/
53125+
53126+ switch(counter)
53127+ {
53128+ case 0:
53129+ __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 0" : : "r" (reg));
53130+ return;
53131+
53132+ case 1:
53133+ __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 1" : : "r" (reg));
53134+ return;
53135+
53136+ case 2:
53137+ __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 2" : : "r" (reg));
53138+ return;
53139+
53140+ case 3:
53141+ __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 3" : : "r" (reg));
53142+ return;
53143+
53144+ default:
53145+ mvOsPrintf("error in program_counter: bad counter number (%d)\n", counter);
53146+ }
53147+ return;
53148+}
53149+
53150+void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent)
53151+{
53152+ int i;
53153+
53154+ for(i=0; i<MV_CPU_CNTRS_NUM; i++)
53155+ {
53156+ pEvent->counters_sum[i] = 0;
53157+ }
53158+ pEvent->num_of_measurements = 0;
53159+}
53160+
53161+
53162+MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold)
53163+{
53164+ int i;
53165+ MV_CPU_CNTRS_EVENT* event = mvOsMalloc(sizeof(MV_CPU_CNTRS_EVENT));
53166+
53167+ if(event)
53168+ {
53169+ strncpy(event->name, name, sizeof(event->name));
53170+ event->num_of_measurements = 0;
53171+ event->avg_sample_count = print_threshold;
53172+ for(i=0; i<MV_CPU_CNTRS_NUM; i++)
53173+ {
53174+ event->counters_before[i] = 0;
53175+ event->counters_after[i] = 0;
53176+ event->counters_sum[i] = 0;
53177+ }
53178+ }
53179+ return event;
53180+}
53181+
53182+void mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event)
53183+{
53184+ if(event != NULL)
53185+ mvOsFree(event);
53186+}
53187+
53188+
53189+MV_STATUS mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op,
53190+ char* name, MV_U32 overhead)
53191+{
53192+ int i;
53193+
53194+ /* Find required operations */
53195+ for(i=0; i<MV_CPU_CNTRS_OPS_NUM; i++)
53196+ {
53197+ if( mvCpuCntrsOpsTbl[counter][i] == op)
53198+ {
53199+ strncpy(mvCpuCntrsTbl[counter].name, name, sizeof(mvCpuCntrsTbl[counter].name));
53200+ mvCpuCntrsTbl[counter].operation = op;
53201+ mvCpuCntrsTbl[counter].opIdx = i+1;
53202+ mvCpuCntrsTbl[counter].overhead = overhead;
53203+ program_counter(counter, mvCpuCntrsTbl[counter].opIdx);
53204+ mvOsPrintf("Counter=%d, opIdx=%d, overhead=%d\n",
53205+ counter, mvCpuCntrsTbl[counter].opIdx, mvCpuCntrsTbl[counter].overhead);
53206+ return MV_OK;
53207+ }
53208+ }
53209+ return MV_NOT_FOUND;
53210+}
53211+
53212+void mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent)
53213+{
53214+ int i;
53215+ MV_U64 counters_avg;
53216+
53217+ if(pEvent->num_of_measurements < pEvent->avg_sample_count)
53218+ return;
53219+
53220+ mvOsPrintf("%16s: ", pEvent->name);
53221+ for(i=0; i<MV_CPU_CNTRS_NUM; i++)
53222+ {
53223+ counters_avg = mvOsDivMod64(pEvent->counters_sum[i],
53224+ pEvent->num_of_measurements, NULL);
53225+ if(counters_avg >= mvCpuCntrsTbl[i].overhead)
53226+ counters_avg -= mvCpuCntrsTbl[i].overhead;
53227+ else
53228+ counters_avg = 0;
53229+
53230+ mvOsPrintf("%s=%5llu, ", mvCpuCntrsTbl[i].name, counters_avg);
53231+ }
53232+ mvOsPrintf("\n");
53233+ mvCpuCntrsEventClear(pEvent);
53234+ mvCpuCntrsReset();
53235+}
53236+
53237+void mvCpuCntrsStatus(void)
53238+{
53239+ int i;
53240+
53241+ for(i=0; i<MV_CPU_CNTRS_NUM; i++)
53242+ {
53243+ mvOsPrintf("#%d: %s, overhead=%d\n",
53244+ i, mvCpuCntrsTbl[i].name, mvCpuCntrsTbl[i].overhead);
53245+ }
53246+}
53247diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h b/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h
53248new file mode 100644
53249index 0000000..0b4998c
53250--- /dev/null
53251+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h
53252@@ -0,0 +1,213 @@
53253+/*******************************************************************************
53254+Copyright (C) Marvell International Ltd. and its affiliates
53255+
53256+This software file (the "File") is owned and distributed by Marvell
53257+International Ltd. and/or its affiliates ("Marvell") under the following
53258+alternative licensing terms. Once you have made an election to distribute the
53259+File under one of the following license alternatives, please (i) delete this
53260+introductory statement regarding license alternatives, (ii) delete the two
53261+license alternatives that you have not elected to use and (iii) preserve the
53262+Marvell copyright notice above.
53263+
53264+
53265+********************************************************************************
53266+Marvell GPL License Option
53267+
53268+If you received this File from Marvell, you may opt to use, redistribute and/or
53269+modify this File in accordance with the terms and conditions of the General
53270+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
53271+available along with the File in the license.txt file or by writing to the Free
53272+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
53273+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
53274+
53275+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
53276+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
53277+DISCLAIMED. The GPL License provides additional details about this warranty
53278+disclaimer.
53279+*******************************************************************************/
53280+#ifndef __mvCpuCntrs_h__
53281+#define __mvCpuCntrs_h__
53282+
53283+#include "mvTypes.h"
53284+#include "mvOs.h"
53285+
53286+
53287+#define MV_CPU_CNTRS_NUM 4
53288+#define MV_CPU_CNTRS_OPS_NUM 32
53289+
53290+typedef enum
53291+{
53292+ MV_CPU_CNTRS_INVALID = 0,
53293+ MV_CPU_CNTRS_CYCLES,
53294+ MV_CPU_CNTRS_ICACHE_READ_MISS,
53295+ MV_CPU_CNTRS_DCACHE_ACCESS,
53296+ MV_CPU_CNTRS_DCACHE_READ_MISS,
53297+ MV_CPU_CNTRS_DCACHE_READ_HIT,
53298+ MV_CPU_CNTRS_DCACHE_WRITE_MISS,
53299+ MV_CPU_CNTRS_DCACHE_WRITE_HIT,
53300+ MV_CPU_CNTRS_DTLB_MISS,
53301+ MV_CPU_CNTRS_TLB_MISS,
53302+ MV_CPU_CNTRS_ITLB_MISS,
53303+ MV_CPU_CNTRS_INSTRUCTIONS,
53304+ MV_CPU_CNTRS_SINGLE_ISSUE,
53305+ MV_CPU_CNTRS_MMU_READ_LATENCY,
53306+ MV_CPU_CNTRS_MMU_READ_BEAT,
53307+ MV_CPU_CNTRS_BRANCH_RETIRED,
53308+ MV_CPU_CNTRS_BRANCH_TAKEN,
53309+ MV_CPU_CNTRS_BRANCH_PREDICT_MISS,
53310+ MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,
53311+ MV_CPU_CNTRS_WB_FULL_CYCLES,
53312+ MV_CPU_CNTRS_WB_WRITE_LATENCY,
53313+ MV_CPU_CNTRS_WB_WRITE_BEAT,
53314+ MV_CPU_CNTRS_ICACHE_READ_LATENCY,
53315+ MV_CPU_CNTRS_ICACHE_READ_BEAT,
53316+ MV_CPU_CNTRS_DCACHE_READ_LATENCY,
53317+ MV_CPU_CNTRS_DCACHE_READ_BEAT,
53318+ MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,
53319+ MV_CPU_CNTRS_DCACHE_WRITE_BEAT,
53320+ MV_CPU_CNTRS_LDM_STM_HOLD,
53321+ MV_CPU_CNTRS_IS_HOLD,
53322+ MV_CPU_CNTRS_DATA_WRITE_ACCESS,
53323+ MV_CPU_CNTRS_DATA_READ_ACCESS,
53324+ MV_CPU_CNTRS_BIU_SIMULT_ACCESS,
53325+ MV_CPU_CNTRS_BIU_ANY_ACCESS,
53326+
53327+} MV_CPU_CNTRS_OPS;
53328+
53329+typedef struct
53330+{
53331+ char name[16];
53332+ MV_CPU_CNTRS_OPS operation;
53333+ int opIdx;
53334+ MV_U32 overhead;
53335+
53336+} MV_CPU_CNTRS_ENTRY;
53337+
53338+
53339+typedef struct
53340+{
53341+ char name[16];
53342+ MV_U32 num_of_measurements;
53343+ MV_U32 avg_sample_count;
53344+ MV_U64 counters_before[MV_CPU_CNTRS_NUM];
53345+ MV_U64 counters_after[MV_CPU_CNTRS_NUM];
53346+ MV_U64 counters_sum[MV_CPU_CNTRS_NUM];
53347+
53348+} MV_CPU_CNTRS_EVENT;
53349+
53350+extern MV_CPU_CNTRS_ENTRY mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];
53351+
53352+
53353+MV_STATUS mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op,
53354+ char* name, MV_U32 overhead);
53355+void mvCpuCntrsInit(void);
53356+MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold);
53357+void mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event);
53358+void mvCpuCntrsReset(void);
53359+void mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent);
53360+void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent);
53361+
53362+/* internal */
53363+void program_counter(int counter, int op);
53364+
53365+static INLINE MV_U64 mvCpuCntrsRead(const int counter)
53366+{
53367+ MV_U32 low = 0, high = 0;
53368+ MV_U32 ll = 0;
53369+
53370+ switch(counter)
53371+ {
53372+ case 0:
53373+ MV_ASM ("mcr p15, 0, %0, c15, c12, 0" : : "r" (ll));
53374+ MV_ASM ("mrc p15, 0, %0, c15, c13, 0" : "=r" (low));
53375+ MV_ASM ("mrc p15, 0, %0, c15, c13, 1" : "=r" (high));
53376+ break;
53377+
53378+ case 1:
53379+ MV_ASM ("mcr p15, 0, %0, c15, c12, 1" : : "r" (ll));
53380+ MV_ASM ("mrc p15, 0, %0, c15, c13, 2" : "=r" (low));
53381+ MV_ASM ("mrc p15, 0, %0, c15, c13, 3" : "=r" (high));
53382+ break;
53383+
53384+ case 2:
53385+ MV_ASM ("mcr p15, 0, %0, c15, c12, 2" : : "r" (ll));
53386+ MV_ASM ("mrc p15, 0, %0, c15, c13, 4" : "=r" (low));
53387+ MV_ASM ("mrc p15, 0, %0, c15, c13, 5" : "=r" (high));
53388+ break;
53389+
53390+ case 3:
53391+ MV_ASM ("mcr p15, 0, %0, c15, c12, 3" : : "r" (ll));
53392+ MV_ASM ("mrc p15, 0, %0, c15, c13, 6" : "=r" (low));
53393+ MV_ASM ("mrc p15, 0, %0, c15, c13, 7" : "=r" (high));
53394+ break;
53395+
53396+ default:
53397+ mvOsPrintf("mv_cpu_cntrs_read: bad counter number (%d)\n", counter);
53398+ }
53399+ program_counter(counter, mvCpuCntrsTbl[counter].opIdx);
53400+ return (((MV_U64)high << 32 ) | low);
53401+
53402+}
53403+
53404+
53405+static INLINE void mvCpuCntrsReadBefore(MV_CPU_CNTRS_EVENT* pEvent)
53406+{
53407+#if 0
53408+ int i;
53409+
53410+ /* order is important - we want to measure the cycle count last here! */
53411+ for(i=0; i<MV_CPU_CNTRS_NUM; i++)
53412+ pEvent->counters_before[i] = mvCpuCntrsRead(i);
53413+#else
53414+ pEvent->counters_before[1] = mvCpuCntrsRead(1);
53415+ pEvent->counters_before[3] = mvCpuCntrsRead(3);
53416+ pEvent->counters_before[0] = mvCpuCntrsRead(0);
53417+ pEvent->counters_before[2] = mvCpuCntrsRead(2);
53418+#endif
53419+}
53420+
53421+static INLINE void mvCpuCntrsReadAfter(MV_CPU_CNTRS_EVENT* pEvent)
53422+{
53423+ int i;
53424+
53425+#if 0
53426+ /* order is important - we want to measure the cycle count first here! */
53427+ for(i=0; i<MV_CPU_CNTRS_NUM; i++)
53428+ pEvent->counters_after[i] = mvCpuCntrsRead(i);
53429+#else
53430+ pEvent->counters_after[2] = mvCpuCntrsRead(2);
53431+ pEvent->counters_after[0] = mvCpuCntrsRead(0);
53432+ pEvent->counters_after[3] = mvCpuCntrsRead(3);
53433+ pEvent->counters_after[1] = mvCpuCntrsRead(1);
53434+#endif
53435+
53436+ for(i=0; i<MV_CPU_CNTRS_NUM; i++)
53437+ {
53438+ pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);
53439+ }
53440+ pEvent->num_of_measurements++;
53441+}
53442+
53443+
53444+#ifdef CONFIG_MV_CPU_PERF_CNTRS
53445+
53446+#define MV_CPU_CNTRS_READ(counter) mvCpuCntrsRead(counter)
53447+
53448+#define MV_CPU_CNTRS_START(event) mvCpuCntrsReadBefore(event)
53449+
53450+#define MV_CPU_CNTRS_STOP(event) mvCpuCntrsReadAfter(event)
53451+
53452+#define MV_CPU_CNTRS_SHOW(event) mvCpuCntrsShow(event)
53453+
53454+#else
53455+
53456+#define MV_CPU_CNTRS_READ(counter)
53457+#define MV_CPU_CNTRS_START(event)
53458+#define MV_CPU_CNTRS_STOP(event)
53459+#define MV_CPU_CNTRS_SHOW(event)
53460+
53461+#endif /* CONFIG_MV_CPU_PERF_CNTRS */
53462+
53463+
53464+#endif /* __mvCpuCntrs_h__ */
53465+
53466diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c b/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c
53467new file mode 100644
53468index 0000000..2401002
53469--- /dev/null
53470+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c
53471@@ -0,0 +1,143 @@
53472+/*
53473+ * This program is free software; you can redistribute it and/or modify
53474+ * it under the terms of the GNU General Public License as published by
53475+ * the Free Software Foundation; either version 2 of the License, or
53476+ * (at your option) any later version.
53477+ *
53478+ * This program is distributed in the hope that it will be useful,
53479+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
53480+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53481+ * GNU General Public License for more details.
53482+ *
53483+ * You should have received a copy of the GNU General Public License
53484+ * along with this program; if not, write to the Free Software
53485+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
53486+ */
53487+
53488+#include "mvOs.h"
53489+#include "mvCpuL2Cntrs.h"
53490+
53491+
53492+
53493+MV_CPU_L2_CNTRS_ENTRY mvCpuL2CntrsTbl[MV_CPU_L2_CNTRS_NUM];
53494+
53495+MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventTbl[128];
53496+
53497+void mvCpuL2CntrsReset(void)
53498+{
53499+ MV_U32 reg = 0;
53500+
53501+ MV_ASM ("mcr p15, 6, %0, c15, c13, 0" : : "r" (reg));
53502+ MV_ASM ("mcr p15, 6, %0, c15, c13, 1" : : "r" (reg));
53503+ MV_ASM ("mcr p15, 6, %0, c15, c13, 2" : : "r" (reg));
53504+ MV_ASM ("mcr p15, 6, %0, c15, c13, 3" : : "r" (reg));
53505+}
53506+
53507+static void mvCpuL2CntrConfig(int counter, int op)
53508+{
53509+ MV_U32 reg = (1 << op) | 0x1; /*enable*/
53510+
53511+ switch(counter)
53512+ {
53513+ case 0:
53514+ MV_ASM ("mcr p15, 6, %0, c15, c12, 0" : : "r" (reg));
53515+ return;
53516+
53517+ case 1:
53518+ MV_ASM ("mcr p15, 6, %0, c15, c12, 1" : : "r" (reg));
53519+ return;
53520+
53521+ default:
53522+ mvOsPrintf("mvCpuL2CntrConfig: bad counter number (%d)\n", counter);
53523+ }
53524+ return;
53525+}
53526+
53527+void mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent)
53528+{
53529+ int i;
53530+
53531+ for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
53532+ {
53533+ pEvent->counters_sum[i] = 0;
53534+ }
53535+ pEvent->num_of_measurements = 0;
53536+}
53537+
53538+
53539+MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold)
53540+{
53541+ int i;
53542+ MV_CPU_L2_CNTRS_EVENT* event = mvOsMalloc(sizeof(MV_CPU_L2_CNTRS_EVENT));
53543+
53544+ if(event)
53545+ {
53546+ strncpy(event->name, name, sizeof(event->name));
53547+ event->num_of_measurements = 0;
53548+ event->avg_sample_count = print_threshold;
53549+ for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
53550+ {
53551+ event->counters_before[i] = 0;
53552+ event->counters_after[i] = 0;
53553+ event->counters_sum[i] = 0;
53554+ }
53555+ }
53556+ return event;
53557+}
53558+
53559+void mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event)
53560+{
53561+ if(event != NULL)
53562+ mvOsFree(event);
53563+}
53564+
53565+
53566+MV_STATUS mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op,
53567+ char* name, MV_U32 overhead)
53568+{
53569+ strncpy(mvCpuL2CntrsTbl[counter].name, name, sizeof(mvCpuL2CntrsTbl[counter].name));
53570+ mvCpuL2CntrsTbl[counter].operation = op;
53571+ mvCpuL2CntrsTbl[counter].opIdx = op;
53572+ mvCpuL2CntrsTbl[counter].overhead = overhead;
53573+ mvCpuL2CntrConfig(counter, op);
53574+ mvOsPrintf("CPU L2 Counter %d: operation=%d, overhead=%d\n",
53575+ counter, op, overhead);
53576+ return MV_OK;
53577+}
53578+
53579+void mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent)
53580+{
53581+ int i;
53582+ MV_U64 counters_avg;
53583+
53584+ if(pEvent->num_of_measurements < pEvent->avg_sample_count)
53585+ return;
53586+
53587+ mvOsPrintf("%16s: ", pEvent->name);
53588+ for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
53589+ {
53590+ counters_avg = mvOsDivMod64(pEvent->counters_sum[i],
53591+ pEvent->num_of_measurements, NULL);
53592+
53593+ if(counters_avg >= mvCpuL2CntrsTbl[i].overhead)
53594+ counters_avg -= mvCpuL2CntrsTbl[i].overhead;
53595+ else
53596+ counters_avg = 0;
53597+
53598+ mvOsPrintf("%s=%5llu, ", mvCpuL2CntrsTbl[i].name, counters_avg);
53599+ }
53600+ mvOsPrintf("\n");
53601+ mvCpuL2CntrsEventClear(pEvent);
53602+ mvCpuL2CntrsReset();
53603+}
53604+
53605+void mvCpuL2CntrsStatus(void)
53606+{
53607+ int i;
53608+
53609+ for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
53610+ {
53611+ mvOsPrintf("#%d: %s, overhead=%d\n",
53612+ i, mvCpuL2CntrsTbl[i].name, mvCpuL2CntrsTbl[i].overhead);
53613+ }
53614+}
53615diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h b/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h
53616new file mode 100644
53617index 0000000..ad6a36f
53618--- /dev/null
53619+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h
53620@@ -0,0 +1,151 @@
53621+/*******************************************************************************
53622+Copyright (C) Marvell International Ltd. and its affiliates
53623+
53624+This software file (the "File") is owned and distributed by Marvell
53625+International Ltd. and/or its affiliates ("Marvell") under the following
53626+alternative licensing terms. Once you have made an election to distribute the
53627+File under one of the following license alternatives, please (i) delete this
53628+introductory statement regarding license alternatives, (ii) delete the two
53629+license alternatives that you have not elected to use and (iii) preserve the
53630+Marvell copyright notice above.
53631+
53632+
53633+********************************************************************************
53634+Marvell GPL License Option
53635+
53636+If you received this File from Marvell, you may opt to use, redistribute and/or
53637+modify this File in accordance with the terms and conditions of the General
53638+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
53639+available along with the File in the license.txt file or by writing to the Free
53640+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
53641+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
53642+
53643+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
53644+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
53645+DISCLAIMED. The GPL License provides additional details about this warranty
53646+disclaimer.
53647+*******************************************************************************/
53648+#ifndef __mvCpuL2Cntrs_h__
53649+#define __mvCpuL2Cntrs_h__
53650+
53651+#include "mvTypes.h"
53652+#include "mvOs.h"
53653+
53654+
53655+#define MV_CPU_L2_CNTRS_NUM 2
53656+
53657+typedef enum
53658+{
53659+ MV_CPU_L2_CNTRS_ENABLE = 0,
53660+ MV_CPU_L2_CNTRS_DATA_REQ,
53661+ MV_CPU_L2_CNTRS_DATA_MISS_REQ,
53662+ MV_CPU_L2_CNTRS_INST_REQ,
53663+ MV_CPU_L2_CNTRS_INST_MISS_REQ,
53664+ MV_CPU_L2_CNTRS_DATA_READ_REQ,
53665+ MV_CPU_L2_CNTRS_DATA_READ_MISS_REQ,
53666+ MV_CPU_L2_CNTRS_DATA_WRITE_REQ,
53667+ MV_CPU_L2_CNTRS_DATA_WRITE_MISS_REQ,
53668+ MV_CPU_L2_CNTRS_RESERVED,
53669+ MV_CPU_L2_CNTRS_DIRTY_EVICT_REQ,
53670+ MV_CPU_L2_CNTRS_EVICT_BUFF_STALL,
53671+ MV_CPU_L2_CNTRS_ACTIVE_CYCLES,
53672+
53673+} MV_CPU_L2_CNTRS_OPS;
53674+
53675+typedef struct
53676+{
53677+ char name[16];
53678+ MV_CPU_L2_CNTRS_OPS operation;
53679+ int opIdx;
53680+ MV_U32 overhead;
53681+
53682+} MV_CPU_L2_CNTRS_ENTRY;
53683+
53684+
53685+typedef struct
53686+{
53687+ char name[16];
53688+ MV_U32 num_of_measurements;
53689+ MV_U32 avg_sample_count;
53690+ MV_U64 counters_before[MV_CPU_L2_CNTRS_NUM];
53691+ MV_U64 counters_after[MV_CPU_L2_CNTRS_NUM];
53692+ MV_U64 counters_sum[MV_CPU_L2_CNTRS_NUM];
53693+
53694+} MV_CPU_L2_CNTRS_EVENT;
53695+
53696+
53697+MV_STATUS mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op,
53698+ char* name, MV_U32 overhead);
53699+void mvCpuL2CntrsInit(void);
53700+MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold);
53701+void mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event);
53702+void mvCpuL2CntrsReset(void);
53703+void mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent);
53704+void mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent);
53705+
53706+static INLINE MV_U64 mvCpuL2CntrsRead(const int counter)
53707+{
53708+ MV_U32 low = 0, high = 0;
53709+
53710+ switch(counter)
53711+ {
53712+ case 0:
53713+ MV_ASM ("mrc p15, 6, %0, c15, c13, 0" : "=r" (low));
53714+ MV_ASM ("mrc p15, 6, %0, c15, c13, 1" : "=r" (high));
53715+ break;
53716+
53717+ case 1:
53718+ MV_ASM ("mrc p15, 6, %0, c15, c13, 2" : "=r" (low));
53719+ MV_ASM ("mrc p15, 6, %0, c15, c13, 3" : "=r" (high));
53720+ break;
53721+
53722+ default:
53723+ mvOsPrintf("mvCpuL2CntrsRead: bad counter number (%d)\n", counter);
53724+ }
53725+ return (((MV_U64)high << 32 ) | low);
53726+
53727+}
53728+
53729+static INLINE void mvCpuL2CntrsReadBefore(MV_CPU_L2_CNTRS_EVENT* pEvent)
53730+{
53731+ int i;
53732+
53733+ for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
53734+ pEvent->counters_before[i] = mvCpuL2CntrsRead(i);
53735+}
53736+
53737+static INLINE void mvCpuL2CntrsReadAfter(MV_CPU_L2_CNTRS_EVENT* pEvent)
53738+{
53739+ int i;
53740+
53741+ for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
53742+ {
53743+ pEvent->counters_after[i] = mvCpuL2CntrsRead(i);
53744+ pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);
53745+ }
53746+ pEvent->num_of_measurements++;
53747+}
53748+
53749+
53750+#ifdef CONFIG_MV_CPU_L2_PERF_CNTRS
53751+
53752+#define MV_CPU_L2_CNTRS_READ(counter) mvCpuL2CntrsRead(counter)
53753+
53754+#define MV_CPU_L2_CNTRS_START(event) mvCpuL2CntrsReadBefore(event)
53755+
53756+#define MV_CPU_L2_CNTRS_STOP(event) mvCpuL2CntrsReadAfter(event)
53757+
53758+#define MV_CPU_L2_CNTRS_SHOW(event) mvCpuL2CntrsShow(event)
53759+
53760+#else
53761+
53762+#define MV_CPU_L2_CNTRS_READ(counter)
53763+#define MV_CPU_L2_CNTRS_START(event)
53764+#define MV_CPU_L2_CNTRS_STOP(event)
53765+#define MV_CPU_L2_CNTRS_SHOW(event)
53766+
53767+#endif /* CONFIG_MV_CPU_L2_PERF_CNTRS */
53768+
53769+
53770+#endif /* __mvCpuL2Cntrs_h__ */
53771+
53772diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c
53773new file mode 100644
53774index 0000000..5c6db90
53775--- /dev/null
53776+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c
53777@@ -0,0 +1,1479 @@
53778+/*******************************************************************************
53779+Copyright (C) Marvell International Ltd. and its affiliates
53780+
53781+This software file (the "File") is owned and distributed by Marvell
53782+International Ltd. and/or its affiliates ("Marvell") under the following
53783+alternative licensing terms. Once you have made an election to distribute the
53784+File under one of the following license alternatives, please (i) delete this
53785+introductory statement regarding license alternatives, (ii) delete the two
53786+license alternatives that you have not elected to use and (iii) preserve the
53787+Marvell copyright notice above.
53788+
53789+********************************************************************************
53790+Marvell Commercial License Option
53791+
53792+If you received this File from Marvell and you have entered into a commercial
53793+license agreement (a "Commercial License") with Marvell, the File is licensed
53794+to you under the terms of the applicable Commercial License.
53795+
53796+********************************************************************************
53797+Marvell GPL License Option
53798+
53799+If you received this File from Marvell, you may opt to use, redistribute and/or
53800+modify this File in accordance with the terms and conditions of the General
53801+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
53802+available along with the File in the license.txt file or by writing to the Free
53803+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
53804+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
53805+
53806+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
53807+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
53808+DISCLAIMED. The GPL License provides additional details about this warranty
53809+disclaimer.
53810+********************************************************************************
53811+Marvell BSD License Option
53812+
53813+If you received this File from Marvell, you may opt to use, redistribute and/or
53814+modify this File under the following licensing terms.
53815+Redistribution and use in source and binary forms, with or without modification,
53816+are permitted provided that the following conditions are met:
53817+
53818+ * Redistributions of source code must retain the above copyright notice,
53819+ this list of conditions and the following disclaimer.
53820+
53821+ * Redistributions in binary form must reproduce the above copyright
53822+ notice, this list of conditions and the following disclaimer in the
53823+ documentation and/or other materials provided with the distribution.
53824+
53825+ * Neither the name of Marvell nor the names of its contributors may be
53826+ used to endorse or promote products derived from this software without
53827+ specific prior written permission.
53828+
53829+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
53830+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53831+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53832+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
53833+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53834+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53835+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
53836+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53837+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
53838+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53839+
53840+*******************************************************************************/
53841+
53842+#include "ddr1_2/mvDram.h"
53843+#include "boardEnv/mvBoardEnvLib.h"
53844+
53845+#undef MV_DEBUG
53846+#ifdef MV_DEBUG
53847+#define DB(x) x
53848+#else
53849+#define DB(x)
53850+#endif
53851+
53852+static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
53853+ MV_DRAM_BANK_INFO *pBankInfo);
53854+static MV_U32 cas2ps(MV_U8 spd_byte);
53855+/*******************************************************************************
53856+* mvDramBankGet - Get the DRAM bank paramters.
53857+*
53858+* DESCRIPTION:
53859+* This function retrieves DRAM bank parameters as described in
53860+* DRAM_BANK_INFO struct to the controller DRAM unit. In case the board
53861+* has its DRAM on DIMMs it will use its EEPROM to extract SPD data
53862+* from it. Otherwise, if the DRAM is soldered on board, the function
53863+* should insert its bank information into MV_DRAM_BANK_INFO struct.
53864+*
53865+* INPUT:
53866+* bankNum - Board DRAM bank number.
53867+*
53868+* OUTPUT:
53869+* pBankInfo - DRAM bank information struct.
53870+*
53871+* RETURN:
53872+* MV_FAIL - Bank parameters could not be read.
53873+*
53874+*******************************************************************************/
53875+MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
53876+{
53877+ MV_DIMM_INFO dimmInfo;
53878+
53879+ DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
53880+ /* zero pBankInfo structure */
53881+ memset(pBankInfo, 0, sizeof(*pBankInfo));
53882+
53883+ if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
53884+ {
53885+ DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
53886+ return MV_BAD_PARAM;
53887+ }
53888+ if( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
53889+ {
53890+ DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
53891+ return MV_FAIL;
53892+ }
53893+ if((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
53894+ {
53895+ DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
53896+ return MV_FAIL;
53897+ }
53898+
53899+ /* convert Dimm info to Bank info */
53900+ cpyDimm2BankInfo(&dimmInfo, pBankInfo);
53901+
53902+ return MV_OK;
53903+}
53904+
53905+/*******************************************************************************
53906+* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
53907+*
53908+* DESCRIPTION:
53909+* Convert a Dimm info struct into a bank info struct.
53910+*
53911+* INPUT:
53912+* pDimmInfo - DIMM information structure.
53913+*
53914+* OUTPUT:
53915+* pBankInfo - DRAM bank information struct.
53916+*
53917+* RETURN:
53918+* None.
53919+*
53920+*******************************************************************************/
53921+static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
53922+ MV_DRAM_BANK_INFO *pBankInfo)
53923+{
53924+ pBankInfo->memoryType = pDimmInfo->memoryType;
53925+
53926+ /* DIMM dimensions */
53927+ pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
53928+ pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
53929+ pBankInfo->dataWidth = pDimmInfo->dataWidth;
53930+ pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
53931+ pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
53932+ pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
53933+ pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
53934+ pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
53935+ pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
53936+
53937+ /* DIMM timing parameters */
53938+ pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
53939+ pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
53940+ pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
53941+ pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
53942+ pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
53943+
53944+ pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
53945+ pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
53946+ pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
53947+ pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
53948+ pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
53949+ pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
53950+ pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
53951+ pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
53952+
53953+ /* Parameters calculated from the extracted DIMM information */
53954+ pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
53955+ pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
53956+ pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
53957+ pDimmInfo->numOfModuleBanks;
53958+
53959+ /* DIMM attributes (MV_TRUE for yes) */
53960+
53961+ if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
53962+ (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
53963+ {
53964+ if (pDimmInfo->dimmAttributes & BIT1)
53965+ pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
53966+ else
53967+ pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
53968+ }
53969+ else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
53970+ {
53971+ if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
53972+ pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
53973+ else
53974+ pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
53975+ }
53976+
53977+ return;
53978+}
53979+
53980+/*******************************************************************************
53981+* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
53982+*
53983+* DESCRIPTION:
53984+* Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
53985+*
53986+* INPUT:
53987+* None.
53988+*
53989+* OUTPUT:
53990+* None.
53991+*
53992+* RETURN:
53993+* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
53994+*
53995+*******************************************************************************/
53996+MV_STATUS dimmSpdCpy(MV_VOID)
53997+{
53998+ MV_U32 i;
53999+ MV_U32 spdChecksum;
54000+
54001+ MV_TWSI_SLAVE twsiSlave;
54002+ MV_U8 data[SPD_SIZE];
54003+
54004+ /* zero dimmInfo structure */
54005+ memset(data, 0, SPD_SIZE);
54006+
54007+ /* read the dimm eeprom */
54008+ DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
54009+ twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
54010+ twsiSlave.slaveAddr.type = ADDR7_BIT;
54011+ twsiSlave.validOffset = MV_TRUE;
54012+ twsiSlave.offset = 0;
54013+ twsiSlave.moreThen256 = MV_FALSE;
54014+
54015+ if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
54016+ &twsiSlave, data, SPD_SIZE) )
54017+ {
54018+ DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
54019+ return MV_FAIL;
54020+ }
54021+ DB(puts("DRAM: Reading dimm info succeded.\n"));
54022+
54023+ /* calculate SPD checksum */
54024+ spdChecksum = 0;
54025+
54026+ for(i = 0 ; i <= 62 ; i++)
54027+ {
54028+ spdChecksum += data[i];
54029+ }
54030+
54031+ if ((spdChecksum & 0xff) != data[63])
54032+ {
54033+ DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
54034+ (MV_U32)(spdChecksum & 0xff), data[63]));
54035+ }
54036+ else
54037+ {
54038+ DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
54039+ }
54040+
54041+ /* copy the SPD content 1:1 into the DIMM 1 SPD */
54042+ twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
54043+ twsiSlave.slaveAddr.type = ADDR7_BIT;
54044+ twsiSlave.validOffset = MV_TRUE;
54045+ twsiSlave.offset = 0;
54046+ twsiSlave.moreThen256 = MV_FALSE;
54047+
54048+ for(i = 0 ; i < SPD_SIZE ; i++)
54049+ {
54050+ twsiSlave.offset = i;
54051+ if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL,
54052+ &twsiSlave, &data[i], 1) )
54053+ {
54054+ mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
54055+ return MV_FAIL;
54056+ }
54057+ mvOsDelay(5);
54058+ }
54059+
54060+ DB(puts("DRAM: Reading dimm info succeded.\n"));
54061+ return MV_OK;
54062+}
54063+
54064+/*******************************************************************************
54065+* dimmSpdGet - Get the SPD parameters.
54066+*
54067+* DESCRIPTION:
54068+* Read the DIMM SPD parameters into given struct parameter.
54069+*
54070+* INPUT:
54071+* dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
54072+*
54073+* OUTPUT:
54074+* pDimmInfo - DIMM information structure.
54075+*
54076+* RETURN:
54077+* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
54078+*
54079+*******************************************************************************/
54080+MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
54081+{
54082+ MV_U32 i;
54083+ MV_U32 density = 1;
54084+ MV_U32 spdChecksum;
54085+
54086+ MV_TWSI_SLAVE twsiSlave;
54087+ MV_U8 data[SPD_SIZE];
54088+
54089+ if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
54090+ {
54091+ DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
54092+ return MV_BAD_PARAM;
54093+ }
54094+
54095+ /* zero dimmInfo structure */
54096+ memset(data, 0, SPD_SIZE);
54097+
54098+ /* read the dimm eeprom */
54099+ DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
54100+ twsiSlave.slaveAddr.address = (dimmNum == 0) ?
54101+ MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
54102+ twsiSlave.slaveAddr.type = ADDR7_BIT;
54103+ twsiSlave.validOffset = MV_TRUE;
54104+ twsiSlave.offset = 0;
54105+ twsiSlave.moreThen256 = MV_FALSE;
54106+
54107+ if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
54108+ &twsiSlave, data, SPD_SIZE) )
54109+ {
54110+ DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
54111+ return MV_FAIL;
54112+ }
54113+ DB(puts("DRAM: Reading dimm info succeded.\n"));
54114+
54115+ /* calculate SPD checksum */
54116+ spdChecksum = 0;
54117+
54118+ for(i = 0 ; i <= 62 ; i++)
54119+ {
54120+ spdChecksum += data[i];
54121+ }
54122+
54123+ if ((spdChecksum & 0xff) != data[63])
54124+ {
54125+ DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
54126+ (MV_U32)(spdChecksum & 0xff), data[63]));
54127+ }
54128+ else
54129+ {
54130+ DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
54131+ }
54132+
54133+ /* copy the SPD content 1:1 into the dimmInfo structure*/
54134+ for(i = 0 ; i < SPD_SIZE ; i++)
54135+ {
54136+ pDimmInfo->spdRawData[i] = data[i];
54137+ DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
54138+ }
54139+
54140+ DB(mvOsPrintf("DRAM SPD Information:\n"));
54141+
54142+ /* Memory type (DDR / SDRAM) */
54143+ switch (data[DIMM_MEM_TYPE])
54144+ {
54145+ case (DIMM_MEM_TYPE_SDRAM):
54146+ pDimmInfo->memoryType = MEM_TYPE_SDRAM;
54147+ DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
54148+ break;
54149+ case (DIMM_MEM_TYPE_DDR1):
54150+ pDimmInfo->memoryType = MEM_TYPE_DDR1;
54151+ DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
54152+ break;
54153+ case (DIMM_MEM_TYPE_DDR2):
54154+ pDimmInfo->memoryType = MEM_TYPE_DDR2;
54155+ DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
54156+ break;
54157+ default:
54158+ mvOsPrintf("ERROR: Undefined memory type!\n");
54159+ return MV_ERROR;
54160+ }
54161+
54162+
54163+ /* Number Of Row Addresses */
54164+ pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
54165+ DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
54166+
54167+ /* Number Of Column Addresses */
54168+ pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
54169+ DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
54170+
54171+ /* Number Of Module Banks */
54172+ pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
54173+ DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
54174+ pDimmInfo->numOfModuleBanks));
54175+
54176+ /* Number of module banks encoded differently for DDR2 */
54177+ if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
54178+ pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
54179+
54180+ /* Data Width */
54181+ pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
54182+ DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
54183+
54184+ /* Minimum Cycle Time At Max CasLatancy */
54185+ pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
54186+
54187+ /* Error Check Type */
54188+ pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
54189+ DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
54190+ pDimmInfo->errorCheckType));
54191+
54192+ /* Refresh Interval */
54193+ pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
54194+ DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
54195+ pDimmInfo->refreshInterval));
54196+
54197+ /* Sdram Width */
54198+ pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
54199+ DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
54200+
54201+ /* Error Check Data Width */
54202+ pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
54203+ DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
54204+ pDimmInfo->errorCheckDataWidth));
54205+
54206+ /* Burst Length Supported */
54207+ /* SDRAM/DDR1:
54208+ *******-******-******-******-******-******-******-*******
54209+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
54210+ *******-******-******-******-******-******-******-*******
54211+ burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
54212+ *********************************************************/
54213+ /* DDR2:
54214+ *******-******-******-******-******-******-******-*******
54215+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
54216+ *******-******-******-******-******-******-******-*******
54217+ burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
54218+ *********************************************************/
54219+
54220+ pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
54221+ DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
54222+ pDimmInfo->burstLengthSupported));
54223+
54224+ /* Number Of Banks On Each Device */
54225+ pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
54226+ DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
54227+ pDimmInfo->numOfBanksOnEachDevice));
54228+
54229+ /* Suported Cas Latencies */
54230+
54231+ /* SDRAM:
54232+ *******-******-******-******-******-******-******-*******
54233+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
54234+ *******-******-******-******-******-******-******-*******
54235+ CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
54236+ ********************************************************/
54237+
54238+ /* DDR 1:
54239+ *******-******-******-******-******-******-******-*******
54240+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
54241+ *******-******-******-******-******-******-******-*******
54242+ CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
54243+ *********************************************************/
54244+
54245+ /* DDR 2:
54246+ *******-******-******-******-******-******-******-*******
54247+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
54248+ *******-******-******-******-******-******-******-*******
54249+ CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
54250+ *********************************************************/
54251+
54252+ pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
54253+ DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
54254+ pDimmInfo->suportedCasLatencies));
54255+
54256+ /* For DDR2 only, get the DIMM type information */
54257+ if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
54258+ {
54259+ pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
54260+ DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
54261+ pDimmInfo->dimmTypeInfo));
54262+ }
54263+
54264+ /* SDRAM Modules Attributes */
54265+ pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
54266+ DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
54267+ pDimmInfo->dimmAttributes));
54268+
54269+ /* Minimum Cycle Time At Max CasLatancy Minus 1*/
54270+ pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
54271+ cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
54272+
54273+ /* Minimum Cycle Time At Max CasLatancy Minus 2*/
54274+ pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
54275+ cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
54276+
54277+ pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
54278+ DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
54279+ pDimmInfo->minRowPrechargeTime));
54280+ pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
54281+ DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
54282+ pDimmInfo->minRowActiveToRowActive));
54283+ pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
54284+ DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
54285+ pDimmInfo->minRasToCasDelay));
54286+ pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
54287+ DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
54288+ pDimmInfo->minRasPulseWidth));
54289+
54290+ /* DIMM Bank Density */
54291+ pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
54292+ DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
54293+ pDimmInfo->dimmBankDensity));
54294+
54295+ /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
54296+ pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
54297+ DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
54298+ pDimmInfo->minWriteRecoveryTime));
54299+
54300+ /* Only DDR2 includes Internal Write To Read Command Delay field. */
54301+ pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
54302+ DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
54303+ pDimmInfo->minWriteToReadCmdDelay));
54304+
54305+ /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
54306+ pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
54307+ DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
54308+ pDimmInfo->minReadToPrechCmdDelay));
54309+
54310+ /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
54311+ pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
54312+ DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
54313+ pDimmInfo->minRefreshToActiveCmd));
54314+
54315+ /* calculating the sdram density. Representing device density from */
54316+ /* bit 20 to allow representation of 4GB and above. */
54317+ /* For example, if density is 512Mbit 0x20000000, will be represent in */
54318+ /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
54319+ /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
54320+ density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
54321+ pDimmInfo->deviceDensity = density *
54322+ pDimmInfo->numOfBanksOnEachDevice *
54323+ pDimmInfo->sdramWidth;
54324+ DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
54325+
54326+ /* Number of devices includeing Error correction */
54327+ pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
54328+ pDimmInfo->numOfModuleBanks;
54329+ DB(mvOsPrintf("DRAM numberOfDevices %d\n",
54330+ pDimmInfo->numberOfDevices));
54331+
54332+ pDimmInfo->size = 0;
54333+
54334+ /* Note that pDimmInfo->size is in MB units */
54335+ if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
54336+ {
54337+ if (pDimmInfo->dimmBankDensity & BIT0)
54338+ pDimmInfo->size += 1024; /* Equal to 1GB */
54339+ else if (pDimmInfo->dimmBankDensity & BIT1)
54340+ pDimmInfo->size += 8; /* Equal to 8MB */
54341+ else if (pDimmInfo->dimmBankDensity & BIT2)
54342+ pDimmInfo->size += 16; /* Equal to 16MB */
54343+ else if (pDimmInfo->dimmBankDensity & BIT3)
54344+ pDimmInfo->size += 32; /* Equal to 32MB */
54345+ else if (pDimmInfo->dimmBankDensity & BIT4)
54346+ pDimmInfo->size += 64; /* Equal to 64MB */
54347+ else if (pDimmInfo->dimmBankDensity & BIT5)
54348+ pDimmInfo->size += 128; /* Equal to 128MB */
54349+ else if (pDimmInfo->dimmBankDensity & BIT6)
54350+ pDimmInfo->size += 256; /* Equal to 256MB */
54351+ else if (pDimmInfo->dimmBankDensity & BIT7)
54352+ pDimmInfo->size += 512; /* Equal to 512MB */
54353+ }
54354+ else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
54355+ {
54356+ if (pDimmInfo->dimmBankDensity & BIT0)
54357+ pDimmInfo->size += 1024; /* Equal to 1GB */
54358+ else if (pDimmInfo->dimmBankDensity & BIT1)
54359+ pDimmInfo->size += 2048; /* Equal to 2GB */
54360+ else if (pDimmInfo->dimmBankDensity & BIT2)
54361+ pDimmInfo->size += 16; /* Equal to 16MB */
54362+ else if (pDimmInfo->dimmBankDensity & BIT3)
54363+ pDimmInfo->size += 32; /* Equal to 32MB */
54364+ else if (pDimmInfo->dimmBankDensity & BIT4)
54365+ pDimmInfo->size += 64; /* Equal to 64MB */
54366+ else if (pDimmInfo->dimmBankDensity & BIT5)
54367+ pDimmInfo->size += 128; /* Equal to 128MB */
54368+ else if (pDimmInfo->dimmBankDensity & BIT6)
54369+ pDimmInfo->size += 256; /* Equal to 256MB */
54370+ else if (pDimmInfo->dimmBankDensity & BIT7)
54371+ pDimmInfo->size += 512; /* Equal to 512MB */
54372+ }
54373+ else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
54374+ {
54375+ if (pDimmInfo->dimmBankDensity & BIT0)
54376+ pDimmInfo->size += 1024; /* Equal to 1GB */
54377+ else if (pDimmInfo->dimmBankDensity & BIT1)
54378+ pDimmInfo->size += 2048; /* Equal to 2GB */
54379+ else if (pDimmInfo->dimmBankDensity & BIT2)
54380+ pDimmInfo->size += 4096; /* Equal to 4GB */
54381+ else if (pDimmInfo->dimmBankDensity & BIT3)
54382+ pDimmInfo->size += 8192; /* Equal to 8GB */
54383+ else if (pDimmInfo->dimmBankDensity & BIT4)
54384+ pDimmInfo->size += 16384; /* Equal to 16GB */
54385+ else if (pDimmInfo->dimmBankDensity & BIT5)
54386+ pDimmInfo->size += 128; /* Equal to 128MB */
54387+ else if (pDimmInfo->dimmBankDensity & BIT6)
54388+ pDimmInfo->size += 256; /* Equal to 256MB */
54389+ else if (pDimmInfo->dimmBankDensity & BIT7)
54390+ pDimmInfo->size += 512; /* Equal to 512MB */
54391+ }
54392+
54393+ pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
54394+
54395+ DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
54396+
54397+ return MV_OK;
54398+}
54399+
54400+/*******************************************************************************
54401+* dimmSpdPrint - Print the SPD parameters.
54402+*
54403+* DESCRIPTION:
54404+* Print the Dimm SPD parameters.
54405+*
54406+* INPUT:
54407+* pDimmInfo - DIMM information structure.
54408+*
54409+* OUTPUT:
54410+* None.
54411+*
54412+* RETURN:
54413+* None.
54414+*
54415+*******************************************************************************/
54416+MV_VOID dimmSpdPrint(MV_U32 dimmNum)
54417+{
54418+ MV_DIMM_INFO dimmInfo;
54419+ MV_U32 i, temp = 0;
54420+ MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
54421+ MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
54422+ MV_U32 busClkPs;
54423+ MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
54424+ temp_buf[40], *spdRawData;
54425+
54426+ busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
54427+
54428+ spdRawData = dimmInfo.spdRawData;
54429+
54430+ if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
54431+ {
54432+ mvOsOutput("ERROR: Could not read SPD information!\n");
54433+ return;
54434+ }
54435+
54436+ /* find Manufactura of Dimm Module */
54437+ mvOsOutput("\nManufacturer's JEDEC ID Code: ");
54438+ for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
54439+ {
54440+ mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
54441+ }
54442+ mvOsOutput("\n");
54443+
54444+ /* Manufacturer's Specific Data */
54445+ for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
54446+ {
54447+ temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
54448+ }
54449+ mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
54450+
54451+ /* Module Part Number */
54452+ for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
54453+ {
54454+ temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
54455+ }
54456+ mvOsOutput("Module Part Number: %s\n", temp_buf);
54457+
54458+ /* Module Serial Number */
54459+ for(i = 0; i < sizeof(MV_U32); i++)
54460+ {
54461+ temp |= spdRawData[95+i] << 8*i;
54462+ }
54463+ mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
54464+ (long)temp);
54465+
54466+ /* find Manufac-Data of Dimm Module */
54467+ mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
54468+ ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
54469+ ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
54470+ /* find modul_revision of Dimm Module */
54471+ mvOsOutput("Module Revision: %d.%d\n",
54472+ spdRawData[91], spdRawData[92]);
54473+
54474+ /* find manufac_place of Dimm Module */
54475+ mvOsOutput("manufac_place: %d\n", spdRawData[72]);
54476+
54477+ /* go over the first 35 I2C data bytes */
54478+ for(i = 2 ; i <= 35 ; i++)
54479+ switch(i)
54480+ {
54481+ case 2: /* Memory type (DDR1/2 / SDRAM) */
54482+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
54483+ mvOsOutput("Dram Type is: SDRAM\n");
54484+ else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
54485+ mvOsOutput("Dram Type is: SDRAM DDR1\n");
54486+ else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
54487+ mvOsOutput("Dram Type is: SDRAM DDR2\n");
54488+ else
54489+ mvOsOutput("Dram Type unknown\n");
54490+ break;
54491+/*----------------------------------------------------------------------------*/
54492+
54493+ case 3: /* Number Of Row Addresses */
54494+ mvOsOutput("Module Number of row addresses: %d\n",
54495+ dimmInfo.numOfRowAddr);
54496+ break;
54497+/*----------------------------------------------------------------------------*/
54498+
54499+ case 4: /* Number Of Column Addresses */
54500+ mvOsOutput("Module Number of col addresses: %d\n",
54501+ dimmInfo.numOfColAddr);
54502+ break;
54503+/*----------------------------------------------------------------------------*/
54504+
54505+ case 5: /* Number Of Module Banks */
54506+ mvOsOutput("Number of Banks on Mod.: %d\n",
54507+ dimmInfo.numOfModuleBanks);
54508+ break;
54509+/*----------------------------------------------------------------------------*/
54510+
54511+ case 6: /* Data Width */
54512+ mvOsOutput("Module Data Width: %d bit\n",
54513+ dimmInfo.dataWidth);
54514+ break;
54515+/*----------------------------------------------------------------------------*/
54516+
54517+ case 8: /* Voltage Interface */
54518+ switch(spdRawData[i])
54519+ {
54520+ case 0x0:
54521+ mvOsOutput("Module is TTL_5V_TOLERANT\n");
54522+ break;
54523+ case 0x1:
54524+ mvOsOutput("Module is LVTTL\n");
54525+ break;
54526+ case 0x2:
54527+ mvOsOutput("Module is HSTL_1_5V\n");
54528+ break;
54529+ case 0x3:
54530+ mvOsOutput("Module is SSTL_3_3V\n");
54531+ break;
54532+ case 0x4:
54533+ mvOsOutput("Module is SSTL_2_5V\n");
54534+ break;
54535+ case 0x5:
54536+ if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
54537+ {
54538+ mvOsOutput("Module is SSTL_1_8V\n");
54539+ break;
54540+ }
54541+ default:
54542+ mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
54543+ break;
54544+ }
54545+ break;
54546+/*----------------------------------------------------------------------------*/
54547+
54548+ case 9: /* Minimum Cycle Time At Max CasLatancy */
54549+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
54550+ rightOfPoint = (spdRawData[i] & 0x0f) * 10;
54551+
54552+ /* DDR2 addition of right of point */
54553+ if ((spdRawData[i] & 0x0f) == 0xA)
54554+ {
54555+ rightOfPoint = 25;
54556+ }
54557+ if ((spdRawData[i] & 0x0f) == 0xB)
54558+ {
54559+ rightOfPoint = 33;
54560+ }
54561+ if ((spdRawData[i] & 0x0f) == 0xC)
54562+ {
54563+ rightOfPoint = 66;
54564+ }
54565+ if ((spdRawData[i] & 0x0f) == 0xD)
54566+ {
54567+ rightOfPoint = 75;
54568+ }
54569+ mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
54570+ leftOfPoint, rightOfPoint);
54571+ break;
54572+/*----------------------------------------------------------------------------*/
54573+
54574+ case 10: /* Clock To Data Out */
54575+ div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
54576+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
54577+ ((spdRawData[i] & 0x0f));
54578+ leftOfPoint = time_tmp / div;
54579+ rightOfPoint = time_tmp % div;
54580+ mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
54581+ leftOfPoint, rightOfPoint);
54582+ break;
54583+/*----------------------------------------------------------------------------*/
54584+
54585+ case 11: /* Error Check Type */
54586+ mvOsOutput("Error Check Type (0=NONE): %d\n",
54587+ dimmInfo.errorCheckType);
54588+ break;
54589+/*----------------------------------------------------------------------------*/
54590+
54591+ case 12: /* Refresh Interval */
54592+ mvOsOutput("Refresh Rate: %x\n",
54593+ dimmInfo.refreshInterval);
54594+ break;
54595+/*----------------------------------------------------------------------------*/
54596+
54597+ case 13: /* Sdram Width */
54598+ mvOsOutput("Sdram Width: %d bits\n",
54599+ dimmInfo.sdramWidth);
54600+ break;
54601+/*----------------------------------------------------------------------------*/
54602+
54603+ case 14: /* Error Check Data Width */
54604+ mvOsOutput("Error Check Data Width: %d bits\n",
54605+ dimmInfo.errorCheckDataWidth);
54606+ break;
54607+/*----------------------------------------------------------------------------*/
54608+
54609+ case 15: /* Minimum Clock Delay is unsupported */
54610+ if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
54611+ (dimmInfo.memoryType == MEM_TYPE_DDR1))
54612+ {
54613+ mvOsOutput("Minimum Clk Delay back to back: %d\n",
54614+ spdRawData[i]);
54615+ }
54616+ break;
54617+/*----------------------------------------------------------------------------*/
54618+
54619+ case 16: /* Burst Length Supported */
54620+ /* SDRAM/DDR1:
54621+ *******-******-******-******-******-******-******-*******
54622+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
54623+ *******-******-******-******-******-******-******-*******
54624+ burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
54625+ *********************************************************/
54626+ /* DDR2:
54627+ *******-******-******-******-******-******-******-*******
54628+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
54629+ *******-******-******-******-******-******-******-*******
54630+ burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
54631+ *********************************************************/
54632+ mvOsOutput("Burst Length Supported: ");
54633+ if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
54634+ (dimmInfo.memoryType == MEM_TYPE_DDR1))
54635+ {
54636+ if (dimmInfo.burstLengthSupported & BIT0)
54637+ mvOsOutput("1, ");
54638+ if (dimmInfo.burstLengthSupported & BIT1)
54639+ mvOsOutput("2, ");
54640+ }
54641+ if (dimmInfo.burstLengthSupported & BIT2)
54642+ mvOsOutput("4, ");
54643+ if (dimmInfo.burstLengthSupported & BIT3)
54644+ mvOsOutput("8, ");
54645+
54646+ mvOsOutput(" Bit \n");
54647+ break;
54648+/*----------------------------------------------------------------------------*/
54649+
54650+ case 17: /* Number Of Banks On Each Device */
54651+ mvOsOutput("Number Of Banks On Each Chip: %d\n",
54652+ dimmInfo.numOfBanksOnEachDevice);
54653+ break;
54654+/*----------------------------------------------------------------------------*/
54655+
54656+ case 18: /* Suported Cas Latencies */
54657+
54658+ /* SDRAM:
54659+ *******-******-******-******-******-******-******-*******
54660+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
54661+ *******-******-******-******-******-******-******-*******
54662+ CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
54663+ ********************************************************/
54664+
54665+ /* DDR 1:
54666+ *******-******-******-******-******-******-******-*******
54667+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
54668+ *******-******-******-******-******-******-******-*******
54669+ CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
54670+ *********************************************************/
54671+
54672+ /* DDR 2:
54673+ *******-******-******-******-******-******-******-*******
54674+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
54675+ *******-******-******-******-******-******-******-*******
54676+ CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
54677+ *********************************************************/
54678+
54679+ mvOsOutput("Suported Cas Latencies: (CL) ");
54680+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
54681+ {
54682+ for (k = 0; k <=7; k++)
54683+ {
54684+ if (dimmInfo.suportedCasLatencies & (1 << k))
54685+ mvOsOutput("%d, ", k+1);
54686+ }
54687+ }
54688+ else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
54689+ {
54690+ if (dimmInfo.suportedCasLatencies & BIT0)
54691+ mvOsOutput("1, ");
54692+ if (dimmInfo.suportedCasLatencies & BIT1)
54693+ mvOsOutput("1.5, ");
54694+ if (dimmInfo.suportedCasLatencies & BIT2)
54695+ mvOsOutput("2, ");
54696+ if (dimmInfo.suportedCasLatencies & BIT3)
54697+ mvOsOutput("2.5, ");
54698+ if (dimmInfo.suportedCasLatencies & BIT4)
54699+ mvOsOutput("3, ");
54700+ if (dimmInfo.suportedCasLatencies & BIT5)
54701+ mvOsOutput("3.5, ");
54702+ }
54703+ else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
54704+ {
54705+ if (dimmInfo.suportedCasLatencies & BIT2)
54706+ mvOsOutput("2, ");
54707+ if (dimmInfo.suportedCasLatencies & BIT3)
54708+ mvOsOutput("3, ");
54709+ if (dimmInfo.suportedCasLatencies & BIT4)
54710+ mvOsOutput("4, ");
54711+ if (dimmInfo.suportedCasLatencies & BIT5)
54712+ mvOsOutput("5, ");
54713+ }
54714+ else
54715+ mvOsOutput("?.?, ");
54716+ mvOsOutput("\n");
54717+ break;
54718+/*----------------------------------------------------------------------------*/
54719+
54720+ case 20: /* DDR2 DIMM type info */
54721+ if (dimmInfo.memoryType == MEM_TYPE_DDR2)
54722+ {
54723+ if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
54724+ mvOsOutput("Registered DIMM (RDIMM)\n");
54725+ else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
54726+ mvOsOutput("Unbuffered DIMM (UDIMM)\n");
54727+ else
54728+ mvOsOutput("Unknown DIMM type.\n");
54729+ }
54730+
54731+ break;
54732+/*----------------------------------------------------------------------------*/
54733+
54734+ case 21: /* SDRAM Modules Attributes */
54735+ mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
54736+
54737+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
54738+ {
54739+ if (dimmInfo.dimmAttributes & BIT0)
54740+ mvOsOutput(" Buffered Addr/Control Input: Yes\n");
54741+ else
54742+ mvOsOutput(" Buffered Addr/Control Input: No\n");
54743+
54744+ if (dimmInfo.dimmAttributes & BIT1)
54745+ mvOsOutput(" Registered Addr/Control Input: Yes\n");
54746+ else
54747+ mvOsOutput(" Registered Addr/Control Input: No\n");
54748+
54749+ if (dimmInfo.dimmAttributes & BIT2)
54750+ mvOsOutput(" On-Card PLL (clock): Yes \n");
54751+ else
54752+ mvOsOutput(" On-Card PLL (clock): No \n");
54753+
54754+ if (dimmInfo.dimmAttributes & BIT3)
54755+ mvOsOutput(" Bufferd DQMB Input: Yes \n");
54756+ else
54757+ mvOsOutput(" Bufferd DQMB Inputs: No \n");
54758+
54759+ if (dimmInfo.dimmAttributes & BIT4)
54760+ mvOsOutput(" Registered DQMB Inputs: Yes \n");
54761+ else
54762+ mvOsOutput(" Registered DQMB Inputs: No \n");
54763+
54764+ if (dimmInfo.dimmAttributes & BIT5)
54765+ mvOsOutput(" Differential Clock Input: Yes \n");
54766+ else
54767+ mvOsOutput(" Differential Clock Input: No \n");
54768+
54769+ if (dimmInfo.dimmAttributes & BIT6)
54770+ mvOsOutput(" redundant Row Addressing: Yes \n");
54771+ else
54772+ mvOsOutput(" redundant Row Addressing: No \n");
54773+ }
54774+ else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
54775+ {
54776+ if (dimmInfo.dimmAttributes & BIT0)
54777+ mvOsOutput(" Buffered Addr/Control Input: Yes\n");
54778+ else
54779+ mvOsOutput(" Buffered Addr/Control Input: No\n");
54780+
54781+ if (dimmInfo.dimmAttributes & BIT1)
54782+ mvOsOutput(" Registered Addr/Control Input: Yes\n");
54783+ else
54784+ mvOsOutput(" Registered Addr/Control Input: No\n");
54785+
54786+ if (dimmInfo.dimmAttributes & BIT2)
54787+ mvOsOutput(" On-Card PLL (clock): Yes \n");
54788+ else
54789+ mvOsOutput(" On-Card PLL (clock): No \n");
54790+
54791+ if (dimmInfo.dimmAttributes & BIT3)
54792+ mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
54793+ else
54794+ mvOsOutput(" FET Switch On-Card Enabled: No \n");
54795+
54796+ if (dimmInfo.dimmAttributes & BIT4)
54797+ mvOsOutput(" FET Switch External Enabled: Yes \n");
54798+ else
54799+ mvOsOutput(" FET Switch External Enabled: No \n");
54800+
54801+ if (dimmInfo.dimmAttributes & BIT5)
54802+ mvOsOutput(" Differential Clock Input: Yes \n");
54803+ else
54804+ mvOsOutput(" Differential Clock Input: No \n");
54805+ }
54806+ else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
54807+ {
54808+ mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
54809+ (dimmInfo.dimmAttributes & 0x3) + 1);
54810+
54811+ mvOsOutput(" Number of PLLs on the DIMM: %d\n",
54812+ ((dimmInfo.dimmAttributes) >> 2) & 0x3);
54813+
54814+ if (dimmInfo.dimmAttributes & BIT4)
54815+ mvOsOutput(" FET Switch External Enabled: Yes \n");
54816+ else
54817+ mvOsOutput(" FET Switch External Enabled: No \n");
54818+
54819+ if (dimmInfo.dimmAttributes & BIT6)
54820+ mvOsOutput(" Analysis probe installed: Yes \n");
54821+ else
54822+ mvOsOutput(" Analysis probe installed: No \n");
54823+ }
54824+
54825+ break;
54826+/*----------------------------------------------------------------------------*/
54827+
54828+ case 22: /* Suported AutoPreCharge */
54829+ mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
54830+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
54831+ {
54832+ if ( spdRawData[i] & BIT0 )
54833+ mvOsOutput(" Early Ras Precharge: Yes \n");
54834+ else
54835+ mvOsOutput(" Early Ras Precharge: No \n");
54836+
54837+ if ( spdRawData[i] & BIT1 )
54838+ mvOsOutput(" AutoPreCharge: Yes \n");
54839+ else
54840+ mvOsOutput(" AutoPreCharge: No \n");
54841+
54842+ if ( spdRawData[i] & BIT2 )
54843+ mvOsOutput(" Precharge All: Yes \n");
54844+ else
54845+ mvOsOutput(" Precharge All: No \n");
54846+
54847+ if ( spdRawData[i] & BIT3 )
54848+ mvOsOutput(" Write 1/ReadBurst: Yes \n");
54849+ else
54850+ mvOsOutput(" Write 1/ReadBurst: No \n");
54851+
54852+ if ( spdRawData[i] & BIT4 )
54853+ mvOsOutput(" lower VCC tolerance: 5%%\n");
54854+ else
54855+ mvOsOutput(" lower VCC tolerance: 10%%\n");
54856+
54857+ if ( spdRawData[i] & BIT5 )
54858+ mvOsOutput(" upper VCC tolerance: 5%%\n");
54859+ else
54860+ mvOsOutput(" upper VCC tolerance: 10%%\n");
54861+ }
54862+ else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
54863+ {
54864+ if ( spdRawData[i] & BIT0 )
54865+ mvOsOutput(" Supports Weak Driver: Yes \n");
54866+ else
54867+ mvOsOutput(" Supports Weak Driver: No \n");
54868+
54869+ if ( !(spdRawData[i] & BIT4) )
54870+ mvOsOutput(" lower VCC tolerance: 0.2V\n");
54871+
54872+ if ( !(spdRawData[i] & BIT5) )
54873+ mvOsOutput(" upper VCC tolerance: 0.2V\n");
54874+
54875+ if ( spdRawData[i] & BIT6 )
54876+ mvOsOutput(" Concurrent Auto Preharge: Yes \n");
54877+ else
54878+ mvOsOutput(" Concurrent Auto Preharge: No \n");
54879+
54880+ if ( spdRawData[i] & BIT7 )
54881+ mvOsOutput(" Supports Fast AP: Yes \n");
54882+ else
54883+ mvOsOutput(" Supports Fast AP: No \n");
54884+ }
54885+ else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
54886+ {
54887+ if ( spdRawData[i] & BIT0 )
54888+ mvOsOutput(" Supports Weak Driver: Yes \n");
54889+ else
54890+ mvOsOutput(" Supports Weak Driver: No \n");
54891+ }
54892+ break;
54893+/*----------------------------------------------------------------------------*/
54894+
54895+ case 23:
54896+ /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
54897+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
54898+ rightOfPoint = (spdRawData[i] & 0x0f) * 10;
54899+
54900+ /* DDR2 addition of right of point */
54901+ if ((spdRawData[i] & 0x0f) == 0xA)
54902+ {
54903+ rightOfPoint = 25;
54904+ }
54905+ if ((spdRawData[i] & 0x0f) == 0xB)
54906+ {
54907+ rightOfPoint = 33;
54908+ }
54909+ if ((spdRawData[i] & 0x0f) == 0xC)
54910+ {
54911+ rightOfPoint = 66;
54912+ }
54913+ if ((spdRawData[i] & 0x0f) == 0xD)
54914+ {
54915+ rightOfPoint = 75;
54916+ }
54917+
54918+ mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
54919+ "(0 = Not supported): %d.%d [ns]\n",
54920+ leftOfPoint, rightOfPoint );
54921+ break;
54922+/*----------------------------------------------------------------------------*/
54923+
54924+ case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
54925+ div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
54926+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
54927+ ((spdRawData[i] & 0x0f));
54928+ leftOfPoint = time_tmp / div;
54929+ rightOfPoint = time_tmp % div;
54930+ mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
54931+ leftOfPoint, rightOfPoint);
54932+ break;
54933+/*----------------------------------------------------------------------------*/
54934+
54935+ case 25:
54936+ /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
54937+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
54938+ {
54939+ leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
54940+ rightOfPoint = (spdRawData[i] & 0x3) * 25;
54941+ }
54942+ else /* DDR1 or DDR2 */
54943+ {
54944+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
54945+ rightOfPoint = (spdRawData[i] & 0x0f) * 10;
54946+
54947+ /* DDR2 addition of right of point */
54948+ if ((spdRawData[i] & 0x0f) == 0xA)
54949+ {
54950+ rightOfPoint = 25;
54951+ }
54952+ if ((spdRawData[i] & 0x0f) == 0xB)
54953+ {
54954+ rightOfPoint = 33;
54955+ }
54956+ if ((spdRawData[i] & 0x0f) == 0xC)
54957+ {
54958+ rightOfPoint = 66;
54959+ }
54960+ if ((spdRawData[i] & 0x0f) == 0xD)
54961+ {
54962+ rightOfPoint = 75;
54963+ }
54964+ }
54965+ mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
54966+ "(0 = Not supported): %d.%d [ns]\n",
54967+ leftOfPoint, rightOfPoint );
54968+ break;
54969+/*----------------------------------------------------------------------------*/
54970+
54971+ case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
54972+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
54973+ {
54974+ leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
54975+ rightOfPoint = (spdRawData[i] & 0x3) * 25;
54976+ }
54977+ else /* DDR1 or DDR2 */
54978+ {
54979+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
54980+ ((spdRawData[i] & 0x0f));
54981+ leftOfPoint = 0;
54982+ rightOfPoint = time_tmp;
54983+ }
54984+ mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
54985+ leftOfPoint, rightOfPoint );
54986+ break;
54987+/*----------------------------------------------------------------------------*/
54988+
54989+ case 27: /* Minimum Row Precharge Time */
54990+ shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
54991+ maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
54992+ 0xff : 0xfc;
54993+ maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
54994+ 0x00 : 0x03;
54995+ leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
54996+ rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
54997+ temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
54998+ trp_clocks = (temp + (busClkPs-1)) / busClkPs;
54999+ mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
55000+ "in Clk cycles %d\n",
55001+ leftOfPoint, rightOfPoint, trp_clocks);
55002+ break;
55003+/*----------------------------------------------------------------------------*/
55004+
55005+ case 28: /* Minimum Row Active to Row Active Time */
55006+ shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
55007+ maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
55008+ 0xff : 0xfc;
55009+ maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
55010+ 0x00 : 0x03;
55011+ leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
55012+ rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
55013+ temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
55014+ trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
55015+ mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
55016+ "%d.%d = in Clk cycles %d\n",
55017+ leftOfPoint, rightOfPoint, trp_clocks);
55018+ break;
55019+/*----------------------------------------------------------------------------*/
55020+
55021+ case 29: /* Minimum Ras-To-Cas Delay */
55022+ shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
55023+ maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
55024+ 0xff : 0xfc;
55025+ maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
55026+ 0x00 : 0x03;
55027+ leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
55028+ rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
55029+ temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
55030+ trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
55031+ mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
55032+ "in Clk cycles %d\n",
55033+ leftOfPoint, rightOfPoint, trp_clocks);
55034+ break;
55035+/*----------------------------------------------------------------------------*/
55036+
55037+ case 30: /* Minimum Ras Pulse Width */
55038+ tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
55039+ mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
55040+ "in Clk cycles %d\n", spdRawData[i], tras_clocks);
55041+ break;
55042+/*----------------------------------------------------------------------------*/
55043+
55044+ case 31: /* Module Bank Density */
55045+ mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
55046+
55047+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
55048+ {
55049+ if (dimmInfo.dimmBankDensity & BIT0)
55050+ mvOsOutput("1GB, ");
55051+ if (dimmInfo.dimmBankDensity & BIT1)
55052+ mvOsOutput("8MB, ");
55053+ if (dimmInfo.dimmBankDensity & BIT2)
55054+ mvOsOutput("16MB, ");
55055+ if (dimmInfo.dimmBankDensity & BIT3)
55056+ mvOsOutput("32MB, ");
55057+ if (dimmInfo.dimmBankDensity & BIT4)
55058+ mvOsOutput("64MB, ");
55059+ if (dimmInfo.dimmBankDensity & BIT5)
55060+ mvOsOutput("128MB, ");
55061+ if (dimmInfo.dimmBankDensity & BIT6)
55062+ mvOsOutput("256MB, ");
55063+ if (dimmInfo.dimmBankDensity & BIT7)
55064+ mvOsOutput("512MB, ");
55065+ }
55066+ else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
55067+ {
55068+ if (dimmInfo.dimmBankDensity & BIT0)
55069+ mvOsOutput("1GB, ");
55070+ if (dimmInfo.dimmBankDensity & BIT1)
55071+ mvOsOutput("2GB, ");
55072+ if (dimmInfo.dimmBankDensity & BIT2)
55073+ mvOsOutput("16MB, ");
55074+ if (dimmInfo.dimmBankDensity & BIT3)
55075+ mvOsOutput("32MB, ");
55076+ if (dimmInfo.dimmBankDensity & BIT4)
55077+ mvOsOutput("64MB, ");
55078+ if (dimmInfo.dimmBankDensity & BIT5)
55079+ mvOsOutput("128MB, ");
55080+ if (dimmInfo.dimmBankDensity & BIT6)
55081+ mvOsOutput("256MB, ");
55082+ if (dimmInfo.dimmBankDensity & BIT7)
55083+ mvOsOutput("512MB, ");
55084+ }
55085+ else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
55086+ {
55087+ if (dimmInfo.dimmBankDensity & BIT0)
55088+ mvOsOutput("1GB, ");
55089+ if (dimmInfo.dimmBankDensity & BIT1)
55090+ mvOsOutput("2GB, ");
55091+ if (dimmInfo.dimmBankDensity & BIT2)
55092+ mvOsOutput("4GB, ");
55093+ if (dimmInfo.dimmBankDensity & BIT3)
55094+ mvOsOutput("8GB, ");
55095+ if (dimmInfo.dimmBankDensity & BIT4)
55096+ mvOsOutput("16GB, ");
55097+ if (dimmInfo.dimmBankDensity & BIT5)
55098+ mvOsOutput("128MB, ");
55099+ if (dimmInfo.dimmBankDensity & BIT6)
55100+ mvOsOutput("256MB, ");
55101+ if (dimmInfo.dimmBankDensity & BIT7)
55102+ mvOsOutput("512MB, ");
55103+ }
55104+ mvOsOutput("\n");
55105+ break;
55106+/*----------------------------------------------------------------------------*/
55107+
55108+ case 32: /* Address And Command Setup Time (measured in ns/1000) */
55109+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
55110+ {
55111+ rightOfPoint = (spdRawData[i] & 0x0f);
55112+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
55113+ if(leftOfPoint > 7)
55114+ {
55115+ leftOfPoint *= -1;
55116+ }
55117+ }
55118+ else /* DDR1 or DDR2 */
55119+ {
55120+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
55121+ ((spdRawData[i] & 0x0f));
55122+ leftOfPoint = time_tmp / 100;
55123+ rightOfPoint = time_tmp % 100;
55124+ }
55125+ mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
55126+ leftOfPoint, rightOfPoint);
55127+ break;
55128+/*----------------------------------------------------------------------------*/
55129+
55130+ case 33: /* Address And Command Hold Time */
55131+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
55132+ {
55133+ rightOfPoint = (spdRawData[i] & 0x0f);
55134+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
55135+ if(leftOfPoint > 7)
55136+ {
55137+ leftOfPoint *= -1;
55138+ }
55139+ }
55140+ else /* DDR1 or DDR2 */
55141+ {
55142+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
55143+ ((spdRawData[i] & 0x0f));
55144+ leftOfPoint = time_tmp / 100;
55145+ rightOfPoint = time_tmp % 100;
55146+ }
55147+ mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
55148+ leftOfPoint, rightOfPoint);
55149+ break;
55150+/*----------------------------------------------------------------------------*/
55151+
55152+ case 34: /* Data Input Setup Time */
55153+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
55154+ {
55155+ rightOfPoint = (spdRawData[i] & 0x0f);
55156+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
55157+ if(leftOfPoint > 7)
55158+ {
55159+ leftOfPoint *= -1;
55160+ }
55161+ }
55162+ else /* DDR1 or DDR2 */
55163+ {
55164+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
55165+ ((spdRawData[i] & 0x0f));
55166+ leftOfPoint = time_tmp / 100;
55167+ rightOfPoint = time_tmp % 100;
55168+ }
55169+ mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
55170+ leftOfPoint, rightOfPoint);
55171+ break;
55172+/*----------------------------------------------------------------------------*/
55173+
55174+ case 35: /* Data Input Hold Time */
55175+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
55176+ {
55177+ rightOfPoint = (spdRawData[i] & 0x0f);
55178+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
55179+ if(leftOfPoint > 7)
55180+ {
55181+ leftOfPoint *= -1;
55182+ }
55183+ }
55184+ else /* DDR1 or DDR2 */
55185+ {
55186+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
55187+ ((spdRawData[i] & 0x0f));
55188+ leftOfPoint = time_tmp / 100;
55189+ rightOfPoint = time_tmp % 100;
55190+ }
55191+ mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
55192+ leftOfPoint, rightOfPoint);
55193+ break;
55194+/*----------------------------------------------------------------------------*/
55195+
55196+ case 36: /* Relevant for DDR2 only: Write Recovery Time */
55197+ leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
55198+ rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
55199+ mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
55200+ leftOfPoint, rightOfPoint);
55201+ break;
55202+/*----------------------------------------------------------------------------*/
55203+ }
55204+
55205+}
55206+
55207+
55208+/*
55209+ * translate ns.ns/10 coding of SPD timing values
55210+ * into ps unit values
55211+ */
55212+/*******************************************************************************
55213+* cas2ps - Translate x.y ns parameter to pico-seconds values
55214+*
55215+* DESCRIPTION:
55216+* This function translates x.y nano seconds to its value in pico seconds.
55217+* For example 3.75ns will return 3750.
55218+*
55219+* INPUT:
55220+* spd_byte - DIMM SPD byte.
55221+*
55222+* OUTPUT:
55223+* None.
55224+*
55225+* RETURN:
55226+* value in pico seconds.
55227+*
55228+*******************************************************************************/
55229+static MV_U32 cas2ps(MV_U8 spd_byte)
55230+{
55231+ MV_U32 ns, ns10;
55232+
55233+ /* isolate upper nibble */
55234+ ns = (spd_byte >> 4) & 0x0F;
55235+ /* isolate lower nibble */
55236+ ns10 = (spd_byte & 0x0F);
55237+
55238+ if( ns10 < 10 ) {
55239+ ns10 *= 10;
55240+ }
55241+ else if( ns10 == 10 )
55242+ ns10 = 25;
55243+ else if( ns10 == 11 )
55244+ ns10 = 33;
55245+ else if( ns10 == 12 )
55246+ ns10 = 66;
55247+ else if( ns10 == 13 )
55248+ ns10 = 75;
55249+ else
55250+ {
55251+ mvOsOutput("cas2ps Err. unsupported cycle time.\n");
55252+ }
55253+
55254+ return (ns*1000 + ns10*10);
55255+}
55256+
55257diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h
55258new file mode 100644
55259index 0000000..6e79d1e
55260--- /dev/null
55261+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h
55262@@ -0,0 +1,191 @@
55263+/*******************************************************************************
55264+Copyright (C) Marvell International Ltd. and its affiliates
55265+
55266+This software file (the "File") is owned and distributed by Marvell
55267+International Ltd. and/or its affiliates ("Marvell") under the following
55268+alternative licensing terms. Once you have made an election to distribute the
55269+File under one of the following license alternatives, please (i) delete this
55270+introductory statement regarding license alternatives, (ii) delete the two
55271+license alternatives that you have not elected to use and (iii) preserve the
55272+Marvell copyright notice above.
55273+
55274+********************************************************************************
55275+Marvell Commercial License Option
55276+
55277+If you received this File from Marvell and you have entered into a commercial
55278+license agreement (a "Commercial License") with Marvell, the File is licensed
55279+to you under the terms of the applicable Commercial License.
55280+
55281+********************************************************************************
55282+Marvell GPL License Option
55283+
55284+If you received this File from Marvell, you may opt to use, redistribute and/or
55285+modify this File in accordance with the terms and conditions of the General
55286+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
55287+available along with the File in the license.txt file or by writing to the Free
55288+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
55289+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
55290+
55291+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
55292+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
55293+DISCLAIMED. The GPL License provides additional details about this warranty
55294+disclaimer.
55295+********************************************************************************
55296+Marvell BSD License Option
55297+
55298+If you received this File from Marvell, you may opt to use, redistribute and/or
55299+modify this File under the following licensing terms.
55300+Redistribution and use in source and binary forms, with or without modification,
55301+are permitted provided that the following conditions are met:
55302+
55303+ * Redistributions of source code must retain the above copyright notice,
55304+ this list of conditions and the following disclaimer.
55305+
55306+ * Redistributions in binary form must reproduce the above copyright
55307+ notice, this list of conditions and the following disclaimer in the
55308+ documentation and/or other materials provided with the distribution.
55309+
55310+ * Neither the name of Marvell nor the names of its contributors may be
55311+ used to endorse or promote products derived from this software without
55312+ specific prior written permission.
55313+
55314+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
55315+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
55316+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55317+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
55318+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
55319+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
55320+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
55321+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55322+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
55323+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55324+
55325+*******************************************************************************/
55326+
55327+#ifndef __INCmvDram
55328+#define __INCmvDram
55329+
55330+#include "ddr1_2/mvDramIf.h"
55331+#include "twsi/mvTwsi.h"
55332+
55333+#define MAX_DIMM_NUM 2
55334+#define SPD_SIZE 128
55335+
55336+/* Dimm spd offsets */
55337+#define DIMM_MEM_TYPE 2
55338+#define DIMM_ROW_NUM 3
55339+#define DIMM_COL_NUM 4
55340+#define DIMM_MODULE_BANK_NUM 5
55341+#define DIMM_DATA_WIDTH 6
55342+#define DIMM_VOLT_IF 8
55343+#define DIMM_MIN_CC_AT_MAX_CAS 9
55344+#define DIMM_ERR_CHECK_TYPE 11
55345+#define DIMM_REFRESH_INTERVAL 12
55346+#define DIMM_SDRAM_WIDTH 13
55347+#define DIMM_ERR_CHECK_DATA_WIDTH 14
55348+#define DIMM_MIN_CLK_DEL 15
55349+#define DIMM_BURST_LEN_SUP 16
55350+#define DIMM_DEV_BANK_NUM 17
55351+#define DIMM_SUP_CAL 18
55352+#define DIMM_DDR2_TYPE_INFORMATION 20 /* DDR2 only */
55353+#define DIMM_BUF_ADDR_CONT_IN 21
55354+#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1 23
55355+#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2 25
55356+#define DIMM_MIN_ROW_PRECHARGE_TIME 27
55357+#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE 28
55358+#define DIMM_MIN_RAS_TO_CAS_DELAY 29
55359+#define DIMM_MIN_RAS_PULSE_WIDTH 30
55360+#define DIMM_BANK_DENSITY 31
55361+#define DIMM_MIN_WRITE_RECOVERY_TIME 36
55362+#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY 37
55363+#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY 38
55364+#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD 42
55365+
55366+/* Dimm Memory Type values */
55367+#define DIMM_MEM_TYPE_SDRAM 0x4
55368+#define DIMM_MEM_TYPE_DDR1 0x7
55369+#define DIMM_MEM_TYPE_DDR2 0x8
55370+
55371+#define DIMM_MODULE_MANU_OFFS 64
55372+#define DIMM_MODULE_MANU_SIZE 8
55373+#define DIMM_MODULE_VEN_OFFS 73
55374+#define DIMM_MODULE_VEN_SIZE 25
55375+#define DIMM_MODULE_ID_OFFS 99
55376+#define DIMM_MODULE_ID_SIZE 18
55377+
55378+/* enumeration for voltage levels. */
55379+typedef enum _mvDimmVoltageIf
55380+{
55381+ TTL_5V_TOLERANT,
55382+ LVTTL,
55383+ HSTL_1_5V,
55384+ SSTL_3_3V,
55385+ SSTL_2_5V,
55386+ VOLTAGE_UNKNOWN,
55387+} MV_DIMM_VOLTAGE_IF;
55388+
55389+
55390+/* enumaration for SDRAM CAS Latencies. */
55391+typedef enum _mvDimmSdramCas
55392+{
55393+ SD_CL_1 =1,
55394+ SD_CL_2,
55395+ SD_CL_3,
55396+ SD_CL_4,
55397+ SD_CL_5,
55398+ SD_CL_6,
55399+ SD_CL_7,
55400+ SD_FAULT
55401+}MV_DIMM_SDRAM_CAS;
55402+
55403+
55404+/* DIMM information structure */
55405+typedef struct _mvDimmInfo
55406+{
55407+ MV_MEMORY_TYPE memoryType; /* DDR or SDRAM */
55408+
55409+ MV_U8 spdRawData[SPD_SIZE]; /* Content of SPD-EEPROM copied 1:1 */
55410+
55411+ /* DIMM dimensions */
55412+ MV_U32 numOfRowAddr;
55413+ MV_U32 numOfColAddr;
55414+ MV_U32 numOfModuleBanks;
55415+ MV_U32 dataWidth;
55416+ MV_U32 errorCheckType; /* ECC , PARITY..*/
55417+ MV_U32 sdramWidth; /* 4,8,16 or 32 */
55418+ MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
55419+ MV_U32 burstLengthSupported;
55420+ MV_U32 numOfBanksOnEachDevice;
55421+ MV_U32 suportedCasLatencies;
55422+ MV_U32 refreshInterval;
55423+ MV_U32 dimmBankDensity;
55424+ MV_U32 dimmTypeInfo; /* DDR2 only */
55425+ MV_U32 dimmAttributes;
55426+
55427+ /* DIMM timing parameters */
55428+ MV_U32 minCycleTimeAtMaxCasLatPs;
55429+ MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
55430+ MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
55431+ MV_U32 minRowPrechargeTime;
55432+ MV_U32 minRowActiveToRowActive;
55433+ MV_U32 minRasToCasDelay;
55434+ MV_U32 minRasPulseWidth;
55435+ MV_U32 minWriteRecoveryTime; /* DDR2 only */
55436+ MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
55437+ MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
55438+ MV_U32 minRefreshToActiveCmd; /* DDR2 only */
55439+
55440+ /* Parameters calculated from the extracted DIMM information */
55441+ MV_U32 size; /* 16,64,128,256 or 512 MByte in MB units */
55442+ MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit in MB units */
55443+ MV_U32 numberOfDevices;
55444+
55445+} MV_DIMM_INFO;
55446+
55447+
55448+MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);
55449+MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);
55450+MV_VOID dimmSpdPrint(MV_U32 dimmNum);
55451+MV_STATUS dimmSpdCpy(MV_VOID);
55452+
55453+#endif /* __INCmvDram */
55454diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c
55455new file mode 100644
55456index 0000000..c44dabe
55457--- /dev/null
55458+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c
55459@@ -0,0 +1,1599 @@
55460+/*******************************************************************************
55461+Copyright (C) Marvell International Ltd. and its affiliates
55462+
55463+This software file (the "File") is owned and distributed by Marvell
55464+International Ltd. and/or its affiliates ("Marvell") under the following
55465+alternative licensing terms. Once you have made an election to distribute the
55466+File under one of the following license alternatives, please (i) delete this
55467+introductory statement regarding license alternatives, (ii) delete the two
55468+license alternatives that you have not elected to use and (iii) preserve the
55469+Marvell copyright notice above.
55470+
55471+********************************************************************************
55472+Marvell Commercial License Option
55473+
55474+If you received this File from Marvell and you have entered into a commercial
55475+license agreement (a "Commercial License") with Marvell, the File is licensed
55476+to you under the terms of the applicable Commercial License.
55477+
55478+********************************************************************************
55479+Marvell GPL License Option
55480+
55481+If you received this File from Marvell, you may opt to use, redistribute and/or
55482+modify this File in accordance with the terms and conditions of the General
55483+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
55484+available along with the File in the license.txt file or by writing to the Free
55485+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
55486+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
55487+
55488+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
55489+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
55490+DISCLAIMED. The GPL License provides additional details about this warranty
55491+disclaimer.
55492+********************************************************************************
55493+Marvell BSD License Option
55494+
55495+If you received this File from Marvell, you may opt to use, redistribute and/or
55496+modify this File under the following licensing terms.
55497+Redistribution and use in source and binary forms, with or without modification,
55498+are permitted provided that the following conditions are met:
55499+
55500+ * Redistributions of source code must retain the above copyright notice,
55501+ this list of conditions and the following disclaimer.
55502+
55503+ * Redistributions in binary form must reproduce the above copyright
55504+ notice, this list of conditions and the following disclaimer in the
55505+ documentation and/or other materials provided with the distribution.
55506+
55507+ * Neither the name of Marvell nor the names of its contributors may be
55508+ used to endorse or promote products derived from this software without
55509+ specific prior written permission.
55510+
55511+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
55512+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
55513+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55514+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
55515+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
55516+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
55517+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
55518+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55519+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
55520+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55521+
55522+*******************************************************************************/
55523+
55524+
55525+/* includes */
55526+#include "ddr1_2/mvDramIf.h"
55527+#include "ctrlEnv/sys/mvCpuIf.h"
55528+
55529+
55530+
55531+#ifdef MV_DEBUG
55532+#define DB(x) x
55533+#else
55534+#define DB(x)
55535+#endif
55536+
55537+/* DRAM bank presence encoding */
55538+#define BANK_PRESENT_CS0 0x1
55539+#define BANK_PRESENT_CS0_CS1 0x3
55540+#define BANK_PRESENT_CS0_CS2 0x5
55541+#define BANK_PRESENT_CS0_CS1_CS2 0x7
55542+#define BANK_PRESENT_CS0_CS2_CS3 0xd
55543+#define BANK_PRESENT_CS0_CS2_CS3_CS4 0xf
55544+
55545+/* locals */
55546+static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
55547+#if defined(MV_INC_BOARD_DDIM)
55548+static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
55549+static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas);
55550+static MV_U32 sdramModeRegCalc(MV_U32 minCas);
55551+static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
55552+static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
55553+static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
55554+static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk,
55555+ MV_U32 forcedCl);
55556+static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
55557+ MV_U32 minCas, MV_U32 busClk);
55558+static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
55559+ MV_U32 busClk);
55560+
55561+/*******************************************************************************
55562+* mvDramIfDetect - Prepare DRAM interface configuration values.
55563+*
55564+* DESCRIPTION:
55565+* This function implements the full DRAM detection and timing
55566+* configuration for best system performance.
55567+* Since this routine runs from a ROM device (Boot Flash), its stack
55568+* resides on RAM, that might be the system DRAM. Changing DRAM
55569+* configuration values while keeping vital data in DRAM is risky. That
55570+* is why the function does not preform the configuration setting but
55571+* prepare those in predefined 32bit registers (in this case IDMA
55572+* registers are used) for other routine to perform the settings.
55573+* The function will call for board DRAM SPD information for each DRAM
55574+* chip select. The function will then analyze those SPD parameters of
55575+* all DRAM banks in order to decide on DRAM configuration compatible
55576+* for all DRAM banks.
55577+* The function will set the CPU DRAM address decode registers.
55578+* Note: This routine prepares values that will overide configuration of
55579+* mvDramBasicAsmInit().
55580+*
55581+* INPUT:
55582+* forcedCl - Forced CAL Latency. If equal to zero, do not force.
55583+*
55584+* OUTPUT:
55585+* None.
55586+*
55587+* RETURN:
55588+* None.
55589+*
55590+*******************************************************************************/
55591+MV_STATUS mvDramIfDetect(MV_U32 forcedCl)
55592+{
55593+ MV_U32 retVal = MV_OK; /* return value */
55594+ MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
55595+ MV_U32 busClk, size, base = 0, i, temp, deviceW, dimmW;
55596+ MV_U8 minCas;
55597+ MV_DRAM_DEC_WIN dramDecWin;
55598+
55599+ dramDecWin.addrWin.baseHigh = 0;
55600+
55601+ busClk = mvBoardSysClkGet();
55602+
55603+ if (0 == busClk)
55604+ {
55605+ mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
55606+ return MV_ERROR;
55607+ }
55608+
55609+ /* Close DRAM banks except bank 0 (in case code is excecuting from it...) */
55610+#if defined(MV_INCLUDE_SDRAM_CS1)
55611+ for(i= SDRAM_CS1; i < MV_DRAM_MAX_CS; i++)
55612+ mvCpuIfTargetWinEnable(i, MV_FALSE);
55613+#endif
55614+
55615+ /* we will use bank 0 as the representative of the all the DRAM banks, */
55616+ /* since bank 0 must exist. */
55617+ for(i = 0; i < MV_DRAM_MAX_CS; i++)
55618+ {
55619+ /* if Bank exist */
55620+ if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
55621+ {
55622+ /* check it isn't SDRAM */
55623+ if(bankInfo[i].memoryType == MEM_TYPE_SDRAM)
55624+ {
55625+ mvOsPrintf("Dram: ERR. SDRAM type not supported !!!\n");
55626+ return MV_ERROR;
55627+ }
55628+ /* All banks must support registry in order to activate it */
55629+ if(bankInfo[i].registeredAddrAndControlInputs !=
55630+ bankInfo[0].registeredAddrAndControlInputs)
55631+ {
55632+ mvOsPrintf("Dram: ERR. different Registered settings !!!\n");
55633+ return MV_ERROR;
55634+ }
55635+
55636+ /* Init the CPU window decode */
55637+ /* Note that the size in Bank info is in MB units */
55638+ /* Note that the Dimm width might be different then the device DRAM width */
55639+ temp = MV_REG_READ(SDRAM_CONFIG_REG);
55640+
55641+ deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_16BIT )? 16 : 32;
55642+ dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
55643+ size = ((bankInfo[i].size << 20) / (dimmW/deviceW));
55644+
55645+ /* We can not change DRAM window settings while excecuting */
55646+ /* code from it. That is why we skip the DRAM CS[0], saving */
55647+ /* it to the ROM configuration routine */
55648+ if(i == SDRAM_CS0)
55649+ {
55650+ MV_U32 sizeToReg;
55651+
55652+ /* Translate the given window size to register format */
55653+ sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
55654+
55655+ /* Size parameter validity check. */
55656+ if (-1 == sizeToReg)
55657+ {
55658+ mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
55659+ ,i);
55660+ return MV_BAD_PARAM;
55661+ }
55662+
55663+ /* Size is located at upper 16 bits */
55664+ sizeToReg <<= SCSR_SIZE_OFFS;
55665+
55666+ /* enable it */
55667+ sizeToReg |= SCSR_WIN_EN;
55668+
55669+ MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
55670+ }
55671+ else
55672+ {
55673+ dramDecWin.addrWin.baseLow = base;
55674+ dramDecWin.addrWin.size = size;
55675+ dramDecWin.enable = MV_TRUE;
55676+
55677+ if (MV_OK != mvDramIfWinSet(SDRAM_CS0 + i, &dramDecWin))
55678+ {
55679+ mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n",
55680+ SDRAM_CS0 + i);
55681+ return MV_ERROR;
55682+ }
55683+ }
55684+
55685+ base += size;
55686+
55687+ /* update the suportedCasLatencies mask */
55688+ bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
55689+
55690+ }
55691+ else
55692+ {
55693+ if( i == 0 ) /* bank 0 doesn't exist */
55694+ {
55695+ mvOsPrintf("Dram: ERR. Fail to detect bank 0 !!!\n");
55696+ return MV_ERROR;
55697+ }
55698+ else
55699+ {
55700+ DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
55701+ bankInfo[i].size = 0; /* Mark this bank as non exist */
55702+ }
55703+ }
55704+ }
55705+
55706+ /* calculate minimum CAS */
55707+ minCas = minCasCalc(&bankInfo[0], busClk, forcedCl);
55708+ if (0 == minCas)
55709+ {
55710+ mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
55711+ (busClk / 1000000));
55712+
55713+ if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
55714+ {
55715+ minCas = DDR2_CL_4; /* Continue with this CAS */
55716+ mvOsPrintf("Set default CAS latency 4\n");
55717+ }
55718+ else
55719+ {
55720+ minCas = DDR1_CL_3; /* Continue with this CAS */
55721+ mvOsPrintf("Set default CAS latency 3\n");
55722+ }
55723+ }
55724+
55725+ /* calc SDRAM_CONFIG_REG and save it to temp register */
55726+ temp = sdramConfigRegCalc(&bankInfo[0], busClk);
55727+ if(-1 == temp)
55728+ {
55729+ mvOsPrintf("Dram: ERR. sdramConfigRegCalc failed !!!\n");
55730+ return MV_ERROR;
55731+ }
55732+ MV_REG_WRITE(DRAM_BUF_REG1, temp);
55733+
55734+ /* calc SDRAM_MODE_REG and save it to temp register */
55735+ temp = sdramModeRegCalc(minCas);
55736+ if(-1 == temp)
55737+ {
55738+ mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
55739+ return MV_ERROR;
55740+ }
55741+ MV_REG_WRITE(DRAM_BUF_REG2, temp);
55742+
55743+ /* calc SDRAM_EXTENDED_MODE_REG and save it to temp register */
55744+ temp = sdramExtModeRegCalc(&bankInfo[0]);
55745+ if(-1 == temp)
55746+ {
55747+ mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
55748+ return MV_ERROR;
55749+ }
55750+ MV_REG_WRITE(DRAM_BUF_REG10, temp);
55751+
55752+ /* calc D_UNIT_CONTROL_LOW and save it to temp register */
55753+ temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas);
55754+ if(-1 == temp)
55755+ {
55756+ mvOsPrintf("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
55757+ return MV_ERROR;
55758+ }
55759+ MV_REG_WRITE(DRAM_BUF_REG3, temp);
55760+
55761+ /* calc SDRAM_ADDR_CTRL_REG and save it to temp register */
55762+ temp = sdramAddrCtrlRegCalc(&bankInfo[0]);
55763+ if(-1 == temp)
55764+ {
55765+ mvOsPrintf("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
55766+ return MV_ERROR;
55767+ }
55768+ MV_REG_WRITE(DRAM_BUF_REG4, temp);
55769+
55770+ /* calc SDRAM_TIMING_CTRL_LOW_REG and save it to temp register */
55771+ temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
55772+ if(-1 == temp)
55773+ {
55774+ mvOsPrintf("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
55775+ return MV_ERROR;
55776+ }
55777+ MV_REG_WRITE(DRAM_BUF_REG5, temp);
55778+
55779+ /* calc SDRAM_TIMING_CTRL_HIGH_REG and save it to temp register */
55780+ temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
55781+ if(-1 == temp)
55782+ {
55783+ mvOsPrintf("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
55784+ return MV_ERROR;
55785+ }
55786+ MV_REG_WRITE(DRAM_BUF_REG6, temp);
55787+
55788+ /* Config DDR2 On Die Termination (ODT) registers */
55789+ if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
55790+ {
55791+ sdramDDr2OdtConfig(bankInfo);
55792+ }
55793+
55794+ /* Note that DDR SDRAM Address/Control and Data pad calibration */
55795+ /* settings is done in mvSdramIfConfig.s */
55796+
55797+ return retVal;
55798+}
55799+
55800+/*******************************************************************************
55801+* minCasCalc - Calculate the Minimum CAS latency which can be used.
55802+*
55803+* DESCRIPTION:
55804+* Calculate the minimum CAS latency that can be used, base on the DRAM
55805+* parameters and the SDRAM bus Clock freq.
55806+*
55807+* INPUT:
55808+* busClk - the DRAM bus Clock.
55809+* pBankInfo - bank info parameters.
55810+*
55811+* OUTPUT:
55812+* None
55813+*
55814+* RETURN:
55815+* The minimum CAS Latency. The function returns 0 if max CAS latency
55816+* supported by banks is incompatible with system bus clock frequancy.
55817+*
55818+*******************************************************************************/
55819+static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk,
55820+ MV_U32 forcedCl)
55821+{
55822+ MV_U32 count = 1, j;
55823+ MV_U32 busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
55824+ MV_U32 startBit, stopBit;
55825+
55826+ /* DDR 1:
55827+ *******-******-******-******-******-******-******-*******
55828+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
55829+ *******-******-******-******-******-******-******-*******
55830+ CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
55831+ *********************************************************/
55832+
55833+ /* DDR 2:
55834+ *******-******-******-******-******-******-******-*******
55835+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
55836+ *******-******-******-******-******-******-******-*******
55837+ CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
55838+ *********************************************************/
55839+
55840+
55841+ /* If we are asked to use the forced CAL */
55842+ if (forcedCl)
55843+ {
55844+ mvOsPrintf("DRAM: Using forced CL %d.%d\n", (forcedCl / 10),
55845+ (forcedCl % 10));
55846+
55847+ if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
55848+ {
55849+ if (forcedCl == 30)
55850+ pBankInfo->suportedCasLatencies = 0x08;
55851+ else if (forcedCl == 40)
55852+ pBankInfo->suportedCasLatencies = 0x10;
55853+ else
55854+ {
55855+ mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n",
55856+ (forcedCl / 10), (forcedCl % 10));
55857+ pBankInfo->suportedCasLatencies = 0x10;
55858+ }
55859+ }
55860+ else
55861+ {
55862+ if (forcedCl == 15)
55863+ pBankInfo->suportedCasLatencies = 0x02;
55864+ else if (forcedCl == 20)
55865+ pBankInfo->suportedCasLatencies = 0x04;
55866+ else if (forcedCl == 25)
55867+ pBankInfo->suportedCasLatencies = 0x08;
55868+ else if (forcedCl == 30)
55869+ pBankInfo->suportedCasLatencies = 0x10;
55870+ else if (forcedCl == 40)
55871+ pBankInfo->suportedCasLatencies = 0x40;
55872+ else
55873+ {
55874+ mvOsPrintf("Forced CL %d.%d not supported. Set default CL 3\n",
55875+ (forcedCl / 10), (forcedCl % 10));
55876+ pBankInfo->suportedCasLatencies = 0x10;
55877+ }
55878+ }
55879+
55880+ return pBankInfo->suportedCasLatencies;
55881+ }
55882+
55883+ /* go over the supported cas mask from Max Cas down and check if the */
55884+ /* SysClk stands in its time requirments. */
55885+
55886+
55887+ DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
55888+ pBankInfo->suportedCasLatencies,busClkPs ));
55889+ for(j = 7; j > 0; j--)
55890+ {
55891+ if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
55892+ {
55893+ /* Reset the bits for CL incompatible for the sysClk */
55894+ switch (count)
55895+ {
55896+ case 1:
55897+ if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs)
55898+ pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
55899+ count++;
55900+ break;
55901+ case 2:
55902+ if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
55903+ pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
55904+ count++;
55905+ break;
55906+ case 3:
55907+ if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
55908+ pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
55909+ count++;
55910+ break;
55911+ default:
55912+ pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
55913+ break;
55914+ }
55915+ }
55916+ }
55917+
55918+ DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
55919+ pBankInfo->suportedCasLatencies ));
55920+
55921+ /* SDRAM DDR1 controller supports CL 1.5 to 3.5 */
55922+ /* SDRAM DDR2 controller supports CL 3 to 5 */
55923+ if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
55924+ {
55925+ startBit = 3; /* DDR2 support CL start with CL3 (bit 3) */
55926+ stopBit = 5; /* DDR2 support CL stops with CL5 (bit 5) */
55927+ }
55928+ else
55929+ {
55930+ startBit = 1; /* DDR1 support CL start with CL1.5 (bit 3) */
55931+ stopBit = 4; /* DDR1 support CL stops with CL3 (bit 4) */
55932+ }
55933+
55934+ for(j = startBit; j <= stopBit ; j++)
55935+ {
55936+ if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
55937+ {
55938+ DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
55939+ return (BIT0 << j);
55940+ }
55941+ }
55942+
55943+ return 0;
55944+}
55945+
55946+/*******************************************************************************
55947+* sdramConfigRegCalc - Calculate sdram config register
55948+*
55949+* DESCRIPTION: Calculate sdram config register optimized value based
55950+* on the bank info parameters.
55951+*
55952+* INPUT:
55953+* pBankInfo - sdram bank parameters
55954+*
55955+* OUTPUT:
55956+* None
55957+*
55958+* RETURN:
55959+* sdram config reg value.
55960+*
55961+*******************************************************************************/
55962+static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
55963+{
55964+ MV_U32 sdramConfig = 0;
55965+ MV_U32 refreshPeriod;
55966+
55967+ busClk /= 1000000; /* we work with busClk in MHz */
55968+
55969+ sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
55970+
55971+ /* figure out the memory refresh internal */
55972+ switch (pBankInfo->refreshInterval & 0xf)
55973+ {
55974+ case 0x0: /* refresh period is 15.625 usec */
55975+ refreshPeriod = 15625;
55976+ break;
55977+ case 0x1: /* refresh period is 3.9 usec */
55978+ refreshPeriod = 3900;
55979+ break;
55980+ case 0x2: /* refresh period is 7.8 usec */
55981+ refreshPeriod = 7800;
55982+ break;
55983+ case 0x3: /* refresh period is 31.3 usec */
55984+ refreshPeriod = 31300;
55985+ break;
55986+ case 0x4: /* refresh period is 62.5 usec */
55987+ refreshPeriod = 62500;
55988+ break;
55989+ case 0x5: /* refresh period is 125 usec */
55990+ refreshPeriod = 125000;
55991+ break;
55992+ default: /* refresh period undefined */
55993+ mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
55994+ return -1;
55995+ }
55996+
55997+ /* Now the refreshPeriod is in register format value */
55998+ refreshPeriod = (busClk * refreshPeriod) / 1000;
55999+
56000+ DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n",
56001+ refreshPeriod));
56002+
56003+ /* make sure the refresh value is only 14 bits */
56004+ if(refreshPeriod > SDRAM_REFRESH_MAX)
56005+ {
56006+ refreshPeriod = SDRAM_REFRESH_MAX;
56007+ DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n",
56008+ refreshPeriod));
56009+ }
56010+
56011+ /* Clear the refresh field */
56012+ sdramConfig &= ~SDRAM_REFRESH_MASK;
56013+
56014+ /* Set new value to refresh field */
56015+ sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
56016+
56017+ /* registered DRAM ? */
56018+ if ( pBankInfo->registeredAddrAndControlInputs )
56019+ {
56020+ /* it's registered DRAM, so set the reg. DRAM bit */
56021+ sdramConfig |= SDRAM_REGISTERED;
56022+ mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");
56023+ }
56024+
56025+ /* set DDR SDRAM devices configuration */
56026+ sdramConfig &= ~SDRAM_DCFG_MASK; /* Clear Dcfg field */
56027+
56028+ switch (pBankInfo->sdramWidth)
56029+ {
56030+ case 8: /* memory is x8 */
56031+ sdramConfig |= SDRAM_DCFG_X8_DEV;
56032+ DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x8\n"));
56033+ break;
56034+ case 16:
56035+ sdramConfig |= SDRAM_DCFG_X16_DEV;
56036+ DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x16\n"));
56037+ break;
56038+ default: /* memory width unsupported */
56039+ mvOsPrintf("Dram: ERR. DRAM chip width is unknown!\n");
56040+ return -1;
56041+ }
56042+
56043+ /* Set static default settings */
56044+ sdramConfig |= SDRAM_CONFIG_DV;
56045+
56046+ DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
56047+ sdramConfig));
56048+
56049+ return sdramConfig;
56050+}
56051+
56052+/*******************************************************************************
56053+* sdramModeRegCalc - Calculate sdram mode register
56054+*
56055+* DESCRIPTION: Calculate sdram mode register optimized value based
56056+* on the bank info parameters and the minCas.
56057+*
56058+* INPUT:
56059+* minCas - minimum CAS supported.
56060+*
56061+* OUTPUT:
56062+* None
56063+*
56064+* RETURN:
56065+* sdram mode reg value.
56066+*
56067+*******************************************************************************/
56068+static MV_U32 sdramModeRegCalc(MV_U32 minCas)
56069+{
56070+ MV_U32 sdramMode;
56071+
56072+ sdramMode = MV_REG_READ(SDRAM_MODE_REG);
56073+
56074+ /* Clear CAS Latency field */
56075+ sdramMode &= ~SDRAM_CL_MASK;
56076+
56077+ mvOsPrintf("DRAM CAS Latency ");
56078+
56079+ if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
56080+ {
56081+ switch (minCas)
56082+ {
56083+ case DDR2_CL_3:
56084+ sdramMode |= SDRAM_DDR2_CL_3;
56085+ mvOsPrintf("3.\n");
56086+ break;
56087+ case DDR2_CL_4:
56088+ sdramMode |= SDRAM_DDR2_CL_4;
56089+ mvOsPrintf("4.\n");
56090+ break;
56091+ case DDR2_CL_5:
56092+ sdramMode |= SDRAM_DDR2_CL_5;
56093+ mvOsPrintf("5.\n");
56094+ break;
56095+ default:
56096+ mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
56097+ return -1;
56098+ }
56099+ sdramMode |= DDR2_MODE_REG_DV;
56100+ }
56101+ else /* DDR1 */
56102+ {
56103+ switch (minCas)
56104+ {
56105+ case DDR1_CL_1_5:
56106+ sdramMode |= SDRAM_DDR1_CL_1_5;
56107+ mvOsPrintf("1.5\n");
56108+ break;
56109+ case DDR1_CL_2:
56110+ sdramMode |= SDRAM_DDR1_CL_2;
56111+ mvOsPrintf("2\n");
56112+ break;
56113+ case DDR1_CL_2_5:
56114+ sdramMode |= SDRAM_DDR1_CL_2_5;
56115+ mvOsPrintf("2.5\n");
56116+ break;
56117+ case DDR1_CL_3:
56118+ sdramMode |= SDRAM_DDR1_CL_3;
56119+ mvOsPrintf("3\n");
56120+ break;
56121+ case DDR1_CL_4:
56122+ sdramMode |= SDRAM_DDR1_CL_4;
56123+ mvOsPrintf("4\n");
56124+ break;
56125+ default:
56126+ mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
56127+ return -1;
56128+ }
56129+ sdramMode |= DDR1_MODE_REG_DV;
56130+ }
56131+
56132+ DB(mvOsPrintf("nsdramModeRegCalc register 0x%x\n", sdramMode ));
56133+
56134+ return sdramMode;
56135+}
56136+
56137+/*******************************************************************************
56138+* sdramExtModeRegCalc - Calculate sdram Extended mode register
56139+*
56140+* DESCRIPTION:
56141+* Return sdram Extended mode register value based
56142+* on the bank info parameters and bank presence.
56143+*
56144+* INPUT:
56145+* pBankInfo - sdram bank parameters
56146+*
56147+* OUTPUT:
56148+* None
56149+*
56150+* RETURN:
56151+* sdram Extended mode reg value.
56152+*
56153+*******************************************************************************/
56154+static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
56155+{
56156+ MV_U32 populateBanks = 0;
56157+ int bankNum;
56158+ if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
56159+ {
56160+ /* Represent the populate banks in binary form */
56161+ for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
56162+ {
56163+ if (0 != pBankInfo[bankNum].size)
56164+ {
56165+ populateBanks |= (1 << bankNum);
56166+ }
56167+ }
56168+
56169+ switch(populateBanks)
56170+ {
56171+ case(BANK_PRESENT_CS0):
56172+ return DDR_SDRAM_EXT_MODE_CS0_DV;
56173+
56174+ case(BANK_PRESENT_CS0_CS1):
56175+ return DDR_SDRAM_EXT_MODE_CS0_DV;
56176+
56177+ case(BANK_PRESENT_CS0_CS2):
56178+ return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
56179+
56180+ case(BANK_PRESENT_CS0_CS1_CS2):
56181+ return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
56182+
56183+ case(BANK_PRESENT_CS0_CS2_CS3):
56184+ return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
56185+
56186+ case(BANK_PRESENT_CS0_CS2_CS3_CS4):
56187+ return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
56188+
56189+ default:
56190+ mvOsPrintf("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
56191+ return -1;
56192+ }
56193+ }
56194+ return 0;
56195+}
56196+
56197+/*******************************************************************************
56198+* dunitCtrlLowRegCalc - Calculate sdram dunit control low register
56199+*
56200+* DESCRIPTION: Calculate sdram dunit control low register optimized value based
56201+* on the bank info parameters and the minCas.
56202+*
56203+* INPUT:
56204+* pBankInfo - sdram bank parameters
56205+* minCas - minimum CAS supported.
56206+*
56207+* OUTPUT:
56208+* None
56209+*
56210+* RETURN:
56211+* sdram dunit control low reg value.
56212+*
56213+*******************************************************************************/
56214+static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas)
56215+{
56216+ MV_U32 dunitCtrlLow;
56217+
56218+ dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
56219+
56220+ /* Clear StBurstDel field */
56221+ dunitCtrlLow &= ~SDRAM_ST_BURST_DEL_MASK;
56222+
56223+#ifdef MV_88W8660
56224+ /* Clear address/control output timing field */
56225+ dunitCtrlLow &= ~SDRAM_CTRL_POS_RISE;
56226+#endif /* MV_88W8660 */
56227+
56228+ DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
56229+
56230+ /* For proper sample of read data set the Dunit Control register's */
56231+ /* stBurstDel bits [27:24] */
56232+ /********-********-********-********-********-*********
56233+ * CL=1.5 | CL=2 | CL=2.5 | CL=3 | CL=4 | CL=5 *
56234+ *********-********-********-********-********-*********
56235+Not Reg. * 0011 | 0011 | 0100 | 0100 | 0101 | TBD *
56236+ *********-********-********-********-********-*********
56237+Registered * 0100 | 0100 | 0101 | 0101 | 0110 | TBD *
56238+ *********-********-********-********-********-*********/
56239+
56240+ if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
56241+ {
56242+ switch (minCas)
56243+ {
56244+ case DDR2_CL_3:
56245+ /* registerd DDR SDRAM? */
56246+ if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
56247+ dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
56248+ else
56249+ dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
56250+ break;
56251+ case DDR2_CL_4:
56252+ /* registerd DDR SDRAM? */
56253+ if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
56254+ dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
56255+ else
56256+ dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
56257+ break;
56258+ default:
56259+ mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n",
56260+ minCas);
56261+ return -1;
56262+ }
56263+ }
56264+ else /* DDR1 */
56265+ {
56266+ switch (minCas)
56267+ {
56268+ case DDR1_CL_1_5:
56269+ /* registerd DDR SDRAM? */
56270+ if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
56271+ dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
56272+ else
56273+ dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
56274+ break;
56275+ case DDR1_CL_2:
56276+ /* registerd DDR SDRAM? */
56277+ if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
56278+ dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
56279+ else
56280+ dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
56281+ break;
56282+ case DDR1_CL_2_5:
56283+ /* registerd DDR SDRAM? */
56284+ if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
56285+ dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
56286+ else
56287+ dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
56288+ break;
56289+ case DDR1_CL_3:
56290+ /* registerd DDR SDRAM? */
56291+ if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
56292+ dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
56293+ else
56294+ dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
56295+ break;
56296+ case DDR1_CL_4:
56297+ /* registerd DDR SDRAM? */
56298+ if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
56299+ dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
56300+ else
56301+ dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
56302+ break;
56303+ default:
56304+ mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n",
56305+ minCas);
56306+ return -1;
56307+ }
56308+
56309+ }
56310+ DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
56311+
56312+ return dunitCtrlLow;
56313+}
56314+
56315+/*******************************************************************************
56316+* sdramAddrCtrlRegCalc - Calculate sdram address control register
56317+*
56318+* DESCRIPTION: Calculate sdram address control register optimized value based
56319+* on the bank info parameters and the minCas.
56320+*
56321+* INPUT:
56322+* pBankInfo - sdram bank parameters
56323+*
56324+* OUTPUT:
56325+* None
56326+*
56327+* RETURN:
56328+* sdram address control reg value.
56329+*
56330+*******************************************************************************/
56331+static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
56332+{
56333+ MV_U32 addrCtrl = 0;
56334+
56335+ /* Set Address Control register static configuration bits */
56336+ addrCtrl = MV_REG_READ(SDRAM_ADDR_CTRL_REG);
56337+
56338+ /* Set address control default value */
56339+ addrCtrl |= SDRAM_ADDR_CTRL_DV;
56340+
56341+ /* Clear DSize field */
56342+ addrCtrl &= ~SDRAM_DSIZE_MASK;
56343+
56344+ /* Note that density is in MB units */
56345+ switch (pBankInfo->deviceDensity)
56346+ {
56347+ case 128: /* 128 Mbit */
56348+ DB(mvOsPrintf("DRAM Device Density 128Mbit\n"));
56349+ addrCtrl |= SDRAM_DSIZE_128Mb;
56350+ break;
56351+ case 256: /* 256 Mbit */
56352+ DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
56353+ addrCtrl |= SDRAM_DSIZE_256Mb;
56354+ break;
56355+ case 512: /* 512 Mbit */
56356+ DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
56357+ addrCtrl |= SDRAM_DSIZE_512Mb;
56358+ break;
56359+ default:
56360+ mvOsPrintf("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
56361+ pBankInfo->deviceDensity);
56362+ return -1;
56363+ }
56364+
56365+ /* SDRAM address control */
56366+ DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
56367+
56368+ return addrCtrl;
56369+}
56370+
56371+/*******************************************************************************
56372+* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
56373+*
56374+* DESCRIPTION:
56375+* This function calculates sdram timing control low register
56376+* optimized value based on the bank info parameters and the minCas.
56377+*
56378+* INPUT:
56379+* pBankInfo - sdram bank parameters
56380+* busClk - Bus clock
56381+*
56382+* OUTPUT:
56383+* None
56384+*
56385+* RETURN:
56386+* sdram timinf control low reg value.
56387+*
56388+*******************************************************************************/
56389+static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
56390+ MV_U32 minCas, MV_U32 busClk)
56391+{
56392+ MV_U32 tRp = 0;
56393+ MV_U32 tRrd = 0;
56394+ MV_U32 tRcd = 0;
56395+ MV_U32 tRas = 0;
56396+ MV_U32 tWr = 0;
56397+ MV_U32 tWtr = 0;
56398+ MV_U32 tRtp = 0;
56399+
56400+ MV_U32 bankNum;
56401+
56402+ busClk = busClk / 1000000; /* In MHz */
56403+
56404+ /* Scan all DRAM banks to find maximum timing values */
56405+ for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
56406+ {
56407+ tRp = MV_MAX(tRp, pBankInfo[bankNum].minRowPrechargeTime);
56408+ tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
56409+ tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
56410+ tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
56411+ }
56412+
56413+ /* Extract timing (in ns) from SPD value. We ignore the tenth ns part. */
56414+ /* by shifting the data two bits right. */
56415+ tRp = tRp >> 2; /* For example 0x50 -> 20ns */
56416+ tRrd = tRrd >> 2;
56417+ tRcd = tRcd >> 2;
56418+
56419+ /* Extract clock cycles from time parameter. We need to round up */
56420+ tRp = ((busClk * tRp) / 1000) + (((busClk * tRp) % 1000) ? 1 : 0);
56421+ /* Micron work around for 133MHz */
56422+ if (busClk == 133)
56423+ tRp += 1;
56424+ DB(mvOsPrintf("Dram Timing Low: tRp = %d ", tRp));
56425+ tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
56426+ /* JEDEC min reqeirments tRrd = 2 */
56427+ if (tRrd < 2)
56428+ tRrd = 2;
56429+ DB(mvOsPrintf("tRrd = %d ", tRrd));
56430+ tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
56431+ DB(mvOsPrintf("tRcd = %d ", tRcd));
56432+ tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
56433+ DB(mvOsPrintf("tRas = %d ", tRas));
56434+
56435+ /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2 */
56436+ if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
56437+ {
56438+ /* Scan all DRAM banks to find maximum timing values */
56439+ for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
56440+ {
56441+ tWr = MV_MAX(tWr, pBankInfo[bankNum].minWriteRecoveryTime);
56442+ tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
56443+ tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
56444+ }
56445+
56446+ /* Extract timing (in ns) from SPD value. We ignore the tenth ns */
56447+ /* part by shifting the data two bits right. */
56448+ tWr = tWr >> 2; /* For example 0x50 -> 20ns */
56449+ tWtr = tWtr >> 2;
56450+ tRtp = tRtp >> 2;
56451+
56452+ /* Extract clock cycles from time parameter. We need to round up */
56453+ tWr = ((busClk * tWr) / 1000) + (((busClk * tWr) % 1000) ? 1 : 0);
56454+ DB(mvOsPrintf("tWr = %d ", tWr));
56455+ tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
56456+ /* JEDEC min reqeirments tWtr = 2 */
56457+ if (tWtr < 2)
56458+ tWtr = 2;
56459+ DB(mvOsPrintf("tWtr = %d ", tWtr));
56460+ tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
56461+ /* JEDEC min reqeirments tRtp = 2 */
56462+ if (tRtp < 2)
56463+ tRtp = 2;
56464+ DB(mvOsPrintf("tRtp = %d ", tRtp));
56465+ }
56466+ else
56467+ {
56468+ tWr = ((busClk*SDRAM_TWR) / 1000) + (((busClk*SDRAM_TWR) % 1000)?1:0);
56469+
56470+ if ((200 == busClk) || ((100 == busClk) && (DDR1_CL_1_5 == minCas)))
56471+ {
56472+ tWtr = 2;
56473+ }
56474+ else
56475+ {
56476+ tWtr = 1;
56477+ }
56478+
56479+ tRtp = 2; /* Must be set to 0x1 (two cycles) when using DDR1 */
56480+ }
56481+
56482+ DB(mvOsPrintf("tWtr = %d\n", tWtr));
56483+
56484+ /* Note: value of 0 in register means one cycle, 1 means two and so on */
56485+ return (((tRp - 1) << SDRAM_TRP_OFFS) |
56486+ ((tRrd - 1) << SDRAM_TRRD_OFFS) |
56487+ ((tRcd - 1) << SDRAM_TRCD_OFFS) |
56488+ ((tRas - 1) << SDRAM_TRAS_OFFS) |
56489+ ((tWr - 1) << SDRAM_TWR_OFFS) |
56490+ ((tWtr - 1) << SDRAM_TWTR_OFFS) |
56491+ ((tRtp - 1) << SDRAM_TRTP_OFFS));
56492+}
56493+
56494+/*******************************************************************************
56495+* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
56496+*
56497+* DESCRIPTION:
56498+* This function calculates sdram timing control high register
56499+* optimized value based on the bank info parameters and the bus clock.
56500+*
56501+* INPUT:
56502+* pBankInfo - sdram bank parameters
56503+* busClk - Bus clock
56504+*
56505+* OUTPUT:
56506+* None
56507+*
56508+* RETURN:
56509+* sdram timinf control high reg value.
56510+*
56511+*******************************************************************************/
56512+static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
56513+ MV_U32 busClk)
56514+{
56515+ MV_U32 tRfc;
56516+ MV_U32 timeNs = 0;
56517+ int bankNum;
56518+ MV_U32 sdramTw2wCyc = 0;
56519+
56520+ busClk = busClk / 1000000; /* In MHz */
56521+
56522+ /* tRfc is different for DDR1 and DDR2. */
56523+ if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
56524+ {
56525+ MV_U32 bankNum;
56526+
56527+ /* Scan all DRAM banks to find maximum timing values */
56528+ for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
56529+ timeNs = MV_MAX(timeNs, pBankInfo[bankNum].minRefreshToActiveCmd);
56530+ }
56531+ else
56532+ {
56533+ if (pBankInfo[0].deviceDensity == _1G)
56534+ {
56535+ timeNs = SDRAM_TRFC_1G;
56536+ }
56537+ else
56538+ {
56539+ if (200 == busClk)
56540+ {
56541+ timeNs = SDRAM_TRFC_64_512M_AT_200MHZ;
56542+ }
56543+ else
56544+ {
56545+ timeNs = SDRAM_TRFC_64_512M;
56546+ }
56547+ }
56548+ }
56549+
56550+ tRfc = ((busClk * timeNs) / 1000) + (((busClk * timeNs) % 1000) ? 1 : 0);
56551+
56552+ DB(mvOsPrintf("Dram Timing High: tRfc = %d\n", tRfc));
56553+
56554+
56555+ /* Represent the populate banks in binary form */
56556+ for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
56557+ {
56558+ if (0 != pBankInfo[bankNum].size)
56559+ sdramTw2wCyc++;
56560+ }
56561+
56562+ /* If we have more the 1 bank then we need the TW2W in 1 for ODT switch */
56563+ if (sdramTw2wCyc > 1)
56564+ sdramTw2wCyc = 1;
56565+ else
56566+ sdramTw2wCyc = 0;
56567+
56568+ /* Note: value of 0 in register means one cycle, 1 means two and so on */
56569+ return ((((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS) |
56570+ ((SDRAM_TR2R_CYC - 1) << SDRAM_TR2R_OFFS) |
56571+ ((SDRAM_TR2WW2R_CYC - 1) << SDRAM_TR2W_W2R_OFFS) |
56572+ (((tRfc - 1) >> 4) << SDRAM_TRFC_EXT_OFFS) |
56573+ (sdramTw2wCyc << SDRAM_TW2W_OFFS));
56574+
56575+}
56576+
56577+/*******************************************************************************
56578+* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
56579+*
56580+* DESCRIPTION:
56581+* This function config DDR2 On Die Termination (ODT) registers.
56582+* ODT configuration is done according to DIMM presence:
56583+*
56584+* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode
56585+* CS0 0x84210000 0x00000000 0x0000780F 0x00000440
56586+* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440
56587+* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404
56588+* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404
56589+* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404
56590+* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404
56591+*
56592+* INPUT:
56593+* pBankInfo - bank info parameters.
56594+*
56595+* OUTPUT:
56596+* None
56597+*
56598+* RETURN:
56599+* None
56600+*******************************************************************************/
56601+static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
56602+{
56603+ MV_U32 populateBanks = 0;
56604+ MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
56605+ int bankNum;
56606+
56607+ /* Represent the populate banks in binary form */
56608+ for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
56609+ {
56610+ if (0 != pBankInfo[bankNum].size)
56611+ {
56612+ populateBanks |= (1 << bankNum);
56613+ }
56614+ }
56615+
56616+ switch(populateBanks)
56617+ {
56618+ case(BANK_PRESENT_CS0):
56619+ odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_DV;
56620+ odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_DV;
56621+ dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
56622+ break;
56623+ case(BANK_PRESENT_CS0_CS1):
56624+ odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_DV;
56625+ odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_DV;
56626+ dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
56627+ break;
56628+ case(BANK_PRESENT_CS0_CS2):
56629+ odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
56630+ odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
56631+ dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
56632+ break;
56633+ case(BANK_PRESENT_CS0_CS1_CS2):
56634+ odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
56635+ odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
56636+ dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
56637+ break;
56638+ case(BANK_PRESENT_CS0_CS2_CS3):
56639+ odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
56640+ odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
56641+ dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
56642+ break;
56643+ case(BANK_PRESENT_CS0_CS2_CS3_CS4):
56644+ odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
56645+ odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
56646+ dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
56647+ break;
56648+ default:
56649+ mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n");
56650+ return;
56651+ }
56652+ MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
56653+ MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
56654+ MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
56655+ return;
56656+}
56657+#endif /* defined(MV_INC_BOARD_DDIM) */
56658+
56659+/*******************************************************************************
56660+* mvDramIfWinSet - Set DRAM interface address decode window
56661+*
56662+* DESCRIPTION:
56663+* This function sets DRAM interface address decode window.
56664+*
56665+* INPUT:
56666+* target - System target. Use only SDRAM targets.
56667+* pAddrDecWin - SDRAM address window structure.
56668+*
56669+* OUTPUT:
56670+* None
56671+*
56672+* RETURN:
56673+* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
56674+* otherwise.
56675+*******************************************************************************/
56676+MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
56677+{
56678+ MV_U32 baseReg=0,sizeReg=0;
56679+ MV_U32 baseToReg=0 , sizeToReg=0;
56680+
56681+ /* Check parameters */
56682+ if (!MV_TARGET_IS_DRAM(target))
56683+ {
56684+ mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
56685+ return MV_BAD_PARAM;
56686+ }
56687+
56688+ /* Check if the requested window overlaps with current enabled windows */
56689+ if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
56690+ {
56691+ mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
56692+ return MV_BAD_PARAM;
56693+ }
56694+
56695+ /* check if address is aligned to the size */
56696+ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
56697+ {
56698+ mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
56699+ "\nAddress 0x%08x is unaligned to size 0x%x.\n",
56700+ target,
56701+ pAddrDecWin->addrWin.baseLow,
56702+ pAddrDecWin->addrWin.size);
56703+ return MV_ERROR;
56704+ }
56705+
56706+ /* read base register*/
56707+ baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
56708+
56709+ /* read size register */
56710+ sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
56711+
56712+ /* BaseLow[31:16] => base register [31:16] */
56713+ baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;
56714+
56715+ /* Write to address decode Base Address Register */
56716+ baseReg &= ~SCBAR_BASE_MASK;
56717+ baseReg |= baseToReg;
56718+
56719+ /* Translate the given window size to register format */
56720+ sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);
56721+
56722+ /* Size parameter validity check. */
56723+ if (-1 == sizeToReg)
56724+ {
56725+ mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
56726+ return MV_BAD_PARAM;
56727+ }
56728+
56729+ /* set size */
56730+ sizeReg &= ~SCSR_SIZE_MASK;
56731+ /* Size is located at upper 16 bits */
56732+ sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);
56733+
56734+ /* enable/Disable */
56735+ if (MV_TRUE == pAddrDecWin->enable)
56736+ {
56737+ sizeReg |= SCSR_WIN_EN;
56738+ }
56739+ else
56740+ {
56741+ sizeReg &= ~SCSR_WIN_EN;
56742+ }
56743+
56744+ /* 3) Write to address decode Base Address Register */
56745+ MV_REG_WRITE(SDRAM_BASE_ADDR_REG(target), baseReg);
56746+
56747+ /* Write to address decode Size Register */
56748+ MV_REG_WRITE(SDRAM_SIZE_REG(target), sizeReg);
56749+
56750+ return MV_OK;
56751+}
56752+/*******************************************************************************
56753+* mvDramIfWinGet - Get DRAM interface address decode window
56754+*
56755+* DESCRIPTION:
56756+* This function gets DRAM interface address decode window.
56757+*
56758+* INPUT:
56759+* target - System target. Use only SDRAM targets.
56760+*
56761+* OUTPUT:
56762+* pAddrDecWin - SDRAM address window structure.
56763+*
56764+* RETURN:
56765+* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
56766+* otherwise.
56767+*******************************************************************************/
56768+MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
56769+{
56770+ MV_U32 baseReg,sizeReg;
56771+ MV_U32 sizeRegVal;
56772+
56773+ /* Check parameters */
56774+ if (!MV_TARGET_IS_DRAM(target))
56775+ {
56776+ mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);
56777+ return MV_ERROR;
56778+ }
56779+
56780+ /* Read base and size registers */
56781+ sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
56782+ baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
56783+
56784+ sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;
56785+
56786+ pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,
56787+ SCSR_SIZE_ALIGNMENT);
56788+
56789+ /* Check if ctrlRegToSize returned OK */
56790+ if (-1 == pAddrDecWin->addrWin.size)
56791+ {
56792+ mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);
56793+ return MV_ERROR;
56794+ }
56795+
56796+ /* Extract base address */
56797+ /* Base register [31:16] ==> baseLow[31:16] */
56798+ pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;
56799+
56800+ pAddrDecWin->addrWin.baseHigh = 0;
56801+
56802+
56803+ if (sizeReg & SCSR_WIN_EN)
56804+ {
56805+ pAddrDecWin->enable = MV_TRUE;
56806+ }
56807+ else
56808+ {
56809+ pAddrDecWin->enable = MV_FALSE;
56810+ }
56811+
56812+ return MV_OK;
56813+}
56814+/*******************************************************************************
56815+* mvDramIfWinEnable - Enable/Disable SDRAM address decode window
56816+*
56817+* DESCRIPTION:
56818+* This function enable/Disable SDRAM address decode window.
56819+*
56820+* INPUT:
56821+* target - System target. Use only SDRAM targets.
56822+*
56823+* OUTPUT:
56824+* None.
56825+*
56826+* RETURN:
56827+* MV_ERROR in case function parameter are invalid, MV_OK otherewise.
56828+*
56829+*******************************************************************************/
56830+MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable)
56831+{
56832+ MV_DRAM_DEC_WIN addrDecWin;
56833+
56834+ /* Check parameters */
56835+ if (!MV_TARGET_IS_DRAM(target))
56836+ {
56837+ mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
56838+ return MV_ERROR;
56839+ }
56840+
56841+ if (enable == MV_TRUE)
56842+ { /* First check for overlap with other enabled windows */
56843+ if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
56844+ {
56845+ mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n",
56846+ target);
56847+ return MV_ERROR;
56848+ }
56849+ /* Check for overlapping */
56850+ if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
56851+ {
56852+ /* No Overlap. Enable address decode winNum window */
56853+ MV_REG_BIT_SET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
56854+ }
56855+ else
56856+ { /* Overlap detected */
56857+ mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
56858+ target);
56859+ return MV_ERROR;
56860+ }
56861+ }
56862+ else
56863+ { /* Disable address decode winNum window */
56864+ MV_REG_BIT_RESET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
56865+ }
56866+
56867+ return MV_OK;
56868+}
56869+
56870+/*******************************************************************************
56871+* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window
56872+*
56873+* DESCRIPTION:
56874+* This function scan each SDRAM address decode window to test if it
56875+* overlapps the given address windoow
56876+*
56877+* INPUT:
56878+* target - SDRAM target where the function skips checking.
56879+* pAddrDecWin - The tested address window for overlapping with
56880+* SDRAM windows.
56881+*
56882+* OUTPUT:
56883+* None.
56884+*
56885+* RETURN:
56886+* MV_TRUE if the given address window overlaps any enabled address
56887+* decode map, MV_FALSE otherwise.
56888+*
56889+*******************************************************************************/
56890+static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
56891+{
56892+ MV_TARGET targetNum;
56893+ MV_DRAM_DEC_WIN addrDecWin;
56894+
56895+ for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)
56896+ {
56897+ /* don't check our winNum or illegal targets */
56898+ if (targetNum == target)
56899+ {
56900+ continue;
56901+ }
56902+
56903+ /* Get window parameters */
56904+ if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))
56905+ {
56906+ mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
56907+ return MV_ERROR;
56908+ }
56909+
56910+ /* Do not check disabled windows */
56911+ if (MV_FALSE == addrDecWin.enable)
56912+ {
56913+ continue;
56914+ }
56915+
56916+ if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
56917+ {
56918+ mvOsPrintf(
56919+ "sdramIfWinOverlap: Required target %d overlap winNum %d\n",
56920+ target, targetNum);
56921+ return MV_TRUE;
56922+ }
56923+ }
56924+
56925+ return MV_FALSE;
56926+}
56927+
56928+/*******************************************************************************
56929+* mvDramIfBankSizeGet - Get DRAM interface bank size.
56930+*
56931+* DESCRIPTION:
56932+* This function returns the size of a given DRAM bank.
56933+*
56934+* INPUT:
56935+* bankNum - Bank number.
56936+*
56937+* OUTPUT:
56938+* None.
56939+*
56940+* RETURN:
56941+* DRAM bank size. If bank is disabled the function return '0'. In case
56942+* or paramter is invalid, the function returns -1.
56943+*
56944+*******************************************************************************/
56945+MV_32 mvDramIfBankSizeGet(MV_U32 bankNum)
56946+{
56947+ MV_DRAM_DEC_WIN addrDecWin;
56948+
56949+ /* Check parameters */
56950+ if (!MV_TARGET_IS_DRAM(bankNum))
56951+ {
56952+ mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
56953+ return -1;
56954+ }
56955+ /* Get window parameters */
56956+ if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
56957+ {
56958+ mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
56959+ return -1;
56960+ }
56961+
56962+ if (MV_TRUE == addrDecWin.enable)
56963+ {
56964+ return addrDecWin.addrWin.size;
56965+ }
56966+ else
56967+ {
56968+ return 0;
56969+ }
56970+}
56971+
56972+
56973+/*******************************************************************************
56974+* mvDramIfSizeGet - Get DRAM interface total size.
56975+*
56976+* DESCRIPTION:
56977+* This function get the DRAM total size.
56978+*
56979+* INPUT:
56980+* None.
56981+*
56982+* OUTPUT:
56983+* None.
56984+*
56985+* RETURN:
56986+* DRAM total size. In case or paramter is invalid, the function
56987+* returns -1.
56988+*
56989+*******************************************************************************/
56990+MV_32 mvDramIfSizeGet(MV_VOID)
56991+{
56992+ MV_U32 totalSize = 0, bankSize = 0, bankNum;
56993+
56994+ for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
56995+ {
56996+ bankSize = mvDramIfBankSizeGet(bankNum);
56997+
56998+ if (-1 == bankSize)
56999+ {
57000+ mvOsPrintf("Dram: mvDramIfSizeGet error with bank %d \n",bankNum);
57001+ return -1;
57002+ }
57003+ else
57004+ {
57005+ totalSize += bankSize;
57006+ }
57007+ }
57008+
57009+ DB(mvOsPrintf("Dram: Total DRAM size is 0x%x \n",totalSize));
57010+
57011+ return totalSize;
57012+}
57013+
57014+/*******************************************************************************
57015+* mvDramIfBankBaseGet - Get DRAM interface bank base.
57016+*
57017+* DESCRIPTION:
57018+* This function returns the 32 bit base address of a given DRAM bank.
57019+*
57020+* INPUT:
57021+* bankNum - Bank number.
57022+*
57023+* OUTPUT:
57024+* None.
57025+*
57026+* RETURN:
57027+* DRAM bank size. If bank is disabled or paramter is invalid, the
57028+* function returns -1.
57029+*
57030+*******************************************************************************/
57031+MV_32 mvDramIfBankBaseGet(MV_U32 bankNum)
57032+{
57033+ MV_DRAM_DEC_WIN addrDecWin;
57034+
57035+ /* Check parameters */
57036+ if (!MV_TARGET_IS_DRAM(bankNum))
57037+ {
57038+ mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
57039+ return -1;
57040+ }
57041+ /* Get window parameters */
57042+ if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
57043+ {
57044+ mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
57045+ return -1;
57046+ }
57047+
57048+ if (MV_TRUE == addrDecWin.enable)
57049+ {
57050+ return addrDecWin.addrWin.baseLow;
57051+ }
57052+ else
57053+ {
57054+ return -1;
57055+ }
57056+}
57057+
57058+
57059diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h
57060new file mode 100644
57061index 0000000..8ae67e7
57062--- /dev/null
57063+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h
57064@@ -0,0 +1,179 @@
57065+/*******************************************************************************
57066+Copyright (C) Marvell International Ltd. and its affiliates
57067+
57068+This software file (the "File") is owned and distributed by Marvell
57069+International Ltd. and/or its affiliates ("Marvell") under the following
57070+alternative licensing terms. Once you have made an election to distribute the
57071+File under one of the following license alternatives, please (i) delete this
57072+introductory statement regarding license alternatives, (ii) delete the two
57073+license alternatives that you have not elected to use and (iii) preserve the
57074+Marvell copyright notice above.
57075+
57076+********************************************************************************
57077+Marvell Commercial License Option
57078+
57079+If you received this File from Marvell and you have entered into a commercial
57080+license agreement (a "Commercial License") with Marvell, the File is licensed
57081+to you under the terms of the applicable Commercial License.
57082+
57083+********************************************************************************
57084+Marvell GPL License Option
57085+
57086+If you received this File from Marvell, you may opt to use, redistribute and/or
57087+modify this File in accordance with the terms and conditions of the General
57088+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
57089+available along with the File in the license.txt file or by writing to the Free
57090+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
57091+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
57092+
57093+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
57094+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
57095+DISCLAIMED. The GPL License provides additional details about this warranty
57096+disclaimer.
57097+********************************************************************************
57098+Marvell BSD License Option
57099+
57100+If you received this File from Marvell, you may opt to use, redistribute and/or
57101+modify this File under the following licensing terms.
57102+Redistribution and use in source and binary forms, with or without modification,
57103+are permitted provided that the following conditions are met:
57104+
57105+ * Redistributions of source code must retain the above copyright notice,
57106+ this list of conditions and the following disclaimer.
57107+
57108+ * Redistributions in binary form must reproduce the above copyright
57109+ notice, this list of conditions and the following disclaimer in the
57110+ documentation and/or other materials provided with the distribution.
57111+
57112+ * Neither the name of Marvell nor the names of its contributors may be
57113+ used to endorse or promote products derived from this software without
57114+ specific prior written permission.
57115+
57116+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
57117+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
57118+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
57119+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
57120+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57121+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57122+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
57123+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57124+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
57125+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57126+
57127+*******************************************************************************/
57128+
57129+
57130+#ifndef __INCmvDramIfh
57131+#define __INCmvDramIfh
57132+
57133+/* includes */
57134+#include "ddr1_2/mvDramIfRegs.h"
57135+#include "ddr1_2/mvDramIfConfig.h"
57136+#include "ctrlEnv/mvCtrlEnvLib.h"
57137+
57138+/* defines */
57139+/* DRAM Timing parameters */
57140+#define SDRAM_TWR 15 /* ns tWr */
57141+#define SDRAM_TRFC_64_512M_AT_200MHZ 70 /* ns tRfc for dens 64-512 @ 200MHz */
57142+#define SDRAM_TRFC_64_512M 75 /* ns tRfc for dens 64-512 */
57143+#define SDRAM_TRFC_1G 120 /* ns tRfc for dens 1GB */
57144+#define SDRAM_TR2R_CYC 1 /* cycle for tR2r */
57145+#define SDRAM_TR2WW2R_CYC 1 /* cycle for tR2wW2r */
57146+
57147+/* typedefs */
57148+
57149+/* enumeration for memory types */
57150+typedef enum _mvMemoryType
57151+{
57152+ MEM_TYPE_SDRAM,
57153+ MEM_TYPE_DDR1,
57154+ MEM_TYPE_DDR2
57155+}MV_MEMORY_TYPE;
57156+
57157+/* enumeration for DDR1 supported CAS Latencies */
57158+typedef enum _mvDimmDdr1Cas
57159+{
57160+ DDR1_CL_1_5 = 0x02,
57161+ DDR1_CL_2 = 0x04,
57162+ DDR1_CL_2_5 = 0x08,
57163+ DDR1_CL_3 = 0x10,
57164+ DDR1_CL_4 = 0x40,
57165+ DDR1_CL_FAULT
57166+} MV_DIMM_DDR1_CAS;
57167+
57168+/* enumeration for DDR2 supported CAS Latencies */
57169+typedef enum _mvDimmDdr2Cas
57170+{
57171+ DDR2_CL_3 = 0x08,
57172+ DDR2_CL_4 = 0x10,
57173+ DDR2_CL_5 = 0x20,
57174+ DDR2_CL_FAULT
57175+} MV_DIMM_DDR2_CAS;
57176+
57177+
57178+typedef struct _mvDramBankInfo
57179+{
57180+ MV_MEMORY_TYPE memoryType; /* DDR1, DDR2 or SDRAM */
57181+
57182+ /* DIMM dimensions */
57183+ MV_U32 numOfRowAddr;
57184+ MV_U32 numOfColAddr;
57185+ MV_U32 dataWidth;
57186+ MV_U32 errorCheckType; /* ECC , PARITY..*/
57187+ MV_U32 sdramWidth; /* 4,8,16 or 32 */
57188+ MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
57189+ MV_U32 burstLengthSupported;
57190+ MV_U32 numOfBanksOnEachDevice;
57191+ MV_U32 suportedCasLatencies;
57192+ MV_U32 refreshInterval;
57193+
57194+ /* DIMM timing parameters */
57195+ MV_U32 minCycleTimeAtMaxCasLatPs;
57196+ MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
57197+ MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
57198+ MV_U32 minRowPrechargeTime;
57199+ MV_U32 minRowActiveToRowActive;
57200+ MV_U32 minRasToCasDelay;
57201+ MV_U32 minRasPulseWidth;
57202+ MV_U32 minWriteRecoveryTime; /* DDR2 only */
57203+ MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
57204+ MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
57205+ MV_U32 minRefreshToActiveCmd; /* DDR2 only */
57206+
57207+ /* Parameters calculated from the extracted DIMM information */
57208+ MV_U32 size;
57209+ MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit */
57210+ MV_U32 numberOfDevices;
57211+
57212+ /* DIMM attributes (MV_TRUE for yes) */
57213+ MV_BOOL registeredAddrAndControlInputs;
57214+
57215+}MV_DRAM_BANK_INFO;
57216+
57217+/* This structure describes CPU interface address decode window */
57218+typedef struct _mvDramIfDecWin
57219+{
57220+ MV_ADDR_WIN addrWin; /* An address window*/
57221+ MV_BOOL enable; /* Address decode window is enabled/disabled */
57222+}MV_DRAM_DEC_WIN;
57223+
57224+#include "ddr1_2/mvDram.h"
57225+
57226+/* mvDramIf.h API list */
57227+MV_VOID mvDramIfBasicAsmInit(MV_VOID);
57228+MV_STATUS mvDramIfDetect(MV_U32 forcedCl);
57229+MV_VOID _mvDramIfConfig(MV_VOID);
57230+
57231+MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
57232+MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
57233+MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable);
57234+MV_32 mvDramIfBankSizeGet(MV_U32 bankNum);
57235+MV_32 mvDramIfBankBaseGet(MV_U32 bankNum);
57236+MV_32 mvDramIfSizeGet(MV_VOID);
57237+
57238+#if 0
57239+MV_STATUS mvDramIfMbusCtrlSet(MV_XBAR_TARGET *pPizzaArbArray);
57240+MV_STATUS mvDramIfMbusToutSet(MV_U32 timeout, MV_BOOL enable);
57241+#endif
57242+
57243+#endif /* __INCmvDramIfh */
57244diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h
57245new file mode 100644
57246index 0000000..049595e
57247--- /dev/null
57248+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h
57249@@ -0,0 +1,192 @@
57250+/*******************************************************************************
57251+Copyright (C) Marvell International Ltd. and its affiliates
57252+
57253+This software file (the "File") is owned and distributed by Marvell
57254+International Ltd. and/or its affiliates ("Marvell") under the following
57255+alternative licensing terms. Once you have made an election to distribute the
57256+File under one of the following license alternatives, please (i) delete this
57257+introductory statement regarding license alternatives, (ii) delete the two
57258+license alternatives that you have not elected to use and (iii) preserve the
57259+Marvell copyright notice above.
57260+
57261+********************************************************************************
57262+Marvell Commercial License Option
57263+
57264+If you received this File from Marvell and you have entered into a commercial
57265+license agreement (a "Commercial License") with Marvell, the File is licensed
57266+to you under the terms of the applicable Commercial License.
57267+
57268+********************************************************************************
57269+Marvell GPL License Option
57270+
57271+If you received this File from Marvell, you may opt to use, redistribute and/or
57272+modify this File in accordance with the terms and conditions of the General
57273+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
57274+available along with the File in the license.txt file or by writing to the Free
57275+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
57276+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
57277+
57278+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
57279+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
57280+DISCLAIMED. The GPL License provides additional details about this warranty
57281+disclaimer.
57282+********************************************************************************
57283+Marvell BSD License Option
57284+
57285+If you received this File from Marvell, you may opt to use, redistribute and/or
57286+modify this File under the following licensing terms.
57287+Redistribution and use in source and binary forms, with or without modification,
57288+are permitted provided that the following conditions are met:
57289+
57290+ * Redistributions of source code must retain the above copyright notice,
57291+ this list of conditions and the following disclaimer.
57292+
57293+ * Redistributions in binary form must reproduce the above copyright
57294+ notice, this list of conditions and the following disclaimer in the
57295+ documentation and/or other materials provided with the distribution.
57296+
57297+ * Neither the name of Marvell nor the names of its contributors may be
57298+ used to endorse or promote products derived from this software without
57299+ specific prior written permission.
57300+
57301+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
57302+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
57303+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
57304+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
57305+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57306+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57307+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
57308+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57309+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
57310+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57311+
57312+*******************************************************************************/
57313+
57314+
57315+#ifndef __INCmvDramIfConfigh
57316+#define __INCmvDramIfConfigh
57317+
57318+/* includes */
57319+
57320+/* defines */
57321+
57322+/* registers defaults values */
57323+
57324+#define SDRAM_CONFIG_DV \
57325+ (SDRAM_PERR_WRITE | \
57326+ SDRAM_SRMODE | \
57327+ SDRAM_SRCLK_GATED)
57328+
57329+#define SDRAM_DUNIT_CTRL_LOW_DV \
57330+ (SDRAM_CTRL_POS_RISE | \
57331+ SDRAM_CLK1DRV_NORMAL | \
57332+ SDRAM_LOCKEN_ENABLE)
57333+
57334+#define SDRAM_ADDR_CTRL_DV 0
57335+
57336+#define SDRAM_TIMING_CTRL_LOW_REG_DV \
57337+ ((0x2 << SDRAM_TRCD_OFFS) | \
57338+ (0x2 << SDRAM_TRP_OFFS) | \
57339+ (0x1 << SDRAM_TWR_OFFS) | \
57340+ (0x0 << SDRAM_TWTR_OFFS) | \
57341+ (0x5 << SDRAM_TRAS_OFFS) | \
57342+ (0x1 << SDRAM_TRRD_OFFS))
57343+/* TRFC 0x27, TW2W 0x1 */
57344+#define SDRAM_TIMING_CTRL_HIGH_REG_DV (( 0x7 << SDRAM_TRFC_OFFS ) |\
57345+ ( 0x2 << SDRAM_TRFC_EXT_OFFS) |\
57346+ ( 0x1 << SDRAM_TW2W_OFFS))
57347+
57348+#define SDRAM_OPEN_PAGES_CTRL_REG_DV SDRAM_OPEN_PAGE_EN
57349+
57350+/* DDR2 ODT default register values */
57351+
57352+/* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode */
57353+/* CS0 0x84210000 0x00000000 0x0000780F 0x00000440 */
57354+/* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440 */
57355+/* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
57356+/* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
57357+/* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
57358+/* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
57359+
57360+#define DDR2_ODT_CTRL_LOW_CS0_DV 0x84210000
57361+#define DDR2_ODT_CTRL_HIGH_CS0_DV 0x00000000
57362+#define DDR2_DUNIT_ODT_CTRL_CS0_DV 0x0000780F
57363+#define DDR_SDRAM_EXT_MODE_CS0_DV 0x00000440
57364+
57365+#define DDR2_ODT_CTRL_LOW_CS0_CS2_DV 0x030C030C
57366+#define DDR2_ODT_CTRL_HIGH_CS0_CS2_DV 0x00000000
57367+#define DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV 0x0000740F
57368+#define DDR_SDRAM_EXT_MODE_CS0_CS2_DV 0x00000404
57369+
57370+
57371+/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */
57372+#define DDR1_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
57373+ (1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
57374+#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
57375+ (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
57376+
57377+
57378+#define DDR1_DATA_PAD_STRENGTH_TYPICAL_DV \
57379+ (1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
57380+#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV \
57381+ (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
57382+
57383+/* DDR SDRAM Mode Register default value */
57384+#define DDR1_MODE_REG_DV 0x00000000
57385+#define DDR2_MODE_REG_DV 0x00000400
57386+
57387+/* DDR SDRAM Timing parameter default values */
57388+#define DDR1_TIMING_LOW_DV 0x11602220
57389+#define DDR1_TIMING_HIGH_DV 0x0000000d
57390+
57391+#define DDR2_TIMING_LOW_DV 0x11812220
57392+#define DDR2_TIMING_HIGH_DV 0x0000030f
57393+
57394+/* For Guideline (GL# MEM-4) DQS Reference Delay Tuning */
57395+#define FTDLL_DDR1_166MHZ ((0x1 << 0) | \
57396+ (0x7F<< 12) | \
57397+ (0x1 << 22))
57398+
57399+#define FTDLL_DDR1_133MHZ FTDLL_DDR1_166MHZ
57400+
57401+#define FTDLL_DDR1_200MHZ ((0x1 << 0) | \
57402+ (0x1 << 12) | \
57403+ (0x3 << 14) | \
57404+ (0x1 << 18) | \
57405+ (0x1 << 22))
57406+
57407+
57408+#define FTDLL_DDR2_166MHZ ((0x1 << 0) | \
57409+ (0x1 << 12) | \
57410+ (0x1 << 14) | \
57411+ (0x1 << 16) | \
57412+ (0x1 << 19) | \
57413+ (0xF << 20))
57414+
57415+#define FTDLL_DDR2_133MHZ FTDLL_DDR2_166MHZ
57416+
57417+#define FTDLL_DDR2_200MHZ ((0x1 << 0) | \
57418+ (0x1 << 12) | \
57419+ (0x1 << 14) | \
57420+ (0x1 << 16) | \
57421+ (0x1 << 19) | \
57422+ (0xF << 20))
57423+
57424+#define FTDLL_DDR2_250MHZ 0x445001
57425+
57426+/* Orion 1 B1 and above */
57427+#define FTDLL_DDR1_166MHZ_5181_B1 0x45D001
57428+
57429+/* Orion nas */
57430+#define FTDLL_DDR2_166MHZ_5182 0x597001
57431+
57432+/* Orion 2 D0 and above */
57433+#define FTDLL_DDR1_166MHZ_5281_D0 0x8D0001
57434+#define FTDLL_DDR1_200MHZ_5281_D0 0x8D0001
57435+#define FTDLL_DDR2_166MHZ_5281_D0 0x485001
57436+#define FTDLL_DDR2_200MHZ_5281_D0 0x485001
57437+#define FTDLL_DDR2_250MHZ_5281_D0 0x445001
57438+#define FTDLL_DDR2_200MHZ_5281_D1 0x995001
57439+#define FTDLL_DDR2_250MHZ_5281_D1 0x984801
57440+
57441+#endif /* __INCmvDramIfh */
57442diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h
57443new file mode 100644
57444index 0000000..f4a2726
57445--- /dev/null
57446+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h
57447@@ -0,0 +1,306 @@
57448+/*******************************************************************************
57449+Copyright (C) Marvell International Ltd. and its affiliates
57450+
57451+This software file (the "File") is owned and distributed by Marvell
57452+International Ltd. and/or its affiliates ("Marvell") under the following
57453+alternative licensing terms. Once you have made an election to distribute the
57454+File under one of the following license alternatives, please (i) delete this
57455+introductory statement regarding license alternatives, (ii) delete the two
57456+license alternatives that you have not elected to use and (iii) preserve the
57457+Marvell copyright notice above.
57458+
57459+********************************************************************************
57460+Marvell Commercial License Option
57461+
57462+If you received this File from Marvell and you have entered into a commercial
57463+license agreement (a "Commercial License") with Marvell, the File is licensed
57464+to you under the terms of the applicable Commercial License.
57465+
57466+********************************************************************************
57467+Marvell GPL License Option
57468+
57469+If you received this File from Marvell, you may opt to use, redistribute and/or
57470+modify this File in accordance with the terms and conditions of the General
57471+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
57472+available along with the File in the license.txt file or by writing to the Free
57473+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
57474+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
57475+
57476+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
57477+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
57478+DISCLAIMED. The GPL License provides additional details about this warranty
57479+disclaimer.
57480+********************************************************************************
57481+Marvell BSD License Option
57482+
57483+If you received this File from Marvell, you may opt to use, redistribute and/or
57484+modify this File under the following licensing terms.
57485+Redistribution and use in source and binary forms, with or without modification,
57486+are permitted provided that the following conditions are met:
57487+
57488+ * Redistributions of source code must retain the above copyright notice,
57489+ this list of conditions and the following disclaimer.
57490+
57491+ * Redistributions in binary form must reproduce the above copyright
57492+ notice, this list of conditions and the following disclaimer in the
57493+ documentation and/or other materials provided with the distribution.
57494+
57495+ * Neither the name of Marvell nor the names of its contributors may be
57496+ used to endorse or promote products derived from this software without
57497+ specific prior written permission.
57498+
57499+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
57500+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
57501+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
57502+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
57503+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57504+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57505+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
57506+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57507+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
57508+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57509+
57510+*******************************************************************************/
57511+
57512+#ifndef __INCmvDramIfRegsh
57513+#define __INCmvDramIfRegsh
57514+
57515+
57516+/* DDR SDRAM Controller Address Decode Registers */
57517+/* SDRAM CSn Base Address Register (SCBAR) */
57518+#define SDRAM_BASE_ADDR_REG(csNum) (0x1500 + (csNum * 8))
57519+#define SCBAR_BASE_OFFS 16
57520+#define SCBAR_BASE_MASK (0xffff << SCBAR_BASE_OFFS)
57521+#define SCBAR_BASE_ALIGNMENT 0x10000
57522+
57523+/* SDRAM CSn Size Register (SCSR) */
57524+#define SDRAM_SIZE_REG(csNum) (0x1504 + (csNum * 8))
57525+#define SCSR_WIN_EN BIT0
57526+#define SCSR_SIZE_OFFS 16
57527+#define SCSR_SIZE_MASK (0xffff << SCSR_SIZE_OFFS)
57528+#define SCSR_SIZE_ALIGNMENT 0x10000
57529+
57530+/* configuration register */
57531+#define SDRAM_CONFIG_REG 0x1400
57532+#define SDRAM_REFRESH_OFFS 0
57533+#define SDRAM_REFRESH_MAX 0x3000
57534+#define SDRAM_REFRESH_MASK (SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)
57535+#define SDRAM_DWIDTH_OFFS 14
57536+#define SDRAM_DWIDTH_MASK (3 << SDRAM_DWIDTH_OFFS)
57537+#define SDRAM_DWIDTH_16BIT (1 << SDRAM_DWIDTH_OFFS)
57538+#define SDRAM_DWIDTH_32BIT (2 << SDRAM_DWIDTH_OFFS)
57539+#define SDRAM_DTYPE_OFFS 16
57540+#define SDRAM_DTYPE_MASK (1 << SDRAM_DTYPE_OFFS)
57541+#define SDRAM_DTYPE_DDR1 (0 << SDRAM_DTYPE_OFFS)
57542+#define SDRAM_DTYPE_DDR2 (1 << SDRAM_DTYPE_OFFS)
57543+#define SDRAM_REGISTERED (1 << 17)
57544+#define SDRAM_PERR_OFFS 18
57545+#define SDRAM_PERR_MASK (1 << SDRAM_PERR_OFFS)
57546+#define SDRAM_PERR_NO_WRITE (0 << SDRAM_PERR_OFFS)
57547+#define SDRAM_PERR_WRITE (1 << SDRAM_PERR_OFFS)
57548+#define SDRAM_DCFG_OFFS 20
57549+#define SDRAM_DCFG_MASK (0x3 << SDRAM_DCFG_OFFS)
57550+#define SDRAM_DCFG_X16_DEV (1 << SDRAM_DCFG_OFFS)
57551+#define SDRAM_DCFG_X8_DEV (2 << SDRAM_DCFG_OFFS)
57552+#define SDRAM_SRMODE (1 << 24)
57553+#define SDRAM_SRCLK_OFFS 25
57554+#define SDRAM_SRCLK_MASK (1 << SDRAM_SRCLK_OFFS)
57555+#define SDRAM_SRCLK_KEPT (0 << SDRAM_SRCLK_OFFS)
57556+#define SDRAM_SRCLK_GATED (1 << SDRAM_SRCLK_OFFS)
57557+#define SDRAM_CATTH_OFFS 26
57558+#define SDRAM_CATTHR_EN (1 << SDRAM_CATTH_OFFS)
57559+
57560+
57561+/* dunit control register */
57562+#define SDRAM_DUNIT_CTRL_REG 0x1404
57563+#define SDRAM_CTRL_POS_OFFS 6
57564+#define SDRAM_CTRL_POS_FALL (0 << SDRAM_CTRL_POS_OFFS)
57565+#define SDRAM_CTRL_POS_RISE (1 << SDRAM_CTRL_POS_OFFS)
57566+#define SDRAM_CLK1DRV_OFFS 12
57567+#define SDRAM_CLK1DRV_MASK (1 << SDRAM_CLK1DRV_OFFS)
57568+#define SDRAM_CLK1DRV_HIGH_Z (0 << SDRAM_CLK1DRV_OFFS)
57569+#define SDRAM_CLK1DRV_NORMAL (1 << SDRAM_CLK1DRV_OFFS)
57570+#define SDRAM_LOCKEN_OFFS 18
57571+#define SDRAM_LOCKEN_MASK (1 << SDRAM_LOCKEN_OFFS)
57572+#define SDRAM_LOCKEN_DISABLE (0 << SDRAM_LOCKEN_OFFS)
57573+#define SDRAM_LOCKEN_ENABLE (1 << SDRAM_LOCKEN_OFFS)
57574+#define SDRAM_ST_BURST_DEL_OFFS 24
57575+#define SDRAM_ST_BURST_DEL_MAX 0xf
57576+#define SDRAM_ST_BURST_DEL_MASK (SDRAM_ST_BURST_DEL_MAX<<SDRAM_ST_BURST_DEL_OFFS)
57577+
57578+/* sdram timing control low register */
57579+#define SDRAM_TIMING_CTRL_LOW_REG 0x1408
57580+#define SDRAM_TRCD_OFFS 4
57581+#define SDRAM_TRCD_MASK (0xF << SDRAM_TRCD_OFFS)
57582+#define SDRAM_TRP_OFFS 8
57583+#define SDRAM_TRP_MASK (0xF << SDRAM_TRP_OFFS)
57584+#define SDRAM_TWR_OFFS 12
57585+#define SDRAM_TWR_MASK (0xF << SDRAM_TWR_OFFS)
57586+#define SDRAM_TWTR_OFFS 16
57587+#define SDRAM_TWTR_MASK (0xF << SDRAM_TWTR_OFFS)
57588+#define SDRAM_TRAS_OFFS 20
57589+#define SDRAM_TRAS_MASK (0xF << SDRAM_TRAS_OFFS)
57590+#define SDRAM_TRRD_OFFS 24
57591+#define SDRAM_TRRD_MASK (0xF << SDRAM_TRRD_OFFS)
57592+#define SDRAM_TRTP_OFFS 28
57593+#define SDRAM_TRTP_MASK (0xF << SDRAM_TRTP_OFFS)
57594+
57595+/* sdram timing control high register */
57596+#define SDRAM_TIMING_CTRL_HIGH_REG 0x140c
57597+#define SDRAM_TRFC_OFFS 0
57598+#define SDRAM_TRFC_MASK (0xF << SDRAM_TRFC_OFFS)
57599+#define SDRAM_TR2R_OFFS 4
57600+#define SDRAM_TR2R_MASK (0x3 << SDRAM_TR2R_OFFS)
57601+#define SDRAM_TR2W_W2R_OFFS 6
57602+#define SDRAM_TR2W_W2R_MASK (0x3 << SDRAM_TR2W_W2R_OFFS)
57603+#define SDRAM_TRFC_EXT_OFFS 8
57604+#define SDRAM_TRFC_EXT_MASK (0x1 << SDRAM_TRFC_EXT_OFFS)
57605+#define SDRAM_TW2W_OFFS 10
57606+#define SDRAM_TW2W_MASK (0x1 << SDRAM_TW2W_OFFS)
57607+
57608+/* address control register */
57609+#define SDRAM_ADDR_CTRL_REG 0x1410
57610+#define SDRAM_DSIZE_OFFS 4
57611+#define SDRAM_DSIZE_MASK (0x3 << SDRAM_DSIZE_OFFS)
57612+#define SDRAM_DSIZE_128Mb (0x0 << SDRAM_DSIZE_OFFS)
57613+#define SDRAM_DSIZE_256Mb (0x1 << SDRAM_DSIZE_OFFS)
57614+#define SDRAM_DSIZE_512Mb (0x2 << SDRAM_DSIZE_OFFS)
57615+
57616+/* SDRAM Open Pages Control registers */
57617+#define SDRAM_OPEN_PAGE_CTRL_REG 0x1414
57618+#define SDRAM_OPEN_PAGE_EN (0 << 0)
57619+#define SDRAM_OPEN_PAGE_DIS (1 << 0)
57620+
57621+/* sdram opertion register */
57622+#define SDRAM_OPERATION_REG 0x1418
57623+#define SDRAM_CMD_OFFS 0
57624+#define SDRAM_CMD_MASK (0x7 << SDRAM_CMD_OFFS)
57625+#define SDRAM_CMD_NORMAL (0x0 << SDRAM_CMD_OFFS)
57626+#define SDRAM_CMD_PRECHARGE_ALL (0x1 << SDRAM_CMD_OFFS)
57627+#define SDRAM_CMD_REFRESH_ALL (0x2 << SDRAM_CMD_OFFS)
57628+#define SDRAM_CMD_REG_SET_CMD (0x3 << SDRAM_CMD_OFFS)
57629+#define SDRAM_CMD_EXT_MODE_SET (0x4 << SDRAM_CMD_OFFS)
57630+#define SDRAM_CMD_NOP (0x5 << SDRAM_CMD_OFFS)
57631+#define SDRAM_CMD_SLF_RFRSH (0x7 << SDRAM_CMD_OFFS)
57632+#define SDRAM_CMD_EMRS2_CMD (0x8 << SDRAM_CMD_OFFS)
57633+#define SDRAM_CMD_EMRS3_CMD (0x9 << SDRAM_CMD_OFFS)
57634+
57635+/* sdram mode register */
57636+#define SDRAM_MODE_REG 0x141c
57637+#define SDRAM_BURST_LEN_OFFS 0
57638+#define SDRAM_BURST_LEN_MASK (0x7 << SDRAM_BURST_LEN_OFFS)
57639+#define SDRAM_BURST_LEN_4 (0x2 << SDRAM_BURST_LEN_OFFS)
57640+#define SDRAM_CL_OFFS 4
57641+#define SDRAM_CL_MASK (0x7 << SDRAM_CL_OFFS)
57642+#define SDRAM_DDR1_CL_2 (0x2 << SDRAM_CL_OFFS)
57643+#define SDRAM_DDR1_CL_3 (0x3 << SDRAM_CL_OFFS)
57644+#define SDRAM_DDR1_CL_4 (0x4 << SDRAM_CL_OFFS)
57645+#define SDRAM_DDR1_CL_1_5 (0x5 << SDRAM_CL_OFFS)
57646+#define SDRAM_DDR1_CL_2_5 (0x6 << SDRAM_CL_OFFS)
57647+#define SDRAM_DDR2_CL_3 (0x3 << SDRAM_CL_OFFS)
57648+#define SDRAM_DDR2_CL_4 (0x4 << SDRAM_CL_OFFS)
57649+#define SDRAM_DDR2_CL_5 (0x5 << SDRAM_CL_OFFS)
57650+#define SDRAM_TM_OFFS 7
57651+#define SDRAM_TM_MASK (1 << SDRAM_TM_OFFS)
57652+#define SDRAM_TM_NORMAL (0 << SDRAM_TM_OFFS)
57653+#define SDRAM_TM_TEST_MODE (1 << SDRAM_TM_OFFS)
57654+#define SDRAM_DLL_OFFS 8
57655+#define SDRAM_DLL_MASK (1 << SDRAM_DLL_OFFS)
57656+#define SDRAM_DLL_NORMAL (0 << SDRAM_DLL_OFFS)
57657+#define SDRAM_DLL_RESET (1 << SDRAM_DLL_OFFS)
57658+#define SDRAM_WR_OFFS 11
57659+#define SDRAM_WR_MAX 7
57660+#define SDRAM_WR_MASK (SDRAM_WR_MAX << SDRAM_WR_OFFS)
57661+#define SDRAM_PD_OFFS 12
57662+#define SDRAM_PD_MASK (1 << SDRAM_PD_OFFS)
57663+#define SDRAM_PD_FAST_EXIT (0 << SDRAM_PD_OFFS)
57664+#define SDRAM_PD_SLOW_EXIT (1 << SDRAM_PD_OFFS)
57665+
57666+/* DDR SDRAM Extended Mode register (DSEMR) */
57667+#define SDRAM_EXTENDED_MODE_REG 0x1420
57668+#define DSEMR_DLL_ENABLE (1 << 0)
57669+#define DSEMR_DS_OFFS 1
57670+#define DSEMR_DS_MASK (1 << DSEMR_DS_OFFS)
57671+#define DSEMR_DS_NORMAL (0 << DSEMR_DS_OFFS)
57672+#define DSEMR_DS_REDUCED (1 << DSEMR_DS_OFFS)
57673+#define DSEMR_RTT0_OFFS 2
57674+#define DSEMR_RTT1_OFFS 6
57675+#define DSEMR_RTT_ODT_DISABLE ((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
57676+#define DSEMR_RTT_ODT_75_OHM ((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
57677+#define DSEMR_RTT_ODT_150_OHM ((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
57678+#define DSEMR_OCD_OFFS 7
57679+#define DSEMR_OCD_MASK (0x7 << DSEMR_OCD_OFFS)
57680+#define DSEMR_OCD_EXIT_CALIB (0 << DSEMR_OCD_OFFS)
57681+#define DSEMR_OCD_DRIVE1 (1 << DSEMR_OCD_OFFS)
57682+#define DSEMR_OCD_DRIVE0 (2 << DSEMR_OCD_OFFS)
57683+#define DSEMR_OCD_ADJUST_MODE (4 << DSEMR_OCD_OFFS)
57684+#define DSEMR_OCD_CALIB_DEFAULT (7 << DSEMR_OCD_OFFS)
57685+#define DSEMR_DQS_OFFS 10
57686+#define DSEMR_DQS_MASK (1 << DSEMR_DQS_OFFS)
57687+#define DSEMR_DQS_DIFFERENTIAL (0 << DSEMR_DQS_OFFS)
57688+#define DSEMR_DQS_SINGLE_ENDED (0 << DSEMR_DQS_OFFS)
57689+#define DSEMR_RDQS_ENABLE (1 << 11)
57690+#define DSEMR_QOFF_OUTPUT_BUFF_EN (1 << 12)
57691+
57692+/* DDR SDRAM Operation Control Register */
57693+#define SDRAM_OPERATION_CTRL_REG 0x142c
57694+
57695+/* Dunit FTDLL Configuration Register */
57696+#define SDRAM_FTDLL_CONFIG_REG 0x1484
57697+
57698+/* Pads Calibration register */
57699+#define SDRAM_ADDR_CTRL_PADS_CAL_REG 0x14c0
57700+#define SDRAM_DATA_PADS_CAL_REG 0x14c4
57701+#define SDRAM_DRVN_OFFS 0
57702+#define SDRAM_DRVN_MASK (0x3F << SDRAM_DRVN_OFFS)
57703+#define SDRAM_DRVP_OFFS 6
57704+#define SDRAM_DRVP_MASK (0x3F << SDRAM_DRVP_OFFS)
57705+#define SDRAM_PRE_DRIVER_STRENGTH_OFFS 12
57706+#define SDRAM_PRE_DRIVER_STRENGTH_MASK (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
57707+#define SDRAM_TUNE_EN BIT16
57708+#define SDRAM_LOCK_OFFS 17
57709+#define SDRAM_LOCK_MAKS (0x1F << SDRAM_LOCK_OFFS)
57710+#define SDRAM_LOCKN_OFFS 17
57711+#define SDRAM_LOCKN_MAKS (0x3F << SDRAM_LOCKN_OFFS)
57712+#define SDRAM_LOCKP_OFFS 23
57713+#define SDRAM_LOCKP_MAKS (0x3F << SDRAM_LOCKP_OFFS)
57714+#define SDRAM_WR_EN (1 << 31)
57715+
57716+/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */
57717+#define DDR2_SDRAM_ODT_CTRL_LOW_REG 0x1494
57718+#define DSOCLR_ODT_RD_OFFS(odtNum) (odtNum * 4)
57719+#define DSOCLR_ODT_RD_MASK(odtNum) (0xf << DSOCLR_ODT_RD_OFFS(odtNum))
57720+#define DSOCLR_ODT_RD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))
57721+#define DSOCLR_ODT_WR_OFFS(odtNum) (16 + (odtNum * 4))
57722+#define DSOCLR_ODT_WR_MASK(odtNum) (0xf << DSOCLR_ODT_WR_OFFS(odtNum))
57723+#define DSOCLR_ODT_WD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))
57724+
57725+/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */
57726+#define DDR2_SDRAM_ODT_CTRL_HIGH_REG 0x1498
57727+/* Optional control values to DSOCHR_ODT_EN macro */
57728+#define DDR2_ODT_CTRL_DUNIT 0
57729+#define DDR2_ODT_CTRL_NEVER 1
57730+#define DDR2_ODT_CTRL_ALWAYS 3
57731+#define DSOCHR_ODT_EN_OFFS(odtNum) (odtNum * 2)
57732+#define DSOCHR_ODT_EN_MASK(odtNum) (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))
57733+#define DSOCHR_ODT_EN(odtNum, ctrl) ((1 << ctrl) << DSOCHR_ODT_RD_OFFS(odtNum))
57734+
57735+/* DDR2 Dunit ODT Control Register (DDOCR)*/
57736+#define DDR2_DUNIT_ODT_CONTROL_REG 0x149c
57737+#define DDOCR_ODT_RD_OFFS 0
57738+#define DDOCR_ODT_RD_MASK (0xf << DDOCR_ODT_RD_OFFS)
57739+#define DDOCR_ODT_RD(bank) ((1 << bank) << DDOCR_ODT_RD_OFFS)
57740+#define DDOCR_ODT_WR_OFFS 4
57741+#define DDOCR_ODT_WR_MASK (0xf << DDOCR_ODT_WR_OFFS)
57742+#define DDOCR_ODT_WR(bank) ((1 << bank) << DDOCR_ODT_WR_OFFS)
57743+#define DSOCR_ODT_EN_OFFS 8
57744+#define DSOCR_ODT_EN_MASK (0x3 << DSOCR_ODT_EN_OFFS)
57745+#define DSOCR_ODT_EN(ctrl) ((1 << ctrl) << DSOCR_ODT_EN_OFFS)
57746+#define DSOCR_ODT_SEL_OFFS 10
57747+#define DSOCR_ODT_SEL_MASK (0x3 << DSOCR_ODT_SEL_OFFS)
57748+
57749+/* DDR SDRAM Initialization Control Register (DSICR) */
57750+#define DDR_SDRAM_INIT_CTRL_REG 0x1480
57751+#define DSICR_INIT_EN (1 << 0)
57752+
57753+#endif /* __INCmvDramIfRegsh */
57754diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c
57755new file mode 100644
57756index 0000000..8c9ce24
57757--- /dev/null
57758+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c
57759@@ -0,0 +1,1855 @@
57760+/*******************************************************************************
57761+Copyright (C) Marvell International Ltd. and its affiliates
57762+
57763+This software file (the "File") is owned and distributed by Marvell
57764+International Ltd. and/or its affiliates ("Marvell") under the following
57765+alternative licensing terms. Once you have made an election to distribute the
57766+File under one of the following license alternatives, please (i) delete this
57767+introductory statement regarding license alternatives, (ii) delete the two
57768+license alternatives that you have not elected to use and (iii) preserve the
57769+Marvell copyright notice above.
57770+
57771+********************************************************************************
57772+Marvell Commercial License Option
57773+
57774+If you received this File from Marvell and you have entered into a commercial
57775+license agreement (a "Commercial License") with Marvell, the File is licensed
57776+to you under the terms of the applicable Commercial License.
57777+
57778+********************************************************************************
57779+Marvell GPL License Option
57780+
57781+If you received this File from Marvell, you may opt to use, redistribute and/or
57782+modify this File in accordance with the terms and conditions of the General
57783+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
57784+available along with the File in the license.txt file or by writing to the Free
57785+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
57786+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
57787+
57788+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
57789+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
57790+DISCLAIMED. The GPL License provides additional details about this warranty
57791+disclaimer.
57792+********************************************************************************
57793+Marvell BSD License Option
57794+
57795+If you received this File from Marvell, you may opt to use, redistribute and/or
57796+modify this File under the following licensing terms.
57797+Redistribution and use in source and binary forms, with or without modification,
57798+are permitted provided that the following conditions are met:
57799+
57800+ * Redistributions of source code must retain the above copyright notice,
57801+ this list of conditions and the following disclaimer.
57802+
57803+ * Redistributions in binary form must reproduce the above copyright
57804+ notice, this list of conditions and the following disclaimer in the
57805+ documentation and/or other materials provided with the distribution.
57806+
57807+ * Neither the name of Marvell nor the names of its contributors may be
57808+ used to endorse or promote products derived from this software without
57809+ specific prior written permission.
57810+
57811+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
57812+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
57813+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
57814+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
57815+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57816+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57817+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
57818+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57819+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
57820+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57821+
57822+*******************************************************************************/
57823+
57824+
57825+/* includes */
57826+#include "ddr2/mvDramIf.h"
57827+#include "ctrlEnv/sys/mvCpuIf.h"
57828+
57829+#include "ddr2/mvDramIfStaticInit.h"
57830+
57831+/* #define MV_DEBUG */
57832+#ifdef MV_DEBUG
57833+#define DB(x) x
57834+#else
57835+#define DB(x)
57836+#endif
57837+
57838+/* DRAM bank presence encoding */
57839+#define BANK_PRESENT_CS0 0x1
57840+#define BANK_PRESENT_CS0_CS1 0x3
57841+#define BANK_PRESENT_CS0_CS2 0x5
57842+#define BANK_PRESENT_CS0_CS1_CS2 0x7
57843+#define BANK_PRESENT_CS0_CS2_CS3 0xd
57844+#define BANK_PRESENT_CS0_CS2_CS3_CS4 0xf
57845+
57846+/* locals */
57847+#ifndef MV_STATIC_DRAM_ON_BOARD
57848+static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
57849+static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk, MV_STATUS TTmode );
57850+static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
57851+static MV_U32 sdramModeRegCalc(MV_U32 minCas);
57852+static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
57853+static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1);
57854+static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk);
57855+static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl);
57856+static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk);
57857+static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
57858+static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas);
57859+static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas);
57860+#endif
57861+MV_32 DRAM_CS_Order[MV_DRAM_MAX_CS] = {N_A
57862+
57863+#ifdef MV_INCLUDE_SDRAM_CS1
57864+ ,N_A
57865+#endif
57866+#ifdef MV_INCLUDE_SDRAM_CS2
57867+ ,N_A
57868+#endif
57869+#ifdef MV_INCLUDE_SDRAM_CS3
57870+ ,N_A
57871+#endif
57872+ };
57873+/* Get DRAM size of CS num */
57874+MV_U32 mvDramCsSizeGet(MV_U32 csNum)
57875+{
57876+ MV_DRAM_BANK_INFO bankInfo;
57877+ MV_U32 size, deviceW, dimmW;
57878+#ifdef MV78XX0
57879+ MV_U32 temp;
57880+#endif
57881+
57882+ if(MV_OK == mvDramBankInfoGet(csNum, &bankInfo))
57883+ {
57884+ if (0 == bankInfo.size)
57885+ return 0;
57886+
57887+ /* Note that the Dimm width might be different then the device DRAM width */
57888+#ifdef MV78XX0
57889+ temp = MV_REG_READ(SDRAM_CONFIG_REG);
57890+ deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
57891+#else
57892+ deviceW = 16 /* KW family */;
57893+#endif
57894+ dimmW = bankInfo.dataWidth - (bankInfo.dataWidth % 16);
57895+ size = ((bankInfo.size << 20) / (dimmW/deviceW));
57896+ return size;
57897+ }
57898+ else
57899+ return 0;
57900+}
57901+/*******************************************************************************
57902+* mvDramIfDetect - Prepare DRAM interface configuration values.
57903+*
57904+* DESCRIPTION:
57905+* This function implements the full DRAM detection and timing
57906+* configuration for best system performance.
57907+* Since this routine runs from a ROM device (Boot Flash), its stack
57908+* resides on RAM, that might be the system DRAM. Changing DRAM
57909+* configuration values while keeping vital data in DRAM is risky. That
57910+* is why the function does not preform the configuration setting but
57911+* prepare those in predefined 32bit registers (in this case IDMA
57912+* registers are used) for other routine to perform the settings.
57913+* The function will call for board DRAM SPD information for each DRAM
57914+* chip select. The function will then analyze those SPD parameters of
57915+* all DRAM banks in order to decide on DRAM configuration compatible
57916+* for all DRAM banks.
57917+* The function will set the CPU DRAM address decode registers.
57918+* Note: This routine prepares values that will overide configuration of
57919+* mvDramBasicAsmInit().
57920+*
57921+* INPUT:
57922+* forcedCl - Forced CAL Latency. If equal to zero, do not force.
57923+* eccDisable - Force down the ECC.
57924+*
57925+* OUTPUT:
57926+* None.
57927+*
57928+* RETURN:
57929+* None.
57930+*
57931+*******************************************************************************/
57932+MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable)
57933+{
57934+ MV_32 MV_DRAM_CS_order[MV_DRAM_MAX_CS] = {
57935+ SDRAM_CS0
57936+#ifdef MV_INCLUDE_SDRAM_CS1
57937+ ,SDRAM_CS1
57938+#endif
57939+#ifdef MV_INCLUDE_SDRAM_CS2
57940+ ,SDRAM_CS2
57941+#endif
57942+#ifdef MV_INCLUDE_SDRAM_CS3
57943+ ,SDRAM_CS3
57944+#endif
57945+ };
57946+ MV_U32 busClk, deviceW, dimmW;
57947+ MV_U32 numOfAllDevices = 0;
57948+ MV_STATUS TTMode;
57949+#ifndef MV_STATIC_DRAM_ON_BOARD
57950+ MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
57951+ MV_U32 size, base = 0, i, j, temp, busClkPs;
57952+ MV_U8 minCas;
57953+ MV_CPU_DEC_WIN dramDecWin;
57954+ dramDecWin.addrWin.baseHigh = 0;
57955+#endif
57956+
57957+ busClk = mvBoardSysClkGet();
57958+
57959+ if (0 == busClk)
57960+ {
57961+ mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
57962+ return MV_ERROR;
57963+ }
57964+
57965+#ifndef MV_STATIC_DRAM_ON_BOARD
57966+
57967+ busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
57968+ /* we will use bank 0 as the representative of the all the DRAM banks, */
57969+ /* since bank 0 must exist. */
57970+ for(i = 0; i < MV_DRAM_MAX_CS; i++)
57971+ {
57972+ /* if Bank exist */
57973+ if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
57974+ {
57975+ DB(mvOsPrintf("Dram: Find bank %d\n", i));
57976+ /* check it isn't SDRAM */
57977+ if(bankInfo[i].memoryType != MEM_TYPE_DDR2)
57978+ {
57979+ mvOsOutput("Dram: ERR. SDRAM type not supported !!!\n");
57980+ return MV_ERROR;
57981+ }
57982+
57983+ /* All banks must support the Mclk freqency */
57984+ if(bankInfo[i].minCycleTimeAtMaxCasLatPs > busClkPs)
57985+ {
57986+ mvOsOutput("Dram: ERR. Bank %d doesn't support memory clock!!!\n", i);
57987+ return MV_ERROR;
57988+ }
57989+
57990+ /* All banks must support registry in order to activate it */
57991+ if(bankInfo[i].registeredAddrAndControlInputs !=
57992+ bankInfo[0].registeredAddrAndControlInputs)
57993+ {
57994+ mvOsOutput("Dram: ERR. different Registered settings !!!\n");
57995+ return MV_ERROR;
57996+ }
57997+
57998+ /* All banks must support same ECC mode */
57999+ if(bankInfo[i].errorCheckType !=
58000+ bankInfo[0].errorCheckType)
58001+ {
58002+ mvOsOutput("Dram: ERR. different ECC settings !!!\n");
58003+ return MV_ERROR;
58004+ }
58005+
58006+ }
58007+ else
58008+ {
58009+ if( i == 0 ) /* bank 0 doesn't exist */
58010+ {
58011+ mvOsOutput("Dram: ERR. Fail to detect bank 0 !!!\n");
58012+ return MV_ERROR;
58013+ }
58014+ else
58015+ {
58016+ DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
58017+ bankInfo[i].size = 0; /* Mark this bank as non exist */
58018+ }
58019+ }
58020+ }
58021+
58022+#ifdef MV_INCLUDE_SDRAM_CS2
58023+ if (bankInfo[SDRAM_CS0].size < bankInfo[SDRAM_CS2].size)
58024+ {
58025+ MV_DRAM_CS_order[0] = SDRAM_CS2;
58026+ MV_DRAM_CS_order[1] = SDRAM_CS3;
58027+ MV_DRAM_CS_order[2] = SDRAM_CS0;
58028+ MV_DRAM_CS_order[3] = SDRAM_CS1;
58029+ DRAM_CS_Order[0] = SDRAM_CS2;
58030+ DRAM_CS_Order[1] = SDRAM_CS3;
58031+ DRAM_CS_Order[2] = SDRAM_CS0;
58032+ DRAM_CS_Order[3] = SDRAM_CS1;
58033+
58034+ }
58035+ else
58036+#endif
58037+ {
58038+ MV_DRAM_CS_order[0] = SDRAM_CS0;
58039+ MV_DRAM_CS_order[1] = SDRAM_CS1;
58040+ DRAM_CS_Order[0] = SDRAM_CS0;
58041+ DRAM_CS_Order[1] = SDRAM_CS1;
58042+#ifdef MV_INCLUDE_SDRAM_CS2
58043+ MV_DRAM_CS_order[2] = SDRAM_CS2;
58044+ MV_DRAM_CS_order[3] = SDRAM_CS3;
58045+ DRAM_CS_Order[2] = SDRAM_CS2;
58046+ DRAM_CS_Order[3] = SDRAM_CS3;
58047+#endif
58048+ }
58049+
58050+ for(j = 0; j < MV_DRAM_MAX_CS; j++)
58051+ {
58052+ i = MV_DRAM_CS_order[j];
58053+
58054+ if (0 == bankInfo[i].size)
58055+ continue;
58056+
58057+ /* Init the CPU window decode */
58058+ /* Note that the Dimm width might be different then the device DRAM width */
58059+#ifdef MV78XX0
58060+ temp = MV_REG_READ(SDRAM_CONFIG_REG);
58061+ deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
58062+#else
58063+ deviceW = 16 /* KW family */;
58064+#endif
58065+ dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
58066+ size = ((bankInfo[i].size << 20) / (dimmW/deviceW));
58067+
58068+ /* We can not change DRAM window settings while excecuting */
58069+ /* code from it. That is why we skip the DRAM CS[0], saving */
58070+ /* it to the ROM configuration routine */
58071+
58072+ numOfAllDevices += bankInfo[i].numberOfDevices;
58073+ if (i == MV_DRAM_CS_order[0])
58074+ {
58075+ MV_U32 sizeToReg;
58076+ /* Translate the given window size to register format */
58077+ sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
58078+ /* Size parameter validity check. */
58079+ if (-1 == sizeToReg)
58080+ {
58081+ mvOsOutput("DRAM: mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
58082+ ,i);
58083+ return MV_BAD_PARAM;
58084+ }
58085+
58086+ DB(mvOsPrintf("Dram: Bank 0 Size - %x\n",sizeToReg);)
58087+ sizeToReg = (sizeToReg << SCSR_SIZE_OFFS);
58088+ sizeToReg |= SCSR_WIN_EN;
58089+ MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
58090+ }
58091+ else
58092+ {
58093+ dramDecWin.addrWin.baseLow = base;
58094+ dramDecWin.addrWin.size = size;
58095+ dramDecWin.enable = MV_TRUE;
58096+ DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
58097+
58098+ /* Check if the DRAM size is more then 3GByte */
58099+ if (base < 0xC0000000)
58100+ {
58101+ DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
58102+ if (MV_OK != mvCpuIfTargetWinSet(i, &dramDecWin))
58103+ {
58104+ mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n", SDRAM_CS0 + i);
58105+ return MV_ERROR;
58106+ }
58107+ }
58108+ }
58109+
58110+ base += size;
58111+
58112+ /* update the suportedCasLatencies mask */
58113+ bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
58114+ }
58115+
58116+ /* calculate minimum CAS */
58117+ minCas = minCasCalc(&bankInfo[0], &bankInfo[2], busClk, forcedCl);
58118+ if (0 == minCas)
58119+ {
58120+ mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
58121+ (busClk / 1000000));
58122+
58123+ minCas = DDR2_CL_4; /* Continue with this CAS */
58124+ mvOsOutput("Set default CAS latency 4\n");
58125+ }
58126+
58127+ /* calc SDRAM_CONFIG_REG and save it to temp register */
58128+ temp = sdramConfigRegCalc(&bankInfo[0],&bankInfo[2], busClk);
58129+ if(-1 == temp)
58130+ {
58131+ mvOsOutput("Dram: ERR. sdramConfigRegCalc failed !!!\n");
58132+ return MV_ERROR;
58133+ }
58134+
58135+ /* check if ECC is enabled by the user */
58136+ if(eccDisable)
58137+ {
58138+ /* turn off ECC*/
58139+ temp &= ~BIT18;
58140+ }
58141+ DB(mvOsPrintf("Dram: sdramConfigRegCalc - %x\n",temp);)
58142+ MV_REG_WRITE(DRAM_BUF_REG1, temp);
58143+
58144+ /* calc SDRAM_MODE_REG and save it to temp register */
58145+ temp = sdramModeRegCalc(minCas);
58146+ if(-1 == temp)
58147+ {
58148+ mvOsOutput("Dram: ERR. sdramModeRegCalc failed !!!\n");
58149+ return MV_ERROR;
58150+ }
58151+ DB(mvOsPrintf("Dram: sdramModeRegCalc - %x\n",temp);)
58152+ MV_REG_WRITE(DRAM_BUF_REG2, temp);
58153+
58154+ /* calc SDRAM_EXTENDED_MODE_REG and save it to temp register */
58155+ temp = sdramExtModeRegCalc(&bankInfo[0], busClk);
58156+ if(-1 == temp)
58157+ {
58158+ mvOsOutput("Dram: ERR. sdramExtModeRegCalc failed !!!\n");
58159+ return MV_ERROR;
58160+ }
58161+ DB(mvOsPrintf("Dram: sdramExtModeRegCalc - %x\n",temp);)
58162+ MV_REG_WRITE(DRAM_BUF_REG10, temp);
58163+
58164+ /* calc D_UNIT_CONTROL_LOW and save it to temp register */
58165+ TTMode = MV_FALSE;
58166+ DB(mvOsPrintf("Dram: numOfAllDevices = %x\n",numOfAllDevices);)
58167+ if( (numOfAllDevices > 9) && (bankInfo[0].registeredAddrAndControlInputs == MV_FALSE) )
58168+ {
58169+ if ( ( (numOfAllDevices > 9) && (busClk > MV_BOARD_SYSCLK_200MHZ) ) ||
58170+ (numOfAllDevices > 18) )
58171+ {
58172+ mvOsOutput("Enable 2T ");
58173+ TTMode = MV_TRUE;
58174+ }
58175+ }
58176+
58177+ temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas, busClk, TTMode );
58178+ if(-1 == temp)
58179+ {
58180+ mvOsOutput("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
58181+ return MV_ERROR;
58182+ }
58183+ DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc - %x\n",temp);)
58184+ MV_REG_WRITE(DRAM_BUF_REG3, temp);
58185+
58186+ /* calc D_UNIT_CONTROL_HIGH and save it to temp register */
58187+ temp = dunitCtrlHighRegCalc(&bankInfo[0], busClk);
58188+ if(-1 == temp)
58189+ {
58190+ mvOsOutput("Dram: ERR. dunitCtrlHighRegCalc failed !!!\n");
58191+ return MV_ERROR;
58192+ }
58193+ DB(mvOsPrintf("Dram: dunitCtrlHighRegCalc - %x\n",temp);)
58194+ /* check if ECC is enabled by the user */
58195+ if(eccDisable)
58196+ {
58197+ /* turn off sample stage if no ecc */
58198+ temp &= ~SDRAM__D2P_EN;;
58199+ }
58200+ MV_REG_WRITE(DRAM_BUF_REG13, temp);
58201+
58202+ /* calc SDRAM_ADDR_CTRL_REG and save it to temp register */
58203+ temp = sdramAddrCtrlRegCalc(&bankInfo[0],&bankInfo[2]);
58204+ if(-1 == temp)
58205+ {
58206+ mvOsOutput("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
58207+ return MV_ERROR;
58208+ }
58209+ DB(mvOsPrintf("Dram: sdramAddrCtrlRegCalc - %x\n",temp);)
58210+ MV_REG_WRITE(DRAM_BUF_REG4, temp);
58211+
58212+ /* calc SDRAM_TIMING_CTRL_LOW_REG and save it to temp register */
58213+ temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
58214+ if(-1 == temp)
58215+ {
58216+ mvOsOutput("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
58217+ return MV_ERROR;
58218+ }
58219+ DB(mvOsPrintf("Dram: sdramTimeCtrlLowRegCalc - %x\n",temp);)
58220+ MV_REG_WRITE(DRAM_BUF_REG5, temp);
58221+
58222+ /* calc SDRAM_TIMING_CTRL_HIGH_REG and save it to temp register */
58223+ temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
58224+ if(-1 == temp)
58225+ {
58226+ mvOsOutput("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
58227+ return MV_ERROR;
58228+ }
58229+ DB(mvOsPrintf("Dram: sdramTimeCtrlHighRegCalc - %x\n",temp);)
58230+ MV_REG_WRITE(DRAM_BUF_REG6, temp);
58231+
58232+ sdramDDr2OdtConfig(bankInfo);
58233+
58234+ /* calc DDR2_SDRAM_TIMING_LOW_REG and save it to temp register */
58235+ temp = sdramDdr2TimeLoRegCalc(minCas);
58236+ if(-1 == temp)
58237+ {
58238+ mvOsOutput("Dram: ERR. sdramDdr2TimeLoRegCalc failed !!!\n");
58239+ return MV_ERROR;
58240+ }
58241+ DB(mvOsPrintf("Dram: sdramDdr2TimeLoRegCalc - %x\n",temp);)
58242+ MV_REG_WRITE(DRAM_BUF_REG11, temp);
58243+
58244+ /* calc DDR2_SDRAM_TIMING_HIGH_REG and save it to temp register */
58245+ temp = sdramDdr2TimeHiRegCalc(minCas);
58246+ if(-1 == temp)
58247+ {
58248+ mvOsOutput("Dram: ERR. sdramDdr2TimeHiRegCalc failed !!!\n");
58249+ return MV_ERROR;
58250+ }
58251+ DB(mvOsPrintf("Dram: sdramDdr2TimeHiRegCalc - %x\n",temp);)
58252+ MV_REG_WRITE(DRAM_BUF_REG12, temp);
58253+#endif
58254+
58255+ /* Note that DDR SDRAM Address/Control and Data pad calibration */
58256+ /* settings is done in mvSdramIfConfig.s */
58257+
58258+ return MV_OK;
58259+}
58260+
58261+
58262+/*******************************************************************************
58263+* mvDramIfBankBaseGet - Get DRAM interface bank base.
58264+*
58265+* DESCRIPTION:
58266+* This function returns the 32 bit base address of a given DRAM bank.
58267+*
58268+* INPUT:
58269+* bankNum - Bank number.
58270+*
58271+* OUTPUT:
58272+* None.
58273+*
58274+* RETURN:
58275+* DRAM bank size. If bank is disabled or paramter is invalid, the
58276+* function returns -1.
58277+*
58278+*******************************************************************************/
58279+MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum)
58280+{
58281+ DB(mvOsPrintf("Dram: mvDramIfBankBaseGet Bank %d base addr is %x \n",
58282+ bankNum, mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum)));
58283+ return mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum);
58284+}
58285+
58286+/*******************************************************************************
58287+* mvDramIfBankSizeGet - Get DRAM interface bank size.
58288+*
58289+* DESCRIPTION:
58290+* This function returns the size of a given DRAM bank.
58291+*
58292+* INPUT:
58293+* bankNum - Bank number.
58294+*
58295+* OUTPUT:
58296+* None.
58297+*
58298+* RETURN:
58299+* DRAM bank size. If bank is disabled the function return '0'. In case
58300+* or paramter is invalid, the function returns -1.
58301+*
58302+*******************************************************************************/
58303+MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum)
58304+{
58305+ DB(mvOsPrintf("Dram: mvDramIfBankSizeGet Bank %d size is %x \n",
58306+ bankNum, mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum)));
58307+ return mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum);
58308+}
58309+
58310+
58311+/*******************************************************************************
58312+* mvDramIfSizeGet - Get DRAM interface total size.
58313+*
58314+* DESCRIPTION:
58315+* This function get the DRAM total size.
58316+*
58317+* INPUT:
58318+* None.
58319+*
58320+* OUTPUT:
58321+* None.
58322+*
58323+* RETURN:
58324+* DRAM total size. In case or paramter is invalid, the function
58325+* returns -1.
58326+*
58327+*******************************************************************************/
58328+MV_U32 mvDramIfSizeGet(MV_VOID)
58329+{
58330+ MV_U32 size = 0, i;
58331+
58332+ for(i = 0; i < MV_DRAM_MAX_CS; i++)
58333+ size += mvDramIfBankSizeGet(i);
58334+
58335+ DB(mvOsPrintf("Dram: mvDramIfSizeGet size is %x \n",size));
58336+ return size;
58337+}
58338+
58339+/*******************************************************************************
58340+* mvDramIfSingleBitErrThresholdSet - Set single bit ECC threshold.
58341+*
58342+* DESCRIPTION:
58343+* The ECC single bit error threshold is the number of single bit
58344+* errors to happen before the Dunit generates an interrupt.
58345+* This function set single bit ECC threshold.
58346+*
58347+* INPUT:
58348+* threshold - threshold.
58349+*
58350+* OUTPUT:
58351+* None.
58352+*
58353+* RETURN:
58354+* MV_BAD_PARAM if threshold is to big, MV_OK otherwise.
58355+*
58356+*******************************************************************************/
58357+MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold)
58358+{
58359+ MV_U32 regVal;
58360+
58361+ if (threshold > SECR_THRECC_MAX)
58362+ {
58363+ return MV_BAD_PARAM;
58364+ }
58365+
58366+ regVal = MV_REG_READ(SDRAM_ECC_CONTROL_REG);
58367+ regVal &= ~SECR_THRECC_MASK;
58368+ regVal |= ((SECR_THRECC(threshold) & SECR_THRECC_MASK));
58369+ MV_REG_WRITE(SDRAM_ECC_CONTROL_REG, regVal);
58370+
58371+ return MV_OK;
58372+}
58373+
58374+#ifndef MV_STATIC_DRAM_ON_BOARD
58375+/*******************************************************************************
58376+* minCasCalc - Calculate the Minimum CAS latency which can be used.
58377+*
58378+* DESCRIPTION:
58379+* Calculate the minimum CAS latency that can be used, base on the DRAM
58380+* parameters and the SDRAM bus Clock freq.
58381+*
58382+* INPUT:
58383+* busClk - the DRAM bus Clock.
58384+* pBankInfo - bank info parameters.
58385+* forcedCl - Forced CAS Latency multiplied by 10. If equal to zero, do not force.
58386+*
58387+* OUTPUT:
58388+* None
58389+*
58390+* RETURN:
58391+* The minimum CAS Latency. The function returns 0 if max CAS latency
58392+* supported by banks is incompatible with system bus clock frequancy.
58393+*
58394+*******************************************************************************/
58395+
58396+static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl)
58397+{
58398+ MV_U32 count = 1, j;
58399+ MV_U32 busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
58400+ MV_U32 startBit, stopBit;
58401+ MV_U32 minCas0 = 0, minCas2 = 0;
58402+
58403+
58404+ /* DDR 2:
58405+ *******-******-******-******-******-******-******-*******
58406+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
58407+ *******-******-******-******-******-******-******-*******
58408+ CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
58409+ Disco VI= * TBD | TBD | 5 | 4 | 3 | TBD | TBD | TBD *
58410+ Disco Duo= * TBD | 6 | 5 | 4 | 3 | TBD | TBD | TBD *
58411+ *********************************************************/
58412+
58413+
58414+ /* If we are asked to use the forced CAL we change the suported CAL to be forcedCl only */
58415+ if (forcedCl)
58416+ {
58417+ mvOsOutput("DRAM: Using forced CL %d.%d\n", (forcedCl / 10), (forcedCl % 10));
58418+
58419+ if (forcedCl == 30)
58420+ pBankInfo->suportedCasLatencies = 0x08;
58421+ else if (forcedCl == 40)
58422+ pBankInfo->suportedCasLatencies = 0x10;
58423+ else if (forcedCl == 50)
58424+ pBankInfo->suportedCasLatencies = 0x20;
58425+ else if (forcedCl == 60)
58426+ pBankInfo->suportedCasLatencies = 0x40;
58427+ else
58428+ {
58429+ mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n",
58430+ (forcedCl / 10), (forcedCl % 10));
58431+ pBankInfo->suportedCasLatencies = 0x10;
58432+ }
58433+
58434+ return pBankInfo->suportedCasLatencies;
58435+ }
58436+
58437+ /* go over the supported cas mask from Max Cas down and check if the */
58438+ /* SysClk stands in its time requirments. */
58439+
58440+ DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
58441+ pBankInfo->suportedCasLatencies,busClkPs ));
58442+ count = 1;
58443+ for(j = 7; j > 0; j--)
58444+ {
58445+ if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
58446+ {
58447+ /* Reset the bits for CL incompatible for the sysClk */
58448+ switch (count)
58449+ {
58450+ case 1:
58451+ if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs)
58452+ pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
58453+ count++;
58454+ break;
58455+ case 2:
58456+ if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
58457+ pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
58458+ count++;
58459+ break;
58460+ case 3:
58461+ if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
58462+ pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
58463+ count++;
58464+ break;
58465+ default:
58466+ pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
58467+ break;
58468+ }
58469+ }
58470+ }
58471+
58472+ DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
58473+ pBankInfo->suportedCasLatencies ));
58474+
58475+ count = 1;
58476+ DB(mvOsPrintf("Dram2: minCasCalc supported mask = %x busClkPs = %x \n",
58477+ pBankInfo2->suportedCasLatencies,busClkPs ));
58478+ for(j = 7; j > 0; j--)
58479+ {
58480+ if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
58481+ {
58482+ /* Reset the bits for CL incompatible for the sysClk */
58483+ switch (count)
58484+ {
58485+ case 1:
58486+ if (pBankInfo2->minCycleTimeAtMaxCasLatPs > busClkPs)
58487+ pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
58488+ count++;
58489+ break;
58490+ case 2:
58491+ if (pBankInfo2->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
58492+ pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
58493+ count++;
58494+ break;
58495+ case 3:
58496+ if (pBankInfo2->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
58497+ pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
58498+ count++;
58499+ break;
58500+ default:
58501+ pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
58502+ break;
58503+ }
58504+ }
58505+ }
58506+
58507+ DB(mvOsPrintf("Dram2: minCasCalc support = %x (after SysCC calc)\n",
58508+ pBankInfo2->suportedCasLatencies ));
58509+
58510+ startBit = 3; /* DDR2 support CL start with CL3 (bit 3) */
58511+ stopBit = 6; /* DDR2 support CL stops with CL6 (bit 6) */
58512+
58513+ for(j = startBit; j <= stopBit ; j++)
58514+ {
58515+ if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
58516+ {
58517+ DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
58518+ minCas0 = (BIT0 << j);
58519+ break;
58520+ }
58521+ }
58522+
58523+ for(j = startBit; j <= stopBit ; j++)
58524+ {
58525+ if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
58526+ {
58527+ DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
58528+ minCas2 = (BIT0 << j);
58529+ break;
58530+ }
58531+ }
58532+
58533+ if (minCas2 > minCas0)
58534+ return minCas2;
58535+ else
58536+ return minCas0;
58537+
58538+ return 0;
58539+}
58540+
58541+/*******************************************************************************
58542+* sdramConfigRegCalc - Calculate sdram config register
58543+*
58544+* DESCRIPTION: Calculate sdram config register optimized value based
58545+* on the bank info parameters.
58546+*
58547+* INPUT:
58548+* busClk - the DRAM bus Clock.
58549+* pBankInfo - sdram bank parameters
58550+*
58551+* OUTPUT:
58552+* None
58553+*
58554+* RETURN:
58555+* sdram config reg value.
58556+*
58557+*******************************************************************************/
58558+static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk)
58559+{
58560+ MV_U32 sdramConfig = 0;
58561+ MV_U32 refreshPeriod;
58562+
58563+ busClk /= 1000000; /* we work with busClk in MHz */
58564+
58565+ sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
58566+
58567+ /* figure out the memory refresh internal */
58568+ switch (pBankInfo->refreshInterval & 0xf)
58569+ {
58570+ case 0x0: /* refresh period is 15.625 usec */
58571+ refreshPeriod = 15625;
58572+ break;
58573+ case 0x1: /* refresh period is 3.9 usec */
58574+ refreshPeriod = 3900;
58575+ break;
58576+ case 0x2: /* refresh period is 7.8 usec */
58577+ refreshPeriod = 7800;
58578+ break;
58579+ case 0x3: /* refresh period is 31.3 usec */
58580+ refreshPeriod = 31300;
58581+ break;
58582+ case 0x4: /* refresh period is 62.5 usec */
58583+ refreshPeriod = 62500;
58584+ break;
58585+ case 0x5: /* refresh period is 125 usec */
58586+ refreshPeriod = 125000;
58587+ break;
58588+ default: /* refresh period undefined */
58589+ mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
58590+ return -1;
58591+ }
58592+
58593+ /* Now the refreshPeriod is in register format value */
58594+ refreshPeriod = (busClk * refreshPeriod) / 1000;
58595+
58596+ DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n",
58597+ refreshPeriod));
58598+
58599+ /* make sure the refresh value is only 14 bits */
58600+ if(refreshPeriod > SDRAM_REFRESH_MAX)
58601+ {
58602+ refreshPeriod = SDRAM_REFRESH_MAX;
58603+ DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n",
58604+ refreshPeriod));
58605+ }
58606+
58607+ /* Clear the refresh field */
58608+ sdramConfig &= ~SDRAM_REFRESH_MASK;
58609+
58610+ /* Set new value to refresh field */
58611+ sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
58612+
58613+ /* registered DRAM ? */
58614+ if ( pBankInfo->registeredAddrAndControlInputs )
58615+ {
58616+ /* it's registered DRAM, so set the reg. DRAM bit */
58617+ sdramConfig |= SDRAM_REGISTERED;
58618+ DB(mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");)
58619+ }
58620+
58621+ /* ECC and IERR support */
58622+ sdramConfig &= ~SDRAM_ECC_MASK; /* Clear ECC field */
58623+ sdramConfig &= ~SDRAM_IERR_MASK; /* Clear IErr field */
58624+
58625+ if ( pBankInfo->errorCheckType )
58626+ {
58627+ sdramConfig |= SDRAM_ECC_EN;
58628+ sdramConfig |= SDRAM_IERR_REPORTE;
58629+ DB(mvOsPrintf("Dram: mvDramIfDetect Enabling ECC\n"));
58630+ }
58631+ else
58632+ {
58633+ sdramConfig |= SDRAM_ECC_DIS;
58634+ sdramConfig |= SDRAM_IERR_IGNORE;
58635+ DB(mvOsPrintf("Dram: mvDramIfDetect Disabling ECC!\n"));
58636+ }
58637+ /* Set static default settings */
58638+ sdramConfig |= SDRAM_CONFIG_DV;
58639+
58640+ DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
58641+ sdramConfig));
58642+
58643+ return sdramConfig;
58644+}
58645+
58646+/*******************************************************************************
58647+* sdramModeRegCalc - Calculate sdram mode register
58648+*
58649+* DESCRIPTION: Calculate sdram mode register optimized value based
58650+* on the bank info parameters and the minCas.
58651+*
58652+* INPUT:
58653+* minCas - minimum CAS supported.
58654+*
58655+* OUTPUT:
58656+* None
58657+*
58658+* RETURN:
58659+* sdram mode reg value.
58660+*
58661+*******************************************************************************/
58662+static MV_U32 sdramModeRegCalc(MV_U32 minCas)
58663+{
58664+ MV_U32 sdramMode;
58665+
58666+ sdramMode = MV_REG_READ(SDRAM_MODE_REG);
58667+
58668+ /* Clear CAS Latency field */
58669+ sdramMode &= ~SDRAM_CL_MASK;
58670+
58671+ DB(mvOsPrintf("DRAM CAS Latency ");)
58672+
58673+ switch (minCas)
58674+ {
58675+ case DDR2_CL_3:
58676+ sdramMode |= SDRAM_DDR2_CL_3;
58677+ DB(mvOsPrintf("3.\n");)
58678+ break;
58679+ case DDR2_CL_4:
58680+ sdramMode |= SDRAM_DDR2_CL_4;
58681+ DB(mvOsPrintf("4.\n");)
58682+ break;
58683+ case DDR2_CL_5:
58684+ sdramMode |= SDRAM_DDR2_CL_5;
58685+ DB(mvOsPrintf("5.\n");)
58686+ break;
58687+ case DDR2_CL_6:
58688+ sdramMode |= SDRAM_DDR2_CL_6;
58689+ DB(mvOsPrintf("6.\n");)
58690+ break;
58691+ default:
58692+ mvOsOutput("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
58693+ return -1;
58694+ }
58695+
58696+ DB(mvOsPrintf("\nsdramModeRegCalc register 0x%x\n", sdramMode ));
58697+
58698+ return sdramMode;
58699+}
58700+/*******************************************************************************
58701+* sdramExtModeRegCalc - Calculate sdram Extended mode register
58702+*
58703+* DESCRIPTION:
58704+* Return sdram Extended mode register value based
58705+* on the bank info parameters and bank presence.
58706+*
58707+* INPUT:
58708+* pBankInfo - sdram bank parameters
58709+* busClk - DRAM frequency
58710+*
58711+* OUTPUT:
58712+* None
58713+*
58714+* RETURN:
58715+* sdram Extended mode reg value.
58716+*
58717+*******************************************************************************/
58718+static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
58719+{
58720+ MV_U32 populateBanks = 0;
58721+ int bankNum;
58722+
58723+ /* Represent the populate banks in binary form */
58724+ for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
58725+ {
58726+ if (0 != pBankInfo[bankNum].size)
58727+ {
58728+ populateBanks |= (1 << bankNum);
58729+ }
58730+ }
58731+
58732+ switch(populateBanks)
58733+ {
58734+ case(BANK_PRESENT_CS0):
58735+ case(BANK_PRESENT_CS0_CS1):
58736+ return DDR_SDRAM_EXT_MODE_CS0_CS1_DV;
58737+
58738+ case(BANK_PRESENT_CS0_CS2):
58739+ case(BANK_PRESENT_CS0_CS1_CS2):
58740+ case(BANK_PRESENT_CS0_CS2_CS3):
58741+ case(BANK_PRESENT_CS0_CS2_CS3_CS4):
58742+ if (busClk >= MV_BOARD_SYSCLK_267MHZ)
58743+ return DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV;
58744+ else
58745+ return DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV;
58746+
58747+ default:
58748+ mvOsOutput("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
58749+ return -1;
58750+ }
58751+ return 0;
58752+}
58753+
58754+/*******************************************************************************
58755+* dunitCtrlLowRegCalc - Calculate sdram dunit control low register
58756+*
58757+* DESCRIPTION: Calculate sdram dunit control low register optimized value based
58758+* on the bank info parameters and the minCas.
58759+*
58760+* INPUT:
58761+* pBankInfo - sdram bank parameters
58762+* minCas - minimum CAS supported.
58763+*
58764+* OUTPUT:
58765+* None
58766+*
58767+* RETURN:
58768+* sdram dunit control low reg value.
58769+*
58770+*******************************************************************************/
58771+static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk, MV_STATUS TTMode)
58772+{
58773+ MV_U32 dunitCtrlLow, cl;
58774+ MV_U32 sbOutR[4]={3,5,7,9} ;
58775+ MV_U32 sbOutU[4]={1,3,5,7} ;
58776+
58777+ dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
58778+
58779+ DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
58780+
58781+ /* Clear StBurstOutDel field */
58782+ dunitCtrlLow &= ~SDRAM_SB_OUT_MASK;
58783+
58784+ /* Clear StBurstInDel field */
58785+ dunitCtrlLow &= ~SDRAM_SB_IN_MASK;
58786+
58787+ /* Clear CtrlPos field */
58788+ dunitCtrlLow &= ~SDRAM_CTRL_POS_MASK;
58789+
58790+ /* Clear 2T field */
58791+ dunitCtrlLow &= ~SDRAM_2T_MASK;
58792+ if (TTMode == MV_TRUE)
58793+ {
58794+ dunitCtrlLow |= SDRAM_2T_MODE;
58795+ }
58796+
58797+ /* For proper sample of read data set the Dunit Control register's */
58798+ /* stBurstInDel bits [27:24] */
58799+ /* 200MHz - 267MHz None reg = CL + 1 */
58800+ /* 200MHz - 267MHz reg = CL + 2 */
58801+ /* > 267MHz None reg = CL + 2 */
58802+ /* > 267MHz reg = CL + 3 */
58803+
58804+ /* For proper sample of read data set the Dunit Control register's */
58805+ /* stBurstOutDel bits [23:20] */
58806+ /********-********-********-********-
58807+ * CL=3 | CL=4 | CL=5 | CL=6 |
58808+ *********-********-********-********-
58809+ Not Reg. * 0001 | 0011 | 0101 | 0111 |
58810+ *********-********-********-********-
58811+ Registered * 0011 | 0101 | 0111 | 1001 |
58812+ *********-********-********-********/
58813+
58814+ /* Set Dunit Control low default value */
58815+ dunitCtrlLow |= SDRAM_DUNIT_CTRL_LOW_DDR2_DV;
58816+
58817+ switch (minCas)
58818+ {
58819+ case DDR2_CL_3: cl = 3; break;
58820+ case DDR2_CL_4: cl = 4; break;
58821+ case DDR2_CL_5: cl = 5; break;
58822+ case DDR2_CL_6: cl = 6; break;
58823+ default:
58824+ mvOsOutput("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n", minCas);
58825+ return -1;
58826+ }
58827+
58828+ /* registerd DDR SDRAM? */
58829+ if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
58830+ {
58831+ dunitCtrlLow |= (sbOutR[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
58832+ }
58833+ else
58834+ {
58835+ dunitCtrlLow |= (sbOutU[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
58836+ }
58837+
58838+ DB(mvOsPrintf("\n\ndunitCtrlLowRegCalc: CL = %d, frequencies=%d\n", cl, busClk));
58839+
58840+ if (busClk <= MV_BOARD_SYSCLK_267MHZ)
58841+ {
58842+ if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
58843+ cl = cl + 2;
58844+ else
58845+ cl = cl + 1;
58846+ }
58847+ else
58848+ {
58849+ if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
58850+ cl = cl + 3;
58851+ else
58852+ cl = cl + 2;
58853+ }
58854+
58855+ DB(mvOsPrintf("dunitCtrlLowRegCalc: SDRAM_SB_IN_DEL_OFFS = %d \n", cl));
58856+ dunitCtrlLow |= cl << SDRAM_SB_IN_DEL_OFFS;
58857+
58858+ DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
58859+
58860+ return dunitCtrlLow;
58861+}
58862+
58863+/*******************************************************************************
58864+* dunitCtrlHighRegCalc - Calculate sdram dunit control high register
58865+*
58866+* DESCRIPTION: Calculate sdram dunit control high register optimized value based
58867+* on the bus clock.
58868+*
58869+* INPUT:
58870+* busClk - DRAM frequency.
58871+*
58872+* OUTPUT:
58873+* None
58874+*
58875+* RETURN:
58876+* sdram dunit control high reg value.
58877+*
58878+*******************************************************************************/
58879+static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
58880+{
58881+ MV_U32 dunitCtrlHigh;
58882+ dunitCtrlHigh = MV_REG_READ(SDRAM_DUNIT_CTRL_HI_REG);
58883+ if(busClk > MV_BOARD_SYSCLK_300MHZ)
58884+ dunitCtrlHigh |= SDRAM__P2D_EN;
58885+ else
58886+ dunitCtrlHigh &= ~SDRAM__P2D_EN;
58887+
58888+ if(busClk > MV_BOARD_SYSCLK_267MHZ)
58889+ dunitCtrlHigh |= (SDRAM__WR_MESH_DELAY_EN | SDRAM__PUP_ZERO_SKEW_EN | SDRAM__ADD_HALF_FCC_EN);
58890+
58891+ /* If ECC support we turn on D2P sample */
58892+ dunitCtrlHigh &= ~SDRAM__D2P_EN; /* Clear D2P bit */
58893+ if (( pBankInfo->errorCheckType ) && (busClk > MV_BOARD_SYSCLK_267MHZ))
58894+ dunitCtrlHigh |= SDRAM__D2P_EN;
58895+
58896+ return dunitCtrlHigh;
58897+}
58898+
58899+/*******************************************************************************
58900+* sdramAddrCtrlRegCalc - Calculate sdram address control register
58901+*
58902+* DESCRIPTION: Calculate sdram address control register optimized value based
58903+* on the bank info parameters and the minCas.
58904+*
58905+* INPUT:
58906+* pBankInfo - sdram bank parameters
58907+*
58908+* OUTPUT:
58909+* None
58910+*
58911+* RETURN:
58912+* sdram address control reg value.
58913+*
58914+*******************************************************************************/
58915+static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1)
58916+{
58917+ MV_U32 addrCtrl = 0;
58918+
58919+ if (pBankInfoDIMM1->size)
58920+ {
58921+ switch (pBankInfoDIMM1->sdramWidth)
58922+ {
58923+ case 4: /* memory is x4 */
58924+ mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
58925+ return -1;
58926+ break;
58927+ case 8: /* memory is x8 */
58928+ addrCtrl |= SDRAM_ADDRSEL_X8(2) | SDRAM_ADDRSEL_X8(3);
58929+ DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x8\n"));
58930+ break;
58931+ case 16:
58932+ addrCtrl |= SDRAM_ADDRSEL_X16(2) | SDRAM_ADDRSEL_X16(3);
58933+ DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x16\n"));
58934+ break;
58935+ default: /* memory width unsupported */
58936+ mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
58937+ return -1;
58938+ }
58939+ }
58940+
58941+ switch (pBankInfo->sdramWidth)
58942+ {
58943+ case 4: /* memory is x4 */
58944+ mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
58945+ return -1;
58946+ break;
58947+ case 8: /* memory is x8 */
58948+ addrCtrl |= SDRAM_ADDRSEL_X8(0) | SDRAM_ADDRSEL_X8(1);
58949+ DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x8\n"));
58950+ break;
58951+ case 16:
58952+ addrCtrl |= SDRAM_ADDRSEL_X16(0) | SDRAM_ADDRSEL_X16(1);
58953+ DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x16\n"));
58954+ break;
58955+ default: /* memory width unsupported */
58956+ mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
58957+ return -1;
58958+ }
58959+
58960+ /* Note that density is in MB units */
58961+ switch (pBankInfo->deviceDensity)
58962+ {
58963+ case 256: /* 256 Mbit */
58964+ DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
58965+ addrCtrl |= SDRAM_DSIZE_256Mb(0) | SDRAM_DSIZE_256Mb(1);
58966+ break;
58967+ case 512: /* 512 Mbit */
58968+ DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
58969+ addrCtrl |= SDRAM_DSIZE_512Mb(0) | SDRAM_DSIZE_512Mb(1);
58970+ break;
58971+ case 1024: /* 1 Gbit */
58972+ DB(mvOsPrintf("DRAM Device Density 1Gbit\n"));
58973+ addrCtrl |= SDRAM_DSIZE_1Gb(0) | SDRAM_DSIZE_1Gb(1);
58974+ break;
58975+ case 2048: /* 2 Gbit */
58976+ DB(mvOsPrintf("DRAM Device Density 2Gbit\n"));
58977+ addrCtrl |= SDRAM_DSIZE_2Gb(0) | SDRAM_DSIZE_2Gb(1);
58978+ break;
58979+ default:
58980+ mvOsOutput("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
58981+ pBankInfo->deviceDensity);
58982+ return -1;
58983+ }
58984+
58985+ if (pBankInfoDIMM1->size)
58986+ {
58987+ switch (pBankInfoDIMM1->deviceDensity)
58988+ {
58989+ case 256: /* 256 Mbit */
58990+ DB(mvOsPrintf("DIMM2: DRAM Device Density 256Mbit\n"));
58991+ addrCtrl |= SDRAM_DSIZE_256Mb(2) | SDRAM_DSIZE_256Mb(3);
58992+ break;
58993+ case 512: /* 512 Mbit */
58994+ DB(mvOsPrintf("DIMM2: DRAM Device Density 512Mbit\n"));
58995+ addrCtrl |= SDRAM_DSIZE_512Mb(2) | SDRAM_DSIZE_512Mb(3);
58996+ break;
58997+ case 1024: /* 1 Gbit */
58998+ DB(mvOsPrintf("DIMM2: DRAM Device Density 1Gbit\n"));
58999+ addrCtrl |= SDRAM_DSIZE_1Gb(2) | SDRAM_DSIZE_1Gb(3);
59000+ break;
59001+ case 2048: /* 2 Gbit */
59002+ DB(mvOsPrintf("DIMM2: DRAM Device Density 2Gbit\n"));
59003+ addrCtrl |= SDRAM_DSIZE_2Gb(2) | SDRAM_DSIZE_2Gb(3);
59004+ break;
59005+ default:
59006+ mvOsOutput("DIMM2: Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
59007+ pBankInfoDIMM1->deviceDensity);
59008+ return -1;
59009+ }
59010+ }
59011+ /* SDRAM address control */
59012+ DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
59013+
59014+ return addrCtrl;
59015+}
59016+
59017+/*******************************************************************************
59018+* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
59019+*
59020+* DESCRIPTION:
59021+* This function calculates sdram timing control low register
59022+* optimized value based on the bank info parameters and the minCas.
59023+*
59024+* INPUT:
59025+* pBankInfo - sdram bank parameters
59026+* minCas - minimum CAS supported.
59027+* busClk - Bus clock
59028+*
59029+* OUTPUT:
59030+* None
59031+*
59032+* RETURN:
59033+* sdram timing control low reg value.
59034+*
59035+*******************************************************************************/
59036+static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk)
59037+{
59038+ MV_U32 tRp = 0;
59039+ MV_U32 tRrd = 0;
59040+ MV_U32 tRcd = 0;
59041+ MV_U32 tRas = 0;
59042+ MV_U32 tWr = 0;
59043+ MV_U32 tWtr = 0;
59044+ MV_U32 tRtp = 0;
59045+ MV_U32 timeCtrlLow = 0;
59046+
59047+ MV_U32 bankNum;
59048+
59049+ busClk = busClk / 1000000; /* In MHz */
59050+
59051+ /* Scan all DRAM banks to find maximum timing values */
59052+ for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
59053+ {
59054+ tRp = MV_MAX(tRp, pBankInfo[bankNum].minRowPrechargeTime);
59055+ tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
59056+ tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
59057+ tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
59058+ }
59059+
59060+ /* Extract timing (in ns) from SPD value. We ignore the tenth ns part. */
59061+ /* by shifting the data two bits right. */
59062+ tRp = tRp >> 2; /* For example 0x50 -> 20ns */
59063+ tRrd = tRrd >> 2;
59064+ tRcd = tRcd >> 2;
59065+
59066+ /* Extract clock cycles from time parameter. We need to round up */
59067+ tRp = ((busClk * tRp) / 1000) + (((busClk * tRp) % 1000) ? 1 : 0);
59068+ DB(mvOsPrintf("Dram Timing Low: tRp = %d ", tRp));
59069+ tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
59070+ /* JEDEC min reqeirments tRrd = 2 */
59071+ if (tRrd < 2)
59072+ tRrd = 2;
59073+ DB(mvOsPrintf("tRrd = %d ", tRrd));
59074+ tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
59075+ DB(mvOsPrintf("tRcd = %d ", tRcd));
59076+ tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
59077+ DB(mvOsPrintf("tRas = %d ", tRas));
59078+
59079+ /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2 */
59080+ /* Scan all DRAM banks to find maximum timing values */
59081+ for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
59082+ {
59083+ tWr = MV_MAX(tWr, pBankInfo[bankNum].minWriteRecoveryTime);
59084+ tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
59085+ tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
59086+ }
59087+
59088+ /* Extract timing (in ns) from SPD value. We ignore the tenth ns */
59089+ /* part by shifting the data two bits right. */
59090+ tWr = tWr >> 2; /* For example 0x50 -> 20ns */
59091+ tWtr = tWtr >> 2;
59092+ tRtp = tRtp >> 2;
59093+ /* Extract clock cycles from time parameter. We need to round up */
59094+ tWr = ((busClk * tWr) / 1000) + (((busClk * tWr) % 1000) ? 1 : 0);
59095+ DB(mvOsPrintf("tWr = %d ", tWr));
59096+ tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
59097+ /* JEDEC min reqeirments tWtr = 2 */
59098+ if (tWtr < 2)
59099+ tWtr = 2;
59100+ DB(mvOsPrintf("tWtr = %d ", tWtr));
59101+ tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
59102+ /* JEDEC min reqeirments tRtp = 2 */
59103+ if (tRtp < 2)
59104+ tRtp = 2;
59105+ DB(mvOsPrintf("tRtp = %d ", tRtp));
59106+
59107+ /* Note: value of 0 in register means one cycle, 1 means two and so on */
59108+ timeCtrlLow = (((tRp - 1) << SDRAM_TRP_OFFS) |
59109+ ((tRrd - 1) << SDRAM_TRRD_OFFS) |
59110+ ((tRcd - 1) << SDRAM_TRCD_OFFS) |
59111+ (((tRas - 1) << SDRAM_TRAS_OFFS) & SDRAM_TRAS_MASK)|
59112+ ((tWr - 1) << SDRAM_TWR_OFFS) |
59113+ ((tWtr - 1) << SDRAM_TWTR_OFFS) |
59114+ ((tRtp - 1) << SDRAM_TRTP_OFFS));
59115+
59116+ /* Check extended tRas bit */
59117+ if ((tRas - 1) & BIT4)
59118+ timeCtrlLow |= (1 << SDRAM_EXT_TRAS_OFFS);
59119+
59120+ return timeCtrlLow;
59121+}
59122+
59123+/*******************************************************************************
59124+* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
59125+*
59126+* DESCRIPTION:
59127+* This function calculates sdram timing control high register
59128+* optimized value based on the bank info parameters and the bus clock.
59129+*
59130+* INPUT:
59131+* pBankInfo - sdram bank parameters
59132+* busClk - Bus clock
59133+*
59134+* OUTPUT:
59135+* None
59136+*
59137+* RETURN:
59138+* sdram timing control high reg value.
59139+*
59140+*******************************************************************************/
59141+static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
59142+{
59143+ MV_U32 tRfc;
59144+ MV_U32 timingHigh;
59145+ MV_U32 timeNs = 0;
59146+ MV_U32 bankNum;
59147+
59148+ busClk = busClk / 1000000; /* In MHz */
59149+
59150+ /* Set DDR timing high register static configuration bits */
59151+ timingHigh = MV_REG_READ(SDRAM_TIMING_CTRL_HIGH_REG);
59152+
59153+ /* Set DDR timing high register default value */
59154+ timingHigh |= SDRAM_TIMING_CTRL_HIGH_REG_DV;
59155+
59156+ /* Clear tRfc field */
59157+ timingHigh &= ~SDRAM_TRFC_MASK;
59158+
59159+ /* Scan all DRAM banks to find maximum timing values */
59160+ for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
59161+ {
59162+ timeNs = MV_MAX(timeNs, pBankInfo[bankNum].minRefreshToActiveCmd);
59163+ DB(mvOsPrintf("Dram: Timing High: minRefreshToActiveCmd = %d\n",
59164+ pBankInfo[bankNum].minRefreshToActiveCmd));
59165+ }
59166+ if(busClk >= 333 && mvCtrlModelGet() == MV_78XX0_A1_REV)
59167+ {
59168+ timingHigh |= 0x1 << SDRAM_TR2W_W2R_OFFS;
59169+ }
59170+
59171+ tRfc = ((busClk * timeNs) / 1000) + (((busClk * timeNs) % 1000) ? 1 : 0);
59172+ /* Note: value of 0 in register means one cycle, 1 means two and so on */
59173+ DB(mvOsPrintf("Dram: Timing High: tRfc = %d\n", tRfc));
59174+ timingHigh |= (((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS);
59175+ DB(mvOsPrintf("Dram: Timing High: tRfc = %d\n", tRfc));
59176+
59177+ /* SDRAM timing high */
59178+ DB(mvOsPrintf("Dram: setting timing high with: %x \n", timingHigh));
59179+
59180+ return timingHigh;
59181+}
59182+/*******************************************************************************
59183+* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
59184+*
59185+* DESCRIPTION:
59186+* This function config DDR2 On Die Termination (ODT) registers.
59187+*
59188+* INPUT:
59189+* pBankInfo - bank info parameters.
59190+*
59191+* OUTPUT:
59192+* None
59193+*
59194+* RETURN:
59195+* None
59196+*******************************************************************************/
59197+static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
59198+{
59199+ MV_U32 populateBanks = 0;
59200+ MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
59201+ int bankNum;
59202+
59203+ /* Represent the populate banks in binary form */
59204+ for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
59205+ {
59206+ if (0 != pBankInfo[bankNum].size)
59207+ {
59208+ populateBanks |= (1 << bankNum);
59209+ }
59210+ }
59211+
59212+ switch(populateBanks)
59213+ {
59214+ case(BANK_PRESENT_CS0):
59215+ case(BANK_PRESENT_CS0_CS1):
59216+ odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS1_DV;
59217+ odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS1_DV;
59218+ dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV;
59219+ break;
59220+ case(BANK_PRESENT_CS0_CS2):
59221+ case(BANK_PRESENT_CS0_CS1_CS2):
59222+ case(BANK_PRESENT_CS0_CS2_CS3):
59223+ case(BANK_PRESENT_CS0_CS2_CS3_CS4):
59224+ odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV;
59225+ odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV;
59226+ dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV;
59227+ break;
59228+ default:
59229+ DB(mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n"));
59230+ return;
59231+ }
59232+ /* DDR2 SDRAM ODT ctrl low */
59233+ DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl low with: %x \n", odtCtrlLow));
59234+ MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
59235+
59236+ /* DDR2 SDRAM ODT ctrl high */
59237+ DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl high with: %x \n", odtCtrlHigh));
59238+ MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
59239+
59240+ /* DDR2 DUNIT ODT ctrl */
59241+ if ( ((mvCtrlModelGet() == MV_78XX0_DEV_ID) && (mvCtrlRevGet() == MV_78XX0_Y0_REV)) ||
59242+ (mvCtrlModelGet() == MV_76100_DEV_ID) ||
59243+ (mvCtrlModelGet() == MV_78100_DEV_ID) ||
59244+ (mvCtrlModelGet() == MV_78200_DEV_ID) )
59245+ dunitOdtCtrl &= ~(BIT9|BIT8); /* Clear ODT always on */
59246+
59247+ DB(mvOsPrintf("DUNIT: DDR2 setting ODT ctrl with: %x \n", dunitOdtCtrl));
59248+ MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
59249+ return;
59250+}
59251+/*******************************************************************************
59252+* sdramDdr2TimeLoRegCalc - Set DDR2 DRAM Timing Low registers.
59253+*
59254+* DESCRIPTION:
59255+* This function config DDR2 DRAM Timing low registers.
59256+*
59257+* INPUT:
59258+* minCas - minimum CAS supported.
59259+*
59260+* OUTPUT:
59261+* None
59262+*
59263+* RETURN:
59264+* DDR2 sdram timing low reg value.
59265+*******************************************************************************/
59266+static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas)
59267+{
59268+ MV_U8 cl = -1;
59269+ MV_U32 ddr2TimeLoReg;
59270+
59271+ /* read and clear the feilds we are going to set */
59272+ ddr2TimeLoReg = MV_REG_READ(SDRAM_DDR2_TIMING_LO_REG);
59273+ ddr2TimeLoReg &= ~(SD2TLR_TODT_ON_RD_MASK |
59274+ SD2TLR_TODT_OFF_RD_MASK |
59275+ SD2TLR_TODT_ON_CTRL_RD_MASK |
59276+ SD2TLR_TODT_OFF_CTRL_RD_MASK);
59277+
59278+ if( minCas == DDR2_CL_3 )
59279+ {
59280+ cl = 3;
59281+ }
59282+ else if( minCas == DDR2_CL_4 )
59283+ {
59284+ cl = 4;
59285+ }
59286+ else if( minCas == DDR2_CL_5 )
59287+ {
59288+ cl = 5;
59289+ }
59290+ else if( minCas == DDR2_CL_6 )
59291+ {
59292+ cl = 6;
59293+ }
59294+ else
59295+ {
59296+ DB(mvOsPrintf("sdramDdr2TimeLoRegCalc: CAS latency %d unsupported. using CAS latency 4\n",
59297+ minCas));
59298+ cl = 4;
59299+ }
59300+
59301+ ddr2TimeLoReg |= ((cl-3) << SD2TLR_TODT_ON_RD_OFFS);
59302+ ddr2TimeLoReg |= ( cl << SD2TLR_TODT_OFF_RD_OFFS);
59303+ ddr2TimeLoReg |= ( cl << SD2TLR_TODT_ON_CTRL_RD_OFFS);
59304+ ddr2TimeLoReg |= ((cl+3) << SD2TLR_TODT_OFF_CTRL_RD_OFFS);
59305+
59306+ /* DDR2 SDRAM timing low */
59307+ DB(mvOsPrintf("Dram: DDR2 setting timing low with: %x \n", ddr2TimeLoReg));
59308+
59309+ return ddr2TimeLoReg;
59310+}
59311+
59312+/*******************************************************************************
59313+* sdramDdr2TimeHiRegCalc - Set DDR2 DRAM Timing High registers.
59314+*
59315+* DESCRIPTION:
59316+* This function config DDR2 DRAM Timing high registers.
59317+*
59318+* INPUT:
59319+* minCas - minimum CAS supported.
59320+*
59321+* OUTPUT:
59322+* None
59323+*
59324+* RETURN:
59325+* DDR2 sdram timing high reg value.
59326+*******************************************************************************/
59327+static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas)
59328+{
59329+ MV_U8 cl = -1;
59330+ MV_U32 ddr2TimeHiReg;
59331+
59332+ /* read and clear the feilds we are going to set */
59333+ ddr2TimeHiReg = MV_REG_READ(SDRAM_DDR2_TIMING_HI_REG);
59334+ ddr2TimeHiReg &= ~(SD2THR_TODT_ON_WR_MASK |
59335+ SD2THR_TODT_OFF_WR_MASK |
59336+ SD2THR_TODT_ON_CTRL_WR_MASK |
59337+ SD2THR_TODT_OFF_CTRL_WR_MASK);
59338+
59339+ if( minCas == DDR2_CL_3 )
59340+ {
59341+ cl = 3;
59342+ }
59343+ else if( minCas == DDR2_CL_4 )
59344+ {
59345+ cl = 4;
59346+ }
59347+ else if( minCas == DDR2_CL_5 )
59348+ {
59349+ cl = 5;
59350+ }
59351+ else if( minCas == DDR2_CL_6 )
59352+ {
59353+ cl = 6;
59354+ }
59355+ else
59356+ {
59357+ mvOsOutput("sdramDdr2TimeHiRegCalc: CAS latency %d unsupported. using CAS latency 4\n",
59358+ minCas);
59359+ cl = 4;
59360+ }
59361+
59362+ ddr2TimeHiReg |= ((cl-3) << SD2THR_TODT_ON_WR_OFFS);
59363+ ddr2TimeHiReg |= ( cl << SD2THR_TODT_OFF_WR_OFFS);
59364+ ddr2TimeHiReg |= ( cl << SD2THR_TODT_ON_CTRL_WR_OFFS);
59365+ ddr2TimeHiReg |= ((cl+3) << SD2THR_TODT_OFF_CTRL_WR_OFFS);
59366+
59367+ /* DDR2 SDRAM timin high */
59368+ DB(mvOsPrintf("Dram: DDR2 setting timing high with: %x \n", ddr2TimeHiReg));
59369+
59370+ return ddr2TimeHiReg;
59371+}
59372+#endif
59373+
59374+/*******************************************************************************
59375+* mvDramIfCalGet - Get CAS Latency
59376+*
59377+* DESCRIPTION:
59378+* This function get the CAS Latency.
59379+*
59380+* INPUT:
59381+* None
59382+*
59383+* OUTPUT:
59384+* None
59385+*
59386+* RETURN:
59387+* CAS latency times 10 (to avoid using floating point).
59388+*
59389+*******************************************************************************/
59390+MV_U32 mvDramIfCalGet(void)
59391+{
59392+ MV_U32 sdramCasLat, casLatMask;
59393+
59394+ casLatMask = (MV_REG_READ(SDRAM_MODE_REG) & SDRAM_CL_MASK);
59395+
59396+ switch (casLatMask)
59397+ {
59398+ case SDRAM_DDR2_CL_3:
59399+ sdramCasLat = 30;
59400+ break;
59401+ case SDRAM_DDR2_CL_4:
59402+ sdramCasLat = 40;
59403+ break;
59404+ case SDRAM_DDR2_CL_5:
59405+ sdramCasLat = 50;
59406+ break;
59407+ case SDRAM_DDR2_CL_6:
59408+ sdramCasLat = 60;
59409+ break;
59410+ default:
59411+ mvOsOutput("mvDramIfCalGet: Err, unknown DDR2 CAL\n");
59412+ return -1;
59413+ }
59414+
59415+ return sdramCasLat;
59416+}
59417+
59418+
59419+/*******************************************************************************
59420+* mvDramIfSelfRefreshSet - Put the dram in self refresh mode -
59421+*
59422+* DESCRIPTION:
59423+* add support in power management.
59424+*
59425+*
59426+* INPUT:
59427+* None
59428+*
59429+* OUTPUT:
59430+* None
59431+*
59432+* RETURN:
59433+* None
59434+*
59435+*******************************************************************************/
59436+
59437+MV_VOID mvDramIfSelfRefreshSet()
59438+{
59439+ MV_U32 operReg;
59440+
59441+ operReg = MV_REG_READ(SDRAM_OPERATION_REG);
59442+ MV_REG_WRITE(SDRAM_OPERATION_REG ,operReg |SDRAM_CMD_SLF_RFRSH);
59443+ /* Read until register is reset to 0 */
59444+ while(MV_REG_READ(SDRAM_OPERATION_REG));
59445+}
59446+/*******************************************************************************
59447+* mvDramIfDimGetSPDversion - return DIMM SPD version.
59448+*
59449+* DESCRIPTION:
59450+* This function prints the DRAM controller information.
59451+*
59452+* INPUT:
59453+* None.
59454+*
59455+* OUTPUT:
59456+* None.
59457+*
59458+* RETURN:
59459+* None.
59460+*
59461+*******************************************************************************/
59462+static void mvDramIfDimGetSPDversion(MV_U32 *pMajor, MV_U32 *pMinor, MV_U32 bankNum)
59463+{
59464+ MV_DIMM_INFO dimmInfo;
59465+ if (bankNum >= MV_DRAM_MAX_CS )
59466+ {
59467+ DB(mvOsPrintf("Dram: mvDramIfDimGetSPDversion bad params \n"));
59468+ return ;
59469+ }
59470+ memset(&dimmInfo,0,sizeof(dimmInfo));
59471+ if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
59472+ {
59473+ DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
59474+ return ;
59475+ }
59476+ *pMajor = dimmInfo.spdRawData[DIMM_SPD_VERSION]/10;
59477+ *pMinor = dimmInfo.spdRawData[DIMM_SPD_VERSION]%10;
59478+}
59479+/*******************************************************************************
59480+* mvDramIfShow - Show DRAM controller information.
59481+*
59482+* DESCRIPTION:
59483+* This function prints the DRAM controller information.
59484+*
59485+* INPUT:
59486+* None.
59487+*
59488+* OUTPUT:
59489+* None.
59490+*
59491+* RETURN:
59492+* None.
59493+*
59494+*******************************************************************************/
59495+void mvDramIfShow(void)
59496+{
59497+ int i, sdramCasLat, sdramCsSize;
59498+ MV_U32 Major=0, Minor=0;
59499+
59500+ mvOsOutput("DRAM Controller info:\n");
59501+
59502+ mvOsOutput("Total DRAM ");
59503+ mvSizePrint(mvDramIfSizeGet());
59504+ mvOsOutput("\n");
59505+
59506+ for(i = 0; i < MV_DRAM_MAX_CS; i++)
59507+ {
59508+ sdramCsSize = mvDramIfBankSizeGet(i);
59509+ if (sdramCsSize)
59510+ {
59511+ if (0 == (i & 1))
59512+ {
59513+ mvDramIfDimGetSPDversion(&Major, &Minor,i);
59514+ mvOsOutput("DIMM %d version %d.%d\n", i/2, Major, Minor);
59515+ }
59516+ mvOsOutput("\tDRAM CS[%d] ", i);
59517+ mvSizePrint(sdramCsSize);
59518+ mvOsOutput("\n");
59519+ }
59520+ }
59521+ sdramCasLat = mvDramIfCalGet();
59522+
59523+ if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_ECC_EN)
59524+ {
59525+ mvOsOutput("ECC enabled, ");
59526+ }
59527+ else
59528+ {
59529+ mvOsOutput("ECC Disabled, ");
59530+ }
59531+
59532+ if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_REGISTERED)
59533+ {
59534+ mvOsOutput("Registered DIMM\n");
59535+ }
59536+ else
59537+ {
59538+ mvOsOutput("Non registered DIMM\n");
59539+ }
59540+
59541+ mvOsOutput("Configured CAS Latency %d.%d\n", sdramCasLat/10, sdramCasLat%10);
59542+}
59543+/*******************************************************************************
59544+* mvDramIfGetFirstCS - find the DRAM bank on the lower address
59545+*
59546+*
59547+* DESCRIPTION:
59548+* This function return the fisrt CS on address 0
59549+*
59550+* INPUT:
59551+* None.
59552+*
59553+* OUTPUT:
59554+* None.
59555+*
59556+* RETURN:
59557+* SDRAM_CS0 or SDRAM_CS2
59558+*
59559+*******************************************************************************/
59560+MV_U32 mvDramIfGetFirstCS(void)
59561+{
59562+ MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
59563+
59564+ if (DRAM_CS_Order[0] == N_A)
59565+ {
59566+ mvDramBankInfoGet(SDRAM_CS0, &bankInfo[SDRAM_CS0]);
59567+#ifdef MV_INCLUDE_SDRAM_CS2
59568+ mvDramBankInfoGet(SDRAM_CS2, &bankInfo[SDRAM_CS2]);
59569+#endif
59570+
59571+#ifdef MV_INCLUDE_SDRAM_CS2
59572+ if (bankInfo[SDRAM_CS0].size < bankInfo[SDRAM_CS2].size)
59573+ {
59574+ DRAM_CS_Order[0] = SDRAM_CS2;
59575+ DRAM_CS_Order[1] = SDRAM_CS3;
59576+ DRAM_CS_Order[2] = SDRAM_CS0;
59577+ DRAM_CS_Order[3] = SDRAM_CS1;
59578+
59579+ return SDRAM_CS2;
59580+ }
59581+#endif
59582+ DRAM_CS_Order[0] = SDRAM_CS0;
59583+ DRAM_CS_Order[1] = SDRAM_CS1;
59584+#ifdef MV_INCLUDE_SDRAM_CS2
59585+ DRAM_CS_Order[2] = SDRAM_CS2;
59586+ DRAM_CS_Order[3] = SDRAM_CS3;
59587+#endif
59588+ return SDRAM_CS0;
59589+ }
59590+ return DRAM_CS_Order[0];
59591+}
59592+/*******************************************************************************
59593+* mvDramIfGetCSorder -
59594+*
59595+*
59596+* DESCRIPTION:
59597+* This function return the fisrt CS on address 0
59598+*
59599+* INPUT:
59600+* CS number.
59601+*
59602+* OUTPUT:
59603+* CS order.
59604+*
59605+* RETURN:
59606+* SDRAM_CS0 or SDRAM_CS2
59607+*
59608+* NOTE: mvDramIfGetFirstCS must be caled before this subroutine
59609+*******************************************************************************/
59610+MV_U32 mvDramIfGetCSorder(MV_U32 csOrder )
59611+{
59612+ return DRAM_CS_Order[csOrder];
59613+}
59614+
59615diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h
59616new file mode 100644
59617index 0000000..b7b596c
59618--- /dev/null
59619+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h
59620@@ -0,0 +1,172 @@
59621+/*******************************************************************************
59622+Copyright (C) Marvell International Ltd. and its affiliates
59623+
59624+This software file (the "File") is owned and distributed by Marvell
59625+International Ltd. and/or its affiliates ("Marvell") under the following
59626+alternative licensing terms. Once you have made an election to distribute the
59627+File under one of the following license alternatives, please (i) delete this
59628+introductory statement regarding license alternatives, (ii) delete the two
59629+license alternatives that you have not elected to use and (iii) preserve the
59630+Marvell copyright notice above.
59631+
59632+********************************************************************************
59633+Marvell Commercial License Option
59634+
59635+If you received this File from Marvell and you have entered into a commercial
59636+license agreement (a "Commercial License") with Marvell, the File is licensed
59637+to you under the terms of the applicable Commercial License.
59638+
59639+********************************************************************************
59640+Marvell GPL License Option
59641+
59642+If you received this File from Marvell, you may opt to use, redistribute and/or
59643+modify this File in accordance with the terms and conditions of the General
59644+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
59645+available along with the File in the license.txt file or by writing to the Free
59646+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
59647+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
59648+
59649+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
59650+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
59651+DISCLAIMED. The GPL License provides additional details about this warranty
59652+disclaimer.
59653+********************************************************************************
59654+Marvell BSD License Option
59655+
59656+If you received this File from Marvell, you may opt to use, redistribute and/or
59657+modify this File under the following licensing terms.
59658+Redistribution and use in source and binary forms, with or without modification,
59659+are permitted provided that the following conditions are met:
59660+
59661+ * Redistributions of source code must retain the above copyright notice,
59662+ this list of conditions and the following disclaimer.
59663+
59664+ * Redistributions in binary form must reproduce the above copyright
59665+ notice, this list of conditions and the following disclaimer in the
59666+ documentation and/or other materials provided with the distribution.
59667+
59668+ * Neither the name of Marvell nor the names of its contributors may be
59669+ used to endorse or promote products derived from this software without
59670+ specific prior written permission.
59671+
59672+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
59673+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59674+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59675+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
59676+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59677+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59678+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
59679+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59680+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59681+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59682+
59683+*******************************************************************************/
59684+
59685+
59686+#ifndef __INCmvDramIfh
59687+#define __INCmvDramIfh
59688+
59689+#ifdef __cplusplus
59690+extern "C" {
59691+#endif /* __cplusplus */
59692+
59693+/* includes */
59694+#include "ddr2/mvDramIfRegs.h"
59695+#include "ddr2/mvDramIfConfig.h"
59696+#include "ctrlEnv/mvCtrlEnvLib.h"
59697+
59698+/* defines */
59699+/* DRAM Timing parameters */
59700+#define SDRAM_TWR 15 /* ns tWr */
59701+#define SDRAM_TRFC_64_512M_AT_200MHZ 70 /* ns tRfc for dens 64-512 @ 200MHz */
59702+#define SDRAM_TRFC_64_512M 75 /* ns tRfc for dens 64-512 */
59703+#define SDRAM_TRFC_1G 120 /* ns tRfc for dens 1GB */
59704+#define SDRAM_TR2R_CYC 1 /* cycle for tR2r */
59705+
59706+#define CAL_AUTO_DETECT 0 /* Do not force CAS latancy (mvDramIfDetect) */
59707+#define ECC_DISABLE 1 /* Force ECC to Disable */
59708+#define ECC_ENABLE 0 /* Force ECC to ENABLE */
59709+/* typedefs */
59710+
59711+/* enumeration for memory types */
59712+typedef enum _mvMemoryType
59713+{
59714+ MEM_TYPE_SDRAM,
59715+ MEM_TYPE_DDR1,
59716+ MEM_TYPE_DDR2
59717+}MV_MEMORY_TYPE;
59718+
59719+/* enumeration for DDR2 supported CAS Latencies */
59720+typedef enum _mvDimmDdr2Cas
59721+{
59722+ DDR2_CL_3 = 0x08,
59723+ DDR2_CL_4 = 0x10,
59724+ DDR2_CL_5 = 0x20,
59725+ DDR2_CL_6 = 0x40,
59726+ DDR2_CL_FAULT
59727+} MV_DIMM_DDR2_CAS;
59728+
59729+
59730+typedef struct _mvDramBankInfo
59731+{
59732+ MV_MEMORY_TYPE memoryType; /* DDR1, DDR2 or SDRAM */
59733+
59734+ /* DIMM dimensions */
59735+ MV_U32 numOfRowAddr;
59736+ MV_U32 numOfColAddr;
59737+ MV_U32 dataWidth;
59738+ MV_U32 errorCheckType; /* ECC , PARITY..*/
59739+ MV_U32 sdramWidth; /* 4,8,16 or 32 */
59740+ MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
59741+ MV_U32 burstLengthSupported;
59742+ MV_U32 numOfBanksOnEachDevice;
59743+ MV_U32 suportedCasLatencies;
59744+ MV_U32 refreshInterval;
59745+
59746+ /* DIMM timing parameters */
59747+ MV_U32 minCycleTimeAtMaxCasLatPs;
59748+ MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
59749+ MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
59750+ MV_U32 minRowPrechargeTime;
59751+ MV_U32 minRowActiveToRowActive;
59752+ MV_U32 minRasToCasDelay;
59753+ MV_U32 minRasPulseWidth;
59754+ MV_U32 minWriteRecoveryTime; /* DDR2 only */
59755+ MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
59756+ MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
59757+ MV_U32 minRefreshToActiveCmd; /* DDR2 only */
59758+
59759+ /* Parameters calculated from the extracted DIMM information */
59760+ MV_U32 size;
59761+ MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit */
59762+ MV_U32 numberOfDevices;
59763+
59764+ /* DIMM attributes (MV_TRUE for yes) */
59765+ MV_BOOL registeredAddrAndControlInputs;
59766+ MV_BOOL registeredDQMBinputs;
59767+
59768+}MV_DRAM_BANK_INFO;
59769+
59770+#include "ddr2/spd/mvSpd.h"
59771+
59772+/* mvDramIf.h API list */
59773+MV_VOID mvDramIfBasicAsmInit(MV_VOID);
59774+MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable);
59775+MV_VOID _mvDramIfConfig(int entryNum);
59776+
59777+MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum);
59778+MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum);
59779+MV_U32 mvDramIfSizeGet(MV_VOID);
59780+MV_U32 mvDramIfCalGet(void);
59781+MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold);
59782+MV_VOID mvDramIfSelfRefreshSet(void);
59783+void mvDramIfShow(void);
59784+MV_U32 mvDramIfGetFirstCS(void);
59785+MV_U32 mvDramIfGetCSorder(MV_U32 csOrder );
59786+MV_U32 mvDramCsSizeGet(MV_U32 csNum);
59787+
59788+#ifdef __cplusplus
59789+}
59790+#endif /* __cplusplus */
59791+
59792+#endif /* __INCmvDramIfh */
59793diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h
59794new file mode 100644
59795index 0000000..b008c23
59796--- /dev/null
59797+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h
59798@@ -0,0 +1,157 @@
59799+/*******************************************************************************
59800+Copyright (C) Marvell International Ltd. and its affiliates
59801+
59802+This software file (the "File") is owned and distributed by Marvell
59803+International Ltd. and/or its affiliates ("Marvell") under the following
59804+alternative licensing terms. Once you have made an election to distribute the
59805+File under one of the following license alternatives, please (i) delete this
59806+introductory statement regarding license alternatives, (ii) delete the two
59807+license alternatives that you have not elected to use and (iii) preserve the
59808+Marvell copyright notice above.
59809+
59810+********************************************************************************
59811+Marvell Commercial License Option
59812+
59813+If you received this File from Marvell and you have entered into a commercial
59814+license agreement (a "Commercial License") with Marvell, the File is licensed
59815+to you under the terms of the applicable Commercial License.
59816+
59817+********************************************************************************
59818+Marvell GPL License Option
59819+
59820+If you received this File from Marvell, you may opt to use, redistribute and/or
59821+modify this File in accordance with the terms and conditions of the General
59822+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
59823+available along with the File in the license.txt file or by writing to the Free
59824+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
59825+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
59826+
59827+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
59828+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
59829+DISCLAIMED. The GPL License provides additional details about this warranty
59830+disclaimer.
59831+********************************************************************************
59832+Marvell BSD License Option
59833+
59834+If you received this File from Marvell, you may opt to use, redistribute and/or
59835+modify this File under the following licensing terms.
59836+Redistribution and use in source and binary forms, with or without modification,
59837+are permitted provided that the following conditions are met:
59838+
59839+ * Redistributions of source code must retain the above copyright notice,
59840+ this list of conditions and the following disclaimer.
59841+
59842+ * Redistributions in binary form must reproduce the above copyright
59843+ notice, this list of conditions and the following disclaimer in the
59844+ documentation and/or other materials provided with the distribution.
59845+
59846+ * Neither the name of Marvell nor the names of its contributors may be
59847+ used to endorse or promote products derived from this software without
59848+ specific prior written permission.
59849+
59850+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
59851+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59852+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59853+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
59854+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59855+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59856+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
59857+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59858+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59859+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59860+
59861+*******************************************************************************/
59862+
59863+
59864+#ifndef __INCmvDramIfConfigh
59865+#define __INCmvDramIfConfigh
59866+
59867+#ifdef __cplusplus
59868+extern "C" {
59869+#endif /* __cplusplus */
59870+
59871+/* includes */
59872+
59873+/* defines */
59874+
59875+/* registers defaults values */
59876+
59877+#define SDRAM_CONFIG_DV (SDRAM_SRMODE_DRAM | BIT25 | BIT30)
59878+
59879+#define SDRAM_DUNIT_CTRL_LOW_DDR2_DV \
59880+ (SDRAM_SRCLK_KEPT | \
59881+ SDRAM_CLK1DRV_NORMAL | \
59882+ (BIT28 | BIT29))
59883+
59884+#define SDRAM_ADDR_CTRL_DV 2
59885+
59886+#define SDRAM_TIMING_CTRL_LOW_REG_DV \
59887+ ((0x2 << SDRAM_TRCD_OFFS) | \
59888+ (0x2 << SDRAM_TRP_OFFS) | \
59889+ (0x1 << SDRAM_TWR_OFFS) | \
59890+ (0x0 << SDRAM_TWTR_OFFS) | \
59891+ (0x5 << SDRAM_TRAS_OFFS) | \
59892+ (0x1 << SDRAM_TRRD_OFFS))
59893+
59894+/* Note: value of 0 in register means one cycle, 1 means two and so on */
59895+#define SDRAM_TIMING_CTRL_HIGH_REG_DV \
59896+ ((0x0 << SDRAM_TR2R_OFFS) | \
59897+ (0x0 << SDRAM_TR2W_W2R_OFFS) | \
59898+ (0x1 << SDRAM_TW2W_OFFS))
59899+
59900+#define SDRAM_OPEN_PAGES_CTRL_REG_DV SDRAM_OPEN_PAGE_EN
59901+
59902+/* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode */
59903+/* CS0 0x84210000 0x00000000 0x0000780F 0x00000440 */
59904+/* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440 */
59905+/* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
59906+/* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
59907+/* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
59908+/* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
59909+
59910+#define DDR2_ODT_CTRL_LOW_CS0_CS1_DV 0x84210000
59911+#define DDR2_ODT_CTRL_HIGH_CS0_CS1_DV 0x00000000
59912+#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV 0x0000E80F
59913+#ifdef MV78XX0
59914+#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV 0x00000040
59915+#else
59916+#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV 0x00000440
59917+#endif
59918+
59919+#define DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV 0x030C030C
59920+#define DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV 0x00000000
59921+#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV 0x0000F40F
59922+#ifdef MV78XX0
59923+#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV 0x00000004
59924+#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV 0x00000044
59925+#else
59926+#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV 0x00000404
59927+#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV 0x00000444
59928+#endif
59929+
59930+/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */
59931+#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
59932+ (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
59933+
59934+#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV \
59935+ (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
59936+
59937+/* DDR SDRAM Mode Register default value */
59938+#define DDR2_MODE_REG_DV (SDRAM_BURST_LEN_4 | SDRAM_WR_3_CYC)
59939+/* DDR SDRAM Timing parameter default values */
59940+#define SDRAM_TIMING_CTRL_LOW_REG_DEFAULT 0x33136552
59941+#define SDRAM_TRFC_DEFAULT_VALUE 0x34
59942+#define SDRAM_TRFC_DEFAULT SDRAM_TRFC_DEFAULT_VALUE
59943+#define SDRAM_TW2W_DEFALT (0x1 << SDRAM_TW2W_OFFS)
59944+
59945+#define SDRAM_TIMING_CTRL_HIGH_REG_DEFAULT (SDRAM_TRFC_DEFAULT | SDRAM_TW2W_DEFALT)
59946+
59947+#define SDRAM_FTDLL_REG_DEFAULT_LEFT 0x88C800
59948+#define SDRAM_FTDLL_REG_DEFAULT_RIGHT 0x88C800
59949+#define SDRAM_FTDLL_REG_DEFAULT_UP 0x88C800
59950+
59951+#ifdef __cplusplus
59952+}
59953+#endif /* __cplusplus */
59954+
59955+#endif /* __INCmvDramIfh */
59956diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h
59957new file mode 100644
59958index 0000000..c2458a6
59959--- /dev/null
59960+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h
59961@@ -0,0 +1,423 @@
59962+/*******************************************************************************
59963+Copyright (C) Marvell International Ltd. and its affiliates
59964+
59965+This software file (the "File") is owned and distributed by Marvell
59966+International Ltd. and/or its affiliates ("Marvell") under the following
59967+alternative licensing terms. Once you have made an election to distribute the
59968+File under one of the following license alternatives, please (i) delete this
59969+introductory statement regarding license alternatives, (ii) delete the two
59970+license alternatives that you have not elected to use and (iii) preserve the
59971+Marvell copyright notice above.
59972+
59973+********************************************************************************
59974+Marvell Commercial License Option
59975+
59976+If you received this File from Marvell and you have entered into a commercial
59977+license agreement (a "Commercial License") with Marvell, the File is licensed
59978+to you under the terms of the applicable Commercial License.
59979+
59980+********************************************************************************
59981+Marvell GPL License Option
59982+
59983+If you received this File from Marvell, you may opt to use, redistribute and/or
59984+modify this File in accordance with the terms and conditions of the General
59985+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
59986+available along with the File in the license.txt file or by writing to the Free
59987+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
59988+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
59989+
59990+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
59991+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
59992+DISCLAIMED. The GPL License provides additional details about this warranty
59993+disclaimer.
59994+********************************************************************************
59995+Marvell BSD License Option
59996+
59997+If you received this File from Marvell, you may opt to use, redistribute and/or
59998+modify this File under the following licensing terms.
59999+Redistribution and use in source and binary forms, with or without modification,
60000+are permitted provided that the following conditions are met:
60001+
60002+ * Redistributions of source code must retain the above copyright notice,
60003+ this list of conditions and the following disclaimer.
60004+
60005+ * Redistributions in binary form must reproduce the above copyright
60006+ notice, this list of conditions and the following disclaimer in the
60007+ documentation and/or other materials provided with the distribution.
60008+
60009+ * Neither the name of Marvell nor the names of its contributors may be
60010+ used to endorse or promote products derived from this software without
60011+ specific prior written permission.
60012+
60013+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
60014+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
60015+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60016+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
60017+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
60018+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60019+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
60020+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60021+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60022+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60023+
60024+*******************************************************************************/
60025+
60026+#ifndef __INCmvDramIfRegsh
60027+#define __INCmvDramIfRegsh
60028+
60029+#ifdef __cplusplus
60030+extern "C" {
60031+#endif /* __cplusplus */
60032+
60033+/* DDR SDRAM Controller Address Decode Registers */
60034+ /* SDRAM CSn Base Address Register (SCBAR) */
60035+#define SDRAM_BASE_ADDR_REG(cpu,csNum) (0x1500 + ((csNum) * 8) + ((cpu) * 0x70))
60036+#define SCBAR_BASE_OFFS 16
60037+#define SCBAR_BASE_MASK (0xffff << SCBAR_BASE_OFFS)
60038+#define SCBAR_BASE_ALIGNMENT 0x10000
60039+
60040+/* SDRAM CSn Size Register (SCSR) */
60041+#define SDRAM_SIZE_REG(cpu,csNum) (0x1504 + ((csNum) * 8) + ((cpu) * 0x70))
60042+#define SCSR_SIZE_OFFS 24
60043+#define SCSR_SIZE_MASK (0xff << SCSR_SIZE_OFFS)
60044+#define SCSR_SIZE_ALIGNMENT 0x1000000
60045+#define SCSR_WIN_EN BIT0
60046+
60047+/* configuration register */
60048+#define SDRAM_CONFIG_REG (DRAM_BASE + 0x1400)
60049+#define SDRAM_REFRESH_OFFS 0
60050+#define SDRAM_REFRESH_MAX 0x3FFF
60051+#define SDRAM_REFRESH_MASK (SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)
60052+#define SDRAM_DWIDTH_OFFS 15
60053+#define SDRAM_DWIDTH_MASK (1 << SDRAM_DWIDTH_OFFS)
60054+#define SDRAM_DWIDTH_32BIT (0 << SDRAM_DWIDTH_OFFS)
60055+#define SDRAM_DWIDTH_64BIT (1 << SDRAM_DWIDTH_OFFS)
60056+#define SDRAM_REGISTERED (1 << 17)
60057+#define SDRAM_ECC_OFFS 18
60058+#define SDRAM_ECC_MASK (1 << SDRAM_ECC_OFFS)
60059+#define SDRAM_ECC_DIS (0 << SDRAM_ECC_OFFS)
60060+#define SDRAM_ECC_EN (1 << SDRAM_ECC_OFFS)
60061+#define SDRAM_IERR_OFFS 19
60062+#define SDRAM_IERR_MASK (1 << SDRAM_IERR_OFFS)
60063+#define SDRAM_IERR_REPORTE (0 << SDRAM_IERR_OFFS)
60064+#define SDRAM_IERR_IGNORE (1 << SDRAM_IERR_OFFS)
60065+#define SDRAM_SRMODE_OFFS 24
60066+#define SDRAM_SRMODE_MASK (1 << SDRAM_SRMODE_OFFS)
60067+#define SDRAM_SRMODE_POWER (0 << SDRAM_SRMODE_OFFS)
60068+#define SDRAM_SRMODE_DRAM (1 << SDRAM_SRMODE_OFFS)
60069+
60070+/* dunit control low register */
60071+#define SDRAM_DUNIT_CTRL_REG (DRAM_BASE + 0x1404)
60072+#define SDRAM_2T_OFFS 4
60073+#define SDRAM_2T_MASK (1 << SDRAM_2T_OFFS)
60074+#define SDRAM_2T_MODE (1 << SDRAM_2T_OFFS)
60075+
60076+#define SDRAM_SRCLK_OFFS 5
60077+#define SDRAM_SRCLK_MASK (1 << SDRAM_SRCLK_OFFS)
60078+#define SDRAM_SRCLK_KEPT (0 << SDRAM_SRCLK_OFFS)
60079+#define SDRAM_SRCLK_GATED (1 << SDRAM_SRCLK_OFFS)
60080+#define SDRAM_CTRL_POS_OFFS 6
60081+#define SDRAM_CTRL_POS_MASK (1 << SDRAM_CTRL_POS_OFFS)
60082+#define SDRAM_CTRL_POS_FALL (0 << SDRAM_CTRL_POS_OFFS)
60083+#define SDRAM_CTRL_POS_RISE (1 << SDRAM_CTRL_POS_OFFS)
60084+#define SDRAM_CLK1DRV_OFFS 12
60085+#define SDRAM_CLK1DRV_MASK (1 << SDRAM_CLK1DRV_OFFS)
60086+#define SDRAM_CLK1DRV_HIGH_Z (0 << SDRAM_CLK1DRV_OFFS)
60087+#define SDRAM_CLK1DRV_NORMAL (1 << SDRAM_CLK1DRV_OFFS)
60088+#define SDRAM_CLK2DRV_OFFS 13
60089+#define SDRAM_CLK2DRV_MASK (1 << SDRAM_CLK2DRV_OFFS)
60090+#define SDRAM_CLK2DRV_HIGH_Z (0 << SDRAM_CLK2DRV_OFFS)
60091+#define SDRAM_CLK2DRV_NORMAL (1 << SDRAM_CLK2DRV_OFFS)
60092+#define SDRAM_SB_OUT_DEL_OFFS 20
60093+#define SDRAM_SB_OUT_DEL_MAX 0xf
60094+#define SDRAM_SB_OUT_MASK (SDRAM_SB_OUT_DEL_MAX<<SDRAM_SB_OUT_DEL_OFFS)
60095+#define SDRAM_SB_IN_DEL_OFFS 24
60096+#define SDRAM_SB_IN_DEL_MAX 0xf
60097+#define SDRAM_SB_IN_MASK (SDRAM_SB_IN_DEL_MAX<<SDRAM_SB_IN_DEL_OFFS)
60098+
60099+/* dunit control hight register */
60100+#define SDRAM_DUNIT_CTRL_HI_REG (DRAM_BASE + 0x1424)
60101+#define SDRAM__D2P_OFFS 7
60102+#define SDRAM__D2P_EN (1 << SDRAM__D2P_OFFS)
60103+#define SDRAM__P2D_OFFS 8
60104+#define SDRAM__P2D_EN (1 << SDRAM__P2D_OFFS)
60105+#define SDRAM__ADD_HALF_FCC_OFFS 9
60106+#define SDRAM__ADD_HALF_FCC_EN (1 << SDRAM__ADD_HALF_FCC_OFFS)
60107+#define SDRAM__PUP_ZERO_SKEW_OFFS 10
60108+#define SDRAM__PUP_ZERO_SKEW_EN (1 << SDRAM__PUP_ZERO_SKEW_OFFS)
60109+#define SDRAM__WR_MESH_DELAY_OFFS 11
60110+#define SDRAM__WR_MESH_DELAY_EN (1 << SDRAM__WR_MESH_DELAY_OFFS)
60111+
60112+/* sdram timing control low register */
60113+#define SDRAM_TIMING_CTRL_LOW_REG (DRAM_BASE + 0x1408)
60114+#define SDRAM_TRCD_OFFS 4
60115+#define SDRAM_TRCD_MASK (0xF << SDRAM_TRCD_OFFS)
60116+#define SDRAM_TRP_OFFS 8
60117+#define SDRAM_TRP_MASK (0xF << SDRAM_TRP_OFFS)
60118+#define SDRAM_TWR_OFFS 12
60119+#define SDRAM_TWR_MASK (0xF << SDRAM_TWR_OFFS)
60120+#define SDRAM_TWTR_OFFS 16
60121+#define SDRAM_TWTR_MASK (0xF << SDRAM_TWTR_OFFS)
60122+#define SDRAM_TRAS_OFFS 0
60123+#define SDRAM_TRAS_MASK (0xF << SDRAM_TRAS_OFFS)
60124+#define SDRAM_EXT_TRAS_OFFS 20
60125+#define SDRAM_EXT_TRAS_MASK (0x1 << SDRAM_EXT_TRAS_OFFS)
60126+#define SDRAM_TRRD_OFFS 24
60127+#define SDRAM_TRRD_MASK (0xF << SDRAM_TRRD_OFFS)
60128+#define SDRAM_TRTP_OFFS 28
60129+#define SDRAM_TRTP_MASK (0xF << SDRAM_TRTP_OFFS)
60130+#define SDRAM_TRTP_DDR1 (0x1 << SDRAM_TRTP_OFFS)
60131+
60132+/* sdram timing control high register */
60133+#define SDRAM_TIMING_CTRL_HIGH_REG (DRAM_BASE + 0x140c)
60134+#define SDRAM_TRFC_OFFS 0
60135+#define SDRAM_TRFC_MASK (0x3F << SDRAM_TRFC_OFFS)
60136+#define SDRAM_TR2R_OFFS 7
60137+#define SDRAM_TR2R_MASK (0x3 << SDRAM_TR2R_OFFS)
60138+#define SDRAM_TR2W_W2R_OFFS 9
60139+#define SDRAM_TR2W_W2R_MASK (0x3 << SDRAM_TR2W_W2R_OFFS)
60140+#define SDRAM_TW2W_OFFS 11
60141+#define SDRAM_TW2W_MASK (0x3 << SDRAM_TW2W_OFFS)
60142+
60143+/* sdram DDR2 timing low register (SD2TLR) */
60144+#define SDRAM_DDR2_TIMING_LO_REG (DRAM_BASE + 0x1428)
60145+#define SD2TLR_TODT_ON_RD_OFFS 4
60146+#define SD2TLR_TODT_ON_RD_MASK (0xF << SD2TLR_TODT_ON_RD_OFFS)
60147+#define SD2TLR_TODT_OFF_RD_OFFS 8
60148+#define SD2TLR_TODT_OFF_RD_MASK (0xF << SD2TLR_TODT_OFF_RD_OFFS)
60149+#define SD2TLR_TODT_ON_CTRL_RD_OFFS 12
60150+#define SD2TLR_TODT_ON_CTRL_RD_MASK (0xF << SD2TLR_TODT_ON_CTRL_RD_OFFS)
60151+#define SD2TLR_TODT_OFF_CTRL_RD_OFFS 16
60152+#define SD2TLR_TODT_OFF_CTRL_RD_MASK (0xF << SD2TLR_TODT_OFF_CTRL_RD_OFFS)
60153+
60154+/* sdram DDR2 timing high register (SD2TLR) */
60155+#define SDRAM_DDR2_TIMING_HI_REG (DRAM_BASE + 0x147C)
60156+#define SD2THR_TODT_ON_WR_OFFS 0
60157+#define SD2THR_TODT_ON_WR_MASK (0xF << SD2THR_TODT_ON_WR_OFFS)
60158+#define SD2THR_TODT_OFF_WR_OFFS 4
60159+#define SD2THR_TODT_OFF_WR_MASK (0xF << SD2THR_TODT_OFF_WR_OFFS)
60160+#define SD2THR_TODT_ON_CTRL_WR_OFFS 8
60161+#define SD2THR_TODT_ON_CTRL_WR_MASK (0xF << SD2THR_TODT_ON_CTRL_WR_OFFS)
60162+#define SD2THR_TODT_OFF_CTRL_WR_OFFS 12
60163+#define SD2THR_TODT_OFF_CTRL_WR_MASK (0xF << SD2THR_TODT_OFF_CTRL_WR_OFFS)
60164+
60165+/* address control register */
60166+#define SDRAM_ADDR_CTRL_REG (DRAM_BASE + 0x1410)
60167+#define SDRAM_ADDRSEL_OFFS(cs) (4 * (cs))
60168+#define SDRAM_ADDRSEL_MASK(cs) (0x3 << SDRAM_ADDRSEL_OFFS(cs))
60169+#define SDRAM_ADDRSEL_X8(cs) (0x0 << SDRAM_ADDRSEL_OFFS(cs))
60170+#define SDRAM_ADDRSEL_X16(cs) (0x1 << SDRAM_ADDRSEL_OFFS(cs))
60171+#define SDRAM_DSIZE_OFFS(cs) (2 + 4 * (cs))
60172+#define SDRAM_DSIZE_MASK(cs) (0x3 << SDRAM_DSIZE_OFFS(cs))
60173+#define SDRAM_DSIZE_256Mb(cs) (0x1 << SDRAM_DSIZE_OFFS(cs))
60174+#define SDRAM_DSIZE_512Mb(cs) (0x2 << SDRAM_DSIZE_OFFS(cs))
60175+#define SDRAM_DSIZE_1Gb(cs) (0x3 << SDRAM_DSIZE_OFFS(cs))
60176+#define SDRAM_DSIZE_2Gb(cs) (0x0 << SDRAM_DSIZE_OFFS(cs))
60177+
60178+/* SDRAM Open Pages Control registers */
60179+#define SDRAM_OPEN_PAGE_CTRL_REG (DRAM_BASE + 0x1414)
60180+#define SDRAM_OPEN_PAGE_EN (0 << 0)
60181+#define SDRAM_OPEN_PAGE_DIS (1 << 0)
60182+
60183+/* sdram opertion register */
60184+#define SDRAM_OPERATION_REG (DRAM_BASE + 0x1418)
60185+#define SDRAM_CMD_OFFS 0
60186+#define SDRAM_CMD_MASK (0xF << SDRAM_CMD_OFFS)
60187+#define SDRAM_CMD_NORMAL (0x0 << SDRAM_CMD_OFFS)
60188+#define SDRAM_CMD_PRECHARGE_ALL (0x1 << SDRAM_CMD_OFFS)
60189+#define SDRAM_CMD_REFRESH_ALL (0x2 << SDRAM_CMD_OFFS)
60190+#define SDRAM_CMD_REG_SET_CMD (0x3 << SDRAM_CMD_OFFS)
60191+#define SDRAM_CMD_EXT_MODE_SET (0x4 << SDRAM_CMD_OFFS)
60192+#define SDRAM_CMD_NOP (0x5 << SDRAM_CMD_OFFS)
60193+#define SDRAM_CMD_SLF_RFRSH (0x7 << SDRAM_CMD_OFFS)
60194+#define SDRAM_CMD_EMRS2_CMD (0x8 << SDRAM_CMD_OFFS)
60195+#define SDRAM_CMD_EMRS3_CMD (0x9 << SDRAM_CMD_OFFS)
60196+
60197+/* sdram mode register */
60198+#define SDRAM_MODE_REG (DRAM_BASE + 0x141c)
60199+#define SDRAM_BURST_LEN_OFFS 0
60200+#define SDRAM_BURST_LEN_MASK (0x7 << SDRAM_BURST_LEN_OFFS)
60201+#define SDRAM_BURST_LEN_4 (0x2 << SDRAM_BURST_LEN_OFFS)
60202+#define SDRAM_CL_OFFS 4
60203+#define SDRAM_CL_MASK (0x7 << SDRAM_CL_OFFS)
60204+#define SDRAM_DDR2_CL_3 (0x3 << SDRAM_CL_OFFS)
60205+#define SDRAM_DDR2_CL_4 (0x4 << SDRAM_CL_OFFS)
60206+#define SDRAM_DDR2_CL_5 (0x5 << SDRAM_CL_OFFS)
60207+#define SDRAM_DDR2_CL_6 (0x6 << SDRAM_CL_OFFS)
60208+
60209+#define SDRAM_TM_OFFS 7
60210+#define SDRAM_TM_MASK (1 << SDRAM_TM_OFFS)
60211+#define SDRAM_TM_NORMAL (0 << SDRAM_TM_OFFS)
60212+#define SDRAM_TM_TEST_MODE (1 << SDRAM_TM_OFFS)
60213+#define SDRAM_DLL_OFFS 8
60214+#define SDRAM_DLL_MASK (1 << SDRAM_DLL_OFFS)
60215+#define SDRAM_DLL_NORMAL (0 << SDRAM_DLL_OFFS)
60216+#define SDRAM_DLL_RESET (1 << SDRAM_DLL_OFFS)
60217+#define SDRAM_WR_OFFS 9
60218+#define SDRAM_WR_MAX 7
60219+#define SDRAM_WR_MASK (SDRAM_WR_MAX << SDRAM_WR_OFFS)
60220+#define SDRAM_WR_2_CYC (1 << SDRAM_WR_OFFS)
60221+#define SDRAM_WR_3_CYC (2 << SDRAM_WR_OFFS)
60222+#define SDRAM_WR_4_CYC (3 << SDRAM_WR_OFFS)
60223+#define SDRAM_WR_5_CYC (4 << SDRAM_WR_OFFS)
60224+#define SDRAM_WR_6_CYC (5 << SDRAM_WR_OFFS)
60225+#define SDRAM_PD_OFFS 12
60226+#define SDRAM_PD_MASK (1 << SDRAM_PD_OFFS)
60227+#define SDRAM_PD_FAST_EXIT (0 << SDRAM_PD_OFFS)
60228+#define SDRAM_PD_SLOW_EXIT (1 << SDRAM_PD_OFFS)
60229+
60230+/* DDR SDRAM Extended Mode register (DSEMR) */
60231+#define SDRAM_EXTENDED_MODE_REG (DRAM_BASE + 0x1420)
60232+#define DSEMR_DLL_ENABLE 0
60233+#define DSEMR_DLL_DISABLE 1
60234+#define DSEMR_DS_OFFS 1
60235+#define DSEMR_DS_MASK (1 << DSEMR_DS_OFFS)
60236+#define DSEMR_DS_NORMAL (0 << DSEMR_DS_OFFS)
60237+#define DSEMR_DS_REDUCED (1 << DSEMR_DS_OFFS)
60238+#define DSEMR_QOFF_OUTPUT_BUFF_EN (0 << 12)
60239+#define DSEMR_RTT0_OFFS 2
60240+#define DSEMR_RTT1_OFFS 6
60241+#define DSEMR_RTT_ODT_DISABLE ((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
60242+#define DSEMR_RTT_ODT_75_OHM ((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
60243+#define DSEMR_RTT_ODT_150_OHM ((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
60244+#define DSEMR_RTT_ODT_50_OHM ((1 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
60245+#define DSEMR_DQS_OFFS 10
60246+#define DSEMR_DQS_MASK (1 << DSEMR_DQS_OFFS)
60247+#define DSEMR_DQS_DIFFERENTIAL (0 << DSEMR_DQS_OFFS)
60248+#define DSEMR_DQS_SINGLE_ENDED (1 << DSEMR_DQS_OFFS)
60249+#define DSEMR_RDQS_ENABLE (1 << 11)
60250+#define DSEMR_QOFF_OUTPUT_BUFF_EN (0 << 12)
60251+#define DSEMR_QOFF_OUTPUT_BUFF_DIS (1 << 12)
60252+
60253+/* DDR SDRAM Operation Control Register */
60254+#define SDRAM_OPERATION_CTRL_REG (DRAM_BASE + 0x142c)
60255+
60256+/* Dunit FTDLL Configuration Register */
60257+#define SDRAM_FTDLL_CONFIG_LEFT_REG (DRAM_BASE + 0x1484)
60258+#define SDRAM_FTDLL_CONFIG_RIGHT_REG (DRAM_BASE + 0x161C)
60259+#define SDRAM_FTDLL_CONFIG_UP_REG (DRAM_BASE + 0x1620)
60260+
60261+/* Pads Calibration register */
60262+#define SDRAM_ADDR_CTRL_PADS_CAL_REG (DRAM_BASE + 0x14c0)
60263+#define SDRAM_DATA_PADS_CAL_REG (DRAM_BASE + 0x14c4)
60264+#define SDRAM_DRVN_OFFS 0
60265+#define SDRAM_DRVN_MASK (0x3F << SDRAM_DRVN_OFFS)
60266+#define SDRAM_DRVP_OFFS 6
60267+#define SDRAM_DRVP_MASK (0x3F << SDRAM_DRVP_OFFS)
60268+#define SDRAM_PRE_DRIVER_STRENGTH_OFFS 12
60269+#define SDRAM_PRE_DRIVER_STRENGTH_MASK (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
60270+#define SDRAM_TUNE_EN BIT16
60271+#define SDRAM_LOCKN_OFFS 17
60272+#define SDRAM_LOCKN_MAKS (0x3F << SDRAM_LOCKN_OFFS)
60273+#define SDRAM_LOCKP_OFFS 23
60274+#define SDRAM_LOCKP_MAKS (0x3F << SDRAM_LOCKP_OFFS)
60275+#define SDRAM_WR_EN (1 << 31)
60276+
60277+/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */
60278+#define DDR2_SDRAM_ODT_CTRL_LOW_REG (DRAM_BASE + 0x1494)
60279+#define DSOCLR_ODT_RD_OFFS(odtNum) (odtNum * 4)
60280+#define DSOCLR_ODT_RD_MASK(odtNum) (0xf << DSOCLR_ODT_RD_OFFS(odtNum))
60281+#define DSOCLR_ODT_RD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))
60282+#define DSOCLR_ODT_WR_OFFS(odtNum) (16 + (odtNum * 4))
60283+#define DSOCLR_ODT_WR_MASK(odtNum) (0xf << DSOCLR_ODT_WR_OFFS(odtNum))
60284+#define DSOCLR_ODT_WR(odtNum, bank) ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))
60285+
60286+/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */
60287+#define DDR2_SDRAM_ODT_CTRL_HIGH_REG (DRAM_BASE + 0x1498)
60288+/* Optional control values to DSOCHR_ODT_EN macro */
60289+#define DDR2_ODT_CTRL_DUNIT 0
60290+#define DDR2_ODT_CTRL_NEVER 1
60291+#define DDR2_ODT_CTRL_ALWAYS 3
60292+#define DSOCHR_ODT_EN_OFFS(odtNum) (odtNum * 2)
60293+#define DSOCHR_ODT_EN_MASK(odtNum) (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))
60294+#define DSOCHR_ODT_EN(odtNum, ctrl) (ctrl << DSOCHR_ODT_EN_OFFS(odtNum))
60295+
60296+/* DDR2 Dunit ODT Control Register (DDOCR)*/
60297+#define DDR2_DUNIT_ODT_CONTROL_REG (DRAM_BASE + 0x149c)
60298+#define DDOCR_ODT_RD_OFFS 0
60299+#define DDOCR_ODT_RD_MASK (0xf << DDOCR_ODT_RD_OFFS)
60300+#define DDOCR_ODT_RD(bank) ((1 << bank) << DDOCR_ODT_RD_OFFS)
60301+#define DDOCR_ODT_WR_OFFS 4
60302+#define DDOCR_ODT_WR_MASK (0xf << DDOCR_ODT_WR_OFFS)
60303+#define DDOCR_ODT_WR(bank) ((1 << bank) << DDOCR_ODT_WR_OFFS)
60304+#define DSOCR_ODT_EN_OFFS 8
60305+#define DSOCR_ODT_EN_MASK (0x3 << DSOCR_ODT_EN_OFFS)
60306+/* For ctrl parameters see DDR2 SDRAM ODT Control (High) Register (0x1498) above. */
60307+#define DSOCR_ODT_EN(ctrl) (ctrl << DSOCR_ODT_EN_OFFS)
60308+#define DSOCR_ODT_SEL_DISABLE 0
60309+#define DSOCR_ODT_SEL_75_OHM 2
60310+#define DSOCR_ODT_SEL_150_OHM 1
60311+#define DSOCR_ODT_SEL_50_OHM 3
60312+#define DSOCR_DQ_ODT_SEL_OFFS 10
60313+#define DSOCR_DQ_ODT_SEL_MASK (0x3 << DSOCR_DQ_ODT_SEL_OFFS)
60314+#define DSOCR_DQ_ODT_SEL(odtSel) (odtSel << DSOCR_DQ_ODT_SEL_OFFS)
60315+#define DSOCR_ST_ODT_SEL_OFFS 12
60316+#define DSOCR_ST_ODT_SEL_MASK (0x3 << DSOCR_ST_ODT_SEL_OFFS)
60317+#define DSOCR_ST_ODT_SEL(odtSel) (odtSel << DSOCR_ST_ODT_SEL_OFFS)
60318+#define DSOCR_ST_ODT_EN (1 << 14)
60319+
60320+/* DDR SDRAM Initialization Control Register (DSICR) */
60321+#define DDR_SDRAM_INIT_CTRL_REG (DRAM_BASE + 0x1480)
60322+#define DSICR_INIT_EN (1 << 0)
60323+#define DSICR_T200_SET (1 << 8)
60324+
60325+/* sdram extended mode2 register (SEM2R) */
60326+#define SDRAM_EXTENDED_MODE2_REG (DRAM_BASE + 0x148C)
60327+#define SEM2R_EMRS2_DDR2_OFFS 0
60328+#define SEM2R_EMRS2_DDR2_MASK (0x7FFF << SEM2R_EMRS2_DDR2_OFFS)
60329+
60330+/* sdram extended mode3 register (SEM3R) */
60331+#define SDRAM_EXTENDED_MODE3_REG (DRAM_BASE + 0x1490)
60332+#define SEM3R_EMRS3_DDR2_OFFS 0
60333+#define SEM3R_EMRS3_DDR2_MASK (0x7FFF << SEM3R_EMRS3_DDR2_OFFS)
60334+
60335+/* sdram error registers */
60336+#define SDRAM_ERROR_CAUSE_REG (DRAM_BASE + 0x14d0)
60337+#define SDRAM_ERROR_MASK_REG (DRAM_BASE + 0x14d4)
60338+#define SDRAM_ERROR_DATA_LOW_REG (DRAM_BASE + 0x1444)
60339+#define SDRAM_ERROR_DATA_HIGH_REG (DRAM_BASE + 0x1440)
60340+#define SDRAM_ERROR_ADDR_REG (DRAM_BASE + 0x1450)
60341+#define SDRAM_ERROR_ECC_REG (DRAM_BASE + 0x1448)
60342+#define SDRAM_CALC_ECC_REG (DRAM_BASE + 0x144c)
60343+#define SDRAM_ECC_CONTROL_REG (DRAM_BASE + 0x1454)
60344+#define SDRAM_SINGLE_BIT_ERR_CNTR_REG (DRAM_BASE + 0x1458)
60345+#define SDRAM_DOUBLE_BIT_ERR_CNTR_REG (DRAM_BASE + 0x145c)
60346+
60347+/* SDRAM Error Cause Register (SECR) */
60348+#define SECR_SINGLE_BIT_ERR BIT0
60349+#define SECR_DOUBLE_BIT_ERR BIT1
60350+#define SECR_DATA_PATH_PARITY_ERR BIT2
60351+/* SDRAM Error Address Register (SEAR) */
60352+#define SEAR_ERR_TYPE_OFFS 0
60353+#define SEAR_ERR_TYPE_MASK (1 << SEAR_ERR_TYPE_OFFS)
60354+#define SEAR_ERR_TYPE_SINGLE 0
60355+#define SEAR_ERR_TYPE_DOUBLE (1 << SEAR_ERR_TYPE_OFFS)
60356+#define SEAR_ERR_CS_OFFS 1
60357+#define SEAR_ERR_CS_MASK (3 << SEAR_ERR_CS_OFFS)
60358+#define SEAR_ERR_CS(csNum) (csNum << SEAR_ERR_CS_OFFS)
60359+#define SEAR_ERR_ADDR_OFFS 3
60360+#define SEAR_ERR_ADDR_MASK (0x1FFFFFFF << SEAR_ERR_ADDR_OFFS)
60361+
60362+/* SDRAM ECC Control Register (SECR) */
60363+#define SECR_FORCEECC_OFFS 0
60364+#define SECR_FORCEECC_MASK (0xFF << SECR_FORCEECC_OFFS)
60365+#define SECR_FORCEEN_OFFS 8
60366+#define SECR_FORCEEN_MASK (1 << SECR_FORCEEN_OFFS)
60367+#define SECR_ECC_CALC_MASK (0 << SECR_FORCEEN_OFFS)
60368+#define SECR_ECC_USER_MASK (1 << SECR_FORCEEN_OFFS)
60369+#define SECR_PERRPROP_EN BIT9
60370+#define SECR_CNTMODE_OFFS 10
60371+#define SECR_CNTMODE_MASK (1 << SECR_CNTMODE_OFFS)
60372+#define SECR_ALL_IN_CS0 (0 << SECR_CNTMODE_OFFS)
60373+#define SECR_NORMAL_COUNTER (1 << SECR_CNTMODE_OFFS)
60374+#define SECR_THRECC_OFFS 16
60375+#define SECR_THRECC_MAX 0xFF
60376+#define SECR_THRECC_MASK (SECR_THRECC_MAX << SECR_THRECC_OFFS)
60377+#define SECR_THRECC(threshold) (threshold << SECR_THRECC_OFFS)
60378+
60379+
60380+#ifdef __cplusplus
60381+}
60382+#endif /* __cplusplus */
60383+
60384+#endif /* __INCmvDramIfRegsh */
60385diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h
60386new file mode 100644
60387index 0000000..5b3ed85
60388--- /dev/null
60389+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h
60390@@ -0,0 +1,179 @@
60391+/*******************************************************************************
60392+Copyright (C) Marvell International Ltd. and its affiliates
60393+
60394+This software file (the "File") is owned and distributed by Marvell
60395+International Ltd. and/or its affiliates ("Marvell") under the following
60396+alternative licensing terms. Once you have made an election to distribute the
60397+File under one of the following license alternatives, please (i) delete this
60398+introductory statement regarding license alternatives, (ii) delete the two
60399+license alternatives that you have not elected to use and (iii) preserve the
60400+Marvell copyright notice above.
60401+
60402+********************************************************************************
60403+Marvell Commercial License Option
60404+
60405+If you received this File from Marvell and you have entered into a commercial
60406+license agreement (a "Commercial License") with Marvell, the File is licensed
60407+to you under the terms of the applicable Commercial License.
60408+
60409+********************************************************************************
60410+Marvell GPL License Option
60411+
60412+If you received this File from Marvell, you may opt to use, redistribute and/or
60413+modify this File in accordance with the terms and conditions of the General
60414+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
60415+available along with the File in the license.txt file or by writing to the Free
60416+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
60417+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
60418+
60419+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
60420+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
60421+DISCLAIMED. The GPL License provides additional details about this warranty
60422+disclaimer.
60423+********************************************************************************
60424+Marvell BSD License Option
60425+
60426+If you received this File from Marvell, you may opt to use, redistribute and/or
60427+modify this File under the following licensing terms.
60428+Redistribution and use in source and binary forms, with or without modification,
60429+are permitted provided that the following conditions are met:
60430+
60431+ * Redistributions of source code must retain the above copyright notice,
60432+ this list of conditions and the following disclaimer.
60433+
60434+ * Redistributions in binary form must reproduce the above copyright
60435+ notice, this list of conditions and the following disclaimer in the
60436+ documentation and/or other materials provided with the distribution.
60437+
60438+ * Neither the name of Marvell nor the names of its contributors may be
60439+ used to endorse or promote products derived from this software without
60440+ specific prior written permission.
60441+
60442+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
60443+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
60444+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60445+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
60446+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
60447+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60448+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
60449+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60450+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60451+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60452+
60453+*******************************************************************************/
60454+
60455+
60456+#ifndef __INCmvDramIfStaticInith
60457+#define __INCmvDramIfStaticInith
60458+
60459+#ifdef MV_STATIC_DRAM_ON_BOARD
60460+#define STATIC_DRAM_BANK_1
60461+#undef STATIC_DRAM_BANK_2
60462+#undef STATIC_DRAM_BANK_3
60463+#undef STATIC_DRAM_BANK_4
60464+
60465+
60466+#ifdef MV_DIMM_TS256MLQ72V5U
60467+#define STATIC_DRAM_BANK_2
60468+#define STATIC_DRAM_BANK_3
60469+#undef STATIC_DRAM_BANK_4
60470+
60471+#define STATIC_SDRAM_CONFIG_REG 0x4724481A /* offset 0x1400 - DMA reg-0xf1000814 */
60472+#define STATIC_SDRAM_DUNIT_CTRL_REG 0x37707450 /* offset 0x1404 - DMA reg-0xf100081c */
60473+#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11A13330 /* offset 0x1408 - DMA reg-0xf1000824 */
60474+#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000601 /* offset 0x140c - DMA reg-0xf1000828 */
60475+#define STATIC_SDRAM_ADDR_CTRL_REG 0x00001CB2 /* offset 0x1410 - DMA reg-0xf1000820 */
60476+#define STATIC_SDRAM_MODE_REG 0x00000642 /* offset 0x141c - DMA reg-0xf1000818 */
60477+#define STATIC_SDRAM_ODT_CTRL_LOW 0x030C030C /* 0x1494 */
60478+#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000 /* 0x1498 */
60479+#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000740F /* 0x149c */
60480+#define STATIC_SDRAM_EXT_MODE 0x00000404 /* 0x1420 */
60481+#define STATIC_SDRAM_DDR2_TIMING_LO 0x00074410 /* 0x1428 */
60482+#define STATIC_SDRAM_DDR2_TIMING_HI 0x00007441 /* 0x147C */
60483+
60484+#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x3FFF /* size bank0 dimm0 - DMA reg-0xf1000810 */
60485+#define STATIC_SDRAM_RANK1_SIZE_DIMM0 0x3FFF /* size bank1 dimm0 */
60486+#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x3FFF /* size bank0 dimm1 */
60487+#define STATIC_SDRAM_RANK1_SIZE_DIMM1 0x0 /* size bank1 dimm1 */
60488+
60489+#endif /* TS256MLQ72V5U */
60490+
60491+
60492+#ifdef MV_MT9VDDT3272AG
60493+/* one DIMM 256M */
60494+#define STATIC_SDRAM_CONFIG_REG 0x5820040d /* offset 0x1400 - DMA reg-0xf1000814 */
60495+#define STATIC_SDRAM_DUNIT_CTRL_REG 0xC4000540 /* offset 0x1404 - DMA reg-0xf100081c */
60496+#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x01602220 /* offset 0x1408 - DMA reg-0xf1000824 */
60497+#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x0000000b /* offset 0x140c - DMA reg-0xf1000828 */
60498+#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000012 /* offset 0x1410 - DMA reg-0xf1000820 */
60499+#define STATIC_SDRAM_MODE_REG 0x00000062 /* offset 0x141c - DMA reg-0xf1000818 */
60500+#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x0fff /* size bank0 dimm0 - DMA reg-0xf1000810 */
60501+#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x0 /* size bank0 dimm1 */
60502+
60503+#endif /* MV_MT9VDDT3272AG */
60504+
60505+
60506+
60507+#ifdef MV_D27RB12P
60508+/*
60509+Two DIMM 512M + ECC enabled, Registered DIMM CAS Latency 2.5
60510+*/
60511+
60512+#define STATIC_SDRAM_CONFIG_REG 0x6826081E /* offset 0x1400 - DMA reg-0xf1000814 */
60513+#define STATIC_SDRAM_DUNIT_CTRL_REG 0xC5000540 /* offset 0x1404 - DMA reg-0xf100081c */
60514+#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x01501220 /* offset 0x1408 - DMA reg-0xf1000824 */
60515+#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000009 /* offset 0x140c - DMA reg-0xf1000828 */
60516+#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000012 /* offset 0x1410 - DMA reg-0xf1000820 */
60517+#define STATIC_SDRAM_MODE_REG 0x00000062 /* offset 0x141c - DMA reg-0xf1000818 */
60518+#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x0FFF /* size bank0 dimm0 - DMA reg-0xf1000810 */
60519+#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x0FFF /* size bank0 dimm1 */
60520+
60521+#define STATIC_DRAM_BANK_2
60522+
60523+#define STATIC_DRAM_BANK_3
60524+#define STATIC_DRAM_BANK_4
60525+
60526+#endif /* mv_D27RB12P */
60527+
60528+#ifdef RD_MV645XX
60529+
60530+#define STATIC_MEM_TYPE MEM_TYPE_DDR2
60531+#define STATIC_DIMM_INFO_BANK0_SIZE 256
60532+/* DDR2 boards 256 MB*/
60533+
60534+#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x00000fff /* size bank0 dimm0 - DMA reg-0xf1000810 */
60535+#define STATIC_SDRAM_CONFIG_REG 0x07190618
60536+#define STATIC_SDRAM_MODE_REG 0x00000432
60537+#define STATIC_SDRAM_DUNIT_CTRL_REG 0xf4a03440
60538+#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000022
60539+#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11712220
60540+#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000504
60541+#define STATIC_SDRAM_ODT_CTRL_LOW 0x84210000
60542+#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000
60543+#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000780f
60544+#define STATIC_SDRAM_EXT_MODE 0x00000440
60545+#define STATIC_SDRAM_DDR2_TIMING_LO 0x00063300
60546+#define STATIC_SDRAM_DDR2_TIMING_HI 0x00006330
60547+#endif /* RD_MV645XX */
60548+
60549+#if MV_DIMM_M3783354CZ3_CE6
60550+
60551+#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x00000FFF /* 0x2010 size bank0 dimm0 - DMA reg-0xf1000810 */
60552+#define STATIC_SDRAM_CONFIG_REG 0x07190618 /* 0x1400 */
60553+#define STATIC_SDRAM_MODE_REG 0x00000432 /* 0x141c */
60554+#define STATIC_SDRAM_DUNIT_CTRL_REG 0xf4a03440 /* 0x1404 */
60555+#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000022 /* 0x1410 */
60556+#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11712220 /* 0x1408 */
60557+#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000504 /* 0x140c */
60558+#define STATIC_SDRAM_ODT_CTRL_LOW 0x84210000 /* 0x1494 */
60559+#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000 /* 0x1498 */
60560+#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000780f /* 0x149c */
60561+#define STATIC_SDRAM_EXT_MODE 0x00000440 /* 0x1420 */
60562+#define STATIC_SDRAM_DDR2_TIMING_LO 0x00063300 /* 0x1428 */
60563+#define STATIC_SDRAM_DDR2_TIMING_HI 0x00006330 /* 0x147C */
60564+
60565+#endif /* MV_DIMM_M3783354CZ3_CE6 */
60566+
60567+#endif /* MV_STATIC_DRAM_ON_BOARD */
60568+#endif /* __INCmvDramIfStaticInith */
60569+
60570diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c
60571new file mode 100644
60572index 0000000..dcc8fdf
60573--- /dev/null
60574+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c
60575@@ -0,0 +1,1474 @@
60576+/*******************************************************************************
60577+Copyright (C) Marvell International Ltd. and its affiliates
60578+
60579+This software file (the "File") is owned and distributed by Marvell
60580+International Ltd. and/or its affiliates ("Marvell") under the following
60581+alternative licensing terms. Once you have made an election to distribute the
60582+File under one of the following license alternatives, please (i) delete this
60583+introductory statement regarding license alternatives, (ii) delete the two
60584+license alternatives that you have not elected to use and (iii) preserve the
60585+Marvell copyright notice above.
60586+
60587+********************************************************************************
60588+Marvell Commercial License Option
60589+
60590+If you received this File from Marvell and you have entered into a commercial
60591+license agreement (a "Commercial License") with Marvell, the File is licensed
60592+to you under the terms of the applicable Commercial License.
60593+
60594+********************************************************************************
60595+Marvell GPL License Option
60596+
60597+If you received this File from Marvell, you may opt to use, redistribute and/or
60598+modify this File in accordance with the terms and conditions of the General
60599+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
60600+available along with the File in the license.txt file or by writing to the Free
60601+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
60602+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
60603+
60604+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
60605+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
60606+DISCLAIMED. The GPL License provides additional details about this warranty
60607+disclaimer.
60608+********************************************************************************
60609+Marvell BSD License Option
60610+
60611+If you received this File from Marvell, you may opt to use, redistribute and/or
60612+modify this File under the following licensing terms.
60613+Redistribution and use in source and binary forms, with or without modification,
60614+are permitted provided that the following conditions are met:
60615+
60616+ * Redistributions of source code must retain the above copyright notice,
60617+ this list of conditions and the following disclaimer.
60618+
60619+ * Redistributions in binary form must reproduce the above copyright
60620+ notice, this list of conditions and the following disclaimer in the
60621+ documentation and/or other materials provided with the distribution.
60622+
60623+ * Neither the name of Marvell nor the names of its contributors may be
60624+ used to endorse or promote products derived from this software without
60625+ specific prior written permission.
60626+
60627+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
60628+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
60629+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60630+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
60631+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
60632+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60633+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
60634+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60635+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60636+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60637+
60638+*******************************************************************************/
60639+
60640+#include "ddr2/spd/mvSpd.h"
60641+#include "boardEnv/mvBoardEnvLib.h"
60642+
60643+/* #define MV_DEBUG */
60644+#ifdef MV_DEBUG
60645+#define DB(x) x
60646+#else
60647+#define DB(x)
60648+#endif
60649+
60650+static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
60651+ MV_DRAM_BANK_INFO *pBankInfo);
60652+static MV_U32 cas2ps(MV_U8 spd_byte);
60653+/*******************************************************************************
60654+* mvDramBankGet - Get the DRAM bank paramters.
60655+*
60656+* DESCRIPTION:
60657+* This function retrieves DRAM bank parameters as described in
60658+* DRAM_BANK_INFO struct to the controller DRAM unit. In case the board
60659+* has its DRAM on DIMMs it will use its EEPROM to extract SPD data
60660+* from it. Otherwise, if the DRAM is soldered on board, the function
60661+* should insert its bank information into MV_DRAM_BANK_INFO struct.
60662+*
60663+* INPUT:
60664+* bankNum - Board DRAM bank number.
60665+*
60666+* OUTPUT:
60667+* pBankInfo - DRAM bank information struct.
60668+*
60669+* RETURN:
60670+* MV_FAIL - Bank parameters could not be read.
60671+*
60672+*******************************************************************************/
60673+MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
60674+{
60675+ MV_DIMM_INFO dimmInfo;
60676+
60677+ DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
60678+ /* zero pBankInfo structure */
60679+
60680+ if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
60681+ {
60682+ DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
60683+ return MV_BAD_PARAM;
60684+ }
60685+ memset(pBankInfo, 0, sizeof(*pBankInfo));
60686+
60687+ if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
60688+ {
60689+ DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
60690+ return MV_FAIL;
60691+ }
60692+ if ((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
60693+ {
60694+ DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
60695+ return MV_FAIL;
60696+ }
60697+ /* convert Dimm info to Bank info */
60698+ cpyDimm2BankInfo(&dimmInfo, pBankInfo);
60699+ return MV_OK;
60700+}
60701+
60702+/*******************************************************************************
60703+* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
60704+*
60705+* DESCRIPTION:
60706+* Convert a Dimm info struct into a bank info struct.
60707+*
60708+* INPUT:
60709+* pDimmInfo - DIMM information structure.
60710+*
60711+* OUTPUT:
60712+* pBankInfo - DRAM bank information struct.
60713+*
60714+* RETURN:
60715+* None.
60716+*
60717+*******************************************************************************/
60718+static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
60719+ MV_DRAM_BANK_INFO *pBankInfo)
60720+{
60721+ pBankInfo->memoryType = pDimmInfo->memoryType;
60722+
60723+ /* DIMM dimensions */
60724+ pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
60725+ pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
60726+ pBankInfo->dataWidth = pDimmInfo->dataWidth;
60727+ pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
60728+ pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
60729+ pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
60730+ pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
60731+ pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
60732+ pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
60733+
60734+ /* DIMM timing parameters */
60735+ pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
60736+ pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
60737+ pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
60738+ pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
60739+ pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
60740+
60741+ pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
60742+ pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
60743+ pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
60744+ pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
60745+ pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
60746+ pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
60747+ pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
60748+ pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
60749+
60750+ /* Parameters calculated from the extracted DIMM information */
60751+ pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
60752+ pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
60753+ pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
60754+ pDimmInfo->numOfModuleBanks;
60755+
60756+ /* DIMM attributes (MV_TRUE for yes) */
60757+
60758+ if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
60759+ (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
60760+ {
60761+ if (pDimmInfo->dimmAttributes & BIT1)
60762+ pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
60763+ else
60764+ pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
60765+ }
60766+ else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
60767+ {
60768+ if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
60769+ pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
60770+ else
60771+ pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
60772+ }
60773+
60774+ return;
60775+}
60776+/*******************************************************************************
60777+* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
60778+*
60779+* DESCRIPTION:
60780+* Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
60781+*
60782+* INPUT:
60783+* None.
60784+*
60785+* OUTPUT:
60786+* None.
60787+*
60788+* RETURN:
60789+* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
60790+*
60791+*******************************************************************************/
60792+MV_STATUS dimmSpdCpy(MV_VOID)
60793+{
60794+ MV_U32 i;
60795+ MV_U32 spdChecksum;
60796+
60797+ MV_TWSI_SLAVE twsiSlave;
60798+ MV_U8 data[SPD_SIZE];
60799+
60800+ /* zero dimmInfo structure */
60801+ memset(data, 0, SPD_SIZE);
60802+
60803+ /* read the dimm eeprom */
60804+ DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
60805+ twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
60806+ twsiSlave.slaveAddr.type = ADDR7_BIT;
60807+ twsiSlave.validOffset = MV_TRUE;
60808+ twsiSlave.offset = 0;
60809+ twsiSlave.moreThen256 = MV_FALSE;
60810+
60811+ if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
60812+ {
60813+ DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
60814+ return MV_FAIL;
60815+ }
60816+ DB(puts("DRAM: Reading dimm info succeded.\n"));
60817+
60818+ /* calculate SPD checksum */
60819+ spdChecksum = 0;
60820+
60821+ for(i = 0 ; i <= 62 ; i++)
60822+ {
60823+ spdChecksum += data[i];
60824+ }
60825+
60826+ if ((spdChecksum & 0xff) != data[63])
60827+ {
60828+ DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
60829+ (MV_U32)(spdChecksum & 0xff), data[63]));
60830+ }
60831+ else
60832+ {
60833+ DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
60834+ }
60835+
60836+ /* copy the SPD content 1:1 into the DIMM 1 SPD */
60837+ twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
60838+ twsiSlave.slaveAddr.type = ADDR7_BIT;
60839+ twsiSlave.validOffset = MV_TRUE;
60840+ twsiSlave.offset = 0;
60841+ twsiSlave.moreThen256 = MV_FALSE;
60842+
60843+ for(i = 0 ; i < SPD_SIZE ; i++)
60844+ {
60845+ twsiSlave.offset = i;
60846+ if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, &data[i], 1) )
60847+ {
60848+ mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
60849+ return MV_FAIL;
60850+ }
60851+ mvOsDelay(5);
60852+ }
60853+
60854+ DB(puts("DRAM: Reading dimm info succeded.\n"));
60855+ return MV_OK;
60856+}
60857+
60858+/*******************************************************************************
60859+* dimmSpdGet - Get the SPD parameters.
60860+*
60861+* DESCRIPTION:
60862+* Read the DIMM SPD parameters into given struct parameter.
60863+*
60864+* INPUT:
60865+* dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
60866+*
60867+* OUTPUT:
60868+* pDimmInfo - DIMM information structure.
60869+*
60870+* RETURN:
60871+* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
60872+*
60873+*******************************************************************************/
60874+MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
60875+{
60876+ MV_U32 i;
60877+ MV_U32 density = 1;
60878+ MV_U32 spdChecksum;
60879+
60880+ MV_TWSI_SLAVE twsiSlave;
60881+ MV_U8 data[SPD_SIZE];
60882+
60883+ if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
60884+ {
60885+ DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
60886+ return MV_BAD_PARAM;
60887+ }
60888+
60889+ /* zero dimmInfo structure */
60890+ memset(data, 0, SPD_SIZE);
60891+
60892+ /* read the dimm eeprom */
60893+ DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
60894+ twsiSlave.slaveAddr.address = (dimmNum == 0) ?
60895+ MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
60896+ twsiSlave.slaveAddr.type = ADDR7_BIT;
60897+ twsiSlave.validOffset = MV_TRUE;
60898+ twsiSlave.offset = 0;
60899+ twsiSlave.moreThen256 = MV_FALSE;
60900+
60901+ if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
60902+ {
60903+ DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
60904+ return MV_FAIL;
60905+ }
60906+ DB(puts("DRAM: Reading dimm info succeded.\n"));
60907+
60908+ /* calculate SPD checksum */
60909+ spdChecksum = 0;
60910+
60911+ for(i = 0 ; i <= 62 ; i++)
60912+ {
60913+ spdChecksum += data[i];
60914+ }
60915+
60916+ if ((spdChecksum & 0xff) != data[63])
60917+ {
60918+ DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
60919+ (MV_U32)(spdChecksum & 0xff), data[63]));
60920+ }
60921+ else
60922+ {
60923+ DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
60924+ }
60925+
60926+ /* copy the SPD content 1:1 into the dimmInfo structure*/
60927+ for(i = 0 ; i < SPD_SIZE ; i++)
60928+ {
60929+ pDimmInfo->spdRawData[i] = data[i];
60930+ DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
60931+ }
60932+
60933+ DB(mvOsPrintf("DRAM SPD Information:\n"));
60934+
60935+ /* Memory type (DDR / SDRAM) */
60936+ switch (data[DIMM_MEM_TYPE])
60937+ {
60938+ case (DIMM_MEM_TYPE_SDRAM):
60939+ pDimmInfo->memoryType = MEM_TYPE_SDRAM;
60940+ DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
60941+ break;
60942+ case (DIMM_MEM_TYPE_DDR1):
60943+ pDimmInfo->memoryType = MEM_TYPE_DDR1;
60944+ DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
60945+ break;
60946+ case (DIMM_MEM_TYPE_DDR2):
60947+ pDimmInfo->memoryType = MEM_TYPE_DDR2;
60948+ DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
60949+ break;
60950+ default:
60951+ mvOsPrintf("ERROR: Undefined memory type!\n");
60952+ return MV_ERROR;
60953+ }
60954+
60955+
60956+ /* Number Of Row Addresses */
60957+ pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
60958+ DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
60959+
60960+ /* Number Of Column Addresses */
60961+ pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
60962+ DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
60963+
60964+ /* Number Of Module Banks */
60965+ pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
60966+ DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
60967+ pDimmInfo->numOfModuleBanks));
60968+
60969+ /* Number of module banks encoded differently for DDR2 */
60970+ if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
60971+ pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
60972+
60973+ /* Data Width */
60974+ pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
60975+ DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
60976+
60977+ /* Minimum Cycle Time At Max CasLatancy */
60978+ pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
60979+
60980+ /* Error Check Type */
60981+ pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
60982+ DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
60983+ pDimmInfo->errorCheckType));
60984+
60985+ /* Refresh Interval */
60986+ pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
60987+ DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
60988+ pDimmInfo->refreshInterval));
60989+
60990+ /* Sdram Width */
60991+ pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
60992+ DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
60993+
60994+ /* Error Check Data Width */
60995+ pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
60996+ DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
60997+ pDimmInfo->errorCheckDataWidth));
60998+
60999+ /* Burst Length Supported */
61000+ /* SDRAM/DDR1:
61001+ *******-******-******-******-******-******-******-*******
61002+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
61003+ *******-******-******-******-******-******-******-*******
61004+ burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
61005+ *********************************************************/
61006+ /* DDR2:
61007+ *******-******-******-******-******-******-******-*******
61008+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
61009+ *******-******-******-******-******-******-******-*******
61010+ burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
61011+ *********************************************************/
61012+
61013+ pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
61014+ DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
61015+ pDimmInfo->burstLengthSupported));
61016+
61017+ /* Number Of Banks On Each Device */
61018+ pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
61019+ DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
61020+ pDimmInfo->numOfBanksOnEachDevice));
61021+
61022+ /* Suported Cas Latencies */
61023+
61024+ /* SDRAM:
61025+ *******-******-******-******-******-******-******-*******
61026+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
61027+ *******-******-******-******-******-******-******-*******
61028+ CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
61029+ ********************************************************/
61030+
61031+ /* DDR 1:
61032+ *******-******-******-******-******-******-******-*******
61033+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
61034+ *******-******-******-******-******-******-******-*******
61035+ CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
61036+ *********************************************************/
61037+
61038+ /* DDR 2:
61039+ *******-******-******-******-******-******-******-*******
61040+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
61041+ *******-******-******-******-******-******-******-*******
61042+ CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
61043+ *********************************************************/
61044+
61045+ pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
61046+ DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
61047+ pDimmInfo->suportedCasLatencies));
61048+
61049+ /* For DDR2 only, get the DIMM type information */
61050+ if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
61051+ {
61052+ pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
61053+ DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
61054+ pDimmInfo->dimmTypeInfo));
61055+ }
61056+
61057+ /* SDRAM Modules Attributes */
61058+ pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
61059+ DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
61060+ pDimmInfo->dimmAttributes));
61061+
61062+ /* Minimum Cycle Time At Max CasLatancy Minus 1*/
61063+ pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
61064+ cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
61065+
61066+ /* Minimum Cycle Time At Max CasLatancy Minus 2*/
61067+ pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
61068+ cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
61069+
61070+ pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
61071+ DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
61072+ pDimmInfo->minRowPrechargeTime));
61073+ pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
61074+ DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
61075+ pDimmInfo->minRowActiveToRowActive));
61076+ pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
61077+ DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
61078+ pDimmInfo->minRasToCasDelay));
61079+ pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
61080+ DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
61081+ pDimmInfo->minRasPulseWidth));
61082+
61083+ /* DIMM Bank Density */
61084+ pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
61085+ DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
61086+ pDimmInfo->dimmBankDensity));
61087+
61088+ /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
61089+ pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
61090+ DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
61091+ pDimmInfo->minWriteRecoveryTime));
61092+
61093+ /* Only DDR2 includes Internal Write To Read Command Delay field. */
61094+ pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
61095+ DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
61096+ pDimmInfo->minWriteToReadCmdDelay));
61097+
61098+ /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
61099+ pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
61100+ DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
61101+ pDimmInfo->minReadToPrechCmdDelay));
61102+
61103+ /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
61104+ pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
61105+ DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
61106+ pDimmInfo->minRefreshToActiveCmd));
61107+
61108+ /* calculating the sdram density. Representing device density from */
61109+ /* bit 20 to allow representation of 4GB and above. */
61110+ /* For example, if density is 512Mbit 0x20000000, will be represent in */
61111+ /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
61112+ /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
61113+ density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
61114+ pDimmInfo->deviceDensity = density *
61115+ pDimmInfo->numOfBanksOnEachDevice *
61116+ pDimmInfo->sdramWidth;
61117+ DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
61118+
61119+ /* Number of devices includeing Error correction */
61120+ pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
61121+ pDimmInfo->numOfModuleBanks;
61122+ DB(mvOsPrintf("DRAM numberOfDevices %d\n",
61123+ pDimmInfo->numberOfDevices));
61124+
61125+ pDimmInfo->size = 0;
61126+
61127+ /* Note that pDimmInfo->size is in MB units */
61128+ if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
61129+ {
61130+ if (pDimmInfo->dimmBankDensity & BIT0)
61131+ pDimmInfo->size += 1024; /* Equal to 1GB */
61132+ else if (pDimmInfo->dimmBankDensity & BIT1)
61133+ pDimmInfo->size += 8; /* Equal to 8MB */
61134+ else if (pDimmInfo->dimmBankDensity & BIT2)
61135+ pDimmInfo->size += 16; /* Equal to 16MB */
61136+ else if (pDimmInfo->dimmBankDensity & BIT3)
61137+ pDimmInfo->size += 32; /* Equal to 32MB */
61138+ else if (pDimmInfo->dimmBankDensity & BIT4)
61139+ pDimmInfo->size += 64; /* Equal to 64MB */
61140+ else if (pDimmInfo->dimmBankDensity & BIT5)
61141+ pDimmInfo->size += 128; /* Equal to 128MB */
61142+ else if (pDimmInfo->dimmBankDensity & BIT6)
61143+ pDimmInfo->size += 256; /* Equal to 256MB */
61144+ else if (pDimmInfo->dimmBankDensity & BIT7)
61145+ pDimmInfo->size += 512; /* Equal to 512MB */
61146+ }
61147+ else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
61148+ {
61149+ if (pDimmInfo->dimmBankDensity & BIT0)
61150+ pDimmInfo->size += 1024; /* Equal to 1GB */
61151+ else if (pDimmInfo->dimmBankDensity & BIT1)
61152+ pDimmInfo->size += 2048; /* Equal to 2GB */
61153+ else if (pDimmInfo->dimmBankDensity & BIT2)
61154+ pDimmInfo->size += 16; /* Equal to 16MB */
61155+ else if (pDimmInfo->dimmBankDensity & BIT3)
61156+ pDimmInfo->size += 32; /* Equal to 32MB */
61157+ else if (pDimmInfo->dimmBankDensity & BIT4)
61158+ pDimmInfo->size += 64; /* Equal to 64MB */
61159+ else if (pDimmInfo->dimmBankDensity & BIT5)
61160+ pDimmInfo->size += 128; /* Equal to 128MB */
61161+ else if (pDimmInfo->dimmBankDensity & BIT6)
61162+ pDimmInfo->size += 256; /* Equal to 256MB */
61163+ else if (pDimmInfo->dimmBankDensity & BIT7)
61164+ pDimmInfo->size += 512; /* Equal to 512MB */
61165+ }
61166+ else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
61167+ {
61168+ if (pDimmInfo->dimmBankDensity & BIT0)
61169+ pDimmInfo->size += 1024; /* Equal to 1GB */
61170+ else if (pDimmInfo->dimmBankDensity & BIT1)
61171+ pDimmInfo->size += 2048; /* Equal to 2GB */
61172+ else if (pDimmInfo->dimmBankDensity & BIT2)
61173+ pDimmInfo->size += 4096; /* Equal to 4GB */
61174+ else if (pDimmInfo->dimmBankDensity & BIT3)
61175+ pDimmInfo->size += 8192; /* Equal to 8GB */
61176+ else if (pDimmInfo->dimmBankDensity & BIT4)
61177+ pDimmInfo->size += 16384; /* Equal to 16GB */
61178+ else if (pDimmInfo->dimmBankDensity & BIT5)
61179+ pDimmInfo->size += 128; /* Equal to 128MB */
61180+ else if (pDimmInfo->dimmBankDensity & BIT6)
61181+ pDimmInfo->size += 256; /* Equal to 256MB */
61182+ else if (pDimmInfo->dimmBankDensity & BIT7)
61183+ pDimmInfo->size += 512; /* Equal to 512MB */
61184+ }
61185+
61186+ pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
61187+
61188+ DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
61189+
61190+ return MV_OK;
61191+}
61192+
61193+/*******************************************************************************
61194+* dimmSpdPrint - Print the SPD parameters.
61195+*
61196+* DESCRIPTION:
61197+* Print the Dimm SPD parameters.
61198+*
61199+* INPUT:
61200+* pDimmInfo - DIMM information structure.
61201+*
61202+* OUTPUT:
61203+* None.
61204+*
61205+* RETURN:
61206+* None.
61207+*
61208+*******************************************************************************/
61209+MV_VOID dimmSpdPrint(MV_U32 dimmNum)
61210+{
61211+ MV_DIMM_INFO dimmInfo;
61212+ MV_U32 i, temp = 0;
61213+ MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
61214+ MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
61215+ MV_U32 busClkPs;
61216+ MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
61217+ temp_buf[40], *spdRawData;
61218+
61219+ busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
61220+
61221+ spdRawData = dimmInfo.spdRawData;
61222+
61223+ if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
61224+ {
61225+ mvOsOutput("ERROR: Could not read SPD information!\n");
61226+ return;
61227+ }
61228+
61229+ /* find Manufactura of Dimm Module */
61230+ mvOsOutput("\nManufacturer's JEDEC ID Code: ");
61231+ for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
61232+ {
61233+ mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
61234+ }
61235+ mvOsOutput("\n");
61236+
61237+ /* Manufacturer's Specific Data */
61238+ for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
61239+ {
61240+ temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
61241+ }
61242+ mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
61243+
61244+ /* Module Part Number */
61245+ for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
61246+ {
61247+ temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
61248+ }
61249+ mvOsOutput("Module Part Number: %s\n", temp_buf);
61250+
61251+ /* Module Serial Number */
61252+ for(i = 0; i < sizeof(MV_U32); i++)
61253+ {
61254+ temp |= spdRawData[95+i] << 8*i;
61255+ }
61256+ mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
61257+ (long)temp);
61258+
61259+ /* find Manufac-Data of Dimm Module */
61260+ mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
61261+ ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
61262+ ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
61263+ /* find modul_revision of Dimm Module */
61264+ mvOsOutput("Module Revision: %d.%d\n",
61265+ spdRawData[62]/10, spdRawData[62]%10);
61266+
61267+ /* find manufac_place of Dimm Module */
61268+ mvOsOutput("manufac_place: %d\n", spdRawData[72]);
61269+
61270+ /* go over the first 35 I2C data bytes */
61271+ for(i = 2 ; i <= 35 ; i++)
61272+ switch(i)
61273+ {
61274+ case 2: /* Memory type (DDR1/2 / SDRAM) */
61275+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
61276+ mvOsOutput("Dram Type is: SDRAM\n");
61277+ else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
61278+ mvOsOutput("Dram Type is: SDRAM DDR1\n");
61279+ else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
61280+ mvOsOutput("Dram Type is: SDRAM DDR2\n");
61281+ else
61282+ mvOsOutput("Dram Type unknown\n");
61283+ break;
61284+/*----------------------------------------------------------------------------*/
61285+
61286+ case 3: /* Number Of Row Addresses */
61287+ mvOsOutput("Module Number of row addresses: %d\n",
61288+ dimmInfo.numOfRowAddr);
61289+ break;
61290+/*----------------------------------------------------------------------------*/
61291+
61292+ case 4: /* Number Of Column Addresses */
61293+ mvOsOutput("Module Number of col addresses: %d\n",
61294+ dimmInfo.numOfColAddr);
61295+ break;
61296+/*----------------------------------------------------------------------------*/
61297+
61298+ case 5: /* Number Of Module Banks */
61299+ mvOsOutput("Number of Banks on Mod.: %d\n",
61300+ dimmInfo.numOfModuleBanks);
61301+ break;
61302+/*----------------------------------------------------------------------------*/
61303+
61304+ case 6: /* Data Width */
61305+ mvOsOutput("Module Data Width: %d bit\n",
61306+ dimmInfo.dataWidth);
61307+ break;
61308+/*----------------------------------------------------------------------------*/
61309+
61310+ case 8: /* Voltage Interface */
61311+ switch(spdRawData[i])
61312+ {
61313+ case 0x0:
61314+ mvOsOutput("Module is TTL_5V_TOLERANT\n");
61315+ break;
61316+ case 0x1:
61317+ mvOsOutput("Module is LVTTL\n");
61318+ break;
61319+ case 0x2:
61320+ mvOsOutput("Module is HSTL_1_5V\n");
61321+ break;
61322+ case 0x3:
61323+ mvOsOutput("Module is SSTL_3_3V\n");
61324+ break;
61325+ case 0x4:
61326+ mvOsOutput("Module is SSTL_2_5V\n");
61327+ break;
61328+ case 0x5:
61329+ if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
61330+ {
61331+ mvOsOutput("Module is SSTL_1_8V\n");
61332+ break;
61333+ }
61334+ default:
61335+ mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
61336+ break;
61337+ }
61338+ break;
61339+/*----------------------------------------------------------------------------*/
61340+
61341+ case 9: /* Minimum Cycle Time At Max CasLatancy */
61342+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
61343+ rightOfPoint = (spdRawData[i] & 0x0f) * 10;
61344+
61345+ /* DDR2 addition of right of point */
61346+ if ((spdRawData[i] & 0x0f) == 0xA)
61347+ {
61348+ rightOfPoint = 25;
61349+ }
61350+ if ((spdRawData[i] & 0x0f) == 0xB)
61351+ {
61352+ rightOfPoint = 33;
61353+ }
61354+ if ((spdRawData[i] & 0x0f) == 0xC)
61355+ {
61356+ rightOfPoint = 66;
61357+ }
61358+ if ((spdRawData[i] & 0x0f) == 0xD)
61359+ {
61360+ rightOfPoint = 75;
61361+ }
61362+ mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
61363+ leftOfPoint, rightOfPoint);
61364+ break;
61365+/*----------------------------------------------------------------------------*/
61366+
61367+ case 10: /* Clock To Data Out */
61368+ div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
61369+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
61370+ ((spdRawData[i] & 0x0f));
61371+ leftOfPoint = time_tmp / div;
61372+ rightOfPoint = time_tmp % div;
61373+ mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
61374+ leftOfPoint, rightOfPoint);
61375+ break;
61376+/*----------------------------------------------------------------------------*/
61377+
61378+ case 11: /* Error Check Type */
61379+ mvOsOutput("Error Check Type (0=NONE): %d\n",
61380+ dimmInfo.errorCheckType);
61381+ break;
61382+/*----------------------------------------------------------------------------*/
61383+
61384+ case 12: /* Refresh Interval */
61385+ mvOsOutput("Refresh Rate: %x\n",
61386+ dimmInfo.refreshInterval);
61387+ break;
61388+/*----------------------------------------------------------------------------*/
61389+
61390+ case 13: /* Sdram Width */
61391+ mvOsOutput("Sdram Width: %d bits\n",
61392+ dimmInfo.sdramWidth);
61393+ break;
61394+/*----------------------------------------------------------------------------*/
61395+
61396+ case 14: /* Error Check Data Width */
61397+ mvOsOutput("Error Check Data Width: %d bits\n",
61398+ dimmInfo.errorCheckDataWidth);
61399+ break;
61400+/*----------------------------------------------------------------------------*/
61401+
61402+ case 15: /* Minimum Clock Delay is unsupported */
61403+ if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
61404+ (dimmInfo.memoryType == MEM_TYPE_DDR1))
61405+ {
61406+ mvOsOutput("Minimum Clk Delay back to back: %d\n",
61407+ spdRawData[i]);
61408+ }
61409+ break;
61410+/*----------------------------------------------------------------------------*/
61411+
61412+ case 16: /* Burst Length Supported */
61413+ /* SDRAM/DDR1:
61414+ *******-******-******-******-******-******-******-*******
61415+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
61416+ *******-******-******-******-******-******-******-*******
61417+ burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
61418+ *********************************************************/
61419+ /* DDR2:
61420+ *******-******-******-******-******-******-******-*******
61421+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
61422+ *******-******-******-******-******-******-******-*******
61423+ burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
61424+ *********************************************************/
61425+ mvOsOutput("Burst Length Supported: ");
61426+ if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
61427+ (dimmInfo.memoryType == MEM_TYPE_DDR1))
61428+ {
61429+ if (dimmInfo.burstLengthSupported & BIT0)
61430+ mvOsOutput("1, ");
61431+ if (dimmInfo.burstLengthSupported & BIT1)
61432+ mvOsOutput("2, ");
61433+ }
61434+ if (dimmInfo.burstLengthSupported & BIT2)
61435+ mvOsOutput("4, ");
61436+ if (dimmInfo.burstLengthSupported & BIT3)
61437+ mvOsOutput("8, ");
61438+
61439+ mvOsOutput(" Bit \n");
61440+ break;
61441+/*----------------------------------------------------------------------------*/
61442+
61443+ case 17: /* Number Of Banks On Each Device */
61444+ mvOsOutput("Number Of Banks On Each Chip: %d\n",
61445+ dimmInfo.numOfBanksOnEachDevice);
61446+ break;
61447+/*----------------------------------------------------------------------------*/
61448+
61449+ case 18: /* Suported Cas Latencies */
61450+
61451+ /* SDRAM:
61452+ *******-******-******-******-******-******-******-*******
61453+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
61454+ *******-******-******-******-******-******-******-*******
61455+ CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
61456+ ********************************************************/
61457+
61458+ /* DDR 1:
61459+ *******-******-******-******-******-******-******-*******
61460+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
61461+ *******-******-******-******-******-******-******-*******
61462+ CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
61463+ *********************************************************/
61464+
61465+ /* DDR 2:
61466+ *******-******-******-******-******-******-******-*******
61467+ * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
61468+ *******-******-******-******-******-******-******-*******
61469+ CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
61470+ *********************************************************/
61471+
61472+ mvOsOutput("Suported Cas Latencies: (CL) ");
61473+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
61474+ {
61475+ for (k = 0; k <=7; k++)
61476+ {
61477+ if (dimmInfo.suportedCasLatencies & (1 << k))
61478+ mvOsOutput("%d, ", k+1);
61479+ }
61480+ }
61481+ else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
61482+ {
61483+ if (dimmInfo.suportedCasLatencies & BIT0)
61484+ mvOsOutput("1, ");
61485+ if (dimmInfo.suportedCasLatencies & BIT1)
61486+ mvOsOutput("1.5, ");
61487+ if (dimmInfo.suportedCasLatencies & BIT2)
61488+ mvOsOutput("2, ");
61489+ if (dimmInfo.suportedCasLatencies & BIT3)
61490+ mvOsOutput("2.5, ");
61491+ if (dimmInfo.suportedCasLatencies & BIT4)
61492+ mvOsOutput("3, ");
61493+ if (dimmInfo.suportedCasLatencies & BIT5)
61494+ mvOsOutput("3.5, ");
61495+ }
61496+ else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
61497+ {
61498+ if (dimmInfo.suportedCasLatencies & BIT2)
61499+ mvOsOutput("2, ");
61500+ if (dimmInfo.suportedCasLatencies & BIT3)
61501+ mvOsOutput("3, ");
61502+ if (dimmInfo.suportedCasLatencies & BIT4)
61503+ mvOsOutput("4, ");
61504+ if (dimmInfo.suportedCasLatencies & BIT5)
61505+ mvOsOutput("5, ");
61506+ }
61507+ else
61508+ mvOsOutput("?.?, ");
61509+ mvOsOutput("\n");
61510+ break;
61511+/*----------------------------------------------------------------------------*/
61512+
61513+ case 20: /* DDR2 DIMM type info */
61514+ if (dimmInfo.memoryType == MEM_TYPE_DDR2)
61515+ {
61516+ if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
61517+ mvOsOutput("Registered DIMM (RDIMM)\n");
61518+ else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
61519+ mvOsOutput("Unbuffered DIMM (UDIMM)\n");
61520+ else
61521+ mvOsOutput("Unknown DIMM type.\n");
61522+ }
61523+
61524+ break;
61525+/*----------------------------------------------------------------------------*/
61526+
61527+ case 21: /* SDRAM Modules Attributes */
61528+ mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
61529+
61530+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
61531+ {
61532+ if (dimmInfo.dimmAttributes & BIT0)
61533+ mvOsOutput(" Buffered Addr/Control Input: Yes\n");
61534+ else
61535+ mvOsOutput(" Buffered Addr/Control Input: No\n");
61536+
61537+ if (dimmInfo.dimmAttributes & BIT1)
61538+ mvOsOutput(" Registered Addr/Control Input: Yes\n");
61539+ else
61540+ mvOsOutput(" Registered Addr/Control Input: No\n");
61541+
61542+ if (dimmInfo.dimmAttributes & BIT2)
61543+ mvOsOutput(" On-Card PLL (clock): Yes \n");
61544+ else
61545+ mvOsOutput(" On-Card PLL (clock): No \n");
61546+
61547+ if (dimmInfo.dimmAttributes & BIT3)
61548+ mvOsOutput(" Bufferd DQMB Input: Yes \n");
61549+ else
61550+ mvOsOutput(" Bufferd DQMB Inputs: No \n");
61551+
61552+ if (dimmInfo.dimmAttributes & BIT4)
61553+ mvOsOutput(" Registered DQMB Inputs: Yes \n");
61554+ else
61555+ mvOsOutput(" Registered DQMB Inputs: No \n");
61556+
61557+ if (dimmInfo.dimmAttributes & BIT5)
61558+ mvOsOutput(" Differential Clock Input: Yes \n");
61559+ else
61560+ mvOsOutput(" Differential Clock Input: No \n");
61561+
61562+ if (dimmInfo.dimmAttributes & BIT6)
61563+ mvOsOutput(" redundant Row Addressing: Yes \n");
61564+ else
61565+ mvOsOutput(" redundant Row Addressing: No \n");
61566+ }
61567+ else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
61568+ {
61569+ if (dimmInfo.dimmAttributes & BIT0)
61570+ mvOsOutput(" Buffered Addr/Control Input: Yes\n");
61571+ else
61572+ mvOsOutput(" Buffered Addr/Control Input: No\n");
61573+
61574+ if (dimmInfo.dimmAttributes & BIT1)
61575+ mvOsOutput(" Registered Addr/Control Input: Yes\n");
61576+ else
61577+ mvOsOutput(" Registered Addr/Control Input: No\n");
61578+
61579+ if (dimmInfo.dimmAttributes & BIT2)
61580+ mvOsOutput(" On-Card PLL (clock): Yes \n");
61581+ else
61582+ mvOsOutput(" On-Card PLL (clock): No \n");
61583+
61584+ if (dimmInfo.dimmAttributes & BIT3)
61585+ mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
61586+ else
61587+ mvOsOutput(" FET Switch On-Card Enabled: No \n");
61588+
61589+ if (dimmInfo.dimmAttributes & BIT4)
61590+ mvOsOutput(" FET Switch External Enabled: Yes \n");
61591+ else
61592+ mvOsOutput(" FET Switch External Enabled: No \n");
61593+
61594+ if (dimmInfo.dimmAttributes & BIT5)
61595+ mvOsOutput(" Differential Clock Input: Yes \n");
61596+ else
61597+ mvOsOutput(" Differential Clock Input: No \n");
61598+ }
61599+ else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
61600+ {
61601+ mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
61602+ (dimmInfo.dimmAttributes & 0x3) + 1);
61603+
61604+ mvOsOutput(" Number of PLLs on the DIMM: %d\n",
61605+ ((dimmInfo.dimmAttributes) >> 2) & 0x3);
61606+
61607+ if (dimmInfo.dimmAttributes & BIT4)
61608+ mvOsOutput(" FET Switch External Enabled: Yes \n");
61609+ else
61610+ mvOsOutput(" FET Switch External Enabled: No \n");
61611+
61612+ if (dimmInfo.dimmAttributes & BIT6)
61613+ mvOsOutput(" Analysis probe installed: Yes \n");
61614+ else
61615+ mvOsOutput(" Analysis probe installed: No \n");
61616+ }
61617+
61618+ break;
61619+/*----------------------------------------------------------------------------*/
61620+
61621+ case 22: /* Suported AutoPreCharge */
61622+ mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
61623+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
61624+ {
61625+ if ( spdRawData[i] & BIT0 )
61626+ mvOsOutput(" Early Ras Precharge: Yes \n");
61627+ else
61628+ mvOsOutput(" Early Ras Precharge: No \n");
61629+
61630+ if ( spdRawData[i] & BIT1 )
61631+ mvOsOutput(" AutoPreCharge: Yes \n");
61632+ else
61633+ mvOsOutput(" AutoPreCharge: No \n");
61634+
61635+ if ( spdRawData[i] & BIT2 )
61636+ mvOsOutput(" Precharge All: Yes \n");
61637+ else
61638+ mvOsOutput(" Precharge All: No \n");
61639+
61640+ if ( spdRawData[i] & BIT3 )
61641+ mvOsOutput(" Write 1/ReadBurst: Yes \n");
61642+ else
61643+ mvOsOutput(" Write 1/ReadBurst: No \n");
61644+
61645+ if ( spdRawData[i] & BIT4 )
61646+ mvOsOutput(" lower VCC tolerance: 5%%\n");
61647+ else
61648+ mvOsOutput(" lower VCC tolerance: 10%%\n");
61649+
61650+ if ( spdRawData[i] & BIT5 )
61651+ mvOsOutput(" upper VCC tolerance: 5%%\n");
61652+ else
61653+ mvOsOutput(" upper VCC tolerance: 10%%\n");
61654+ }
61655+ else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
61656+ {
61657+ if ( spdRawData[i] & BIT0 )
61658+ mvOsOutput(" Supports Weak Driver: Yes \n");
61659+ else
61660+ mvOsOutput(" Supports Weak Driver: No \n");
61661+
61662+ if ( !(spdRawData[i] & BIT4) )
61663+ mvOsOutput(" lower VCC tolerance: 0.2V\n");
61664+
61665+ if ( !(spdRawData[i] & BIT5) )
61666+ mvOsOutput(" upper VCC tolerance: 0.2V\n");
61667+
61668+ if ( spdRawData[i] & BIT6 )
61669+ mvOsOutput(" Concurrent Auto Preharge: Yes \n");
61670+ else
61671+ mvOsOutput(" Concurrent Auto Preharge: No \n");
61672+
61673+ if ( spdRawData[i] & BIT7 )
61674+ mvOsOutput(" Supports Fast AP: Yes \n");
61675+ else
61676+ mvOsOutput(" Supports Fast AP: No \n");
61677+ }
61678+ else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
61679+ {
61680+ if ( spdRawData[i] & BIT0 )
61681+ mvOsOutput(" Supports Weak Driver: Yes \n");
61682+ else
61683+ mvOsOutput(" Supports Weak Driver: No \n");
61684+ }
61685+ break;
61686+/*----------------------------------------------------------------------------*/
61687+
61688+ case 23:
61689+ /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
61690+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
61691+ rightOfPoint = (spdRawData[i] & 0x0f) * 10;
61692+
61693+ /* DDR2 addition of right of point */
61694+ if ((spdRawData[i] & 0x0f) == 0xA)
61695+ {
61696+ rightOfPoint = 25;
61697+ }
61698+ if ((spdRawData[i] & 0x0f) == 0xB)
61699+ {
61700+ rightOfPoint = 33;
61701+ }
61702+ if ((spdRawData[i] & 0x0f) == 0xC)
61703+ {
61704+ rightOfPoint = 66;
61705+ }
61706+ if ((spdRawData[i] & 0x0f) == 0xD)
61707+ {
61708+ rightOfPoint = 75;
61709+ }
61710+
61711+ mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
61712+ "(0 = Not supported): %d.%d [ns]\n",
61713+ leftOfPoint, rightOfPoint );
61714+ break;
61715+/*----------------------------------------------------------------------------*/
61716+
61717+ case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
61718+ div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
61719+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
61720+ ((spdRawData[i] & 0x0f));
61721+ leftOfPoint = time_tmp / div;
61722+ rightOfPoint = time_tmp % div;
61723+ mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
61724+ leftOfPoint, rightOfPoint);
61725+ break;
61726+/*----------------------------------------------------------------------------*/
61727+
61728+ case 25:
61729+ /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
61730+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
61731+ {
61732+ leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
61733+ rightOfPoint = (spdRawData[i] & 0x3) * 25;
61734+ }
61735+ else /* DDR1 or DDR2 */
61736+ {
61737+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
61738+ rightOfPoint = (spdRawData[i] & 0x0f) * 10;
61739+
61740+ /* DDR2 addition of right of point */
61741+ if ((spdRawData[i] & 0x0f) == 0xA)
61742+ {
61743+ rightOfPoint = 25;
61744+ }
61745+ if ((spdRawData[i] & 0x0f) == 0xB)
61746+ {
61747+ rightOfPoint = 33;
61748+ }
61749+ if ((spdRawData[i] & 0x0f) == 0xC)
61750+ {
61751+ rightOfPoint = 66;
61752+ }
61753+ if ((spdRawData[i] & 0x0f) == 0xD)
61754+ {
61755+ rightOfPoint = 75;
61756+ }
61757+ }
61758+ mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
61759+ "(0 = Not supported): %d.%d [ns]\n",
61760+ leftOfPoint, rightOfPoint );
61761+ break;
61762+/*----------------------------------------------------------------------------*/
61763+
61764+ case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
61765+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
61766+ {
61767+ leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
61768+ rightOfPoint = (spdRawData[i] & 0x3) * 25;
61769+ }
61770+ else /* DDR1 or DDR2 */
61771+ {
61772+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
61773+ ((spdRawData[i] & 0x0f));
61774+ leftOfPoint = 0;
61775+ rightOfPoint = time_tmp;
61776+ }
61777+ mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
61778+ leftOfPoint, rightOfPoint );
61779+ break;
61780+/*----------------------------------------------------------------------------*/
61781+
61782+ case 27: /* Minimum Row Precharge Time */
61783+ shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
61784+ maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
61785+ 0xff : 0xfc;
61786+ maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
61787+ 0x00 : 0x03;
61788+ leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
61789+ rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
61790+ temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
61791+ trp_clocks = (temp + (busClkPs-1)) / busClkPs;
61792+ mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
61793+ "in Clk cycles %d\n",
61794+ leftOfPoint, rightOfPoint, trp_clocks);
61795+ break;
61796+/*----------------------------------------------------------------------------*/
61797+
61798+ case 28: /* Minimum Row Active to Row Active Time */
61799+ shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
61800+ maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
61801+ 0xff : 0xfc;
61802+ maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
61803+ 0x00 : 0x03;
61804+ leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
61805+ rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
61806+ temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
61807+ trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
61808+ mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
61809+ "%d.%d = in Clk cycles %d\n",
61810+ leftOfPoint, rightOfPoint, trp_clocks);
61811+ break;
61812+/*----------------------------------------------------------------------------*/
61813+
61814+ case 29: /* Minimum Ras-To-Cas Delay */
61815+ shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
61816+ maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
61817+ 0xff : 0xfc;
61818+ maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
61819+ 0x00 : 0x03;
61820+ leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
61821+ rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
61822+ temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
61823+ trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
61824+ mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
61825+ "in Clk cycles %d\n",
61826+ leftOfPoint, rightOfPoint, trp_clocks);
61827+ break;
61828+/*----------------------------------------------------------------------------*/
61829+
61830+ case 30: /* Minimum Ras Pulse Width */
61831+ tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
61832+ mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
61833+ "in Clk cycles %d\n", spdRawData[i], tras_clocks);
61834+ break;
61835+/*----------------------------------------------------------------------------*/
61836+
61837+ case 31: /* Module Bank Density */
61838+ mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
61839+
61840+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
61841+ {
61842+ if (dimmInfo.dimmBankDensity & BIT0)
61843+ mvOsOutput("1GB, ");
61844+ if (dimmInfo.dimmBankDensity & BIT1)
61845+ mvOsOutput("8MB, ");
61846+ if (dimmInfo.dimmBankDensity & BIT2)
61847+ mvOsOutput("16MB, ");
61848+ if (dimmInfo.dimmBankDensity & BIT3)
61849+ mvOsOutput("32MB, ");
61850+ if (dimmInfo.dimmBankDensity & BIT4)
61851+ mvOsOutput("64MB, ");
61852+ if (dimmInfo.dimmBankDensity & BIT5)
61853+ mvOsOutput("128MB, ");
61854+ if (dimmInfo.dimmBankDensity & BIT6)
61855+ mvOsOutput("256MB, ");
61856+ if (dimmInfo.dimmBankDensity & BIT7)
61857+ mvOsOutput("512MB, ");
61858+ }
61859+ else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
61860+ {
61861+ if (dimmInfo.dimmBankDensity & BIT0)
61862+ mvOsOutput("1GB, ");
61863+ if (dimmInfo.dimmBankDensity & BIT1)
61864+ mvOsOutput("2GB, ");
61865+ if (dimmInfo.dimmBankDensity & BIT2)
61866+ mvOsOutput("16MB, ");
61867+ if (dimmInfo.dimmBankDensity & BIT3)
61868+ mvOsOutput("32MB, ");
61869+ if (dimmInfo.dimmBankDensity & BIT4)
61870+ mvOsOutput("64MB, ");
61871+ if (dimmInfo.dimmBankDensity & BIT5)
61872+ mvOsOutput("128MB, ");
61873+ if (dimmInfo.dimmBankDensity & BIT6)
61874+ mvOsOutput("256MB, ");
61875+ if (dimmInfo.dimmBankDensity & BIT7)
61876+ mvOsOutput("512MB, ");
61877+ }
61878+ else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
61879+ {
61880+ if (dimmInfo.dimmBankDensity & BIT0)
61881+ mvOsOutput("1GB, ");
61882+ if (dimmInfo.dimmBankDensity & BIT1)
61883+ mvOsOutput("2GB, ");
61884+ if (dimmInfo.dimmBankDensity & BIT2)
61885+ mvOsOutput("4GB, ");
61886+ if (dimmInfo.dimmBankDensity & BIT3)
61887+ mvOsOutput("8GB, ");
61888+ if (dimmInfo.dimmBankDensity & BIT4)
61889+ mvOsOutput("16GB, ");
61890+ if (dimmInfo.dimmBankDensity & BIT5)
61891+ mvOsOutput("128MB, ");
61892+ if (dimmInfo.dimmBankDensity & BIT6)
61893+ mvOsOutput("256MB, ");
61894+ if (dimmInfo.dimmBankDensity & BIT7)
61895+ mvOsOutput("512MB, ");
61896+ }
61897+ mvOsOutput("\n");
61898+ break;
61899+/*----------------------------------------------------------------------------*/
61900+
61901+ case 32: /* Address And Command Setup Time (measured in ns/1000) */
61902+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
61903+ {
61904+ rightOfPoint = (spdRawData[i] & 0x0f);
61905+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
61906+ if(leftOfPoint > 7)
61907+ {
61908+ leftOfPoint *= -1;
61909+ }
61910+ }
61911+ else /* DDR1 or DDR2 */
61912+ {
61913+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
61914+ ((spdRawData[i] & 0x0f));
61915+ leftOfPoint = time_tmp / 100;
61916+ rightOfPoint = time_tmp % 100;
61917+ }
61918+ mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
61919+ leftOfPoint, rightOfPoint);
61920+ break;
61921+/*----------------------------------------------------------------------------*/
61922+
61923+ case 33: /* Address And Command Hold Time */
61924+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
61925+ {
61926+ rightOfPoint = (spdRawData[i] & 0x0f);
61927+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
61928+ if(leftOfPoint > 7)
61929+ {
61930+ leftOfPoint *= -1;
61931+ }
61932+ }
61933+ else /* DDR1 or DDR2 */
61934+ {
61935+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
61936+ ((spdRawData[i] & 0x0f));
61937+ leftOfPoint = time_tmp / 100;
61938+ rightOfPoint = time_tmp % 100;
61939+ }
61940+ mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
61941+ leftOfPoint, rightOfPoint);
61942+ break;
61943+/*----------------------------------------------------------------------------*/
61944+
61945+ case 34: /* Data Input Setup Time */
61946+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
61947+ {
61948+ rightOfPoint = (spdRawData[i] & 0x0f);
61949+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
61950+ if(leftOfPoint > 7)
61951+ {
61952+ leftOfPoint *= -1;
61953+ }
61954+ }
61955+ else /* DDR1 or DDR2 */
61956+ {
61957+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
61958+ ((spdRawData[i] & 0x0f));
61959+ leftOfPoint = time_tmp / 100;
61960+ rightOfPoint = time_tmp % 100;
61961+ }
61962+ mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
61963+ leftOfPoint, rightOfPoint);
61964+ break;
61965+/*----------------------------------------------------------------------------*/
61966+
61967+ case 35: /* Data Input Hold Time */
61968+ if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
61969+ {
61970+ rightOfPoint = (spdRawData[i] & 0x0f);
61971+ leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
61972+ if(leftOfPoint > 7)
61973+ {
61974+ leftOfPoint *= -1;
61975+ }
61976+ }
61977+ else /* DDR1 or DDR2 */
61978+ {
61979+ time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
61980+ ((spdRawData[i] & 0x0f));
61981+ leftOfPoint = time_tmp / 100;
61982+ rightOfPoint = time_tmp % 100;
61983+ }
61984+ mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
61985+ leftOfPoint, rightOfPoint);
61986+ break;
61987+/*----------------------------------------------------------------------------*/
61988+
61989+ case 36: /* Relevant for DDR2 only: Write Recovery Time */
61990+ leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
61991+ rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
61992+ mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
61993+ leftOfPoint, rightOfPoint);
61994+ break;
61995+/*----------------------------------------------------------------------------*/
61996+ }
61997+
61998+}
61999+
62000+
62001+/*
62002+ * translate ns.ns/10 coding of SPD timing values
62003+ * into ps unit values
62004+ */
62005+/*******************************************************************************
62006+* cas2ps - Translate x.y ns parameter to pico-seconds values
62007+*
62008+* DESCRIPTION:
62009+* This function translates x.y nano seconds to its value in pico seconds.
62010+* For example 3.75ns will return 3750.
62011+*
62012+* INPUT:
62013+* spd_byte - DIMM SPD byte.
62014+*
62015+* OUTPUT:
62016+* None.
62017+*
62018+* RETURN:
62019+* value in pico seconds.
62020+*
62021+*******************************************************************************/
62022+static MV_U32 cas2ps(MV_U8 spd_byte)
62023+{
62024+ MV_U32 ns, ns10;
62025+
62026+ /* isolate upper nibble */
62027+ ns = (spd_byte >> 4) & 0x0F;
62028+ /* isolate lower nibble */
62029+ ns10 = (spd_byte & 0x0F);
62030+
62031+ if( ns10 < 10 ) {
62032+ ns10 *= 10;
62033+ }
62034+ else if( ns10 == 10 )
62035+ ns10 = 25;
62036+ else if( ns10 == 11 )
62037+ ns10 = 33;
62038+ else if( ns10 == 12 )
62039+ ns10 = 66;
62040+ else if( ns10 == 13 )
62041+ ns10 = 75;
62042+ else
62043+ {
62044+ mvOsOutput("cas2ps Err. unsupported cycle time.\n");
62045+ }
62046+
62047+ return (ns*1000 + ns10*10);
62048+}
62049+
62050diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h
62051new file mode 100644
62052index 0000000..ae692ef
62053--- /dev/null
62054+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h
62055@@ -0,0 +1,192 @@
62056+/*******************************************************************************
62057+Copyright (C) Marvell International Ltd. and its affiliates
62058+
62059+This software file (the "File") is owned and distributed by Marvell
62060+International Ltd. and/or its affiliates ("Marvell") under the following
62061+alternative licensing terms. Once you have made an election to distribute the
62062+File under one of the following license alternatives, please (i) delete this
62063+introductory statement regarding license alternatives, (ii) delete the two
62064+license alternatives that you have not elected to use and (iii) preserve the
62065+Marvell copyright notice above.
62066+
62067+********************************************************************************
62068+Marvell Commercial License Option
62069+
62070+If you received this File from Marvell and you have entered into a commercial
62071+license agreement (a "Commercial License") with Marvell, the File is licensed
62072+to you under the terms of the applicable Commercial License.
62073+
62074+********************************************************************************
62075+Marvell GPL License Option
62076+
62077+If you received this File from Marvell, you may opt to use, redistribute and/or
62078+modify this File in accordance with the terms and conditions of the General
62079+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
62080+available along with the File in the license.txt file or by writing to the Free
62081+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
62082+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
62083+
62084+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
62085+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
62086+DISCLAIMED. The GPL License provides additional details about this warranty
62087+disclaimer.
62088+********************************************************************************
62089+Marvell BSD License Option
62090+
62091+If you received this File from Marvell, you may opt to use, redistribute and/or
62092+modify this File under the following licensing terms.
62093+Redistribution and use in source and binary forms, with or without modification,
62094+are permitted provided that the following conditions are met:
62095+
62096+ * Redistributions of source code must retain the above copyright notice,
62097+ this list of conditions and the following disclaimer.
62098+
62099+ * Redistributions in binary form must reproduce the above copyright
62100+ notice, this list of conditions and the following disclaimer in the
62101+ documentation and/or other materials provided with the distribution.
62102+
62103+ * Neither the name of Marvell nor the names of its contributors may be
62104+ used to endorse or promote products derived from this software without
62105+ specific prior written permission.
62106+
62107+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
62108+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62109+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62110+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
62111+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62112+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62113+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
62114+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62115+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62116+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62117+
62118+*******************************************************************************/
62119+
62120+#ifndef __INCmvDram
62121+#define __INCmvDram
62122+
62123+#include "ddr2/mvDramIf.h"
62124+#include "twsi/mvTwsi.h"
62125+
62126+#define MAX_DIMM_NUM 2
62127+#define SPD_SIZE 128
62128+
62129+/* Dimm spd offsets */
62130+#define DIMM_MEM_TYPE 2
62131+#define DIMM_ROW_NUM 3
62132+#define DIMM_COL_NUM 4
62133+#define DIMM_MODULE_BANK_NUM 5
62134+#define DIMM_DATA_WIDTH 6
62135+#define DIMM_VOLT_IF 8
62136+#define DIMM_MIN_CC_AT_MAX_CAS 9
62137+#define DIMM_ERR_CHECK_TYPE 11
62138+#define DIMM_REFRESH_INTERVAL 12
62139+#define DIMM_SDRAM_WIDTH 13
62140+#define DIMM_ERR_CHECK_DATA_WIDTH 14
62141+#define DIMM_MIN_CLK_DEL 15
62142+#define DIMM_BURST_LEN_SUP 16
62143+#define DIMM_DEV_BANK_NUM 17
62144+#define DIMM_SUP_CAL 18
62145+#define DIMM_DDR2_TYPE_INFORMATION 20 /* DDR2 only */
62146+#define DIMM_BUF_ADDR_CONT_IN 21
62147+#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1 23
62148+#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2 25
62149+#define DIMM_MIN_ROW_PRECHARGE_TIME 27
62150+#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE 28
62151+#define DIMM_MIN_RAS_TO_CAS_DELAY 29
62152+#define DIMM_MIN_RAS_PULSE_WIDTH 30
62153+#define DIMM_BANK_DENSITY 31
62154+#define DIMM_MIN_WRITE_RECOVERY_TIME 36
62155+#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY 37
62156+#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY 38
62157+#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD 42
62158+#define DIMM_SPD_VERSION 62
62159+
62160+/* Dimm Memory Type values */
62161+#define DIMM_MEM_TYPE_SDRAM 0x4
62162+#define DIMM_MEM_TYPE_DDR1 0x7
62163+#define DIMM_MEM_TYPE_DDR2 0x8
62164+
62165+#define DIMM_MODULE_MANU_OFFS 64
62166+#define DIMM_MODULE_MANU_SIZE 8
62167+#define DIMM_MODULE_VEN_OFFS 73
62168+#define DIMM_MODULE_VEN_SIZE 25
62169+#define DIMM_MODULE_ID_OFFS 99
62170+#define DIMM_MODULE_ID_SIZE 18
62171+
62172+/* enumeration for voltage levels. */
62173+typedef enum _mvDimmVoltageIf
62174+{
62175+ TTL_5V_TOLERANT,
62176+ LVTTL,
62177+ HSTL_1_5V,
62178+ SSTL_3_3V,
62179+ SSTL_2_5V,
62180+ VOLTAGE_UNKNOWN,
62181+} MV_DIMM_VOLTAGE_IF;
62182+
62183+
62184+/* enumaration for SDRAM CAS Latencies. */
62185+typedef enum _mvDimmSdramCas
62186+{
62187+ SD_CL_1 =1,
62188+ SD_CL_2,
62189+ SD_CL_3,
62190+ SD_CL_4,
62191+ SD_CL_5,
62192+ SD_CL_6,
62193+ SD_CL_7,
62194+ SD_FAULT
62195+}MV_DIMM_SDRAM_CAS;
62196+
62197+
62198+/* DIMM information structure */
62199+typedef struct _mvDimmInfo
62200+{
62201+ MV_MEMORY_TYPE memoryType; /* DDR or SDRAM */
62202+
62203+ MV_U8 spdRawData[SPD_SIZE]; /* Content of SPD-EEPROM copied 1:1 */
62204+
62205+ /* DIMM dimensions */
62206+ MV_U32 numOfRowAddr;
62207+ MV_U32 numOfColAddr;
62208+ MV_U32 numOfModuleBanks;
62209+ MV_U32 dataWidth;
62210+ MV_U32 errorCheckType; /* ECC , PARITY..*/
62211+ MV_U32 sdramWidth; /* 4,8,16 or 32 */
62212+ MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
62213+ MV_U32 burstLengthSupported;
62214+ MV_U32 numOfBanksOnEachDevice;
62215+ MV_U32 suportedCasLatencies;
62216+ MV_U32 refreshInterval;
62217+ MV_U32 dimmBankDensity;
62218+ MV_U32 dimmTypeInfo; /* DDR2 only */
62219+ MV_U32 dimmAttributes;
62220+
62221+ /* DIMM timing parameters */
62222+ MV_U32 minCycleTimeAtMaxCasLatPs;
62223+ MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
62224+ MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
62225+ MV_U32 minRowPrechargeTime;
62226+ MV_U32 minRowActiveToRowActive;
62227+ MV_U32 minRasToCasDelay;
62228+ MV_U32 minRasPulseWidth;
62229+ MV_U32 minWriteRecoveryTime; /* DDR2 only */
62230+ MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
62231+ MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
62232+ MV_U32 minRefreshToActiveCmd; /* DDR2 only */
62233+
62234+ /* Parameters calculated from the extracted DIMM information */
62235+ MV_U32 size; /* 16,64,128,256 or 512 MByte in MB units */
62236+ MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit in MB units */
62237+ MV_U32 numberOfDevices;
62238+
62239+} MV_DIMM_INFO;
62240+
62241+
62242+MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);
62243+MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);
62244+MV_VOID dimmSpdPrint(MV_U32 dimmNum);
62245+MV_STATUS dimmSpdCpy(MV_VOID);
62246+
62247+#endif /* __INCmvDram */
62248diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c b/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c
62249new file mode 100644
62250index 0000000..2acd82b
62251--- /dev/null
62252+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c
62253@@ -0,0 +1,2952 @@
62254+/*******************************************************************************
62255+Copyright (C) Marvell International Ltd. and its affiliates
62256+
62257+This software file (the "File") is owned and distributed by Marvell
62258+International Ltd. and/or its affiliates ("Marvell") under the following
62259+alternative licensing terms. Once you have made an election to distribute the
62260+File under one of the following license alternatives, please (i) delete this
62261+introductory statement regarding license alternatives, (ii) delete the two
62262+license alternatives that you have not elected to use and (iii) preserve the
62263+Marvell copyright notice above.
62264+
62265+********************************************************************************
62266+Marvell Commercial License Option
62267+
62268+If you received this File from Marvell and you have entered into a commercial
62269+license agreement (a "Commercial License") with Marvell, the File is licensed
62270+to you under the terms of the applicable Commercial License.
62271+
62272+********************************************************************************
62273+Marvell GPL License Option
62274+
62275+If you received this File from Marvell, you may opt to use, redistribute and/or
62276+modify this File in accordance with the terms and conditions of the General
62277+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
62278+available along with the File in the license.txt file or by writing to the Free
62279+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
62280+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
62281+
62282+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
62283+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
62284+DISCLAIMED. The GPL License provides additional details about this warranty
62285+disclaimer.
62286+********************************************************************************
62287+Marvell BSD License Option
62288+
62289+If you received this File from Marvell, you may opt to use, redistribute and/or
62290+modify this File under the following licensing terms.
62291+Redistribution and use in source and binary forms, with or without modification,
62292+are permitted provided that the following conditions are met:
62293+
62294+ * Redistributions of source code must retain the above copyright notice,
62295+ this list of conditions and the following disclaimer.
62296+
62297+ * Redistributions in binary form must reproduce the above copyright
62298+ notice, this list of conditions and the following disclaimer in the
62299+ documentation and/or other materials provided with the distribution.
62300+
62301+ * Neither the name of Marvell nor the names of its contributors may be
62302+ used to endorse or promote products derived from this software without
62303+ specific prior written permission.
62304+
62305+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
62306+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62307+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62308+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
62309+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62310+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62311+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
62312+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62313+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62314+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62315+
62316+*******************************************************************************/
62317+
62318+/*******************************************************************************
62319+* mvEth.c - Marvell's Gigabit Ethernet controller low level driver
62320+*
62321+* DESCRIPTION:
62322+* This file introduce OS independent APIs to Marvell's Gigabit Ethernet
62323+* controller. This Gigabit Ethernet Controller driver API controls
62324+* 1) Operations (i.e. port Init, Finish, Up, Down, PhyReset etc').
62325+* 2) Data flow (i.e. port Send, Receive etc').
62326+* 3) MAC Filtering functions (ethSetMcastAddr, ethSetRxFilterMode, etc.)
62327+* 4) MIB counters support (ethReadMibCounter)
62328+* 5) Debug functions (ethPortRegs, ethPortCounters, ethPortQueues, etc.)
62329+* Each Gigabit Ethernet port is controlled via ETH_PORT_CTRL struct.
62330+* This struct includes configuration information as well as driver
62331+* internal data needed for its operations.
62332+*
62333+* Supported Features:
62334+* - OS independent. All required OS services are implemented via external
62335+* OS dependent components (like osLayer or ethOsg)
62336+* - The user is free from Rx/Tx queue managing.
62337+* - Simple Gigabit Ethernet port operation API.
62338+* - Simple Gigabit Ethernet port data flow API.
62339+* - Data flow and operation API support per queue functionality.
62340+* - Support cached descriptors for better performance.
62341+* - PHY access and control API.
62342+* - Port Configuration API.
62343+* - Full control over Special and Other Multicast MAC tables.
62344+*
62345+*******************************************************************************/
62346+/* includes */
62347+#include "mvTypes.h"
62348+#include "mv802_3.h"
62349+#include "mvDebug.h"
62350+#include "mvCommon.h"
62351+#include "mvOs.h"
62352+#include "ctrlEnv/mvCtrlEnvLib.h"
62353+#include "eth-phy/mvEthPhy.h"
62354+#include "eth/mvEth.h"
62355+#include "eth/gbe/mvEthGbe.h"
62356+#include "cpu/mvCpu.h"
62357+
62358+#ifdef INCLUDE_SYNC_BARR
62359+#include "sys/mvCpuIf.h"
62360+#endif
62361+
62362+#ifdef MV_RT_DEBUG
62363+# define ETH_DEBUG
62364+#endif
62365+
62366+
62367+/* locals */
62368+MV_BOOL ethDescInSram;
62369+MV_BOOL ethDescSwCoher;
62370+
62371+/* This array holds the control structure of each port */
62372+ETH_PORT_CTRL* ethPortCtrl[MV_ETH_MAX_PORTS];
62373+
62374+/* Ethernet Port Local routines */
62375+
62376+static void ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);
62377+
62378+static void ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);
62379+
62380+static void ethSetUcastTable(int portNo, int queue);
62381+
62382+static MV_BOOL ethSetUcastAddr (int ethPortNum, MV_U8 lastNibble, int queue);
62383+static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue);
62384+static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue);
62385+
62386+static void ethFreeDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, MV_BUF_INFO* pDescBuf);
62387+static MV_U8* ethAllocDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, int size,
62388+ MV_ULONG* pPhysAddr, MV_U32 *memHandle);
62389+
62390+static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize);
62391+
62392+static void mvEthPortSgmiiConfig(int port);
62393+
62394+
62395+
62396+/******************************************************************************/
62397+/* EthDrv Initialization functions */
62398+/******************************************************************************/
62399+
62400+/*******************************************************************************
62401+* mvEthHalInit - Initialize the Giga Ethernet unit
62402+*
62403+* DESCRIPTION:
62404+* This function initialize the Giga Ethernet unit.
62405+* 1) Configure Address decode windows of the unit
62406+* 2) Set registers to HW default values.
62407+* 3) Clear and Disable interrupts
62408+*
62409+* INPUT: NONE
62410+*
62411+* RETURN: NONE
62412+*
62413+* NOTE: this function is called once in the boot process.
62414+*******************************************************************************/
62415+void mvEthHalInit(void)
62416+{
62417+ int port;
62418+
62419+ /* Init static data structures */
62420+ for (port=0; port<MV_ETH_MAX_PORTS; port++)
62421+ {
62422+ ethPortCtrl[port] = NULL;
62423+ }
62424+ /* Power down all existing ports */
62425+ for(port=0; port<mvCtrlEthMaxPortGet(); port++)
62426+ {
62427+
62428+#if defined (MV78200)
62429+ /* Skip ports mapped to another CPU*/
62430+ if (MV_FALSE == mvSocUnitIsMappedToThisCpu(GIGA0+port))
62431+ {
62432+ continue;
62433+ }
62434+#endif
62435+
62436+ /* Skip power down ports */
62437+ if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;
62438+
62439+ /* Disable Giga Ethernet Unit interrupts */
62440+ MV_REG_WRITE(ETH_UNIT_INTR_MASK_REG(port), 0);
62441+
62442+ /* Clear ETH_UNIT_INTR_CAUSE_REG register */
62443+ MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);
62444+
62445+ }
62446+
62447+ mvEthMemAttrGet(&ethDescInSram, &ethDescSwCoher);
62448+
62449+#if defined(ETH_DESCR_IN_SRAM)
62450+ if(ethDescInSram == MV_FALSE)
62451+ {
62452+ mvOsPrintf("ethDrv: WARNING! Descriptors will be allocated in DRAM instead of SRAM.\n");
62453+ }
62454+#endif /* ETH_DESCR_IN_SRAM */
62455+}
62456+
62457+/*******************************************************************************
62458+* mvEthMemAttrGet - Define properties (SRAM/DRAM, SW_COHER / HW_COHER / UNCACHED)
62459+* of of memory location for RX and TX descriptors.
62460+*
62461+* DESCRIPTION:
62462+* This function allocates memory for RX and TX descriptors.
62463+* - If ETH_DESCR_IN_SRAM defined, allocate from SRAM memory.
62464+* - If ETH_DESCR_IN_SDRAM defined, allocate from SDRAM memory.
62465+*
62466+* INPUT:
62467+* MV_BOOL* pIsSram - place of descriptors:
62468+* MV_TRUE - in SRAM
62469+* MV_FALSE - in DRAM
62470+* MV_BOOL* pIsSwCoher - cache coherency of descriptors:
62471+* MV_TRUE - driver is responsible for cache coherency
62472+* MV_FALSE - driver is not responsible for cache coherency
62473+*
62474+* RETURN:
62475+*
62476+*******************************************************************************/
62477+void mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher)
62478+{
62479+ MV_BOOL isSram, isSwCoher;
62480+
62481+ isSram = MV_FALSE;
62482+#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW)
62483+ isSwCoher = MV_TRUE;
62484+#else
62485+ isSwCoher = MV_FALSE;
62486+#endif
62487+
62488+#if defined(ETH_DESCR_IN_SRAM)
62489+ if( mvCtrlSramSizeGet() > 0)
62490+ {
62491+ isSram = MV_TRUE;
62492+ #if (INTEG_SRAM_COHER == MV_CACHE_COHER_SW)
62493+ isSwCoher = MV_TRUE;
62494+ #else
62495+ isSwCoher = MV_FALSE;
62496+ #endif
62497+ }
62498+#endif /* ETH_DESCR_IN_SRAM */
62499+
62500+ if(pIsSram != NULL)
62501+ *pIsSram = isSram;
62502+
62503+ if(pIsSwCoher != NULL)
62504+ *pIsSwCoher = isSwCoher;
62505+}
62506+
62507+
62508+
62509+/******************************************************************************/
62510+/* Port Initialization functions */
62511+/******************************************************************************/
62512+
62513+/*******************************************************************************
62514+* mvEthPortInit - Initialize the Ethernet port driver
62515+*
62516+* DESCRIPTION:
62517+* This function initialize the ethernet port.
62518+* 1) Allocate and initialize internal port Control structure.
62519+* 2) Create RX and TX descriptor rings for default RX and TX queues
62520+* 3) Disable RX and TX operations, clear cause registers and
62521+* mask all interrupts.
62522+* 4) Set all registers to default values and clean all MAC tables.
62523+*
62524+* INPUT:
62525+* int portNo - Ethernet port number
62526+* ETH_PORT_INIT *pEthPortInit - Ethernet port init structure
62527+*
62528+* RETURN:
62529+* void* - ethernet port handler, that should be passed to the most other
62530+* functions dealing with this port.
62531+*
62532+* NOTE: This function is called once per port when loading the eth module.
62533+*******************************************************************************/
62534+void* mvEthPortInit(int portNo, MV_ETH_PORT_INIT *pEthPortInit)
62535+{
62536+ int queue, descSize;
62537+ ETH_PORT_CTRL* pPortCtrl;
62538+
62539+ /* Check validity of parameters */
62540+ if( (portNo >= (int)mvCtrlEthMaxPortGet()) ||
62541+ (pEthPortInit->rxDefQ >= MV_ETH_RX_Q_NUM) ||
62542+ (pEthPortInit->maxRxPktSize < 1518) )
62543+ {
62544+ mvOsPrintf("EthPort #%d: Bad initialization parameters\n", portNo);
62545+ return NULL;
62546+ }
62547+ if( (pEthPortInit->rxDescrNum[pEthPortInit->rxDefQ]) == 0)
62548+ {
62549+ mvOsPrintf("EthPort #%d: rxDefQ (%d) must be created\n",
62550+ portNo, pEthPortInit->rxDefQ);
62551+ return NULL;
62552+ }
62553+
62554+ pPortCtrl = (ETH_PORT_CTRL*)mvOsMalloc( sizeof(ETH_PORT_CTRL) );
62555+ if(pPortCtrl == NULL)
62556+ {
62557+ mvOsPrintf("EthDrv: Can't allocate %dB for port #%d control structure!\n",
62558+ (int)sizeof(ETH_PORT_CTRL), portNo);
62559+ return NULL;
62560+ }
62561+
62562+ memset(pPortCtrl, 0, sizeof(ETH_PORT_CTRL) );
62563+ ethPortCtrl[portNo] = pPortCtrl;
62564+
62565+ pPortCtrl->portState = MV_UNDEFINED_STATE;
62566+
62567+ pPortCtrl->portNo = portNo;
62568+
62569+ pPortCtrl->osHandle = pEthPortInit->osHandle;
62570+
62571+ /* Copy Configuration parameters */
62572+ pPortCtrl->portConfig.maxRxPktSize = pEthPortInit->maxRxPktSize;
62573+ pPortCtrl->portConfig.rxDefQ = pEthPortInit->rxDefQ;
62574+ pPortCtrl->portConfig.ejpMode = 0;
62575+
62576+ for( queue=0; queue<MV_ETH_RX_Q_NUM; queue++ )
62577+ {
62578+ pPortCtrl->rxQueueConfig[queue].descrNum = pEthPortInit->rxDescrNum[queue];
62579+ }
62580+ for( queue=0; queue<MV_ETH_TX_Q_NUM; queue++ )
62581+ {
62582+ pPortCtrl->txQueueConfig[queue].descrNum = pEthPortInit->txDescrNum[queue];
62583+ }
62584+
62585+ mvEthPortDisable(pPortCtrl);
62586+
62587+ /* Set the board information regarding PHY address */
62588+ mvEthPhyAddrSet(pPortCtrl, mvBoardPhyAddrGet(portNo) );
62589+
62590+ /* Create all requested RX queues */
62591+ for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
62592+ {
62593+ if(pPortCtrl->rxQueueConfig[queue].descrNum == 0)
62594+ continue;
62595+
62596+ /* Allocate memory for RX descriptors */
62597+ descSize = ((pPortCtrl->rxQueueConfig[queue].descrNum * ETH_RX_DESC_ALIGNED_SIZE) +
62598+ CPU_D_CACHE_LINE_SIZE);
62599+
62600+ pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr =
62601+ ethAllocDescrMemory(pPortCtrl, descSize,
62602+ &pPortCtrl->rxQueue[queue].descBuf.bufPhysAddr,
62603+ &pPortCtrl->rxQueue[queue].descBuf.memHandle);
62604+ pPortCtrl->rxQueue[queue].descBuf.bufSize = descSize;
62605+ if(pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr == NULL)
62606+ {
62607+ mvOsPrintf("EthPort #%d, rxQ=%d: Can't allocate %d bytes in %s for %d RX descr\n",
62608+ pPortCtrl->portNo, queue, descSize,
62609+ ethDescInSram ? "SRAM" : "DRAM",
62610+ pPortCtrl->rxQueueConfig[queue].descrNum);
62611+ return NULL;
62612+ }
62613+
62614+ ethInitRxDescRing(pPortCtrl, queue);
62615+ }
62616+ /* Create TX queues */
62617+ for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
62618+ {
62619+ if(pPortCtrl->txQueueConfig[queue].descrNum == 0)
62620+ continue;
62621+
62622+ /* Allocate memory for TX descriptors */
62623+ descSize = ((pPortCtrl->txQueueConfig[queue].descrNum * ETH_TX_DESC_ALIGNED_SIZE) +
62624+ CPU_D_CACHE_LINE_SIZE);
62625+
62626+ pPortCtrl->txQueue[queue].descBuf.bufVirtPtr =
62627+ ethAllocDescrMemory(pPortCtrl, descSize,
62628+ &pPortCtrl->txQueue[queue].descBuf.bufPhysAddr,
62629+ &pPortCtrl->txQueue[queue].descBuf.memHandle);
62630+ pPortCtrl->txQueue[queue].descBuf.bufSize = descSize;
62631+ if(pPortCtrl->txQueue[queue].descBuf.bufVirtPtr == NULL)
62632+ {
62633+ mvOsPrintf("EthPort #%d, txQ=%d: Can't allocate %d bytes in %s for %d TX descr\n",
62634+ pPortCtrl->portNo, queue, descSize, ethDescInSram ? "SRAM" : "DRAM",
62635+ pPortCtrl->txQueueConfig[queue].descrNum);
62636+ return NULL;
62637+ }
62638+
62639+ ethInitTxDescRing(pPortCtrl, queue);
62640+ }
62641+ mvEthDefaultsSet(pPortCtrl);
62642+
62643+ pPortCtrl->portState = MV_IDLE;
62644+ return pPortCtrl;
62645+}
62646+
62647+/*******************************************************************************
62648+* ethPortFinish - Finish the Ethernet port driver
62649+*
62650+* DESCRIPTION:
62651+* This function finish the ethernet port.
62652+* 1) Down ethernet port if needed.
62653+* 2) Delete RX and TX descriptor rings for all created RX and TX queues
62654+* 3) Free internal port Control structure.
62655+*
62656+* INPUT:
62657+* void* pEthPortHndl - Ethernet port handler
62658+*
62659+* RETURN: NONE.
62660+*
62661+*******************************************************************************/
62662+void mvEthPortFinish(void* pPortHndl)
62663+{
62664+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
62665+ int queue, portNo = pPortCtrl->portNo;
62666+
62667+ if(pPortCtrl->portState == MV_ACTIVE)
62668+ {
62669+ mvOsPrintf("ethPort #%d: Warning !!! Finish port in Active state\n",
62670+ portNo);
62671+ mvEthPortDisable(pPortHndl);
62672+ }
62673+
62674+ /* Free all allocated RX queues */
62675+ for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
62676+ {
62677+ ethFreeDescrMemory(pPortCtrl, &pPortCtrl->rxQueue[queue].descBuf);
62678+ }
62679+
62680+ /* Free all allocated TX queues */
62681+ for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
62682+ {
62683+ ethFreeDescrMemory(pPortCtrl, &pPortCtrl->txQueue[queue].descBuf);
62684+ }
62685+
62686+ /* Free port control structure */
62687+ mvOsFree(pPortCtrl);
62688+
62689+ ethPortCtrl[portNo] = NULL;
62690+}
62691+
62692+/*******************************************************************************
62693+* mvEthDefaultsSet - Set defaults to the ethernet port
62694+*
62695+* DESCRIPTION:
62696+* This function set default values to the ethernet port.
62697+* 1) Clear Cause registers and Mask all interrupts
62698+* 2) Clear all MAC tables
62699+* 3) Set defaults to all registers
62700+* 4) Reset all created RX and TX descriptors ring
62701+* 5) Reset PHY
62702+*
62703+* INPUT:
62704+* void* pEthPortHndl - Ethernet port handler
62705+*
62706+* RETURN: MV_STATUS
62707+* MV_OK - Success, Others - Failure
62708+* NOTE:
62709+* This function update all the port configuration except those set
62710+* Initialy by the OsGlue by MV_ETH_PORT_INIT.
62711+* This function can be called after portDown to return the port setting
62712+* to defaults.
62713+*******************************************************************************/
62714+MV_STATUS mvEthDefaultsSet(void* pPortHndl)
62715+{
62716+ int ethPortNo, queue;
62717+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
62718+ ETH_QUEUE_CTRL* pQueueCtrl;
62719+ MV_U32 txPrio;
62720+ MV_U32 portCfgReg, portCfgExtReg, portSerialCtrlReg, portSerialCtrl1Reg, portSdmaCfgReg;
62721+ MV_BOARD_MAC_SPEED boardMacCfg;
62722+
62723+ ethPortNo = pPortCtrl->portNo;
62724+
62725+ /* Clear Cause registers */
62726+ MV_REG_WRITE(ETH_INTR_CAUSE_REG(ethPortNo),0);
62727+ MV_REG_WRITE(ETH_INTR_CAUSE_EXT_REG(ethPortNo),0);
62728+
62729+ /* Mask all interrupts */
62730+ MV_REG_WRITE(ETH_INTR_MASK_REG(ethPortNo),0);
62731+ MV_REG_WRITE(ETH_INTR_MASK_EXT_REG(ethPortNo),0);
62732+
62733+ portCfgReg = PORT_CONFIG_VALUE;
62734+ portCfgExtReg = PORT_CONFIG_EXTEND_VALUE;
62735+
62736+ boardMacCfg = mvBoardMacSpeedGet(ethPortNo);
62737+
62738+ if(boardMacCfg == BOARD_MAC_SPEED_100M)
62739+ {
62740+ portSerialCtrlReg = PORT_SERIAL_CONTROL_100MB_FORCE_VALUE;
62741+ }
62742+ else if(boardMacCfg == BOARD_MAC_SPEED_1000M)
62743+ {
62744+ portSerialCtrlReg = PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE;
62745+ }
62746+ else
62747+ {
62748+ portSerialCtrlReg = PORT_SERIAL_CONTROL_VALUE;
62749+ }
62750+
62751+ /* build PORT_SDMA_CONFIG_REG */
62752+ portSdmaCfgReg = ETH_TX_INTR_COAL_MASK(0);
62753+ portSdmaCfgReg |= ETH_TX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);
62754+
62755+#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB) || \
62756+ (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT) )
62757+ /* some devices have restricted RX burst size when using HW coherency */
62758+ portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_4_64BIT_VALUE);
62759+#else
62760+ portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);
62761+#endif
62762+
62763+#if defined(MV_CPU_BE)
62764+ /* big endian */
62765+# if defined(MV_ARM)
62766+ portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK |
62767+ ETH_TX_NO_DATA_SWAP_MASK |
62768+ ETH_DESC_SWAP_MASK);
62769+# elif defined(MV_PPC)
62770+ portSdmaCfgReg |= (ETH_RX_DATA_SWAP_MASK |
62771+ ETH_TX_DATA_SWAP_MASK |
62772+ ETH_NO_DESC_SWAP_MASK);
62773+# else
62774+# error "Giga Ethernet Swap policy is not defined for the CPU_ARCH"
62775+# endif /* MV_ARM / MV_PPC */
62776+
62777+#else /* MV_CPU_LE */
62778+ /* little endian */
62779+ portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK |
62780+ ETH_TX_NO_DATA_SWAP_MASK |
62781+ ETH_NO_DESC_SWAP_MASK);
62782+#endif /* MV_CPU_BE / MV_CPU_LE */
62783+
62784+ pPortCtrl->portRxQueueCmdReg = 0;
62785+ pPortCtrl->portTxQueueCmdReg = 0;
62786+
62787+#if (MV_ETH_VERSION >= 4)
62788+ if(pPortCtrl->portConfig.ejpMode == MV_TRUE)
62789+ {
62790+ MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), ETH_TX_EJP_ENABLE_MASK);
62791+ }
62792+ else
62793+ {
62794+ MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), 0)
62795+ }
62796+#endif /* (MV_ETH_VERSION >= 4) */
62797+
62798+ ethSetUcastTable(ethPortNo, -1);
62799+ mvEthSetSpecialMcastTable(ethPortNo, -1);
62800+ mvEthSetOtherMcastTable(ethPortNo, -1);
62801+
62802+ portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;
62803+
62804+ portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);
62805+
62806+ MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);
62807+
62808+ /* Update value of PortConfig register accordingly with all RxQueue types */
62809+ pPortCtrl->portConfig.rxArpQ = pPortCtrl->portConfig.rxDefQ;
62810+ pPortCtrl->portConfig.rxBpduQ = pPortCtrl->portConfig.rxDefQ;
62811+ pPortCtrl->portConfig.rxTcpQ = pPortCtrl->portConfig.rxDefQ;
62812+ pPortCtrl->portConfig.rxUdpQ = pPortCtrl->portConfig.rxDefQ;
62813+
62814+ portCfgReg &= ~ETH_DEF_RX_QUEUE_ALL_MASK;
62815+ portCfgReg |= ETH_DEF_RX_QUEUE_MASK(pPortCtrl->portConfig.rxDefQ);
62816+
62817+ portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;
62818+ portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ);
62819+
62820+ portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;
62821+ portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);
62822+
62823+ portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;
62824+ portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);
62825+
62826+ portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;
62827+ portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);
62828+
62829+ /* Assignment of Tx CTRP of given queue */
62830+ txPrio = 0;
62831+
62832+ for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
62833+ {
62834+ pQueueCtrl = &pPortCtrl->txQueue[queue];
62835+
62836+ if(pQueueCtrl->pFirstDescr != NULL)
62837+ {
62838+ ethResetTxDescRing(pPortCtrl, queue);
62839+
62840+ MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue),
62841+ 0x3fffffff);
62842+ MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue),
62843+ 0x03ffffff);
62844+ }
62845+ else
62846+ {
62847+ MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue), 0x0);
62848+ MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue), 0x0);
62849+ }
62850+ }
62851+
62852+ /* Assignment of Rx CRDP of given queue */
62853+ for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
62854+ {
62855+ ethResetRxDescRing(pPortCtrl, queue);
62856+ }
62857+
62858+ /* Allow receiving packes with odd number of preamble nibbles */
62859+ portSerialCtrl1Reg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo));
62860+ portSerialCtrl1Reg |= ETH_EN_MII_ODD_PRE_MASK;
62861+ MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo), portSerialCtrl1Reg);
62862+
62863+ /* Assign port configuration and command. */
62864+ MV_REG_WRITE(ETH_PORT_CONFIG_REG(ethPortNo), portCfgReg);
62865+
62866+ MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(ethPortNo), portCfgExtReg);
62867+
62868+ /* Assign port SDMA configuration */
62869+ MV_REG_WRITE(ETH_SDMA_CONFIG_REG(ethPortNo), portSdmaCfgReg);
62870+
62871+ /* Turn off the port/queue bandwidth limitation */
62872+ MV_REG_WRITE(ETH_MAX_TRANSMIT_UNIT_REG(ethPortNo), 0x0);
62873+
62874+ return MV_OK;
62875+}
62876+
62877+/*******************************************************************************
62878+* ethPortUp - Start the Ethernet port RX and TX activity.
62879+*
62880+* DESCRIPTION:
62881+* This routine start Rx and Tx activity:
62882+*
62883+* Note: Each Rx and Tx queue descriptor's list must be initialized prior
62884+* to calling this function (use etherInitTxDescRing for Tx queues and
62885+* etherInitRxDescRing for Rx queues).
62886+*
62887+* INPUT:
62888+* void* pEthPortHndl - Ethernet port handler
62889+*
62890+* RETURN: MV_STATUS
62891+* MV_OK - Success, Others - Failure.
62892+*
62893+* NOTE : used for port link up.
62894+*******************************************************************************/
62895+MV_STATUS mvEthPortUp(void* pEthPortHndl)
62896+{
62897+ int ethPortNo;
62898+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
62899+
62900+ ethPortNo = pPortCtrl->portNo;
62901+
62902+ if( (pPortCtrl->portState != MV_ACTIVE) &&
62903+ (pPortCtrl->portState != MV_PAUSED) )
62904+ {
62905+ mvOsPrintf("ethDrv port%d: Unexpected port state %d\n",
62906+ ethPortNo, pPortCtrl->portState);
62907+ return MV_BAD_STATE;
62908+ }
62909+
62910+ ethPortNo = pPortCtrl->portNo;
62911+
62912+ /* Enable port RX. */
62913+ MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNo), pPortCtrl->portRxQueueCmdReg);
62914+
62915+ /* Enable port TX. */
62916+ MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(ethPortNo)) = pPortCtrl->portTxQueueCmdReg;
62917+
62918+ pPortCtrl->portState = MV_ACTIVE;
62919+
62920+ return MV_OK;
62921+}
62922+
62923+/*******************************************************************************
62924+* ethPortDown - Stop the Ethernet port activity.
62925+*
62926+* DESCRIPTION:
62927+*
62928+* INPUT:
62929+* void* pEthPortHndl - Ethernet port handler
62930+*
62931+* RETURN: MV_STATUS
62932+* MV_OK - Success, Others - Failure.
62933+*
62934+* NOTE : used for port link down.
62935+*******************************************************************************/
62936+MV_STATUS mvEthPortDown(void* pEthPortHndl)
62937+{
62938+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
62939+ int ethPortNum = pPortCtrl->portNo;
62940+ unsigned int regData;
62941+ volatile int uDelay, mDelay;
62942+
62943+ /* Stop Rx port activity. Check port Rx activity. */
62944+ regData = (MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_RXQ_ENABLE_MASK;
62945+ if(regData != 0)
62946+ {
62947+ /* Issue stop command for active channels only */
62948+ MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNum), (regData << ETH_RXQ_DISABLE_OFFSET));
62949+ }
62950+
62951+ /* Stop Tx port activity. Check port Tx activity. */
62952+ regData = (MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_TXQ_ENABLE_MASK;
62953+ if(regData != 0)
62954+ {
62955+ /* Issue stop command for active channels only */
62956+ MV_REG_WRITE(ETH_TX_QUEUE_COMMAND_REG(ethPortNum),
62957+ (regData << ETH_TXQ_DISABLE_OFFSET) );
62958+ }
62959+
62960+ /* Force link down */
62961+/*
62962+ regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
62963+ regData &= ~(ETH_DO_NOT_FORCE_LINK_FAIL_MASK);
62964+ MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
62965+*/
62966+ /* Wait for all Rx activity to terminate. */
62967+ mDelay = 0;
62968+ do
62969+ {
62970+ if(mDelay >= RX_DISABLE_TIMEOUT_MSEC)
62971+ {
62972+ mvOsPrintf("ethPort_%d: TIMEOUT for RX stopped !!! rxQueueCmd - 0x08%x\n",
62973+ ethPortNum, regData);
62974+ break;
62975+ }
62976+ mvOsDelay(1);
62977+ mDelay++;
62978+
62979+ /* Check port RX Command register that all Rx queues are stopped */
62980+ regData = MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum));
62981+ }
62982+ while(regData & 0xFF);
62983+
62984+ /* Wait for all Tx activity to terminate. */
62985+ mDelay = 0;
62986+ do
62987+ {
62988+ if(mDelay >= TX_DISABLE_TIMEOUT_MSEC)
62989+ {
62990+ mvOsPrintf("ethPort_%d: TIMEOUT for TX stoped !!! txQueueCmd - 0x08%x\n",
62991+ ethPortNum, regData);
62992+ break;
62993+ }
62994+ mvOsDelay(1);
62995+ mDelay++;
62996+
62997+ /* Check port TX Command register that all Tx queues are stopped */
62998+ regData = MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum));
62999+ }
63000+ while(regData & 0xFF);
63001+
63002+ /* Double check to Verify that TX FIFO is Empty */
63003+ mDelay = 0;
63004+ while(MV_TRUE)
63005+ {
63006+ do
63007+ {
63008+ if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)
63009+ {
63010+ mvOsPrintf("\n ethPort_%d: TIMEOUT for TX FIFO empty !!! portStatus - 0x08%x\n",
63011+ ethPortNum, regData);
63012+ break;
63013+ }
63014+ mvOsDelay(1);
63015+ mDelay++;
63016+
63017+ regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));
63018+ }
63019+ while( ((regData & ETH_TX_FIFO_EMPTY_MASK) == 0) ||
63020+ ((regData & ETH_TX_IN_PROGRESS_MASK) != 0) );
63021+
63022+ if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)
63023+ break;
63024+
63025+ /* Double check */
63026+ regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));
63027+ if( ((regData & ETH_TX_FIFO_EMPTY_MASK) != 0) &&
63028+ ((regData & ETH_TX_IN_PROGRESS_MASK) == 0) )
63029+ {
63030+ break;
63031+ }
63032+ else
63033+ mvOsPrintf("ethPort_%d: TX FIFO Empty double check failed. %d msec, portStatus=0x%x\n",
63034+ ethPortNum, mDelay, regData);
63035+ }
63036+
63037+ /* Do NOT force link down */
63038+/*
63039+ regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
63040+ regData |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK);
63041+ MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
63042+*/
63043+ /* Wait about 2500 tclk cycles */
63044+ uDelay = (PORT_DISABLE_WAIT_TCLOCKS/(mvBoardTclkGet()/1000000));
63045+ mvOsUDelay(uDelay);
63046+
63047+ pPortCtrl->portState = MV_PAUSED;
63048+
63049+ return MV_OK;
63050+}
63051+
63052+
63053+/*******************************************************************************
63054+* ethPortEnable - Enable the Ethernet port and Start RX and TX.
63055+*
63056+* DESCRIPTION:
63057+* This routine enable the Ethernet port and Rx and Tx activity:
63058+*
63059+* Note: Each Rx and Tx queue descriptor's list must be initialized prior
63060+* to calling this function (use etherInitTxDescRing for Tx queues and
63061+* etherInitRxDescRing for Rx queues).
63062+*
63063+* INPUT:
63064+* void* pEthPortHndl - Ethernet port handler
63065+*
63066+* RETURN: MV_STATUS
63067+* MV_OK - Success, Others - Failure.
63068+*
63069+* NOTE: main usage is to enable the port after ifconfig up.
63070+*******************************************************************************/
63071+MV_STATUS mvEthPortEnable(void* pEthPortHndl)
63072+{
63073+ int ethPortNo;
63074+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
63075+ MV_U32 portSerialCtrlReg;
63076+
63077+ ethPortNo = pPortCtrl->portNo;
63078+
63079+ /* Enable port */
63080+ portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNo));
63081+ portSerialCtrlReg |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK | ETH_PORT_ENABLE_MASK);
63082+
63083+ MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);
63084+
63085+ mvEthMibCountersClear(pEthPortHndl);
63086+
63087+ pPortCtrl->portState = MV_PAUSED;
63088+
63089+ /* If Link is UP, Start RX and TX traffic */
63090+ if( MV_REG_READ( ETH_PORT_STATUS_REG(ethPortNo) ) & ETH_LINK_UP_MASK)
63091+ return( mvEthPortUp(pEthPortHndl) );
63092+
63093+ return MV_NOT_READY;
63094+}
63095+
63096+
63097+/*******************************************************************************
63098+* mvEthPortDisable - Stop RX and TX activities and Disable the Ethernet port.
63099+*
63100+* DESCRIPTION:
63101+*
63102+* INPUT:
63103+* void* pEthPortHndl - Ethernet port handler
63104+*
63105+* RETURN: MV_STATUS
63106+* MV_OK - Success, Others - Failure.
63107+*
63108+* NOTE: main usage is to disable the port after ifconfig down.
63109+*******************************************************************************/
63110+MV_STATUS mvEthPortDisable(void* pEthPortHndl)
63111+{
63112+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
63113+ int ethPortNum = pPortCtrl->portNo;
63114+ unsigned int regData;
63115+ volatile int mvDelay;
63116+
63117+ if(pPortCtrl->portState == MV_ACTIVE)
63118+ {
63119+ /* Stop RX and TX activities */
63120+ mvEthPortDown(pEthPortHndl);
63121+ }
63122+
63123+ /* Reset the Enable bit in the Serial Control Register */
63124+ regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
63125+ regData &= ~(ETH_PORT_ENABLE_MASK);
63126+ MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
63127+
63128+ /* Wait about 2500 tclk cycles */
63129+ mvDelay = (PORT_DISABLE_WAIT_TCLOCKS*(mvCpuPclkGet()/mvBoardTclkGet()));
63130+ for(mvDelay; mvDelay>0; mvDelay--);
63131+
63132+ pPortCtrl->portState = MV_IDLE;
63133+ return MV_OK;
63134+}
63135+
63136+/*******************************************************************************
63137+* mvEthPortForceTxDone - Get next buffer from TX queue in spite of buffer ownership.
63138+*
63139+* DESCRIPTION:
63140+* This routine used to free buffers attached to the Tx ring and should
63141+* be called only when Giga Ethernet port is Down
63142+*
63143+* INPUT:
63144+* void* pEthPortHndl - Ethernet Port handler.
63145+* int txQueue - Number of TX queue.
63146+*
63147+* OUTPUT:
63148+* MV_PKT_INFO *pPktInfo - Pointer to packet was sent.
63149+*
63150+* RETURN:
63151+* MV_EMPTY - There is no more buffers in this queue.
63152+* MV_OK - Buffer detached from the queue and pPktInfo structure
63153+* filled with relevant information.
63154+*
63155+*******************************************************************************/
63156+MV_PKT_INFO* mvEthPortForceTxDone(void* pEthPortHndl, int txQueue)
63157+{
63158+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
63159+ ETH_QUEUE_CTRL* pQueueCtrl;
63160+ MV_PKT_INFO* pPktInfo;
63161+ ETH_TX_DESC* pTxDesc;
63162+ int port = pPortCtrl->portNo;
63163+
63164+ pQueueCtrl = &pPortCtrl->txQueue[txQueue];
63165+
63166+ while( (pQueueCtrl->pUsedDescr != pQueueCtrl->pCurrentDescr) ||
63167+ (pQueueCtrl->resource == 0) )
63168+ {
63169+ /* Free next descriptor */
63170+ pQueueCtrl->resource++;
63171+ pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pUsedDescr;
63172+
63173+ /* pPktInfo is available only in descriptors which are last descriptors */
63174+ pPktInfo = (MV_PKT_INFO*)pTxDesc->returnInfo;
63175+ if (pPktInfo)
63176+ pPktInfo->status = pTxDesc->cmdSts;
63177+
63178+ pTxDesc->cmdSts = 0x0;
63179+ pTxDesc->returnInfo = 0x0;
63180+ ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);
63181+
63182+ pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);
63183+
63184+ if (pPktInfo)
63185+ if (pPktInfo->status & ETH_TX_LAST_DESC_MASK)
63186+ return pPktInfo;
63187+ }
63188+ MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(port, txQueue),
63189+ (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
63190+ return NULL;
63191+}
63192+
63193+
63194+
63195+/*******************************************************************************
63196+* mvEthPortForceRx - Get next buffer from RX queue in spite of buffer ownership.
63197+*
63198+* DESCRIPTION:
63199+* This routine used to free buffers attached to the Rx ring and should
63200+* be called only when Giga Ethernet port is Down
63201+*
63202+* INPUT:
63203+* void* pEthPortHndl - Ethernet Port handler.
63204+* int rxQueue - Number of Rx queue.
63205+*
63206+* OUTPUT:
63207+* MV_PKT_INFO *pPktInfo - Pointer to received packet.
63208+*
63209+* RETURN:
63210+* MV_EMPTY - There is no more buffers in this queue.
63211+* MV_OK - Buffer detached from the queue and pBufInfo structure
63212+* filled with relevant information.
63213+*
63214+*******************************************************************************/
63215+MV_PKT_INFO* mvEthPortForceRx(void* pEthPortHndl, int rxQueue)
63216+{
63217+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
63218+ ETH_QUEUE_CTRL* pQueueCtrl;
63219+ ETH_RX_DESC* pRxDesc;
63220+ MV_PKT_INFO* pPktInfo;
63221+ int port = pPortCtrl->portNo;
63222+
63223+ pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
63224+
63225+ if(pQueueCtrl->resource == 0)
63226+ {
63227+ MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue),
63228+ (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
63229+
63230+ return NULL;
63231+ }
63232+ /* Free next descriptor */
63233+ pQueueCtrl->resource--;
63234+ pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pCurrentDescr;
63235+ pPktInfo = (MV_PKT_INFO*)pRxDesc->returnInfo;
63236+
63237+ pPktInfo->status = pRxDesc->cmdSts;
63238+ pRxDesc->cmdSts = 0x0;
63239+ pRxDesc->returnInfo = 0x0;
63240+ ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);
63241+
63242+ pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);
63243+ return pPktInfo;
63244+}
63245+
63246+
63247+/******************************************************************************/
63248+/* Port Configuration functions */
63249+/******************************************************************************/
63250+/*******************************************************************************
63251+* mvEthMruGet - Get MRU configuration for Max Rx packet size.
63252+*
63253+* INPUT:
63254+* MV_U32 maxRxPktSize - max packet size.
63255+*
63256+* RETURN: MV_U32 - MRU configuration.
63257+*
63258+*******************************************************************************/
63259+static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize)
63260+{
63261+ MV_U32 portSerialCtrlReg = 0;
63262+
63263+ if(maxRxPktSize > 9192)
63264+ portSerialCtrlReg |= ETH_MAX_RX_PACKET_9700BYTE;
63265+ else if(maxRxPktSize > 9022)
63266+ portSerialCtrlReg |= ETH_MAX_RX_PACKET_9192BYTE;
63267+ else if(maxRxPktSize > 1552)
63268+ portSerialCtrlReg |= ETH_MAX_RX_PACKET_9022BYTE;
63269+ else if(maxRxPktSize > 1522)
63270+ portSerialCtrlReg |= ETH_MAX_RX_PACKET_1552BYTE;
63271+ else if(maxRxPktSize > 1518)
63272+ portSerialCtrlReg |= ETH_MAX_RX_PACKET_1522BYTE;
63273+ else
63274+ portSerialCtrlReg |= ETH_MAX_RX_PACKET_1518BYTE;
63275+
63276+ return portSerialCtrlReg;
63277+}
63278+
63279+/*******************************************************************************
63280+* mvEthRxCoalSet - Sets coalescing interrupt mechanism on RX path
63281+*
63282+* DESCRIPTION:
63283+* This routine sets the RX coalescing interrupt mechanism parameter.
63284+* This parameter is a timeout counter, that counts in 64 tClk
63285+* chunks, that when timeout event occurs a maskable interrupt occurs.
63286+* The parameter is calculated using the tCLK frequency of the
63287+* MV-64xxx chip, and the required number is in micro seconds.
63288+*
63289+* INPUT:
63290+* void* pPortHndl - Ethernet Port handler.
63291+* MV_U32 uSec - Number of micro seconds between
63292+* RX interrupts
63293+*
63294+* RETURN:
63295+* None.
63296+*
63297+* COMMENT:
63298+* 1 sec - TCLK_RATE clocks
63299+* 1 uSec - TCLK_RATE / 1,000,000 clocks
63300+*
63301+* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
63302+*
63303+* RETURN:
63304+* None.
63305+*
63306+*******************************************************************************/
63307+MV_U32 mvEthRxCoalSet (void* pPortHndl, MV_U32 uSec)
63308+{
63309+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
63310+ MV_U32 coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);
63311+ MV_U32 portSdmaCfgReg;
63312+
63313+ portSdmaCfgReg = MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));
63314+ portSdmaCfgReg &= ~ETH_RX_INTR_COAL_ALL_MASK;
63315+
63316+ portSdmaCfgReg |= ETH_RX_INTR_COAL_MASK(coal);
63317+
63318+#if (MV_ETH_VERSION >= 2)
63319+ /* Set additional bit if needed ETH_RX_INTR_COAL_MSB_BIT (25) */
63320+ if(ETH_RX_INTR_COAL_MASK(coal) > ETH_RX_INTR_COAL_ALL_MASK)
63321+ portSdmaCfgReg |= ETH_RX_INTR_COAL_MSB_MASK;
63322+#endif /* MV_ETH_VERSION >= 2 */
63323+
63324+ MV_REG_WRITE (ETH_SDMA_CONFIG_REG(pPortCtrl->portNo), portSdmaCfgReg);
63325+ return coal;
63326+}
63327+
63328+/*******************************************************************************
63329+* mvEthTxCoalSet - Sets coalescing interrupt mechanism on TX path
63330+*
63331+* DESCRIPTION:
63332+* This routine sets the TX coalescing interrupt mechanism parameter.
63333+* This parameter is a timeout counter, that counts in 64 tClk
63334+* chunks, that when timeout event occurs a maskable interrupt
63335+* occurs.
63336+* The parameter is calculated using the tCLK frequency of the
63337+* MV-64xxx chip, and the required number is in micro seconds.
63338+*
63339+* INPUT:
63340+* void* pPortHndl - Ethernet Port handler.
63341+* MV_U32 uSec - Number of micro seconds between
63342+* RX interrupts
63343+*
63344+* RETURN:
63345+* None.
63346+*
63347+* COMMENT:
63348+* 1 sec - TCLK_RATE clocks
63349+* 1 uSec - TCLK_RATE / 1,000,000 clocks
63350+*
63351+* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
63352+*
63353+*******************************************************************************/
63354+MV_U32 mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec)
63355+{
63356+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
63357+ MV_U32 coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);
63358+ MV_U32 regVal;
63359+
63360+ regVal = MV_REG_READ(ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));
63361+ regVal &= ~ETH_TX_INTR_COAL_ALL_MASK;
63362+ regVal |= ETH_TX_INTR_COAL_MASK(coal);
63363+
63364+ /* Set TX Coalescing mechanism */
63365+ MV_REG_WRITE (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo), regVal);
63366+ return coal;
63367+}
63368+
63369+/*******************************************************************************
63370+* mvEthCoalGet - Gets RX and TX coalescing values in micro seconds
63371+*
63372+* DESCRIPTION:
63373+* This routine gets the RX and TX coalescing interrupt values.
63374+* The parameter is calculated using the tCLK frequency of the
63375+* MV-64xxx chip, and the returned numbers are in micro seconds.
63376+*
63377+* INPUTs:
63378+* void* pPortHndl - Ethernet Port handler.
63379+*
63380+* OUTPUTs:
63381+* MV_U32* pRxCoal - Number of micro seconds between RX interrupts
63382+* MV_U32* pTxCoal - Number of micro seconds between TX interrupts
63383+*
63384+* RETURN:
63385+* MV_STATUS MV_OK - success
63386+* Others - failure.
63387+*
63388+* COMMENT:
63389+* 1 sec - TCLK_RATE clocks
63390+* 1 uSec - TCLK_RATE / 1,000,000 clocks
63391+*
63392+* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
63393+*
63394+*******************************************************************************/
63395+MV_STATUS mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal)
63396+{
63397+ MV_U32 regVal, coal, usec;
63398+
63399+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
63400+
63401+ /* get TX Coalescing */
63402+ regVal = MV_REG_READ (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));
63403+ coal = ((regVal & ETH_TX_INTR_COAL_ALL_MASK) >> ETH_TX_INTR_COAL_OFFSET);
63404+
63405+ usec = (coal * 64) / (mvBoardTclkGet() / 1000000);
63406+ if(pTxCoal != NULL)
63407+ *pTxCoal = usec;
63408+
63409+ /* Get RX Coalescing */
63410+ regVal = MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));
63411+ coal = ((regVal & ETH_RX_INTR_COAL_ALL_MASK) >> ETH_RX_INTR_COAL_OFFSET);
63412+
63413+#if (MV_ETH_VERSION >= 2)
63414+ if(regVal & ETH_RX_INTR_COAL_MSB_MASK)
63415+ {
63416+ /* Add MSB */
63417+ coal |= (ETH_RX_INTR_COAL_ALL_MASK + 1);
63418+ }
63419+#endif /* MV_ETH_VERSION >= 2 */
63420+
63421+ usec = (coal * 64) / (mvBoardTclkGet() / 1000000);
63422+ if(pRxCoal != NULL)
63423+ *pRxCoal = usec;
63424+
63425+ return MV_OK;
63426+}
63427+
63428+/*******************************************************************************
63429+* mvEthMaxRxSizeSet -
63430+*
63431+* DESCRIPTION:
63432+* Change maximum receive size of the port. This configuration will take place
63433+* after next call of ethPortSetDefaults() function.
63434+*
63435+* INPUT:
63436+*
63437+* RETURN:
63438+*******************************************************************************/
63439+MV_STATUS mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize)
63440+{
63441+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
63442+ MV_U32 portSerialCtrlReg;
63443+
63444+ if((maxRxSize < 1518) || (maxRxSize & ~ETH_RX_BUFFER_MASK))
63445+ return MV_BAD_PARAM;
63446+
63447+ pPortCtrl->portConfig.maxRxPktSize = maxRxSize;
63448+
63449+ portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo));
63450+ portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;
63451+ portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);
63452+ MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo), portSerialCtrlReg);
63453+
63454+ return MV_OK;
63455+}
63456+
63457+
63458+/******************************************************************************/
63459+/* MAC Filtering functions */
63460+/******************************************************************************/
63461+
63462+/*******************************************************************************
63463+* mvEthRxFilterModeSet - Configure Fitering mode of Ethernet port
63464+*
63465+* DESCRIPTION:
63466+* This routine used to free buffers attached to the Rx ring and should
63467+* be called only when Giga Ethernet port is Down
63468+*
63469+* INPUT:
63470+* void* pEthPortHndl - Ethernet Port handler.
63471+* MV_BOOL isPromisc - Promiscous mode
63472+* MV_TRUE - accept all Broadcast, Multicast
63473+* and Unicast packets
63474+* MV_FALSE - accept all Broadcast,
63475+* specially added Multicast and
63476+* single Unicast packets
63477+*
63478+* RETURN: MV_STATUS MV_OK - Success, Other - Failure
63479+*
63480+*******************************************************************************/
63481+MV_STATUS mvEthRxFilterModeSet(void* pEthPortHndl, MV_BOOL isPromisc)
63482+{
63483+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
63484+ int queue;
63485+ MV_U32 portCfgReg;
63486+
63487+ portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
63488+ /* Set / Clear UPM bit in port configuration register */
63489+ if(isPromisc)
63490+ {
63491+ /* Accept all multicast packets to RX default queue */
63492+ queue = pPortCtrl->portConfig.rxDefQ;
63493+ portCfgReg |= ETH_UNICAST_PROMISCUOUS_MODE_MASK;
63494+ memset(pPortCtrl->mcastCount, 1, sizeof(pPortCtrl->mcastCount));
63495+ MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo),0xFFFF);
63496+ MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo),0xFFFFFFFF);
63497+ }
63498+ else
63499+ {
63500+ /* Reject all Multicast addresses */
63501+ queue = -1;
63502+ portCfgReg &= ~ETH_UNICAST_PROMISCUOUS_MODE_MASK;
63503+ /* Clear all mcastCount */
63504+ memset(pPortCtrl->mcastCount, 0, sizeof(pPortCtrl->mcastCount));
63505+ }
63506+ MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
63507+
63508+ /* Set Special Multicast and Other Multicast tables */
63509+ mvEthSetSpecialMcastTable(pPortCtrl->portNo, queue);
63510+ mvEthSetOtherMcastTable(pPortCtrl->portNo, queue);
63511+ ethSetUcastTable(pPortCtrl->portNo, queue);
63512+
63513+ return MV_OK;
63514+}
63515+
63516+/*******************************************************************************
63517+* mvEthMacAddrSet - This function Set the port Unicast address.
63518+*
63519+* DESCRIPTION:
63520+* This function Set the port Ethernet MAC address. This address
63521+* will be used to send Pause frames if enabled. Packets with this
63522+* address will be accepted and dispatched to default RX queue
63523+*
63524+* INPUT:
63525+* void* pEthPortHndl - Ethernet port handler.
63526+* char* pAddr - Address to be set
63527+*
63528+* RETURN: MV_STATUS
63529+* MV_OK - Success, Other - Faulure
63530+*
63531+*******************************************************************************/
63532+MV_STATUS mvEthMacAddrSet(void* pPortHndl, unsigned char *pAddr, int queue)
63533+{
63534+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
63535+ unsigned int macH;
63536+ unsigned int macL;
63537+
63538+ if(queue >= MV_ETH_RX_Q_NUM)
63539+ {
63540+ mvOsPrintf("ethDrv: RX queue #%d is out of range\n", queue);
63541+ return MV_BAD_PARAM;
63542+ }
63543+
63544+ if(queue != -1)
63545+ {
63546+ macL = (pAddr[4] << 8) | (pAddr[5]);
63547+ macH = (pAddr[0] << 24)| (pAddr[1] << 16) |
63548+ (pAddr[2] << 8) | (pAddr[3] << 0);
63549+
63550+ MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo), macL);
63551+ MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo), macH);
63552+ }
63553+
63554+ /* Accept frames of this address */
63555+ ethSetUcastAddr(pPortCtrl->portNo, pAddr[5], queue);
63556+
63557+ return MV_OK;
63558+}
63559+
63560+/*******************************************************************************
63561+* mvEthMacAddrGet - This function returns the port Unicast address.
63562+*
63563+* DESCRIPTION:
63564+* This function returns the port Ethernet MAC address.
63565+*
63566+* INPUT:
63567+* int portNo - Ethernet port number.
63568+* char* pAddr - Pointer where address will be written to
63569+*
63570+* RETURN: MV_STATUS
63571+* MV_OK - Success, Other - Faulure
63572+*
63573+*******************************************************************************/
63574+MV_STATUS mvEthMacAddrGet(int portNo, unsigned char *pAddr)
63575+{
63576+ unsigned int macH;
63577+ unsigned int macL;
63578+
63579+ if(pAddr == NULL)
63580+ {
63581+ mvOsPrintf("mvEthMacAddrGet: NULL pointer.\n");
63582+ return MV_BAD_PARAM;
63583+ }
63584+
63585+ macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(portNo));
63586+ macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(portNo));
63587+ pAddr[0] = (macH >> 24) & 0xff;
63588+ pAddr[1] = (macH >> 16) & 0xff;
63589+ pAddr[2] = (macH >> 8) & 0xff;
63590+ pAddr[3] = macH & 0xff;
63591+ pAddr[4] = (macL >> 8) & 0xff;
63592+ pAddr[5] = macL & 0xff;
63593+
63594+ return MV_OK;
63595+}
63596+
63597+/*******************************************************************************
63598+* mvEthMcastCrc8Get - Calculate CRC8 of MAC address.
63599+*
63600+* DESCRIPTION:
63601+*
63602+* INPUT:
63603+* MV_U8* pAddr - Address to calculate CRC-8
63604+*
63605+* RETURN: MV_U8 - CRC-8 of this MAC address
63606+*
63607+*******************************************************************************/
63608+MV_U8 mvEthMcastCrc8Get(MV_U8* pAddr)
63609+{
63610+ unsigned int macH;
63611+ unsigned int macL;
63612+ int macArray[48];
63613+ int crc[8];
63614+ int i;
63615+ unsigned char crcResult = 0;
63616+
63617+ /* Calculate CRC-8 out of the given address */
63618+ macH = (pAddr[0] << 8) | (pAddr[1]);
63619+ macL = (pAddr[2] << 24)| (pAddr[3] << 16) |
63620+ (pAddr[4] << 8) | (pAddr[5] << 0);
63621+
63622+ for(i=0; i<32; i++)
63623+ macArray[i] = (macL >> i) & 0x1;
63624+
63625+ for(i=32; i<48; i++)
63626+ macArray[i] = (macH >> (i - 32)) & 0x1;
63627+
63628+ crc[0] = macArray[45] ^ macArray[43] ^ macArray[40] ^ macArray[39] ^
63629+ macArray[35] ^ macArray[34] ^ macArray[31] ^ macArray[30] ^
63630+ macArray[28] ^ macArray[23] ^ macArray[21] ^ macArray[19] ^
63631+ macArray[18] ^ macArray[16] ^ macArray[14] ^ macArray[12] ^
63632+ macArray[8] ^ macArray[7] ^ macArray[6] ^ macArray[0];
63633+
63634+ crc[1] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^
63635+ macArray[41] ^ macArray[39] ^ macArray[36] ^ macArray[34] ^
63636+ macArray[32] ^ macArray[30] ^ macArray[29] ^ macArray[28] ^
63637+ macArray[24] ^ macArray[23] ^ macArray[22] ^ macArray[21] ^
63638+ macArray[20] ^ macArray[18] ^ macArray[17] ^ macArray[16] ^
63639+ macArray[15] ^ macArray[14] ^ macArray[13] ^ macArray[12] ^
63640+ macArray[9] ^ macArray[6] ^ macArray[1] ^ macArray[0];
63641+
63642+ crc[2] = macArray[47] ^ macArray[46] ^ macArray[44] ^ macArray[43] ^
63643+ macArray[42] ^ macArray[39] ^ macArray[37] ^ macArray[34] ^
63644+ macArray[33] ^ macArray[29] ^ macArray[28] ^ macArray[25] ^
63645+ macArray[24] ^ macArray[22] ^ macArray[17] ^ macArray[15] ^
63646+ macArray[13] ^ macArray[12] ^ macArray[10] ^ macArray[8] ^
63647+ macArray[6] ^ macArray[2] ^ macArray[1] ^ macArray[0];
63648+
63649+ crc[3] = macArray[47] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^
63650+ macArray[40] ^ macArray[38] ^ macArray[35] ^ macArray[34] ^
63651+ macArray[30] ^ macArray[29] ^ macArray[26] ^ macArray[25] ^
63652+ macArray[23] ^ macArray[18] ^ macArray[16] ^ macArray[14] ^
63653+ macArray[13] ^ macArray[11] ^ macArray[9] ^ macArray[7] ^
63654+ macArray[3] ^ macArray[2] ^ macArray[1];
63655+
63656+ crc[4] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[41] ^
63657+ macArray[39] ^ macArray[36] ^ macArray[35] ^ macArray[31] ^
63658+ macArray[30] ^ macArray[27] ^ macArray[26] ^ macArray[24] ^
63659+ macArray[19] ^ macArray[17] ^ macArray[15] ^ macArray[14] ^
63660+ macArray[12] ^ macArray[10] ^ macArray[8] ^ macArray[4] ^
63661+ macArray[3] ^ macArray[2];
63662+
63663+ crc[5] = macArray[47] ^ macArray[46] ^ macArray[45] ^ macArray[42] ^
63664+ macArray[40] ^ macArray[37] ^ macArray[36] ^ macArray[32] ^
63665+ macArray[31] ^ macArray[28] ^ macArray[27] ^ macArray[25] ^
63666+ macArray[20] ^ macArray[18] ^ macArray[16] ^ macArray[15] ^
63667+ macArray[13] ^ macArray[11] ^ macArray[9] ^ macArray[5] ^
63668+ macArray[4] ^ macArray[3];
63669+
63670+ crc[6] = macArray[47] ^ macArray[46] ^ macArray[43] ^ macArray[41] ^
63671+ macArray[38] ^ macArray[37] ^ macArray[33] ^ macArray[32] ^
63672+ macArray[29] ^ macArray[28] ^ macArray[26] ^ macArray[21] ^
63673+ macArray[19] ^ macArray[17] ^ macArray[16] ^ macArray[14] ^
63674+ macArray[12] ^ macArray[10] ^ macArray[6] ^ macArray[5] ^
63675+ macArray[4];
63676+
63677+ crc[7] = macArray[47] ^ macArray[44] ^ macArray[42] ^ macArray[39] ^
63678+ macArray[38] ^ macArray[34] ^ macArray[33] ^ macArray[30] ^
63679+ macArray[29] ^ macArray[27] ^ macArray[22] ^ macArray[20] ^
63680+ macArray[18] ^ macArray[17] ^ macArray[15] ^ macArray[13] ^
63681+ macArray[11] ^ macArray[7] ^ macArray[6] ^ macArray[5];
63682+
63683+ for(i=0; i<8; i++)
63684+ crcResult = crcResult | (crc[i] << i);
63685+
63686+ return crcResult;
63687+}
63688+/*******************************************************************************
63689+* mvEthMcastAddrSet - Multicast address settings.
63690+*
63691+* DESCRIPTION:
63692+* This API controls the MV device MAC multicast support.
63693+* The MV device supports multicast using two tables:
63694+* 1) Special Multicast Table for MAC addresses of the form
63695+* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
63696+* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
63697+* Table entries in the DA-Filter table.
63698+* In this case, the function calls ethPortSmcAddr() routine to set the
63699+* Special Multicast Table.
63700+* 2) Other Multicast Table for multicast of another type. A CRC-8bit
63701+* is used as an index to the Other Multicast Table entries in the
63702+* DA-Filter table.
63703+* In this case, the function calculates the CRC-8bit value and calls
63704+* ethPortOmcAddr() routine to set the Other Multicast Table.
63705+*
63706+* INPUT:
63707+* void* pEthPortHndl - Ethernet port handler.
63708+* MV_U8* pAddr - Address to be set
63709+* int queue - RX queue to capture all packets with this
63710+* Multicast MAC address.
63711+* -1 means delete this Multicast address.
63712+*
63713+* RETURN: MV_STATUS
63714+* MV_TRUE - Success, Other - Failure
63715+*
63716+*******************************************************************************/
63717+MV_STATUS mvEthMcastAddrSet(void* pPortHndl, MV_U8 *pAddr, int queue)
63718+{
63719+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
63720+ unsigned char crcResult = 0;
63721+
63722+ if(queue >= MV_ETH_RX_Q_NUM)
63723+ {
63724+ mvOsPrintf("ethPort %d: RX queue #%d is out of range\n",
63725+ pPortCtrl->portNo, queue);
63726+ return MV_BAD_PARAM;
63727+ }
63728+
63729+ if((pAddr[0] == 0x01) &&
63730+ (pAddr[1] == 0x00) &&
63731+ (pAddr[2] == 0x5E) &&
63732+ (pAddr[3] == 0x00) &&
63733+ (pAddr[4] == 0x00))
63734+ {
63735+ ethSetSpecialMcastAddr(pPortCtrl->portNo, pAddr[5], queue);
63736+ }
63737+ else
63738+ {
63739+ crcResult = mvEthMcastCrc8Get(pAddr);
63740+
63741+ /* Check Add counter for this CRC value */
63742+ if(queue == -1)
63743+ {
63744+ if(pPortCtrl->mcastCount[crcResult] == 0)
63745+ {
63746+ mvOsPrintf("ethPort #%d: No valid Mcast for crc8=0x%02x\n",
63747+ pPortCtrl->portNo, (unsigned)crcResult);
63748+ return MV_NO_SUCH;
63749+ }
63750+
63751+ pPortCtrl->mcastCount[crcResult]--;
63752+ if(pPortCtrl->mcastCount[crcResult] != 0)
63753+ {
63754+ mvOsPrintf("ethPort #%d: After delete there are %d valid Mcast for crc8=0x%02x\n",
63755+ pPortCtrl->portNo, pPortCtrl->mcastCount[crcResult],
63756+ (unsigned)crcResult);
63757+ return MV_NO_CHANGE;
63758+ }
63759+ }
63760+ else
63761+ {
63762+ pPortCtrl->mcastCount[crcResult]++;
63763+ if(pPortCtrl->mcastCount[crcResult] > 1)
63764+ {
63765+ mvOsPrintf("ethPort #%d: Valid Mcast for crc8=0x%02x already exists\n",
63766+ pPortCtrl->portNo, (unsigned)crcResult);
63767+ return MV_NO_CHANGE;
63768+ }
63769+ }
63770+ ethSetOtherMcastAddr(pPortCtrl->portNo, crcResult, queue);
63771+ }
63772+ return MV_OK;
63773+}
63774+
63775+/*******************************************************************************
63776+* ethSetUcastTable - Unicast address settings.
63777+*
63778+* DESCRIPTION:
63779+* Set all entries in the Unicast MAC Table queue==-1 means reject all
63780+* INPUT:
63781+*
63782+* RETURN:
63783+*
63784+*******************************************************************************/
63785+static void ethSetUcastTable(int portNo, int queue)
63786+{
63787+ int offset;
63788+ MV_U32 regValue;
63789+
63790+ if(queue == -1)
63791+ {
63792+ regValue = 0;
63793+ }
63794+ else
63795+ {
63796+ regValue = (((0x01 | (queue<<1)) << 0) |
63797+ ((0x01 | (queue<<1)) << 8) |
63798+ ((0x01 | (queue<<1)) << 16) |
63799+ ((0x01 | (queue<<1)) << 24));
63800+ }
63801+
63802+ for (offset=0; offset<=0xC; offset+=4)
63803+ MV_REG_WRITE((ETH_DA_FILTER_UCAST_BASE(portNo) + offset), regValue);
63804+}
63805+
63806+/*******************************************************************************
63807+* mvEthSetSpecialMcastTable - Special Multicast address settings.
63808+*
63809+* DESCRIPTION:
63810+* Set all entries to the Special Multicast MAC Table. queue==-1 means reject all
63811+* INPUT:
63812+*
63813+* RETURN:
63814+*
63815+*******************************************************************************/
63816+MV_VOID mvEthSetSpecialMcastTable(int portNo, int queue)
63817+{
63818+ int offset;
63819+ MV_U32 regValue;
63820+
63821+ if(queue == -1)
63822+ {
63823+ regValue = 0;
63824+ }
63825+ else
63826+ {
63827+ regValue = (((0x01 | (queue<<1)) << 0) |
63828+ ((0x01 | (queue<<1)) << 8) |
63829+ ((0x01 | (queue<<1)) << 16) |
63830+ ((0x01 | (queue<<1)) << 24));
63831+ }
63832+
63833+ for (offset=0; offset<=0xFC; offset+=4)
63834+ {
63835+ MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(portNo) +
63836+ offset), regValue);
63837+ }
63838+}
63839+
63840+/*******************************************************************************
63841+* mvEthSetOtherMcastTable - Other Multicast address settings.
63842+*
63843+* DESCRIPTION:
63844+* Set all entries to the Other Multicast MAC Table. queue==-1 means reject all
63845+* INPUT:
63846+*
63847+* RETURN:
63848+*
63849+*******************************************************************************/
63850+MV_VOID mvEthSetOtherMcastTable(int portNo, int queue)
63851+{
63852+ int offset;
63853+ MV_U32 regValue;
63854+
63855+ if(queue == -1)
63856+ {
63857+ regValue = 0;
63858+ }
63859+ else
63860+ {
63861+ regValue = (((0x01 | (queue<<1)) << 0) |
63862+ ((0x01 | (queue<<1)) << 8) |
63863+ ((0x01 | (queue<<1)) << 16) |
63864+ ((0x01 | (queue<<1)) << 24));
63865+ }
63866+
63867+ for (offset=0; offset<=0xFC; offset+=4)
63868+ {
63869+ MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(portNo) +
63870+ offset), regValue);
63871+ }
63872+}
63873+
63874+/*******************************************************************************
63875+* ethSetUcastAddr - This function Set the port unicast address table
63876+*
63877+* DESCRIPTION:
63878+* This function locates the proper entry in the Unicast table for the
63879+* specified MAC nibble and sets its properties according to function
63880+* parameters.
63881+*
63882+* INPUT:
63883+* int ethPortNum - Port number.
63884+* MV_U8 lastNibble - Unicast MAC Address last nibble.
63885+* int queue - Rx queue number for this MAC address.
63886+* value "-1" means remove address
63887+*
63888+* OUTPUT:
63889+* This function add/removes MAC addresses from the port unicast address
63890+* table.
63891+*
63892+* RETURN:
63893+* MV_TRUE is output succeeded.
63894+* MV_FALSE if option parameter is invalid.
63895+*
63896+*******************************************************************************/
63897+static MV_BOOL ethSetUcastAddr(int portNo, MV_U8 lastNibble, int queue)
63898+{
63899+ unsigned int unicastReg;
63900+ unsigned int tblOffset;
63901+ unsigned int regOffset;
63902+
63903+ /* Locate the Unicast table entry */
63904+ lastNibble = (0xf & lastNibble);
63905+ tblOffset = (lastNibble / 4) * 4; /* Register offset from unicast table base*/
63906+ regOffset = lastNibble % 4; /* Entry offset within the above register */
63907+
63908+
63909+ unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(portNo) +
63910+ tblOffset));
63911+
63912+
63913+ if(queue == -1)
63914+ {
63915+ /* Clear accepts frame bit at specified unicast DA table entry */
63916+ unicastReg &= ~(0xFF << (8*regOffset));
63917+ }
63918+ else
63919+ {
63920+ unicastReg &= ~(0xFF << (8*regOffset));
63921+ unicastReg |= ((0x01 | (queue<<1)) << (8*regOffset));
63922+ }
63923+ MV_REG_WRITE( (ETH_DA_FILTER_UCAST_BASE(portNo) + tblOffset),
63924+ unicastReg);
63925+
63926+ return MV_TRUE;
63927+}
63928+
63929+/*******************************************************************************
63930+* ethSetSpecialMcastAddr - Special Multicast address settings.
63931+*
63932+* DESCRIPTION:
63933+* This routine controls the MV device special MAC multicast support.
63934+* The Special Multicast Table for MAC addresses supports MAC of the form
63935+* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
63936+* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
63937+* Table entries in the DA-Filter table.
63938+* This function set the Special Multicast Table appropriate entry
63939+* according to the argument given.
63940+*
63941+* INPUT:
63942+* int ethPortNum Port number.
63943+* unsigned char mcByte Multicast addr last byte (MAC DA[7:0] bits).
63944+* int queue Rx queue number for this MAC address.
63945+* int option 0 = Add, 1 = remove address.
63946+*
63947+* OUTPUT:
63948+* See description.
63949+*
63950+* RETURN:
63951+* MV_TRUE is output succeeded.
63952+* MV_FALSE if option parameter is invalid.
63953+*
63954+*******************************************************************************/
63955+static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue)
63956+{
63957+ unsigned int smcTableReg;
63958+ unsigned int tblOffset;
63959+ unsigned int regOffset;
63960+
63961+ /* Locate the SMC table entry */
63962+ tblOffset = (lastByte / 4); /* Register offset from SMC table base */
63963+ regOffset = lastByte % 4; /* Entry offset within the above register */
63964+
63965+ smcTableReg = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) + tblOffset*4));
63966+
63967+ if(queue == -1)
63968+ {
63969+ /* Clear accepts frame bit at specified Special DA table entry */
63970+ smcTableReg &= ~(0xFF << (8 * regOffset));
63971+ }
63972+ else
63973+ {
63974+ smcTableReg &= ~(0xFF << (8 * regOffset));
63975+ smcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));
63976+ }
63977+ MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) +
63978+ tblOffset*4), smcTableReg);
63979+
63980+ return MV_TRUE;
63981+}
63982+
63983+/*******************************************************************************
63984+* ethSetOtherMcastAddr - Multicast address settings.
63985+*
63986+* DESCRIPTION:
63987+* This routine controls the MV device Other MAC multicast support.
63988+* The Other Multicast Table is used for multicast of another type.
63989+* A CRC-8bit is used as an index to the Other Multicast Table entries
63990+* in the DA-Filter table.
63991+* The function gets the CRC-8bit value from the calling routine and
63992+* set the Other Multicast Table appropriate entry according to the
63993+* CRC-8 argument given.
63994+*
63995+* INPUT:
63996+* int ethPortNum Port number.
63997+* MV_U8 crc8 A CRC-8bit (Polynomial: x^8+x^2+x^1+1).
63998+* int queue Rx queue number for this MAC address.
63999+*
64000+* OUTPUT:
64001+* See description.
64002+*
64003+* RETURN:
64004+* MV_TRUE is output succeeded.
64005+* MV_FALSE if option parameter is invalid.
64006+*
64007+*******************************************************************************/
64008+static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue)
64009+{
64010+ unsigned int omcTableReg;
64011+ unsigned int tblOffset;
64012+ unsigned int regOffset;
64013+
64014+ /* Locate the OMC table entry */
64015+ tblOffset = (crc8 / 4) * 4; /* Register offset from OMC table base */
64016+ regOffset = crc8 % 4; /* Entry offset within the above register */
64017+
64018+ omcTableReg = MV_REG_READ(
64019+ (ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset));
64020+
64021+ if(queue == -1)
64022+ {
64023+ /* Clear accepts frame bit at specified Other DA table entry */
64024+ omcTableReg &= ~(0xFF << (8 * regOffset));
64025+ }
64026+ else
64027+ {
64028+ omcTableReg &= ~(0xFF << (8 * regOffset));
64029+ omcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));
64030+ }
64031+
64032+ MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset),
64033+ omcTableReg);
64034+
64035+ return MV_TRUE;
64036+}
64037+
64038+
64039+/******************************************************************************/
64040+/* MIB Counters functions */
64041+/******************************************************************************/
64042+
64043+
64044+/*******************************************************************************
64045+* mvEthMibCounterRead - Read a MIB counter
64046+*
64047+* DESCRIPTION:
64048+* This function reads a MIB counter of a specific ethernet port.
64049+* NOTE - Read from ETH_MIB_GOOD_OCTETS_RECEIVED_LOW or
64050+* ETH_MIB_GOOD_OCTETS_SENT_LOW counters will return 64 bits value,
64051+* so pHigh32 pointer should not be NULL in this case.
64052+*
64053+* INPUT:
64054+* int ethPortNum - Ethernet Port number.
64055+* unsigned int mibOffset - MIB counter offset.
64056+*
64057+* OUTPUT:
64058+* MV_U32* pHigh32 - pointer to place where 32 most significant bits
64059+* of the counter will be stored.
64060+*
64061+* RETURN:
64062+* 32 low sgnificant bits of MIB counter value.
64063+*
64064+*******************************************************************************/
64065+MV_U32 mvEthMibCounterRead(void* pPortHandle, unsigned int mibOffset,
64066+ MV_U32* pHigh32)
64067+{
64068+ int portNo;
64069+ MV_U32 valLow32, valHigh32;
64070+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64071+
64072+ portNo = pPortCtrl->portNo;
64073+
64074+ valLow32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset);
64075+
64076+ /* Implement FEr ETH. Erroneous Value when Reading the Upper 32-bits */
64077+ /* of a 64-bit MIB Counter. */
64078+ if( (mibOffset == ETH_MIB_GOOD_OCTETS_RECEIVED_LOW) ||
64079+ (mibOffset == ETH_MIB_GOOD_OCTETS_SENT_LOW) )
64080+ {
64081+ valHigh32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset + 4);
64082+ if(pHigh32 != NULL)
64083+ *pHigh32 = valHigh32;
64084+ }
64085+ return valLow32;
64086+}
64087+
64088+/*******************************************************************************
64089+* mvEthMibCountersClear - Clear all MIB counters
64090+*
64091+* DESCRIPTION:
64092+* This function clears all MIB counters
64093+*
64094+* INPUT:
64095+* int ethPortNum - Ethernet Port number.
64096+*
64097+*
64098+* RETURN: void
64099+*
64100+*******************************************************************************/
64101+void mvEthMibCountersClear(void* pPortHandle)
64102+{
64103+ int i, portNo;
64104+ unsigned int dummy;
64105+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64106+
64107+ portNo = pPortCtrl->portNo;
64108+
64109+ /* Perform dummy reads from MIB counters */
64110+ for(i=ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i<ETH_MIB_LATE_COLLISION; i+=4)
64111+ dummy = MV_REG_READ((ETH_MIB_COUNTERS_BASE(portNo) + i));
64112+}
64113+
64114+
64115+/******************************************************************************/
64116+/* RX Dispatching configuration routines */
64117+/******************************************************************************/
64118+
64119+int mvEthTosToRxqGet(void* pPortHandle, int tos)
64120+{
64121+ MV_U32 regValue;
64122+ int regIdx, regOffs, rxq;
64123+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64124+
64125+ if(tos > 0xFF)
64126+ {
64127+ mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);
64128+ return -1;
64129+ }
64130+ regIdx = mvOsDivide(tos>>2, 10);
64131+ regOffs = mvOsReminder(tos>>2, 10);
64132+
64133+ regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );
64134+ rxq = (regValue >> (regOffs*3));
64135+ rxq &= 0x7;
64136+
64137+ return rxq;
64138+}
64139+
64140+/*******************************************************************************
64141+* mvEthTosToRxqSet - Map packets with special TOS value to special RX queue
64142+*
64143+* DESCRIPTION:
64144+*
64145+* INPUT:
64146+* void* pPortHandle - Pointer to port specific handler;
64147+* int tos - TOS value in the IP header of the packet
64148+* int rxq - RX Queue for packets with the configured TOS value
64149+* Negative value (-1) means no special processing for these packets,
64150+* so they will be processed as regular packets.
64151+*
64152+* RETURN: MV_STATUS
64153+*******************************************************************************/
64154+MV_STATUS mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq)
64155+{
64156+ MV_U32 regValue;
64157+ int regIdx, regOffs;
64158+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64159+
64160+ if( (rxq < 0) || (rxq >= MV_ETH_RX_Q_NUM) )
64161+ {
64162+ mvOsPrintf("eth_%d: RX queue #%d is out of range\n", pPortCtrl->portNo, rxq);
64163+ return MV_BAD_PARAM;
64164+ }
64165+ if(tos > 0xFF)
64166+ {
64167+ mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);
64168+ return MV_BAD_PARAM;
64169+ }
64170+ regIdx = mvOsDivide(tos>>2, 10);
64171+ regOffs = mvOsReminder(tos>>2, 10);
64172+
64173+ regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );
64174+ regValue &= ~(0x7 << (regOffs*3));
64175+ regValue |= (rxq << (regOffs*3));
64176+
64177+ MV_REG_WRITE(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx), regValue);
64178+ return MV_OK;
64179+}
64180+
64181+/*******************************************************************************
64182+* mvEthVlanPrioRxQueue - Configure RX queue to capture VLAN tagged packets with
64183+* special priority bits [0-2]
64184+*
64185+* DESCRIPTION:
64186+*
64187+* INPUT:
64188+* void* pPortHandle - Pointer to port specific handler;
64189+* int bpduQueue - Special queue to capture VLAN tagged packets with special
64190+* priority.
64191+* Negative value (-1) means no special processing for these packets,
64192+* so they will be processed as regular packets.
64193+*
64194+* RETURN: MV_STATUS
64195+* MV_OK - Success
64196+* MV_FAIL - Failed.
64197+*
64198+*******************************************************************************/
64199+MV_STATUS mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue)
64200+{
64201+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64202+ MV_U32 vlanPrioReg;
64203+
64204+ if(vlanPrioQueue >= MV_ETH_RX_Q_NUM)
64205+ {
64206+ mvOsPrintf("ethDrv: RX queue #%d is out of range\n", vlanPrioQueue);
64207+ return MV_BAD_PARAM;
64208+ }
64209+ if(vlanPrio >= 8)
64210+ {
64211+ mvOsPrintf("ethDrv: vlanPrio=%d is out of range\n", vlanPrio);
64212+ return MV_BAD_PARAM;
64213+ }
64214+
64215+ vlanPrioReg = MV_REG_READ(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo));
64216+ vlanPrioReg &= ~(0x7 << (vlanPrio*3));
64217+ vlanPrioReg |= (vlanPrioQueue << (vlanPrio*3));
64218+ MV_REG_WRITE(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo), vlanPrioReg);
64219+
64220+ return MV_OK;
64221+}
64222+
64223+
64224+/*******************************************************************************
64225+* mvEthBpduRxQueue - Configure RX queue to capture BPDU packets.
64226+*
64227+* DESCRIPTION:
64228+* This function defines processing of BPDU packets.
64229+* BPDU packets can be accepted and captured to one of RX queues
64230+* or can be processing as regular Multicast packets.
64231+*
64232+* INPUT:
64233+* void* pPortHandle - Pointer to port specific handler;
64234+* int bpduQueue - Special queue to capture BPDU packets (DA is equal to
64235+* 01-80-C2-00-00-00 through 01-80-C2-00-00-FF,
64236+* except for the Flow-Control Pause packets).
64237+* Negative value (-1) means no special processing for BPDU,
64238+* packets so they will be processed as regular Multicast packets.
64239+*
64240+* RETURN: MV_STATUS
64241+* MV_OK - Success
64242+* MV_FAIL - Failed.
64243+*
64244+*******************************************************************************/
64245+MV_STATUS mvEthBpduRxQueue(void* pPortHandle, int bpduQueue)
64246+{
64247+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64248+ MV_U32 portCfgReg;
64249+ MV_U32 portCfgExtReg;
64250+
64251+ if(bpduQueue >= MV_ETH_RX_Q_NUM)
64252+ {
64253+ mvOsPrintf("ethDrv: RX queue #%d is out of range\n", bpduQueue);
64254+ return MV_BAD_PARAM;
64255+ }
64256+
64257+ portCfgExtReg = MV_REG_READ(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo));
64258+
64259+ portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
64260+ if(bpduQueue >= 0)
64261+ {
64262+ pPortCtrl->portConfig.rxBpduQ = bpduQueue;
64263+
64264+ portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;
64265+ portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);
64266+
64267+ MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
64268+
64269+ portCfgExtReg |= ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK;
64270+ }
64271+ else
64272+ {
64273+ pPortCtrl->portConfig.rxBpduQ = -1;
64274+ /* no special processing for BPDU packets */
64275+ portCfgExtReg &= (~ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK);
64276+ }
64277+
64278+ MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo), portCfgExtReg);
64279+
64280+ return MV_OK;
64281+}
64282+
64283+
64284+/*******************************************************************************
64285+* mvEthArpRxQueue - Configure RX queue to capture ARP packets.
64286+*
64287+* DESCRIPTION:
64288+* This function defines processing of ARP (type=0x0806) packets.
64289+* ARP packets can be accepted and captured to one of RX queues
64290+* or can be processed as other Broadcast packets.
64291+*
64292+* INPUT:
64293+* void* pPortHandle - Pointer to port specific handler;
64294+* int arpQueue - Special queue to capture ARP packets (type=0x806).
64295+* Negative value (-1) means discard ARP packets
64296+*
64297+* RETURN: MV_STATUS
64298+* MV_OK - Success
64299+* MV_FAIL - Failed.
64300+*
64301+*******************************************************************************/
64302+MV_STATUS mvEthArpRxQueue(void* pPortHandle, int arpQueue)
64303+{
64304+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64305+ MV_U32 portCfgReg;
64306+
64307+ if(arpQueue >= MV_ETH_RX_Q_NUM)
64308+ {
64309+ mvOsPrintf("ethDrv: RX queue #%d is out of range\n", arpQueue);
64310+ return MV_BAD_PARAM;
64311+ }
64312+
64313+ portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
64314+
64315+ if(arpQueue >= 0)
64316+ {
64317+ pPortCtrl->portConfig.rxArpQ = arpQueue;
64318+ portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;
64319+ portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ);
64320+
64321+ portCfgReg &= (~ETH_REJECT_ARP_BCAST_MASK);
64322+ }
64323+ else
64324+ {
64325+ pPortCtrl->portConfig.rxArpQ = -1;
64326+ portCfgReg |= ETH_REJECT_ARP_BCAST_MASK;
64327+ }
64328+
64329+ MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
64330+
64331+ return MV_OK;
64332+}
64333+
64334+
64335+/*******************************************************************************
64336+* mvEthTcpRxQueue - Configure RX queue to capture TCP packets.
64337+*
64338+* DESCRIPTION:
64339+* This function defines processing of TCP packets.
64340+* TCP packets can be accepted and captured to one of RX queues
64341+* or can be processed as regular Unicast packets.
64342+*
64343+* INPUT:
64344+* void* pPortHandle - Pointer to port specific handler;
64345+* int tcpQueue - Special queue to capture TCP packets. Value "-1"
64346+* means no special processing for TCP packets,
64347+* so they will be processed as regular
64348+*
64349+* RETURN: MV_STATUS
64350+* MV_OK - Success
64351+* MV_FAIL - Failed.
64352+*
64353+*******************************************************************************/
64354+MV_STATUS mvEthTcpRxQueue(void* pPortHandle, int tcpQueue)
64355+{
64356+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64357+ MV_U32 portCfgReg;
64358+
64359+ if(tcpQueue >= MV_ETH_RX_Q_NUM)
64360+ {
64361+ mvOsPrintf("ethDrv: RX queue #%d is out of range\n", tcpQueue);
64362+ return MV_BAD_PARAM;
64363+ }
64364+ portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
64365+
64366+ if(tcpQueue >= 0)
64367+ {
64368+ pPortCtrl->portConfig.rxTcpQ = tcpQueue;
64369+ portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;
64370+ portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);
64371+
64372+ portCfgReg |= ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK;
64373+ }
64374+ else
64375+ {
64376+ pPortCtrl->portConfig.rxTcpQ = -1;
64377+ portCfgReg &= (~ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK);
64378+ }
64379+
64380+ MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
64381+
64382+ return MV_OK;
64383+}
64384+
64385+
64386+/*******************************************************************************
64387+* mvEthUdpRxQueue - Configure RX queue to capture UDP packets.
64388+*
64389+* DESCRIPTION:
64390+* This function defines processing of UDP packets.
64391+* TCP packets can be accepted and captured to one of RX queues
64392+* or can be processed as regular Unicast packets.
64393+*
64394+* INPUT:
64395+* void* pPortHandle - Pointer to port specific handler;
64396+* int udpQueue - Special queue to capture UDP packets. Value "-1"
64397+* means no special processing for UDP packets,
64398+* so they will be processed as regular
64399+*
64400+* RETURN: MV_STATUS
64401+* MV_OK - Success
64402+* MV_FAIL - Failed.
64403+*
64404+*******************************************************************************/
64405+MV_STATUS mvEthUdpRxQueue(void* pPortHandle, int udpQueue)
64406+{
64407+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64408+ MV_U32 portCfgReg;
64409+
64410+ if(udpQueue >= MV_ETH_RX_Q_NUM)
64411+ {
64412+ mvOsPrintf("ethDrv: RX queue #%d is out of range\n", udpQueue);
64413+ return MV_BAD_PARAM;
64414+ }
64415+
64416+ portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
64417+
64418+ if(udpQueue >= 0)
64419+ {
64420+ pPortCtrl->portConfig.rxUdpQ = udpQueue;
64421+ portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;
64422+ portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);
64423+
64424+ portCfgReg |= ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;
64425+ }
64426+ else
64427+ {
64428+ pPortCtrl->portConfig.rxUdpQ = -1;
64429+ portCfgReg &= ~ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;
64430+ }
64431+
64432+ MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
64433+
64434+ return MV_OK;
64435+}
64436+
64437+
64438+/******************************************************************************/
64439+/* Speed, Duplex, FlowControl routines */
64440+/******************************************************************************/
64441+
64442+/*******************************************************************************
64443+* mvEthSpeedDuplexSet - Set Speed and Duplex of the port.
64444+*
64445+* DESCRIPTION:
64446+* This function configure the port to work with desirable Duplex and Speed.
64447+* Changing of these parameters are allowed only when port is disabled.
64448+* This function disable the port if was enabled, change duplex and speed
64449+* and, enable the port back if needed.
64450+*
64451+* INPUT:
64452+* void* pPortHandle - Pointer to port specific handler;
64453+* ETH_PORT_SPEED speed - Speed of the port.
64454+* ETH_PORT_SPEED duplex - Duplex of the port.
64455+*
64456+* RETURN: MV_STATUS
64457+* MV_OK - Success
64458+* MV_OUT_OF_RANGE - Failed. Port is out of valid range
64459+* MV_NOT_FOUND - Failed. Port is not initialized.
64460+* MV_BAD_PARAM - Input parameters (speed/duplex) in conflict.
64461+* MV_BAD_VALUE - Value of one of input parameters (speed, duplex)
64462+* is not valid
64463+*
64464+*******************************************************************************/
64465+MV_STATUS mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed,
64466+ MV_ETH_PORT_DUPLEX duplex)
64467+{
64468+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64469+ int port = pPortCtrl->portNo;
64470+ MV_U32 portSerialCtrlReg;
64471+
64472+ if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet()) )
64473+ return MV_OUT_OF_RANGE;
64474+
64475+ pPortCtrl = ethPortCtrl[port];
64476+ if(pPortCtrl == NULL)
64477+ return MV_NOT_FOUND;
64478+
64479+ /* Check validity */
64480+ if( (speed == MV_ETH_SPEED_1000) && (duplex == MV_ETH_DUPLEX_HALF) )
64481+ return MV_BAD_PARAM;
64482+
64483+ portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
64484+ /* Set Speed */
64485+ switch(speed)
64486+ {
64487+ case MV_ETH_SPEED_AN:
64488+ portSerialCtrlReg &= ~ETH_DISABLE_SPEED_AUTO_NEG_MASK;
64489+ break;
64490+
64491+ case MV_ETH_SPEED_10:
64492+ portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
64493+ portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;
64494+ portSerialCtrlReg &= ~ETH_SET_MII_SPEED_100_MASK;
64495+ break;
64496+
64497+ case MV_ETH_SPEED_100:
64498+ portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
64499+ portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;
64500+ portSerialCtrlReg |= ETH_SET_MII_SPEED_100_MASK;
64501+ break;
64502+
64503+ case MV_ETH_SPEED_1000:
64504+ portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
64505+ portSerialCtrlReg |= ETH_SET_GMII_SPEED_1000_MASK;
64506+ break;
64507+
64508+ default:
64509+ mvOsPrintf("ethDrv: Unexpected Speed value %d\n", speed);
64510+ return MV_BAD_VALUE;
64511+ }
64512+ /* Set duplex */
64513+ switch(duplex)
64514+ {
64515+ case MV_ETH_DUPLEX_AN:
64516+ portSerialCtrlReg &= ~ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
64517+ break;
64518+
64519+ case MV_ETH_DUPLEX_HALF:
64520+ portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
64521+ portSerialCtrlReg &= ~ETH_SET_FULL_DUPLEX_MASK;
64522+ break;
64523+
64524+ case MV_ETH_DUPLEX_FULL:
64525+ portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
64526+ portSerialCtrlReg |= ETH_SET_FULL_DUPLEX_MASK;
64527+ break;
64528+
64529+ default:
64530+ mvOsPrintf("ethDrv: Unexpected Duplex value %d\n", duplex);
64531+ return MV_BAD_VALUE;
64532+ }
64533+ MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);
64534+
64535+ return MV_OK;
64536+}
64537+
64538+/*******************************************************************************
64539+* mvEthFlowCtrlSet - Set Flow Control of the port.
64540+*
64541+* DESCRIPTION:
64542+* This function configure the port to work with desirable Duplex and
64543+* Speed. Changing of these parameters are allowed only when port is
64544+* disabled. This function disable the port if was enabled, change
64545+* duplex and speed and, enable the port back if needed.
64546+*
64547+* INPUT:
64548+* void* pPortHandle - Pointer to port specific handler;
64549+* MV_ETH_PORT_FC flowControl - Flow control of the port.
64550+*
64551+* RETURN: MV_STATUS
64552+* MV_OK - Success
64553+* MV_OUT_OF_RANGE - Failed. Port is out of valid range
64554+* MV_NOT_FOUND - Failed. Port is not initialized.
64555+* MV_BAD_VALUE - Value flowControl parameters is not valid
64556+*
64557+*******************************************************************************/
64558+MV_STATUS mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl)
64559+{
64560+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64561+ int port = pPortCtrl->portNo;
64562+ MV_U32 portSerialCtrlReg;
64563+
64564+ if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet() ) )
64565+ return MV_OUT_OF_RANGE;
64566+
64567+ pPortCtrl = ethPortCtrl[port];
64568+ if(pPortCtrl == NULL)
64569+ return MV_NOT_FOUND;
64570+
64571+ portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
64572+ switch(flowControl)
64573+ {
64574+ case MV_ETH_FC_AN_ADV_DIS:
64575+ portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;
64576+ portSerialCtrlReg &= ~ETH_ADVERTISE_SYM_FC_MASK;
64577+ break;
64578+
64579+ case MV_ETH_FC_AN_ADV_SYM:
64580+ portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;
64581+ portSerialCtrlReg |= ETH_ADVERTISE_SYM_FC_MASK;
64582+ break;
64583+
64584+ case MV_ETH_FC_DISABLE:
64585+ portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;
64586+ portSerialCtrlReg &= ~ETH_SET_FLOW_CTRL_MASK;
64587+ break;
64588+
64589+ case MV_ETH_FC_ENABLE:
64590+ portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;
64591+ portSerialCtrlReg |= ETH_SET_FLOW_CTRL_MASK;
64592+ break;
64593+
64594+ default:
64595+ mvOsPrintf("ethDrv: Unexpected FlowControl value %d\n", flowControl);
64596+ return MV_BAD_VALUE;
64597+ }
64598+ MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);
64599+
64600+ return MV_OK;
64601+}
64602+
64603+/*******************************************************************************
64604+* mvEthHeaderModeSet - Set port header mode.
64605+*
64606+* DESCRIPTION:
64607+* This function configures the port to work in Marvell-Header mode.
64608+*
64609+* INPUT:
64610+* void* pPortHandle - Pointer to port specific handler;
64611+* MV_ETH_HEADER_MODE headerMode - The header mode to set the port in.
64612+*
64613+* RETURN: MV_STATUS
64614+* MV_OK - Success
64615+* MV_NOT_SUPPORTED- Feature not supported.
64616+* MV_OUT_OF_RANGE - Failed. Port is out of valid range
64617+* MV_NOT_FOUND - Failed. Port is not initialized.
64618+* MV_BAD_VALUE - Value of headerMode or numRxQueue parameter is not valid.
64619+*
64620+*******************************************************************************/
64621+MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode)
64622+{
64623+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64624+ int port = pPortCtrl->portNo;
64625+ MV_U32 mvHeaderReg;
64626+ MV_U32 numRxQ = MV_ETH_RX_Q_NUM;
64627+
64628+ if((port < 0) || (port >= mvCtrlEthMaxPortGet()))
64629+ return MV_OUT_OF_RANGE;
64630+
64631+ pPortCtrl = ethPortCtrl[port];
64632+ if(pPortCtrl == NULL)
64633+ return MV_NOT_FOUND;
64634+
64635+ mvHeaderReg = MV_REG_READ(ETH_PORT_MARVELL_HEADER_REG(port));
64636+ /* Disable header mode. */
64637+ mvHeaderReg &= ~ETH_MVHDR_EN_MASK;
64638+
64639+ if(headerMode != MV_ETH_DISABLE_HEADER_MODE)
64640+ {
64641+ /* Enable Header mode. */
64642+ mvHeaderReg |= ETH_MVHDR_EN_MASK;
64643+
64644+ /* Clear DA-Prefix & MHMask fields.*/
64645+ mvHeaderReg &= ~(ETH_MVHDR_DAPREFIX_MASK | ETH_MVHDR_MHMASK_MASK);
64646+
64647+ if(numRxQ > 1)
64648+ {
64649+ switch (headerMode)
64650+ {
64651+ case(MV_ETH_ENABLE_HEADER_MODE_PRI_2_1):
64652+ mvHeaderReg |= ETH_MVHDR_DAPREFIX_PRI_1_2;
64653+ break;
64654+ case(MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM):
64655+ mvHeaderReg |= ETH_MVHDR_DAPREFIX_DBNUM_PRI;
64656+ break;
64657+ case(MV_ETH_ENABLE_HEADER_MODE_PRI_SPID):
64658+ mvHeaderReg |= ETH_MVHDR_DAPREFIX_SPID_PRI;
64659+ break;
64660+ default:
64661+ break;
64662+ }
64663+
64664+ switch (numRxQ)
64665+ {
64666+ case (4):
64667+ mvHeaderReg |= ETH_MVHDR_MHMASK_4_QUEUE;
64668+ break;
64669+ case (8):
64670+ mvHeaderReg |= ETH_MVHDR_MHMASK_8_QUEUE;
64671+ break;
64672+ default:
64673+ break;
64674+ }
64675+ }
64676+ }
64677+
64678+ MV_REG_WRITE(ETH_PORT_MARVELL_HEADER_REG(port), mvHeaderReg);
64679+
64680+ return MV_OK;
64681+}
64682+
64683+#if (MV_ETH_VERSION >= 4)
64684+/*******************************************************************************
64685+* mvEthEjpModeSet - Enable / Disable EJP policy for TX.
64686+*
64687+* DESCRIPTION:
64688+* This function
64689+*
64690+* INPUT:
64691+* void* pPortHandle - Pointer to port specific handler;
64692+* MV_BOOL TRUE - enable EJP mode
64693+* FALSE - disable EJP mode
64694+*
64695+* OUTPUT: MV_STATUS
64696+* MV_OK - Success
64697+* Other - Failure
64698+*
64699+* RETURN: None.
64700+*
64701+*******************************************************************************/
64702+MV_STATUS mvEthEjpModeSet(void* pPortHandle, int mode)
64703+{
64704+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64705+ int port = pPortCtrl->portNo;
64706+
64707+ if((port < 0) || (port >= mvCtrlEthMaxPortGet()))
64708+ return MV_OUT_OF_RANGE;
64709+
64710+ pPortCtrl = ethPortCtrl[port];
64711+ if(pPortCtrl == NULL)
64712+ return MV_NOT_FOUND;
64713+
64714+ pPortCtrl->portConfig.ejpMode = mode;
64715+ if(mode)
64716+ {
64717+ /* EJP enabled */
64718+ MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), ETH_TX_EJP_ENABLE_MASK);
64719+ }
64720+ else
64721+ {
64722+ /* EJP disabled */
64723+ MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), 0);
64724+ }
64725+ mvOsPrintf("eth_%d: EJP %s - ETH_TXQ_CMD_1_REG: 0x%x = 0x%08x\n",
64726+ port, mode ? "Enabled" : "Disabled", ETH_TXQ_CMD_1_REG(port),
64727+ MV_REG_READ(ETH_TXQ_CMD_1_REG(port)));
64728+
64729+ return MV_OK;
64730+}
64731+#endif /* MV_ETH_VERSION >= 4 */
64732+
64733+/*******************************************************************************
64734+* mvEthStatusGet - Get major properties of the port .
64735+*
64736+* DESCRIPTION:
64737+* This function get major properties of the port (link, speed, duplex,
64738+* flowControl, etc) and return them using the single structure.
64739+*
64740+* INPUT:
64741+* void* pPortHandle - Pointer to port specific handler;
64742+*
64743+* OUTPUT:
64744+* MV_ETH_PORT_STATUS* pStatus - Pointer to structure, were port status
64745+* will be placed.
64746+*
64747+* RETURN: None.
64748+*
64749+*******************************************************************************/
64750+void mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus)
64751+{
64752+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64753+ int port = pPortCtrl->portNo;
64754+
64755+ MV_U32 regValue;
64756+
64757+ regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );
64758+
64759+ if(regValue & ETH_GMII_SPEED_1000_MASK)
64760+ pStatus->speed = MV_ETH_SPEED_1000;
64761+ else if(regValue & ETH_MII_SPEED_100_MASK)
64762+ pStatus->speed = MV_ETH_SPEED_100;
64763+ else
64764+ pStatus->speed = MV_ETH_SPEED_10;
64765+
64766+ if(regValue & ETH_LINK_UP_MASK)
64767+ pStatus->isLinkUp = MV_TRUE;
64768+ else
64769+ pStatus->isLinkUp = MV_FALSE;
64770+
64771+ if(regValue & ETH_FULL_DUPLEX_MASK)
64772+ pStatus->duplex = MV_ETH_DUPLEX_FULL;
64773+ else
64774+ pStatus->duplex = MV_ETH_DUPLEX_HALF;
64775+
64776+
64777+ if(regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK)
64778+ pStatus->flowControl = MV_ETH_FC_ENABLE;
64779+ else
64780+ pStatus->flowControl = MV_ETH_FC_DISABLE;
64781+}
64782+
64783+
64784+/******************************************************************************/
64785+/* PHY Control Functions */
64786+/******************************************************************************/
64787+
64788+
64789+/*******************************************************************************
64790+* mvEthPhyAddrSet - Set the ethernet port PHY address.
64791+*
64792+* DESCRIPTION:
64793+* This routine set the ethernet port PHY address according to given
64794+* parameter.
64795+*
64796+* INPUT:
64797+* void* pPortHandle - Pointer to port specific handler;
64798+* int phyAddr - PHY address
64799+*
64800+* RETURN:
64801+* None.
64802+*
64803+*******************************************************************************/
64804+void mvEthPhyAddrSet(void* pPortHandle, int phyAddr)
64805+{
64806+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64807+ int port = pPortCtrl->portNo;
64808+ unsigned int regData;
64809+
64810+ regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));
64811+
64812+ regData &= ~ETH_PHY_ADDR_MASK;
64813+ regData |= phyAddr;
64814+
64815+ MV_REG_WRITE(ETH_PHY_ADDR_REG(port), regData);
64816+
64817+ return;
64818+}
64819+
64820+/*******************************************************************************
64821+* mvEthPhyAddrGet - Get the ethernet port PHY address.
64822+*
64823+* DESCRIPTION:
64824+* This routine returns the given ethernet port PHY address.
64825+*
64826+* INPUT:
64827+* void* pPortHandle - Pointer to port specific handler;
64828+*
64829+*
64830+* RETURN: int - PHY address.
64831+*
64832+*******************************************************************************/
64833+int mvEthPhyAddrGet(void* pPortHandle)
64834+{
64835+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
64836+ int port = pPortCtrl->portNo;
64837+ unsigned int regData;
64838+
64839+ regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));
64840+
64841+ return ((regData >> (5 * port)) & 0x1f);
64842+}
64843+
64844+/******************************************************************************/
64845+/* Descriptor handling Functions */
64846+/******************************************************************************/
64847+
64848+/*******************************************************************************
64849+* etherInitRxDescRing - Curve a Rx chain desc list and buffer in memory.
64850+*
64851+* DESCRIPTION:
64852+* This function prepares a Rx chained list of descriptors and packet
64853+* buffers in a form of a ring. The routine must be called after port
64854+* initialization routine and before port start routine.
64855+* The Ethernet SDMA engine uses CPU bus addresses to access the various
64856+* devices in the system (i.e. DRAM). This function uses the ethernet
64857+* struct 'virtual to physical' routine (set by the user) to set the ring
64858+* with physical addresses.
64859+*
64860+* INPUT:
64861+* ETH_QUEUE_CTRL *pEthPortCtrl Ethernet Port Control srtuct.
64862+* int rxQueue Number of Rx queue.
64863+* int rxDescNum Number of Rx descriptors
64864+* MV_U8* rxDescBaseAddr Rx descriptors memory area base addr.
64865+*
64866+* OUTPUT:
64867+* The routine updates the Ethernet port control struct with information
64868+* regarding the Rx descriptors and buffers.
64869+*
64870+* RETURN: None
64871+*
64872+*******************************************************************************/
64873+static void ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)
64874+{
64875+ ETH_RX_DESC *pRxDescBase, *pRxDesc, *pRxPrevDesc;
64876+ int ix, rxDescNum = pPortCtrl->rxQueueConfig[queue].descrNum;
64877+ ETH_QUEUE_CTRL *pQueueCtrl = &pPortCtrl->rxQueue[queue];
64878+
64879+ /* Make sure descriptor address is cache line size aligned */
64880+ pRxDescBase = (ETH_RX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr,
64881+ CPU_D_CACHE_LINE_SIZE);
64882+
64883+ pRxDesc = (ETH_RX_DESC*)pRxDescBase;
64884+ pRxPrevDesc = pRxDesc;
64885+
64886+ /* initialize the Rx descriptors ring */
64887+ for (ix=0; ix<rxDescNum; ix++)
64888+ {
64889+ pRxDesc->bufSize = 0x0;
64890+ pRxDesc->byteCnt = 0x0;
64891+ pRxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
64892+ pRxDesc->bufPtr = 0x0;
64893+ pRxDesc->returnInfo = 0x0;
64894+ pRxPrevDesc = pRxDesc;
64895+ if(ix == (rxDescNum-1))
64896+ {
64897+ /* Closing Rx descriptors ring */
64898+ pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDescBase);
64899+ }
64900+ else
64901+ {
64902+ pRxDesc = (ETH_RX_DESC*)((MV_ULONG)pRxDesc + ETH_RX_DESC_ALIGNED_SIZE);
64903+ pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDesc);
64904+ }
64905+ ETH_DESCR_FLUSH_INV(pPortCtrl, pRxPrevDesc);
64906+ }
64907+
64908+ pQueueCtrl->pCurrentDescr = pRxDescBase;
64909+ pQueueCtrl->pUsedDescr = pRxDescBase;
64910+
64911+ pQueueCtrl->pFirstDescr = pRxDescBase;
64912+ pQueueCtrl->pLastDescr = pRxDesc;
64913+ pQueueCtrl->resource = 0;
64914+}
64915+
64916+void ethResetRxDescRing(void* pPortHndl, int queue)
64917+{
64918+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
64919+ ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[queue];
64920+ ETH_RX_DESC* pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;
64921+
64922+ pQueueCtrl->resource = 0;
64923+ if(pQueueCtrl->pFirstDescr != NULL)
64924+ {
64925+ while(MV_TRUE)
64926+ {
64927+ pRxDesc->bufSize = 0x0;
64928+ pRxDesc->byteCnt = 0x0;
64929+ pRxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
64930+ pRxDesc->bufPtr = 0x0;
64931+ pRxDesc->returnInfo = 0x0;
64932+ ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);
64933+ if( (void*)pRxDesc == pQueueCtrl->pLastDescr)
64934+ break;
64935+ pRxDesc = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);
64936+ }
64937+ pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;
64938+ pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;
64939+
64940+ /* Update RX Command register */
64941+ pPortCtrl->portRxQueueCmdReg |= (1 << queue);
64942+
64943+ /* update HW */
64944+ MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),
64945+ (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
64946+ }
64947+ else
64948+ {
64949+ /* Update RX Command register */
64950+ pPortCtrl->portRxQueueCmdReg &= ~(1 << queue);
64951+
64952+ /* update HW */
64953+ MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0);
64954+ }
64955+}
64956+
64957+/*******************************************************************************
64958+* etherInitTxDescRing - Curve a Tx chain desc list and buffer in memory.
64959+*
64960+* DESCRIPTION:
64961+* This function prepares a Tx chained list of descriptors and packet
64962+* buffers in a form of a ring. The routine must be called after port
64963+* initialization routine and before port start routine.
64964+* The Ethernet SDMA engine uses CPU bus addresses to access the various
64965+* devices in the system (i.e. DRAM). This function uses the ethernet
64966+* struct 'virtual to physical' routine (set by the user) to set the ring
64967+* with physical addresses.
64968+*
64969+* INPUT:
64970+* ETH_PORT_CTRL *pEthPortCtrl Ethernet Port Control srtuct.
64971+* int txQueue Number of Tx queue.
64972+* int txDescNum Number of Tx descriptors
64973+* int txBuffSize Size of Tx buffer
64974+* MV_U8* pTxDescBase Tx descriptors memory area base addr.
64975+*
64976+* OUTPUT:
64977+* The routine updates the Ethernet port control struct with information
64978+* regarding the Tx descriptors and buffers.
64979+*
64980+* RETURN: None.
64981+*
64982+*******************************************************************************/
64983+static void ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)
64984+{
64985+ ETH_TX_DESC *pTxDescBase, *pTxDesc, *pTxPrevDesc;
64986+ int ix, txDescNum = pPortCtrl->txQueueConfig[queue].descrNum;
64987+ ETH_QUEUE_CTRL *pQueueCtrl = &pPortCtrl->txQueue[queue];
64988+
64989+ /* Make sure descriptor address is cache line size aligned */
64990+ pTxDescBase = (ETH_TX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr,
64991+ CPU_D_CACHE_LINE_SIZE);
64992+
64993+ pTxDesc = (ETH_TX_DESC*)pTxDescBase;
64994+ pTxPrevDesc = pTxDesc;
64995+
64996+ /* initialize the Tx descriptors ring */
64997+ for (ix=0; ix<txDescNum; ix++)
64998+ {
64999+ pTxDesc->byteCnt = 0x0000;
65000+ pTxDesc->L4iChk = 0x0000;
65001+ pTxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
65002+ pTxDesc->bufPtr = 0x0;
65003+ pTxDesc->returnInfo = 0x0;
65004+
65005+ pTxPrevDesc = pTxDesc;
65006+
65007+ if(ix == (txDescNum-1))
65008+ {
65009+ /* Closing Tx descriptors ring */
65010+ pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDescBase);
65011+ }
65012+ else
65013+ {
65014+ pTxDesc = (ETH_TX_DESC*)((MV_ULONG)pTxDesc + ETH_TX_DESC_ALIGNED_SIZE);
65015+ pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDesc);
65016+ }
65017+ ETH_DESCR_FLUSH_INV(pPortCtrl, pTxPrevDesc);
65018+ }
65019+
65020+ pQueueCtrl->pCurrentDescr = pTxDescBase;
65021+ pQueueCtrl->pUsedDescr = pTxDescBase;
65022+
65023+ pQueueCtrl->pFirstDescr = pTxDescBase;
65024+ pQueueCtrl->pLastDescr = pTxDesc;
65025+ /* Leave one TX descriptor out of use */
65026+ pQueueCtrl->resource = txDescNum - 1;
65027+}
65028+
65029+void ethResetTxDescRing(void* pPortHndl, int queue)
65030+{
65031+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
65032+ ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[queue];
65033+ ETH_TX_DESC* pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;
65034+
65035+ pQueueCtrl->resource = 0;
65036+ if(pQueueCtrl->pFirstDescr != NULL)
65037+ {
65038+ while(MV_TRUE)
65039+ {
65040+ pTxDesc->byteCnt = 0x0000;
65041+ pTxDesc->L4iChk = 0x0000;
65042+ pTxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
65043+ pTxDesc->bufPtr = 0x0;
65044+ pTxDesc->returnInfo = 0x0;
65045+ ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);
65046+ pQueueCtrl->resource++;
65047+ if( (void*)pTxDesc == pQueueCtrl->pLastDescr)
65048+ break;
65049+ pTxDesc = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);
65050+ }
65051+ /* Leave one TX descriptor out of use */
65052+ pQueueCtrl->resource--;
65053+ pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;
65054+ pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;
65055+
65056+ /* Update TX Command register */
65057+ pPortCtrl->portTxQueueCmdReg |= MV_32BIT_LE_FAST(1 << queue);
65058+ /* update HW */
65059+ MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),
65060+ (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
65061+ }
65062+ else
65063+ {
65064+ /* Update TX Command register */
65065+ pPortCtrl->portTxQueueCmdReg &= MV_32BIT_LE_FAST(~(1 << queue));
65066+ /* update HW */
65067+ MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0 );
65068+ }
65069+}
65070+
65071+/*******************************************************************************
65072+* ethAllocDescrMemory - Free memory allocated for RX and TX descriptors.
65073+*
65074+* DESCRIPTION:
65075+* This function allocates memory for RX and TX descriptors.
65076+* - If ETH_DESCR_IN_SRAM defined, allocate memory from SRAM.
65077+* - If ETH_DESCR_IN_SDRAM defined, allocate memory in SDRAM.
65078+*
65079+* INPUT:
65080+* int size - size of memory should be allocated.
65081+*
65082+* RETURN: None
65083+*
65084+*******************************************************************************/
65085+static MV_U8* ethAllocDescrMemory(ETH_PORT_CTRL* pPortCtrl, int descSize,
65086+ MV_ULONG* pPhysAddr, MV_U32 *memHandle)
65087+{
65088+ MV_U8* pVirt;
65089+
65090+#if defined(ETH_DESCR_IN_SRAM)
65091+ if(ethDescInSram == MV_TRUE)
65092+ pVirt = (char*)mvSramMalloc(descSize, pPhysAddr);
65093+ else
65094+#endif /* ETH_DESCR_IN_SRAM */
65095+ {
65096+#ifdef ETH_DESCR_UNCACHED
65097+ pVirt = (MV_U8*)mvOsIoUncachedMalloc(pPortCtrl->osHandle, descSize,
65098+ pPhysAddr,memHandle);
65099+#else
65100+ pVirt = (MV_U8*)mvOsIoCachedMalloc(pPortCtrl->osHandle, descSize,
65101+ pPhysAddr, memHandle);
65102+#endif /* ETH_DESCR_UNCACHED */
65103+ }
65104+ memset(pVirt, 0, descSize);
65105+
65106+ return pVirt;
65107+}
65108+
65109+/*******************************************************************************
65110+* ethFreeDescrMemory - Free memory allocated for RX and TX descriptors.
65111+*
65112+* DESCRIPTION:
65113+* This function frees memory allocated for RX and TX descriptors.
65114+* - If ETH_DESCR_IN_SRAM defined, free memory using gtSramFree() function.
65115+* - If ETH_DESCR_IN_SDRAM defined, free memory using mvOsFree() function.
65116+*
65117+* INPUT:
65118+* void* pVirtAddr - virtual pointer to memory allocated for RX and TX
65119+* desriptors.
65120+*
65121+* RETURN: None
65122+*
65123+*******************************************************************************/
65124+void ethFreeDescrMemory(ETH_PORT_CTRL* pPortCtrl, MV_BUF_INFO* pDescBuf)
65125+{
65126+ if( (pDescBuf == NULL) || (pDescBuf->bufVirtPtr == NULL) )
65127+ return;
65128+
65129+#if defined(ETH_DESCR_IN_SRAM)
65130+ if( ethDescInSram )
65131+ {
65132+ mvSramFree(pDescBuf->bufSize, pDescBuf->bufPhysAddr, pDescBuf->bufVirtPtr);
65133+ return;
65134+ }
65135+#endif /* ETH_DESCR_IN_SRAM */
65136+
65137+#ifdef ETH_DESCR_UNCACHED
65138+ mvOsIoUncachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr,
65139+ pDescBuf->bufVirtPtr,pDescBuf->memHandle);
65140+#else
65141+ mvOsIoCachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr,
65142+ pDescBuf->bufVirtPtr,pDescBuf->memHandle);
65143+#endif /* ETH_DESCR_UNCACHED */
65144+}
65145+
65146+/******************************************************************************/
65147+/* Other Functions */
65148+/******************************************************************************/
65149+
65150+void mvEthPortPowerUp(int port)
65151+{
65152+ MV_U32 regVal;
65153+
65154+ /* MAC Cause register should be cleared */
65155+ MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);
65156+
65157+ if (mvBoardIsPortInSgmii(port))
65158+ mvEthPortSgmiiConfig(port);
65159+
65160+ /* Cancel Port Reset */
65161+ regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
65162+ regVal &= (~ETH_PORT_RESET_MASK);
65163+ MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);
65164+ while( (MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) != 0);
65165+}
65166+
65167+void mvEthPortPowerDown(int port)
65168+{
65169+ MV_U32 regVal;
65170+
65171+ /* Port must be DISABLED */
65172+ regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
65173+ if( (regVal & ETH_PORT_ENABLE_MASK) != 0)
65174+ {
65175+ mvOsPrintf("ethPort #%d: PowerDown - port must be Disabled (PSC=0x%x)\n",
65176+ port, regVal);
65177+ return;
65178+ }
65179+
65180+ /* Port Reset (Read after write the register as a precaution) */
65181+ regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
65182+ MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal | ETH_PORT_RESET_MASK);
65183+ while((MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) == 0);
65184+}
65185+
65186+static void mvEthPortSgmiiConfig(int port)
65187+{
65188+ MV_U32 regVal;
65189+
65190+ regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
65191+
65192+ regVal |= (ETH_SGMII_MODE_MASK /*| ETH_INBAND_AUTO_NEG_ENABLE_MASK */);
65193+ regVal &= (~ETH_INBAND_AUTO_NEG_BYPASS_MASK);
65194+
65195+ MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);
65196+}
65197+
65198+
65199+
65200+
65201+
65202+
65203+
65204+
65205+
65206diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c b/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c
65207new file mode 100644
65208index 0000000..62edcb5
65209--- /dev/null
65210+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c
65211@@ -0,0 +1,748 @@
65212+/*******************************************************************************
65213+Copyright (C) Marvell International Ltd. and its affiliates
65214+
65215+This software file (the "File") is owned and distributed by Marvell
65216+International Ltd. and/or its affiliates ("Marvell") under the following
65217+alternative licensing terms. Once you have made an election to distribute the
65218+File under one of the following license alternatives, please (i) delete this
65219+introductory statement regarding license alternatives, (ii) delete the two
65220+license alternatives that you have not elected to use and (iii) preserve the
65221+Marvell copyright notice above.
65222+
65223+********************************************************************************
65224+Marvell Commercial License Option
65225+
65226+If you received this File from Marvell and you have entered into a commercial
65227+license agreement (a "Commercial License") with Marvell, the File is licensed
65228+to you under the terms of the applicable Commercial License.
65229+
65230+********************************************************************************
65231+Marvell GPL License Option
65232+
65233+If you received this File from Marvell, you may opt to use, redistribute and/or
65234+modify this File in accordance with the terms and conditions of the General
65235+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
65236+available along with the File in the license.txt file or by writing to the Free
65237+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
65238+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
65239+
65240+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
65241+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
65242+DISCLAIMED. The GPL License provides additional details about this warranty
65243+disclaimer.
65244+********************************************************************************
65245+Marvell BSD License Option
65246+
65247+If you received this File from Marvell, you may opt to use, redistribute and/or
65248+modify this File under the following licensing terms.
65249+Redistribution and use in source and binary forms, with or without modification,
65250+are permitted provided that the following conditions are met:
65251+
65252+ * Redistributions of source code must retain the above copyright notice,
65253+ this list of conditions and the following disclaimer.
65254+
65255+ * Redistributions in binary form must reproduce the above copyright
65256+ notice, this list of conditions and the following disclaimer in the
65257+ documentation and/or other materials provided with the distribution.
65258+
65259+ * Neither the name of Marvell nor the names of its contributors may be
65260+ used to endorse or promote products derived from this software without
65261+ specific prior written permission.
65262+
65263+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
65264+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65265+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
65266+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
65267+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
65268+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
65269+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
65270+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
65271+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
65272+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65273+
65274+*******************************************************************************/
65275+
65276+/*******************************************************************************
65277+* mvEthDebug.c - Source file for user friendly debug functions
65278+*
65279+* DESCRIPTION:
65280+*
65281+* DEPENDENCIES:
65282+* None.
65283+*
65284+*******************************************************************************/
65285+
65286+#include "mvOs.h"
65287+#include "mvCommon.h"
65288+#include "mvTypes.h"
65289+#include "mv802_3.h"
65290+#include "mvDebug.h"
65291+#include "ctrlEnv/mvCtrlEnvLib.h"
65292+#include "eth-phy/mvEthPhy.h"
65293+#include "eth/mvEth.h"
65294+#include "eth/gbe/mvEthDebug.h"
65295+
65296+/* #define mvOsPrintf printf */
65297+
65298+void mvEthPortShow(void* pHndl);
65299+void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);
65300+
65301+/******************************************************************************/
65302+/* Debug functions */
65303+/******************************************************************************/
65304+void ethRxCoal(int port, int usec)
65305+{
65306+ void* pHndl;
65307+
65308+ pHndl = mvEthPortHndlGet(port);
65309+ if(pHndl != NULL)
65310+ {
65311+ mvEthRxCoalSet(pHndl, usec);
65312+ }
65313+}
65314+
65315+void ethTxCoal(int port, int usec)
65316+{
65317+ void* pHndl;
65318+
65319+ pHndl = mvEthPortHndlGet(port);
65320+ if(pHndl != NULL)
65321+ {
65322+ mvEthTxCoalSet(pHndl, usec);
65323+ }
65324+}
65325+
65326+#if (MV_ETH_VERSION >= 4)
65327+void ethEjpModeSet(int port, int mode)
65328+{
65329+ void* pHndl;
65330+
65331+ pHndl = mvEthPortHndlGet(port);
65332+ if(pHndl != NULL)
65333+ {
65334+ mvEthEjpModeSet(pHndl, mode);
65335+ }
65336+}
65337+#endif /* (MV_ETH_VERSION >= 4) */
65338+
65339+void ethBpduRxQ(int port, int bpduQueue)
65340+{
65341+ void* pHndl;
65342+
65343+ pHndl = mvEthPortHndlGet(port);
65344+ if(pHndl != NULL)
65345+ {
65346+ mvEthBpduRxQueue(pHndl, bpduQueue);
65347+ }
65348+}
65349+
65350+void ethArpRxQ(int port, int arpQueue)
65351+{
65352+ void* pHndl;
65353+
65354+ pHndl = mvEthPortHndlGet(port);
65355+ if(pHndl != NULL)
65356+ {
65357+ mvEthArpRxQueue(pHndl, arpQueue);
65358+ }
65359+}
65360+
65361+void ethTcpRxQ(int port, int tcpQueue)
65362+{
65363+ void* pHndl;
65364+
65365+ pHndl = mvEthPortHndlGet(port);
65366+ if(pHndl != NULL)
65367+ {
65368+ mvEthTcpRxQueue(pHndl, tcpQueue);
65369+ }
65370+}
65371+
65372+void ethUdpRxQ(int port, int udpQueue)
65373+{
65374+ void* pHndl;
65375+
65376+ pHndl = mvEthPortHndlGet(port);
65377+ if(pHndl != NULL)
65378+ {
65379+ mvEthUdpRxQueue(pHndl, udpQueue);
65380+ }
65381+}
65382+
65383+void ethTxPolicyRegs(int port)
65384+{
65385+ int queue;
65386+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)mvEthPortHndlGet(port);
65387+
65388+ if(pPortCtrl == NULL)
65389+ {
65390+ return;
65391+ }
65392+ mvOsPrintf("Port #%d TX Policy: EJP=%d, TXQs: ",
65393+ port, pPortCtrl->portConfig.ejpMode);
65394+ for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
65395+ {
65396+ if(pPortCtrl->txQueueConfig[queue].descrNum > 0)
65397+ mvOsPrintf("%d, ", queue);
65398+ }
65399+ mvOsPrintf("\n");
65400+
65401+ mvOsPrintf("\n\t TX policy Port #%d configuration registers\n", port);
65402+
65403+ mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
65404+ ETH_TX_QUEUE_COMMAND_REG(port),
65405+ MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );
65406+
65407+ mvOsPrintf("ETH_TX_FIXED_PRIO_CFG_REG : 0x%X = 0x%08x\n",
65408+ ETH_TX_FIXED_PRIO_CFG_REG(port),
65409+ MV_REG_READ( ETH_TX_FIXED_PRIO_CFG_REG(port) ) );
65410+
65411+ mvOsPrintf("ETH_TX_TOKEN_RATE_CFG_REG : 0x%X = 0x%08x\n",
65412+ ETH_TX_TOKEN_RATE_CFG_REG(port),
65413+ MV_REG_READ( ETH_TX_TOKEN_RATE_CFG_REG(port) ) );
65414+
65415+ mvOsPrintf("ETH_MAX_TRANSMIT_UNIT_REG : 0x%X = 0x%08x\n",
65416+ ETH_MAX_TRANSMIT_UNIT_REG(port),
65417+ MV_REG_READ( ETH_MAX_TRANSMIT_UNIT_REG(port) ) );
65418+
65419+ mvOsPrintf("ETH_TX_TOKEN_BUCKET_SIZE_REG : 0x%X = 0x%08x\n",
65420+ ETH_TX_TOKEN_BUCKET_SIZE_REG(port),
65421+ MV_REG_READ( ETH_TX_TOKEN_BUCKET_SIZE_REG(port) ) );
65422+
65423+ mvOsPrintf("ETH_TX_TOKEN_BUCKET_COUNT_REG : 0x%X = 0x%08x\n",
65424+ ETH_TX_TOKEN_BUCKET_COUNT_REG(port),
65425+ MV_REG_READ( ETH_TX_TOKEN_BUCKET_COUNT_REG(port) ) );
65426+
65427+ for(queue=0; queue<MV_ETH_MAX_TXQ; queue++)
65428+ {
65429+ mvOsPrintf("\n\t TX policy Port #%d, Queue #%d configuration registers\n", port, queue);
65430+
65431+ mvOsPrintf("ETH_TXQ_TOKEN_COUNT_REG : 0x%X = 0x%08x\n",
65432+ ETH_TXQ_TOKEN_COUNT_REG(port, queue),
65433+ MV_REG_READ( ETH_TXQ_TOKEN_COUNT_REG(port, queue) ) );
65434+
65435+ mvOsPrintf("ETH_TXQ_TOKEN_CFG_REG : 0x%X = 0x%08x\n",
65436+ ETH_TXQ_TOKEN_CFG_REG(port, queue),
65437+ MV_REG_READ( ETH_TXQ_TOKEN_CFG_REG(port, queue) ) );
65438+
65439+ mvOsPrintf("ETH_TXQ_ARBITER_CFG_REG : 0x%X = 0x%08x\n",
65440+ ETH_TXQ_ARBITER_CFG_REG(port, queue),
65441+ MV_REG_READ( ETH_TXQ_ARBITER_CFG_REG(port, queue) ) );
65442+ }
65443+ mvOsPrintf("\n");
65444+}
65445+
65446+/* Print important registers of Ethernet port */
65447+void ethPortRegs(int port)
65448+{
65449+ mvOsPrintf("\n\t ethGiga #%d port Registers:\n", port);
65450+
65451+ mvOsPrintf("ETH_PORT_STATUS_REG : 0x%X = 0x%08x\n",
65452+ ETH_PORT_STATUS_REG(port),
65453+ MV_REG_READ( ETH_PORT_STATUS_REG(port) ) );
65454+
65455+ mvOsPrintf("ETH_PORT_SERIAL_CTRL_REG : 0x%X = 0x%08x\n",
65456+ ETH_PORT_SERIAL_CTRL_REG(port),
65457+ MV_REG_READ( ETH_PORT_SERIAL_CTRL_REG(port) ) );
65458+
65459+ mvOsPrintf("ETH_PORT_CONFIG_REG : 0x%X = 0x%08x\n",
65460+ ETH_PORT_CONFIG_REG(port),
65461+ MV_REG_READ( ETH_PORT_CONFIG_REG(port) ) );
65462+
65463+ mvOsPrintf("ETH_PORT_CONFIG_EXTEND_REG : 0x%X = 0x%08x\n",
65464+ ETH_PORT_CONFIG_EXTEND_REG(port),
65465+ MV_REG_READ( ETH_PORT_CONFIG_EXTEND_REG(port) ) );
65466+
65467+ mvOsPrintf("ETH_SDMA_CONFIG_REG : 0x%X = 0x%08x\n",
65468+ ETH_SDMA_CONFIG_REG(port),
65469+ MV_REG_READ( ETH_SDMA_CONFIG_REG(port) ) );
65470+
65471+ mvOsPrintf("ETH_TX_FIFO_URGENT_THRESH_REG : 0x%X = 0x%08x\n",
65472+ ETH_TX_FIFO_URGENT_THRESH_REG(port),
65473+ MV_REG_READ( ETH_TX_FIFO_URGENT_THRESH_REG(port) ) );
65474+
65475+ mvOsPrintf("ETH_RX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
65476+ ETH_RX_QUEUE_COMMAND_REG(port),
65477+ MV_REG_READ( ETH_RX_QUEUE_COMMAND_REG(port) ) );
65478+
65479+ mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
65480+ ETH_TX_QUEUE_COMMAND_REG(port),
65481+ MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );
65482+
65483+ mvOsPrintf("ETH_INTR_CAUSE_REG : 0x%X = 0x%08x\n",
65484+ ETH_INTR_CAUSE_REG(port),
65485+ MV_REG_READ( ETH_INTR_CAUSE_REG(port) ) );
65486+
65487+ mvOsPrintf("ETH_INTR_EXTEND_CAUSE_REG : 0x%X = 0x%08x\n",
65488+ ETH_INTR_CAUSE_EXT_REG(port),
65489+ MV_REG_READ( ETH_INTR_CAUSE_EXT_REG(port) ) );
65490+
65491+ mvOsPrintf("ETH_INTR_MASK_REG : 0x%X = 0x%08x\n",
65492+ ETH_INTR_MASK_REG(port),
65493+ MV_REG_READ( ETH_INTR_MASK_REG(port) ) );
65494+
65495+ mvOsPrintf("ETH_INTR_EXTEND_MASK_REG : 0x%X = 0x%08x\n",
65496+ ETH_INTR_MASK_EXT_REG(port),
65497+ MV_REG_READ( ETH_INTR_MASK_EXT_REG(port) ) );
65498+
65499+ mvOsPrintf("ETH_RX_DESCR_STAT_CMD_REG : 0x%X = 0x%08x\n",
65500+ ETH_RX_DESCR_STAT_CMD_REG(port, 0),
65501+ MV_REG_READ( ETH_RX_DESCR_STAT_CMD_REG(port, 0) ) );
65502+
65503+ mvOsPrintf("ETH_RX_BYTE_COUNT_REG : 0x%X = 0x%08x\n",
65504+ ETH_RX_BYTE_COUNT_REG(port, 0),
65505+ MV_REG_READ( ETH_RX_BYTE_COUNT_REG(port, 0) ) );
65506+
65507+ mvOsPrintf("ETH_RX_BUF_PTR_REG : 0x%X = 0x%08x\n",
65508+ ETH_RX_BUF_PTR_REG(port, 0),
65509+ MV_REG_READ( ETH_RX_BUF_PTR_REG(port, 0) ) );
65510+
65511+ mvOsPrintf("ETH_RX_CUR_DESC_PTR_REG : 0x%X = 0x%08x\n",
65512+ ETH_RX_CUR_DESC_PTR_REG(port, 0),
65513+ MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, 0) ) );
65514+}
65515+
65516+
65517+/* Print Giga Ethernet UNIT registers */
65518+void ethRegs(int port)
65519+{
65520+ mvOsPrintf("ETH_PHY_ADDR_REG : 0x%X = 0x%08x\n",
65521+ ETH_PHY_ADDR_REG(port),
65522+ MV_REG_READ(ETH_PHY_ADDR_REG(port)) );
65523+
65524+ mvOsPrintf("ETH_UNIT_INTR_CAUSE_REG : 0x%X = 0x%08x\n",
65525+ ETH_UNIT_INTR_CAUSE_REG(port),
65526+ MV_REG_READ( ETH_UNIT_INTR_CAUSE_REG(port)) );
65527+
65528+ mvOsPrintf("ETH_UNIT_INTR_MASK_REG : 0x%X = 0x%08x\n",
65529+ ETH_UNIT_INTR_MASK_REG(port),
65530+ MV_REG_READ( ETH_UNIT_INTR_MASK_REG(port)) );
65531+
65532+ mvOsPrintf("ETH_UNIT_ERROR_ADDR_REG : 0x%X = 0x%08x\n",
65533+ ETH_UNIT_ERROR_ADDR_REG(port),
65534+ MV_REG_READ(ETH_UNIT_ERROR_ADDR_REG(port)) );
65535+
65536+ mvOsPrintf("ETH_UNIT_INT_ADDR_ERROR_REG : 0x%X = 0x%08x\n",
65537+ ETH_UNIT_INT_ADDR_ERROR_REG(port),
65538+ MV_REG_READ(ETH_UNIT_INT_ADDR_ERROR_REG(port)) );
65539+
65540+}
65541+
65542+/******************************************************************************/
65543+/* MIB Counters functions */
65544+/******************************************************************************/
65545+
65546+/*******************************************************************************
65547+* ethClearMibCounters - Clear all MIB counters
65548+*
65549+* DESCRIPTION:
65550+* This function clears all MIB counters of a specific ethernet port.
65551+* A read from the MIB counter will reset the counter.
65552+*
65553+* INPUT:
65554+* int port - Ethernet Port number.
65555+*
65556+* RETURN: None
65557+*
65558+*******************************************************************************/
65559+void ethClearCounters(int port)
65560+{
65561+ void* pHndl;
65562+
65563+ pHndl = mvEthPortHndlGet(port);
65564+ if(pHndl != NULL)
65565+ mvEthMibCountersClear(pHndl);
65566+
65567+ return;
65568+}
65569+
65570+
65571+/* Print counters of the Ethernet port */
65572+void ethPortCounters(int port)
65573+{
65574+ MV_U32 regValue, regValHigh;
65575+ void* pHndl;
65576+
65577+ pHndl = mvEthPortHndlGet(port);
65578+ if(pHndl == NULL)
65579+ return;
65580+
65581+ mvOsPrintf("\n\t Port #%d MIB Counters\n\n", port);
65582+
65583+ mvOsPrintf("GoodFramesReceived = %u\n",
65584+ mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_RECEIVED, NULL));
65585+ mvOsPrintf("BadFramesReceived = %u\n",
65586+ mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FRAMES_RECEIVED, NULL));
65587+ mvOsPrintf("BroadcastFramesReceived = %u\n",
65588+ mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_RECEIVED, NULL));
65589+ mvOsPrintf("MulticastFramesReceived = %u\n",
65590+ mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_RECEIVED, NULL));
65591+
65592+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW,
65593+ &regValHigh);
65594+ mvOsPrintf("GoodOctetsReceived = 0x%08x%08x\n",
65595+ regValHigh, regValue);
65596+
65597+ mvOsPrintf("\n");
65598+ mvOsPrintf("GoodFramesSent = %u\n",
65599+ mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_SENT, NULL));
65600+ mvOsPrintf("BroadcastFramesSent = %u\n",
65601+ mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_SENT, NULL));
65602+ mvOsPrintf("MulticastFramesSent = %u\n",
65603+ mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_SENT, NULL));
65604+
65605+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_SENT_LOW,
65606+ &regValHigh);
65607+ mvOsPrintf("GoodOctetsSent = 0x%08x%08x\n", regValHigh, regValue);
65608+
65609+
65610+ mvOsPrintf("\n\t FC Control Counters\n");
65611+
65612+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNREC_MAC_CONTROL_RECEIVED, NULL);
65613+ mvOsPrintf("UnrecogMacControlReceived = %u\n", regValue);
65614+
65615+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FC_RECEIVED, NULL);
65616+ mvOsPrintf("GoodFCFramesReceived = %u\n", regValue);
65617+
65618+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FC_RECEIVED, NULL);
65619+ mvOsPrintf("BadFCFramesReceived = %u\n", regValue);
65620+
65621+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FC_SENT, NULL);
65622+ mvOsPrintf("FCFramesSent = %u\n", regValue);
65623+
65624+
65625+ mvOsPrintf("\n\t RX Errors\n");
65626+
65627+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_OCTETS_RECEIVED, NULL);
65628+ mvOsPrintf("BadOctetsReceived = %u\n", regValue);
65629+
65630+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNDERSIZE_RECEIVED, NULL);
65631+ mvOsPrintf("UndersizeFramesReceived = %u\n", regValue);
65632+
65633+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FRAGMENTS_RECEIVED, NULL);
65634+ mvOsPrintf("FragmentsReceived = %u\n", regValue);
65635+
65636+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_OVERSIZE_RECEIVED, NULL);
65637+ mvOsPrintf("OversizeFramesReceived = %u\n", regValue);
65638+
65639+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_JABBER_RECEIVED, NULL);
65640+ mvOsPrintf("JabbersReceived = %u\n", regValue);
65641+
65642+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_MAC_RECEIVE_ERROR, NULL);
65643+ mvOsPrintf("MacReceiveErrors = %u\n", regValue);
65644+
65645+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_CRC_EVENT, NULL);
65646+ mvOsPrintf("BadCrcReceived = %u\n", regValue);
65647+
65648+ mvOsPrintf("\n\t TX Errors\n");
65649+
65650+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR, NULL);
65651+ mvOsPrintf("TxMacErrors = %u\n", regValue);
65652+
65653+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_EXCESSIVE_COLLISION, NULL);
65654+ mvOsPrintf("TxExcessiveCollisions = %u\n", regValue);
65655+
65656+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_COLLISION, NULL);
65657+ mvOsPrintf("TxCollisions = %u\n", regValue);
65658+
65659+ regValue = mvEthMibCounterRead(pHndl, ETH_MIB_LATE_COLLISION, NULL);
65660+ mvOsPrintf("TxLateCollisions = %u\n", regValue);
65661+
65662+
65663+ mvOsPrintf("\n");
65664+ regValue = MV_REG_READ( ETH_RX_DISCARD_PKTS_CNTR_REG(port));
65665+ mvOsPrintf("Rx Discard packets counter = %u\n", regValue);
65666+
65667+ regValue = MV_REG_READ(ETH_RX_OVERRUN_PKTS_CNTR_REG(port));
65668+ mvOsPrintf("Rx Overrun packets counter = %u\n", regValue);
65669+}
65670+
65671+/* Print RMON counters of the Ethernet port */
65672+void ethPortRmonCounters(int port)
65673+{
65674+ void* pHndl;
65675+
65676+ pHndl = mvEthPortHndlGet(port);
65677+ if(pHndl == NULL)
65678+ return;
65679+
65680+ mvOsPrintf("\n\t Port #%d RMON MIB Counters\n\n", port);
65681+
65682+ mvOsPrintf("64 ByteFramesReceived = %u\n",
65683+ mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_64_OCTETS, NULL));
65684+ mvOsPrintf("65...127 ByteFramesReceived = %u\n",
65685+ mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_65_TO_127_OCTETS, NULL));
65686+ mvOsPrintf("128...255 ByteFramesReceived = %u\n",
65687+ mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_128_TO_255_OCTETS, NULL));
65688+ mvOsPrintf("256...511 ByteFramesReceived = %u\n",
65689+ mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_256_TO_511_OCTETS, NULL));
65690+ mvOsPrintf("512...1023 ByteFramesReceived = %u\n",
65691+ mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_512_TO_1023_OCTETS, NULL));
65692+ mvOsPrintf("1024...Max ByteFramesReceived = %u\n",
65693+ mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_1024_TO_MAX_OCTETS, NULL));
65694+}
65695+
65696+/* Print port information */
65697+void ethPortStatus(int port)
65698+{
65699+ void* pHndl;
65700+
65701+ pHndl = mvEthPortHndlGet(port);
65702+ if(pHndl != NULL)
65703+ {
65704+ mvEthPortShow(pHndl);
65705+ }
65706+}
65707+
65708+/* Print port queues information */
65709+void ethPortQueues(int port, int rxQueue, int txQueue, int mode)
65710+{
65711+ void* pHndl;
65712+
65713+ pHndl = mvEthPortHndlGet(port);
65714+ if(pHndl != NULL)
65715+ {
65716+ mvEthQueuesShow(pHndl, rxQueue, txQueue, mode);
65717+ }
65718+}
65719+
65720+void ethUcastSet(int port, char* macStr, int queue)
65721+{
65722+ void* pHndl;
65723+ MV_U8 macAddr[MV_MAC_ADDR_SIZE];
65724+
65725+ pHndl = mvEthPortHndlGet(port);
65726+ if(pHndl != NULL)
65727+ {
65728+ mvMacStrToHex(macStr, macAddr);
65729+ mvEthMacAddrSet(pHndl, macAddr, queue);
65730+ }
65731+}
65732+
65733+
65734+void ethPortUcastShow(int port)
65735+{
65736+ MV_U32 unicastReg, macL, macH;
65737+ int i, j;
65738+
65739+ macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(port));
65740+ macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(port));
65741+
65742+ mvOsPrintf("\n\t Port #%d Unicast MAC table: %02x:%02x:%02x:%02x:%02x:%02x\n\n",
65743+ port, ((macH >> 24) & 0xff), ((macH >> 16) & 0xff),
65744+ ((macH >> 8) & 0xff), (macH & 0xff),
65745+ ((macL >> 8) & 0xff), (macL & 0xff) );
65746+
65747+ for (i=0; i<4; i++)
65748+ {
65749+ unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(port) + i*4));
65750+ for(j=0; j<4; j++)
65751+ {
65752+ MV_U8 macEntry = (unicastReg >> (8*j)) & 0xFF;
65753+
65754+ mvOsPrintf("%X: %8s, Q = %d\n", i*4+j,
65755+ (macEntry & BIT0) ? "Accept" : "Reject", (macEntry >> 1) & 0x7);
65756+ }
65757+ }
65758+}
65759+
65760+void ethMcastAdd(int port, char* macStr, int queue)
65761+{
65762+ void* pHndl;
65763+ MV_U8 macAddr[MV_MAC_ADDR_SIZE];
65764+
65765+ pHndl = mvEthPortHndlGet(port);
65766+ if(pHndl != NULL)
65767+ {
65768+ mvMacStrToHex(macStr, macAddr);
65769+ mvEthMcastAddrSet(pHndl, macAddr, queue);
65770+ }
65771+}
65772+
65773+void ethPortMcast(int port)
65774+{
65775+ int tblIdx, regIdx;
65776+ MV_U32 regVal;
65777+
65778+ mvOsPrintf("\n\t Port #%d Special (IP) Multicast table: 01:00:5E:00:00:XX\n\n",
65779+ port);
65780+
65781+ for(tblIdx=0; tblIdx<(256/4); tblIdx++)
65782+ {
65783+ regVal = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(port) + tblIdx*4));
65784+ for(regIdx=0; regIdx<4; regIdx++)
65785+ {
65786+ if((regVal & (0x01 << (regIdx*8))) != 0)
65787+ {
65788+ mvOsPrintf("0x%02X: Accepted, rxQ = %d\n",
65789+ tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));
65790+ }
65791+ }
65792+ }
65793+ mvOsPrintf("\n\t Port #%d Other Multicast table\n\n", port);
65794+ for(tblIdx=0; tblIdx<(256/4); tblIdx++)
65795+ {
65796+ regVal = MV_REG_READ((ETH_DA_FILTER_OTH_MCAST_BASE(port) + tblIdx*4));
65797+ for(regIdx=0; regIdx<4; regIdx++)
65798+ {
65799+ if((regVal & (0x01 << (regIdx*8))) != 0)
65800+ {
65801+ mvOsPrintf("Crc8=0x%02X: Accepted, rxQ = %d\n",
65802+ tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));
65803+ }
65804+ }
65805+ }
65806+}
65807+
65808+
65809+/* Print status of Ethernet port */
65810+void mvEthPortShow(void* pHndl)
65811+{
65812+ MV_U32 regValue, rxCoal, txCoal;
65813+ int speed, queue, port;
65814+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pHndl;
65815+
65816+ port = pPortCtrl->portNo;
65817+
65818+ regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );
65819+
65820+ mvOsPrintf("\n\t ethGiga #%d port Status: 0x%04x = 0x%08x\n\n",
65821+ port, ETH_PORT_STATUS_REG(port), regValue);
65822+
65823+ mvOsPrintf("descInSram=%d, descSwCoher=%d\n",
65824+ ethDescInSram, ethDescSwCoher);
65825+
65826+ if(regValue & ETH_GMII_SPEED_1000_MASK)
65827+ speed = 1000;
65828+ else if(regValue & ETH_MII_SPEED_100_MASK)
65829+ speed = 100;
65830+ else
65831+ speed = 10;
65832+
65833+ mvEthCoalGet(pPortCtrl, &rxCoal, &txCoal);
65834+
65835+ /* Link, Speed, Duplex, FlowControl */
65836+ mvOsPrintf("Link=%s, Speed=%d, Duplex=%s, RxFlowControl=%s",
65837+ (regValue & ETH_LINK_UP_MASK) ? "UP" : "DOWN",
65838+ speed,
65839+ (regValue & ETH_FULL_DUPLEX_MASK) ? "FULL" : "HALF",
65840+ (regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK) ? "ENABLE" : "DISABLE");
65841+
65842+ mvOsPrintf("\n");
65843+
65844+ mvOsPrintf("RxCoal = %d usec, TxCoal = %d usec\n",
65845+ rxCoal, txCoal);
65846+
65847+ mvOsPrintf("rxDefQ=%d, arpQ=%d, bpduQ=%d, tcpQ=%d, udpQ=%d\n\n",
65848+ pPortCtrl->portConfig.rxDefQ, pPortCtrl->portConfig.rxArpQ,
65849+ pPortCtrl->portConfig.rxBpduQ,
65850+ pPortCtrl->portConfig.rxTcpQ, pPortCtrl->portConfig.rxUdpQ);
65851+
65852+ /* Print all RX and TX queues */
65853+ for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
65854+ {
65855+ mvOsPrintf("RX Queue #%d: base=0x%lx, free=%d\n",
65856+ queue, (MV_ULONG)pPortCtrl->rxQueue[queue].pFirstDescr,
65857+ mvEthRxResourceGet(pPortCtrl, queue) );
65858+ }
65859+ mvOsPrintf("\n");
65860+ for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
65861+ {
65862+ mvOsPrintf("TX Queue #%d: base=0x%lx, free=%d\n",
65863+ queue, (MV_ULONG)pPortCtrl->txQueue[queue].pFirstDescr,
65864+ mvEthTxResourceGet(pPortCtrl, queue) );
65865+ }
65866+}
65867+
65868+/* Print RX and TX queue of the Ethernet port */
65869+void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode)
65870+{
65871+ ETH_PORT_CTRL *pPortCtrl = (ETH_PORT_CTRL*)pHndl;
65872+ ETH_QUEUE_CTRL *pQueueCtrl;
65873+ MV_U32 regValue;
65874+ ETH_RX_DESC *pRxDescr;
65875+ ETH_TX_DESC *pTxDescr;
65876+ int i, port = pPortCtrl->portNo;
65877+
65878+ if( (rxQueue >=0) && (rxQueue < MV_ETH_RX_Q_NUM) )
65879+ {
65880+ pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);
65881+ mvOsPrintf("Port #%d, RX Queue #%d\n\n", port, rxQueue);
65882+
65883+ mvOsPrintf("CURR_RX_DESC_PTR : 0x%X = 0x%08x\n",
65884+ ETH_RX_CUR_DESC_PTR_REG(port, rxQueue),
65885+ MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue)));
65886+
65887+
65888+ if(pQueueCtrl->pFirstDescr != NULL)
65889+ {
65890+ mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",
65891+ (MV_ULONG)pQueueCtrl->pFirstDescr, (MV_ULONG)pQueueCtrl->pLastDescr,
65892+ pQueueCtrl->resource);
65893+ mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",
65894+ (MV_ULONG)pQueueCtrl->pCurrentDescr,
65895+ (MV_ULONG)pQueueCtrl->pUsedDescr);
65896+
65897+ if(mode == 1)
65898+ {
65899+ pRxDescr = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;
65900+ i = 0;
65901+ do
65902+ {
65903+ mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%4d, buf=%08x, pkt=%lx, os=%lx\n",
65904+ i, (MV_U32)pRxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pRxDescr),
65905+ pRxDescr->cmdSts, pRxDescr->byteCnt, (MV_U32)pRxDescr->bufSize,
65906+ (unsigned int)pRxDescr->bufPtr, (MV_ULONG)pRxDescr->returnInfo,
65907+ ((MV_PKT_INFO*)pRxDescr->returnInfo)->osInfo);
65908+
65909+ ETH_DESCR_INV(pPortCtrl, pRxDescr);
65910+ pRxDescr = RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl);
65911+ i++;
65912+ } while (pRxDescr != pQueueCtrl->pFirstDescr);
65913+ }
65914+ }
65915+ else
65916+ mvOsPrintf("RX Queue #%d is NOT CREATED\n", rxQueue);
65917+ }
65918+
65919+ if( (txQueue >=0) && (txQueue < MV_ETH_TX_Q_NUM) )
65920+ {
65921+ pQueueCtrl = &(pPortCtrl->txQueue[txQueue]);
65922+ mvOsPrintf("Port #%d, TX Queue #%d\n\n", port, txQueue);
65923+
65924+ regValue = MV_REG_READ( ETH_TX_CUR_DESC_PTR_REG(port, txQueue));
65925+ mvOsPrintf("CURR_TX_DESC_PTR : 0x%X = 0x%08x\n",
65926+ ETH_TX_CUR_DESC_PTR_REG(port, txQueue), regValue);
65927+
65928+ if(pQueueCtrl->pFirstDescr != NULL)
65929+ {
65930+ mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",
65931+ (MV_ULONG)pQueueCtrl->pFirstDescr,
65932+ (MV_ULONG)pQueueCtrl->pLastDescr,
65933+ pQueueCtrl->resource);
65934+ mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",
65935+ (MV_ULONG)pQueueCtrl->pCurrentDescr,
65936+ (MV_ULONG)pQueueCtrl->pUsedDescr);
65937+
65938+ if(mode == 1)
65939+ {
65940+ pTxDescr = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;
65941+ i = 0;
65942+ do
65943+ {
65944+ mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%08x, pkt=%lx, os=%lx\n",
65945+ i, (MV_U32)pTxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxDescr),
65946+ pTxDescr->cmdSts, pTxDescr->byteCnt,
65947+ (MV_U32)pTxDescr->bufPtr, (MV_ULONG)pTxDescr->returnInfo,
65948+ pTxDescr->returnInfo ? (((MV_PKT_INFO*)pTxDescr->returnInfo)->osInfo) : 0x0);
65949+
65950+ ETH_DESCR_INV(pPortCtrl, pTxDescr);
65951+ pTxDescr = TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl);
65952+ i++;
65953+ } while (pTxDescr != pQueueCtrl->pFirstDescr);
65954+ }
65955+ }
65956+ else
65957+ mvOsPrintf("TX Queue #%d is NOT CREATED\n", txQueue);
65958+ }
65959+}
65960diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h b/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h
65961new file mode 100644
65962index 0000000..b772a74
65963--- /dev/null
65964+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h
65965@@ -0,0 +1,146 @@
65966+/*******************************************************************************
65967+Copyright (C) Marvell International Ltd. and its affiliates
65968+
65969+This software file (the "File") is owned and distributed by Marvell
65970+International Ltd. and/or its affiliates ("Marvell") under the following
65971+alternative licensing terms. Once you have made an election to distribute the
65972+File under one of the following license alternatives, please (i) delete this
65973+introductory statement regarding license alternatives, (ii) delete the two
65974+license alternatives that you have not elected to use and (iii) preserve the
65975+Marvell copyright notice above.
65976+
65977+********************************************************************************
65978+Marvell Commercial License Option
65979+
65980+If you received this File from Marvell and you have entered into a commercial
65981+license agreement (a "Commercial License") with Marvell, the File is licensed
65982+to you under the terms of the applicable Commercial License.
65983+
65984+********************************************************************************
65985+Marvell GPL License Option
65986+
65987+If you received this File from Marvell, you may opt to use, redistribute and/or
65988+modify this File in accordance with the terms and conditions of the General
65989+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
65990+available along with the File in the license.txt file or by writing to the Free
65991+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
65992+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
65993+
65994+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
65995+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
65996+DISCLAIMED. The GPL License provides additional details about this warranty
65997+disclaimer.
65998+********************************************************************************
65999+Marvell BSD License Option
66000+
66001+If you received this File from Marvell, you may opt to use, redistribute and/or
66002+modify this File under the following licensing terms.
66003+Redistribution and use in source and binary forms, with or without modification,
66004+are permitted provided that the following conditions are met:
66005+
66006+ * Redistributions of source code must retain the above copyright notice,
66007+ this list of conditions and the following disclaimer.
66008+
66009+ * Redistributions in binary form must reproduce the above copyright
66010+ notice, this list of conditions and the following disclaimer in the
66011+ documentation and/or other materials provided with the distribution.
66012+
66013+ * Neither the name of Marvell nor the names of its contributors may be
66014+ used to endorse or promote products derived from this software without
66015+ specific prior written permission.
66016+
66017+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
66018+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
66019+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66020+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
66021+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
66022+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
66023+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
66024+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
66025+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
66026+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
66027+
66028+*******************************************************************************/
66029+#ifndef __MV_ETH_DEBUG_H__
66030+#define __MV_ETH_DEBUG_H__
66031+
66032+#if 0
66033+/*
66034+ ** Externs
66035+ */
66036+void ethBpduRxQ(int port, int bpduQueue);
66037+void ethArpRxQ(int port, int bpduQueue);
66038+void ethTcpRxQ(int port, int bpduQueue);
66039+void ethUdpRxQ(int port, int bpduQueue);
66040+void ethMcastAdd(int port, char* macStr, int queue);
66041+
66042+#ifdef INCLUDE_MULTI_QUEUE
66043+void ethRxPolicy( int port);
66044+void ethTxPolicy( int port);
66045+void ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);
66046+void ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);
66047+void ethRxPolQ(int port, int rxQueue, int rxQuota);
66048+#endif /* INCLUDE_MULTI_QUEUE */
66049+
66050+void print_egiga_stat(void *sc, unsigned int port);
66051+void ethPortStatus (int port);
66052+void ethPortQueues( int port, int rxQueue, int txQueue, int mode);
66053+void ethPortMcast(int port);
66054+void ethPortRegs(int port);
66055+void ethPortCounters(int port);
66056+void ethPortRmonCounters(int port);
66057+void ethRxCoal(int port, int usec);
66058+void ethTxCoal(int port, int usec);
66059+
66060+void ethRegs(int port);
66061+void ethClearCounters(int port);
66062+void ethUcastSet(int port, char* macStr, int queue);
66063+void ethPortUcastShow(int port);
66064+
66065+#ifdef CONFIG_MV_ETH_HEADER
66066+void run_com_header(const char *buffer);
66067+#endif
66068+
66069+#ifdef INCLUDE_MULTI_QUEUE
66070+void ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);
66071+void ethRxPolQ(int port, int queue, int quota);
66072+void ethRxPolicy(int port);
66073+void ethTxPolDef(int port, int txQ, char* headerHexStr);
66074+void ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);
66075+void ethTxPolicy(int port);
66076+#endif /* INCLUDE_MULTI_QUEUE */
66077+
66078+#if (MV_ETH_VERSION >= 4)
66079+void ethEjpModeSet(int port, int mode)
66080+#endif
66081+#endif /* 0 */
66082+
66083+
66084+
66085+
66086+void ethRxCoal(int port, int usec);
66087+void ethTxCoal(int port, int usec);
66088+#if (MV_ETH_VERSION >= 4)
66089+void ethEjpModeSet(int port, int mode);
66090+#endif /* (MV_ETH_VERSION >= 4) */
66091+
66092+void ethBpduRxQ(int port, int bpduQueue);
66093+void ethArpRxQ(int port, int arpQueue);
66094+void ethTcpRxQ(int port, int tcpQueue);
66095+void ethUdpRxQ(int port, int udpQueue);
66096+void ethTxPolicyRegs(int port);
66097+void ethPortRegs(int port);
66098+void ethRegs(int port);
66099+void ethClearCounters(int port);
66100+void ethPortCounters(int port);
66101+void ethPortRmonCounters(int port);
66102+void ethPortStatus(int port);
66103+void ethPortQueues(int port, int rxQueue, int txQueue, int mode);
66104+void ethUcastSet(int port, char* macStr, int queue);
66105+void ethPortUcastShow(int port);
66106+void ethMcastAdd(int port, char* macStr, int queue);
66107+void ethPortMcast(int port);
66108+void mvEthPortShow(void* pHndl);
66109+void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);
66110+
66111+#endif
66112diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h b/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h
66113new file mode 100644
66114index 0000000..83ad6ad
66115--- /dev/null
66116+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h
66117@@ -0,0 +1,751 @@
66118+/*******************************************************************************
66119+Copyright (C) Marvell International Ltd. and its affiliates
66120+
66121+This software file (the "File") is owned and distributed by Marvell
66122+International Ltd. and/or its affiliates ("Marvell") under the following
66123+alternative licensing terms. Once you have made an election to distribute the
66124+File under one of the following license alternatives, please (i) delete this
66125+introductory statement regarding license alternatives, (ii) delete the two
66126+license alternatives that you have not elected to use and (iii) preserve the
66127+Marvell copyright notice above.
66128+
66129+********************************************************************************
66130+Marvell Commercial License Option
66131+
66132+If you received this File from Marvell and you have entered into a commercial
66133+license agreement (a "Commercial License") with Marvell, the File is licensed
66134+to you under the terms of the applicable Commercial License.
66135+
66136+********************************************************************************
66137+Marvell GPL License Option
66138+
66139+If you received this File from Marvell, you may opt to use, redistribute and/or
66140+modify this File in accordance with the terms and conditions of the General
66141+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
66142+available along with the File in the license.txt file or by writing to the Free
66143+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
66144+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
66145+
66146+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
66147+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
66148+DISCLAIMED. The GPL License provides additional details about this warranty
66149+disclaimer.
66150+********************************************************************************
66151+Marvell BSD License Option
66152+
66153+If you received this File from Marvell, you may opt to use, redistribute and/or
66154+modify this File under the following licensing terms.
66155+Redistribution and use in source and binary forms, with or without modification,
66156+are permitted provided that the following conditions are met:
66157+
66158+ * Redistributions of source code must retain the above copyright notice,
66159+ this list of conditions and the following disclaimer.
66160+
66161+ * Redistributions in binary form must reproduce the above copyright
66162+ notice, this list of conditions and the following disclaimer in the
66163+ documentation and/or other materials provided with the distribution.
66164+
66165+ * Neither the name of Marvell nor the names of its contributors may be
66166+ used to endorse or promote products derived from this software without
66167+ specific prior written permission.
66168+
66169+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
66170+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
66171+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66172+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
66173+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
66174+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
66175+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
66176+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
66177+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
66178+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
66179+
66180+*******************************************************************************/
66181+
66182+/*******************************************************************************
66183+* mvEth.h - Header File for : Marvell Gigabit Ethernet Controller
66184+*
66185+* DESCRIPTION:
66186+* This header file contains macros typedefs and function declaration specific to
66187+* the Marvell Gigabit Ethernet Controller.
66188+*
66189+* DEPENDENCIES:
66190+* None.
66191+*
66192+*******************************************************************************/
66193+
66194+#ifndef __mvEthGbe_h__
66195+#define __mvEthGbe_h__
66196+
66197+extern MV_BOOL ethDescInSram;
66198+extern MV_BOOL ethDescSwCoher;
66199+extern ETH_PORT_CTRL* ethPortCtrl[];
66200+
66201+static INLINE MV_ULONG ethDescVirtToPhy(ETH_QUEUE_CTRL* pQueueCtrl, MV_U8* pDesc)
66202+{
66203+#if defined (ETH_DESCR_IN_SRAM)
66204+ if( ethDescInSram )
66205+ return mvSramVirtToPhy(pDesc);
66206+ else
66207+#endif /* ETH_DESCR_IN_SRAM */
66208+ return (pQueueCtrl->descBuf.bufPhysAddr + (pDesc - pQueueCtrl->descBuf.bufVirtPtr));
66209+}
66210+/* Return port handler */
66211+#define mvEthPortHndlGet(port) ethPortCtrl[port]
66212+
66213+/* Used as WA for HW/SW race on TX */
66214+static INLINE int mvEthPortTxEnable(void* pPortHndl, int queue, int max_deep)
66215+{
66216+ int deep = 0;
66217+ MV_U32 txCurrReg, txEnReg;
66218+ ETH_TX_DESC* pTxLastDesc;
66219+ ETH_QUEUE_CTRL* pQueueCtrl;
66220+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
66221+
66222+ txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));
66223+ if( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) == 0)
66224+ {
66225+ MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
66226+ return 0;
66227+ }
66228+
66229+ pQueueCtrl = &pPortCtrl->txQueue[queue];
66230+ pTxLastDesc = pQueueCtrl->pCurrentDescr;
66231+ txCurrReg = MV_REG_READ(ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue));
66232+ if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)
66233+ {
66234+ /* All descriptors are processed, no chance for race */
66235+ return 0;
66236+ }
66237+
66238+ /* Check distance betwee HW and SW location: */
66239+ /* If distance between HW and SW pointers is less than max_deep descriptors */
66240+ /* Race condition is possible, so wait end of TX and restart TXQ */
66241+ while(deep < max_deep)
66242+ {
66243+ pTxLastDesc = TX_PREV_DESC_PTR(pTxLastDesc, pQueueCtrl);
66244+ if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)
66245+ {
66246+ int count = 0;
66247+
66248+ while( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) != 0)
66249+ {
66250+ count++;
66251+ if(count > 10000)
66252+ {
66253+ mvOsPrintf("mvEthPortTxEnable: timeout - TXQ_CMD=0x%08x\n",
66254+ MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) );
66255+ break;
66256+ }
66257+ txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));
66258+ }
66259+
66260+ MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
66261+ return count;
66262+ }
66263+ deep++;
66264+ }
66265+ /* Distance between HW and SW pointers is more than max_deep descriptors, */
66266+ /* So NO race condition - do nothing */
66267+ return -1;
66268+}
66269+
66270+
66271+/* defines */
66272+#define ETH_CSUM_MIN_BYTE_COUNT 72
66273+
66274+/* Tailgate and Kirwood have only 2K TX FIFO */
66275+#if (MV_ETH_VERSION == 2) || (MV_ETH_VERSION == 4)
66276+#define ETH_CSUM_MAX_BYTE_COUNT 1600
66277+#else
66278+#define ETH_CSUM_MAX_BYTE_COUNT 9*1024
66279+#endif /* MV_ETH_VERSION */
66280+
66281+#define ETH_MV_HEADER_SIZE 2
66282+#define ETH_MV_TX_EN
66283+
66284+/* An offest in Tx descriptors to store data for buffers less than 8 Bytes */
66285+#define MIN_TX_BUFF_LOAD 8
66286+#define TX_BUF_OFFSET_IN_DESC (ETH_TX_DESC_ALIGNED_SIZE - MIN_TX_BUFF_LOAD)
66287+
66288+/* Default port configuration value */
66289+#define PORT_CONFIG_VALUE \
66290+ ETH_DEF_RX_QUEUE_MASK(0) | \
66291+ ETH_DEF_RX_ARP_QUEUE_MASK(0) | \
66292+ ETH_DEF_RX_TCP_QUEUE_MASK(0) | \
66293+ ETH_DEF_RX_UDP_QUEUE_MASK(0) | \
66294+ ETH_DEF_RX_BPDU_QUEUE_MASK(0) | \
66295+ ETH_RX_CHECKSUM_WITH_PSEUDO_HDR
66296+
66297+/* Default port extend configuration value */
66298+#define PORT_CONFIG_EXTEND_VALUE 0
66299+
66300+#define PORT_SERIAL_CONTROL_VALUE \
66301+ ETH_DISABLE_FC_AUTO_NEG_MASK | \
66302+ BIT9 | \
66303+ ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
66304+ ETH_MAX_RX_PACKET_1552BYTE | \
66305+ ETH_SET_FULL_DUPLEX_MASK
66306+
66307+#define PORT_SERIAL_CONTROL_100MB_FORCE_VALUE \
66308+ ETH_FORCE_LINK_PASS_MASK | \
66309+ ETH_DISABLE_DUPLEX_AUTO_NEG_MASK | \
66310+ ETH_DISABLE_FC_AUTO_NEG_MASK | \
66311+ BIT9 | \
66312+ ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
66313+ ETH_DISABLE_SPEED_AUTO_NEG_MASK | \
66314+ ETH_SET_FULL_DUPLEX_MASK | \
66315+ ETH_SET_MII_SPEED_100_MASK | \
66316+ ETH_MAX_RX_PACKET_1552BYTE
66317+
66318+
66319+#define PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE \
66320+ ETH_FORCE_LINK_PASS_MASK | \
66321+ ETH_DISABLE_DUPLEX_AUTO_NEG_MASK | \
66322+ ETH_DISABLE_FC_AUTO_NEG_MASK | \
66323+ BIT9 | \
66324+ ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
66325+ ETH_DISABLE_SPEED_AUTO_NEG_MASK | \
66326+ ETH_SET_FULL_DUPLEX_MASK | \
66327+ ETH_SET_GMII_SPEED_1000_MASK | \
66328+ ETH_MAX_RX_PACKET_1552BYTE
66329+
66330+#define PORT_SERIAL_CONTROL_SGMII_IBAN_VALUE \
66331+ ETH_DISABLE_FC_AUTO_NEG_MASK | \
66332+ BIT9 | \
66333+ ETH_IN_BAND_AN_EN_MASK | \
66334+ ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
66335+ ETH_MAX_RX_PACKET_1552BYTE
66336+
66337+/* Function headers: */
66338+MV_VOID mvEthSetSpecialMcastTable(int portNo, int queue);
66339+MV_STATUS mvEthArpRxQueue(void* pPortHandle, int arpQueue);
66340+MV_STATUS mvEthUdpRxQueue(void* pPortHandle, int udpQueue);
66341+MV_STATUS mvEthTcpRxQueue(void* pPortHandle, int tcpQueue);
66342+MV_STATUS mvEthMacAddrGet(int portNo, unsigned char *pAddr);
66343+MV_VOID mvEthSetOtherMcastTable(int portNo, int queue);
66344+MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);
66345+/* Interrupt Coalesting functions */
66346+MV_U32 mvEthRxCoalSet(void* pPortHndl, MV_U32 uSec);
66347+MV_U32 mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec);
66348+MV_STATUS mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal);
66349+
66350+/******************************************************************************/
66351+/* Data Flow functions */
66352+/******************************************************************************/
66353+static INLINE void mvEthPortTxRestart(void* pPortHndl)
66354+{
66355+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
66356+
66357+ MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
66358+}
66359+
66360+/* Get number of Free resources in specific TX queue */
66361+static INLINE int mvEthTxResourceGet(void* pPortHndl, int txQueue)
66362+{
66363+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
66364+
66365+ return (pPortCtrl->txQueue[txQueue].resource);
66366+}
66367+
66368+/* Get number of Free resources in specific RX queue */
66369+static INLINE int mvEthRxResourceGet(void* pPortHndl, int rxQueue)
66370+{
66371+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
66372+
66373+ return (pPortCtrl->rxQueue[rxQueue].resource);
66374+}
66375+
66376+static INLINE int mvEthTxQueueIsFull(void* pPortHndl, int txQueue)
66377+{
66378+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
66379+
66380+ if(pPortCtrl->txQueue[txQueue].resource == 0)
66381+ return MV_TRUE;
66382+
66383+ return MV_FALSE;
66384+}
66385+
66386+/* Get number of Free resources in specific RX queue */
66387+static INLINE int mvEthRxQueueIsFull(void* pPortHndl, int rxQueue)
66388+{
66389+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
66390+ ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
66391+
66392+ if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
66393+ (pQueueCtrl->resource != 0) )
66394+ return MV_TRUE;
66395+
66396+ return MV_FALSE;
66397+}
66398+
66399+static INLINE int mvEthTxQueueIsEmpty(void* pPortHndl, int txQueue)
66400+{
66401+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
66402+ ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[txQueue];
66403+
66404+ if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
66405+ (pQueueCtrl->resource != 0) )
66406+ {
66407+ return MV_TRUE;
66408+ }
66409+ return MV_FALSE;
66410+}
66411+
66412+/* Get number of Free resources in specific RX queue */
66413+static INLINE int mvEthRxQueueIsEmpty(void* pPortHndl, int rxQueue)
66414+{
66415+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
66416+
66417+ if(pPortCtrl->rxQueue[rxQueue].resource == 0)
66418+ return MV_TRUE;
66419+
66420+ return MV_FALSE;
66421+}
66422+
66423+/*******************************************************************************
66424+* mvEthPortTx - Send an Ethernet packet
66425+*
66426+* DESCRIPTION:
66427+* This routine send a given packet described by pPktInfo parameter.
66428+* Single buffer only.
66429+*
66430+* INPUT:
66431+* void* pEthPortHndl - Ethernet Port handler.
66432+* int txQueue - Number of Tx queue.
66433+* MV_PKT_INFO *pPktInfo - User packet to send.
66434+*
66435+* RETURN:
66436+* MV_NO_RESOURCE - No enough resources to send this packet.
66437+* MV_ERROR - Unexpected Fatal error.
66438+* MV_OK - Packet send successfully.
66439+*
66440+*******************************************************************************/
66441+static INLINE MV_STATUS mvEthPortTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)
66442+{
66443+ ETH_TX_DESC* pTxCurrDesc;
66444+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
66445+ ETH_QUEUE_CTRL* pQueueCtrl;
66446+ int portNo;
66447+ MV_BUF_INFO* pBufInfo = pPktInfo->pFrags;
66448+
66449+#ifdef ETH_DEBUG
66450+ if(pPortCtrl->portState != MV_ACTIVE)
66451+ return MV_BAD_STATE;
66452+#endif /* ETH_DEBUG */
66453+
66454+ portNo = pPortCtrl->portNo;
66455+ pQueueCtrl = &pPortCtrl->txQueue[txQueue];
66456+
66457+ /* Get the Tx Desc ring indexes */
66458+ pTxCurrDesc = pQueueCtrl->pCurrentDescr;
66459+
66460+ /* Check if there is enough resources to send the packet */
66461+ if(pQueueCtrl->resource == 0)
66462+ return MV_NO_RESOURCE;
66463+
66464+ pTxCurrDesc->byteCnt = pBufInfo->dataSize;
66465+
66466+ /* Flash Buffer */
66467+ if(pPktInfo->pktSize != 0)
66468+ {
66469+#ifdef MV_NETBSD
66470+ pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;
66471+ ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);
66472+#else
66473+ pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);
66474+#endif
66475+ pPktInfo->pktSize = 0;
66476+ }
66477+ else
66478+ pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;
66479+
66480+ pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;
66481+
66482+ /* There is only one buffer in the packet */
66483+ /* The OSG might set some bits for checksum offload, so add them to first descriptor */
66484+ pTxCurrDesc->cmdSts = pPktInfo->status |
66485+ ETH_BUFFER_OWNED_BY_DMA |
66486+ ETH_TX_GENERATE_CRC_MASK |
66487+ ETH_TX_ENABLE_INTERRUPT_MASK |
66488+ ETH_TX_ZERO_PADDING_MASK |
66489+ ETH_TX_FIRST_DESC_MASK |
66490+ ETH_TX_LAST_DESC_MASK;
66491+
66492+ ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
66493+
66494+ pQueueCtrl->resource--;
66495+ pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
66496+
66497+ /* Apply send command */
66498+ MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;
66499+
66500+ return MV_OK;
66501+}
66502+
66503+
66504+/*******************************************************************************
66505+* mvEthPortSgTx - Send an Ethernet packet
66506+*
66507+* DESCRIPTION:
66508+* This routine send a given packet described by pBufInfo parameter. It
66509+* supports transmitting of a packet spaned over multiple buffers.
66510+*
66511+* INPUT:
66512+* void* pEthPortHndl - Ethernet Port handler.
66513+* int txQueue - Number of Tx queue.
66514+* MV_PKT_INFO *pPktInfo - User packet to send.
66515+*
66516+* RETURN:
66517+* MV_NO_RESOURCE - No enough resources to send this packet.
66518+* MV_ERROR - Unexpected Fatal error.
66519+* MV_OK - Packet send successfully.
66520+*
66521+*******************************************************************************/
66522+static INLINE MV_STATUS mvEthPortSgTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)
66523+{
66524+ ETH_TX_DESC* pTxFirstDesc;
66525+ ETH_TX_DESC* pTxCurrDesc;
66526+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
66527+ ETH_QUEUE_CTRL* pQueueCtrl;
66528+ int portNo, bufCount;
66529+ MV_BUF_INFO* pBufInfo = pPktInfo->pFrags;
66530+ MV_U8* pTxBuf;
66531+
66532+#ifdef ETH_DEBUG
66533+ if(pPortCtrl->portState != MV_ACTIVE)
66534+ return MV_BAD_STATE;
66535+#endif /* ETH_DEBUG */
66536+
66537+ portNo = pPortCtrl->portNo;
66538+ pQueueCtrl = &pPortCtrl->txQueue[txQueue];
66539+
66540+ /* Get the Tx Desc ring indexes */
66541+ pTxCurrDesc = pQueueCtrl->pCurrentDescr;
66542+
66543+ /* Check if there is enough resources to send the packet */
66544+ if(pQueueCtrl->resource < pPktInfo->numFrags)
66545+ return MV_NO_RESOURCE;
66546+
66547+ /* Remember first desc */
66548+ pTxFirstDesc = pTxCurrDesc;
66549+
66550+ bufCount = 0;
66551+ while(MV_TRUE)
66552+ {
66553+ if(pBufInfo[bufCount].dataSize <= MIN_TX_BUFF_LOAD)
66554+ {
66555+ /* Buffers with a payload smaller than MIN_TX_BUFF_LOAD (8 bytes) must be aligned */
66556+ /* to 64-bit boundary. Two options here: */
66557+ /* 1) Usually, copy the payload to the reserved 8 bytes inside descriptor. */
66558+ /* 2) In the Half duplex workaround, the reserved 8 bytes inside descriptor are used */
66559+ /* as a pointer to the aligned buffer, copy the small payload to this buffer. */
66560+ pTxBuf = ((MV_U8*)pTxCurrDesc)+TX_BUF_OFFSET_IN_DESC;
66561+ mvOsBCopy(pBufInfo[bufCount].bufVirtPtr, pTxBuf, pBufInfo[bufCount].dataSize);
66562+ pTxCurrDesc->bufPtr = ethDescVirtToPhy(pQueueCtrl, pTxBuf);
66563+ }
66564+ else
66565+ {
66566+ /* Flash Buffer */
66567+#ifdef MV_NETBSD
66568+ pTxCurrDesc->bufPtr = pBufInfo[bufCount].bufPhysAddr;
66569+ ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);
66570+#else
66571+ pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);
66572+#endif
66573+ }
66574+
66575+ pTxCurrDesc->byteCnt = pBufInfo[bufCount].dataSize;
66576+ bufCount++;
66577+
66578+ if(bufCount >= pPktInfo->numFrags)
66579+ break;
66580+
66581+ if(bufCount > 1)
66582+ {
66583+ /* There is middle buffer of the packet Not First and Not Last */
66584+ pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA;
66585+ ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
66586+ }
66587+ /* Go to next descriptor and next buffer */
66588+ pTxCurrDesc = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
66589+ }
66590+ /* Set last desc with DMA ownership and interrupt enable. */
66591+ pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;
66592+ if(bufCount == 1)
66593+ {
66594+ /* There is only one buffer in the packet */
66595+ /* The OSG might set some bits for checksum offload, so add them to first descriptor */
66596+ pTxCurrDesc->cmdSts = pPktInfo->status |
66597+ ETH_BUFFER_OWNED_BY_DMA |
66598+ ETH_TX_GENERATE_CRC_MASK |
66599+ ETH_TX_ENABLE_INTERRUPT_MASK |
66600+ ETH_TX_ZERO_PADDING_MASK |
66601+ ETH_TX_FIRST_DESC_MASK |
66602+ ETH_TX_LAST_DESC_MASK;
66603+
66604+ ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
66605+ }
66606+ else
66607+ {
66608+ /* Last but not First */
66609+ pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA |
66610+ ETH_TX_ENABLE_INTERRUPT_MASK |
66611+ ETH_TX_ZERO_PADDING_MASK |
66612+ ETH_TX_LAST_DESC_MASK;
66613+
66614+ ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
66615+
66616+ /* Update First when more than one buffer in the packet */
66617+ /* The OSG might set some bits for checksum offload, so add them to first descriptor */
66618+ pTxFirstDesc->cmdSts = pPktInfo->status |
66619+ ETH_BUFFER_OWNED_BY_DMA |
66620+ ETH_TX_GENERATE_CRC_MASK |
66621+ ETH_TX_FIRST_DESC_MASK;
66622+
66623+ ETH_DESCR_FLUSH_INV(pPortCtrl, pTxFirstDesc);
66624+ }
66625+ /* Update txQueue state */
66626+ pQueueCtrl->resource -= bufCount;
66627+ pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
66628+
66629+ /* Apply send command */
66630+ MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;
66631+
66632+ return MV_OK;
66633+}
66634+
66635+/*******************************************************************************
66636+* mvEthPortTxDone - Free all used Tx descriptors and mBlks.
66637+*
66638+* DESCRIPTION:
66639+* This routine returns the transmitted packet information to the caller.
66640+*
66641+* INPUT:
66642+* void* pEthPortHndl - Ethernet Port handler.
66643+* int txQueue - Number of Tx queue.
66644+*
66645+* OUTPUT:
66646+* MV_PKT_INFO *pPktInfo - Pointer to packet was sent.
66647+*
66648+* RETURN:
66649+* MV_NOT_FOUND - No transmitted packets to return. Transmit in progress.
66650+* MV_EMPTY - No transmitted packets to return. TX Queue is empty.
66651+* MV_ERROR - Unexpected Fatal error.
66652+* MV_OK - There is transmitted packet in the queue,
66653+* 'pPktInfo' filled with relevant information.
66654+*
66655+*******************************************************************************/
66656+static INLINE MV_PKT_INFO* mvEthPortTxDone(void* pEthPortHndl, int txQueue)
66657+{
66658+ ETH_TX_DESC* pTxCurrDesc;
66659+ ETH_TX_DESC* pTxUsedDesc;
66660+ ETH_QUEUE_CTRL* pQueueCtrl;
66661+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
66662+ MV_PKT_INFO* pPktInfo;
66663+ MV_U32 commandStatus;
66664+
66665+ pQueueCtrl = &pPortCtrl->txQueue[txQueue];
66666+
66667+ pTxUsedDesc = pQueueCtrl->pUsedDescr;
66668+ pTxCurrDesc = pQueueCtrl->pCurrentDescr;
66669+
66670+ while(MV_TRUE)
66671+ {
66672+ /* No more used descriptors */
66673+ commandStatus = pTxUsedDesc->cmdSts;
66674+ if (commandStatus & (ETH_BUFFER_OWNED_BY_DMA))
66675+ {
66676+ ETH_DESCR_INV(pPortCtrl, pTxUsedDesc);
66677+ return NULL;
66678+ }
66679+ if( (pTxUsedDesc == pTxCurrDesc) &&
66680+ (pQueueCtrl->resource != 0) )
66681+ {
66682+ return NULL;
66683+ }
66684+ pQueueCtrl->resource++;
66685+ pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxUsedDesc, pQueueCtrl);
66686+ if(commandStatus & (ETH_TX_LAST_DESC_MASK))
66687+ {
66688+ pPktInfo = (MV_PKT_INFO*)pTxUsedDesc->returnInfo;
66689+ pPktInfo->status = commandStatus;
66690+ return pPktInfo;
66691+ }
66692+ pTxUsedDesc = pQueueCtrl->pUsedDescr;
66693+ }
66694+}
66695+
66696+/*******************************************************************************
66697+* mvEthPortRx - Get new received packets from Rx queue.
66698+*
66699+* DESCRIPTION:
66700+* This routine returns the received data to the caller. There is no
66701+* data copying during routine operation. All information is returned
66702+* using pointer to packet information struct passed from the caller.
66703+*
66704+* INPUT:
66705+* void* pEthPortHndl - Ethernet Port handler.
66706+* int rxQueue - Number of Rx queue.
66707+*
66708+* OUTPUT:
66709+* MV_PKT_INFO *pPktInfo - Pointer to received packet.
66710+*
66711+* RETURN:
66712+* MV_NO_RESOURCE - No free resources in RX queue.
66713+* MV_ERROR - Unexpected Fatal error.
66714+* MV_OK - New packet received and 'pBufInfo' structure filled
66715+* with relevant information.
66716+*
66717+*******************************************************************************/
66718+static INLINE MV_PKT_INFO* mvEthPortRx(void* pEthPortHndl, int rxQueue)
66719+{
66720+ ETH_RX_DESC *pRxCurrDesc;
66721+ MV_U32 commandStatus;
66722+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
66723+ ETH_QUEUE_CTRL* pQueueCtrl;
66724+ MV_PKT_INFO* pPktInfo;
66725+
66726+ pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);
66727+
66728+ /* Check resources */
66729+ if(pQueueCtrl->resource == 0)
66730+ {
66731+ mvOsPrintf("ethPortRx: no more resources\n");
66732+ return NULL;
66733+ }
66734+ while(MV_TRUE)
66735+ {
66736+ /* Get the Rx Desc ring 'curr and 'used' indexes */
66737+ pRxCurrDesc = pQueueCtrl->pCurrentDescr;
66738+
66739+ commandStatus = pRxCurrDesc->cmdSts;
66740+ if (commandStatus & (ETH_BUFFER_OWNED_BY_DMA))
66741+ {
66742+ /* Nothing to receive... */
66743+ ETH_DESCR_INV(pPortCtrl, pRxCurrDesc);
66744+ return NULL;
66745+ }
66746+
66747+ /* Valid RX only if FIRST and LAST bits are set */
66748+ if( (commandStatus & (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK)) ==
66749+ (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK) )
66750+ {
66751+ pPktInfo = (MV_PKT_INFO*)pRxCurrDesc->returnInfo;
66752+ pPktInfo->pFrags->dataSize = pRxCurrDesc->byteCnt - 4;
66753+ pPktInfo->status = commandStatus;
66754+ pPktInfo->fragIP = pRxCurrDesc->bufSize & ETH_RX_IP_FRAGMENTED_FRAME_MASK;
66755+
66756+ pQueueCtrl->resource--;
66757+ /* Update 'curr' in data structure */
66758+ pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);
66759+
66760+#ifdef INCLUDE_SYNC_BARR
66761+ mvCpuIfSyncBarr(DRAM_TARGET);
66762+#endif
66763+ return pPktInfo;
66764+ }
66765+ else
66766+ {
66767+ ETH_RX_DESC* pRxUsedDesc = pQueueCtrl->pUsedDescr;
66768+
66769+#ifdef ETH_DEBUG
66770+ mvOsPrintf("ethDrv: Unexpected Jumbo frame: "
66771+ "status=0x%08x, byteCnt=%d, pData=0x%x\n",
66772+ commandStatus, pRxCurrDesc->byteCnt, pRxCurrDesc->bufPtr);
66773+#endif /* ETH_DEBUG */
66774+
66775+ /* move buffer from pCurrentDescr position to pUsedDescr position */
66776+ pRxUsedDesc->bufPtr = pRxCurrDesc->bufPtr;
66777+ pRxUsedDesc->returnInfo = pRxCurrDesc->returnInfo;
66778+ pRxUsedDesc->bufSize = pRxCurrDesc->bufSize & ETH_RX_BUFFER_MASK;
66779+
66780+ /* Return the descriptor to DMA ownership */
66781+ pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA |
66782+ ETH_RX_ENABLE_INTERRUPT_MASK;
66783+
66784+ /* Flush descriptor and CPU pipe */
66785+ ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);
66786+
66787+ /* Move the used descriptor pointer to the next descriptor */
66788+ pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);
66789+ pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);
66790+ }
66791+ }
66792+}
66793+
66794+/*******************************************************************************
66795+* mvEthPortRxDone - Returns a Rx buffer back to the Rx ring.
66796+*
66797+* DESCRIPTION:
66798+* This routine returns a Rx buffer back to the Rx ring.
66799+*
66800+* INPUT:
66801+* void* pEthPortHndl - Ethernet Port handler.
66802+* int rxQueue - Number of Rx queue.
66803+* MV_PKT_INFO *pPktInfo - Pointer to received packet.
66804+*
66805+* RETURN:
66806+* MV_ERROR - Unexpected Fatal error.
66807+* MV_OUT_OF_RANGE - RX queue is already FULL, so this buffer can't be
66808+* returned to this queue.
66809+* MV_FULL - Buffer returned successfully and RX queue became full.
66810+* More buffers should not be returned at the time.
66811+* MV_OK - Buffer returned successfully and there are more free
66812+* places in the queue.
66813+*
66814+*******************************************************************************/
66815+static INLINE MV_STATUS mvEthPortRxDone(void* pEthPortHndl, int rxQueue, MV_PKT_INFO *pPktInfo)
66816+{
66817+ ETH_RX_DESC* pRxUsedDesc;
66818+ ETH_QUEUE_CTRL* pQueueCtrl;
66819+ ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
66820+
66821+ pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
66822+
66823+ /* Get 'used' Rx descriptor */
66824+ pRxUsedDesc = pQueueCtrl->pUsedDescr;
66825+
66826+ /* Check that ring is not FULL */
66827+ if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
66828+ (pQueueCtrl->resource != 0) )
66829+ {
66830+ mvOsPrintf("%s %d: out of range Error resource=%d, curr=%p, used=%p\n",
66831+ __FUNCTION__, pPortCtrl->portNo, pQueueCtrl->resource,
66832+ pQueueCtrl->pCurrentDescr, pQueueCtrl->pUsedDescr);
66833+ return MV_OUT_OF_RANGE;
66834+ }
66835+
66836+ pRxUsedDesc->bufPtr = pPktInfo->pFrags->bufPhysAddr;
66837+ pRxUsedDesc->returnInfo = (MV_ULONG)pPktInfo;
66838+ pRxUsedDesc->bufSize = pPktInfo->pFrags->bufSize & ETH_RX_BUFFER_MASK;
66839+
66840+ /* Invalidate data buffer accordingly with pktSize */
66841+ if(pPktInfo->pktSize != 0)
66842+ {
66843+ ETH_PACKET_CACHE_INVALIDATE(pPktInfo->pFrags->bufVirtPtr, pPktInfo->pktSize);
66844+ pPktInfo->pktSize = 0;
66845+ }
66846+
66847+ /* Return the descriptor to DMA ownership */
66848+ pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT_MASK;
66849+
66850+ /* Flush descriptor and CPU pipe */
66851+ ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);
66852+
66853+ pQueueCtrl->resource++;
66854+
66855+ /* Move the used descriptor pointer to the next descriptor */
66856+ pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);
66857+
66858+ /* If ring became Full return MV_FULL */
66859+ if(pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr)
66860+ return MV_FULL;
66861+
66862+ return MV_OK;
66863+}
66864+
66865+
66866+#endif /* __mvEthGbe_h__ */
66867+
66868+
66869diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h b/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h
66870new file mode 100644
66871index 0000000..0f57ee7
66872--- /dev/null
66873+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h
66874@@ -0,0 +1,700 @@
66875+/*******************************************************************************
66876+Copyright (C) Marvell International Ltd. and its affiliates
66877+
66878+This software file (the "File") is owned and distributed by Marvell
66879+International Ltd. and/or its affiliates ("Marvell") under the following
66880+alternative licensing terms. Once you have made an election to distribute the
66881+File under one of the following license alternatives, please (i) delete this
66882+introductory statement regarding license alternatives, (ii) delete the two
66883+license alternatives that you have not elected to use and (iii) preserve the
66884+Marvell copyright notice above.
66885+
66886+********************************************************************************
66887+Marvell Commercial License Option
66888+
66889+If you received this File from Marvell and you have entered into a commercial
66890+license agreement (a "Commercial License") with Marvell, the File is licensed
66891+to you under the terms of the applicable Commercial License.
66892+
66893+********************************************************************************
66894+Marvell GPL License Option
66895+
66896+If you received this File from Marvell, you may opt to use, redistribute and/or
66897+modify this File in accordance with the terms and conditions of the General
66898+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
66899+available along with the File in the license.txt file or by writing to the Free
66900+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
66901+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
66902+
66903+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
66904+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
66905+DISCLAIMED. The GPL License provides additional details about this warranty
66906+disclaimer.
66907+********************************************************************************
66908+Marvell BSD License Option
66909+
66910+If you received this File from Marvell, you may opt to use, redistribute and/or
66911+modify this File under the following licensing terms.
66912+Redistribution and use in source and binary forms, with or without modification,
66913+are permitted provided that the following conditions are met:
66914+
66915+ * Redistributions of source code must retain the above copyright notice,
66916+ this list of conditions and the following disclaimer.
66917+
66918+ * Redistributions in binary form must reproduce the above copyright
66919+ notice, this list of conditions and the following disclaimer in the
66920+ documentation and/or other materials provided with the distribution.
66921+
66922+ * Neither the name of Marvell nor the names of its contributors may be
66923+ used to endorse or promote products derived from this software without
66924+ specific prior written permission.
66925+
66926+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
66927+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
66928+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66929+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
66930+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
66931+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
66932+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
66933+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
66934+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
66935+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
66936+
66937+*******************************************************************************/
66938+
66939+
66940+#ifndef __INCmvEthRegsh
66941+#define __INCmvEthRegsh
66942+
66943+#ifdef __cplusplus
66944+extern "C" {
66945+#endif /* __cplusplus */
66946+
66947+#include "ctrlEnv/mvCtrlEnvSpec.h"
66948+
66949+/****************************************/
66950+/* Ethernet Unit Registers */
66951+/****************************************/
66952+#define ETH_REG_BASE MV_ETH_REG_BASE
66953+
66954+#define ETH_PHY_ADDR_REG(port) (ETH_REG_BASE(port) + 0x000)
66955+#define ETH_SMI_REG(port) (ETH_REG_BASE(port) + 0x004)
66956+#define ETH_UNIT_DEF_ADDR_REG(port) (ETH_REG_BASE(port) + 0x008)
66957+#define ETH_UNIT_DEF_ID_REG(port) (ETH_REG_BASE(port) + 0x00c)
66958+#define ETH_UNIT_RESERVED(port) (ETH_REG_BASE(port) + 0x014)
66959+#define ETH_UNIT_INTR_CAUSE_REG(port) (ETH_REG_BASE(port) + 0x080)
66960+#define ETH_UNIT_INTR_MASK_REG(port) (ETH_REG_BASE(port) + 0x084)
66961+
66962+
66963+#define ETH_UNIT_ERROR_ADDR_REG(port) (ETH_REG_BASE(port) + 0x094)
66964+#define ETH_UNIT_INT_ADDR_ERROR_REG(port) (ETH_REG_BASE(port) + 0x098)
66965+#define ETH_UNIT_CONTROL_REG(port) (ETH_REG_BASE(port) + 0x0B0)
66966+
66967+#define ETH_PORT_CONFIG_REG(port) (ETH_REG_BASE(port) + 0x400)
66968+#define ETH_PORT_CONFIG_EXTEND_REG(port) (ETH_REG_BASE(port) + 0x404)
66969+#define ETH_MII_SERIAL_PARAM_REG(port) (ETH_REG_BASE(port) + 0x408)
66970+#define ETH_GMII_SERIAL_PARAM_REG(port) (ETH_REG_BASE(port) + 0x40c)
66971+#define ETH_VLAN_ETHER_TYPE_REG(port) (ETH_REG_BASE(port) + 0x410)
66972+#define ETH_MAC_ADDR_LOW_REG(port) (ETH_REG_BASE(port) + 0x414)
66973+#define ETH_MAC_ADDR_HIGH_REG(port) (ETH_REG_BASE(port) + 0x418)
66974+#define ETH_SDMA_CONFIG_REG(port) (ETH_REG_BASE(port) + 0x41c)
66975+#define ETH_DIFF_SERV_PRIO_REG(port, code) (ETH_REG_BASE(port) + 0x420 + ((code)<<2))
66976+#define ETH_PORT_SERIAL_CTRL_REG(port) (ETH_REG_BASE(port) + 0x43c)
66977+#define ETH_VLAN_TAG_TO_PRIO_REG(port) (ETH_REG_BASE(port) + 0x440)
66978+#define ETH_PORT_STATUS_REG(port) (ETH_REG_BASE(port) + 0x444)
66979+
66980+#define ETH_RX_QUEUE_COMMAND_REG(port) (ETH_REG_BASE(port) + 0x680)
66981+#define ETH_TX_QUEUE_COMMAND_REG(port) (ETH_REG_BASE(port) + 0x448)
66982+
66983+#define ETH_PORT_SERIAL_CTRL_1_REG(port) (ETH_REG_BASE(port) + 0x44c)
66984+#define ETH_PORT_STATUS_1_REG(port) (ETH_REG_BASE(port) + 0x450)
66985+#define ETH_PORT_MARVELL_HEADER_REG(port) (ETH_REG_BASE(port) + 0x454)
66986+#define ETH_PORT_FIFO_PARAMS_REG(port) (ETH_REG_BASE(port) + 0x458)
66987+#define ETH_MAX_TOKEN_BUCKET_SIZE_REG(port) (ETH_REG_BASE(port) + 0x45c)
66988+#define ETH_INTR_CAUSE_REG(port) (ETH_REG_BASE(port) + 0x460)
66989+#define ETH_INTR_CAUSE_EXT_REG(port) (ETH_REG_BASE(port) + 0x464)
66990+#define ETH_INTR_MASK_REG(port) (ETH_REG_BASE(port) + 0x468)
66991+#define ETH_INTR_MASK_EXT_REG(port) (ETH_REG_BASE(port) + 0x46c)
66992+#define ETH_TX_FIFO_URGENT_THRESH_REG(port) (ETH_REG_BASE(port) + 0x474)
66993+#define ETH_RX_MINIMAL_FRAME_SIZE_REG(port) (ETH_REG_BASE(port) + 0x47c)
66994+#define ETH_RX_DISCARD_PKTS_CNTR_REG(port) (ETH_REG_BASE(port) + 0x484)
66995+#define ETH_RX_OVERRUN_PKTS_CNTR_REG(port) (ETH_REG_BASE(port) + 0x488)
66996+#define ETH_INTERNAL_ADDR_ERROR_REG(port) (ETH_REG_BASE(port) + 0x494)
66997+#define ETH_TX_FIXED_PRIO_CFG_REG(port) (ETH_REG_BASE(port) + 0x4dc)
66998+#define ETH_TX_TOKEN_RATE_CFG_REG(port) (ETH_REG_BASE(port) + 0x4e0)
66999+#define ETH_TX_QUEUE_COMMAND1_REG(port) (ETH_REG_BASE(port) + 0x4e4)
67000+#define ETH_MAX_TRANSMIT_UNIT_REG(port) (ETH_REG_BASE(port) + 0x4e8)
67001+#define ETH_TX_TOKEN_BUCKET_SIZE_REG(port) (ETH_REG_BASE(port) + 0x4ec)
67002+#define ETH_TX_TOKEN_BUCKET_COUNT_REG(port) (ETH_REG_BASE(port) + 0x780)
67003+#define ETH_RX_DESCR_STAT_CMD_REG(port, q) (ETH_REG_BASE(port) + 0x600 + ((q)<<4))
67004+#define ETH_RX_BYTE_COUNT_REG(port, q) (ETH_REG_BASE(port) + 0x604 + ((q)<<4))
67005+#define ETH_RX_BUF_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x608 + ((q)<<4))
67006+#define ETH_RX_CUR_DESC_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x60c + ((q)<<4))
67007+#define ETH_TX_CUR_DESC_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x6c0 + ((q)<<2))
67008+
67009+#define ETH_TXQ_TOKEN_COUNT_REG(port, q) (ETH_REG_BASE(port) + 0x700 + ((q)<<4))
67010+#define ETH_TXQ_TOKEN_CFG_REG(port, q) (ETH_REG_BASE(port) + 0x704 + ((q)<<4))
67011+#define ETH_TXQ_ARBITER_CFG_REG(port, q) (ETH_REG_BASE(port) + 0x708 + ((q)<<4))
67012+
67013+#if (MV_ETH_VERSION >= 4)
67014+#define ETH_TXQ_CMD_1_REG(port) (ETH_REG_BASE(port) + 0x4E4)
67015+#define ETH_EJP_TX_HI_IPG_REG(port) (ETH_REG_BASE(port) + 0x7A8)
67016+#define ETH_EJP_TX_LO_IPG_REG(port) (ETH_REG_BASE(port) + 0x7B8)
67017+#define ETH_EJP_HI_TKN_LO_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C0)
67018+#define ETH_EJP_HI_TKN_ASYNC_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C4)
67019+#define ETH_EJP_LO_TKN_ASYNC_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C8)
67020+#define ETH_EJP_TX_SPEED_REG(port) (ETH_REG_BASE(port) + 0x7D0)
67021+#endif /* MV_ETH_VERSION >= 4 */
67022+
67023+#define ETH_MIB_COUNTERS_BASE(port) (ETH_REG_BASE(port) + 0x1000)
67024+#define ETH_DA_FILTER_SPEC_MCAST_BASE(port) (ETH_REG_BASE(port) + 0x1400)
67025+#define ETH_DA_FILTER_OTH_MCAST_BASE(port) (ETH_REG_BASE(port) + 0x1500)
67026+#define ETH_DA_FILTER_UCAST_BASE(port) (ETH_REG_BASE(port) + 0x1600)
67027+
67028+/* Phy address register definitions */
67029+#define ETH_PHY_ADDR_OFFS 0
67030+#define ETH_PHY_ADDR_MASK (0x1f <<ETH_PHY_ADDR_OFFS)
67031+
67032+/* MIB Counters register definitions */
67033+#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW 0x0
67034+#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH 0x4
67035+#define ETH_MIB_BAD_OCTETS_RECEIVED 0x8
67036+#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR 0xc
67037+#define ETH_MIB_GOOD_FRAMES_RECEIVED 0x10
67038+#define ETH_MIB_BAD_FRAMES_RECEIVED 0x14
67039+#define ETH_MIB_BROADCAST_FRAMES_RECEIVED 0x18
67040+#define ETH_MIB_MULTICAST_FRAMES_RECEIVED 0x1c
67041+#define ETH_MIB_FRAMES_64_OCTETS 0x20
67042+#define ETH_MIB_FRAMES_65_TO_127_OCTETS 0x24
67043+#define ETH_MIB_FRAMES_128_TO_255_OCTETS 0x28
67044+#define ETH_MIB_FRAMES_256_TO_511_OCTETS 0x2c
67045+#define ETH_MIB_FRAMES_512_TO_1023_OCTETS 0x30
67046+#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS 0x34
67047+#define ETH_MIB_GOOD_OCTETS_SENT_LOW 0x38
67048+#define ETH_MIB_GOOD_OCTETS_SENT_HIGH 0x3c
67049+#define ETH_MIB_GOOD_FRAMES_SENT 0x40
67050+#define ETH_MIB_EXCESSIVE_COLLISION 0x44
67051+#define ETH_MIB_MULTICAST_FRAMES_SENT 0x48
67052+#define ETH_MIB_BROADCAST_FRAMES_SENT 0x4c
67053+#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED 0x50
67054+#define ETH_MIB_FC_SENT 0x54
67055+#define ETH_MIB_GOOD_FC_RECEIVED 0x58
67056+#define ETH_MIB_BAD_FC_RECEIVED 0x5c
67057+#define ETH_MIB_UNDERSIZE_RECEIVED 0x60
67058+#define ETH_MIB_FRAGMENTS_RECEIVED 0x64
67059+#define ETH_MIB_OVERSIZE_RECEIVED 0x68
67060+#define ETH_MIB_JABBER_RECEIVED 0x6c
67061+#define ETH_MIB_MAC_RECEIVE_ERROR 0x70
67062+#define ETH_MIB_BAD_CRC_EVENT 0x74
67063+#define ETH_MIB_COLLISION 0x78
67064+#define ETH_MIB_LATE_COLLISION 0x7c
67065+
67066+
67067+/****************************************/
67068+/* Ethernet Unit Register BITs */
67069+/****************************************/
67070+
67071+#define ETH_RXQ_ENABLE_OFFSET 0
67072+#define ETH_RXQ_ENABLE_MASK (0x000000FF << ETH_RXQ_ENABLE_OFFSET)
67073+
67074+#define ETH_RXQ_DISABLE_OFFSET 8
67075+#define ETH_RXQ_DISABLE_MASK (0x000000FF << ETH_RXQ_DISABLE_OFFSET)
67076+
67077+/***** BITs of Transmit Queue Command (TQC) register *****/
67078+#define ETH_TXQ_ENABLE_OFFSET 0
67079+#define ETH_TXQ_ENABLE_MASK (0x000000FF << ETH_TXQ_ENABLE_OFFSET)
67080+
67081+#define ETH_TXQ_DISABLE_OFFSET 8
67082+#define ETH_TXQ_DISABLE_MASK (0x000000FF << ETH_TXQ_DISABLE_OFFSET)
67083+
67084+#if (MV_ETH_VERSION >= 4)
67085+#define ETH_TX_EJP_RESET_BIT 0
67086+#define ETH_TX_EJP_RESET_MASK (1 << ETH_TX_EJP_RESET_BIT)
67087+
67088+#define ETH_TX_EJP_ENABLE_BIT 2
67089+#define ETH_TX_EJP_ENABLE_MASK (1 << ETH_TX_EJP_ENABLE_BIT)
67090+
67091+#define ETH_TX_LEGACY_WRR_BIT 3
67092+#define ETH_TX_LEGACY_WRR_MASK (1 << ETH_TX_LEGACY_WRR_BIT)
67093+#endif /* (MV_ETH_VERSION >= 4) */
67094+
67095+/***** BITs of Ethernet Port Status reg (PSR) *****/
67096+#define ETH_LINK_UP_BIT 1
67097+#define ETH_LINK_UP_MASK (1<<ETH_LINK_UP_BIT)
67098+
67099+#define ETH_FULL_DUPLEX_BIT 2
67100+#define ETH_FULL_DUPLEX_MASK (1<<ETH_FULL_DUPLEX_BIT)
67101+
67102+#define ETH_ENABLE_RCV_FLOW_CTRL_BIT 3
67103+#define ETH_ENABLE_RCV_FLOW_CTRL_MASK (1<<ETH_ENABLE_RCV_FLOW_CTRL_BIT)
67104+
67105+#define ETH_GMII_SPEED_1000_BIT 4
67106+#define ETH_GMII_SPEED_1000_MASK (1<<ETH_GMII_SPEED_1000_BIT)
67107+
67108+#define ETH_MII_SPEED_100_BIT 5
67109+#define ETH_MII_SPEED_100_MASK (1<<ETH_MII_SPEED_100_BIT)
67110+
67111+#define ETH_TX_IN_PROGRESS_BIT 7
67112+#define ETH_TX_IN_PROGRESS_MASK (1<<ETH_TX_IN_PROGRESS_BIT)
67113+
67114+#define ETH_TX_FIFO_EMPTY_BIT 10
67115+#define ETH_TX_FIFO_EMPTY_MASK (1<<ETH_TX_FIFO_EMPTY_BIT)
67116+
67117+/***** BITs of Ethernet Port Status 1 reg (PS1R) *****/
67118+#define ETH_AUTO_NEG_DONE_BIT 4
67119+#define ETH_AUTO_NEG_DONE_MASK (1<<ETH_AUTO_NEG_DONE_BIT)
67120+
67121+#define ETH_SERDES_PLL_LOCKED_BIT 6
67122+#define ETH_SERDES_PLL_LOCKED_MASK (1<<ETH_SERDES_PLL_LOCKED_BIT)
67123+
67124+/***** BITs of Port Configuration reg (PxCR) *****/
67125+#define ETH_UNICAST_PROMISCUOUS_MODE_BIT 0
67126+#define ETH_UNICAST_PROMISCUOUS_MODE_MASK (1<<ETH_UNICAST_PROMISCUOUS_MODE_BIT)
67127+
67128+#define ETH_DEF_RX_QUEUE_OFFSET 1
67129+#define ETH_DEF_RX_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_QUEUE_OFFSET)
67130+#define ETH_DEF_RX_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_QUEUE_OFFSET)
67131+
67132+#define ETH_DEF_RX_ARP_QUEUE_OFFSET 4
67133+#define ETH_DEF_RX_ARP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_ARP_QUEUE_OFFSET)
67134+#define ETH_DEF_RX_ARP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_ARP_QUEUE_OFFSET)
67135+
67136+#define ETH_REJECT_NOT_IP_ARP_BCAST_BIT 7
67137+#define ETH_REJECT_NOT_IP_ARP_BCAST_MASK (1<<ETH_REJECT_NOT_IP_ARP_BCAST_BIT)
67138+
67139+#define ETH_REJECT_IP_BCAST_BIT 8
67140+#define ETH_REJECT_IP_BCAST_MASK (1<<ETH_REJECT_IP_BCAST_BIT)
67141+
67142+#define ETH_REJECT_ARP_BCAST_BIT 9
67143+#define ETH_REJECT_ARP_BCAST_MASK (1<<ETH_REJECT_ARP_BCAST_BIT)
67144+
67145+#define ETH_TX_NO_SET_ERROR_SUMMARY_BIT 12
67146+#define ETH_TX_NO_SET_ERROR_SUMMARY_MASK (1<<ETH_TX_NO_SET_ERROR_SUMMARY_BIT)
67147+
67148+#define ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT 14
67149+#define ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK (1<<ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT)
67150+
67151+#define ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT 15
67152+#define ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK (1<<ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT)
67153+
67154+#define ETH_DEF_RX_TCP_QUEUE_OFFSET 16
67155+#define ETH_DEF_RX_TCP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_TCP_QUEUE_OFFSET)
67156+#define ETH_DEF_RX_TCP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_TCP_QUEUE_OFFSET)
67157+
67158+#define ETH_DEF_RX_UDP_QUEUE_OFFSET 19
67159+#define ETH_DEF_RX_UDP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_UDP_QUEUE_OFFSET)
67160+#define ETH_DEF_RX_UDP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_UDP_QUEUE_OFFSET)
67161+
67162+#define ETH_DEF_RX_BPDU_QUEUE_OFFSET 22
67163+#define ETH_DEF_RX_BPDU_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)
67164+#define ETH_DEF_RX_BPDU_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)
67165+
67166+#define ETH_RX_CHECKSUM_MODE_OFFSET 25
67167+#define ETH_RX_CHECKSUM_NO_PSEUDO_HDR (0<<ETH_RX_CHECKSUM_MODE_OFFSET)
67168+#define ETH_RX_CHECKSUM_WITH_PSEUDO_HDR (1<<ETH_RX_CHECKSUM_MODE_OFFSET)
67169+
67170+/***** BITs of Port Configuration Extend reg (PxCXR) *****/
67171+#define ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT 1
67172+#define ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK (1<<ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT)
67173+
67174+#define ETH_TX_DISABLE_GEN_CRC_BIT 3
67175+#define ETH_TX_DISABLE_GEN_CRC_MASK (1<<ETH_TX_DISABLE_GEN_CRC_BIT)
67176+
67177+/***** BITs of Tx/Rx queue command reg (RQCR/TQCR) *****/
67178+#define ETH_QUEUE_ENABLE_OFFSET 0
67179+#define ETH_QUEUE_ENABLE_ALL_MASK (0xFF<<ETH_QUEUE_ENABLE_OFFSET)
67180+#define ETH_QUEUE_ENABLE_MASK(queue) (1<<((queue)+ETH_QUEUE_ENABLE_OFFSET))
67181+
67182+#define ETH_QUEUE_DISABLE_OFFSET 8
67183+#define ETH_QUEUE_DISABLE_ALL_MASK (0xFF<<ETH_QUEUE_DISABLE_OFFSET)
67184+#define ETH_QUEUE_DISABLE_MASK(queue) (1<<((queue)+ETH_QUEUE_DISABLE_OFFSET))
67185+
67186+
67187+/***** BITs of Port Sdma Configuration reg (SDCR) *****/
67188+#define ETH_RX_FRAME_INTERRUPT_BIT 0
67189+#define ETH_RX_FRAME_INTERRUPT_MASK (1<<ETH_RX_FRAME_INTERRUPT_BIT)
67190+
67191+#define ETH_BURST_SIZE_1_64BIT_VALUE 0
67192+#define ETH_BURST_SIZE_2_64BIT_VALUE 1
67193+#define ETH_BURST_SIZE_4_64BIT_VALUE 2
67194+#define ETH_BURST_SIZE_8_64BIT_VALUE 3
67195+#define ETH_BURST_SIZE_16_64BIT_VALUE 4
67196+
67197+#define ETH_RX_BURST_SIZE_OFFSET 1
67198+#define ETH_RX_BURST_SIZE_ALL_MASK (0x7<<ETH_RX_BURST_SIZE_OFFSET)
67199+#define ETH_RX_BURST_SIZE_MASK(burst) ((burst)<<ETH_RX_BURST_SIZE_OFFSET)
67200+
67201+#define ETH_RX_NO_DATA_SWAP_BIT 4
67202+#define ETH_RX_NO_DATA_SWAP_MASK (1<<ETH_RX_NO_DATA_SWAP_BIT)
67203+#define ETH_RX_DATA_SWAP_MASK (0<<ETH_RX_NO_DATA_SWAP_BIT)
67204+
67205+#define ETH_TX_NO_DATA_SWAP_BIT 5
67206+#define ETH_TX_NO_DATA_SWAP_MASK (1<<ETH_TX_NO_DATA_SWAP_BIT)
67207+#define ETH_TX_DATA_SWAP_MASK (0<<ETH_TX_NO_DATA_SWAP_BIT)
67208+
67209+#define ETH_DESC_SWAP_BIT 6
67210+#define ETH_DESC_SWAP_MASK (1<<ETH_DESC_SWAP_BIT)
67211+#define ETH_NO_DESC_SWAP_MASK (0<<ETH_DESC_SWAP_BIT)
67212+
67213+#define ETH_RX_INTR_COAL_OFFSET 7
67214+#define ETH_RX_INTR_COAL_ALL_MASK (0x3fff<<ETH_RX_INTR_COAL_OFFSET)
67215+#define ETH_RX_INTR_COAL_MASK(value) (((value)<<ETH_RX_INTR_COAL_OFFSET) \
67216+ & ETH_RX_INTR_COAL_ALL_MASK)
67217+
67218+#define ETH_TX_BURST_SIZE_OFFSET 22
67219+#define ETH_TX_BURST_SIZE_ALL_MASK (0x7<<ETH_TX_BURST_SIZE_OFFSET)
67220+#define ETH_TX_BURST_SIZE_MASK(burst) ((burst)<<ETH_TX_BURST_SIZE_OFFSET)
67221+
67222+#define ETH_RX_INTR_COAL_MSB_BIT 25
67223+#define ETH_RX_INTR_COAL_MSB_MASK (1<<ETH_RX_INTR_COAL_MSB_BIT)
67224+
67225+/* BITs Port #x Tx FIFO Urgent Threshold (PxTFUT) */
67226+#define ETH_TX_INTR_COAL_OFFSET 4
67227+#define ETH_TX_INTR_COAL_ALL_MASK (0x3fff << ETH_TX_INTR_COAL_OFFSET)
67228+#define ETH_TX_INTR_COAL_MASK(value) (((value) << ETH_TX_INTR_COAL_OFFSET) \
67229+ & ETH_TX_INTR_COAL_ALL_MASK)
67230+
67231+/* BITs of Port Serial Control reg (PSCR) */
67232+#define ETH_PORT_ENABLE_BIT 0
67233+#define ETH_PORT_ENABLE_MASK (1<<ETH_PORT_ENABLE_BIT)
67234+
67235+#define ETH_FORCE_LINK_PASS_BIT 1
67236+#define ETH_FORCE_LINK_PASS_MASK (1<<ETH_FORCE_LINK_PASS_BIT)
67237+
67238+#define ETH_DISABLE_DUPLEX_AUTO_NEG_BIT 2
67239+#define ETH_DISABLE_DUPLEX_AUTO_NEG_MASK (1<<ETH_DISABLE_DUPLEX_AUTO_NEG_BIT)
67240+
67241+#define ETH_DISABLE_FC_AUTO_NEG_BIT 3
67242+#define ETH_DISABLE_FC_AUTO_NEG_MASK (1<<ETH_DISABLE_FC_AUTO_NEG_BIT)
67243+
67244+#define ETH_ADVERTISE_SYM_FC_BIT 4
67245+#define ETH_ADVERTISE_SYM_FC_MASK (1<<ETH_ADVERTISE_SYM_FC_BIT)
67246+
67247+#define ETH_TX_FC_MODE_OFFSET 5
67248+#define ETH_TX_FC_MODE_MASK (3<<ETH_TX_FC_MODE_OFFSET)
67249+#define ETH_TX_FC_NO_PAUSE (0<<ETH_TX_FC_MODE_OFFSET)
67250+#define ETH_TX_FC_SEND_PAUSE (1<<ETH_TX_FC_MODE_OFFSET)
67251+
67252+#define ETH_TX_BP_MODE_OFFSET 7
67253+#define ETH_TX_BP_MODE_MASK (3<<ETH_TX_BP_MODE_OFFSET)
67254+#define ETH_TX_BP_NO_JAM (0<<ETH_TX_BP_MODE_OFFSET)
67255+#define ETH_TX_BP_SEND_JAM (1<<ETH_TX_BP_MODE_OFFSET)
67256+
67257+#define ETH_DO_NOT_FORCE_LINK_FAIL_BIT 10
67258+#define ETH_DO_NOT_FORCE_LINK_FAIL_MASK (1<<ETH_DO_NOT_FORCE_LINK_FAIL_BIT)
67259+
67260+#define ETH_RETRANSMIT_FOREVER_BIT 11
67261+#define ETH_RETRANSMIT_FOREVER_MASK (1<<ETH_RETRANSMIT_FOREVER_BIT)
67262+
67263+#define ETH_DISABLE_SPEED_AUTO_NEG_BIT 13
67264+#define ETH_DISABLE_SPEED_AUTO_NEG_MASK (1<<ETH_DISABLE_SPEED_AUTO_NEG_BIT)
67265+
67266+#define ETH_DTE_ADVERT_BIT 14
67267+#define ETH_DTE_ADVERT_MASK (1<<ETH_DTE_ADVERT_BIT)
67268+
67269+#define ETH_MII_PHY_MODE_BIT 15
67270+#define ETH_MII_PHY_MODE_MAC (0<<ETH_MII_PHY_MODE_BIT)
67271+#define ETH_MII_PHY_MODE_PHY (1<<ETH_MII_PHY_MODE_BIT)
67272+
67273+#define ETH_MII_SOURCE_SYNCH_BIT 16
67274+#define ETH_MII_STANDARD_SYNCH (0<<ETH_MII_SOURCE_SYNCH_BIT)
67275+#define ETH_MII_400Mbps_SYNCH (1<<ETH_MII_SOURCE_CLK_BIT)
67276+
67277+#define ETH_MAX_RX_PACKET_SIZE_OFFSET 17
67278+#define ETH_MAX_RX_PACKET_SIZE_MASK (7<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
67279+#define ETH_MAX_RX_PACKET_1518BYTE (0<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
67280+#define ETH_MAX_RX_PACKET_1522BYTE (1<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
67281+#define ETH_MAX_RX_PACKET_1552BYTE (2<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
67282+#define ETH_MAX_RX_PACKET_9022BYTE (3<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
67283+#define ETH_MAX_RX_PACKET_9192BYTE (4<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
67284+#define ETH_MAX_RX_PACKET_9700BYTE (5<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
67285+
67286+#define ETH_SET_FULL_DUPLEX_BIT 21
67287+#define ETH_SET_FULL_DUPLEX_MASK (1<<ETH_SET_FULL_DUPLEX_BIT)
67288+
67289+#define ETH_SET_FLOW_CTRL_BIT 22
67290+#define ETH_SET_FLOW_CTRL_MASK (1<<ETH_SET_FLOW_CTRL_BIT)
67291+
67292+#define ETH_SET_GMII_SPEED_1000_BIT 23
67293+#define ETH_SET_GMII_SPEED_1000_MASK (1<<ETH_SET_GMII_SPEED_1000_BIT)
67294+
67295+#define ETH_SET_MII_SPEED_100_BIT 24
67296+#define ETH_SET_MII_SPEED_100_MASK (1<<ETH_SET_MII_SPEED_100_BIT)
67297+
67298+/* BITs of Port Serial Control 1 reg (PSC1R) */
67299+#define ETH_PSC_ENABLE_BIT 2
67300+#define ETH_PSC_ENABLE_MASK (1<<ETH_PSC_ENABLE_BIT)
67301+
67302+#define ETH_RGMII_ENABLE_BIT 3
67303+#define ETH_RGMII_ENABLE_MASK (1<<ETH_RGMII_ENABLE_BIT)
67304+
67305+#define ETH_PORT_RESET_BIT 4
67306+#define ETH_PORT_RESET_MASK (1<<ETH_PORT_RESET_BIT)
67307+
67308+#define ETH_INBAND_AUTO_NEG_ENABLE_BIT 6
67309+#define ETH_INBAND_AUTO_NEG_ENABLE_MASK (1<<ETH_INBAND_AUTO_NEG_ENABLE_BIT)
67310+
67311+#define ETH_INBAND_AUTO_NEG_BYPASS_BIT 7
67312+#define ETH_INBAND_AUTO_NEG_BYPASS_MASK (1<<ETH_INBAND_AUTO_NEG_BYPASS_BIT)
67313+
67314+#define ETH_INBAND_AUTO_NEG_START_BIT 8
67315+#define ETH_INBAND_AUTO_NEG_START_MASK (1<<ETH_INBAND_AUTO_NEG_START_BIT)
67316+
67317+#define ETH_PORT_TYPE_BIT 11
67318+#define ETH_PORT_TYPE_1000BasedX_MASK (1<<ETH_PORT_TYPE_BIT)
67319+
67320+#define ETH_SGMII_MODE_BIT 12
67321+#define ETH_1000BaseX_MODE_MASK (0<<ETH_SGMII_MODE_BIT)
67322+#define ETH_SGMII_MODE_MASK (1<<ETH_SGMII_MODE_BIT)
67323+
67324+#define ETH_MGMII_MODE_BIT 13
67325+
67326+#define ETH_EN_MII_ODD_PRE_BIT 22
67327+#define ETH_EN_MII_ODD_PRE_MASK (1<<ETH_EN_MII_ODD_PRE_BIT)
67328+
67329+/* BITs of SDMA Descriptor Command/Status field */
67330+#if defined(MV_CPU_BE)
67331+typedef struct _ethRxDesc
67332+{
67333+ MV_U16 byteCnt ; /* Descriptor buffer byte count */
67334+ MV_U16 bufSize ; /* Buffer size */
67335+ MV_U32 cmdSts ; /* Descriptor command status */
67336+ MV_U32 nextDescPtr; /* Next descriptor pointer */
67337+ MV_U32 bufPtr ; /* Descriptor buffer pointer */
67338+ MV_ULONG returnInfo ; /* User resource return information */
67339+} ETH_RX_DESC;
67340+
67341+typedef struct _ethTxDesc
67342+{
67343+ MV_U16 byteCnt ; /* Descriptor buffer byte count */
67344+ MV_U16 L4iChk ; /* CPU provided TCP Checksum */
67345+ MV_U32 cmdSts ; /* Descriptor command status */
67346+ MV_U32 nextDescPtr; /* Next descriptor pointer */
67347+ MV_U32 bufPtr ; /* Descriptor buffer pointer */
67348+ MV_ULONG returnInfo ; /* User resource return information */
67349+ MV_U8* alignBufPtr; /* Pointer to 8 byte aligned buffer */
67350+} ETH_TX_DESC;
67351+
67352+#elif defined(MV_CPU_LE)
67353+
67354+typedef struct _ethRxDesc
67355+{
67356+ MV_U32 cmdSts ; /* Descriptor command status */
67357+ MV_U16 bufSize ; /* Buffer size */
67358+ MV_U16 byteCnt ; /* Descriptor buffer byte count */
67359+ MV_U32 bufPtr ; /* Descriptor buffer pointer */
67360+ MV_U32 nextDescPtr; /* Next descriptor pointer */
67361+ MV_ULONG returnInfo ; /* User resource return information */
67362+} ETH_RX_DESC;
67363+
67364+typedef struct _ethTxDesc
67365+{
67366+ MV_U32 cmdSts ; /* Descriptor command status */
67367+ MV_U16 L4iChk ; /* CPU provided TCP Checksum */
67368+ MV_U16 byteCnt ; /* Descriptor buffer byte count */
67369+ MV_U32 bufPtr ; /* Descriptor buffer pointer */
67370+ MV_U32 nextDescPtr; /* Next descriptor pointer */
67371+ MV_ULONG returnInfo ; /* User resource return information */
67372+ MV_U8* alignBufPtr; /* Pointer to 32 byte aligned buffer */
67373+} ETH_TX_DESC;
67374+
67375+#else
67376+#error "MV_CPU_BE or MV_CPU_LE must be defined"
67377+#endif /* MV_CPU_BE || MV_CPU_LE */
67378+
67379+/* Buffer offset from buffer pointer */
67380+#define ETH_RX_BUF_OFFSET 0x2
67381+
67382+
67383+/* Tx & Rx descriptor bits */
67384+#define ETH_ERROR_SUMMARY_BIT 0
67385+#define ETH_ERROR_SUMMARY_MASK (1<<ETH_ERROR_SUMMARY_BIT)
67386+
67387+#define ETH_BUFFER_OWNER_BIT 31
67388+#define ETH_BUFFER_OWNED_BY_DMA (1<<ETH_BUFFER_OWNER_BIT)
67389+#define ETH_BUFFER_OWNED_BY_HOST (0<<ETH_BUFFER_OWNER_BIT)
67390+
67391+/* Tx descriptor bits */
67392+#define ETH_TX_ERROR_CODE_OFFSET 1
67393+#define ETH_TX_ERROR_CODE_MASK (3<<ETH_TX_ERROR_CODE_OFFSET)
67394+#define ETH_TX_LATE_COLLISION_ERROR (0<<ETH_TX_ERROR_CODE_OFFSET)
67395+#define ETH_TX_UNDERRUN_ERROR (1<<ETH_TX_ERROR_CODE_OFFSET)
67396+#define ETH_TX_EXCESSIVE_COLLISION_ERROR (2<<ETH_TX_ERROR_CODE_OFFSET)
67397+
67398+#define ETH_TX_LLC_SNAP_FORMAT_BIT 9
67399+#define ETH_TX_LLC_SNAP_FORMAT_MASK (1<<ETH_TX_LLC_SNAP_FORMAT_BIT)
67400+
67401+#define ETH_TX_IP_FRAG_BIT 10
67402+#define ETH_TX_IP_FRAG_MASK (1<<ETH_TX_IP_FRAG_BIT)
67403+#define ETH_TX_IP_FRAG (0<<ETH_TX_IP_FRAG_BIT)
67404+#define ETH_TX_IP_NO_FRAG (1<<ETH_TX_IP_FRAG_BIT)
67405+
67406+#define ETH_TX_IP_HEADER_LEN_OFFSET 11
67407+#define ETH_TX_IP_HEADER_LEN_ALL_MASK (0xF<<ETH_TX_IP_HEADER_LEN_OFFSET)
67408+#define ETH_TX_IP_HEADER_LEN_MASK(len) ((len)<<ETH_TX_IP_HEADER_LEN_OFFSET)
67409+
67410+#define ETH_TX_VLAN_TAGGED_FRAME_BIT 15
67411+#define ETH_TX_VLAN_TAGGED_FRAME_MASK (1<<ETH_TX_VLAN_TAGGED_FRAME_BIT)
67412+
67413+#define ETH_TX_L4_TYPE_BIT 16
67414+#define ETH_TX_L4_TCP_TYPE (0<<ETH_TX_L4_TYPE_BIT)
67415+#define ETH_TX_L4_UDP_TYPE (1<<ETH_TX_L4_TYPE_BIT)
67416+
67417+#define ETH_TX_GENERATE_L4_CHKSUM_BIT 17
67418+#define ETH_TX_GENERATE_L4_CHKSUM_MASK (1<<ETH_TX_GENERATE_L4_CHKSUM_BIT)
67419+
67420+#define ETH_TX_GENERATE_IP_CHKSUM_BIT 18
67421+#define ETH_TX_GENERATE_IP_CHKSUM_MASK (1<<ETH_TX_GENERATE_IP_CHKSUM_BIT)
67422+
67423+#define ETH_TX_ZERO_PADDING_BIT 19
67424+#define ETH_TX_ZERO_PADDING_MASK (1<<ETH_TX_ZERO_PADDING_BIT)
67425+
67426+#define ETH_TX_LAST_DESC_BIT 20
67427+#define ETH_TX_LAST_DESC_MASK (1<<ETH_TX_LAST_DESC_BIT)
67428+
67429+#define ETH_TX_FIRST_DESC_BIT 21
67430+#define ETH_TX_FIRST_DESC_MASK (1<<ETH_TX_FIRST_DESC_BIT)
67431+
67432+#define ETH_TX_GENERATE_CRC_BIT 22
67433+#define ETH_TX_GENERATE_CRC_MASK (1<<ETH_TX_GENERATE_CRC_BIT)
67434+
67435+#define ETH_TX_ENABLE_INTERRUPT_BIT 23
67436+#define ETH_TX_ENABLE_INTERRUPT_MASK (1<<ETH_TX_ENABLE_INTERRUPT_BIT)
67437+
67438+#define ETH_TX_AUTO_MODE_BIT 30
67439+#define ETH_TX_AUTO_MODE_MASK (1<<ETH_TX_AUTO_MODE_BIT)
67440+
67441+
67442+/* Rx descriptor bits */
67443+#define ETH_RX_ERROR_CODE_OFFSET 1
67444+#define ETH_RX_ERROR_CODE_MASK (3<<ETH_RX_ERROR_CODE_OFFSET)
67445+#define ETH_RX_CRC_ERROR (0<<ETH_RX_ERROR_CODE_OFFSET)
67446+#define ETH_RX_OVERRUN_ERROR (1<<ETH_RX_ERROR_CODE_OFFSET)
67447+#define ETH_RX_MAX_FRAME_LEN_ERROR (2<<ETH_RX_ERROR_CODE_OFFSET)
67448+#define ETH_RX_RESOURCE_ERROR (3<<ETH_RX_ERROR_CODE_OFFSET)
67449+
67450+#define ETH_RX_L4_CHECKSUM_OFFSET 3
67451+#define ETH_RX_L4_CHECKSUM_MASK (0xffff<<ETH_RX_L4_CHECKSUM_OFFSET)
67452+
67453+#define ETH_RX_VLAN_TAGGED_FRAME_BIT 19
67454+#define ETH_RX_VLAN_TAGGED_FRAME_MASK (1<<ETH_RX_VLAN_TAGGED_FRAME_BIT)
67455+
67456+#define ETH_RX_BPDU_FRAME_BIT 20
67457+#define ETH_RX_BPDU_FRAME_MASK (1<<ETH_RX_BPDU_FRAME_BIT)
67458+
67459+#define ETH_RX_L4_TYPE_OFFSET 21
67460+#define ETH_RX_L4_TYPE_MASK (3<<ETH_RX_L4_TYPE_OFFSET)
67461+#define ETH_RX_L4_TCP_TYPE (0<<ETH_RX_L4_TYPE_OFFSET)
67462+#define ETH_RX_L4_UDP_TYPE (1<<ETH_RX_L4_TYPE_OFFSET)
67463+#define ETH_RX_L4_OTHER_TYPE (2<<ETH_RX_L4_TYPE_OFFSET)
67464+
67465+#define ETH_RX_NOT_LLC_SNAP_FORMAT_BIT 23
67466+#define ETH_RX_NOT_LLC_SNAP_FORMAT_MASK (1<<ETH_RX_NOT_LLC_SNAP_FORMAT_BIT)
67467+
67468+#define ETH_RX_IP_FRAME_TYPE_BIT 24
67469+#define ETH_RX_IP_FRAME_TYPE_MASK (1<<ETH_RX_IP_FRAME_TYPE_BIT)
67470+
67471+#define ETH_RX_IP_HEADER_OK_BIT 25
67472+#define ETH_RX_IP_HEADER_OK_MASK (1<<ETH_RX_IP_HEADER_OK_BIT)
67473+
67474+#define ETH_RX_LAST_DESC_BIT 26
67475+#define ETH_RX_LAST_DESC_MASK (1<<ETH_RX_LAST_DESC_BIT)
67476+
67477+#define ETH_RX_FIRST_DESC_BIT 27
67478+#define ETH_RX_FIRST_DESC_MASK (1<<ETH_RX_FIRST_DESC_BIT)
67479+
67480+#define ETH_RX_UNKNOWN_DA_BIT 28
67481+#define ETH_RX_UNKNOWN_DA_MASK (1<<ETH_RX_UNKNOWN_DA_BIT)
67482+
67483+#define ETH_RX_ENABLE_INTERRUPT_BIT 29
67484+#define ETH_RX_ENABLE_INTERRUPT_MASK (1<<ETH_RX_ENABLE_INTERRUPT_BIT)
67485+
67486+#define ETH_RX_L4_CHECKSUM_OK_BIT 30
67487+#define ETH_RX_L4_CHECKSUM_OK_MASK (1<<ETH_RX_L4_CHECKSUM_OK_BIT)
67488+
67489+/* Rx descriptor bufSize field */
67490+#define ETH_RX_IP_FRAGMENTED_FRAME_BIT 2
67491+#define ETH_RX_IP_FRAGMENTED_FRAME_MASK (1<<ETH_RX_IP_FRAGMENTED_FRAME_BIT)
67492+
67493+#define ETH_RX_BUFFER_MASK 0xFFF8
67494+
67495+
67496+/* Ethernet Cause Register BITs */
67497+#define ETH_CAUSE_RX_READY_SUM_BIT 0
67498+#define ETH_CAUSE_EXTEND_BIT 1
67499+
67500+#define ETH_CAUSE_RX_READY_OFFSET 2
67501+#define ETH_CAUSE_RX_READY_BIT(queue) (ETH_CAUSE_RX_READY_OFFSET + (queue))
67502+#define ETH_CAUSE_RX_READY_MASK(queue) (1 << (ETH_CAUSE_RX_READY_BIT(queue)))
67503+
67504+#define ETH_CAUSE_RX_ERROR_SUM_BIT 10
67505+#define ETH_CAUSE_RX_ERROR_OFFSET 11
67506+#define ETH_CAUSE_RX_ERROR_BIT(queue) (ETH_CAUSE_RX_ERROR_OFFSET + (queue))
67507+#define ETH_CAUSE_RX_ERROR_MASK(queue) (1 << (ETH_CAUSE_RX_ERROR_BIT(queue)))
67508+
67509+#define ETH_CAUSE_TX_END_BIT 19
67510+#define ETH_CAUSE_SUM_BIT 31
67511+
67512+/* Ethernet Cause Extended Register BITs */
67513+#define ETH_CAUSE_TX_BUF_OFFSET 0
67514+#define ETH_CAUSE_TX_BUF_BIT(queue) (ETH_CAUSE_TX_BUF_OFFSET + (queue))
67515+#define ETH_CAUSE_TX_BUF_MASK(queue) (1 << (ETH_CAUSE_TX_BUF_BIT(queue)))
67516+
67517+#define ETH_CAUSE_TX_ERROR_OFFSET 8
67518+#define ETH_CAUSE_TX_ERROR_BIT(queue) (ETH_CAUSE_TX_ERROR_OFFSET + (queue))
67519+#define ETH_CAUSE_TX_ERROR_MASK(queue) (1 << (ETH_CAUSE_TX_ERROR_BIT(queue)))
67520+
67521+#define ETH_CAUSE_PHY_STATUS_CHANGE_BIT 16
67522+#define ETH_CAUSE_RX_OVERRUN_BIT 18
67523+#define ETH_CAUSE_TX_UNDERRUN_BIT 19
67524+#define ETH_CAUSE_LINK_STATE_CHANGE_BIT 20
67525+#define ETH_CAUSE_INTERNAL_ADDR_ERR_BIT 23
67526+#define ETH_CAUSE_EXTEND_SUM_BIT 31
67527+
67528+/* Marvell Header Register */
67529+/* Marvell Header register bits */
67530+#define ETH_MVHDR_EN_BIT 0
67531+#define ETH_MVHDR_EN_MASK (1 << ETH_MVHDR_EN_BIT)
67532+
67533+#define ETH_MVHDR_DAPREFIX_BIT 1
67534+#define ETH_MVHDR_DAPREFIX_MASK (0x3 << ETH_MVHDR_DAPREFIX_BIT)
67535+#define ETH_MVHDR_DAPREFIX_PRI_1_2 (0x1 << ETH_MVHDR_DAPREFIX_BIT)
67536+#define ETH_MVHDR_DAPREFIX_DBNUM_PRI (0x2 << ETH_MVHDR_DAPREFIX_BIT)
67537+#define ETH_MVHDR_DAPREFIX_SPID_PRI (0x3 << ETH_MVHDR_DAPREFIX_BIT)
67538+
67539+#define ETH_MVHDR_MHMASK_BIT 8
67540+#define ETH_MVHDR_MHMASK_MASK (0x3 << ETH_MVHDR_MHMASK_BIT)
67541+#define ETH_MVHDR_MHMASK_8_QUEUE (0x0 << ETH_MVHDR_MHMASK_BIT)
67542+#define ETH_MVHDR_MHMASK_4_QUEUE (0x1 << ETH_MVHDR_MHMASK_BIT)
67543+#define ETH_MVHDR_MHMASK_2_QUEUE (0x3 << ETH_MVHDR_MHMASK_BIT)
67544+
67545+
67546+/* Relevant for 6183 ONLY */
67547+#define ETH_UNIT_PORTS_PADS_CALIB_0_REG (MV_ETH_REG_BASE(0) + 0x0A0)
67548+#define ETH_UNIT_PORTS_PADS_CALIB_1_REG (MV_ETH_REG_BASE(0) + 0x0A4)
67549+#define ETH_UNIT_PORTS_PADS_CALIB_2_REG (MV_ETH_REG_BASE(0) + 0x0A8)
67550+/* Ethernet Unit Ports Pads Calibration_REG (ETH_UNIT_PORTS_PADS_CALIB_x_REG) */
67551+#define ETH_ETHERNET_PAD_CLIB_DRVN_OFFS 0
67552+#define ETH_ETHERNET_PAD_CLIB_DRVN_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_DRVN_OFFS)
67553+
67554+#define ETH_ETHERNET_PAD_CLIB_DRVP_OFFS 5
67555+#define ETH_ETHERNET_PAD_CLIB_DRVP_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_DRVP_OFFS)
67556+
67557+#define ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS 16
67558+#define ETH_ETHERNET_PAD_CLIB_TUNEEN_MASK (0x1 << ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS)
67559+
67560+#define ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS 17
67561+#define ETH_ETHERNET_PAD_CLIB_LOCKN_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS)
67562+
67563+#define ETH_ETHERNET_PAD_CLIB_OFFST_OFFS 24
67564+#define ETH_ETHERNET_PAD_CLIB_OFFST_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_OFFST_OFFS)
67565+
67566+#define ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS 31
67567+#define ETH_ETHERNET_PAD_CLIB_WR_EN_MASK (0x1 << ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS)
67568+
67569+
67570+#ifdef __cplusplus
67571+}
67572+#endif /* __cplusplus */
67573+
67574+#endif /* __INCmvEthRegsh */
67575diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h b/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h
67576new file mode 100644
67577index 0000000..30f2a40
67578--- /dev/null
67579+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h
67580@@ -0,0 +1,356 @@
67581+/*******************************************************************************
67582+Copyright (C) Marvell International Ltd. and its affiliates
67583+
67584+This software file (the "File") is owned and distributed by Marvell
67585+International Ltd. and/or its affiliates ("Marvell") under the following
67586+alternative licensing terms. Once you have made an election to distribute the
67587+File under one of the following license alternatives, please (i) delete this
67588+introductory statement regarding license alternatives, (ii) delete the two
67589+license alternatives that you have not elected to use and (iii) preserve the
67590+Marvell copyright notice above.
67591+
67592+********************************************************************************
67593+Marvell Commercial License Option
67594+
67595+If you received this File from Marvell and you have entered into a commercial
67596+license agreement (a "Commercial License") with Marvell, the File is licensed
67597+to you under the terms of the applicable Commercial License.
67598+
67599+********************************************************************************
67600+Marvell GPL License Option
67601+
67602+If you received this File from Marvell, you may opt to use, redistribute and/or
67603+modify this File in accordance with the terms and conditions of the General
67604+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
67605+available along with the File in the license.txt file or by writing to the Free
67606+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
67607+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
67608+
67609+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
67610+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
67611+DISCLAIMED. The GPL License provides additional details about this warranty
67612+disclaimer.
67613+********************************************************************************
67614+Marvell BSD License Option
67615+
67616+If you received this File from Marvell, you may opt to use, redistribute and/or
67617+modify this File under the following licensing terms.
67618+Redistribution and use in source and binary forms, with or without modification,
67619+are permitted provided that the following conditions are met:
67620+
67621+ * Redistributions of source code must retain the above copyright notice,
67622+ this list of conditions and the following disclaimer.
67623+
67624+ * Redistributions in binary form must reproduce the above copyright
67625+ notice, this list of conditions and the following disclaimer in the
67626+ documentation and/or other materials provided with the distribution.
67627+
67628+ * Neither the name of Marvell nor the names of its contributors may be
67629+ used to endorse or promote products derived from this software without
67630+ specific prior written permission.
67631+
67632+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
67633+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
67634+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
67635+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
67636+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
67637+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
67638+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
67639+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
67640+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
67641+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67642+
67643+*******************************************************************************/
67644+
67645+/*******************************************************************************
67646+* mvEth.h - Header File for : Ethernet Controller
67647+*
67648+* DESCRIPTION:
67649+* This header file contains macros typedefs and function declaration for
67650+* Marvell Gigabit Ethernet Controllers.
67651+*
67652+* DEPENDENCIES:
67653+* None.
67654+*
67655+*******************************************************************************/
67656+
67657+#ifndef __mvEth_h__
67658+#define __mvEth_h__
67659+
67660+/* includes */
67661+#include "mvTypes.h"
67662+#include "mv802_3.h"
67663+#include "ctrlEnv/mvCtrlEnvLib.h"
67664+#include "ctrlEnv/mvCtrlEnvAddrDec.h"
67665+#include "eth/gbe/mvEthRegs.h"
67666+#include "mvSysHwConfig.h"
67667+
67668+/* defines */
67669+
67670+#define MV_ETH_EXTRA_FRAGS_NUM 2
67671+
67672+
67673+typedef enum
67674+{
67675+ MV_ETH_SPEED_AN,
67676+ MV_ETH_SPEED_10,
67677+ MV_ETH_SPEED_100,
67678+ MV_ETH_SPEED_1000
67679+
67680+} MV_ETH_PORT_SPEED;
67681+
67682+typedef enum
67683+{
67684+ MV_ETH_DUPLEX_AN,
67685+ MV_ETH_DUPLEX_HALF,
67686+ MV_ETH_DUPLEX_FULL
67687+
67688+} MV_ETH_PORT_DUPLEX;
67689+
67690+typedef enum
67691+{
67692+ MV_ETH_FC_AN_ADV_DIS,
67693+ MV_ETH_FC_AN_ADV_SYM,
67694+ MV_ETH_FC_DISABLE,
67695+ MV_ETH_FC_ENABLE
67696+
67697+} MV_ETH_PORT_FC;
67698+
67699+typedef enum
67700+{
67701+ MV_ETH_PRIO_FIXED = 0, /* Fixed priority mode */
67702+ MV_ETH_PRIO_WRR = 1 /* Weighted round robin priority mode */
67703+} MV_ETH_PRIO_MODE;
67704+
67705+/* Ethernet port specific infomation */
67706+typedef struct
67707+{
67708+ int maxRxPktSize;
67709+ int rxDefQ;
67710+ int rxBpduQ;
67711+ int rxArpQ;
67712+ int rxTcpQ;
67713+ int rxUdpQ;
67714+ int ejpMode;
67715+} MV_ETH_PORT_CFG;
67716+
67717+typedef struct
67718+{
67719+ int descrNum;
67720+} MV_ETH_RX_Q_CFG;
67721+
67722+typedef struct
67723+{
67724+ int descrNum;
67725+ MV_ETH_PRIO_MODE prioMode;
67726+ int quota;
67727+} MV_ETH_TX_Q_CFG;
67728+
67729+typedef struct
67730+{
67731+ int maxRxPktSize;
67732+ int rxDefQ;
67733+ int txDescrNum[MV_ETH_TX_Q_NUM];
67734+ int rxDescrNum[MV_ETH_RX_Q_NUM];
67735+ void *osHandle;
67736+} MV_ETH_PORT_INIT;
67737+
67738+typedef struct
67739+{
67740+ MV_BOOL isLinkUp;
67741+ MV_ETH_PORT_SPEED speed;
67742+ MV_ETH_PORT_DUPLEX duplex;
67743+ MV_ETH_PORT_FC flowControl;
67744+
67745+} MV_ETH_PORT_STATUS;
67746+
67747+typedef enum
67748+{
67749+ MV_ETH_DISABLE_HEADER_MODE = 0,
67750+ MV_ETH_ENABLE_HEADER_MODE_PRI_2_1 = 1,
67751+ MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM = 2,
67752+ MV_ETH_ENABLE_HEADER_MODE_PRI_SPID = 3
67753+} MV_ETH_HEADER_MODE;
67754+
67755+
67756+/* ethernet.h API list */
67757+void mvEthHalInit(void);
67758+void mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher);
67759+
67760+/* Port Initalization routines */
67761+void* mvEthPortInit (int port, MV_ETH_PORT_INIT *pPortInit);
67762+void ethResetTxDescRing(void* pPortHndl, int queue);
67763+void ethResetRxDescRing(void* pPortHndl, int queue);
67764+
67765+void* mvEthPortHndlGet(int port);
67766+
67767+void mvEthPortFinish(void* pEthPortHndl);
67768+MV_STATUS mvEthPortDown(void* pEthPortHndl);
67769+MV_STATUS mvEthPortDisable(void* pEthPortHndl);
67770+MV_STATUS mvEthPortUp(void* pEthPortHndl);
67771+MV_STATUS mvEthPortEnable(void* pEthPortHndl);
67772+
67773+/* Port data flow routines */
67774+MV_PKT_INFO *mvEthPortForceTxDone(void* pEthPortHndl, int txQueue);
67775+MV_PKT_INFO *mvEthPortForceRx(void* pEthPortHndl, int rxQueue);
67776+
67777+/* Port Configuration routines */
67778+MV_STATUS mvEthDefaultsSet(void* pEthPortHndl);
67779+MV_STATUS mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize);
67780+
67781+/* Port RX MAC Filtering control routines */
67782+MV_U8 mvEthMcastCrc8Get(MV_U8* pAddr);
67783+MV_STATUS mvEthRxFilterModeSet(void* pPortHndl, MV_BOOL isPromisc);
67784+MV_STATUS mvEthMacAddrSet(void* pPortHandle, MV_U8* pMacAddr, int queue);
67785+MV_STATUS mvEthMcastAddrSet(void* pPortHandle, MV_U8 *pAddr, int queue);
67786+
67787+/* MIB Counters APIs */
67788+MV_U32 mvEthMibCounterRead(void* pPortHndl, unsigned int mibOffset,
67789+ MV_U32* pHigh32);
67790+void mvEthMibCountersClear(void* pPortHandle);
67791+
67792+/* TX Scheduling configuration routines */
67793+MV_STATUS mvEthTxQueueConfig(void* pPortHandle, int txQueue,
67794+ MV_ETH_PRIO_MODE txPrioMode, int txQuota);
67795+
67796+/* RX Dispatching configuration routines */
67797+MV_STATUS mvEthBpduRxQueue(void* pPortHandle, int bpduQueue);
67798+MV_STATUS mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue);
67799+MV_STATUS mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq);
67800+int mvEthTosToRxqGet(void* pPortHandle, int tos);
67801+
67802+/* Speed, Duplex, FlowControl routines */
67803+MV_STATUS mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed,
67804+ MV_ETH_PORT_DUPLEX duplex);
67805+
67806+MV_STATUS mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl);
67807+
67808+#if (MV_ETH_VERSION >= 4)
67809+MV_STATUS mvEthEjpModeSet(void* pPortHandle, int mode);
67810+#endif /* (MV_ETH_VERSION >= 4) */
67811+
67812+void mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus);
67813+
67814+/* Marvell Header control */
67815+MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);
67816+
67817+/* PHY routines */
67818+void mvEthPhyAddrSet(void* pPortHandle, int phyAddr);
67819+int mvEthPhyAddrGet(void* pPortHandle);
67820+
67821+/* Power management routines */
67822+void mvEthPortPowerDown(int port);
67823+void mvEthPortPowerUp(int port);
67824+
67825+/******************** ETH PRIVATE ************************/
67826+
67827+/*#define UNCACHED_TX_BUFFERS*/
67828+/*#define UNCACHED_RX_BUFFERS*/
67829+
67830+
67831+/* Port attributes */
67832+/* Size of a Tx/Rx descriptor used in chain list data structure */
67833+#define ETH_RX_DESC_ALIGNED_SIZE 32
67834+#define ETH_TX_DESC_ALIGNED_SIZE 32
67835+
67836+#define TX_DISABLE_TIMEOUT_MSEC 1000
67837+#define RX_DISABLE_TIMEOUT_MSEC 1000
67838+#define TX_FIFO_EMPTY_TIMEOUT_MSEC 10000
67839+#define PORT_DISABLE_WAIT_TCLOCKS 5000
67840+
67841+/* Macros that save access to desc in order to find next desc pointer */
67842+#define RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl) \
67843+ ((pRxDescr) == (pQueueCtrl)->pLastDescr) ? \
67844+ (ETH_RX_DESC*)((pQueueCtrl)->pFirstDescr) : \
67845+ (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) + ETH_RX_DESC_ALIGNED_SIZE)
67846+
67847+#define TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl) \
67848+ ((pTxDescr) == (pQueueCtrl)->pLastDescr) ? \
67849+ (ETH_TX_DESC*)((pQueueCtrl)->pFirstDescr) : \
67850+ (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) + ETH_TX_DESC_ALIGNED_SIZE)
67851+
67852+#define RX_PREV_DESC_PTR(pRxDescr, pQueueCtrl) \
67853+ ((pRxDescr) == (pQueueCtrl)->pFirstDescr) ? \
67854+ (ETH_RX_DESC*)((pQueueCtrl)->pLastDescr) : \
67855+ (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) - ETH_RX_DESC_ALIGNED_SIZE)
67856+
67857+#define TX_PREV_DESC_PTR(pTxDescr, pQueueCtrl) \
67858+ ((pTxDescr) == (pQueueCtrl)->pFirstDescr) ? \
67859+ (ETH_TX_DESC*)((pQueueCtrl)->pLastDescr) : \
67860+ (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) - ETH_TX_DESC_ALIGNED_SIZE)
67861+
67862+
67863+/* Queue specific information */
67864+typedef struct
67865+{
67866+ void* pFirstDescr;
67867+ void* pLastDescr;
67868+ void* pCurrentDescr;
67869+ void* pUsedDescr;
67870+ int resource;
67871+ MV_BUF_INFO descBuf;
67872+} ETH_QUEUE_CTRL;
67873+
67874+
67875+/* Ethernet port specific infomation */
67876+typedef struct _ethPortCtrl
67877+{
67878+ int portNo;
67879+ ETH_QUEUE_CTRL rxQueue[MV_ETH_RX_Q_NUM]; /* Rx ring resource */
67880+ ETH_QUEUE_CTRL txQueue[MV_ETH_TX_Q_NUM]; /* Tx ring resource */
67881+
67882+ MV_ETH_PORT_CFG portConfig;
67883+ MV_ETH_RX_Q_CFG rxQueueConfig[MV_ETH_RX_Q_NUM];
67884+ MV_ETH_TX_Q_CFG txQueueConfig[MV_ETH_TX_Q_NUM];
67885+
67886+ /* Register images - For DP */
67887+ MV_U32 portTxQueueCmdReg; /* Port active Tx queues summary */
67888+ MV_U32 portRxQueueCmdReg; /* Port active Rx queues summary */
67889+
67890+ MV_STATE portState;
67891+
67892+ MV_U8 mcastCount[256];
67893+ MV_U32* hashPtr;
67894+ void *osHandle;
67895+} ETH_PORT_CTRL;
67896+
67897+/************** MACROs ****************/
67898+
67899+/* MACROs to Flush / Invalidate TX / RX Buffers */
67900+#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_TX_BUFFERS)
67901+# define ETH_PACKET_CACHE_FLUSH(pAddr, size) \
67902+ mvOsCacheClear(NULL, (pAddr), (size)); \
67903+ /*CPU_PIPE_FLUSH;*/
67904+#else
67905+# define ETH_PACKET_CACHE_FLUSH(pAddr, size) \
67906+ mvOsIoVirtToPhy(NULL, (pAddr));
67907+#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW */
67908+
67909+#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_RX_BUFFERS) )
67910+# define ETH_PACKET_CACHE_INVALIDATE(pAddr, size) \
67911+ mvOsCacheInvalidate (NULL, (pAddr), (size)); \
67912+ /*CPU_PIPE_FLUSH;*/
67913+#else
67914+# define ETH_PACKET_CACHE_INVALIDATE(pAddr, size)
67915+#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW && !UNCACHED_RX_BUFFERS */
67916+
67917+#ifdef ETH_DESCR_UNCACHED
67918+
67919+#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr)
67920+#define ETH_DESCR_INV(pPortCtrl, pDescr)
67921+
67922+#else
67923+
67924+#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr) \
67925+ mvOsCacheLineFlushInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))
67926+
67927+#define ETH_DESCR_INV(pPortCtrl, pDescr) \
67928+ mvOsCacheLineInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))
67929+
67930+#endif /* ETH_DESCR_UNCACHED */
67931+
67932+#include "eth/gbe/mvEthGbe.h"
67933+
67934+#endif /* __mvEth_h__ */
67935+
67936+
67937diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c b/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c
67938new file mode 100644
67939index 0000000..d7a5132
67940--- /dev/null
67941+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c
67942@@ -0,0 +1,362 @@
67943+/*******************************************************************************
67944+Copyright (C) Marvell International Ltd. and its affiliates
67945+
67946+This software file (the "File") is owned and distributed by Marvell
67947+International Ltd. and/or its affiliates ("Marvell") under the following
67948+alternative licensing terms. Once you have made an election to distribute the
67949+File under one of the following license alternatives, please (i) delete this
67950+introductory statement regarding license alternatives, (ii) delete the two
67951+license alternatives that you have not elected to use and (iii) preserve the
67952+Marvell copyright notice above.
67953+
67954+********************************************************************************
67955+Marvell Commercial License Option
67956+
67957+If you received this File from Marvell and you have entered into a commercial
67958+license agreement (a "Commercial License") with Marvell, the File is licensed
67959+to you under the terms of the applicable Commercial License.
67960+
67961+********************************************************************************
67962+Marvell GPL License Option
67963+
67964+If you received this File from Marvell, you may opt to use, redistribute and/or
67965+modify this File in accordance with the terms and conditions of the General
67966+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
67967+available along with the File in the license.txt file or by writing to the Free
67968+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
67969+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
67970+
67971+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
67972+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
67973+DISCLAIMED. The GPL License provides additional details about this warranty
67974+disclaimer.
67975+********************************************************************************
67976+Marvell BSD License Option
67977+
67978+If you received this File from Marvell, you may opt to use, redistribute and/or
67979+modify this File under the following licensing terms.
67980+Redistribution and use in source and binary forms, with or without modification,
67981+are permitted provided that the following conditions are met:
67982+
67983+ * Redistributions of source code must retain the above copyright notice,
67984+ this list of conditions and the following disclaimer.
67985+
67986+ * Redistributions in binary form must reproduce the above copyright
67987+ notice, this list of conditions and the following disclaimer in the
67988+ documentation and/or other materials provided with the distribution.
67989+
67990+ * Neither the name of Marvell nor the names of its contributors may be
67991+ used to endorse or promote products derived from this software without
67992+ specific prior written permission.
67993+
67994+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
67995+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
67996+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
67997+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
67998+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
67999+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
68000+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
68001+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
68002+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
68003+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68004+
68005+*******************************************************************************/
68006+
68007+#include "gpp/mvGpp.h"
68008+#include "ctrlEnv/mvCtrlEnvLib.h"
68009+/* defines */
68010+#ifdef MV_DEBUG
68011+ #define DB(x) x
68012+#else
68013+ #define DB(x)
68014+#endif
68015+
68016+static MV_VOID gppRegSet(MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value);
68017+
68018+/*******************************************************************************
68019+* mvGppTypeSet - Enable a GPP (OUT) pin
68020+*
68021+* DESCRIPTION:
68022+*
68023+* INPUT:
68024+* group - GPP group number
68025+* mask - 32bit mask value. Each set bit in the mask means that the type
68026+* of corresponding GPP will be set. Other GPPs are ignored.
68027+* value - 32bit value that describes GPP type per pin.
68028+*
68029+* OUTPUT:
68030+* None.
68031+*
68032+* EXAMPLE:
68033+* Set GPP8 to input and GPP15 to output.
68034+* mvGppTypeSet(0, (GPP8 | GPP15),
68035+* ((MV_GPP_IN & GPP8) | (MV_GPP_OUT & GPP15)) );
68036+*
68037+* RETURN:
68038+* None.
68039+*
68040+*******************************************************************************/
68041+MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value)
68042+{
68043+ if (group >= MV_GPP_MAX_GROUP)
68044+ {
68045+ DB(mvOsPrintf("mvGppTypeSet: ERR. invalid group number \n"));
68046+ return MV_BAD_PARAM;
68047+ }
68048+
68049+ gppRegSet(group, GPP_DATA_OUT_EN_REG(group), mask, value);
68050+
68051+ /* Workaround for Erratum FE-MISC-70*/
68052+ if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))
68053+ {
68054+ mask &= 0x2;
68055+ gppRegSet(0, GPP_DATA_OUT_EN_REG(0), mask, value);
68056+ } /*End of WA*/
68057+
68058+ return MV_OK;
68059+
68060+}
68061+
68062+/*******************************************************************************
68063+* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms
68064+*
68065+* DESCRIPTION:
68066+*
68067+* INPUT:
68068+* group - GPP group number
68069+* mask - 32bit mask value. Each set bit in the mask means that the type
68070+* of corresponding GPP will be set. Other GPPs are ignored.
68071+* value - 32bit value that describes GPP blink per pin.
68072+*
68073+* OUTPUT:
68074+* None.
68075+*
68076+* EXAMPLE:
68077+* Set GPP8 to be static and GPP15 to be blinking.
68078+* mvGppBlinkEn(0, (GPP8 | GPP15),
68079+* ((MV_GPP_OUT_STATIC & GPP8) | (MV_GPP_OUT_BLINK & GPP15)) );
68080+*
68081+* RETURN:
68082+* None.
68083+*
68084+*******************************************************************************/
68085+MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value)
68086+{
68087+ if (group >= MV_GPP_MAX_GROUP)
68088+ {
68089+ DB(mvOsPrintf("mvGppBlinkEn: ERR. invalid group number \n"));
68090+ return MV_BAD_PARAM;
68091+ }
68092+
68093+ gppRegSet(group, GPP_BLINK_EN_REG(group), mask, value);
68094+
68095+ return MV_OK;
68096+
68097+}
68098+/*******************************************************************************
68099+* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode
68100+*
68101+* DESCRIPTION:
68102+*
68103+* INPUT:
68104+* group - GPP group number
68105+* mask - 32bit mask value. Each set bit in the mask means that the type
68106+* of corresponding GPP will be set. Other GPPs are ignored.
68107+* value - 32bit value that describes GPP polarity per pin.
68108+*
68109+* OUTPUT:
68110+* None.
68111+*
68112+* EXAMPLE:
68113+* Set GPP8 to the actual pin value and GPP15 to be inverted.
68114+* mvGppPolaritySet(0, (GPP8 | GPP15),
68115+* ((MV_GPP_IN_ORIGIN & GPP8) | (MV_GPP_IN_INVERT & GPP15)) );
68116+*
68117+* RETURN:
68118+* None.
68119+*
68120+*******************************************************************************/
68121+MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value)
68122+{
68123+ if (group >= MV_GPP_MAX_GROUP)
68124+ {
68125+ DB(mvOsPrintf("mvGppPolaritySet: ERR. invalid group number \n"));
68126+ return MV_BAD_PARAM;
68127+ }
68128+
68129+ gppRegSet(group, GPP_DATA_IN_POL_REG(group), mask, value);
68130+
68131+ return MV_OK;
68132+
68133+}
68134+
68135+/*******************************************************************************
68136+* mvGppPolarityGet - Get a value of relevant bits from GPP Polarity register.
68137+*
68138+* DESCRIPTION:
68139+*
68140+* INPUT:
68141+* group - GPP group number
68142+* mask - 32bit mask value. Each set bit in the mask means that the
68143+* returned value is valid for it.
68144+*
68145+* OUTPUT:
68146+* None.
68147+*
68148+* EXAMPLE:
68149+* Get GPP8 and GPP15 value.
68150+* mvGppPolarityGet(0, (GPP8 | GPP15));
68151+*
68152+* RETURN:
68153+* 32bit value that describes GPP polatity mode per pin.
68154+*
68155+*******************************************************************************/
68156+MV_U32 mvGppPolarityGet(MV_U32 group, MV_U32 mask)
68157+{
68158+ MV_U32 regVal;
68159+
68160+ if (group >= MV_GPP_MAX_GROUP)
68161+ {
68162+ DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));
68163+ return MV_ERROR;
68164+ }
68165+ regVal = MV_REG_READ(GPP_DATA_IN_POL_REG(group));
68166+
68167+ return (regVal & mask);
68168+}
68169+
68170+/*******************************************************************************
68171+* mvGppValueGet - Get a GPP Pin list value.
68172+*
68173+* DESCRIPTION:
68174+* This function get GPP value.
68175+*
68176+* INPUT:
68177+* group - GPP group number
68178+* mask - 32bit mask value. Each set bit in the mask means that the
68179+* returned value is valid for it.
68180+*
68181+* OUTPUT:
68182+* None.
68183+*
68184+* EXAMPLE:
68185+* Get GPP8 and GPP15 value.
68186+* mvGppValueGet(0, (GPP8 | GPP15));
68187+*
68188+* RETURN:
68189+* 32bit value that describes GPP activity mode per pin.
68190+*
68191+*******************************************************************************/
68192+MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask)
68193+{
68194+ MV_U32 gppData;
68195+
68196+ gppData = MV_REG_READ(GPP_DATA_IN_REG(group));
68197+
68198+ gppData &= mask;
68199+
68200+ return gppData;
68201+
68202+}
68203+
68204+/*******************************************************************************
68205+* mvGppValueSet - Set a GPP Pin list value.
68206+*
68207+* DESCRIPTION:
68208+* This function set value for given GPP pin list.
68209+*
68210+* INPUT:
68211+* group - GPP group number
68212+* mask - 32bit mask value. Each set bit in the mask means that the
68213+* value of corresponding GPP will be set accordingly. Other GPP
68214+* are not affected.
68215+* value - 32bit value that describes GPP value per pin.
68216+*
68217+* OUTPUT:
68218+* None.
68219+*
68220+* EXAMPLE:
68221+* Set GPP8 value of '0' and GPP15 value of '1'.
68222+* mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (GPP15)) );
68223+*
68224+* RETURN:
68225+* None.
68226+*
68227+*******************************************************************************/
68228+MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value)
68229+{
68230+ MV_U32 outEnable, tmp;
68231+ MV_U32 i;
68232+
68233+ if (group >= MV_GPP_MAX_GROUP)
68234+ {
68235+ DB(mvOsPrintf("mvGppValueSet: Error invalid group number \n"));
68236+ return MV_BAD_PARAM;
68237+ }
68238+
68239+ /* verify that the gpp pin is configured as output */
68240+ /* Note that in the register out enabled -> bit = '0'. */
68241+ outEnable = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(group));
68242+
68243+ /* Workaround for Erratum FE-MISC-70*/
68244+ if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))
68245+ {
68246+ tmp = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(0));
68247+ outEnable &= 0xfffffffd;
68248+ outEnable |= (tmp & 0x2);
68249+ } /*End of WA*/
68250+
68251+ for (i = 0 ; i < 32 ;i++)
68252+ {
68253+ if (((mask & (1 << i)) & (outEnable & (1 << i))) != (mask & (1 << i)))
68254+ {
68255+ mvOsPrintf("mvGppValueSet: Err. An attempt to set output "\
68256+ "value to GPP %d in input mode.\n", i);
68257+ return MV_ERROR;
68258+ }
68259+ }
68260+
68261+ gppRegSet(group, GPP_DATA_OUT_REG(group), mask, value);
68262+
68263+ return MV_OK;
68264+
68265+}
68266+/*******************************************************************************
68267+* gppRegSet - Set a specific GPP pin on a specific GPP register
68268+*
68269+* DESCRIPTION:
68270+* This function set a specific GPP pin on a specific GPP register
68271+*
68272+* INPUT:
68273+* regOffs - GPP Register offset
68274+* group - GPP group number
68275+* mask - 32bit mask value. Each set bit in the mask means that the
68276+* value of corresponding GPP will be set accordingly. Other GPP
68277+* are not affected.
68278+* value - 32bit value that describes GPP value per pin.
68279+*
68280+* OUTPUT:
68281+* None.
68282+*
68283+* EXAMPLE:
68284+* Set GPP8 value of '0' and GPP15 value of '1'.
68285+* mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (1 & GPP15)) );
68286+*
68287+* RETURN:
68288+* None.
68289+*
68290+*******************************************************************************/
68291+static MV_VOID gppRegSet (MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value)
68292+{
68293+ MV_U32 gppData;
68294+
68295+ gppData = MV_REG_READ(regOffs);
68296+
68297+ gppData &= ~mask;
68298+
68299+ gppData |= (value & mask);
68300+
68301+ MV_REG_WRITE(regOffs, gppData);
68302+}
68303+
68304+
68305diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h b/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h
68306new file mode 100644
68307index 0000000..801472d
68308--- /dev/null
68309+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h
68310@@ -0,0 +1,118 @@
68311+/*******************************************************************************
68312+Copyright (C) Marvell International Ltd. and its affiliates
68313+
68314+This software file (the "File") is owned and distributed by Marvell
68315+International Ltd. and/or its affiliates ("Marvell") under the following
68316+alternative licensing terms. Once you have made an election to distribute the
68317+File under one of the following license alternatives, please (i) delete this
68318+introductory statement regarding license alternatives, (ii) delete the two
68319+license alternatives that you have not elected to use and (iii) preserve the
68320+Marvell copyright notice above.
68321+
68322+********************************************************************************
68323+Marvell Commercial License Option
68324+
68325+If you received this File from Marvell and you have entered into a commercial
68326+license agreement (a "Commercial License") with Marvell, the File is licensed
68327+to you under the terms of the applicable Commercial License.
68328+
68329+********************************************************************************
68330+Marvell GPL License Option
68331+
68332+If you received this File from Marvell, you may opt to use, redistribute and/or
68333+modify this File in accordance with the terms and conditions of the General
68334+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
68335+available along with the File in the license.txt file or by writing to the Free
68336+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
68337+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
68338+
68339+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
68340+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
68341+DISCLAIMED. The GPL License provides additional details about this warranty
68342+disclaimer.
68343+********************************************************************************
68344+Marvell BSD License Option
68345+
68346+If you received this File from Marvell, you may opt to use, redistribute and/or
68347+modify this File under the following licensing terms.
68348+Redistribution and use in source and binary forms, with or without modification,
68349+are permitted provided that the following conditions are met:
68350+
68351+ * Redistributions of source code must retain the above copyright notice,
68352+ this list of conditions and the following disclaimer.
68353+
68354+ * Redistributions in binary form must reproduce the above copyright
68355+ notice, this list of conditions and the following disclaimer in the
68356+ documentation and/or other materials provided with the distribution.
68357+
68358+ * Neither the name of Marvell nor the names of its contributors may be
68359+ used to endorse or promote products derived from this software without
68360+ specific prior written permission.
68361+
68362+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
68363+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
68364+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
68365+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
68366+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68367+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
68368+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
68369+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
68370+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
68371+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68372+
68373+*******************************************************************************/
68374+
68375+#ifndef __INCmvGppH
68376+#define __INCmvGppH
68377+
68378+#include "mvCommon.h"
68379+#include "mvOs.h"
68380+#include "ctrlEnv/mvCtrlEnvSpec.h"
68381+#include "gpp/mvGppRegs.h"
68382+
68383+/* These macros describes the GPP type. Each of the GPPs pins can */
68384+/* be assigned to act as a general purpose input or output pin. */
68385+#define MV_GPP_IN 0xFFFFFFFF /* GPP input */
68386+#define MV_GPP_OUT 0 /* GPP output */
68387+
68388+
68389+/* These macros describes the GPP Out Enable. */
68390+#define MV_GPP_OUT_DIS 0xFFFFFFFF /* Out pin disabled*/
68391+#define MV_GPP_OUT_EN 0 /* Out pin enabled*/
68392+
68393+/* These macros describes the GPP Out Blinking. */
68394+/* When set and the corresponding bit in GPIO Data Out Enable Control */
68395+/* Register is enabled, the GPIO pin blinks every ~100 ms (a period of */
68396+/* 2^24 TCLK clocks). */
68397+#define MV_GPP_OUT_BLINK 0xFFFFFFFF /* Out pin blinking*/
68398+#define MV_GPP_OUT_STATIC 0 /* Out pin static*/
68399+
68400+
68401+/* These macros describes the GPP Polarity. */
68402+/* When set to 1 GPIO Data In Register reflects the inverted value of the */
68403+/* corresponding pin. */
68404+
68405+#define MV_GPP_IN_INVERT 0xFFFFFFFF /* Inverted value is got*/
68406+#define MV_GPP_IN_ORIGIN 0 /* original value is got*/
68407+
68408+/* mvGppTypeSet - Set PP pin mode (IN or OUT) */
68409+MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value);
68410+
68411+/* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms */
68412+MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value);
68413+
68414+/* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode. */
68415+MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value);
68416+
68417+/* mvGppPolarityGet - Get the Polarity of a GPP Pin */
68418+MV_U32 mvGppPolarityGet(MV_U32 group, MV_U32 mask);
68419+
68420+/* mvGppValueGet - Get a GPP Pin list value.*/
68421+MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask);
68422+
68423+
68424+/* mvGppValueSet - Set a GPP Pin list value. */
68425+MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value);
68426+
68427+#endif /* #ifndef __INCmvGppH */
68428+
68429diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h b/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h
68430new file mode 100644
68431index 0000000..14b199f
68432--- /dev/null
68433+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h
68434@@ -0,0 +1,116 @@
68435+/*******************************************************************************
68436+Copyright (C) Marvell International Ltd. and its affiliates
68437+
68438+This software file (the "File") is owned and distributed by Marvell
68439+International Ltd. and/or its affiliates ("Marvell") under the following
68440+alternative licensing terms. Once you have made an election to distribute the
68441+File under one of the following license alternatives, please (i) delete this
68442+introductory statement regarding license alternatives, (ii) delete the two
68443+license alternatives that you have not elected to use and (iii) preserve the
68444+Marvell copyright notice above.
68445+
68446+********************************************************************************
68447+Marvell Commercial License Option
68448+
68449+If you received this File from Marvell and you have entered into a commercial
68450+license agreement (a "Commercial License") with Marvell, the File is licensed
68451+to you under the terms of the applicable Commercial License.
68452+
68453+********************************************************************************
68454+Marvell GPL License Option
68455+
68456+If you received this File from Marvell, you may opt to use, redistribute and/or
68457+modify this File in accordance with the terms and conditions of the General
68458+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
68459+available along with the File in the license.txt file or by writing to the Free
68460+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
68461+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
68462+
68463+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
68464+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
68465+DISCLAIMED. The GPL License provides additional details about this warranty
68466+disclaimer.
68467+********************************************************************************
68468+Marvell BSD License Option
68469+
68470+If you received this File from Marvell, you may opt to use, redistribute and/or
68471+modify this File under the following licensing terms.
68472+Redistribution and use in source and binary forms, with or without modification,
68473+are permitted provided that the following conditions are met:
68474+
68475+ * Redistributions of source code must retain the above copyright notice,
68476+ this list of conditions and the following disclaimer.
68477+
68478+ * Redistributions in binary form must reproduce the above copyright
68479+ notice, this list of conditions and the following disclaimer in the
68480+ documentation and/or other materials provided with the distribution.
68481+
68482+ * Neither the name of Marvell nor the names of its contributors may be
68483+ used to endorse or promote products derived from this software without
68484+ specific prior written permission.
68485+
68486+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
68487+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
68488+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
68489+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
68490+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68491+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
68492+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
68493+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
68494+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
68495+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68496+
68497+*******************************************************************************/
68498+
68499+#ifndef __INCmvGppRegsH
68500+#define __INCmvGppRegsH
68501+
68502+#define MV_GPP0 BIT0
68503+#define MV_GPP1 BIT1
68504+#define MV_GPP2 BIT2
68505+#define MV_GPP3 BIT3
68506+#define MV_GPP4 BIT4
68507+#define MV_GPP5 BIT5
68508+#define MV_GPP6 BIT6
68509+#define MV_GPP7 BIT7
68510+#define MV_GPP8 BIT8
68511+#define MV_GPP9 BIT9
68512+#define MV_GPP10 BIT10
68513+#define MV_GPP11 BIT11
68514+#define MV_GPP12 BIT12
68515+#define MV_GPP13 BIT13
68516+#define MV_GPP14 BIT14
68517+#define MV_GPP15 BIT15
68518+#define MV_GPP16 BIT16
68519+#define MV_GPP17 BIT17
68520+#define MV_GPP18 BIT18
68521+#define MV_GPP19 BIT19
68522+#define MV_GPP20 BIT20
68523+#define MV_GPP21 BIT21
68524+#define MV_GPP22 BIT22
68525+#define MV_GPP23 BIT23
68526+#define MV_GPP24 BIT24
68527+#define MV_GPP25 BIT25
68528+#define MV_GPP26 BIT26
68529+#define MV_GPP27 BIT27
68530+#define MV_GPP28 BIT28
68531+#define MV_GPP29 BIT29
68532+#define MV_GPP30 BIT30
68533+#define MV_GPP31 BIT31
68534+
68535+
68536+/* registers offsets */
68537+
68538+#define GPP_DATA_OUT_REG(grp) ((grp == 0) ? 0x10100 : 0x10140)
68539+#define GPP_DATA_OUT_EN_REG(grp) ((grp == 0) ? 0x10104 : 0x10144)
68540+#define GPP_BLINK_EN_REG(grp) ((grp == 0) ? 0x10108 : 0x10148)
68541+#define GPP_DATA_IN_POL_REG(grp) ((grp == 0) ? 0x1010C : 0x1014c)
68542+#define GPP_DATA_IN_REG(grp) ((grp == 0) ? 0x10110 : 0x10150)
68543+#define GPP_INT_CAUSE_REG(grp) ((grp == 0) ? 0x10114 : 0x10154)
68544+#define GPP_INT_MASK_REG(grp) ((grp == 0) ? 0x10118 : 0x10158)
68545+#define GPP_INT_LVL_REG(grp) ((grp == 0) ? 0x1011c : 0x1015c)
68546+
68547+#define GPP_DATA_OUT_SET_REG 0x10120
68548+#define GPP_DATA_OUT_CLEAR_REG 0x10124
68549+
68550+#endif /* #ifndef __INCmvGppRegsH */
68551diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c b/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c
68552new file mode 100644
68553index 0000000..5ee430c
68554--- /dev/null
68555+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c
68556@@ -0,0 +1,669 @@
68557+/*******************************************************************************
68558+Copyright (C) Marvell International Ltd. and its affiliates
68559+
68560+This software file (the "File") is owned and distributed by Marvell
68561+International Ltd. and/or its affiliates ("Marvell") under the following
68562+alternative licensing terms. Once you have made an election to distribute the
68563+File under one of the following license alternatives, please (i) delete this
68564+introductory statement regarding license alternatives, (ii) delete the two
68565+license alternatives that you have not elected to use and (iii) preserve the
68566+Marvell copyright notice above.
68567+
68568+********************************************************************************
68569+Marvell Commercial License Option
68570+
68571+If you received this File from Marvell and you have entered into a commercial
68572+license agreement (a "Commercial License") with Marvell, the File is licensed
68573+to you under the terms of the applicable Commercial License.
68574+
68575+********************************************************************************
68576+Marvell GPL License Option
68577+
68578+If you received this File from Marvell, you may opt to use, redistribute and/or
68579+modify this File in accordance with the terms and conditions of the General
68580+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
68581+available along with the File in the license.txt file or by writing to the Free
68582+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
68583+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
68584+
68585+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
68586+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
68587+DISCLAIMED. The GPL License provides additional details about this warranty
68588+disclaimer.
68589+********************************************************************************
68590+Marvell BSD License Option
68591+
68592+If you received this File from Marvell, you may opt to use, redistribute and/or
68593+modify this File under the following licensing terms.
68594+Redistribution and use in source and binary forms, with or without modification,
68595+are permitted provided that the following conditions are met:
68596+
68597+ * Redistributions of source code must retain the above copyright notice,
68598+ this list of conditions and the following disclaimer.
68599+
68600+ * Redistributions in binary form must reproduce the above copyright
68601+ notice, this list of conditions and the following disclaimer in the
68602+ documentation and/or other materials provided with the distribution.
68603+
68604+ * Neither the name of Marvell nor the names of its contributors may be
68605+ used to endorse or promote products derived from this software without
68606+ specific prior written permission.
68607+
68608+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
68609+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
68610+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
68611+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
68612+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68613+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
68614+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
68615+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
68616+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
68617+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68618+
68619+*******************************************************************************/
68620+
68621+#include "mvPciIf.h"
68622+#include "ctrlEnv/sys/mvSysPex.h"
68623+
68624+#if defined(MV_INCLUDE_PCI)
68625+#include "ctrlEnv/sys/mvSysPci.h"
68626+#endif
68627+
68628+
68629+/* defines */
68630+#ifdef MV_DEBUG
68631+ #define DB(x) x
68632+#else
68633+ #define DB(x)
68634+#endif
68635+
68636+
68637+/*******************************************************************************
68638+* mvPciInit - Initialize PCI interfaces
68639+*
68640+* DESCRIPTION:
68641+*
68642+* INPUT:
68643+*
68644+*
68645+* OUTPUT:
68646+* None.
68647+*
68648+* RETURN:
68649+* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
68650+*
68651+*******************************************************************************/
68652+
68653+
68654+MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode)
68655+{
68656+ PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
68657+
68658+ if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
68659+ {
68660+ #if defined(MV_INCLUDE_PCI)
68661+
68662+ MV_PCI_MOD pciMod;
68663+
68664+ if (PCI_IF_MODE_HOST == pciIfmode)
68665+ {
68666+ pciMod = MV_PCI_MOD_HOST;
68667+ }
68668+ else if (PCI_IF_MODE_DEVICE == pciIfmode)
68669+ {
68670+ pciMod = MV_PCI_MOD_DEVICE;
68671+ }
68672+ else
68673+ {
68674+ mvOsPrintf("%s: ERROR!!! Bus %d mode %d neither host nor device!\n",
68675+ __FUNCTION__, pciIf, pciIfmode);
68676+ return MV_FAIL;
68677+ }
68678+
68679+ return mvPciInit(pciIf - MV_PCI_START_IF, pciMod);
68680+ #else
68681+ return MV_OK;
68682+ #endif
68683+ }
68684+ else if (PCI_IF_TYPE_PEX == pciIfType)
68685+ {
68686+ #if defined(MV_INCLUDE_PEX)
68687+
68688+ MV_PEX_TYPE pexType;
68689+
68690+ if (PCI_IF_MODE_HOST == pciIfmode)
68691+ {
68692+ pexType = MV_PEX_ROOT_COMPLEX;
68693+ }
68694+ else if (PCI_IF_MODE_DEVICE == pciIfmode)
68695+ {
68696+ pexType = MV_PEX_END_POINT;
68697+ }
68698+ else
68699+ {
68700+ mvOsPrintf("%s: ERROR!!! Bus %d type %d neither root complex nor" \
68701+ " end point\n", __FUNCTION__, pciIf, pciIfmode);
68702+ return MV_FAIL;
68703+ }
68704+ return mvPexInit(pciIf - MV_PEX_START_IF, pexType);
68705+
68706+ #else
68707+ return MV_OK;
68708+ #endif
68709+
68710+ }
68711+ else
68712+ {
68713+ mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
68714+ }
68715+
68716+ return MV_FAIL;
68717+
68718+}
68719+
68720+/* PCI configuration space read write */
68721+
68722+/*******************************************************************************
68723+* mvPciConfigRead - Read from configuration space
68724+*
68725+* DESCRIPTION:
68726+* This function performs a 32 bit read from PCI configuration space.
68727+* It supports both type 0 and type 1 of Configuration Transactions
68728+* (local and over bridge). In order to read from local bus segment, use
68729+* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
68730+* will result configuration transaction of type 1 (over bridge).
68731+*
68732+* INPUT:
68733+* pciIf - PCI interface number.
68734+* bus - PCI segment bus number.
68735+* dev - PCI device number.
68736+* func - Function number.
68737+* regOffs - Register offset.
68738+*
68739+* OUTPUT:
68740+* None.
68741+*
68742+* RETURN:
68743+* 32bit register data, 0xffffffff on error
68744+*
68745+*******************************************************************************/
68746+MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
68747+ MV_U32 regOff)
68748+{
68749+ PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
68750+
68751+ if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
68752+ {
68753+ #if defined(MV_INCLUDE_PCI)
68754+ return mvPciConfigRead(pciIf - MV_PCI_START_IF,
68755+ bus,
68756+ dev,
68757+ func,
68758+ regOff);
68759+ #else
68760+ return 0xffffffff;
68761+ #endif
68762+ }
68763+ else if (PCI_IF_TYPE_PEX == pciIfType)
68764+ {
68765+ #if defined(MV_INCLUDE_PEX)
68766+ return mvPexConfigRead(pciIf - MV_PEX_START_IF,
68767+ bus,
68768+ dev,
68769+ func,
68770+ regOff);
68771+ #else
68772+ return 0xffffffff;
68773+ #endif
68774+
68775+ }
68776+ else
68777+ {
68778+ mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
68779+ }
68780+
68781+ return 0;
68782+
68783+}
68784+
68785+/*******************************************************************************
68786+* mvPciConfigWrite - Write to configuration space
68787+*
68788+* DESCRIPTION:
68789+* This function performs a 32 bit write to PCI configuration space.
68790+* It supports both type 0 and type 1 of Configuration Transactions
68791+* (local and over bridge). In order to write to local bus segment, use
68792+* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
68793+* will result configuration transaction of type 1 (over bridge).
68794+*
68795+* INPUT:
68796+* pciIf - PCI interface number.
68797+* bus - PCI segment bus number.
68798+* dev - PCI device number.
68799+* func - Function number.
68800+* regOffs - Register offset.
68801+* data - 32bit data.
68802+*
68803+* OUTPUT:
68804+* None.
68805+*
68806+* RETURN:
68807+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
68808+*
68809+*******************************************************************************/
68810+MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
68811+ MV_U32 func, MV_U32 regOff, MV_U32 data)
68812+{
68813+ PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
68814+
68815+ if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
68816+ {
68817+ #if defined(MV_INCLUDE_PCI)
68818+ return mvPciConfigWrite(pciIf - MV_PCI_START_IF,
68819+ bus,
68820+ dev,
68821+ func,
68822+ regOff,
68823+ data);
68824+ #else
68825+ return MV_OK;
68826+ #endif
68827+ }
68828+ else if (PCI_IF_TYPE_PEX == pciIfType)
68829+ {
68830+ #if defined(MV_INCLUDE_PEX)
68831+ return mvPexConfigWrite(pciIf - MV_PEX_START_IF,
68832+ bus,
68833+ dev,
68834+ func,
68835+ regOff,
68836+ data);
68837+ #else
68838+ return MV_OK;
68839+ #endif
68840+
68841+ }
68842+ else
68843+ {
68844+ mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
68845+ }
68846+
68847+ return MV_FAIL;
68848+
68849+}
68850+
68851+/*******************************************************************************
68852+* mvPciMasterEnable - Enable/disale PCI interface master transactions.
68853+*
68854+* DESCRIPTION:
68855+* This function performs read modified write to PCI command status
68856+* (offset 0x4) to set/reset bit 2. After this bit is set, the PCI
68857+* master is allowed to gain ownership on the bus, otherwise it is
68858+* incapable to do so.
68859+*
68860+* INPUT:
68861+* pciIf - PCI interface number.
68862+* enable - Enable/disable parameter.
68863+*
68864+* OUTPUT:
68865+* None.
68866+*
68867+* RETURN:
68868+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
68869+*
68870+*******************************************************************************/
68871+MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable)
68872+{
68873+
68874+ PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
68875+
68876+ if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
68877+ {
68878+ #if defined(MV_INCLUDE_PCI)
68879+ return mvPciMasterEnable(pciIf - MV_PCI_START_IF,
68880+ enable);
68881+ #else
68882+ return MV_OK;
68883+ #endif
68884+ }
68885+ else if (PCI_IF_TYPE_PEX == pciIfType)
68886+ {
68887+ #if defined(MV_INCLUDE_PEX)
68888+ return mvPexMasterEnable(pciIf - MV_PEX_START_IF,
68889+ enable);
68890+ #else
68891+ return MV_OK;
68892+ #endif
68893+ }
68894+ else
68895+ {
68896+ mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
68897+ }
68898+
68899+ return MV_FAIL;
68900+
68901+}
68902+
68903+
68904+/*******************************************************************************
68905+* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.
68906+*
68907+* DESCRIPTION:
68908+* This function performs read modified write to PCI command status
68909+* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
68910+* the PCI slave is allowed to respond to PCI IO space access (bit 0)
68911+* and PCI memory space access (bit 1).
68912+*
68913+* INPUT:
68914+* pciIf - PCI interface number.
68915+* dev - PCI device number.
68916+* enable - Enable/disable parameter.
68917+*
68918+* OUTPUT:
68919+* None.
68920+*
68921+* RETURN:
68922+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
68923+*
68924+*******************************************************************************/
68925+MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev, MV_BOOL enable)
68926+{
68927+
68928+ PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
68929+
68930+ if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
68931+ {
68932+ #if defined(MV_INCLUDE_PCI)
68933+ return mvPciSlaveEnable(pciIf - MV_PCI_START_IF,bus,dev,
68934+ enable);
68935+ #else
68936+ return MV_OK;
68937+ #endif
68938+ }
68939+ else if (PCI_IF_TYPE_PEX == pciIfType)
68940+ {
68941+ #if defined(MV_INCLUDE_PEX)
68942+ return mvPexSlaveEnable(pciIf - MV_PEX_START_IF,bus,dev,
68943+ enable);
68944+ #else
68945+ return MV_OK;
68946+ #endif
68947+ }
68948+ else
68949+ {
68950+ mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
68951+ }
68952+
68953+ return MV_FAIL;
68954+
68955+}
68956+
68957+/*******************************************************************************
68958+* mvPciLocalBusNumSet - Set PCI interface local bus number.
68959+*
68960+* DESCRIPTION:
68961+* This function sets given PCI interface its local bus number.
68962+* Note: In case the PCI interface is PCI-X, the information is read-only.
68963+*
68964+* INPUT:
68965+* pciIf - PCI interface number.
68966+* busNum - Bus number.
68967+*
68968+* OUTPUT:
68969+* None.
68970+*
68971+* RETURN:
68972+* MV_NOT_ALLOWED in case PCI interface is PCI-X.
68973+* MV_BAD_PARAM on bad parameters ,
68974+* otherwise MV_OK
68975+*
68976+*******************************************************************************/
68977+MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)
68978+{
68979+ PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
68980+
68981+ if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
68982+ {
68983+ #if defined(MV_INCLUDE_PCI)
68984+ return mvPciLocalBusNumSet(pciIf - MV_PCI_START_IF,
68985+ busNum);
68986+ #else
68987+ return MV_OK;
68988+ #endif
68989+ }
68990+ else if (PCI_IF_TYPE_PEX == pciIfType)
68991+ {
68992+ #if defined(MV_INCLUDE_PEX)
68993+ return mvPexLocalBusNumSet(pciIf - MV_PEX_START_IF,
68994+ busNum);
68995+ #else
68996+ return MV_OK;
68997+ #endif
68998+ }
68999+ else
69000+ {
69001+ mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
69002+ }
69003+
69004+ return MV_FAIL;
69005+
69006+}
69007+
69008+/*******************************************************************************
69009+* mvPciLocalBusNumGet - Get PCI interface local bus number.
69010+*
69011+* DESCRIPTION:
69012+* This function gets the local bus number of a given PCI interface.
69013+*
69014+* INPUT:
69015+* pciIf - PCI interface number.
69016+*
69017+* OUTPUT:
69018+* None.
69019+*
69020+* RETURN:
69021+* Local bus number.0xffffffff on Error
69022+*
69023+*******************************************************************************/
69024+MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf)
69025+{
69026+ PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
69027+
69028+ if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
69029+ {
69030+ #if defined(MV_INCLUDE_PCI)
69031+ return mvPciLocalBusNumGet(pciIf - MV_PCI_START_IF);
69032+ #else
69033+ return 0xFFFFFFFF;
69034+ #endif
69035+ }
69036+ else if (PCI_IF_TYPE_PEX == pciIfType)
69037+ {
69038+ #if defined(MV_INCLUDE_PEX)
69039+ return mvPexLocalBusNumGet(pciIf - MV_PEX_START_IF);
69040+ #else
69041+ return 0xFFFFFFFF;
69042+ #endif
69043+
69044+ }
69045+ else
69046+ {
69047+ mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n",__FUNCTION__, pciIf);
69048+ }
69049+
69050+ return 0;
69051+
69052+}
69053+
69054+
69055+/*******************************************************************************
69056+* mvPciLocalDevNumSet - Set PCI interface local device number.
69057+*
69058+* DESCRIPTION:
69059+* This function sets given PCI interface its local device number.
69060+* Note: In case the PCI interface is PCI-X, the information is read-only.
69061+*
69062+* INPUT:
69063+* pciIf - PCI interface number.
69064+* devNum - Device number.
69065+*
69066+* OUTPUT:
69067+* None.
69068+*
69069+* RETURN:
69070+* MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,
69071+* otherwise MV_OK
69072+*
69073+*******************************************************************************/
69074+MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)
69075+{
69076+ PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
69077+
69078+ if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
69079+ {
69080+ #if defined(MV_INCLUDE_PCI)
69081+ return mvPciLocalDevNumSet(pciIf - MV_PCI_START_IF,
69082+ devNum);
69083+ #else
69084+ return MV_OK;
69085+ #endif
69086+ }
69087+ else if (PCI_IF_TYPE_PEX == pciIfType)
69088+ {
69089+ #if defined(MV_INCLUDE_PEX)
69090+ return mvPexLocalDevNumSet(pciIf - MV_PEX_START_IF,
69091+ devNum);
69092+ #else
69093+ return MV_OK;
69094+ #endif
69095+ }
69096+ else
69097+ {
69098+ mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
69099+ }
69100+
69101+ return MV_FAIL;
69102+
69103+}
69104+
69105+/*******************************************************************************
69106+* mvPciLocalDevNumGet - Get PCI interface local device number.
69107+*
69108+* DESCRIPTION:
69109+* This function gets the local device number of a given PCI interface.
69110+*
69111+* INPUT:
69112+* pciIf - PCI interface number.
69113+*
69114+* OUTPUT:
69115+* None.
69116+*
69117+* RETURN:
69118+* Local device number. 0xffffffff on Error
69119+*
69120+*******************************************************************************/
69121+MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf)
69122+{
69123+ PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
69124+
69125+ if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
69126+ {
69127+ #if defined(MV_INCLUDE_PCI)
69128+ return mvPciLocalDevNumGet(pciIf - MV_PCI_START_IF);
69129+ #else
69130+ return 0xFFFFFFFF;
69131+ #endif
69132+ }
69133+ else if (PCI_IF_TYPE_PEX == pciIfType)
69134+ {
69135+ #if defined(MV_INCLUDE_PEX)
69136+ return mvPexLocalDevNumGet(pciIf - MV_PEX_START_IF);
69137+ #else
69138+ return 0xFFFFFFFF;
69139+ #endif
69140+
69141+ }
69142+ else
69143+ {
69144+ mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
69145+ }
69146+
69147+ return 0;
69148+
69149+}
69150+
69151+/*******************************************************************************
69152+* mvPciIfTypeGet -
69153+*
69154+* DESCRIPTION:
69155+*
69156+* INPUT:
69157+*
69158+* OUTPUT:
69159+* None.
69160+*
69161+* RETURN:
69162+*
69163+*******************************************************************************/
69164+
69165+PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf)
69166+{
69167+
69168+ if ((pciIf >= MV_PCI_START_IF)&&(pciIf < MV_PCI_MAX_IF + MV_PCI_START_IF))
69169+ {
69170+ return PCI_IF_TYPE_CONVEN_PCIX;
69171+ }
69172+ else if ((pciIf >= MV_PEX_START_IF) &&
69173+ (pciIf < MV_PEX_MAX_IF + MV_PEX_START_IF))
69174+ {
69175+ return PCI_IF_TYPE_PEX;
69176+
69177+ }
69178+ else
69179+ {
69180+ mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
69181+ }
69182+
69183+ return 0xffffffff;
69184+
69185+}
69186+
69187+/*******************************************************************************
69188+* mvPciIfTypeGet -
69189+*
69190+* DESCRIPTION:
69191+*
69192+* INPUT:
69193+*
69194+* OUTPUT:
69195+* None.
69196+*
69197+* RETURN:
69198+*
69199+*******************************************************************************/
69200+
69201+MV_U32 mvPciRealIfNumGet(MV_U32 pciIf)
69202+{
69203+
69204+ PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
69205+
69206+ if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
69207+ {
69208+ return (pciIf - MV_PCI_START_IF);
69209+ }
69210+ else if (PCI_IF_TYPE_PEX == pciIfType)
69211+ {
69212+ return (pciIf - MV_PEX_START_IF);
69213+
69214+ }
69215+ else
69216+ {
69217+ mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
69218+ }
69219+
69220+ return 0xffffffff;
69221+
69222+}
69223+
69224+
69225+
69226diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h b/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h
69227new file mode 100644
69228index 0000000..5f7caaa
69229--- /dev/null
69230+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h
69231@@ -0,0 +1,134 @@
69232+/*******************************************************************************
69233+Copyright (C) Marvell International Ltd. and its affiliates
69234+
69235+This software file (the "File") is owned and distributed by Marvell
69236+International Ltd. and/or its affiliates ("Marvell") under the following
69237+alternative licensing terms. Once you have made an election to distribute the
69238+File under one of the following license alternatives, please (i) delete this
69239+introductory statement regarding license alternatives, (ii) delete the two
69240+license alternatives that you have not elected to use and (iii) preserve the
69241+Marvell copyright notice above.
69242+
69243+********************************************************************************
69244+Marvell Commercial License Option
69245+
69246+If you received this File from Marvell and you have entered into a commercial
69247+license agreement (a "Commercial License") with Marvell, the File is licensed
69248+to you under the terms of the applicable Commercial License.
69249+
69250+********************************************************************************
69251+Marvell GPL License Option
69252+
69253+If you received this File from Marvell, you may opt to use, redistribute and/or
69254+modify this File in accordance with the terms and conditions of the General
69255+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
69256+available along with the File in the license.txt file or by writing to the Free
69257+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
69258+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
69259+
69260+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
69261+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
69262+DISCLAIMED. The GPL License provides additional details about this warranty
69263+disclaimer.
69264+********************************************************************************
69265+Marvell BSD License Option
69266+
69267+If you received this File from Marvell, you may opt to use, redistribute and/or
69268+modify this File under the following licensing terms.
69269+Redistribution and use in source and binary forms, with or without modification,
69270+are permitted provided that the following conditions are met:
69271+
69272+ * Redistributions of source code must retain the above copyright notice,
69273+ this list of conditions and the following disclaimer.
69274+
69275+ * Redistributions in binary form must reproduce the above copyright
69276+ notice, this list of conditions and the following disclaimer in the
69277+ documentation and/or other materials provided with the distribution.
69278+
69279+ * Neither the name of Marvell nor the names of its contributors may be
69280+ used to endorse or promote products derived from this software without
69281+ specific prior written permission.
69282+
69283+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
69284+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
69285+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
69286+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
69287+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
69288+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69289+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
69290+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69291+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
69292+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69293+
69294+*******************************************************************************/
69295+
69296+#ifndef __INCPCIIFH
69297+#define __INCPCIIFH
69298+
69299+#include "mvSysHwConfig.h"
69300+#include "pci-if/mvPciIfRegs.h"
69301+#if defined(MV_INCLUDE_PEX)
69302+#include "pex/mvPex.h"
69303+#endif
69304+#if defined(MV_INCLUDE_PCI)
69305+#include "pci/mvPci.h"
69306+#endif
69307+#include "ctrlEnv/mvCtrlEnvLib.h"
69308+#include "ctrlEnv/mvCtrlEnvAddrDec.h"
69309+
69310+typedef enum _mvPCIIfType
69311+{
69312+ PCI_IF_TYPE_CONVEN_PCIX,
69313+ PCI_IF_TYPE_PEX
69314+
69315+}PCI_IF_TYPE;
69316+
69317+typedef enum _mvPCIIfMode
69318+{
69319+ PCI_IF_MODE_HOST,
69320+ PCI_IF_MODE_DEVICE
69321+}PCI_IF_MODE;
69322+
69323+
69324+/* Global Functions prototypes */
69325+
69326+/* mvPciIfInit - Initialize PCI interfaces*/
69327+MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode);
69328+
69329+/* mvPciIfConfigRead - Read from configuration space */
69330+MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
69331+ MV_U32 func,MV_U32 regOff);
69332+
69333+/* mvPciIfConfigWrite - Write to configuration space */
69334+MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
69335+ MV_U32 func, MV_U32 regOff, MV_U32 data);
69336+
69337+/* mvPciIfMasterEnable - Enable/disale PCI interface master transactions.*/
69338+MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable);
69339+
69340+/* mvPciIfSlaveEnable - Enable/disale PCI interface slave transactions.*/
69341+MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev,
69342+ MV_BOOL enable);
69343+
69344+/* mvPciIfLocalBusNumSet - Set PCI interface local bus number.*/
69345+MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);
69346+
69347+/* mvPciIfLocalBusNumGet - Get PCI interface local bus number.*/
69348+MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf);
69349+
69350+/* mvPciIfLocalDevNumSet - Set PCI interface local device number.*/
69351+MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);
69352+
69353+/* mvPciIfLocalDevNumGet - Get PCI interface local device number.*/
69354+MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf);
69355+
69356+/* mvPciIfTypeGet - Get PCI If type*/
69357+PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf);
69358+
69359+MV_U32 mvPciRealIfNumGet(MV_U32 pciIf);
69360+
69361+/* mvPciIfAddrDecShow - Display address decode windows attributes */
69362+MV_VOID mvPciIfAddrDecShow(MV_VOID);
69363+
69364+#endif /* #ifndef __INCPCIIFH */
69365+
69366diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h b/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h
69367new file mode 100644
69368index 0000000..754e837
69369--- /dev/null
69370+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h
69371@@ -0,0 +1,245 @@
69372+/*******************************************************************************
69373+Copyright (C) Marvell International Ltd. and its affiliates
69374+
69375+This software file (the "File") is owned and distributed by Marvell
69376+International Ltd. and/or its affiliates ("Marvell") under the following
69377+alternative licensing terms. Once you have made an election to distribute the
69378+File under one of the following license alternatives, please (i) delete this
69379+introductory statement regarding license alternatives, (ii) delete the two
69380+license alternatives that you have not elected to use and (iii) preserve the
69381+Marvell copyright notice above.
69382+
69383+********************************************************************************
69384+Marvell Commercial License Option
69385+
69386+If you received this File from Marvell and you have entered into a commercial
69387+license agreement (a "Commercial License") with Marvell, the File is licensed
69388+to you under the terms of the applicable Commercial License.
69389+
69390+********************************************************************************
69391+Marvell GPL License Option
69392+
69393+If you received this File from Marvell, you may opt to use, redistribute and/or
69394+modify this File in accordance with the terms and conditions of the General
69395+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
69396+available along with the File in the license.txt file or by writing to the Free
69397+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
69398+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
69399+
69400+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
69401+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
69402+DISCLAIMED. The GPL License provides additional details about this warranty
69403+disclaimer.
69404+********************************************************************************
69405+Marvell BSD License Option
69406+
69407+If you received this File from Marvell, you may opt to use, redistribute and/or
69408+modify this File under the following licensing terms.
69409+Redistribution and use in source and binary forms, with or without modification,
69410+are permitted provided that the following conditions are met:
69411+
69412+ * Redistributions of source code must retain the above copyright notice,
69413+ this list of conditions and the following disclaimer.
69414+
69415+ * Redistributions in binary form must reproduce the above copyright
69416+ notice, this list of conditions and the following disclaimer in the
69417+ documentation and/or other materials provided with the distribution.
69418+
69419+ * Neither the name of Marvell nor the names of its contributors may be
69420+ used to endorse or promote products derived from this software without
69421+ specific prior written permission.
69422+
69423+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
69424+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
69425+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
69426+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
69427+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
69428+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69429+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
69430+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69431+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
69432+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69433+
69434+*******************************************************************************/
69435+
69436+#ifndef __INCPCIIFREGSH
69437+#define __INCPCIIFREGSH
69438+
69439+
69440+/* defines */
69441+#define MAX_PCI_DEVICES 32
69442+#define MAX_PCI_FUNCS 8
69443+#define MAX_PCI_BUSSES 128
69444+
69445+/***************************************/
69446+/* PCI Configuration registers */
69447+/***************************************/
69448+
69449+/*********************************************/
69450+/* PCI Configuration, Function 0, Registers */
69451+/*********************************************/
69452+
69453+
69454+/* Standard registers */
69455+#define PCI_DEVICE_AND_VENDOR_ID 0x000
69456+#define PCI_STATUS_AND_COMMAND 0x004
69457+#define PCI_CLASS_CODE_AND_REVISION_ID 0x008
69458+#define PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE 0x00C
69459+#define PCI_MEMORY_BAR_BASE_ADDR(barNum) (0x010 + ((barNum) << 2))
69460+#define PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID 0x02C
69461+#define PCI_EXPANSION_ROM_BASE_ADDR_REG 0x030
69462+#define PCI_CAPABILTY_LIST_POINTER 0x034
69463+#define PCI_INTERRUPT_PIN_AND_LINE 0x03C
69464+
69465+
69466+/* PCI Device and Vendor ID Register (PDVIR) */
69467+#define PDVIR_VEN_ID_OFFS 0 /* Vendor ID */
69468+#define PDVIR_VEN_ID_MASK (0xffff << PDVIR_VEN_ID_OFFS)
69469+
69470+#define PDVIR_DEV_ID_OFFS 16 /* Device ID */
69471+#define PDVIR_DEV_ID_MASK (0xffff << PDVIR_DEV_ID_OFFS)
69472+
69473+/* PCI Status and Command Register (PSCR) */
69474+#define PSCR_IO_EN BIT0 /* IO Enable */
69475+#define PSCR_MEM_EN BIT1 /* Memory Enable */
69476+#define PSCR_MASTER_EN BIT2 /* Master Enable */
69477+#define PSCR_SPECIAL_EN BIT3 /* Special Cycle Enable */
69478+#define PSCR_MEM_WRI_INV BIT4 /* Memory Write and Invalidate Enable */
69479+#define PSCR_VGA BIT5 /* VGA Palette Snoops */
69480+#define PSCR_PERR_EN BIT6 /* Parity Errors Respond Enable */
69481+#define PSCR_ADDR_STEP BIT7 /* Address Stepping Enable (Wait Cycle En)*/
69482+#define PSCR_SERR_EN BIT8 /* Ability to assert SERR# line */
69483+#define PSCR_FAST_BTB_EN BIT9 /* generate fast back-to-back transactions*/
69484+#define PSCR_CAP_LIST BIT20 /* Capability List Support */
69485+#define PSCR_66MHZ_EN BIT21 /* 66 MHz Capable */
69486+#define PSCR_UDF_EN BIT22 /* User definable features */
69487+#define PSCR_TAR_FAST_BB BIT23 /* fast back-to-back transactions capable */
69488+#define PSCR_DATA_PERR BIT24 /* Data Parity reported */
69489+
69490+#define PSCR_DEVSEL_TIM_OFFS 25 /* DEVSEL timing */
69491+#define PSCR_DEVSEL_TIM_MASK (0x3 << PSCR_DEVSEL_TIM_OFFS)
69492+#define PSCR_DEVSEL_TIM_FAST (0x0 << PSCR_DEVSEL_TIM_OFFS)
69493+#define PSCR_DEVSEL_TIM_MED (0x1 << PSCR_DEVSEL_TIM_OFFS)
69494+#define PSCR_DEVSEL_TIM_SLOW (0x2 << PSCR_DEVSEL_TIM_OFFS)
69495+
69496+#define PSCR_SLAVE_TABORT BIT27 /* Signalled Target Abort */
69497+#define PSCR_MASTER_TABORT BIT28 /* Recieved Target Abort */
69498+#define PSCR_MABORT BIT29 /* Recieved Master Abort */
69499+#define PSCR_SYSERR BIT30 /* Signalled system error */
69500+#define PSCR_DET_PARERR BIT31 /* Detect Parity Error */
69501+
69502+/* PCI configuration register offset=0x08 fields
69503+ (PCI_CLASS_CODE_AND_REVISION_ID)(PCCRI) */
69504+
69505+#define PCCRIR_REVID_OFFS 0 /* Revision ID */
69506+#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS)
69507+
69508+#define PCCRIR_FULL_CLASS_OFFS 8 /* Full Class Code */
69509+#define PCCRIR_FULL_CLASS_MASK (0xffffff << PCCRIR_FULL_CLASS_OFFS)
69510+
69511+#define PCCRIR_PROGIF_OFFS 8 /* Prog .I/F*/
69512+#define PCCRIR_PROGIF_MASK (0xff << PCCRIR_PROGIF_OFFS)
69513+
69514+#define PCCRIR_SUB_CLASS_OFFS 16 /* Sub Class*/
69515+#define PCCRIR_SUB_CLASS_MASK (0xff << PCCRIR_SUB_CLASS_OFFS)
69516+
69517+#define PCCRIR_BASE_CLASS_OFFS 24 /* Base Class*/
69518+#define PCCRIR_BASE_CLASS_MASK (0xff << PCCRIR_BASE_CLASS_OFFS)
69519+
69520+/* PCI configuration register offset=0x0C fields
69521+ (PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE)(PBHTLTCL) */
69522+
69523+#define PBHTLTCLR_CACHELINE_OFFS 0 /* Specifies the cache line size */
69524+#define PBHTLTCLR_CACHELINE_MASK (0xff << PBHTLTCLR_CACHELINE_OFFS)
69525+
69526+#define PBHTLTCLR_LATTIMER_OFFS 8 /* latency timer */
69527+#define PBHTLTCLR_LATTIMER_MASK (0xff << PBHTLTCLR_LATTIMER_OFFS)
69528+
69529+#define PBHTLTCLR_HEADTYPE_FULL_OFFS 16 /* Full Header Type */
69530+#define PBHTLTCLR_HEADTYPE_FULL_MASK (0xff << PBHTLTCLR_HEADTYPE_FULL_OFFS)
69531+
69532+#define PBHTLTCLR_MULTI_FUNC BIT23 /* Multi/Single function */
69533+
69534+#define PBHTLTCLR_HEADER_OFFS 16 /* Header type */
69535+#define PBHTLTCLR_HEADER_MASK (0x7f << PBHTLTCLR_HEADER_OFFS)
69536+#define PBHTLTCLR_HEADER_STANDARD (0x0 << PBHTLTCLR_HEADER_OFFS)
69537+#define PBHTLTCLR_HEADER_PCI2PCI_BRIDGE (0x1 << PBHTLTCLR_HEADER_OFFS)
69538+
69539+
69540+#define PBHTLTCLR_BISTCOMP_OFFS 24 /* BIST Completion Code */
69541+#define PBHTLTCLR_BISTCOMP_MASK (0xf << PBHTLTCLR_BISTCOMP_OFFS)
69542+
69543+#define PBHTLTCLR_BISTACT BIT30 /* BIST Activate bit */
69544+#define PBHTLTCLR_BISTCAP BIT31 /* BIST Capable Bit */
69545+
69546+
69547+/* PCI Bar Base Low Register (PBBLR) */
69548+#define PBBLR_IOSPACE BIT0 /* Memory Space Indicator */
69549+
69550+#define PBBLR_TYPE_OFFS 1 /* BAR Type/Init Val. */
69551+#define PBBLR_TYPE_MASK (0x3 << PBBLR_TYPE_OFFS)
69552+#define PBBLR_TYPE_32BIT_ADDR (0x0 << PBBLR_TYPE_OFFS)
69553+#define PBBLR_TYPE_64BIT_ADDR (0x2 << PBBLR_TYPE_OFFS)
69554+
69555+#define PBBLR_PREFETCH_EN BIT3 /* Prefetch Enable */
69556+
69557+
69558+#define PBBLR_MEM_BASE_OFFS 4 /* Memory Bar Base address. Corresponds to
69559+ address bits [31:4] */
69560+#define PBBLR_MEM_BASE_MASK (0xfffffff << PBBLR_MEM_BASE_OFFS)
69561+
69562+#define PBBLR_IO_BASE_OFFS 2 /* IO Bar Base address. Corresponds to
69563+ address bits [31:2] */
69564+#define PBBLR_IO_BASE_MASK (0x3fffffff << PBBLR_IO_BASE_OFFS)
69565+
69566+
69567+#define PBBLR_BASE_OFFS 12 /* Base address. Address bits [31:12] */
69568+#define PBBLR_BASE_MASK (0xfffff << PBBLR_BASE_OFFS)
69569+#define PBBLR_BASE_ALIGNMET (1 << PBBLR_BASE_OFFS)
69570+
69571+
69572+/* PCI Bar Base High Fegister (PBBHR) */
69573+#define PBBHR_BASE_OFFS 0 /* Base address. Address bits [31:12] */
69574+#define PBBHR_BASE_MASK (0xffffffff << PBBHR_BASE_OFFS)
69575+
69576+
69577+/* PCI configuration register offset=0x2C fields
69578+ (PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID)(PSISVI) */
69579+
69580+#define PSISVIR_VENID_OFFS 0 /* Subsystem Manufacturer Vendor ID Number */
69581+#define PSISVIR_VENID_MASK (0xffff << PSISVIR_VENID_OFFS)
69582+
69583+#define PSISVIR_DEVID_OFFS 16 /* Subsystem Device ID Number */
69584+#define PSISVIR_DEVID_MASK (0xffff << PSISVIR_DEVID_OFFS)
69585+
69586+/* PCI configuration register offset=0x30 fields
69587+ (PCI_EXPANSION_ROM_BASE_ADDR_REG)(PERBA) */
69588+
69589+#define PERBAR_EXPROMEN BIT0 /* Expansion ROM Enable */
69590+
69591+#define PERBAR_BASE_OFFS 12 /* Expansion ROM Base Address */
69592+#define PERBAR_BASE_MASK (0xfffff << PERBAR_BASE_OFFS)
69593+
69594+/* PCI configuration register offset=0x34 fields
69595+ (PCI_CAPABILTY_LIST_POINTER)(PCLP) */
69596+
69597+#define PCLPR_CAPPTR_OFFS 0 /* Capability List Pointer */
69598+#define PCLPR_CAPPTR_MASK (0xff << PCLPR_CAPPTR_OFFS)
69599+
69600+/* PCI configuration register offset=0x3C fields
69601+ (PCI_INTERRUPT_PIN_AND_LINE)(PIPL) */
69602+
69603+#define PIPLR_INTLINE_OFFS 0 /* Interrupt line (IRQ) */
69604+#define PIPLR_INTLINE_MASK (0xff << PIPLR_INTLINE_OFFS)
69605+
69606+#define PIPLR_INTPIN_OFFS 8 /* interrupt pin (A,B,C,D) */
69607+#define PIPLR_INTPIN_MASK (0xff << PIPLR_INTPIN_OFFS)
69608+
69609+#define PIPLR_MINGRANT_OFFS 16 /* Minimum Grant on 250 nano seconds units */
69610+#define PIPLR_MINGRANT_MASK (0xff << PIPLR_MINGRANT_OFFS)
69611+
69612+#define PIPLR_MAXLATEN_OFFS 24 /* Maximum latency on 250 nano seconds units */
69613+#define PIPLR_MAXLATEN_MASK (0xff << PIPLR_MAXLATEN_OFFS)
69614+
69615+#endif /* #ifndef __INCPCIIFREGSH */
69616+
69617diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c b/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c
69618new file mode 100644
69619index 0000000..6de1b0c
69620--- /dev/null
69621+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c
69622@@ -0,0 +1,1006 @@
69623+/*******************************************************************************
69624+Copyright (C) Marvell International Ltd. and its affiliates
69625+
69626+This software file (the "File") is owned and distributed by Marvell
69627+International Ltd. and/or its affiliates ("Marvell") under the following
69628+alternative licensing terms. Once you have made an election to distribute the
69629+File under one of the following license alternatives, please (i) delete this
69630+introductory statement regarding license alternatives, (ii) delete the two
69631+license alternatives that you have not elected to use and (iii) preserve the
69632+Marvell copyright notice above.
69633+
69634+********************************************************************************
69635+Marvell Commercial License Option
69636+
69637+If you received this File from Marvell and you have entered into a commercial
69638+license agreement (a "Commercial License") with Marvell, the File is licensed
69639+to you under the terms of the applicable Commercial License.
69640+
69641+********************************************************************************
69642+Marvell GPL License Option
69643+
69644+If you received this File from Marvell, you may opt to use, redistribute and/or
69645+modify this File in accordance with the terms and conditions of the General
69646+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
69647+available along with the File in the license.txt file or by writing to the Free
69648+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
69649+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
69650+
69651+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
69652+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
69653+DISCLAIMED. The GPL License provides additional details about this warranty
69654+disclaimer.
69655+********************************************************************************
69656+Marvell BSD License Option
69657+
69658+If you received this File from Marvell, you may opt to use, redistribute and/or
69659+modify this File under the following licensing terms.
69660+Redistribution and use in source and binary forms, with or without modification,
69661+are permitted provided that the following conditions are met:
69662+
69663+ * Redistributions of source code must retain the above copyright notice,
69664+ this list of conditions and the following disclaimer.
69665+
69666+ * Redistributions in binary form must reproduce the above copyright
69667+ notice, this list of conditions and the following disclaimer in the
69668+ documentation and/or other materials provided with the distribution.
69669+
69670+ * Neither the name of Marvell nor the names of its contributors may be
69671+ used to endorse or promote products derived from this software without
69672+ specific prior written permission.
69673+
69674+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
69675+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
69676+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
69677+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
69678+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
69679+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69680+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
69681+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69682+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
69683+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69684+
69685+*******************************************************************************/
69686+
69687+/* includes */
69688+#include "mvPciUtils.h"
69689+
69690+#include "ctrlEnv/mvCtrlEnvLib.h"
69691+
69692+/* #define MV_DEBUG */
69693+/* defines */
69694+#ifdef MV_DEBUG
69695+ #define DB(x) x
69696+ #define mvOsPrintf printf
69697+#else
69698+ #define DB(x)
69699+#endif
69700+
69701+/*
69702+This module only support scanning of Header type 00h of pci devices
69703+There is no suppotr for Header type 01h of pci devices ( PCI bridges )
69704+*/
69705+
69706+
69707+static MV_STATUS pciDetectDevice(MV_U32 pciIf,
69708+ MV_U32 bus,
69709+ MV_U32 dev,
69710+ MV_U32 func,
69711+ MV_PCI_DEVICE *pPciAgent);
69712+
69713+static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
69714+ MV_U32 bus,
69715+ MV_U32 dev,
69716+ MV_U32 func,
69717+ MV_PCI_DEVICE *pPciAgent);
69718+
69719+
69720+
69721+
69722+
69723+
69724+/*******************************************************************************
69725+* mvPciScan - Scan a PCI interface bus
69726+*
69727+* DESCRIPTION:
69728+* Performs a full scan on a PCI interface and returns all possible details
69729+* on the agents found on the bus.
69730+*
69731+* INPUT:
69732+* pciIf - PCI Interface
69733+* pPciAgents - Pointer to an Array of the pci agents to be detected
69734+* pPciAgentsNum - pPciAgents array maximum number of elements
69735+*
69736+* OUTPUT:
69737+* pPciAgents - Array of the pci agents detected on the bus
69738+* pPciAgentsNum - Number of pci agents detected on the bus
69739+*
69740+* RETURN:
69741+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
69742+*
69743+*******************************************************************************/
69744+
69745+MV_STATUS mvPciScan(MV_U32 pciIf,
69746+ MV_PCI_DEVICE *pPciAgents,
69747+ MV_U32 *pPciAgentsNum)
69748+{
69749+
69750+ MV_U32 devIndex,funcIndex=0,busIndex=0,detectedDevNum=0;
69751+ MV_U32 localBus=mvPciIfLocalBusNumGet(pciIf);
69752+ MV_PCI_DEVICE *pPciDevice;
69753+ MV_PCI_DEVICE *pMainDevice;
69754+
69755+ DB(mvOsPrintf("mvPciScan: PCI interface num %d\n", pciIf));
69756+ /* Parameter checking */
69757+ if (pciIf >= mvCtrlPexMaxIfGet())
69758+ {
69759+ DB(mvOsPrintf("mvPciScan: ERR. Invalid PCI interface num %d\n", pciIf));
69760+ return MV_BAD_PARAM;
69761+ }
69762+ if (NULL == pPciAgents)
69763+ {
69764+ DB(mvOsPrintf("mvPciScan: ERR. pPciAgents=NULL \n"));
69765+ return MV_BAD_PARAM;
69766+ }
69767+ if (NULL == pPciAgentsNum)
69768+ {
69769+ DB(mvOsPrintf("mvPciScan: ERR. pPciAgentsNum=NULL \n"));
69770+ return MV_BAD_PARAM;
69771+ }
69772+
69773+
69774+ DB(mvOsPrintf("mvPciScan: PCI interface num %d mvPciMasterEnable\n", pciIf));
69775+ /* Master enable the MV PCI master */
69776+ if (MV_OK != mvPciIfMasterEnable(pciIf,MV_TRUE))
69777+ {
69778+ DB(mvOsPrintf("mvPciScan: ERR. mvPciMasterEnable failed \n"));
69779+ return MV_ERROR;
69780+
69781+ }
69782+
69783+ DB(mvOsPrintf("mvPciScan: PCI interface num scan%d\n", pciIf));
69784+
69785+ /* go through all busses */
69786+ for (busIndex=localBus ; busIndex < MAX_PCI_BUSSES ; busIndex++)
69787+ {
69788+ /* go through all possible devices on the local bus */
69789+ for (devIndex=0 ; devIndex < MAX_PCI_DEVICES ; devIndex++)
69790+ {
69791+ /* always start with function equal to zero */
69792+ funcIndex=0;
69793+
69794+ pPciDevice=&pPciAgents[detectedDevNum];
69795+ DB(mvOsPrintf("mvPciScan: PCI interface num scan%d:%d\n", busIndex, devIndex));
69796+
69797+ if (MV_ERROR == pciDetectDevice(pciIf,
69798+ busIndex,
69799+ devIndex,
69800+ funcIndex,
69801+ pPciDevice))
69802+ {
69803+ /* no device detected , try the next address */
69804+ continue;
69805+ }
69806+
69807+ /* We are here ! means we have detected a device*/
69808+ /* always we start with only one function per device */
69809+ pMainDevice = pPciDevice;
69810+ pPciDevice->funtionsNum = 1;
69811+
69812+
69813+ /* move on */
69814+ detectedDevNum++;
69815+
69816+
69817+ /* check if we have no more room for a new device */
69818+ if (detectedDevNum == *pPciAgentsNum)
69819+ {
69820+ DB(mvOsPrintf("mvPciScan: ERR. array passed too small \n"));
69821+ return MV_ERROR;
69822+ }
69823+
69824+ /* check the detected device if it is a multi functional device then
69825+ scan all device functions*/
69826+ if (pPciDevice->isMultiFunction == MV_TRUE)
69827+ {
69828+ /* start with function number 1 because we have already detected
69829+ function 0 */
69830+ for (funcIndex=1; funcIndex<MAX_PCI_FUNCS ; funcIndex++)
69831+ {
69832+ pPciDevice=&pPciAgents[detectedDevNum];
69833+
69834+ if (MV_ERROR == pciDetectDevice(pciIf,
69835+ busIndex,
69836+ devIndex,
69837+ funcIndex,
69838+ pPciDevice))
69839+ {
69840+ /* no device detected means no more functions !*/
69841+ continue;
69842+ }
69843+ /* We are here ! means we have detected a device */
69844+
69845+ /* move on */
69846+ pMainDevice->funtionsNum++;
69847+ detectedDevNum++;
69848+
69849+ /* check if we have no more room for a new device */
69850+ if (detectedDevNum == *pPciAgentsNum)
69851+ {
69852+ DB(mvOsPrintf("mvPciScan: ERR. Array too small\n"));
69853+ return MV_ERROR;
69854+ }
69855+
69856+
69857+ }
69858+ }
69859+
69860+ }
69861+
69862+ }
69863+
69864+ /* return the number of devices actually detected on the bus ! */
69865+ *pPciAgentsNum = detectedDevNum;
69866+
69867+ return MV_OK;
69868+
69869+}
69870+
69871+
69872+/*******************************************************************************
69873+* pciDetectDevice - Detect a pci device parameters
69874+*
69875+* DESCRIPTION:
69876+* This function detect if a pci agent exist on certain address !
69877+* and if exists then it fills all possible information on the
69878+* agent
69879+*
69880+* INPUT:
69881+* pciIf - PCI Interface
69882+* bus - Bus number
69883+* dev - Device number
69884+* func - Function number
69885+*
69886+*
69887+*
69888+* OUTPUT:
69889+* pPciAgent - pointer to the pci agent filled with its information
69890+*
69891+* RETURN:
69892+* MV_ERROR if no device , MV_OK otherwise
69893+*
69894+*******************************************************************************/
69895+
69896+static MV_STATUS pciDetectDevice(MV_U32 pciIf,
69897+ MV_U32 bus,
69898+ MV_U32 dev,
69899+ MV_U32 func,
69900+ MV_PCI_DEVICE *pPciAgent)
69901+{
69902+ MV_U32 pciData;
69903+
69904+ /* no Parameters checking ! because it is static function and it is assumed
69905+ that all parameters were checked in the calling function */
69906+
69907+
69908+ /* Try read the PCI Vendor ID and Device ID */
69909+
69910+ /* We will scan only ourselves and the PCI slots that exist on the
69911+ board, because we may have a case that we have one slot that has
69912+ a Cardbus connector, and because CardBus answers all IDsels we want
69913+ to scan only this slot and ourseleves.
69914+
69915+ */
69916+ #if defined(MV_INCLUDE_PCI)
69917+ if ((PCI_IF_TYPE_CONVEN_PCIX == mvPciIfTypeGet(pciIf)) &&
69918+ (DB_88F5181_DDR1_PRPMC != mvBoardIdGet()) &&
69919+ (DB_88F5181_DDR1_PEXPCI != mvBoardIdGet()) &&
69920+ (DB_88F5181_DDR1_MNG != mvBoardIdGet()))
69921+ {
69922+
69923+ if (mvBoardIsOurPciSlot(bus, dev) == MV_FALSE)
69924+ {
69925+ return MV_ERROR;
69926+ }
69927+ }
69928+ #endif /* defined(MV_INCLUDE_PCI) */
69929+
69930+ pciData = mvPciIfConfigRead(pciIf, bus,dev,func, PCI_DEVICE_AND_VENDOR_ID);
69931+
69932+ if (PCI_ERROR_CODE == pciData)
69933+ {
69934+ /* no device exist */
69935+ return MV_ERROR;
69936+ }
69937+
69938+ /* we are here ! means a device is detected */
69939+
69940+ /* fill basic information */
69941+ pPciAgent->busNumber=bus;
69942+ pPciAgent->deviceNum=dev;
69943+ pPciAgent->function=func;
69944+
69945+ /* Fill the PCI Vendor ID and Device ID */
69946+
69947+ pPciAgent->venID = (pciData & PDVIR_VEN_ID_MASK) >> PDVIR_VEN_ID_OFFS;
69948+ pPciAgent->deviceID = (pciData & PDVIR_DEV_ID_MASK) >> PDVIR_DEV_ID_OFFS;
69949+
69950+ /* Read Status and command */
69951+ pciData = mvPciIfConfigRead(pciIf,
69952+ bus,dev,func,
69953+ PCI_STATUS_AND_COMMAND);
69954+
69955+
69956+ /* Fill related Status and Command information*/
69957+
69958+ if (pciData & PSCR_TAR_FAST_BB)
69959+ {
69960+ pPciAgent->isFastB2BCapable = MV_TRUE;
69961+ }
69962+ else
69963+ {
69964+ pPciAgent->isFastB2BCapable = MV_FALSE;
69965+ }
69966+
69967+ if (pciData & PSCR_CAP_LIST)
69968+ {
69969+ pPciAgent->isCapListSupport=MV_TRUE;
69970+ }
69971+ else
69972+ {
69973+ pPciAgent->isCapListSupport=MV_FALSE;
69974+ }
69975+
69976+ if (pciData & PSCR_66MHZ_EN)
69977+ {
69978+ pPciAgent->is66MHZCapable=MV_TRUE;
69979+ }
69980+ else
69981+ {
69982+ pPciAgent->is66MHZCapable=MV_FALSE;
69983+ }
69984+
69985+ /* Read Class Code and Revision */
69986+ pciData = mvPciIfConfigRead(pciIf,
69987+ bus,dev,func,
69988+ PCI_CLASS_CODE_AND_REVISION_ID);
69989+
69990+
69991+ pPciAgent->baseClassCode =
69992+ (pciData & PCCRIR_BASE_CLASS_MASK) >> PCCRIR_BASE_CLASS_OFFS;
69993+
69994+ pPciAgent->subClassCode =
69995+ (pciData & PCCRIR_SUB_CLASS_MASK) >> PCCRIR_SUB_CLASS_OFFS;
69996+
69997+ pPciAgent->progIf =
69998+ (pciData & PCCRIR_PROGIF_MASK) >> PCCRIR_PROGIF_OFFS;
69999+
70000+ pPciAgent->revisionID =
70001+ (pciData & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS;
70002+
70003+ /* Read PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE */
70004+ pciData = mvPciIfConfigRead(pciIf,
70005+ bus,dev,func,
70006+ PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE);
70007+
70008+
70009+
70010+ pPciAgent->pciCacheLine=
70011+ (pciData & PBHTLTCLR_CACHELINE_MASK ) >> PBHTLTCLR_CACHELINE_OFFS;
70012+ pPciAgent->pciLatencyTimer=
70013+ (pciData & PBHTLTCLR_LATTIMER_MASK) >> PBHTLTCLR_LATTIMER_OFFS;
70014+
70015+ switch (pciData & PBHTLTCLR_HEADER_MASK)
70016+ {
70017+ case PBHTLTCLR_HEADER_STANDARD:
70018+
70019+ pPciAgent->pciHeader=MV_PCI_STANDARD;
70020+ break;
70021+ case PBHTLTCLR_HEADER_PCI2PCI_BRIDGE:
70022+
70023+ pPciAgent->pciHeader=MV_PCI_PCI2PCI_BRIDGE;
70024+ break;
70025+
70026+ }
70027+
70028+ if (pciData & PBHTLTCLR_MULTI_FUNC)
70029+ {
70030+ pPciAgent->isMultiFunction=MV_TRUE;
70031+ }
70032+ else
70033+ {
70034+ pPciAgent->isMultiFunction=MV_FALSE;
70035+ }
70036+
70037+ if (pciData & PBHTLTCLR_BISTCAP)
70038+ {
70039+ pPciAgent->isBISTCapable=MV_TRUE;
70040+ }
70041+ else
70042+ {
70043+ pPciAgent->isBISTCapable=MV_FALSE;
70044+ }
70045+
70046+
70047+ /* read this device pci bars */
70048+
70049+ pciDetectDeviceBars(pciIf,
70050+ bus,dev,func,
70051+ pPciAgent);
70052+
70053+
70054+ /* check if we are bridge*/
70055+ if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
70056+ (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
70057+ {
70058+
70059+ /* Read P2P_BUSSES_NUM */
70060+ pciData = mvPciIfConfigRead(pciIf,
70061+ bus,dev,func,
70062+ P2P_BUSSES_NUM);
70063+
70064+ pPciAgent->p2pPrimBusNum =
70065+ (pciData & PBM_PRIME_BUS_NUM_MASK) >> PBM_PRIME_BUS_NUM_OFFS;
70066+
70067+ pPciAgent->p2pSecBusNum =
70068+ (pciData & PBM_SEC_BUS_NUM_MASK) >> PBM_SEC_BUS_NUM_OFFS;
70069+
70070+ pPciAgent->p2pSubBusNum =
70071+ (pciData & PBM_SUB_BUS_NUM_MASK) >> PBM_SUB_BUS_NUM_OFFS;
70072+
70073+ pPciAgent->p2pSecLatencyTimer =
70074+ (pciData & PBM_SEC_LAT_TMR_MASK) >> PBM_SEC_LAT_TMR_OFFS;
70075+
70076+ /* Read P2P_IO_BASE_LIMIT_SEC_STATUS */
70077+ pciData = mvPciIfConfigRead(pciIf,
70078+ bus,dev,func,
70079+ P2P_IO_BASE_LIMIT_SEC_STATUS);
70080+
70081+ pPciAgent->p2pSecStatus =
70082+ (pciData & PIBLSS_SEC_STATUS_MASK) >> PIBLSS_SEC_STATUS_OFFS;
70083+
70084+
70085+ pPciAgent->p2pIObase =
70086+ (pciData & PIBLSS_IO_BASE_MASK) << PIBLSS_IO_LIMIT_OFFS;
70087+
70088+ /* clear low address (should be zero)*/
70089+ pPciAgent->p2pIObase &= PIBLSS_HIGH_ADDR_MASK;
70090+
70091+ pPciAgent->p2pIOLimit =
70092+ (pciData & PIBLSS_IO_LIMIT_MASK);
70093+
70094+ /* fill low address with 0xfff */
70095+ pPciAgent->p2pIOLimit |= PIBLSS_LOW_ADDR_MASK;
70096+
70097+
70098+ switch ((pciData & PIBLSS_ADD_CAP_MASK) >> PIBLSS_ADD_CAP_OFFS)
70099+ {
70100+ case PIBLSS_ADD_CAP_16BIT:
70101+
70102+ pPciAgent->bIO32 = MV_FALSE;
70103+
70104+ break;
70105+ case PIBLSS_ADD_CAP_32BIT:
70106+
70107+ pPciAgent->bIO32 = MV_TRUE;
70108+
70109+ /* Read P2P_IO_BASE_LIMIT_UPPER_16 */
70110+ pciData = mvPciIfConfigRead(pciIf,
70111+ bus,dev,func,
70112+ P2P_IO_BASE_LIMIT_UPPER_16);
70113+
70114+ pPciAgent->p2pIObase |=
70115+ (pciData & PRBU_IO_UPP_BASE_MASK) << PRBU_IO_UPP_LIMIT_OFFS;
70116+
70117+
70118+ pPciAgent->p2pIOLimit |=
70119+ (pciData & PRBU_IO_UPP_LIMIT_MASK);
70120+
70121+ break;
70122+
70123+ }
70124+
70125+
70126+ /* Read P2P_MEM_BASE_LIMIT */
70127+ pciData = mvPciIfConfigRead(pciIf,
70128+ bus,dev,func,
70129+ P2P_MEM_BASE_LIMIT);
70130+
70131+ pPciAgent->p2pMemBase =
70132+ (pciData & PMBL_MEM_BASE_MASK) << PMBL_MEM_LIMIT_OFFS;
70133+
70134+ /* clear low address */
70135+ pPciAgent->p2pMemBase &= PMBL_HIGH_ADDR_MASK;
70136+
70137+ pPciAgent->p2pMemLimit =
70138+ (pciData & PMBL_MEM_LIMIT_MASK);
70139+
70140+ /* add 0xfffff */
70141+ pPciAgent->p2pMemLimit |= PMBL_LOW_ADDR_MASK;
70142+
70143+
70144+ /* Read P2P_PREF_MEM_BASE_LIMIT */
70145+ pciData = mvPciIfConfigRead(pciIf,
70146+ bus,dev,func,
70147+ P2P_PREF_MEM_BASE_LIMIT);
70148+
70149+
70150+ pPciAgent->p2pPrefMemBase =
70151+ (pciData & PRMBL_PREF_MEM_BASE_MASK) << PRMBL_PREF_MEM_LIMIT_OFFS;
70152+
70153+ /* get high address only */
70154+ pPciAgent->p2pPrefMemBase &= PRMBL_HIGH_ADDR_MASK;
70155+
70156+
70157+
70158+ pPciAgent->p2pPrefMemLimit =
70159+ (pciData & PRMBL_PREF_MEM_LIMIT_MASK);
70160+
70161+ /* add 0xfffff */
70162+ pPciAgent->p2pPrefMemLimit |= PRMBL_LOW_ADDR_MASK;
70163+
70164+ switch (pciData & PRMBL_ADD_CAP_MASK)
70165+ {
70166+ case PRMBL_ADD_CAP_32BIT:
70167+
70168+ pPciAgent->bPrefMem64 = MV_FALSE;
70169+
70170+ /* Read P2P_PREF_BASE_UPPER_32 */
70171+ pPciAgent->p2pPrefBaseUpper32Bits = 0;
70172+
70173+ /* Read P2P_PREF_LIMIT_UPPER_32 */
70174+ pPciAgent->p2pPrefLimitUpper32Bits = 0;
70175+
70176+ break;
70177+ case PRMBL_ADD_CAP_64BIT:
70178+
70179+ pPciAgent->bPrefMem64 = MV_TRUE;
70180+
70181+ /* Read P2P_PREF_BASE_UPPER_32 */
70182+ pPciAgent->p2pPrefBaseUpper32Bits = mvPciIfConfigRead(pciIf,
70183+ bus,dev,func,
70184+ P2P_PREF_BASE_UPPER_32);
70185+
70186+ /* Read P2P_PREF_LIMIT_UPPER_32 */
70187+ pPciAgent->p2pPrefLimitUpper32Bits = mvPciIfConfigRead(pciIf,
70188+ bus,dev,func,
70189+ P2P_PREF_LIMIT_UPPER_32);
70190+
70191+ break;
70192+
70193+ }
70194+
70195+ }
70196+ else /* no bridge */
70197+ {
70198+ /* Read PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID */
70199+ pciData = mvPciIfConfigRead(pciIf,
70200+ bus,dev,func,
70201+ PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID);
70202+
70203+
70204+ pPciAgent->subSysVenID =
70205+ (pciData & PSISVIR_VENID_MASK) >> PSISVIR_VENID_OFFS;
70206+ pPciAgent->subSysID =
70207+ (pciData & PSISVIR_DEVID_MASK) >> PSISVIR_DEVID_OFFS;
70208+
70209+
70210+ /* Read PCI_EXPANSION_ROM_BASE_ADDR_REG */
70211+ pciData = mvPciIfConfigRead(pciIf,
70212+ bus,dev,func,
70213+ PCI_EXPANSION_ROM_BASE_ADDR_REG);
70214+
70215+
70216+ if (pciData & PERBAR_EXPROMEN)
70217+ {
70218+ pPciAgent->isExpRom = MV_TRUE;
70219+ }
70220+ else
70221+ {
70222+ pPciAgent->isExpRom = MV_FALSE;
70223+ }
70224+
70225+ pPciAgent->expRomAddr =
70226+ (pciData & PERBAR_BASE_MASK) >> PERBAR_BASE_OFFS;
70227+
70228+ }
70229+
70230+
70231+ if (MV_TRUE == pPciAgent->isCapListSupport)
70232+ {
70233+ /* Read PCI_CAPABILTY_LIST_POINTER */
70234+ pciData = mvPciIfConfigRead(pciIf,
70235+ bus,dev,func,
70236+ PCI_CAPABILTY_LIST_POINTER);
70237+
70238+ pPciAgent->capListPointer =
70239+ (pciData & PCLPR_CAPPTR_MASK) >> PCLPR_CAPPTR_OFFS;
70240+
70241+ }
70242+
70243+ /* Read PCI_INTERRUPT_PIN_AND_LINE */
70244+ pciData = mvPciIfConfigRead(pciIf,
70245+ bus,dev,func,
70246+ PCI_INTERRUPT_PIN_AND_LINE);
70247+
70248+
70249+ pPciAgent->irqLine=
70250+ (pciData & PIPLR_INTLINE_MASK) >> PIPLR_INTLINE_OFFS;
70251+
70252+ pPciAgent->intPin=
70253+ (MV_PCI_INT_PIN)(pciData & PIPLR_INTPIN_MASK) >> PIPLR_INTPIN_OFFS;
70254+
70255+ pPciAgent->minGrant=
70256+ (pciData & PIPLR_MINGRANT_MASK) >> PIPLR_MINGRANT_OFFS;
70257+ pPciAgent->maxLatency=
70258+ (pciData & PIPLR_MAXLATEN_MASK) >> PIPLR_MAXLATEN_OFFS;
70259+
70260+ mvPciClassNameGet(pPciAgent->baseClassCode,
70261+ (MV_8 *)pPciAgent->type);
70262+
70263+ return MV_OK;
70264+
70265+
70266+}
70267+
70268+/*******************************************************************************
70269+* pciDetectDeviceBars - Detect a pci device bars
70270+*
70271+* DESCRIPTION:
70272+* This function detects all pci agent bars
70273+*
70274+* INPUT:
70275+* pciIf - PCI Interface
70276+* bus - Bus number
70277+* dev - Device number
70278+* func - Function number
70279+*
70280+*
70281+*
70282+* OUTPUT:
70283+* pPciAgent - pointer to the pci agent filled with its information
70284+*
70285+* RETURN:
70286+* detected bars number
70287+*
70288+*******************************************************************************/
70289+static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
70290+ MV_U32 bus,
70291+ MV_U32 dev,
70292+ MV_U32 func,
70293+ MV_PCI_DEVICE *pPciAgent)
70294+{
70295+ MV_U32 pciData,barIndex,detectedBar=0;
70296+ MV_U32 tmpBaseHigh=0,tmpBaseLow=0;
70297+ MV_U32 pciMaxBars=0;
70298+
70299+ pPciAgent->barsNum=0;
70300+
70301+ /* check if we are bridge*/
70302+ if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
70303+ (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
70304+ {
70305+ pciMaxBars = 2;
70306+ }
70307+ else /* no bridge */
70308+ {
70309+ pciMaxBars = 6;
70310+ }
70311+
70312+ /* read this device pci bars */
70313+ for (barIndex = 0 ; barIndex < pciMaxBars ; barIndex++ )
70314+ {
70315+ /* Read PCI_MEMORY_BAR_BASE_ADDR */
70316+ tmpBaseLow = pciData = mvPciIfConfigRead(pciIf,
70317+ bus,dev,func,
70318+ PCI_MEMORY_BAR_BASE_ADDR(barIndex));
70319+
70320+ pPciAgent->pciBar[detectedBar].barOffset =
70321+ PCI_MEMORY_BAR_BASE_ADDR(barIndex);
70322+
70323+ /* check if the bar is 32bit or 64bit bar */
70324+ switch (pciData & PBBLR_TYPE_MASK)
70325+ {
70326+ case PBBLR_TYPE_32BIT_ADDR:
70327+ pPciAgent->pciBar[detectedBar].barType = PCI_32BIT_BAR;
70328+ break;
70329+ case PBBLR_TYPE_64BIT_ADDR:
70330+ pPciAgent->pciBar[detectedBar].barType = PCI_64BIT_BAR;
70331+ break;
70332+
70333+ }
70334+
70335+ /* check if it is memory or IO bar */
70336+ if (pciData & PBBLR_IOSPACE)
70337+ {
70338+ pPciAgent->pciBar[detectedBar].barMapping=PCI_IO_BAR;
70339+ }
70340+ else
70341+ {
70342+ pPciAgent->pciBar[detectedBar].barMapping=PCI_MEMORY_BAR;
70343+ }
70344+
70345+ /* if it is memory bar then check if it is prefetchable */
70346+ if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
70347+ {
70348+ if (pciData & PBBLR_PREFETCH_EN)
70349+ {
70350+ pPciAgent->pciBar[detectedBar].isPrefetchable = MV_TRUE;
70351+ }
70352+ else
70353+ {
70354+ pPciAgent->pciBar[detectedBar].isPrefetchable = MV_FALSE;
70355+ }
70356+
70357+ pPciAgent->pciBar[detectedBar].barBaseLow =
70358+ pciData & PBBLR_MEM_BASE_MASK;
70359+
70360+
70361+ }
70362+ else /* IO Bar */
70363+ {
70364+ pPciAgent->pciBar[detectedBar].barBaseLow =
70365+ pciData & PBBLR_IO_BASE_MASK;
70366+
70367+ }
70368+
70369+ pPciAgent->pciBar[detectedBar].barBaseHigh=0;
70370+
70371+ if (PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType)
70372+ {
70373+ barIndex++;
70374+
70375+ tmpBaseHigh = pPciAgent->pciBar[detectedBar].barBaseHigh =
70376+ mvPciIfConfigRead(pciIf,
70377+ bus,dev,func,
70378+ PCI_MEMORY_BAR_BASE_ADDR(barIndex));
70379+
70380+
70381+ }
70382+
70383+ /* calculating full base address (64bit) */
70384+ pPciAgent->pciBar[detectedBar].barBaseAddr =
70385+ (MV_U64)pPciAgent->pciBar[detectedBar].barBaseHigh;
70386+
70387+ pPciAgent->pciBar[detectedBar].barBaseAddr <<= 32;
70388+
70389+ pPciAgent->pciBar[detectedBar].barBaseAddr |=
70390+ (MV_U64)pPciAgent->pciBar[detectedBar].barBaseLow;
70391+
70392+
70393+
70394+ /* get the sizes of the the bar */
70395+
70396+ pPciAgent->pciBar[detectedBar].barSizeHigh=0;
70397+
70398+ if ((PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType) &&
70399+ (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping))
70400+
70401+ {
70402+ /* write oxffffffff to the bar to get the size */
70403+ /* start with sizelow ( original value was saved in tmpBaseLow ) */
70404+ mvPciIfConfigWrite(pciIf,
70405+ bus,dev,func,
70406+ PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
70407+ 0xffffffff);
70408+
70409+ /* read size */
70410+ pPciAgent->pciBar[detectedBar].barSizeLow =
70411+ mvPciIfConfigRead(pciIf,
70412+ bus,dev,func,
70413+ PCI_MEMORY_BAR_BASE_ADDR(barIndex-1));
70414+
70415+
70416+
70417+ /* restore original value */
70418+ mvPciIfConfigWrite(pciIf,
70419+ bus,dev,func,
70420+ PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
70421+ tmpBaseLow);
70422+
70423+
70424+ /* now do the same for BaseHigh */
70425+
70426+ /* write oxffffffff to the bar to get the size */
70427+ mvPciIfConfigWrite(pciIf,
70428+ bus,dev,func,
70429+ PCI_MEMORY_BAR_BASE_ADDR(barIndex),
70430+ 0xffffffff);
70431+
70432+ /* read size */
70433+ pPciAgent->pciBar[detectedBar].barSizeHigh =
70434+ mvPciIfConfigRead(pciIf,
70435+ bus,dev,func,
70436+ PCI_MEMORY_BAR_BASE_ADDR(barIndex));
70437+
70438+ /* restore original value */
70439+ mvPciIfConfigWrite(pciIf,
70440+ bus,dev,func,
70441+ PCI_MEMORY_BAR_BASE_ADDR(barIndex),
70442+ tmpBaseHigh);
70443+
70444+ if ((0 == pPciAgent->pciBar[detectedBar].barSizeLow)&&
70445+ (0 == pPciAgent->pciBar[detectedBar].barSizeHigh))
70446+ {
70447+ /* this bar is not applicable for this device,
70448+ ignore all previous settings and check the next bar*/
70449+
70450+ /* we though this was a 64bit bar , and it seems this
70451+ was wrong ! so decrement barIndex */
70452+ barIndex--;
70453+ continue;
70454+ }
70455+
70456+ /* calculate the full 64 bit size */
70457+
70458+ if (0 != pPciAgent->pciBar[detectedBar].barSizeHigh)
70459+ {
70460+ pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
70461+
70462+ pPciAgent->pciBar[detectedBar].barSizeLow =
70463+ ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
70464+
70465+ pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
70466+
70467+ }
70468+ else
70469+ {
70470+
70471+ pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
70472+
70473+ pPciAgent->pciBar[detectedBar].barSizeLow =
70474+ ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
70475+
70476+ pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
70477+
70478+ }
70479+
70480+
70481+
70482+ }
70483+ else /* 32bit bar */
70484+ {
70485+ /* write oxffffffff to the bar to get the size */
70486+ mvPciIfConfigWrite(pciIf,
70487+ bus,dev,func,
70488+ PCI_MEMORY_BAR_BASE_ADDR(barIndex),
70489+ 0xffffffff);
70490+
70491+ /* read size */
70492+ pPciAgent->pciBar[detectedBar].barSizeLow =
70493+ mvPciIfConfigRead(pciIf,
70494+ bus,dev,func,
70495+ PCI_MEMORY_BAR_BASE_ADDR(barIndex));
70496+
70497+ if (0 == pPciAgent->pciBar[detectedBar].barSizeLow)
70498+ {
70499+ /* this bar is not applicable for this device,
70500+ ignore all previous settings and check the next bar*/
70501+ continue;
70502+ }
70503+
70504+
70505+ /* restore original value */
70506+ mvPciIfConfigWrite(pciIf,
70507+ bus,dev,func,
70508+ PCI_MEMORY_BAR_BASE_ADDR(barIndex),
70509+ tmpBaseLow);
70510+
70511+ /* calculate size low */
70512+
70513+ if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
70514+ {
70515+ pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
70516+ }
70517+ else
70518+ {
70519+ pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_IO_BASE_MASK;
70520+ }
70521+
70522+ pPciAgent->pciBar[detectedBar].barSizeLow =
70523+ ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
70524+
70525+ pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
70526+ pPciAgent->pciBar[detectedBar].barSize =
70527+ (MV_U64)pPciAgent->pciBar[detectedBar].barSizeLow;
70528+
70529+
70530+ }
70531+
70532+ /* we are here ! this means we have already detected a bar for
70533+ this device , now move on */
70534+
70535+ detectedBar++;
70536+ pPciAgent->barsNum++;
70537+ }
70538+
70539+ return detectedBar;
70540+}
70541+
70542+
70543+/*******************************************************************************
70544+* mvPciClassNameGet - get PCI class name
70545+*
70546+* DESCRIPTION:
70547+* This function returns the PCI class name
70548+*
70549+* INPUT:
70550+* baseClassCode - Base Class Code.
70551+*
70552+* OUTPUT:
70553+* pType - the class name
70554+*
70555+* RETURN:
70556+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
70557+*
70558+*******************************************************************************/
70559+MV_STATUS mvPciClassNameGet(MV_U32 baseClassCode, MV_8 *pType)
70560+{
70561+
70562+ switch(baseClassCode)
70563+ {
70564+ case 0x0:
70565+ strcpy(pType,"Old generation device");
70566+ break;
70567+ case 0x1:
70568+ strcpy(pType,"Mass storage controller");
70569+ break;
70570+ case 0x2:
70571+ strcpy(pType,"Network controller");
70572+ break;
70573+ case 0x3:
70574+ strcpy(pType,"Display controller");
70575+ break;
70576+ case 0x4:
70577+ strcpy(pType,"Multimedia device");
70578+ break;
70579+ case 0x5:
70580+ strcpy(pType,"Memory controller");
70581+ break;
70582+ case 0x6:
70583+ strcpy(pType,"Bridge Device");
70584+ break;
70585+ case 0x7:
70586+ strcpy(pType,"Simple Communication controllers");
70587+ break;
70588+ case 0x8:
70589+ strcpy(pType,"Base system peripherals");
70590+ break;
70591+ case 0x9:
70592+ strcpy(pType,"Input Devices");
70593+ break;
70594+ case 0xa:
70595+ strcpy(pType,"Docking stations");
70596+ break;
70597+ case 0xb:
70598+ strcpy(pType,"Processors");
70599+ break;
70600+ case 0xc:
70601+ strcpy(pType,"Serial bus controllers");
70602+ break;
70603+ case 0xd:
70604+ strcpy(pType,"Wireless controllers");
70605+ break;
70606+ case 0xe:
70607+ strcpy(pType,"Intelligent I/O controllers");
70608+ break;
70609+ case 0xf:
70610+ strcpy(pType,"Satellite communication controllers");
70611+ break;
70612+ case 0x10:
70613+ strcpy(pType,"Encryption/Decryption controllers");
70614+ break;
70615+ case 0x11:
70616+ strcpy(pType,"Data acquisition and signal processing controllers");
70617+ break;
70618+ default:
70619+ strcpy(pType,"Unknown device");
70620+ break;
70621+ }
70622+
70623+ return MV_OK;
70624+
70625+}
70626+
70627+
70628+
70629diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h b/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h
70630new file mode 100644
70631index 0000000..444f53c
70632--- /dev/null
70633+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h
70634@@ -0,0 +1,323 @@
70635+/*******************************************************************************
70636+Copyright (C) Marvell International Ltd. and its affiliates
70637+
70638+This software file (the "File") is owned and distributed by Marvell
70639+International Ltd. and/or its affiliates ("Marvell") under the following
70640+alternative licensing terms. Once you have made an election to distribute the
70641+File under one of the following license alternatives, please (i) delete this
70642+introductory statement regarding license alternatives, (ii) delete the two
70643+license alternatives that you have not elected to use and (iii) preserve the
70644+Marvell copyright notice above.
70645+
70646+********************************************************************************
70647+Marvell Commercial License Option
70648+
70649+If you received this File from Marvell and you have entered into a commercial
70650+license agreement (a "Commercial License") with Marvell, the File is licensed
70651+to you under the terms of the applicable Commercial License.
70652+
70653+********************************************************************************
70654+Marvell GPL License Option
70655+
70656+If you received this File from Marvell, you may opt to use, redistribute and/or
70657+modify this File in accordance with the terms and conditions of the General
70658+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
70659+available along with the File in the license.txt file or by writing to the Free
70660+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
70661+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
70662+
70663+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
70664+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
70665+DISCLAIMED. The GPL License provides additional details about this warranty
70666+disclaimer.
70667+********************************************************************************
70668+Marvell BSD License Option
70669+
70670+If you received this File from Marvell, you may opt to use, redistribute and/or
70671+modify this File under the following licensing terms.
70672+Redistribution and use in source and binary forms, with or without modification,
70673+are permitted provided that the following conditions are met:
70674+
70675+ * Redistributions of source code must retain the above copyright notice,
70676+ this list of conditions and the following disclaimer.
70677+
70678+ * Redistributions in binary form must reproduce the above copyright
70679+ notice, this list of conditions and the following disclaimer in the
70680+ documentation and/or other materials provided with the distribution.
70681+
70682+ * Neither the name of Marvell nor the names of its contributors may be
70683+ used to endorse or promote products derived from this software without
70684+ specific prior written permission.
70685+
70686+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
70687+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70688+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70689+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
70690+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70691+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70692+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
70693+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70694+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70695+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70696+
70697+*******************************************************************************/
70698+
70699+#ifndef __INCmvPciUtilsh
70700+#define __INCmvPciUtilsh
70701+
70702+/*
70703+This module only support scanning of Header type 00h of pci devices
70704+There is no suppotr for Header type 01h of pci devices ( PCI bridges )
70705+*/
70706+
70707+/* includes */
70708+#include "mvSysHwConfig.h"
70709+#include "pci-if/mvPciIf.h"
70710+#include "pci/mvPciRegs.h"
70711+
70712+
70713+
70714+/* PCI base address low bar mask */
70715+#define PCI_ERROR_CODE 0xffffffff
70716+
70717+#define PCI_BRIDGE_CLASS 0x6
70718+#define P2P_BRIDGE_SUB_CLASS_CODE 0x4
70719+
70720+
70721+#define P2P_BUSSES_NUM 0x18
70722+#define P2P_IO_BASE_LIMIT_SEC_STATUS 0x1C
70723+#define P2P_MEM_BASE_LIMIT 0x20
70724+#define P2P_PREF_MEM_BASE_LIMIT 0x24
70725+#define P2P_PREF_BASE_UPPER_32 0x28
70726+#define P2P_PREF_LIMIT_UPPER_32 0x2C
70727+#define P2P_IO_BASE_LIMIT_UPPER_16 0x30
70728+#define P2P_EXP_ROM 0x38
70729+
70730+/* P2P_BUSSES_NUM (PBM) */
70731+
70732+#define PBM_PRIME_BUS_NUM_OFFS 0
70733+#define PBM_PRIME_BUS_NUM_MASK (0xff << PBM_PRIME_BUS_NUM_OFFS)
70734+
70735+#define PBM_SEC_BUS_NUM_OFFS 8
70736+#define PBM_SEC_BUS_NUM_MASK (0xff << PBM_SEC_BUS_NUM_OFFS)
70737+
70738+#define PBM_SUB_BUS_NUM_OFFS 16
70739+#define PBM_SUB_BUS_NUM_MASK (0xff << PBM_SUB_BUS_NUM_OFFS)
70740+
70741+#define PBM_SEC_LAT_TMR_OFFS 24
70742+#define PBM_SEC_LAT_TMR_MASK (0xff << PBM_SEC_LAT_TMR_OFFS)
70743+
70744+/* P2P_IO_BASE_LIMIT_SEC_STATUS (PIBLSS) */
70745+
70746+#define PIBLSS_IO_BASE_OFFS 0
70747+#define PIBLSS_IO_BASE_MASK (0xff << PIBLSS_IO_BASE_OFFS)
70748+
70749+#define PIBLSS_ADD_CAP_OFFS 0
70750+#define PIBLSS_ADD_CAP_MASK (0x3 << PIBLSS_ADD_CAP_OFFS)
70751+#define PIBLSS_ADD_CAP_16BIT (0x0 << PIBLSS_ADD_CAP_OFFS)
70752+#define PIBLSS_ADD_CAP_32BIT (0x1 << PIBLSS_ADD_CAP_OFFS)
70753+
70754+#define PIBLSS_LOW_ADDR_OFFS 0
70755+#define PIBLSS_LOW_ADDR_MASK (0xFFF << PIBLSS_LOW_ADDR_OFFS)
70756+
70757+#define PIBLSS_HIGH_ADDR_OFFS 12
70758+#define PIBLSS_HIGH_ADDR_MASK (0xF << PIBLSS_HIGH_ADDR_OFFS)
70759+
70760+#define PIBLSS_IO_LIMIT_OFFS 8
70761+#define PIBLSS_IO_LIMIT_MASK (0xff << PIBLSS_IO_LIMIT_OFFS)
70762+
70763+#define PIBLSS_SEC_STATUS_OFFS 16
70764+#define PIBLSS_SEC_STATUS_MASK (0xffff << PIBLSS_SEC_STATUS_OFFS)
70765+
70766+
70767+/* P2P_MEM_BASE_LIMIT (PMBL)*/
70768+
70769+#define PMBL_MEM_BASE_OFFS 0
70770+#define PMBL_MEM_BASE_MASK (0xffff << PMBL_MEM_BASE_OFFS)
70771+
70772+#define PMBL_MEM_LIMIT_OFFS 16
70773+#define PMBL_MEM_LIMIT_MASK (0xffff << PMBL_MEM_LIMIT_OFFS)
70774+
70775+
70776+#define PMBL_LOW_ADDR_OFFS 0
70777+#define PMBL_LOW_ADDR_MASK (0xFFFFF << PMBL_LOW_ADDR_OFFS)
70778+
70779+#define PMBL_HIGH_ADDR_OFFS 20
70780+#define PMBL_HIGH_ADDR_MASK (0xFFF << PMBL_HIGH_ADDR_OFFS)
70781+
70782+
70783+/* P2P_PREF_MEM_BASE_LIMIT (PRMBL) */
70784+
70785+#define PRMBL_PREF_MEM_BASE_OFFS 0
70786+#define PRMBL_PREF_MEM_BASE_MASK (0xffff << PRMBL_PREF_MEM_BASE_OFFS)
70787+
70788+#define PRMBL_PREF_MEM_LIMIT_OFFS 16
70789+#define PRMBL_PREF_MEM_LIMIT_MASK (0xffff<<PRMBL_PREF_MEM_LIMIT_OFFS)
70790+
70791+#define PRMBL_LOW_ADDR_OFFS 0
70792+#define PRMBL_LOW_ADDR_MASK (0xFFFFF << PRMBL_LOW_ADDR_OFFS)
70793+
70794+#define PRMBL_HIGH_ADDR_OFFS 20
70795+#define PRMBL_HIGH_ADDR_MASK (0xFFF << PRMBL_HIGH_ADDR_OFFS)
70796+
70797+#define PRMBL_ADD_CAP_OFFS 0
70798+#define PRMBL_ADD_CAP_MASK (0xf << PRMBL_ADD_CAP_OFFS)
70799+#define PRMBL_ADD_CAP_32BIT (0x0 << PRMBL_ADD_CAP_OFFS)
70800+#define PRMBL_ADD_CAP_64BIT (0x1 << PRMBL_ADD_CAP_OFFS)
70801+
70802+/* P2P_IO_BASE_LIMIT_UPPER_16 (PIBLU) */
70803+
70804+#define PRBU_IO_UPP_BASE_OFFS 0
70805+#define PRBU_IO_UPP_BASE_MASK (0xffff << PRBU_IO_UPP_BASE_OFFS)
70806+
70807+#define PRBU_IO_UPP_LIMIT_OFFS 16
70808+#define PRBU_IO_UPP_LIMIT_MASK (0xffff << PRBU_IO_UPP_LIMIT_OFFS)
70809+
70810+
70811+/* typedefs */
70812+
70813+typedef enum _mvPciBarMapping
70814+{
70815+ PCI_MEMORY_BAR,
70816+ PCI_IO_BAR,
70817+ PCI_NO_MAPPING
70818+}MV_PCI_BAR_MAPPING;
70819+
70820+typedef enum _mvPciBarType
70821+{
70822+ PCI_32BIT_BAR,
70823+ PCI_64BIT_BAR
70824+}MV_PCI_BAR_TYPE;
70825+
70826+typedef enum _mvPciIntPin
70827+{
70828+ MV_PCI_INTA = 1,
70829+ MV_PCI_INTB = 2,
70830+ MV_PCI_INTC = 3,
70831+ MV_PCI_INTD = 4
70832+}MV_PCI_INT_PIN;
70833+
70834+typedef enum _mvPciHeader
70835+{
70836+ MV_PCI_STANDARD,
70837+ MV_PCI_PCI2PCI_BRIDGE
70838+
70839+}MV_PCI_HEADER;
70840+
70841+
70842+/* BAR structure */
70843+typedef struct _pciBar
70844+{
70845+ MV_U32 barOffset;
70846+ MV_U32 barBaseLow;
70847+ MV_U32 barBaseHigh;
70848+ MV_U32 barSizeLow;
70849+ MV_U32 barSizeHigh;
70850+ /* The 'barBaseAddr' is a 64-bit variable
70851+ that will contain the TOTAL base address
70852+ value achived by combining both the 'barBaseLow'
70853+ and the 'barBaseHigh' parameters as follows:
70854+
70855+ BIT: 63 31 0
70856+ | | |
70857+ barBaseHigh barBaseLow */
70858+ MV_U64 barBaseAddr;
70859+ /* The 'barSize' is a 64-bit variable
70860+ that will contain the TOTAL size achived
70861+ by combining both the 'barSizeLow' and
70862+ the 'barSizeHigh' parameters as follows:
70863+
70864+ BIT: 63 31 0
70865+ | | |
70866+ barSizeHigh barSizeLow
70867+
70868+ NOTE: The total size described above
70869+ is AFTER the size calculation as
70870+ described in PCI spec rev2.2 */
70871+ MV_U64 barSize;
70872+ MV_BOOL isPrefetchable;
70873+ MV_PCI_BAR_TYPE barType;
70874+ MV_PCI_BAR_MAPPING barMapping;
70875+
70876+
70877+} PCI_BAR;
70878+
70879+/* Device information structure */
70880+typedef struct _mvPciDevice
70881+{
70882+ /* Device specific information */
70883+ MV_U32 busNumber; /* Pci agent bus number */
70884+ MV_U32 deviceNum; /* Pci agent device number */
70885+ MV_U32 function; /* Pci agent function number */
70886+
70887+ MV_U32 venID; /* Pci agent Vendor ID */
70888+ MV_U32 deviceID; /* Pci agent Device ID */
70889+
70890+ MV_BOOL isFastB2BCapable; /* Capability of Fast Back to Back
70891+ transactions */
70892+ MV_BOOL isCapListSupport; /* Support of Capability list */
70893+ MV_BOOL is66MHZCapable; /* 66MHZ support */
70894+
70895+ MV_U32 baseClassCode; /* Pci agent base Class Code */
70896+ MV_U32 subClassCode; /* Pci agent sub Class Code */
70897+ MV_U32 progIf; /* Pci agent Programing interface */
70898+ MV_U32 revisionID;
70899+
70900+ PCI_BAR pciBar[6]; /* Pci agent bar list */
70901+
70902+ MV_U32 p2pPrimBusNum; /* P2P Primary Bus number*/
70903+ MV_U32 p2pSecBusNum; /* P2P Secondary Bus Number*/
70904+ MV_U32 p2pSubBusNum; /* P2P Subordinate bus Number */
70905+ MV_U32 p2pSecLatencyTimer; /* P2P Econdary Latency Timer*/
70906+ MV_U32 p2pIObase; /* P2P IO Base */
70907+ MV_U32 p2pIOLimit; /* P2P IO Linit */
70908+ MV_BOOL bIO32;
70909+ MV_U32 p2pSecStatus; /* P2P Secondary Status */
70910+ MV_U32 p2pMemBase; /* P2P Memory Space */
70911+ MV_U32 p2pMemLimit; /* P2P Memory Limit*/
70912+ MV_U32 p2pPrefMemBase; /* P2P Prefetchable Mem Base*/
70913+ MV_U32 p2pPrefMemLimit; /* P2P Prefetchable Memory Limit*/
70914+ MV_BOOL bPrefMem64;
70915+ MV_U32 p2pPrefBaseUpper32Bits;/* P2P Prefetchable upper 32 bits*/
70916+ MV_U32 p2pPrefLimitUpper32Bits;/* P2P prefetchable limit upper 32*/
70917+
70918+
70919+ MV_U32 pciCacheLine; /* Pci agent cache line */
70920+ MV_U32 pciLatencyTimer; /* Pci agent Latency timer */
70921+ MV_PCI_HEADER pciHeader; /* Pci agent header type*/
70922+ MV_BOOL isMultiFunction; /* Multi function support */
70923+ MV_BOOL isBISTCapable; /* Self test capable */
70924+
70925+ MV_U32 subSysID; /* Sub System ID */
70926+ MV_U32 subSysVenID; /* Sub System Vendor ID */
70927+
70928+ MV_BOOL isExpRom; /* Expantion Rom support */
70929+ MV_U32 expRomAddr; /* Expantion Rom pointer */
70930+
70931+ MV_U32 capListPointer; /* Capability list pointer */
70932+
70933+ MV_U32 irqLine; /* IRQ line */
70934+ MV_PCI_INT_PIN intPin; /* Interrupt pin */
70935+ MV_U32 minGrant; /* Minimum grant*/
70936+ MV_U32 maxLatency; /* Maximum latency*/
70937+
70938+ MV_U32 funtionsNum; /* pci agent total functions number */
70939+
70940+ MV_U32 barsNum;
70941+ MV_U8 type[60]; /* class name of the pci agent */
70942+
70943+
70944+} MV_PCI_DEVICE;
70945+
70946+/* PCI gloabl functions */
70947+MV_STATUS mvPciClassNameGet(MV_U32 classCode, MV_8 *pType);
70948+
70949+
70950+/* Performs a full scan on both PCIs and returns all possible details on the
70951+ agents found on the bus. */
70952+MV_STATUS mvPciScan(MV_U32 pciIf,
70953+ MV_PCI_DEVICE *pPciAgents,
70954+ MV_U32 *pPciAgentsNum);
70955+
70956+
70957+#endif /* #ifndef __INCmvPciUtilsh */
70958diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c b/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c
70959new file mode 100644
70960index 0000000..5430f51
70961--- /dev/null
70962+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c
70963@@ -0,0 +1,1047 @@
70964+/*******************************************************************************
70965+Copyright (C) Marvell International Ltd. and its affiliates
70966+
70967+This software file (the "File") is owned and distributed by Marvell
70968+International Ltd. and/or its affiliates ("Marvell") under the following
70969+alternative licensing terms. Once you have made an election to distribute the
70970+File under one of the following license alternatives, please (i) delete this
70971+introductory statement regarding license alternatives, (ii) delete the two
70972+license alternatives that you have not elected to use and (iii) preserve the
70973+Marvell copyright notice above.
70974+
70975+********************************************************************************
70976+Marvell Commercial License Option
70977+
70978+If you received this File from Marvell and you have entered into a commercial
70979+license agreement (a "Commercial License") with Marvell, the File is licensed
70980+to you under the terms of the applicable Commercial License.
70981+
70982+********************************************************************************
70983+Marvell GPL License Option
70984+
70985+If you received this File from Marvell, you may opt to use, redistribute and/or
70986+modify this File in accordance with the terms and conditions of the General
70987+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
70988+available along with the File in the license.txt file or by writing to the Free
70989+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
70990+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
70991+
70992+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
70993+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
70994+DISCLAIMED. The GPL License provides additional details about this warranty
70995+disclaimer.
70996+********************************************************************************
70997+Marvell BSD License Option
70998+
70999+If you received this File from Marvell, you may opt to use, redistribute and/or
71000+modify this File under the following licensing terms.
71001+Redistribution and use in source and binary forms, with or without modification,
71002+are permitted provided that the following conditions are met:
71003+
71004+ * Redistributions of source code must retain the above copyright notice,
71005+ this list of conditions and the following disclaimer.
71006+
71007+ * Redistributions in binary form must reproduce the above copyright
71008+ notice, this list of conditions and the following disclaimer in the
71009+ documentation and/or other materials provided with the distribution.
71010+
71011+ * Neither the name of Marvell nor the names of its contributors may be
71012+ used to endorse or promote products derived from this software without
71013+ specific prior written permission.
71014+
71015+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
71016+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
71017+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
71018+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
71019+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
71020+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
71021+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
71022+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71023+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
71024+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71025+
71026+*******************************************************************************/
71027+#include "pci/mvPci.h"
71028+
71029+#include "ctrlEnv/mvCtrlEnvLib.h"
71030+
71031+/* defines */
71032+#ifdef MV_DEBUG
71033+ #define DB(x) x
71034+#else
71035+ #define DB(x)
71036+#endif
71037+
71038+
71039+
71040+MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod)
71041+{
71042+ if (MV_PCI_MOD_HOST == pciIfmod)
71043+ {
71044+
71045+ mvPciLocalBusNumSet(pciIf, PCI_HOST_BUS_NUM(pciIf));
71046+ mvPciLocalDevNumSet(pciIf, PCI_HOST_DEV_NUM(pciIf));
71047+
71048+ /* Local device master Enable */
71049+ mvPciMasterEnable(pciIf, MV_TRUE);
71050+
71051+ /* Local device slave Enable */
71052+ mvPciSlaveEnable(pciIf, mvPciLocalBusNumGet(pciIf),
71053+ mvPciLocalDevNumGet(pciIf), MV_TRUE);
71054+ }
71055+ /* enable CPU-2-PCI ordering */
71056+ MV_REG_BIT_SET(PCI_CMD_REG(0), PCR_CPU_TO_PCI_ORDER_EN);
71057+}
71058+
71059+/*******************************************************************************
71060+* mvPciCommandSet - Set PCI comman register value.
71061+*
71062+* DESCRIPTION:
71063+* This function sets a given PCI interface with its command register
71064+* value.
71065+*
71066+* INPUT:
71067+* pciIf - PCI interface number.
71068+* command - 32bit value to be written to comamnd register.
71069+*
71070+* OUTPUT:
71071+* None.
71072+*
71073+* RETURN:
71074+* MV_BAD_PARAM if pciIf is not in range otherwise MV_OK
71075+*
71076+*******************************************************************************/
71077+MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command)
71078+{
71079+ MV_U32 locBusNum, locDevNum, regVal;
71080+
71081+ locBusNum = mvPciLocalBusNumGet(pciIf);
71082+ locDevNum = mvPciLocalDevNumGet(pciIf);
71083+
71084+ /* Parameter checking */
71085+ if (pciIf >= mvCtrlPciMaxIfGet())
71086+ {
71087+ mvOsPrintf("mvPciCommandSet: ERR. Invalid PCI IF num %d\n", pciIf);
71088+ return MV_BAD_PARAM;
71089+ }
71090+
71091+ /* Set command register */
71092+ MV_REG_WRITE(PCI_CMD_REG(pciIf), command);
71093+
71094+ /* Upodate device max outstanding split tarnsaction */
71095+ if ((command & PCR_CPU_TO_PCI_ORDER_EN) &&
71096+ (command & PCR_PCI_TO_CPU_ORDER_EN))
71097+ {
71098+ /* Read PCI-X command register */
71099+ regVal = mvPciConfigRead (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND);
71100+
71101+ /* clear bits 22:20 */
71102+ regVal &= 0xff8fffff;
71103+
71104+ /* set reset value */
71105+ regVal |= (0x3 << 20);
71106+
71107+ /* Write back the value */
71108+ mvPciConfigWrite (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND, regVal);
71109+ }
71110+
71111+ return MV_OK;
71112+
71113+
71114+}
71115+
71116+
71117+/*******************************************************************************
71118+* mvPciModeGet - Get PCI interface mode.
71119+*
71120+* DESCRIPTION:
71121+* This function returns the given PCI interface mode.
71122+*
71123+* INPUT:
71124+* pciIf - PCI interface number.
71125+*
71126+* OUTPUT:
71127+* pPciMode - Pointer to PCI mode structure.
71128+*
71129+* RETURN:
71130+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
71131+*
71132+*******************************************************************************/
71133+MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode)
71134+{
71135+ MV_U32 pciMode;
71136+
71137+ /* Parameter checking */
71138+ if (pciIf >= mvCtrlPciMaxIfGet())
71139+ {
71140+ mvOsPrintf("mvPciModeGet: ERR. Invalid PCI interface %d\n", pciIf);
71141+ return MV_BAD_PARAM;
71142+ }
71143+ if (NULL == pPciMode)
71144+ {
71145+ mvOsPrintf("mvPciModeGet: ERR. pPciMode = NULL \n");
71146+ return MV_BAD_PARAM;
71147+ }
71148+
71149+ /* Read pci mode register */
71150+ pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));
71151+
71152+ switch (pciMode & PMR_PCI_MODE_MASK)
71153+ {
71154+ case PMR_PCI_MODE_CONV:
71155+ pPciMode->pciType = MV_PCI_CONV;
71156+
71157+ if (MV_REG_READ(PCI_DLL_CTRL_REG(pciIf)) & PDC_DLL_EN)
71158+ {
71159+ pPciMode->pciSpeed = 66000000; /* 66MHZ */
71160+ }
71161+ else
71162+ {
71163+ pPciMode->pciSpeed = 33000000; /* 33MHZ */
71164+ }
71165+
71166+ break;
71167+
71168+ case PMR_PCI_MODE_PCIX_66MHZ:
71169+ pPciMode->pciType = MV_PCIX;
71170+ pPciMode->pciSpeed = 66000000; /* 66MHZ */
71171+ break;
71172+
71173+ case PMR_PCI_MODE_PCIX_100MHZ:
71174+ pPciMode->pciType = MV_PCIX;
71175+ pPciMode->pciSpeed = 100000000; /* 100MHZ */
71176+ break;
71177+
71178+ case PMR_PCI_MODE_PCIX_133MHZ:
71179+ pPciMode->pciType = MV_PCIX;
71180+ pPciMode->pciSpeed = 133000000; /* 133MHZ */
71181+ break;
71182+
71183+ default:
71184+ {
71185+ mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");
71186+ return MV_ERROR;
71187+ }
71188+ }
71189+
71190+ switch (pciMode & PMR_PCI_64_MASK)
71191+ {
71192+ case PMR_PCI_64_64BIT:
71193+ pPciMode->pciWidth = MV_PCI_64;
71194+ break;
71195+
71196+ case PMR_PCI_64_32BIT:
71197+ pPciMode->pciWidth = MV_PCI_32;
71198+ break;
71199+
71200+ default:
71201+ {
71202+ mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");
71203+ return MV_ERROR;
71204+ }
71205+ }
71206+
71207+ return MV_OK;
71208+}
71209+
71210+/*******************************************************************************
71211+* mvPciRetrySet - Set PCI retry counters
71212+*
71213+* DESCRIPTION:
71214+* This function specifies the number of times the PCI controller
71215+* retries a transaction before it quits.
71216+* Applies to the PCI Master when acting as a requester.
71217+* Applies to the PCI slave when acting as a completer (PCI-X mode).
71218+* A 0x00 value means a "retry forever".
71219+*
71220+* INPUT:
71221+* pciIf - PCI interface number.
71222+* counter - Number of times PCI controller retry. Use counter value
71223+* up to PRR_RETRY_CNTR_MAX.
71224+*
71225+* OUTPUT:
71226+* None.
71227+*
71228+* RETURN:
71229+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
71230+*
71231+*******************************************************************************/
71232+MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter)
71233+{
71234+ MV_U32 pciRetry;
71235+
71236+ /* Parameter checking */
71237+ if (pciIf >= mvCtrlPciMaxIfGet())
71238+ {
71239+ mvOsPrintf("mvPciRetrySet: ERR. Invalid PCI interface %d\n", pciIf);
71240+ return MV_BAD_PARAM;
71241+ }
71242+
71243+ if (counter >= PRR_RETRY_CNTR_MAX)
71244+ {
71245+ mvOsPrintf("mvPciRetrySet: ERR. Invalid counter: %d\n", counter);
71246+ return MV_BAD_PARAM;
71247+
71248+ }
71249+
71250+ /* Reading PCI retry register */
71251+ pciRetry = MV_REG_READ(PCI_RETRY_REG(pciIf));
71252+
71253+ pciRetry &= ~PRR_RETRY_CNTR_MASK;
71254+
71255+ pciRetry |= (counter << PRR_RETRY_CNTR_OFFS);
71256+
71257+ /* write new value */
71258+ MV_REG_WRITE(PCI_RETRY_REG(pciIf), pciRetry);
71259+
71260+ return MV_OK;
71261+}
71262+
71263+
71264+/*******************************************************************************
71265+* mvPciDiscardTimerSet - Set PCI discard timer
71266+*
71267+* DESCRIPTION:
71268+* This function set PCI discard timer.
71269+* In conventional PCI mode:
71270+* Specifies the number of PCLK cycles the PCI slave keeps a non-accessed
71271+* read buffers (non-completed delayed read) before invalidate the buffer.
71272+* Set to '0' to disable the timer. The PCI slave waits for delayed
71273+* read completion forever.
71274+* In PCI-X mode:
71275+* Specifies the number of PCLK cycles the PCI master waits for split
71276+* completion transaction, before it invalidates the pre-allocated read
71277+* buffer.
71278+* Set to '0' to disable the timer. The PCI master waits for split
71279+* completion forever.
71280+* NOTE: Must be set to a number greater than MV_PCI_MAX_DISCARD_CLK,
71281+* unless using the "wait for ever" setting 0x0.
71282+* NOTE: Must not be updated while there are pending read requests.
71283+*
71284+* INPUT:
71285+* pciIf - PCI interface number.
71286+* pClkCycles - Number of PCI clock cycles.
71287+*
71288+* OUTPUT:
71289+* None.
71290+*
71291+* RETURN:
71292+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
71293+*
71294+*******************************************************************************/
71295+MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles)
71296+{
71297+ MV_U32 pciDiscardTimer;
71298+
71299+ /* Parameter checking */
71300+ if (pciIf >= mvCtrlPciMaxIfGet())
71301+ {
71302+ mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid PCI interface %d\n",
71303+ pciIf);
71304+ return MV_BAD_PARAM;
71305+ }
71306+
71307+ if (pClkCycles >= PDTR_TIMER_MIN)
71308+ {
71309+ mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid Clk value: %d\n",
71310+ pClkCycles);
71311+ return MV_BAD_PARAM;
71312+
71313+ }
71314+
71315+ /* Read PCI Discard Timer */
71316+ pciDiscardTimer = MV_REG_READ(PCI_DISCARD_TIMER_REG(pciIf));
71317+
71318+ pciDiscardTimer &= ~PDTR_TIMER_MASK;
71319+
71320+ pciDiscardTimer |= (pClkCycles << PDTR_TIMER_OFFS);
71321+
71322+ /* Write new value */
71323+ MV_REG_WRITE(PCI_DISCARD_TIMER_REG(pciIf), pciDiscardTimer);
71324+
71325+ return MV_OK;
71326+
71327+}
71328+
71329+/* PCI Arbiter routines */
71330+
71331+/*******************************************************************************
71332+* mvPciArbEnable - PCI arbiter enable/disable
71333+*
71334+* DESCRIPTION:
71335+* This fuction enable/disables a given PCI interface arbiter.
71336+* NOTE: Arbiter setting can not be changed while in work. It should only
71337+* be set once.
71338+* INPUT:
71339+* pciIf - PCI interface number.
71340+* enable - Enable/disable parameter. If enable = MV_TRUE then enable.
71341+*
71342+* OUTPUT:
71343+* None.
71344+*
71345+* RETURN:
71346+* None.
71347+*
71348+*******************************************************************************/
71349+MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable)
71350+{
71351+ MV_U32 regVal;
71352+
71353+ /* Parameter checking */
71354+ if (pciIf >= mvCtrlPciMaxIfGet())
71355+ {
71356+ mvOsPrintf("mvPciArbEnable: ERR. Invalid PCI interface %d\n", pciIf);
71357+ return MV_ERROR;
71358+ }
71359+
71360+ /* Set PCI Arbiter Control register according to default configuration */
71361+ regVal = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
71362+
71363+ /* Make sure arbiter disabled before changing its values */
71364+ MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
71365+
71366+ regVal &= ~PCI_ARBITER_CTRL_DEFAULT_MASK;
71367+
71368+ regVal |= PCI_ARBITER_CTRL_DEFAULT; /* Set default configuration */
71369+
71370+ if (MV_TRUE == enable)
71371+ {
71372+ regVal |= PACR_ARB_ENABLE;
71373+ }
71374+ else
71375+ {
71376+ regVal &= ~PACR_ARB_ENABLE;
71377+ }
71378+
71379+ /* Write to register */
71380+ MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), regVal);
71381+
71382+ return MV_OK;
71383+}
71384+
71385+
71386+/*******************************************************************************
71387+* mvPciArbParkDis - Disable arbiter parking on agent
71388+*
71389+* DESCRIPTION:
71390+* This function disables the PCI arbiter from parking on the given agent
71391+* list.
71392+*
71393+* INPUT:
71394+* pciIf - PCI interface number.
71395+* pciAgentMask - When a bit in the mask is set to '1', parking on
71396+* the associated PCI master is disabled. Mask bit
71397+* refers to bit 0 - 6. For example disable parking on PCI
71398+* agent 3 set pciAgentMask 0x4 (bit 3 is set).
71399+*
71400+* OUTPUT:
71401+* None.
71402+*
71403+* RETURN:
71404+* None.
71405+*
71406+*******************************************************************************/
71407+MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask)
71408+{
71409+ MV_U32 pciArbiterCtrl;
71410+
71411+ /* Parameter checking */
71412+ if (pciIf >= mvCtrlPciMaxIfGet())
71413+ {
71414+ mvOsPrintf("mvPciArbParkDis: ERR. Invalid PCI interface %d\n", pciIf);
71415+ return MV_ERROR;
71416+ }
71417+
71418+ /* Reading Arbiter Control register */
71419+ pciArbiterCtrl = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
71420+
71421+ /* Arbiter must be disabled before changing parking */
71422+ MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
71423+
71424+ /* do the change */
71425+ pciArbiterCtrl &= ~PACR_PARK_DIS_MASK;
71426+ pciArbiterCtrl |= (pciAgentMask << PACR_PARK_DIS_OFFS);
71427+
71428+ /* writing new value ( if th earbiter was enabled before the change */
71429+ /* here it will be reenabled */
71430+ MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);
71431+
71432+ return MV_OK;
71433+}
71434+
71435+
71436+/*******************************************************************************
71437+* mvPciArbBrokDetectSet - Set PCI arbiter broken detection
71438+*
71439+* DESCRIPTION:
71440+* This function sets the maximum number of cycles that the arbiter
71441+* waits for a PCI master to respond to its grant assertion. If a
71442+* PCI agent fails to respond within this time, the PCI arbiter aborts
71443+* the transaction and performs a new arbitration cycle.
71444+* NOTE: Value must be greater than '1' for conventional PCI and
71445+* greater than '5' for PCI-X.
71446+*
71447+* INPUT:
71448+* pciIf - PCI interface number.
71449+* pClkCycles - Number of PCI clock cycles. If equal to '0' the broken
71450+* master detection is disabled.
71451+*
71452+* OUTPUT:
71453+* None.
71454+*
71455+* RETURN:
71456+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
71457+*
71458+*******************************************************************************/
71459+MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles)
71460+{
71461+ MV_U32 pciArbiterCtrl;
71462+ MV_U32 pciMode;
71463+
71464+ /* Parameter checking */
71465+ if (pciIf >= mvCtrlPciMaxIfGet())
71466+ {
71467+ mvOsPrintf("mvPciArbBrokDetectSet: ERR. Invalid PCI interface %d\n",
71468+ pciIf);
71469+ return MV_BAD_PARAM;
71470+ }
71471+
71472+ /* Checking PCI mode and if pClkCycles is legal value */
71473+ pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));
71474+ pciMode &= PMR_PCI_MODE_MASK;
71475+
71476+ if (PMR_PCI_MODE_CONV == pciMode)
71477+ {
71478+ if (pClkCycles < PACR_BROKEN_VAL_CONV_MIN)
71479+ return MV_ERROR;
71480+ }
71481+ else
71482+ {
71483+ if (pClkCycles < PACR_BROKEN_VAL_PCIX_MIN)
71484+ return MV_ERROR;
71485+ }
71486+
71487+ pClkCycles <<= PACR_BROKEN_VAL_OFFS;
71488+
71489+ /* Reading Arbiter Control register */
71490+ pciArbiterCtrl = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
71491+ pciArbiterCtrl &= ~PACR_BROKEN_VAL_MASK;
71492+ pciArbiterCtrl |= pClkCycles;
71493+
71494+ /* Arbiter must be disabled before changing broken detection */
71495+ MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
71496+
71497+ /* writing new value ( if th earbiter was enabled before the change */
71498+ /* here it will be reenabled */
71499+
71500+ MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);
71501+
71502+ return MV_OK;
71503+}
71504+
71505+/* PCI configuration space read write */
71506+
71507+/*******************************************************************************
71508+* mvPciConfigRead - Read from configuration space
71509+*
71510+* DESCRIPTION:
71511+* This function performs a 32 bit read from PCI configuration space.
71512+* It supports both type 0 and type 1 of Configuration Transactions
71513+* (local and over bridge). In order to read from local bus segment, use
71514+* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
71515+* will result configuration transaction of type 1 (over bridge).
71516+*
71517+* INPUT:
71518+* pciIf - PCI interface number.
71519+* bus - PCI segment bus number.
71520+* dev - PCI device number.
71521+* func - Function number.
71522+* regOffs - Register offset.
71523+*
71524+* OUTPUT:
71525+* None.
71526+*
71527+* RETURN:
71528+* 32bit register data, 0xffffffff on error
71529+*
71530+*******************************************************************************/
71531+MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
71532+ MV_U32 regOff)
71533+{
71534+ MV_U32 pciData = 0;
71535+
71536+ /* Parameter checking */
71537+ if (PCI_DEFAULT_IF != pciIf)
71538+ {
71539+ if (pciIf >= mvCtrlPciMaxIfGet())
71540+ {
71541+ mvOsPrintf("mvPciConfigRead: ERR. Invalid PCI interface %d\n",pciIf);
71542+ return 0xFFFFFFFF;
71543+ }
71544+ }
71545+
71546+ if (dev >= MAX_PCI_DEVICES)
71547+ {
71548+ DB(mvOsPrintf("mvPciConfigRead: ERR. device number illigal %d\n", dev));
71549+ return 0xFFFFFFFF;
71550+ }
71551+
71552+ if (func >= MAX_PCI_FUNCS)
71553+ {
71554+ DB(mvOsPrintf("mvPciConfigRead: ERR. function number illigal %d\n", func));
71555+ return 0xFFFFFFFF;
71556+ }
71557+
71558+ if (bus >= MAX_PCI_BUSSES)
71559+ {
71560+ DB(mvOsPrintf("mvPciConfigRead: ERR. bus number illigal %d\n", bus));
71561+ return MV_ERROR;
71562+ }
71563+
71564+
71565+ /* Creating PCI address to be passed */
71566+ pciData |= (bus << PCAR_BUS_NUM_OFFS);
71567+ pciData |= (dev << PCAR_DEVICE_NUM_OFFS);
71568+ pciData |= (func << PCAR_FUNC_NUM_OFFS);
71569+ pciData |= (regOff & PCAR_REG_NUM_MASK);
71570+
71571+ pciData |= PCAR_CONFIG_EN;
71572+
71573+ /* Write the address to the PCI configuration address register */
71574+ MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);
71575+
71576+ /* In order to let the PCI controller absorbed the address of the read */
71577+ /* transaction we perform a validity check that the address was written */
71578+ if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))
71579+ {
71580+ return MV_ERROR;
71581+ }
71582+ /* Read the Data returned in the PCI Data register */
71583+ pciData = MV_REG_READ(PCI_CONFIG_DATA_REG(pciIf));
71584+
71585+ return pciData;
71586+}
71587+
71588+/*******************************************************************************
71589+* mvPciConfigWrite - Write to configuration space
71590+*
71591+* DESCRIPTION:
71592+* This function performs a 32 bit write to PCI configuration space.
71593+* It supports both type 0 and type 1 of Configuration Transactions
71594+* (local and over bridge). In order to write to local bus segment, use
71595+* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
71596+* will result configuration transaction of type 1 (over bridge).
71597+*
71598+* INPUT:
71599+* pciIf - PCI interface number.
71600+* bus - PCI segment bus number.
71601+* dev - PCI device number.
71602+* func - Function number.
71603+* regOffs - Register offset.
71604+* data - 32bit data.
71605+*
71606+* OUTPUT:
71607+* None.
71608+*
71609+* RETURN:
71610+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
71611+*
71612+*******************************************************************************/
71613+MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
71614+ MV_U32 func, MV_U32 regOff, MV_U32 data)
71615+{
71616+ MV_U32 pciData = 0;
71617+
71618+ /* Parameter checking */
71619+ if (PCI_DEFAULT_IF != pciIf)
71620+ {
71621+ if (pciIf >= mvCtrlPciMaxIfGet())
71622+ {
71623+ mvOsPrintf("mvPciConfigWrite: ERR. Invalid PCI interface %d\n",
71624+ pciIf);
71625+ return 0xFFFFFFFF;
71626+ }
71627+ }
71628+
71629+ if (dev >= MAX_PCI_DEVICES)
71630+ {
71631+ mvOsPrintf("mvPciConfigWrite: ERR. device number illigal %d\n",dev);
71632+ return MV_BAD_PARAM;
71633+ }
71634+
71635+ if (func >= MAX_PCI_FUNCS)
71636+ {
71637+ mvOsPrintf("mvPciConfigWrite: ERR. function number illigal %d\n", func);
71638+ return MV_ERROR;
71639+ }
71640+
71641+ if (bus >= MAX_PCI_BUSSES)
71642+ {
71643+ mvOsPrintf("mvPciConfigWrite: ERR. bus number illigal %d\n", bus);
71644+ return MV_ERROR;
71645+ }
71646+
71647+ /* Creating PCI address to be passed */
71648+ pciData |= (bus << PCAR_BUS_NUM_OFFS);
71649+ pciData |= (dev << PCAR_DEVICE_NUM_OFFS);
71650+ pciData |= (func << PCAR_FUNC_NUM_OFFS);
71651+ pciData |= (regOff & PCAR_REG_NUM_MASK);
71652+
71653+ pciData |= PCAR_CONFIG_EN;
71654+
71655+ /* Write the address to the PCI configuration address register */
71656+ MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);
71657+
71658+ /* In order to let the PCI controller absorbed the address of the read */
71659+ /* transaction we perform a validity check that the address was written */
71660+ if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))
71661+ {
71662+ return MV_ERROR;
71663+ }
71664+
71665+ /* Write the Data passed to the PCI Data register */
71666+ MV_REG_WRITE(PCI_CONFIG_DATA_REG(pciIf), data);
71667+
71668+ return MV_OK;
71669+}
71670+
71671+/*******************************************************************************
71672+* mvPciMasterEnable - Enable/disale PCI interface master transactions.
71673+*
71674+* DESCRIPTION:
71675+* This function performs read modified write to PCI command status
71676+* (offset 0x4) to set/reset bit 2. After this bit is set, the PCI
71677+* master is allowed to gain ownership on the bus, otherwise it is
71678+* incapable to do so.
71679+*
71680+* INPUT:
71681+* pciIf - PCI interface number.
71682+* enable - Enable/disable parameter.
71683+*
71684+* OUTPUT:
71685+* None.
71686+*
71687+* RETURN:
71688+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
71689+*
71690+*******************************************************************************/
71691+MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable)
71692+{
71693+ MV_U32 pciCommandStatus;
71694+ MV_U32 RegOffs;
71695+ MV_U32 localBus;
71696+ MV_U32 localDev;
71697+
71698+ /* Parameter checking */
71699+ if (pciIf >= mvCtrlPciMaxIfGet())
71700+ {
71701+ mvOsPrintf("mvPciMasterEnable: ERR. Invalid PCI interface %d\n", pciIf);
71702+ return MV_ERROR;
71703+ }
71704+
71705+ localBus = mvPciLocalBusNumGet(pciIf);
71706+ localDev = mvPciLocalDevNumGet(pciIf);
71707+
71708+ RegOffs = PCI_STATUS_AND_COMMAND;
71709+
71710+ pciCommandStatus = mvPciConfigRead(pciIf, localBus, localDev, 0, RegOffs);
71711+
71712+ if (MV_TRUE == enable)
71713+ {
71714+ pciCommandStatus |= PSCR_MASTER_EN;
71715+ }
71716+ else
71717+ {
71718+ pciCommandStatus &= ~PSCR_MASTER_EN;
71719+ }
71720+
71721+ mvPciConfigWrite(pciIf, localBus, localDev, 0, RegOffs, pciCommandStatus);
71722+
71723+ return MV_OK;
71724+}
71725+
71726+
71727+/*******************************************************************************
71728+* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.
71729+*
71730+* DESCRIPTION:
71731+* This function performs read modified write to PCI command status
71732+* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
71733+* the PCI slave is allowed to respond to PCI IO space access (bit 0)
71734+* and PCI memory space access (bit 1).
71735+*
71736+* INPUT:
71737+* pciIf - PCI interface number.
71738+* dev - PCI device number.
71739+* enable - Enable/disable parameter.
71740+*
71741+* OUTPUT:
71742+* None.
71743+*
71744+* RETURN:
71745+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
71746+*
71747+*******************************************************************************/
71748+MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_BOOL enable)
71749+{
71750+ MV_U32 pciCommandStatus;
71751+ MV_U32 RegOffs;
71752+
71753+ /* Parameter checking */
71754+ if (pciIf >= mvCtrlPciMaxIfGet())
71755+ {
71756+ mvOsPrintf("mvPciSlaveEnable: ERR. Invalid PCI interface %d\n", pciIf);
71757+ return MV_BAD_PARAM;
71758+ }
71759+ if (dev >= MAX_PCI_DEVICES)
71760+ {
71761+ mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n", dev);
71762+ return MV_BAD_PARAM;
71763+
71764+ }
71765+
71766+ RegOffs = PCI_STATUS_AND_COMMAND;
71767+
71768+ pciCommandStatus=mvPciConfigRead(pciIf, bus, dev, 0, RegOffs);
71769+
71770+ if (MV_TRUE == enable)
71771+ {
71772+ pciCommandStatus |= (PSCR_IO_EN | PSCR_MEM_EN);
71773+ }
71774+ else
71775+ {
71776+ pciCommandStatus &= ~(PSCR_IO_EN | PSCR_MEM_EN);
71777+ }
71778+
71779+ mvPciConfigWrite(pciIf, bus, dev, 0, RegOffs, pciCommandStatus);
71780+
71781+ return MV_OK;
71782+}
71783+
71784+/*******************************************************************************
71785+* mvPciLocalBusNumSet - Set PCI interface local bus number.
71786+*
71787+* DESCRIPTION:
71788+* This function sets given PCI interface its local bus number.
71789+* Note: In case the PCI interface is PCI-X, the information is read-only.
71790+*
71791+* INPUT:
71792+* pciIf - PCI interface number.
71793+* busNum - Bus number.
71794+*
71795+* OUTPUT:
71796+* None.
71797+*
71798+* RETURN:
71799+* MV_NOT_ALLOWED in case PCI interface is PCI-X.
71800+* MV_BAD_PARAM on bad parameters ,
71801+* otherwise MV_OK
71802+*
71803+*******************************************************************************/
71804+MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)
71805+{
71806+ MV_U32 pciP2PConfig;
71807+ MV_PCI_MODE pciMode;
71808+ MV_U32 localBus;
71809+ MV_U32 localDev;
71810+
71811+
71812+ /* Parameter checking */
71813+ if (pciIf >= mvCtrlPciMaxIfGet())
71814+ {
71815+ mvOsPrintf("mvPciLocalBusNumSet: ERR. Invalid PCI interface %d\n",pciIf);
71816+ return MV_BAD_PARAM;
71817+ }
71818+ if (busNum >= MAX_PCI_BUSSES)
71819+ {
71820+ mvOsPrintf("mvPciLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
71821+ return MV_ERROR;
71822+
71823+ }
71824+
71825+ localBus = mvPciLocalBusNumGet(pciIf);
71826+ localDev = mvPciLocalDevNumGet(pciIf);
71827+
71828+
71829+ /* PCI interface mode */
71830+ mvPciModeGet(pciIf, &pciMode);
71831+
71832+ /* if PCI type is PCI-X then it is not allowed to change the dev number */
71833+ if (MV_PCIX == pciMode.pciType)
71834+ {
71835+ pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );
71836+
71837+ pciP2PConfig &= ~PXS_BN_MASK;
71838+
71839+ pciP2PConfig |= (busNum << PXS_BN_OFFS) & PXS_BN_MASK;
71840+
71841+ mvPciConfigWrite(pciIf, localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );
71842+
71843+ }
71844+ else
71845+ {
71846+ pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
71847+
71848+ pciP2PConfig &= ~PPCR_BUS_NUM_MASK;
71849+
71850+ pciP2PConfig |= (busNum << PPCR_BUS_NUM_OFFS) & PPCR_BUS_NUM_MASK;
71851+
71852+ MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);
71853+
71854+ }
71855+
71856+
71857+ return MV_OK;
71858+}
71859+
71860+
71861+/*******************************************************************************
71862+* mvPciLocalBusNumGet - Get PCI interface local bus number.
71863+*
71864+* DESCRIPTION:
71865+* This function gets the local bus number of a given PCI interface.
71866+*
71867+* INPUT:
71868+* pciIf - PCI interface number.
71869+*
71870+* OUTPUT:
71871+* None.
71872+*
71873+* RETURN:
71874+* Local bus number.0xffffffff on Error
71875+*
71876+*******************************************************************************/
71877+MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf)
71878+{
71879+ MV_U32 pciP2PConfig;
71880+
71881+ /* Parameter checking */
71882+ if (PCI_DEFAULT_IF != pciIf)
71883+ {
71884+ if (pciIf >= mvCtrlPciMaxIfGet())
71885+ {
71886+ mvOsPrintf("mvPciLocalBusNumGet: ERR. Invalid PCI interface %d\n",
71887+ pciIf);
71888+ return 0xFFFFFFFF;
71889+ }
71890+ }
71891+
71892+ pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
71893+ pciP2PConfig &= PPCR_BUS_NUM_MASK;
71894+ return (pciP2PConfig >> PPCR_BUS_NUM_OFFS);
71895+}
71896+
71897+
71898+/*******************************************************************************
71899+* mvPciLocalDevNumSet - Set PCI interface local device number.
71900+*
71901+* DESCRIPTION:
71902+* This function sets given PCI interface its local device number.
71903+* Note: In case the PCI interface is PCI-X, the information is read-only.
71904+*
71905+* INPUT:
71906+* pciIf - PCI interface number.
71907+* devNum - Device number.
71908+*
71909+* OUTPUT:
71910+* None.
71911+*
71912+* RETURN:
71913+* MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,
71914+* otherwise MV_OK
71915+*
71916+*******************************************************************************/
71917+MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)
71918+{
71919+ MV_U32 pciP2PConfig;
71920+ MV_PCI_MODE pciMode;
71921+ MV_U32 localBus;
71922+ MV_U32 localDev;
71923+
71924+ /* Parameter checking */
71925+ if (pciIf >= mvCtrlPciMaxIfGet())
71926+ {
71927+ mvOsPrintf("mvPciLocalDevNumSet: ERR. Invalid PCI interface %d\n",pciIf);
71928+ return MV_BAD_PARAM;
71929+ }
71930+ if (devNum >= MAX_PCI_DEVICES)
71931+ {
71932+ mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n",
71933+ devNum);
71934+ return MV_BAD_PARAM;
71935+
71936+ }
71937+
71938+ localBus = mvPciLocalBusNumGet(pciIf);
71939+ localDev = mvPciLocalDevNumGet(pciIf);
71940+
71941+ /* PCI interface mode */
71942+ mvPciModeGet(pciIf, &pciMode);
71943+
71944+ /* if PCI type is PCIX then it is not allowed to change the dev number */
71945+ if (MV_PCIX == pciMode.pciType)
71946+ {
71947+ pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );
71948+
71949+ pciP2PConfig &= ~PXS_DN_MASK;
71950+
71951+ pciP2PConfig |= (devNum << PXS_DN_OFFS) & PXS_DN_MASK;
71952+
71953+ mvPciConfigWrite(pciIf,localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );
71954+ }
71955+ else
71956+ {
71957+ pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
71958+
71959+ pciP2PConfig &= ~PPCR_DEV_NUM_MASK;
71960+
71961+ pciP2PConfig |= (devNum << PPCR_DEV_NUM_OFFS) & PPCR_DEV_NUM_MASK;
71962+
71963+ MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);
71964+ }
71965+
71966+ return MV_OK;
71967+}
71968+
71969+/*******************************************************************************
71970+* mvPciLocalDevNumGet - Get PCI interface local device number.
71971+*
71972+* DESCRIPTION:
71973+* This function gets the local device number of a given PCI interface.
71974+*
71975+* INPUT:
71976+* pciIf - PCI interface number.
71977+*
71978+* OUTPUT:
71979+* None.
71980+*
71981+* RETURN:
71982+* Local device number. 0xffffffff on Error
71983+*
71984+*******************************************************************************/
71985+MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf)
71986+{
71987+ MV_U32 pciP2PConfig;
71988+
71989+ /* Parameter checking */
71990+
71991+ if (PCI_DEFAULT_IF != pciIf)
71992+ {
71993+ if (pciIf >= mvCtrlPciMaxIfGet())
71994+ {
71995+ mvOsPrintf("mvPciLocalDevNumGet: ERR. Invalid PCI interface %d\n",
71996+ pciIf);
71997+ return 0xFFFFFFFF;
71998+ }
71999+ }
72000+
72001+ pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
72002+
72003+ pciP2PConfig &= PPCR_DEV_NUM_MASK;
72004+
72005+ return (pciP2PConfig >> PPCR_DEV_NUM_OFFS);
72006+}
72007+
72008+
72009+
72010+
72011diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h b/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h
72012new file mode 100644
72013index 0000000..3c521db
72014--- /dev/null
72015+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h
72016@@ -0,0 +1,185 @@
72017+/*******************************************************************************
72018+Copyright (C) Marvell International Ltd. and its affiliates
72019+
72020+This software file (the "File") is owned and distributed by Marvell
72021+International Ltd. and/or its affiliates ("Marvell") under the following
72022+alternative licensing terms. Once you have made an election to distribute the
72023+File under one of the following license alternatives, please (i) delete this
72024+introductory statement regarding license alternatives, (ii) delete the two
72025+license alternatives that you have not elected to use and (iii) preserve the
72026+Marvell copyright notice above.
72027+
72028+********************************************************************************
72029+Marvell Commercial License Option
72030+
72031+If you received this File from Marvell and you have entered into a commercial
72032+license agreement (a "Commercial License") with Marvell, the File is licensed
72033+to you under the terms of the applicable Commercial License.
72034+
72035+********************************************************************************
72036+Marvell GPL License Option
72037+
72038+If you received this File from Marvell, you may opt to use, redistribute and/or
72039+modify this File in accordance with the terms and conditions of the General
72040+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
72041+available along with the File in the license.txt file or by writing to the Free
72042+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
72043+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
72044+
72045+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
72046+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
72047+DISCLAIMED. The GPL License provides additional details about this warranty
72048+disclaimer.
72049+********************************************************************************
72050+Marvell BSD License Option
72051+
72052+If you received this File from Marvell, you may opt to use, redistribute and/or
72053+modify this File under the following licensing terms.
72054+Redistribution and use in source and binary forms, with or without modification,
72055+are permitted provided that the following conditions are met:
72056+
72057+ * Redistributions of source code must retain the above copyright notice,
72058+ this list of conditions and the following disclaimer.
72059+
72060+ * Redistributions in binary form must reproduce the above copyright
72061+ notice, this list of conditions and the following disclaimer in the
72062+ documentation and/or other materials provided with the distribution.
72063+
72064+ * Neither the name of Marvell nor the names of its contributors may be
72065+ used to endorse or promote products derived from this software without
72066+ specific prior written permission.
72067+
72068+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
72069+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
72070+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72071+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
72072+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72073+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
72074+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
72075+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72076+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72077+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72078+
72079+*******************************************************************************/
72080+
72081+
72082+#ifndef __INCPCIH
72083+#define __INCPCIH
72084+
72085+#include "mvCommon.h"
72086+#include "mvOs.h"
72087+#include "ctrlEnv/mvCtrlEnvSpec.h"
72088+#include "pci/mvPciRegs.h"
72089+
72090+
72091+/* NOTE not supported in this driver:
72092+
72093+ Built In Self Test (BIST)
72094+ Vital Product Data (VPD)
72095+ Message Signaled Interrupt (MSI)
72096+ Power Management
72097+ Compact PCI Hot Swap
72098+ Header retarget
72099+
72100+Registers not supported:
72101+1) PCI DLL Status and Control (PCI0 0x1D20, PCI1 0x1DA0)
72102+2) PCI/MPP Pads Calibration (CI0/MPP[31:16] 0x1D1C, PCI1/MPP[15:0] 0X1D9C)
72103+*/
72104+
72105+/* defines */
72106+/* The number of supported PCI interfaces depend on Marvell controller */
72107+/* device number. This device number ID is located on the PCI unit */
72108+/* configuration header. This creates a loop where calling PCI */
72109+/* configuration read/write routine results a call to get PCI configuration */
72110+/* information etc. This macro defines a default PCI interface. This PCI */
72111+/* interface is sure to exist. */
72112+#define PCI_DEFAULT_IF 0
72113+
72114+
72115+/* typedefs */
72116+/* The Marvell controller supports both conventional PCI and PCI-X. */
72117+/* This enumeration describes the PCI type. */
72118+typedef enum _mvPciType
72119+{
72120+ MV_PCI_CONV, /* Conventional PCI */
72121+ MV_PCIX /* PCI-X */
72122+}MV_PCI_TYPE;
72123+
72124+typedef enum _mvPciMod
72125+{
72126+ MV_PCI_MOD_HOST,
72127+ MV_PCI_MOD_DEVICE
72128+}MV_PCI_MOD;
72129+
72130+
72131+/* The Marvell controller supports both PCI width of 32 and 64 bit. */
72132+/* This enumerator describes PCI width */
72133+typedef enum _mvPciWidth
72134+{
72135+ MV_PCI_32, /* PCI width 32bit */
72136+ MV_PCI_64 /* PCI width 64bit */
72137+}MV_PCI_WIDTH;
72138+
72139+/* This structure describes the PCI unit configured type, speed and width. */
72140+typedef struct _mvPciMode
72141+{
72142+ MV_PCI_TYPE pciType; /* PCI type */
72143+ MV_U32 pciSpeed; /* Assuming PCI base clock on board is 33MHz */
72144+ MV_PCI_WIDTH pciWidth; /* PCI bus width */
72145+}MV_PCI_MODE;
72146+
72147+/* mvPciInit - Initialize PCI interfaces*/
72148+MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod);
72149+
72150+/* mvPciCommandSet - Set PCI comman register value.*/
72151+MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command);
72152+
72153+/* mvPciModeGet - Get PCI interface mode.*/
72154+MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode);
72155+
72156+/* mvPciRetrySet - Set PCI retry counters*/
72157+MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter);
72158+
72159+/* mvPciDiscardTimerSet - Set PCI discard timer*/
72160+MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles);
72161+
72162+/* mvPciArbEnable - PCI arbiter enable/disable*/
72163+MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable);
72164+
72165+/* mvPciArbParkDis - Disable arbiter parking on agent */
72166+MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask);
72167+
72168+/* mvPciArbBrokDetectSet - Set PCI arbiter broken detection */
72169+MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles);
72170+
72171+/* mvPciConfigRead - Read from configuration space */
72172+MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
72173+ MV_U32 func,MV_U32 regOff);
72174+
72175+/* mvPciConfigWrite - Write to configuration space */
72176+MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
72177+ MV_U32 func, MV_U32 regOff, MV_U32 data);
72178+
72179+/* mvPciMasterEnable - Enable/disale PCI interface master transactions.*/
72180+MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable);
72181+
72182+/* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.*/
72183+MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,MV_BOOL enable);
72184+
72185+/* mvPciLocalBusNumSet - Set PCI interface local bus number.*/
72186+MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);
72187+
72188+/* mvPciLocalBusNumGet - Get PCI interface local bus number.*/
72189+MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf);
72190+
72191+/* mvPciLocalDevNumSet - Set PCI interface local device number.*/
72192+MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);
72193+
72194+/* mvPciLocalDevNumGet - Get PCI interface local device number.*/
72195+MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf);
72196+
72197+
72198+#endif /* #ifndef __INCPCIH */
72199+
72200+
72201+
72202diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h b/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h
72203new file mode 100644
72204index 0000000..9ae555f
72205--- /dev/null
72206+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h
72207@@ -0,0 +1,411 @@
72208+/*******************************************************************************
72209+Copyright (C) Marvell International Ltd. and its affiliates
72210+
72211+This software file (the "File") is owned and distributed by Marvell
72212+International Ltd. and/or its affiliates ("Marvell") under the following
72213+alternative licensing terms. Once you have made an election to distribute the
72214+File under one of the following license alternatives, please (i) delete this
72215+introductory statement regarding license alternatives, (ii) delete the two
72216+license alternatives that you have not elected to use and (iii) preserve the
72217+Marvell copyright notice above.
72218+
72219+********************************************************************************
72220+Marvell Commercial License Option
72221+
72222+If you received this File from Marvell and you have entered into a commercial
72223+license agreement (a "Commercial License") with Marvell, the File is licensed
72224+to you under the terms of the applicable Commercial License.
72225+
72226+********************************************************************************
72227+Marvell GPL License Option
72228+
72229+If you received this File from Marvell, you may opt to use, redistribute and/or
72230+modify this File in accordance with the terms and conditions of the General
72231+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
72232+available along with the File in the license.txt file or by writing to the Free
72233+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
72234+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
72235+
72236+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
72237+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
72238+DISCLAIMED. The GPL License provides additional details about this warranty
72239+disclaimer.
72240+********************************************************************************
72241+Marvell BSD License Option
72242+
72243+If you received this File from Marvell, you may opt to use, redistribute and/or
72244+modify this File under the following licensing terms.
72245+Redistribution and use in source and binary forms, with or without modification,
72246+are permitted provided that the following conditions are met:
72247+
72248+ * Redistributions of source code must retain the above copyright notice,
72249+ this list of conditions and the following disclaimer.
72250+
72251+ * Redistributions in binary form must reproduce the above copyright
72252+ notice, this list of conditions and the following disclaimer in the
72253+ documentation and/or other materials provided with the distribution.
72254+
72255+ * Neither the name of Marvell nor the names of its contributors may be
72256+ used to endorse or promote products derived from this software without
72257+ specific prior written permission.
72258+
72259+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
72260+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
72261+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72262+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
72263+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72264+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
72265+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
72266+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72267+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72268+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72269+
72270+*******************************************************************************/
72271+
72272+#ifndef __INCPCIREGSH
72273+#define __INCPCIREGSH
72274+
72275+
72276+#include "pci-if/mvPciIfRegs.h"
72277+/* defines */
72278+#define MAX_PCI_DEVICES 32
72279+#define MAX_PCI_FUNCS 8
72280+#define MAX_PCI_BUSSES 128
72281+
72282+/* enumerators */
72283+
72284+/* This enumerator described the possible PCI slave targets. */
72285+/* PCI slave targets are designated memory/IO address spaces that the */
72286+/* PCI slave targets can access. They are also refered as "targets" */
72287+/* this enumeratoe order is determined by the content of :
72288+ PCI_BASE_ADDR_ENABLE_REG */
72289+
72290+
72291+/* registers offsetes defines */
72292+
72293+
72294+
72295+/*************************/
72296+/* PCI control registers */
72297+/*************************/
72298+/* maen : should add new registers */
72299+#define PCI_CMD_REG(pciIf) (0x30c00 + ((pciIf) * 0x80))
72300+#define PCI_MODE_REG(pciIf) (0x30d00 + ((pciIf) * 0x80))
72301+#define PCI_RETRY_REG(pciIf) (0x30c04 + ((pciIf) * 0x80))
72302+#define PCI_DISCARD_TIMER_REG(pciIf) (0x30d04 + ((pciIf) * 0x80))
72303+#define PCI_ARBITER_CTRL_REG(pciIf) (0x31d00 + ((pciIf) * 0x80))
72304+#define PCI_P2P_CONFIG_REG(pciIf) (0x31d14 + ((pciIf) * 0x80))
72305+#define PCI_ACCESS_CTRL_BASEL_REG(pciIf, targetWin) \
72306+ (0x31e00 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
72307+#define PCI_ACCESS_CTRL_BASEH_REG(pciIf, targetWin) \
72308+ (0x31e04 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
72309+#define PCI_ACCESS_CTRL_SIZE_REG(pciIf, targetWin) \
72310+ (0x31e08 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
72311+
72312+#define PCI_DLL_CTRL_REG(pciIf) (0x31d20 + ((pciIf) * 0x80))
72313+
72314+/* PCI Dll Control (PDC)*/
72315+#define PDC_DLL_EN BIT0
72316+
72317+
72318+/* PCI Command Register (PCR) */
72319+#define PCR_MASTER_BYTE_SWAP_EN BIT0
72320+#define PCR_MASTER_WR_COMBINE_EN BIT4
72321+#define PCR_MASTER_RD_COMBINE_EN BIT5
72322+#define PCR_MASTER_WR_TRIG_WHOLE BIT6
72323+#define PCR_MASTER_RD_TRIG_WHOLE BIT7
72324+#define PCR_MASTER_MEM_RD_LINE_EN BIT8
72325+#define PCR_MASTER_MEM_RD_MULT_EN BIT9
72326+#define PCR_MASTER_WORD_SWAP_EN BIT10
72327+#define PCR_SLAVE_WORD_SWAP_EN BIT11
72328+#define PCR_NS_ACCORDING_RCV_TRANS BIT14
72329+#define PCR_MASTER_PCIX_REQ64N_EN BIT15
72330+#define PCR_SLAVE_BYTE_SWAP_EN BIT16
72331+#define PCR_MASTER_DAC_EN BIT17
72332+#define PCR_MASTER_M64_ALLIGN BIT18
72333+#define PCR_ERRORS_PROPAGATION_EN BIT19
72334+#define PCR_SLAVE_SWAP_ENABLE BIT20
72335+#define PCR_MASTER_SWAP_ENABLE BIT21
72336+#define PCR_MASTER_INT_SWAP_EN BIT22
72337+#define PCR_LOOP_BACK_ENABLE BIT23
72338+#define PCR_SLAVE_INTREG_SWAP_OFFS 24
72339+#define PCR_SLAVE_INTREG_SWAP_MASK 0x3
72340+#define PCR_SLAVE_INTREG_BYTE_SWAP \
72341+ (MV_BYTE_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
72342+#define PCR_SLAVE_INTREG_NO_SWAP \
72343+ (MV_NO_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
72344+#define PCR_SLAVE_INTREG_BYTE_WORD \
72345+ (MV_BYTE_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
72346+#define PCR_SLAVE_INTREG_WORD_SWAP \
72347+ (MV_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
72348+#define PCR_RESET_REASSERTION_EN BIT26
72349+#define PCR_PCI_TO_CPU_REG_ORDER_EN BIT28
72350+#define PCR_CPU_TO_PCI_ORDER_EN BIT29
72351+#define PCR_PCI_TO_CPU_ORDER_EN BIT30
72352+
72353+/* PCI Mode Register (PMR) */
72354+#define PMR_PCI_ID_OFFS 0 /* PCI Interface ID */
72355+#define PMR_PCI_ID_MASK (0x1 << PMR_PCI_ID_OFFS)
72356+#define PMR_PCI_ID_PCI(pciNum) ((pciNum) << PCI_MODE_PCIID_OFFS)
72357+
72358+#define PMR_PCI_64_OFFS 2 /* 64-bit PCI Interface */
72359+#define PMR_PCI_64_MASK (0x1 << PMR_PCI_64_OFFS)
72360+#define PMR_PCI_64_64BIT (0x1 << PMR_PCI_64_OFFS)
72361+#define PMR_PCI_64_32BIT (0x0 << PMR_PCI_64_OFFS)
72362+
72363+#define PMR_PCI_MODE_OFFS 4 /* PCI interface mode of operation */
72364+#define PMR_PCI_MODE_MASK (0x3 << PMR_PCI_MODE_OFFS)
72365+#define PMR_PCI_MODE_CONV (0x0 << PMR_PCI_MODE_OFFS)
72366+#define PMR_PCI_MODE_PCIX_66MHZ (0x1 << PMR_PCI_MODE_OFFS)
72367+#define PMR_PCI_MODE_PCIX_100MHZ (0x2 << PMR_PCI_MODE_OFFS)
72368+#define PMR_PCI_MODE_PCIX_133MHZ (0x3 << PMR_PCI_MODE_OFFS)
72369+
72370+#define PMR_EXP_ROM_SUPPORT BIT8 /* Expansion ROM Active */
72371+
72372+#define PMR_PCI_RESET_OFFS 31 /* PCI Interface Reset Indication */
72373+#define PMR_PCI_RESET_MASK (0x1 << PMR_PCI_RESET_OFFS)
72374+#define PMR_PCI_RESET_PCIXRST (0x0 << PMR_PCI_RESET_OFFS)
72375+
72376+
72377+/* PCI Retry Register (PRR) */
72378+#define PRR_RETRY_CNTR_OFFS 16 /* Retry Counter */
72379+#define PRR_RETRY_CNTR_MAX 0xff
72380+#define PRR_RETRY_CNTR_MASK (PRR_RETRY_CNTR_MAX << PRR_RETRY_CNTR_OFFS)
72381+
72382+
72383+/* PCI Discard Timer Register (PDTR) */
72384+#define PDTR_TIMER_OFFS 0 /* Timer */
72385+#define PDTR_TIMER_MAX 0xffff
72386+#define PDTR_TIMER_MIN 0x7F
72387+#define PDTR_TIMER_MASK (PDTR_TIMER_MAX << PDTR_TIMER_OFFS)
72388+
72389+
72390+/* PCI Arbiter Control Register (PACR) */
72391+#define PACR_BROKEN_DETECT_EN BIT1 /* Broken Detection Enable */
72392+
72393+#define PACR_BROKEN_VAL_OFFS 3 /* Broken Value */
72394+#define PACR_BROKEN_VAL_MASK (0xf << PACR_BROKEN_VAL_OFFS)
72395+#define PACR_BROKEN_VAL_CONV_MIN 0x2
72396+#define PACR_BROKEN_VAL_PCIX_MIN 0x6
72397+
72398+#define PACR_PARK_DIS_OFFS 14 /* Parking Disable */
72399+#define PACR_PARK_DIS_MAX_AGENT 0x3f
72400+#define PACR_PARK_DIS_MASK (PACR_PARK_DIS_MAX_AGENT<<PACR_PARK_DIS_OFFS)
72401+#define PACR_PARK_DIS(agent) ((1 << (agent)) << PACR_PARK_DIS_OFFS)
72402+
72403+#define PACR_ARB_ENABLE BIT31 /* Enable Internal Arbiter */
72404+
72405+
72406+/* PCI P2P Configuration Register (PPCR) */
72407+#define PPCR_2ND_BUS_L_OFFS 0 /* 2nd PCI Interface Bus Range Lower */
72408+#define PPCR_2ND_BUS_L_MASK (0xff << PPCR_2ND_BUS_L_OFFS)
72409+
72410+#define PPCR_2ND_BUS_H_OFFS 8 /* 2nd PCI Interface Bus Range Upper */
72411+#define PPCR_2ND_BUS_H_MASK (0xff << PPCR_2ND_BUS_H_OFFS)
72412+
72413+#define PPCR_BUS_NUM_OFFS 16 /* The PCI interface's Bus number */
72414+#define PPCR_BUS_NUM_MASK (0xff << PPCR_BUS_NUM_OFFS)
72415+
72416+#define PPCR_DEV_NUM_OFFS 24 /* The PCI interface’s Device number */
72417+#define PPCR_DEV_NUM_MASK (0xff << PPCR_DEV_NUM_OFFS)
72418+
72419+
72420+/* PCI Access Control Base Low Register (PACBLR) */
72421+#define PACBLR_EN BIT0 /* Access control window enable */
72422+
72423+#define PACBLR_ACCPROT BIT4 /* Access Protect */
72424+#define PACBLR_WRPROT BIT5 /* Write Protect */
72425+
72426+#define PACBLR_PCISWAP_OFFS 6 /* PCI slave Data Swap Control */
72427+#define PACBLR_PCISWAP_MASK (0x3 << PACBLR_PCISWAP_OFFS)
72428+#define PACBLR_PCISWAP_BYTE (0x0 << PACBLR_PCISWAP_OFFS)
72429+#define PACBLR_PCISWAP_NO_SWAP (0x1 << PACBLR_PCISWAP_OFFS)
72430+#define PACBLR_PCISWAP_BYTE_WORD (0x2 << PACBLR_PCISWAP_OFFS)
72431+#define PACBLR_PCISWAP_WORD (0x3 << PACBLR_PCISWAP_OFFS)
72432+
72433+#define PACBLR_RDMBURST_OFFS 8 /* Read Max Burst */
72434+#define PACBLR_RDMBURST_MASK (0x3 << PACBLR_RDMBURST_OFFS)
72435+#define PACBLR_RDMBURST_32BYTE (0x0 << PACBLR_RDMBURST_OFFS)
72436+#define PACBLR_RDMBURST_64BYTE (0x1 << PACBLR_RDMBURST_OFFS)
72437+#define PACBLR_RDMBURST_128BYTE (0x2 << PACBLR_RDMBURST_OFFS)
72438+
72439+#define PACBLR_RDSIZE_OFFS 10 /* Typical PCI read transaction Size. */
72440+#define PACBLR_RDSIZE_MASK (0x3 << PACBLR_RDSIZE_OFFS)
72441+#define PACBLR_RDSIZE_32BYTE (0x0 << PACBLR_RDSIZE_OFFS)
72442+#define PACBLR_RDSIZE_64BYTE (0x1 << PACBLR_RDSIZE_OFFS)
72443+#define PACBLR_RDSIZE_128BYTE (0x2 << PACBLR_RDSIZE_OFFS)
72444+#define PACBLR_RDSIZE_256BYTE (0x3 << PACBLR_RDSIZE_OFFS)
72445+
72446+#define PACBLR_BASE_L_OFFS 12 /* Corresponds to address bits [31:12] */
72447+#define PACBLR_BASE_L_MASK (0xfffff << PACBLR_BASE_L_OFFS)
72448+#define PACBLR_BASE_L_ALIGNMENT (1 << PACBLR_BASE_L_OFFS)
72449+#define PACBLR_BASE_ALIGN_UP(base) \
72450+ ((base+PACBLR_BASE_L_ALIGNMENT)&PACBLR_BASE_L_MASK)
72451+#define PACBLR_BASE_ALIGN_DOWN(base) (base & PACBLR_BASE_L_MASK)
72452+
72453+
72454+/* PCI Access Control Base High Register (PACBHR) */
72455+#define PACBHR_BASE_H_OFFS 0 /* Corresponds to address bits [63:32] */
72456+#define PACBHR_CTRL_BASE_H_MASK (0xffffffff << PACBHR_BASE_H_OFFS)
72457+
72458+/* PCI Access Control Size Register (PACSR) */
72459+#define PACSR_WRMBURST_OFFS 8 /* Write Max Burst */
72460+#define PACSR_WRMBURST_MASK (0x3 << PACSR_WRMBURST_OFFS)
72461+#define PACSR_WRMBURST_32BYTE (0x0 << PACSR_WRMBURST_OFFS)
72462+#define PACSR_WRMBURST_64BYTE (0x1 << PACSR_WRMBURST_OFFS)
72463+#define PACSR_WRMBURST_128BYTE (0x2 << PACSR_WRMBURST_OFFS)
72464+
72465+#define PACSR_PCI_ORDERING BIT11 /* PCI Ordering required */
72466+
72467+#define PACSR_SIZE_OFFS 12 /* PCI access window size */
72468+#define PACSR_SIZE_MASK (0xfffff << PACSR_SIZE_OFFS)
72469+#define PACSR_SIZE_ALIGNMENT (1 << PACSR_SIZE_OFFS)
72470+#define PACSR_SIZE_ALIGN_UP(size) \
72471+ ((size+PACSR_SIZE_ALIGNMENT)&PACSR_SIZE_MASK)
72472+#define PACSR_SIZE_ALIGN_DOWN(size) (size & PACSR_SIZE_MASK)
72473+
72474+
72475+/***************************************/
72476+/* PCI Configuration Access Registers */
72477+/***************************************/
72478+
72479+#define PCI_CONFIG_ADDR_REG(pciIf) (0x30C78 - ((pciIf) * 0x80) )
72480+#define PCI_CONFIG_DATA_REG(pciIf) (0x30C7C - ((pciIf) * 0x80) )
72481+#define PCI_INT_ACK_REG(pciIf) (0x30C34 + ((pciIf) * 0x80) )
72482+
72483+/* PCI Configuration Address Register (PCAR) */
72484+#define PCAR_REG_NUM_OFFS 2
72485+#define PCAR_REG_NUM_MASK (0x3F << PCAR_REG_NUM_OFFS)
72486+
72487+#define PCAR_FUNC_NUM_OFFS 8
72488+#define PCAR_FUNC_NUM_MASK (0x7 << PCAR_FUNC_NUM_OFFS)
72489+
72490+#define PCAR_DEVICE_NUM_OFFS 11
72491+#define PCAR_DEVICE_NUM_MASK (0x1F << PCAR_DEVICE_NUM_OFFS)
72492+
72493+#define PCAR_BUS_NUM_OFFS 16
72494+#define PCAR_BUS_NUM_MASK (0xFF << PCAR_BUS_NUM_OFFS)
72495+
72496+#define PCAR_CONFIG_EN BIT31
72497+
72498+
72499+/***************************************/
72500+/* PCI Configuration registers */
72501+/***************************************/
72502+
72503+/*********************************************/
72504+/* PCI Configuration, Function 0, Registers */
72505+/*********************************************/
72506+
72507+/* Marvell Specific */
72508+#define PCI_SCS0_BASE_ADDR_LOW 0x010
72509+#define PCI_SCS0_BASE_ADDR_HIGH 0x014
72510+#define PCI_SCS1_BASE_ADDR_LOW 0x018
72511+#define PCI_SCS1_BASE_ADDR_HIGH 0x01C
72512+#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_L 0x020
72513+#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_H 0x024
72514+
72515+/* capability list */
72516+#define PCI_POWER_MNG_CAPABILITY 0x040
72517+#define PCI_POWER_MNG_STATUS_CONTROL 0x044
72518+#define PCI_VPD_ADDRESS_REG 0x048
72519+#define PCI_VPD_DATA_REG 0x04c
72520+#define PCI_MSI_MESSAGE_CONTROL 0x050
72521+#define PCI_MSI_MESSAGE_ADDR 0x054
72522+#define PCI_MSI_MESSAGE_UPPER_ADDR 0x058
72523+#define PCI_MSI_MESSAGE_DATA 0x05c
72524+#define PCIX_COMMAND 0x060
72525+#define PCIX_STATUS 0x064
72526+#define PCI_COMPACT_PCI_HOT_SWAP 0x068
72527+
72528+
72529+/*********************************************/
72530+/* PCI Configuration, Function 1, Registers */
72531+/*********************************************/
72532+
72533+#define PCI_SCS2_BASE_ADDR_LOW 0x10
72534+#define PCI_SCS2_BASE_ADDR_HIGH 0x14
72535+#define PCI_SCS3_BASE_ADDR_LOW 0x18
72536+#define PCI_SCS3_BASE_ADDR_HIGH 0x1c
72537+
72538+
72539+/***********************************************/
72540+/* PCI Configuration, Function 2, Registers */
72541+/***********************************************/
72542+
72543+#define PCI_DEVCS0_BASE_ADDR_LOW 0x10
72544+#define PCI_DEVCS0_BASE_ADDR_HIGH 0x14
72545+#define PCI_DEVCS1_BASE_ADDR_LOW 0x18
72546+#define PCI_DEVCS1_BASE_ADDR_HIGH 0x1c
72547+#define PCI_DEVCS2_BASE_ADDR_LOW 0x20
72548+#define PCI_DEVCS2_BASE_ADDR_HIGH 0x24
72549+
72550+/***********************************************/
72551+/* PCI Configuration, Function 3, Registers */
72552+/***********************************************/
72553+
72554+#define PCI_BOOTCS_BASE_ADDR_LOW 0x18
72555+#define PCI_BOOTCS_BASE_ADDR_HIGH 0x1c
72556+
72557+/***********************************************/
72558+/* PCI Configuration, Function 4, Registers */
72559+/***********************************************/
72560+
72561+#define PCI_P2P_MEM0_BASE_ADDR_LOW 0x10
72562+#define PCI_P2P_MEM0_BASE_ADDR_HIGH 0x14
72563+#define PCI_P2P_IO_BASE_ADDR 0x20
72564+#define PCI_INTER_REGS_IO_MAPPED_BASE_ADDR 0x24
72565+
72566+/* PCIX_STATUS register fields (PXS) */
72567+
72568+#define PXS_FN_OFFS 0 /* Description Number */
72569+#define PXS_FN_MASK (0x7 << PXS_FN_OFFS)
72570+
72571+#define PXS_DN_OFFS 3 /* Device Number */
72572+#define PXS_DN_MASK (0x1f << PXS_DN_OFFS)
72573+
72574+#define PXS_BN_OFFS 8 /* Bus Number */
72575+#define PXS_BN_MASK (0xff << PXS_BN_OFFS)
72576+
72577+
72578+/* PCI Error Report Register Map */
72579+#define PCI_SERRN_MASK_REG(pciIf) (0x30c28 + (pciIf * 0x80))
72580+#define PCI_CAUSE_REG(pciIf) (0x31d58 + (pciIf * 0x80))
72581+#define PCI_MASK_REG(pciIf) (0x31d5C + (pciIf * 0x80))
72582+#define PCI_ERROR_ADDR_LOW_REG(pciIf) (0x31d40 + (pciIf * 0x80))
72583+#define PCI_ERROR_ADDR_HIGH_REG(pciIf) (0x31d44 + (pciIf * 0x80))
72584+#define PCI_ERROR_ATTRIBUTE_REG(pciIf) (0x31d48 + (pciIf * 0x80))
72585+#define PCI_ERROR_COMMAND_REG(pciIf) (0x31d50 + (pciIf * 0x80))
72586+
72587+/* PCI Interrupt Cause Register (PICR) */
72588+#define PICR_ERR_SEL_OFFS 27
72589+#define PICR_ERR_SEL_MASK (0x1f << PICR_ERR_SEL_OFFS)
72590+
72591+/* PCI Error Command Register (PECR) */
72592+#define PECR_ERR_CMD_OFFS 0
72593+#define PECR_ERR_CMD_MASK (0xf << PECR_ERR_CMD_OFFS)
72594+#define PECR_DAC BIT4
72595+
72596+
72597+/* defaults */
72598+/* Set bits means value is about to change according to new value */
72599+#define PCI_COMMAND_DEFAULT_MASK 0xffffdff1
72600+#define PCI_COMMAND_DEFAULT \
72601+ (PCR_MASTER_WR_TRIG_WHOLE | \
72602+ PCR_MASTER_RD_TRIG_WHOLE | \
72603+ PCR_MASTER_MEM_RD_LINE_EN | \
72604+ PCR_MASTER_MEM_RD_MULT_EN | \
72605+ PCR_NS_ACCORDING_RCV_TRANS | \
72606+ PCR_MASTER_PCIX_REQ64N_EN | \
72607+ PCR_MASTER_DAC_EN | \
72608+ PCR_MASTER_M64_ALLIGN | \
72609+ PCR_ERRORS_PROPAGATION_EN)
72610+
72611+
72612+#define PCI_ARBITER_CTRL_DEFAULT_MASK 0x801fc07a
72613+#define PCI_ARBITER_CTRL_DEFAULT \
72614+ (PACR_BROKEN_VAL_PCIX_MIN << PACR_BROKEN_VAL_OFFS)
72615+
72616+
72617+#endif /* #ifndef __INCPCIREGSH */
72618+
72619diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c b/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c
72620new file mode 100644
72621index 0000000..709bb49
72622--- /dev/null
72623+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c
72624@@ -0,0 +1,1143 @@
72625+/*******************************************************************************
72626+Copyright (C) Marvell International Ltd. and its affiliates
72627+
72628+This software file (the "File") is owned and distributed by Marvell
72629+International Ltd. and/or its affiliates ("Marvell") under the following
72630+alternative licensing terms. Once you have made an election to distribute the
72631+File under one of the following license alternatives, please (i) delete this
72632+introductory statement regarding license alternatives, (ii) delete the two
72633+license alternatives that you have not elected to use and (iii) preserve the
72634+Marvell copyright notice above.
72635+
72636+********************************************************************************
72637+Marvell Commercial License Option
72638+
72639+If you received this File from Marvell and you have entered into a commercial
72640+license agreement (a "Commercial License") with Marvell, the File is licensed
72641+to you under the terms of the applicable Commercial License.
72642+
72643+********************************************************************************
72644+Marvell GPL License Option
72645+
72646+If you received this File from Marvell, you may opt to use, redistribute and/or
72647+modify this File in accordance with the terms and conditions of the General
72648+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
72649+available along with the File in the license.txt file or by writing to the Free
72650+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
72651+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
72652+
72653+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
72654+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
72655+DISCLAIMED. The GPL License provides additional details about this warranty
72656+disclaimer.
72657+********************************************************************************
72658+Marvell BSD License Option
72659+
72660+If you received this File from Marvell, you may opt to use, redistribute and/or
72661+modify this File under the following licensing terms.
72662+Redistribution and use in source and binary forms, with or without modification,
72663+are permitted provided that the following conditions are met:
72664+
72665+ * Redistributions of source code must retain the above copyright notice,
72666+ this list of conditions and the following disclaimer.
72667+
72668+ * Redistributions in binary form must reproduce the above copyright
72669+ notice, this list of conditions and the following disclaimer in the
72670+ documentation and/or other materials provided with the distribution.
72671+
72672+ * Neither the name of Marvell nor the names of its contributors may be
72673+ used to endorse or promote products derived from this software without
72674+ specific prior written permission.
72675+
72676+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
72677+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
72678+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72679+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
72680+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72681+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
72682+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
72683+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72684+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72685+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72686+
72687+*******************************************************************************/
72688+
72689+#include "pex/mvPex.h"
72690+
72691+#include "ctrlEnv/mvCtrlEnvLib.h"
72692+
72693+/* defines */
72694+#ifdef MV_DEBUG
72695+#define DB(x) x
72696+#else
72697+#define DB(x)
72698+#endif
72699+
72700+MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
72701+{
72702+ MV_PEX_MODE pexMode;
72703+ MV_U32 regVal;
72704+ MV_U32 status;
72705+
72706+ /* First implement Guideline (GL# PCI Express-2) Wrong Default Value */
72707+ /* to Transmitter Output Current (TXAMP) Relevant for: 88F5181-A1/B0/B1 */
72708+ /* and 88F5281-B0 and above, 88F5182, 88F5082, 88F5181L, 88F6082/L */
72709+
72710+ if ((mvCtrlModelGet() != MV_1281_DEV_ID) &&
72711+ (mvCtrlModelGet() != MV_6281_DEV_ID) &&
72712+ (mvCtrlModelGet() != MV_6192_DEV_ID) &&
72713+ (mvCtrlModelGet() != MV_6190_DEV_ID) &&
72714+ (mvCtrlModelGet() != MV_6180_DEV_ID) &&
72715+ (mvCtrlModelGet() != MV_6183_DEV_ID) &&
72716+ (mvCtrlModelGet() != MV_6183L_DEV_ID) &&
72717+ (mvCtrlModelGet() != MV_78100_DEV_ID) &&
72718+ (mvCtrlModelGet() != MV_78200_DEV_ID) &&
72719+ (mvCtrlModelGet() != MV_76100_DEV_ID) &&
72720+ (mvCtrlModelGet() != MV_78XX0_DEV_ID))
72721+ {
72722+
72723+ /* Read current value of TXAMP */
72724+ MV_REG_WRITE(0x41b00, 0x80820000); /* Write the read command */
72725+
72726+ regVal = MV_REG_READ(0x41b00); /* Extract the data */
72727+
72728+ /* Prepare new data for write */
72729+ regVal &= ~0x7; /* Clear bits [2:0] */
72730+ regVal |= 0x4; /* Set the new value */
72731+ regVal &= ~0x80000000; /* Set "write" command */
72732+ MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
72733+
72734+ }
72735+ else
72736+ {
72737+ /* Implement 1.0V termination GL for 88F1281 device only */
72738+ /* BIT0 - Common mode feedback */
72739+ /* BIT3 - TxBuf, extra drive for 1.0V termination */
72740+ if (mvCtrlModelGet() == MV_1281_DEV_ID)
72741+ {
72742+ MV_REG_WRITE(0x41b00, 0x80860000); /* Write the read command */
72743+ regVal = MV_REG_READ(0x41b00); /* Extract the data */
72744+ regVal |= (BIT0 | BIT3);
72745+ regVal &= ~0x80000000; /* Set "write" command */
72746+ MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
72747+
72748+ MV_REG_WRITE(0x31b00, 0x80860000); /* Write the read command */
72749+ regVal = MV_REG_READ(0x31b00); /* Extract the data */
72750+ regVal |= (BIT0 | BIT3);
72751+ regVal &= ~0x80000000; /* Set "write" command */
72752+ MV_REG_WRITE(0x31b00, regVal); /* Write the write command */
72753+ }
72754+ }
72755+
72756+ if( mvPexModeGet(pexIf, &pexMode) != MV_OK)
72757+ {
72758+ mvOsPrintf("PEX init ERR. mvPexModeGet failed (pexType=%d)\n",pexMode.pexType);
72759+ return MV_ERROR;
72760+ }
72761+
72762+ /* Check that required PEX type is the one set in reset time */
72763+ if (pexType != pexMode.pexType)
72764+ {
72765+ /* No Link. Shut down the Phy */
72766+ mvPexPowerDown(pexIf);
72767+ mvOsPrintf("PEX init ERR. PEX type sampled mismatch (%d,%d)\n",pexType,pexMode.pexType);
72768+ return MV_ERROR;
72769+ }
72770+
72771+ if (MV_PEX_ROOT_COMPLEX == pexType)
72772+ {
72773+ mvPexLocalBusNumSet(pexIf, PEX_HOST_BUS_NUM(pexIf));
72774+ mvPexLocalDevNumSet(pexIf, PEX_HOST_DEV_NUM(pexIf));
72775+
72776+ /* Local device master Enable */
72777+ mvPexMasterEnable(pexIf, MV_TRUE);
72778+
72779+ /* Local device slave Enable */
72780+ mvPexSlaveEnable(pexIf, mvPexLocalBusNumGet(pexIf),
72781+ mvPexLocalDevNumGet(pexIf), MV_TRUE);
72782+ /* Interrupt disable */
72783+ status = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND));
72784+ status |= PXSAC_INT_DIS;
72785+ MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND), status);
72786+ }
72787+
72788+ /* now wait 500 ms to be sure the link is valid (spec compliant) */
72789+ mvOsDelay(500);
72790+ /* Check if we have link */
72791+ if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
72792+ {
72793+ mvOsPrintf("PEX%d interface detected no Link.\n",pexIf);
72794+ return MV_NO_SUCH;
72795+ }
72796+
72797+ if (MV_PEX_WITDH_X1 == pexMode.pexWidth)
72798+ {
72799+ mvOsPrintf("PEX%d interface detected Link X1\n",pexIf);
72800+ }
72801+ else
72802+ {
72803+ mvOsPrintf("PEX%d interface detected Link X4\n",pexIf);
72804+ }
72805+
72806+#ifdef PCIE_VIRTUAL_BRIDGE_SUPPORT
72807+ mvPexVrtBrgInit(pexIf);
72808+#endif
72809+ return MV_OK;
72810+}
72811+
72812+/*******************************************************************************
72813+* mvPexModeGet - Get Pex Mode
72814+*
72815+* DESCRIPTION:
72816+*
72817+* INPUT:
72818+* pexIf - PEX interface number.
72819+*
72820+* OUTPUT:
72821+* pexMode - Pex mode structure
72822+*
72823+* RETURN:
72824+* MV_OK on success , MV_ERROR otherwise
72825+*
72826+*******************************************************************************/
72827+MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode)
72828+{
72829+ MV_U32 pexData;
72830+
72831+ /* Parameter checking */
72832+ if (PEX_DEFAULT_IF != pexIf)
72833+ {
72834+ if (pexIf >= mvCtrlPexMaxIfGet())
72835+ {
72836+ mvOsPrintf("mvPexModeGet: ERR. Invalid PEX interface %d\n",pexIf);
72837+ return MV_ERROR;
72838+ }
72839+ }
72840+
72841+ pexData = MV_REG_READ(PEX_CTRL_REG(pexIf));
72842+
72843+ switch (pexData & PXCR_DEV_TYPE_CTRL_MASK)
72844+ {
72845+ case PXCR_DEV_TYPE_CTRL_CMPLX:
72846+ pexMode->pexType = MV_PEX_ROOT_COMPLEX;
72847+ break;
72848+ case PXCR_DEV_TYPE_CTRL_POINT:
72849+ pexMode->pexType = MV_PEX_END_POINT;
72850+ break;
72851+
72852+ }
72853+
72854+ /* Check if we have link */
72855+ if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
72856+ {
72857+ pexMode->pexLinkUp = MV_FALSE;
72858+
72859+ /* If there is no link, the auto negotiation data is worthless */
72860+ pexMode->pexWidth = MV_PEX_WITDH_INVALID;
72861+ }
72862+ else
72863+ {
72864+ pexMode->pexLinkUp = MV_TRUE;
72865+
72866+ /* We have link. The link width is now valid */
72867+ pexData = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG));
72868+ pexMode->pexWidth = ((pexData & PXLCSR_NEG_LNK_WDTH_MASK) >>
72869+ PXLCSR_NEG_LNK_WDTH_OFFS);
72870+ }
72871+
72872+ return MV_OK;
72873+}
72874+
72875+
72876+/* PEX configuration space read write */
72877+
72878+/*******************************************************************************
72879+* mvPexConfigRead - Read from configuration space
72880+*
72881+* DESCRIPTION:
72882+* This function performs a 32 bit read from PEX configuration space.
72883+* It supports both type 0 and type 1 of Configuration Transactions
72884+* (local and over bridge). In order to read from local bus segment, use
72885+* bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
72886+* will result configuration transaction of type 1 (over bridge).
72887+*
72888+* INPUT:
72889+* pexIf - PEX interface number.
72890+* bus - PEX segment bus number.
72891+* dev - PEX device number.
72892+* func - Function number.
72893+* regOffs - Register offset.
72894+*
72895+* OUTPUT:
72896+* None.
72897+*
72898+* RETURN:
72899+* 32bit register data, 0xffffffff on error
72900+*
72901+*******************************************************************************/
72902+MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
72903+ MV_U32 regOff)
72904+{
72905+#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
72906+ return mvPexVrtBrgConfigRead (pexIf, bus, dev, func, regOff);
72907+}
72908+
72909+MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
72910+ MV_U32 regOff)
72911+{
72912+#endif
72913+ MV_U32 pexData = 0;
72914+ MV_U32 localDev,localBus;
72915+
72916+ /* Parameter checking */
72917+ if (PEX_DEFAULT_IF != pexIf)
72918+ {
72919+ if (pexIf >= mvCtrlPexMaxIfGet())
72920+ {
72921+ mvOsPrintf("mvPexConfigRead: ERR. Invalid PEX interface %d\n",pexIf);
72922+ return 0xFFFFFFFF;
72923+ }
72924+ }
72925+
72926+ if (dev >= MAX_PEX_DEVICES)
72927+ {
72928+ DB(mvOsPrintf("mvPexConfigRead: ERR. device number illigal %d\n", dev));
72929+ return 0xFFFFFFFF;
72930+ }
72931+
72932+ if (func >= MAX_PEX_FUNCS)
72933+ {
72934+ DB(mvOsPrintf("mvPexConfigRead: ERR. function num illigal %d\n", func));
72935+ return 0xFFFFFFFF;
72936+ }
72937+
72938+ if (bus >= MAX_PEX_BUSSES)
72939+ {
72940+ DB(mvOsPrintf("mvPexConfigRead: ERR. bus number illigal %d\n", bus));
72941+ return MV_ERROR;
72942+ }
72943+
72944+ DB(mvOsPrintf("mvPexConfigRead: pexIf %d, bus %d, dev %d, func %d, regOff 0x%x\n",
72945+ pexIf, bus, dev, func, regOff));
72946+
72947+ localDev = mvPexLocalDevNumGet(pexIf);
72948+ localBus = mvPexLocalBusNumGet(pexIf);
72949+
72950+ /* Speed up the process. In case on no link, return MV_ERROR */
72951+ if ((dev != localDev) || (bus != localBus))
72952+ {
72953+ pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
72954+
72955+ if ((pexData & PXSR_DL_DOWN))
72956+ {
72957+ return MV_ERROR;
72958+ }
72959+ }
72960+
72961+ /* in PCI Express we have only one device number */
72962+ /* and this number is the first number we encounter
72963+ else that the localDev*/
72964+ /* spec pex define return on config read/write on any device */
72965+ if (bus == localBus)
72966+ {
72967+ if (localDev == 0)
72968+ {
72969+ /* if local dev is 0 then the first number we encounter
72970+ after 0 is 1 */
72971+ if ((dev != 1)&&(dev != localDev))
72972+ {
72973+ return MV_ERROR;
72974+ }
72975+ }
72976+ else
72977+ {
72978+ /* if local dev is not 0 then the first number we encounter
72979+ is 0 */
72980+
72981+ if ((dev != 0)&&(dev != localDev))
72982+ {
72983+ return MV_ERROR;
72984+ }
72985+ }
72986+ if(func != 0 ) /* i.e bridge */
72987+ {
72988+ return MV_ERROR;
72989+ }
72990+ }
72991+
72992+
72993+ /* Creating PEX address to be passed */
72994+ pexData = (bus << PXCAR_BUS_NUM_OFFS);
72995+ pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
72996+ pexData |= (func << PXCAR_FUNC_NUM_OFFS);
72997+ pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
72998+ /* extended register space */
72999+ pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
73000+ PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
73001+
73002+ pexData |= PXCAR_CONFIG_EN;
73003+
73004+ /* Write the address to the PEX configuration address register */
73005+ MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
73006+
73007+ DB(mvOsPrintf("mvPexConfigRead:address pexData=%x ",pexData));
73008+
73009+
73010+ /* In order to let the PEX controller absorbed the address of the read */
73011+ /* transaction we perform a validity check that the address was written */
73012+ if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
73013+ {
73014+ return MV_ERROR;
73015+ }
73016+
73017+ /* cleaning Master Abort */
73018+ MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
73019+ PXSAC_MABORT);
73020+#if 0
73021+ /* Guideline (GL# PCI Express-1) Erroneous Read Data on Configuration */
73022+ /* This guideline is relevant for all devices except of the following devices:
73023+ 88F5281-BO and above, 88F5181L-A0 and above, 88F1281 A0 and above
73024+ 88F6183 A0 and above, 88F6183L */
73025+ if ( ( (dev != localDev) || (bus != localBus) ) &&
73026+ (
73027+ !(MV_5281_DEV_ID == mvCtrlModelGet())&&
73028+ !((MV_5181_DEV_ID == mvCtrlModelGet())&& (mvCtrlRevGet() >= MV_5181L_A0_REV))&&
73029+ !(MV_1281_DEV_ID == mvCtrlModelGet())&&
73030+ !(MV_6183_DEV_ID == mvCtrlModelGet())&&
73031+ !(MV_6183L_DEV_ID == mvCtrlModelGet())&&
73032+ !(MV_6281_DEV_ID == mvCtrlModelGet())&&
73033+ !(MV_6192_DEV_ID == mvCtrlModelGet())&&
73034+ !(MV_6190_DEV_ID == mvCtrlModelGet())&&
73035+ !(MV_6180_DEV_ID == mvCtrlModelGet())&&
73036+ !(MV_78XX0_DEV_ID == mvCtrlModelGet())
73037+ ))
73038+ {
73039+
73040+ /* PCI-Express configuration read work-around */
73041+
73042+ /* we will use one of the Punit (AHBToMbus) windows to access the xbar
73043+ and read the data from there */
73044+ /*
73045+ Need to configure the 2 free Punit (AHB to MBus bridge)
73046+ address decoding windows:
73047+ Configure the flash Window to handle Configuration space requests
73048+ for PEX0/1:
73049+ 1. write 0x7931/0x7941 to the flash window and the size,
73050+ 79-xbar attr (pci cfg), 3/4-xbar target (pex0/1), 1-WinEn
73051+ 2. write base to flash window
73052+
73053+ Configuration transactions from the CPU should write/read the data
73054+ to/from address of the form:
73055+ addr[31:28] = 0x5 (for PEX0) or 0x6 (for PEX1)
73056+ addr[27:24] = extended register number
73057+ addr[23:16] = bus number
73058+ addr[15:11] = device number
73059+ addr[10:8] = function number
73060+ addr[7:0] = register number
73061+ */
73062+
73063+ #include "ctrlEnv/sys/mvAhbToMbus.h"
73064+ {
73065+ MV_U32 winNum;
73066+ MV_AHB_TO_MBUS_DEC_WIN originWin;
73067+ MV_U32 pciAddr=0;
73068+ MV_U32 remapLow=0,remapHigh=0;
73069+
73070+ /*
73071+ We will use DEV_CS2\Flash window for this workarround
73072+ */
73073+
73074+ winNum = mvAhbToMbusWinTargetGet(PEX_CONFIG_RW_WA_TARGET);
73075+
73076+ /* save remap values if exist */
73077+ if ((1 == winNum)||(0 == winNum))
73078+ {
73079+ remapLow = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum));
73080+ remapHigh = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum));
73081+
73082+ }
73083+
73084+
73085+ /* save the original window values */
73086+ mvAhbToMbusWinGet(winNum,&originWin);
73087+
73088+ if (PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES)
73089+ {
73090+ /* set the window as xbar window */
73091+ if (pexIf)
73092+ {
73093+ MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
73094+ (0x7931 | (((originWin.addrWin.size >> 16)-1) ) << 16));
73095+ }
73096+ else
73097+ {
73098+ MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
73099+ (0x7941 | (((originWin.addrWin.size >> 16)-1) ) << 16));
73100+ }
73101+
73102+ MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
73103+ originWin.addrWin.baseLow);
73104+
73105+ /*pciAddr = originWin.addrWin.baseLow;*/
73106+ pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(
73107+ (MV_U32)originWin.addrWin.baseLow);
73108+
73109+ }
73110+ else
73111+ {
73112+ /* set the window as xbar window */
73113+ if (pexIf)
73114+ {
73115+ MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
73116+ (0x7931 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
73117+ }
73118+ else
73119+ {
73120+ MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
73121+ (0x7941 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
73122+ }
73123+
73124+ MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
73125+ PEX_CONFIG_RW_WA_BASE);
73126+
73127+ pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(PEX_CONFIG_RW_WA_BASE);
73128+ }
73129+
73130+
73131+ /* remap should be as base */
73132+ if ((1 == winNum)||(0 == winNum))
73133+ {
73134+ MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),pciAddr);
73135+ MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),0);
73136+
73137+ }
73138+
73139+ /* extended register space */
73140+ pciAddr |= (bus << 16);
73141+ pciAddr |= (dev << 11);
73142+ pciAddr |= (func << 8);
73143+ pciAddr |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
73144+
73145+ pexData = *(MV_U32*)pciAddr;
73146+ pexData = MV_32BIT_LE(pexData); /* Data always in LE */
73147+
73148+ /* restore the original window values */
73149+ mvAhbToMbusWinSet(winNum,&originWin);
73150+
73151+ /* restore original remap values*/
73152+ if ((1 == winNum)||(0 == winNum))
73153+ {
73154+ MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),remapLow);
73155+ MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),remapHigh);
73156+
73157+ }
73158+ }
73159+ }
73160+ else
73161+#endif
73162+ {
73163+ /* Read the Data returned in the PEX Data register */
73164+ pexData = MV_REG_READ(PEX_CFG_DATA_REG(pexIf));
73165+
73166+ }
73167+
73168+ DB(mvOsPrintf("mvPexConfigRead: got : %x \n",pexData));
73169+
73170+ return pexData;
73171+
73172+}
73173+
73174+/*******************************************************************************
73175+* mvPexConfigWrite - Write to configuration space
73176+*
73177+* DESCRIPTION:
73178+* This function performs a 32 bit write to PEX configuration space.
73179+* It supports both type 0 and type 1 of Configuration Transactions
73180+* (local and over bridge). In order to write to local bus segment, use
73181+* bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
73182+* will result configuration transaction of type 1 (over bridge).
73183+*
73184+* INPUT:
73185+* pexIf - PEX interface number.
73186+* bus - PEX segment bus number.
73187+* dev - PEX device number.
73188+* func - Function number.
73189+* regOffs - Register offset.
73190+* data - 32bit data.
73191+*
73192+* OUTPUT:
73193+* None.
73194+*
73195+* RETURN:
73196+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
73197+*
73198+*******************************************************************************/
73199+MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
73200+ MV_U32 func, MV_U32 regOff, MV_U32 data)
73201+{
73202+#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
73203+ return mvPexVrtBrgConfigWrite (pexIf, bus, dev, func, regOff, data);
73204+}
73205+
73206+MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
73207+ MV_U32 func, MV_U32 regOff, MV_U32 data)
73208+{
73209+#endif
73210+ MV_U32 pexData = 0;
73211+ MV_U32 localDev,localBus;
73212+
73213+ /* Parameter checking */
73214+ if (PEX_DEFAULT_IF != pexIf)
73215+ {
73216+ if (pexIf >= mvCtrlPexMaxIfGet())
73217+ {
73218+ mvOsPrintf("mvPexConfigWrite: ERR. Invalid PEX interface %d\n",
73219+ pexIf);
73220+ return MV_ERROR;
73221+ }
73222+ }
73223+
73224+ if (dev >= MAX_PEX_DEVICES)
73225+ {
73226+ mvOsPrintf("mvPexConfigWrite: ERR. device number illigal %d\n",dev);
73227+ return MV_BAD_PARAM;
73228+ }
73229+
73230+ if (func >= MAX_PEX_FUNCS)
73231+ {
73232+ mvOsPrintf("mvPexConfigWrite: ERR. function number illigal %d\n", func);
73233+ return MV_ERROR;
73234+ }
73235+
73236+ if (bus >= MAX_PEX_BUSSES)
73237+ {
73238+ mvOsPrintf("mvPexConfigWrite: ERR. bus number illigal %d\n", bus);
73239+ return MV_ERROR;
73240+ }
73241+
73242+
73243+
73244+ localDev = mvPexLocalDevNumGet(pexIf);
73245+ localBus = mvPexLocalBusNumGet(pexIf);
73246+
73247+
73248+ /* in PCI Express we have only one device number other than ourselves*/
73249+ /* and this number is the first number we encounter
73250+ else than the localDev that can be any valid dev number*/
73251+ /* pex spec define return on config read/write on any device */
73252+ if (bus == localBus)
73253+ {
73254+
73255+ if (localDev == 0)
73256+ {
73257+ /* if local dev is 0 then the first number we encounter
73258+ after 0 is 1 */
73259+ if ((dev != 1)&&(dev != localDev))
73260+ {
73261+ return MV_ERROR;
73262+ }
73263+
73264+ }
73265+ else
73266+ {
73267+ /* if local dev is not 0 then the first number we encounter
73268+ is 0 */
73269+
73270+ if ((dev != 0)&&(dev != localDev))
73271+ {
73272+ return MV_ERROR;
73273+ }
73274+ }
73275+
73276+
73277+ }
73278+
73279+ /* if we are not accessing ourselves , then check the link */
73280+ if ((dev != localDev) || (bus != localBus) )
73281+ {
73282+ /* workarround */
73283+ /* when no link return MV_ERROR */
73284+
73285+ pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
73286+
73287+ if ((pexData & PXSR_DL_DOWN))
73288+ {
73289+ return MV_ERROR;
73290+ }
73291+
73292+ }
73293+
73294+ pexData =0;
73295+
73296+ /* Creating PEX address to be passed */
73297+ pexData |= (bus << PXCAR_BUS_NUM_OFFS);
73298+ pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
73299+ pexData |= (func << PXCAR_FUNC_NUM_OFFS);
73300+ pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
73301+ /* extended register space */
73302+ pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
73303+ PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
73304+ pexData |= PXCAR_CONFIG_EN;
73305+
73306+ DB(mvOsPrintf("mvPexConfigWrite: If=%x bus=%x func=%x dev=%x regOff=%x data=%x \n",
73307+ pexIf,bus,func,dev,regOff,data,pexData) );
73308+
73309+ /* Write the address to the PEX configuration address register */
73310+ MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
73311+
73312+ /* Clear CPU pipe. Important where CPU can perform OOO execution */
73313+ CPU_PIPE_FLUSH;
73314+
73315+ /* In order to let the PEX controller absorbed the address of the read */
73316+ /* transaction we perform a validity check that the address was written */
73317+ if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
73318+ {
73319+ return MV_ERROR;
73320+ }
73321+
73322+ /* Write the Data passed to the PEX Data register */
73323+ MV_REG_WRITE(PEX_CFG_DATA_REG(pexIf), data);
73324+
73325+ return MV_OK;
73326+
73327+}
73328+
73329+/*******************************************************************************
73330+* mvPexMasterEnable - Enable/disale PEX interface master transactions.
73331+*
73332+* DESCRIPTION:
73333+* This function performs read modified write to PEX command status
73334+* (offset 0x4) to set/reset bit 2. After this bit is set, the PEX
73335+* master is allowed to gain ownership on the bus, otherwise it is
73336+* incapable to do so.
73337+*
73338+* INPUT:
73339+* pexIf - PEX interface number.
73340+* enable - Enable/disable parameter.
73341+*
73342+* OUTPUT:
73343+* None.
73344+*
73345+* RETURN:
73346+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
73347+*
73348+*******************************************************************************/
73349+MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable)
73350+{
73351+ MV_U32 pexCommandStatus;
73352+ MV_U32 localBus;
73353+ MV_U32 localDev;
73354+
73355+ /* Parameter checking */
73356+ if (pexIf >= mvCtrlPexMaxIfGet())
73357+ {
73358+ mvOsPrintf("mvPexMasterEnable: ERR. Invalid PEX interface %d\n", pexIf);
73359+ return MV_ERROR;
73360+ }
73361+
73362+ localBus = mvPexLocalBusNumGet(pexIf);
73363+ localDev = mvPexLocalDevNumGet(pexIf);
73364+
73365+ pexCommandStatus = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
73366+ PEX_STATUS_AND_COMMAND));
73367+
73368+
73369+ if (MV_TRUE == enable)
73370+ {
73371+ pexCommandStatus |= PXSAC_MASTER_EN;
73372+ }
73373+ else
73374+ {
73375+ pexCommandStatus &= ~PXSAC_MASTER_EN;
73376+ }
73377+
73378+
73379+ MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
73380+ pexCommandStatus);
73381+
73382+ return MV_OK;
73383+}
73384+
73385+
73386+/*******************************************************************************
73387+* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.
73388+*
73389+* DESCRIPTION:
73390+* This function performs read modified write to PEX command status
73391+* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
73392+* the PEX slave is allowed to respond to PEX IO space access (bit 0)
73393+* and PEX memory space access (bit 1).
73394+*
73395+* INPUT:
73396+* pexIf - PEX interface number.
73397+* dev - PEX device number.
73398+* enable - Enable/disable parameter.
73399+*
73400+* OUTPUT:
73401+* None.
73402+*
73403+* RETURN:
73404+* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
73405+*
73406+*******************************************************************************/
73407+MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable)
73408+{
73409+ MV_U32 pexCommandStatus;
73410+ MV_U32 RegOffs;
73411+
73412+ /* Parameter checking */
73413+ if (pexIf >= mvCtrlPexMaxIfGet())
73414+ {
73415+ mvOsPrintf("mvPexSlaveEnable: ERR. Invalid PEX interface %d\n", pexIf);
73416+ return MV_BAD_PARAM;
73417+ }
73418+ if (dev >= MAX_PEX_DEVICES)
73419+ {
73420+ mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n", dev);
73421+ return MV_BAD_PARAM;
73422+
73423+ }
73424+
73425+
73426+ RegOffs = PEX_STATUS_AND_COMMAND;
73427+
73428+ pexCommandStatus = mvPexConfigRead(pexIf, bus, dev, 0, RegOffs);
73429+
73430+ if (MV_TRUE == enable)
73431+ {
73432+ pexCommandStatus |= (PXSAC_IO_EN | PXSAC_MEM_EN);
73433+ }
73434+ else
73435+ {
73436+ pexCommandStatus &= ~(PXSAC_IO_EN | PXSAC_MEM_EN);
73437+ }
73438+
73439+ mvPexConfigWrite(pexIf, bus, dev, 0, RegOffs, pexCommandStatus);
73440+
73441+ return MV_OK;
73442+
73443+}
73444+
73445+/*******************************************************************************
73446+* mvPexLocalBusNumSet - Set PEX interface local bus number.
73447+*
73448+* DESCRIPTION:
73449+* This function sets given PEX interface its local bus number.
73450+* Note: In case the PEX interface is PEX-X, the information is read-only.
73451+*
73452+* INPUT:
73453+* pexIf - PEX interface number.
73454+* busNum - Bus number.
73455+*
73456+* OUTPUT:
73457+* None.
73458+*
73459+* RETURN:
73460+* MV_NOT_ALLOWED in case PEX interface is PEX-X.
73461+* MV_BAD_PARAM on bad parameters ,
73462+* otherwise MV_OK
73463+*
73464+*******************************************************************************/
73465+MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum)
73466+{
73467+ MV_U32 pexStatus;
73468+ MV_U32 localBus;
73469+ MV_U32 localDev;
73470+
73471+
73472+ /* Parameter checking */
73473+ if (pexIf >= mvCtrlPexMaxIfGet())
73474+ {
73475+ mvOsPrintf("mvPexLocalBusNumSet: ERR. Invalid PEX interface %d\n",pexIf);
73476+ return MV_BAD_PARAM;
73477+ }
73478+ if (busNum >= MAX_PEX_BUSSES)
73479+ {
73480+ mvOsPrintf("mvPexLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
73481+ return MV_ERROR;
73482+
73483+ }
73484+
73485+ localBus = mvPexLocalBusNumGet(pexIf);
73486+ localDev = mvPexLocalDevNumGet(pexIf);
73487+
73488+
73489+
73490+ pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
73491+
73492+ pexStatus &= ~PXSR_PEX_BUS_NUM_MASK;
73493+
73494+ pexStatus |= (busNum << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
73495+
73496+ MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
73497+
73498+
73499+ return MV_OK;
73500+}
73501+
73502+
73503+/*******************************************************************************
73504+* mvPexLocalBusNumGet - Get PEX interface local bus number.
73505+*
73506+* DESCRIPTION:
73507+* This function gets the local bus number of a given PEX interface.
73508+*
73509+* INPUT:
73510+* pexIf - PEX interface number.
73511+*
73512+* OUTPUT:
73513+* None.
73514+*
73515+* RETURN:
73516+* Local bus number.0xffffffff on Error
73517+*
73518+*******************************************************************************/
73519+MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf)
73520+{
73521+ MV_U32 pexStatus;
73522+
73523+ /* Parameter checking */
73524+ if (PEX_DEFAULT_IF != pexIf)
73525+ {
73526+ if (pexIf >= mvCtrlPexMaxIfGet())
73527+ {
73528+ mvOsPrintf("mvPexLocalBusNumGet: ERR. Invalid PEX interface %d\n",pexIf);
73529+ return 0xFFFFFFFF;
73530+ }
73531+ }
73532+
73533+
73534+ pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
73535+
73536+ pexStatus &= PXSR_PEX_BUS_NUM_MASK;
73537+
73538+ return (pexStatus >> PXSR_PEX_BUS_NUM_OFFS);
73539+
73540+}
73541+
73542+
73543+/*******************************************************************************
73544+* mvPexLocalDevNumSet - Set PEX interface local device number.
73545+*
73546+* DESCRIPTION:
73547+* This function sets given PEX interface its local device number.
73548+* Note: In case the PEX interface is PEX-X, the information is read-only.
73549+*
73550+* INPUT:
73551+* pexIf - PEX interface number.
73552+* devNum - Device number.
73553+*
73554+* OUTPUT:
73555+* None.
73556+*
73557+* RETURN:
73558+* MV_NOT_ALLOWED in case PEX interface is PEX-X.
73559+* MV_BAD_PARAM on bad parameters ,
73560+* otherwise MV_OK
73561+*
73562+*******************************************************************************/
73563+MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum)
73564+{
73565+ MV_U32 pexStatus;
73566+ MV_U32 localBus;
73567+ MV_U32 localDev;
73568+
73569+ /* Parameter checking */
73570+ if (pexIf >= mvCtrlPexMaxIfGet())
73571+ {
73572+ mvOsPrintf("mvPexLocalDevNumSet: ERR. Invalid PEX interface %d\n",pexIf);
73573+ return MV_BAD_PARAM;
73574+ }
73575+ if (devNum >= MAX_PEX_DEVICES)
73576+ {
73577+ mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n",
73578+ devNum);
73579+ return MV_BAD_PARAM;
73580+
73581+ }
73582+
73583+ localBus = mvPexLocalBusNumGet(pexIf);
73584+ localDev = mvPexLocalDevNumGet(pexIf);
73585+
73586+
73587+ pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
73588+
73589+ pexStatus &= ~PXSR_PEX_DEV_NUM_MASK;
73590+
73591+ pexStatus |= (devNum << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
73592+
73593+ MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
73594+
73595+
73596+ return MV_OK;
73597+}
73598+
73599+/*******************************************************************************
73600+* mvPexLocalDevNumGet - Get PEX interface local device number.
73601+*
73602+* DESCRIPTION:
73603+* This function gets the local device number of a given PEX interface.
73604+*
73605+* INPUT:
73606+* pexIf - PEX interface number.
73607+*
73608+* OUTPUT:
73609+* None.
73610+*
73611+* RETURN:
73612+* Local device number. 0xffffffff on Error
73613+*
73614+*******************************************************************************/
73615+MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf)
73616+{
73617+ MV_U32 pexStatus;
73618+
73619+ /* Parameter checking */
73620+
73621+ if (PEX_DEFAULT_IF != pexIf)
73622+ {
73623+ if (pexIf >= mvCtrlPexMaxIfGet())
73624+ {
73625+ mvOsPrintf("mvPexLocalDevNumGet: ERR. Invalid PEX interface %d\n",
73626+ pexIf);
73627+ return 0xFFFFFFFF;
73628+ }
73629+ }
73630+
73631+ pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
73632+
73633+ pexStatus &= PXSR_PEX_DEV_NUM_MASK;
73634+
73635+ return (pexStatus >> PXSR_PEX_DEV_NUM_OFFS);
73636+}
73637+
73638+MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value)
73639+{
73640+
73641+ MV_U32 regAddr;
73642+ if (pexIf >= mvCtrlPexMaxIfGet())
73643+ {
73644+ mvOsPrintf("mvPexPhyRegRead: ERR. Invalid PEX interface %d\n", pexIf);
73645+ return;
73646+ }
73647+ regAddr = (BIT31 | ((regOffset & 0x3fff) << 16));
73648+ MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
73649+ *value = MV_REG_READ(PEX_PHY_ACCESS_REG(pexIf));
73650+}
73651+
73652+
73653+MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value)
73654+{
73655+
73656+ MV_U32 regAddr;
73657+ if(pexIf >= mvCtrlPexMaxIfGet())
73658+ {
73659+ mvOsPrintf("mvPexPhyRegWrite: ERR. Invalid PEX interface %d\n", pexIf);
73660+ return;
73661+ }
73662+ regAddr = (((regOffset & 0x3fff) << 16) | value);
73663+ MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
73664+}
73665+
73666+/*******************************************************************************
73667+* mvPexActiveStateLinkPMEnable
73668+*
73669+* DESCRIPTION:
73670+* Enable Active Link State Power Management
73671+*
73672+* INPUT:
73673+* pexIf - PEX interface number.
73674+* enable - MV_TRUE to enable ASPM, MV_FALSE to disable.
73675+*
73676+* OUTPUT:
73677+* None
73678+*
73679+* RETURN:
73680+* MV_OK on success , MV_ERROR otherwise
73681+*
73682+*******************************************************************************/
73683+MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable)
73684+{
73685+ MV_U32 reg;
73686+
73687+ if(pexIf >= mvCtrlPexMaxIfGet())
73688+ {
73689+ mvOsPrintf("mvPexActiveStateLinkPMEnable: ERR. Invalid PEX interface %d\n", pexIf);
73690+ return MV_ERROR;
73691+ }
73692+
73693+ reg = MV_REG_READ(PEX_PWR_MNG_EXT_REG(pexIf)) & ~PXPMER_L1_ASPM_EN_MASK;
73694+ if(enable == MV_TRUE)
73695+ reg |= PXPMER_L1_ASPM_EN_MASK;
73696+ MV_REG_WRITE(PEX_PWR_MNG_EXT_REG(pexIf), reg);
73697+
73698+ /* Enable / Disable L0/1 entry */
73699+ reg = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG))
73700+ & ~PXLCSR_ASPM_CNT_MASK;
73701+ if(enable == MV_TRUE)
73702+ reg |= PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP;
73703+ MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG), reg);
73704+
73705+ return MV_OK;
73706+}
73707+
73708+
73709+/*******************************************************************************
73710+* mvPexForceX1
73711+*
73712+* DESCRIPTION:
73713+* shut down lanes 1-3 if recognize that attached to an x1 end-point
73714+* INPUT:
73715+* pexIf - PEX interface number.
73716+*
73717+* OUTPUT:
73718+* None
73719+*
73720+* RETURN:
73721+* MV_OK on success , MV_ERROR otherwise
73722+*
73723+*******************************************************************************/
73724+MV_U32 mvPexForceX1(MV_U32 pexIf)
73725+{
73726+ MV_U32 regData = 0;
73727+ if(pexIf >= mvCtrlPexMaxIfGet())
73728+ {
73729+ mvOsPrintf("mvPexForceX1: ERR. Invalid PEX interface %d\n", pexIf);
73730+ return MV_BAD_PARAM;
73731+ }
73732+
73733+ regData = MV_REG_READ(PEX_CTRL_REG(pexIf)) & ~(PXCR_CONF_LINK_MASK) ;
73734+ regData |= PXCR_CONF_LINK_X1;
73735+
73736+ MV_REG_WRITE(PEX_CTRL_REG(pexIf), regData);
73737+ return MV_OK;
73738+}
73739+
73740+MV_BOOL mvPexIsPowerUp(MV_U32 pexIf)
73741+{
73742+ if(pexIf >= mvCtrlPexMaxIfGet())
73743+ {
73744+ mvOsPrintf("mvPexIsPowerUp: ERR. Invalid PEX interface %d\n", pexIf);
73745+ return MV_FALSE;
73746+ }
73747+ return mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf);
73748+}
73749+
73750+
73751+MV_VOID mvPexPowerDown(MV_U32 pexIf)
73752+{
73753+ if ( (mvCtrlModelGet() == MV_78XX0_DEV_ID) ||
73754+ (mvCtrlModelGet() == MV_76100_DEV_ID) ||
73755+ (mvCtrlModelGet() == MV_78100_DEV_ID) ||
73756+ (mvCtrlModelGet() == MV_78200_DEV_ID) )
73757+ {
73758+ mvCtrlPwrClckSet(PEX_UNIT_ID, pexIf, MV_FALSE);
73759+ }
73760+ else
73761+ {
73762+ MV_REG_WRITE((0x41B00 -(pexIf)*0x10000), 0x20800087);
73763+ }
73764+}
73765+
73766+
73767+
73768diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h b/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h
73769new file mode 100644
73770index 0000000..e84fdf9
73771--- /dev/null
73772+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h
73773@@ -0,0 +1,168 @@
73774+/*******************************************************************************
73775+Copyright (C) Marvell International Ltd. and its affiliates
73776+
73777+This software file (the "File") is owned and distributed by Marvell
73778+International Ltd. and/or its affiliates ("Marvell") under the following
73779+alternative licensing terms. Once you have made an election to distribute the
73780+File under one of the following license alternatives, please (i) delete this
73781+introductory statement regarding license alternatives, (ii) delete the two
73782+license alternatives that you have not elected to use and (iii) preserve the
73783+Marvell copyright notice above.
73784+
73785+********************************************************************************
73786+Marvell Commercial License Option
73787+
73788+If you received this File from Marvell and you have entered into a commercial
73789+license agreement (a "Commercial License") with Marvell, the File is licensed
73790+to you under the terms of the applicable Commercial License.
73791+
73792+********************************************************************************
73793+Marvell GPL License Option
73794+
73795+If you received this File from Marvell, you may opt to use, redistribute and/or
73796+modify this File in accordance with the terms and conditions of the General
73797+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
73798+available along with the File in the license.txt file or by writing to the Free
73799+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
73800+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
73801+
73802+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
73803+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
73804+DISCLAIMED. The GPL License provides additional details about this warranty
73805+disclaimer.
73806+********************************************************************************
73807+Marvell BSD License Option
73808+
73809+If you received this File from Marvell, you may opt to use, redistribute and/or
73810+modify this File under the following licensing terms.
73811+Redistribution and use in source and binary forms, with or without modification,
73812+are permitted provided that the following conditions are met:
73813+
73814+ * Redistributions of source code must retain the above copyright notice,
73815+ this list of conditions and the following disclaimer.
73816+
73817+ * Redistributions in binary form must reproduce the above copyright
73818+ notice, this list of conditions and the following disclaimer in the
73819+ documentation and/or other materials provided with the distribution.
73820+
73821+ * Neither the name of Marvell nor the names of its contributors may be
73822+ used to endorse or promote products derived from this software without
73823+ specific prior written permission.
73824+
73825+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
73826+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73827+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73828+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
73829+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73830+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73831+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
73832+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73833+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73834+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73835+
73836+*******************************************************************************/
73837+
73838+#ifndef __INCPEXH
73839+#define __INCPEXH
73840+
73841+#include "mvCommon.h"
73842+#include "mvOs.h"
73843+#include "pex/mvPexRegs.h"
73844+#include "ctrlEnv/mvCtrlEnvSpec.h"
73845+
73846+
73847+
73848+/* NOTE not supported in this driver:*/
73849+
73850+
73851+/* defines */
73852+/* The number of supported PEX interfaces depend on Marvell controller */
73853+/* device number. This device number ID is located on the PEX unit */
73854+/* configuration header. This creates a loop where calling PEX */
73855+/* configuration read/write routine results a call to get PEX configuration */
73856+/* information etc. This macro defines a default PEX interface. This PEX */
73857+/* interface is sure to exist. */
73858+#define PEX_DEFAULT_IF 0
73859+
73860+
73861+/* typedefs */
73862+/* The Marvell controller supports both root complex and end point devices */
73863+/* This enumeration describes the PEX type. */
73864+typedef enum _mvPexType
73865+{
73866+ MV_PEX_ROOT_COMPLEX, /* root complex device */
73867+ MV_PEX_END_POINT /* end point device */
73868+}MV_PEX_TYPE;
73869+
73870+typedef enum _mvPexWidth
73871+{
73872+ MV_PEX_WITDH_X1 = 1,
73873+ MV_PEX_WITDH_X2,
73874+ MV_PEX_WITDH_X3,
73875+ MV_PEX_WITDH_X4,
73876+ MV_PEX_WITDH_INVALID
73877+}MV_PEX_WIDTH;
73878+
73879+/* PEX Bar attributes */
73880+typedef struct _mvPexMode
73881+{
73882+ MV_PEX_TYPE pexType;
73883+ MV_PEX_WIDTH pexWidth;
73884+ MV_BOOL pexLinkUp;
73885+}MV_PEX_MODE;
73886+
73887+
73888+
73889+/* Global Functions prototypes */
73890+/* mvPexInit - Initialize PEX interfaces*/
73891+MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType);
73892+
73893+/* mvPexModeGet - Get Pex If mode */
73894+MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode);
73895+
73896+/* mvPexConfigRead - Read from configuration space */
73897+MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
73898+ MV_U32 func,MV_U32 regOff);
73899+
73900+/* mvPexConfigWrite - Write to configuration space */
73901+MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
73902+ MV_U32 func, MV_U32 regOff, MV_U32 data);
73903+
73904+/* mvPexMasterEnable - Enable/disale PEX interface master transactions.*/
73905+MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable);
73906+
73907+/* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.*/
73908+MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable);
73909+
73910+/* mvPexLocalBusNumSet - Set PEX interface local bus number.*/
73911+MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum);
73912+
73913+/* mvPexLocalBusNumGet - Get PEX interface local bus number.*/
73914+MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf);
73915+
73916+/* mvPexLocalDevNumSet - Set PEX interface local device number.*/
73917+MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum);
73918+
73919+/* mvPexLocalDevNumGet - Get PEX interface local device number.*/
73920+MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf);
73921+/* mvPexForceX1 - Force PEX interface to X1 mode. */
73922+MV_U32 mvPexForceX1(MV_U32 pexIf);
73923+
73924+/* mvPexIsPowerUp - Is PEX interface Power up? */
73925+MV_BOOL mvPexIsPowerUp(MV_U32 pexIf);
73926+
73927+/* mvPexPowerDown - Power Down */
73928+MV_VOID mvPexPowerDown(MV_U32 pexIf);
73929+
73930+/* mvPexPowerUp - Power Up */
73931+MV_VOID mvPexPowerUp(MV_U32 pexIf);
73932+
73933+/* mvPexPhyRegRead - Pex phy read */
73934+MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value);
73935+
73936+/* mvPexPhyRegWrite - Pex phy write */
73937+MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value);
73938+
73939+MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable);
73940+
73941+#endif /* #ifndef __INCPEXH */
73942diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h b/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h
73943new file mode 100644
73944index 0000000..ea19e2f
73945--- /dev/null
73946+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h
73947@@ -0,0 +1,751 @@
73948+/*******************************************************************************
73949+Copyright (C) Marvell International Ltd. and its affiliates
73950+
73951+This software file (the "File") is owned and distributed by Marvell
73952+International Ltd. and/or its affiliates ("Marvell") under the following
73953+alternative licensing terms. Once you have made an election to distribute the
73954+File under one of the following license alternatives, please (i) delete this
73955+introductory statement regarding license alternatives, (ii) delete the two
73956+license alternatives that you have not elected to use and (iii) preserve the
73957+Marvell copyright notice above.
73958+
73959+********************************************************************************
73960+Marvell Commercial License Option
73961+
73962+If you received this File from Marvell and you have entered into a commercial
73963+license agreement (a "Commercial License") with Marvell, the File is licensed
73964+to you under the terms of the applicable Commercial License.
73965+
73966+********************************************************************************
73967+Marvell GPL License Option
73968+
73969+If you received this File from Marvell, you may opt to use, redistribute and/or
73970+modify this File in accordance with the terms and conditions of the General
73971+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
73972+available along with the File in the license.txt file or by writing to the Free
73973+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
73974+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
73975+
73976+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
73977+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
73978+DISCLAIMED. The GPL License provides additional details about this warranty
73979+disclaimer.
73980+********************************************************************************
73981+Marvell BSD License Option
73982+
73983+If you received this File from Marvell, you may opt to use, redistribute and/or
73984+modify this File under the following licensing terms.
73985+Redistribution and use in source and binary forms, with or without modification,
73986+are permitted provided that the following conditions are met:
73987+
73988+ * Redistributions of source code must retain the above copyright notice,
73989+ this list of conditions and the following disclaimer.
73990+
73991+ * Redistributions in binary form must reproduce the above copyright
73992+ notice, this list of conditions and the following disclaimer in the
73993+ documentation and/or other materials provided with the distribution.
73994+
73995+ * Neither the name of Marvell nor the names of its contributors may be
73996+ used to endorse or promote products derived from this software without
73997+ specific prior written permission.
73998+
73999+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
74000+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
74001+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74002+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
74003+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
74004+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
74005+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
74006+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74007+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74008+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74009+
74010+*******************************************************************************/
74011+
74012+#ifndef __INCPEXREGSH
74013+#define __INCPEXREGSH
74014+
74015+#ifdef __cplusplus
74016+extern "C" {
74017+#endif /* __cplusplus */
74018+
74019+/* defines */
74020+#define MAX_PEX_DEVICES 32
74021+#define MAX_PEX_FUNCS 8
74022+#define MAX_PEX_BUSSES 256
74023+
74024+
74025+
74026+/*********************************************************/
74027+/* PCI Express Configuration Cycles Generation Registers */
74028+/*********************************************************/
74029+
74030+#define PEX_CFG_ADDR_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x18F8)
74031+#define PEX_CFG_DATA_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x18FC)
74032+#define PEX_PHY_ACCESS_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1B00)
74033+/* PCI Express Configuration Address Register */
74034+/* PEX_CFG_ADDR_REG (PXCAR)*/
74035+
74036+#define PXCAR_REG_NUM_OFFS 2
74037+#define PXCAR_REG_NUM_MAX 0x3F
74038+#define PXCAR_REG_NUM_MASK (PXCAR_REG_NUM_MAX << PXCAR_REG_NUM_OFFS)
74039+#define PXCAR_FUNC_NUM_OFFS 8
74040+#define PXCAR_FUNC_NUM_MAX 0x7
74041+#define PXCAR_FUNC_NUM_MASK (PXCAR_FUNC_NUM_MAX << PXCAR_FUNC_NUM_OFFS)
74042+#define PXCAR_DEVICE_NUM_OFFS 11
74043+#define PXCAR_DEVICE_NUM_MAX 0x1F
74044+#define PXCAR_DEVICE_NUM_MASK (PXCAR_DEVICE_NUM_MAX << PXCAR_DEVICE_NUM_OFFS)
74045+#define PXCAR_BUS_NUM_OFFS 16
74046+#define PXCAR_BUS_NUM_MAX 0xFF
74047+#define PXCAR_BUS_NUM_MASK (PXCAR_BUS_NUM_MAX << PXCAR_BUS_NUM_OFFS)
74048+#define PXCAR_EXT_REG_NUM_OFFS 24
74049+#define PXCAR_EXT_REG_NUM_MAX 0xF
74050+
74051+/* in pci express register address is now the legacy register address (8 bits)
74052+with the new extended register address (more 4 bits) , below is the mask of
74053+the upper 4 bits of the full register address */
74054+
74055+#define PXCAR_REAL_EXT_REG_NUM_OFFS 8
74056+#define PXCAR_EXT_REG_NUM_MASK (PXCAR_EXT_REG_NUM_MAX << PXCAR_EXT_REG_NUM_OFFS)
74057+#define PXCAR_CONFIG_EN BIT31
74058+
74059+#define PXCAR_REAL_EXT_REG_NUM_OFFS 8
74060+#define PXCAR_REAL_EXT_REG_NUM_MASK (0xF << PXCAR_REAL_EXT_REG_NUM_OFFS)
74061+
74062+/* The traditional PCI spec defined 6-bit field to describe register offset.*/
74063+/* The new PCI Express extend the register offset by an extra 4-bits. */
74064+/* The below macro assign 10-bit register offset into the apprpreate */
74065+/* fields in the CFG_ADDR_REG */
74066+#define PXCAR_REG_OFFS_SET(regOffs) \
74067+ ( (regOff & PXCAR_REG_NUM_MASK) | \
74068+ ( ((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >> PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS) )
74069+
74070+/***********************************/
74071+/* PCI Express Interrupt registers */
74072+/***********************************/
74073+#define PEX_CAUSE_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1900)
74074+#define PEX_MASK_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1910)
74075+
74076+#define PXICR_TX_REQ_IN_DLDOWN_ERR BIT0 /* Transmit request while field */
74077+ /* <DLDown> of the PCI Express */
74078+/* PCI Express Interrupt Cause */
74079+/* PEX_INT_CAUSE_REG (PXICR)*/
74080+/* PEX_INT_MASK_REG*/
74081+/*
74082+NOTE:All bits except bits[27:24] are Read/Write Clear only. A cause bit sets
74083+upon an error event occurrence. A write of 0 clears the bit. A write of 1 has
74084+no affect. Bits[24:27} are set and cleared upon reception of interrupt
74085+emulation messages.
74086+
74087+Mask bit per cause bit. If a bit is set to 1, the corresponding event is
74088+enabled. Mask does not affect setting of the Interrupt Cause register bits;
74089+it only affects the assertion of the interrupt .*/
74090+
74091+
74092+#define PXICR_MDIS_CAUSE BIT1 /* Attempt to generate PCI transaction
74093+ while master is disabled */
74094+#define PXICR_ERR_WRTO_REG_CAUSE BIT3 /* Erroneous write attempt to
74095+ PCI Express internal register*/
74096+#define PXICR_HIT_DFLT_WIN_ERR BIT4 /* Hit Default Window Error */
74097+#define PXICR_RX_RAM_PAR_ERR BIT6 /* Rx RAM Parity Error */
74098+#define PXICR_TX_RAM_PAR_ERR BIT7 /* Tx RAM Parity Error */
74099+#define PXICR_COR_ERR_DET BIT8 /* Correctable Error Detected*/
74100+#define PXICR_NF_ERR_DET BIT9 /* Non-Fatal Error Detected*/
74101+#define PXICR_FERR_DET BIT10 /* Fatal Error Detected*/
74102+#define PXICR_DSTATE_CHANGE BIT11 /* Dstate Change Indication*/
74103+#define PXICR_BIST BIT12 /* PCI-Express BIST activated*/
74104+#define PXICR_FLW_CTRL_PROT BIT14 /* Flow Control Protocol Error */
74105+
74106+#define PXICR_RCV_UR_CA_ERR BIT15 /* Received UR or CA status. */
74107+#define PXICR_RCV_ERR_FATAL BIT16 /* Received ERR_FATAL message.*/
74108+#define PXICR_RCV_ERR_NON_FATAL BIT17 /* Received ERR_NONFATAL message*/
74109+#define PXICR_RCV_ERR_COR BIT18 /* Received ERR_COR message.*/
74110+#define PXICR_RCV_CRS BIT19 /* Received CRS completion status*/
74111+#define PXICR_SLV_HOT_RESET BIT20 /* Received Hot Reset Indication*/
74112+#define PXICR_SLV_DIS_LINK BIT21 /* Slave Disable Link Indication*/
74113+#define PXICR_SLV_LB BIT22 /* Slave Loopback Indication*/
74114+#define PXICR_LINK_FAIL BIT23 /* Link Failure indication.*/
74115+#define PXICR_RCV_INTA BIT24 /* IntA status.*/
74116+#define PXICR_RCV_INTB BIT25 /* IntB status.*/
74117+#define PXICR_RCV_INTC BIT26 /* IntC status.*/
74118+#define PXICR_RCV_INTD BIT27 /* IntD status.*/
74119+#define PXICR_RCV_PM_PME BIT28 /* Received PM_PME message. */
74120+
74121+
74122+/********************************************/
74123+/* PCI Express Control and Status Registers */
74124+/********************************************/
74125+#define PEX_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A00)
74126+#define PEX_STATUS_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A04)
74127+#define PEX_COMPLT_TMEOUT_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A10)
74128+#define PEX_PWR_MNG_EXT_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A18)
74129+#define PEX_FLOW_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A20)
74130+#define PEX_ACK_TMR_4X_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A30)
74131+#define PEX_ACK_TMR_1X_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A40)
74132+#define PEX_TL_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1AB0)
74133+
74134+
74135+#define PEX_RAM_PARITY_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A50)
74136+/* PCI Express Control Register */
74137+/* PEX_CTRL_REG (PXCR) */
74138+
74139+#define PXCR_CONF_LINK_OFFS 0
74140+#define PXCR_CONF_LINK_MASK (1 << PXCR_CONF_LINK_OFFS)
74141+#define PXCR_CONF_LINK_X4 (0 << PXCR_CONF_LINK_OFFS)
74142+#define PXCR_CONF_LINK_X1 (1 << PXCR_CONF_LINK_OFFS)
74143+#define PXCR_DEV_TYPE_CTRL_OFFS 1 /*PCI ExpressDevice Type Control*/
74144+#define PXCR_DEV_TYPE_CTRL_MASK BIT1
74145+#define PXCR_DEV_TYPE_CTRL_CMPLX (1 << PXCR_DEV_TYPE_CTRL_OFFS)
74146+#define PXCR_DEV_TYPE_CTRL_POINT (0 << PXCR_DEV_TYPE_CTRL_OFFS)
74147+#define PXCR_CFG_MAP_TO_MEM_EN BIT2 /* Configuration Header Mapping
74148+ to Memory Space Enable */
74149+
74150+#define PXCR_CFG_MAP_TO_MEM_EN BIT2 /* Configuration Header Mapping
74151+ to Memory Space Enable*/
74152+
74153+#define PXCR_RSRV1_OFFS 5
74154+#define PXCR_RSRV1_MASK (0x7 << PXCR_RSRV1_OFFS)
74155+#define PXCR_RSRV1_VAL (0x0 << PXCR_RSRV1_OFFS)
74156+
74157+#define PXCR_CONF_MAX_OUTSTND_OFFS 8 /*Maximum outstanding NP requests as a master*/
74158+#define PXCR_CONF_MAX_OUTSTND_MASK (0x3 << PXCR_CONF_MAX_OUTSTND_OFFS)
74159+
74160+
74161+#define PXCR_CONF_NFTS_OFFS 16 /*number of FTS Ordered-Sets*/
74162+#define PXCR_CONF_NFTS_MASK (0xff << PXCR_CONF_NFTS_OFFS)
74163+
74164+#define PXCR_CONF_MSTR_HOT_RESET BIT24 /*Master Hot-Reset.*/
74165+#define PXCR_CONF_MSTR_LB BIT26 /* Master Loopback */
74166+#define PXCR_CONF_MSTR_DIS_SCRMB BIT27 /* Master Disable Scrambling*/
74167+#define PXCR_CONF_DIRECT_DIS_SCRMB BIT28 /* Direct Disable Scrambling*/
74168+
74169+/* PCI Express Status Register */
74170+/* PEX_STATUS_REG (PXSR) */
74171+
74172+#define PXSR_DL_DOWN BIT0 /* DL_Down indication.*/
74173+
74174+#define PXSR_PEX_BUS_NUM_OFFS 8 /* Bus Number Indication */
74175+#define PXSR_PEX_BUS_NUM_MASK (0xff << PXSR_PEX_BUS_NUM_OFFS)
74176+
74177+#define PXSR_PEX_DEV_NUM_OFFS 16 /* Device Number Indication */
74178+#define PXSR_PEX_DEV_NUM_MASK (0x1f << PXSR_PEX_DEV_NUM_OFFS)
74179+
74180+#define PXSR_PEX_SLV_HOT_RESET BIT24 /* Slave Hot Reset Indication*/
74181+#define PXSR_PEX_SLV_DIS_LINK BIT25 /* Slave Disable Link Indication*/
74182+#define PXSR_PEX_SLV_LB BIT26 /* Slave Loopback Indication*/
74183+#define PXSR_PEX_SLV_DIS_SCRMB BIT27 /* Slave Disable Scrambling Indication*/
74184+
74185+
74186+/* PCI Express Completion Timeout Register */
74187+/* PEX_COMPLT_TMEOUT_REG (PXCTR)*/
74188+
74189+#define PXCTR_CMP_TO_THRSHLD_OFFS 0 /* Completion Timeout Threshold */
74190+#define PXCTR_CMP_TO_THRSHLD_MASK (0xffff << PXCTR_CMP_TO_THRSHLD_OFFS)
74191+
74192+/* PCI Express Power Management Extended Register */
74193+/* PEX_PWR_MNG_EXT_REG (PXPMER) */
74194+
74195+#define PXPMER_L1_ASPM_EN_OFFS 1
74196+#define PXPMER_L1_ASPM_EN_MASK (0x1 << PXPMER_L1_ASPM_EN_OFFS)
74197+
74198+/* PCI Express Flow Control Register */
74199+/* PEX_FLOW_CTRL_REG (PXFCR)*/
74200+
74201+#define PXFCR_PH_INIT_FC_OFFS 0 /*Posted Headers Flow Control Credit
74202+ Initial Value.*/
74203+#define PXFCR_PH_INIT_FC_MASK (0xff << PXFCR_PH_INIT_FC_OFFS)
74204+
74205+
74206+#define PXFCR_NPH_INIT_FC_OFFS 8 /* Classified Non-Posted Headers
74207+ Flow Control Credit Initial Value*/
74208+#define PXFCR_NPH_INIT_FC_MASK (0xff << PXFCR_NPH_INIT_FC_OFFS)
74209+
74210+#define PXFCR_CH_INIT_FC_OFFS 16 /* Completion Headers Flow Control
74211+ Credit Initial Value Infinite*/
74212+
74213+#define PXFCR_CH_INIT_FC_MASK (0xff << PXFCR_CH_INIT_FC_OFFS)
74214+
74215+#define PXFCR_FC_UPDATE_TO_OFFS 24 /* Flow Control Update Timeout */
74216+#define PXFCR_FC_UPDATE_TO_MASK (0xff << PXFCR_FC_UPDATE_TO_OFFS)
74217+
74218+/* PCI Express Acknowledge Timers (4X) Register */
74219+/* PEX_ACK_TMR_4X_REG (PXAT4R) */
74220+#define PXAT1R_ACK_LAT_TOX4_OFFS 0 /* Ack Latency Timer Timeout Value */
74221+#define PXAT1R_ACK_LAT_TOX4_MASK (0xffff << PXAT4R_ACK_LAT_TOX1_OFFS)
74222+#define PXAT1R_ACK_RPLY_TOX4_OFFS 16 /* Ack Replay Timer Timeout Value */
74223+#define PXAT1R_ACK_RPLY_TOX4_MASK (0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)
74224+
74225+/* PCI Express Acknowledge Timers (1X) Register */
74226+/* PEX_ACK_TMR_1X_REG (PXAT1R) */
74227+
74228+#define PXAT1R_ACK_LAT_TOX1_OFFS 0 /* Acknowledge Latency Timer Timeout
74229+ Value for 1X Link*/
74230+#define PXAT1R_ACK_LAT_TOX1_MASK (0xffff << PXAT1R_ACK_LAT_TOX1_OFFS)
74231+
74232+#define PXAT1R_ACK_RPLY_TOX1_OFFS 16 /* Acknowledge Replay Timer Timeout
74233+ Value for 1X*/
74234+#define PXAT1R_ACK_RPLY_TOX1_MASK (0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)
74235+
74236+
74237+/* PCI Express TL Control Register */
74238+/* PEX_TL_CTRL_REG (PXTCR) */
74239+
74240+#define PXTCR_TX_CMP_BUFF_NO_OFFS 8 /*Number of completion buffers in Tx*/
74241+#define PXTCR_TX_CMP_BUFF_NO_MASK (0xf << PXTCR_TX_CMP_BUFF_NO_OFFS)
74242+
74243+/* PCI Express Debug MAC Control Register */
74244+/* PEX_DEBUG_MAC_CTRL_REG (PXDMCR) */
74245+
74246+#define PXDMCR_LINKUP BIT4
74247+
74248+
74249+
74250+/**********************************************/
74251+/* PCI Express Configuration Header Registers */
74252+/**********************************************/
74253+#define PEX_CFG_DIRECT_ACCESS(pexIf,cfgReg) ((PEX_IF_BASE(pexIf)) + (cfgReg))
74254+
74255+#define PEX_DEVICE_AND_VENDOR_ID 0x000
74256+#define PEX_STATUS_AND_COMMAND 0x004
74257+#define PEX_CLASS_CODE_AND_REVISION_ID 0x008
74258+#define PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE 0x00C
74259+#define PEX_MEMORY_BAR_BASE_ADDR(barNum) (0x010 + ((barNum) << 2))
74260+#define PEX_MV_BAR_BASE(barNum) (0x010 + (barNum) * 8)
74261+#define PEX_MV_BAR_BASE_HIGH(barNum) (0x014 + (barNum) * 8)
74262+#define PEX_BAR0_INTER_REG 0x010
74263+#define PEX_BAR0_INTER_REG_HIGH 0x014
74264+#define PEX_BAR1_REG 0x018
74265+#define PEX_BAR1_REG_HIGH 0x01C
74266+#define PEX_BAR2_REG 0x020
74267+#define PEX_BAR2_REG_HIGH 0x024
74268+
74269+#define PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID 0x02C
74270+#define PEX_EXPANSION_ROM_BASE_ADDR_REG 0x030
74271+#define PEX_CAPABILTY_LIST_POINTER 0x034
74272+#define PEX_INTERRUPT_PIN_AND_LINE 0x03C
74273+
74274+/* capability list */
74275+#define PEX_POWER_MNG_CAPABILITY 0x040
74276+#define PEX_POWER_MNG_STATUS_CONTROL 0x044
74277+
74278+#define PEX_MSI_MESSAGE_CONTROL 0x050
74279+#define PEX_MSI_MESSAGE_ADDR 0x054
74280+#define PEX_MSI_MESSAGE_HIGH_ADDR 0x058
74281+#define PEX_MSI_MESSAGE_DATA 0x05C
74282+
74283+#define PEX_CAPABILITY_REG 0x60
74284+#define PEX_DEV_CAPABILITY_REG 0x64
74285+#define PEX_DEV_CTRL_STAT_REG 0x68
74286+#define PEX_LINK_CAPABILITY_REG 0x6C
74287+#define PEX_LINK_CTRL_STAT_REG 0x70
74288+
74289+#define PEX_ADV_ERR_RPRT_HDR_TRGT_REG 0x100
74290+#define PEX_UNCORRECT_ERR_STAT_REG 0x104
74291+#define PEX_UNCORRECT_ERR_MASK_REG 0x108
74292+#define PEX_UNCORRECT_ERR_SERVITY_REG 0x10C
74293+#define PEX_CORRECT_ERR_STAT_REG 0x110
74294+#define PEX_CORRECT_ERR_MASK_REG 0x114
74295+#define PEX_ADV_ERR_CAPABILITY_CTRL_REG 0x118
74296+#define PEX_HDR_LOG_FIRST_DWORD_REG 0x11C
74297+#define PEX_HDR_LOG_SECOND_DWORD_REG 0x120
74298+#define PEX_HDR_LOG_THIRD_DWORD_REG 0x124
74299+#define PEX_HDR_LOG_FOURTH_DWORD_REG 0x128
74300+
74301+
74302+
74303+/* PCI Express Device and Vendor ID Register*/
74304+/*PEX_DEVICE_AND_VENDOR_ID (PXDAVI)*/
74305+
74306+#define PXDAVI_VEN_ID_OFFS 0 /* Vendor ID */
74307+#define PXDAVI_VEN_ID_MASK (0xffff << PXDAVI_VEN_ID_OFFS)
74308+
74309+#define PXDAVI_DEV_ID_OFFS 16 /* Device ID */
74310+#define PXDAVI_DEV_ID_MASK (0xffff << PXDAVI_DEV_ID_OFFS)
74311+
74312+
74313+/* PCI Express Command and Status Register*/
74314+/*PEX_STATUS_AND_COMMAND (PXSAC)*/
74315+
74316+#define PXSAC_IO_EN BIT0 /* IO Enable */
74317+#define PXSAC_MEM_EN BIT1 /* Memory Enable */
74318+#define PXSAC_MASTER_EN BIT2 /* Master Enable */
74319+#define PXSAC_PERR_EN BIT6 /* Parity Errors Respond Enable */
74320+#define PXSAC_SERR_EN BIT8 /* Ability to assert SERR# line */
74321+#define PXSAC_INT_DIS BIT10 /* Interrupt Disable */
74322+#define PXSAC_INT_STAT BIT19 /* Interrupt Status */
74323+#define PXSAC_CAP_LIST BIT20 /* Capability List Support */
74324+#define PXSAC_MAS_DATA_PERR BIT24 /* Master Data Parity Error */
74325+#define PXSAC_SLAVE_TABORT BIT27 /* Signalled Target Abort */
74326+#define PXSAC_RT_ABORT BIT28 /* Recieved Target Abort */
74327+#define PXSAC_MABORT BIT29 /* Recieved Master Abort */
74328+#define PXSAC_SYSERR BIT30 /* Signalled system error */
74329+#define PXSAC_DET_PARERR BIT31 /* Detect Parity Error */
74330+
74331+
74332+/* PCI Express Class Code and Revision ID Register*/
74333+/*PEX_CLASS_CODE_AND_REVISION_ID (PXCCARI)*/
74334+
74335+#define PXCCARI_REVID_OFFS 0 /* Revision ID */
74336+#define PXCCARI_REVID_MASK (0xff << PXCCARI_REVID_OFFS)
74337+
74338+#define PXCCARI_FULL_CLASS_OFFS 8 /* Full Class Code */
74339+#define PXCCARI_FULL_CLASS_MASK (0xffffff << PXCCARI_FULL_CLASS_OFFS)
74340+
74341+#define PXCCARI_PROGIF_OFFS 8 /* Prog .I/F*/
74342+#define PXCCARI_PROGIF_MASK (0xff << PXCCARI_PROGIF_OFFS)
74343+
74344+#define PXCCARI_SUB_CLASS_OFFS 16 /* Sub Class*/
74345+#define PXCCARI_SUB_CLASS_MASK (0xff << PXCCARI_SUB_CLASS_OFFS)
74346+
74347+#define PXCCARI_BASE_CLASS_OFFS 24 /* Base Class*/
74348+#define PXCCARI_BASE_CLASS_MASK (0xff << PXCCARI_BASE_CLASS_OFFS)
74349+
74350+
74351+/* PCI Express BIST, Header Type and Cache Line Size Register*/
74352+/*PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE (PXBHTLTCL)*/
74353+
74354+#define PXBHTLTCL_CACHELINE_OFFS 0 /* Specifies the cache line size */
74355+#define PXBHTLTCL_CACHELINE_MASK (0xff << PXBHTLTCL_CACHELINE_OFFS)
74356+
74357+#define PXBHTLTCL_HEADTYPE_FULL_OFFS 16 /* Full Header Type */
74358+#define PXBHTLTCL_HEADTYPE_FULL_MASK (0xff << PXBHTLTCL_HEADTYPE_FULL_OFFS)
74359+
74360+#define PXBHTLTCL_MULTI_FUNC BIT23 /* Multi/Single function */
74361+
74362+#define PXBHTLTCL_HEADER_OFFS 16 /* Header type */
74363+#define PXBHTLTCL_HEADER_MASK (0x7f << PXBHTLTCL_HEADER_OFFS)
74364+#define PXBHTLTCL_HEADER_STANDARD (0x0 << PXBHTLTCL_HEADER_OFFS)
74365+#define PXBHTLTCL_HEADER_PCI2PCI_BRIDGE (0x1 << PXBHTLTCL_HEADER_OFFS)
74366+
74367+
74368+#define PXBHTLTCL_BISTCOMP_OFFS 24 /* BIST Completion Code */
74369+#define PXBHTLTCL_BISTCOMP_MASK (0xf << PXBHTLTCL_BISTCOMP_OFFS)
74370+
74371+#define PXBHTLTCL_BISTACT BIT30 /* BIST Activate bit */
74372+#define PXBHTLTCL_BISTCAP BIT31 /* BIST Capable Bit */
74373+#define PXBHTLTCL_BISTCAP_OFFS 31
74374+#define PXBHTLTCL_BISTCAP_MASK BIT31
74375+#define PXBHTLTCL_BISTCAP_VAL 0
74376+
74377+
74378+/* PCI Express Subsystem Device and Vendor ID */
74379+/*PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID (PXSIASVI)*/
74380+
74381+#define PXSIASVI_VENID_OFFS 0 /* Subsystem Manufacturer Vendor ID Number */
74382+#define PXSIASVI_VENID_MASK (0xffff << PXSIASVI_VENID_OFFS)
74383+
74384+#define PXSIASVI_DEVID_OFFS 16 /* Subsystem Device ID Number */
74385+#define PXSIASVI_DEVID_MASK (0xffff << PXSIASVI_DEVID_OFFS)
74386+
74387+
74388+/* PCI Express Capability List Pointer Register*/
74389+/*PEX_CAPABILTY_LIST_POINTER (PXCLP)*/
74390+
74391+#define PXCLP_CAPPTR_OFFS 0 /* Capability List Pointer */
74392+#define PXCLP_CAPPTR_MASK (0xff << PXCLP_CAPPTR_OFFS)
74393+
74394+/* PCI Express Interrupt Pin and Line Register */
74395+/*PEX_INTERRUPT_PIN_AND_LINE (PXIPAL)*/
74396+
74397+#define PXIPAL_INTLINE_OFFS 0 /* Interrupt line (IRQ) */
74398+#define PXIPAL_INTLINE_MASK (0xff << PXIPAL_INTLINE_OFFS)
74399+
74400+#define PXIPAL_INTPIN_OFFS 8 /* interrupt pin (A,B,C,D) */
74401+#define PXIPAL_INTPIN_MASK (0xff << PXIPAL_INTPIN_OFFS)
74402+
74403+
74404+/* PCI Express Power Management Capability Header Register*/
74405+/*PEX_POWER_MNG_CAPABILITY (PXPMC)*/
74406+
74407+#define PXPMC_CAP_ID_OFFS 0 /* Capability ID */
74408+#define PXPMC_CAP_ID_MASK (0xff << PXPMC_CAP_ID_OFFS)
74409+
74410+#define PXPMC_NEXT_PTR_OFFS 8 /* Next Item Pointer */
74411+#define PXPMC_NEXT_PTR_MASK (0xff << PXPMC_NEXT_PTR_OFFS)
74412+
74413+#define PXPMC_PMC_VER_OFFS 16 /* PCI Power Management Capability Version*/
74414+#define PXPMC_PMC_VER_MASK (0x7 << PXPMC_PMC_VER_OFFS)
74415+
74416+#define PXPMC_DSI BIT21/* Device Specific Initialization */
74417+
74418+#define PXPMC_AUX_CUR_OFFS 22 /* Auxiliary Current Requirements */
74419+#define PXPMC_AUX_CUR_MASK (0x7 << PXPMC_AUX_CUR_OFFS)
74420+
74421+#define PXPMC_D1_SUP BIT25 /* D1 Power Management support*/
74422+
74423+#define PXPMC_D2_SUP BIT26 /* D2 Power Management support*/
74424+
74425+#define PXPMC_PME_SUP_OFFS 27 /* PM Event generation support*/
74426+#define PXPMC_PME_SUP_MASK (0x1f << PXPMC_PME_SUP_OFFS)
74427+
74428+/* PCI Express Power Management Control and Status Register*/
74429+/*PEX_POWER_MNG_STATUS_CONTROL (PXPMSC)*/
74430+
74431+#define PXPMSC_PM_STATE_OFFS 0 /* Power State */
74432+#define PXPMSC_PM_STATE_MASK (0x3 << PXPMSC_PM_STATE_OFFS)
74433+#define PXPMSC_PM_STATE_D0 (0x0 << PXPMSC_PM_STATE_OFFS)
74434+#define PXPMSC_PM_STATE_D1 (0x1 << PXPMSC_PM_STATE_OFFS)
74435+#define PXPMSC_PM_STATE_D2 (0x2 << PXPMSC_PM_STATE_OFFS)
74436+#define PXPMSC_PM_STATE_D3 (0x3 << PXPMSC_PM_STATE_OFFS)
74437+
74438+#define PXPMSC_PME_EN BIT8/* PM_PME Message Generation Enable */
74439+
74440+#define PXPMSC_PM_DATA_SEL_OFFS 9 /* Data Select*/
74441+#define PXPMSC_PM_DATA_SEL_MASK (0xf << PXPMSC_PM_DATA_SEL_OFFS)
74442+
74443+#define PXPMSC_PM_DATA_SCALE_OFFS 13 /* Data Scale */
74444+#define PXPMSC_PM_DATA_SCALE_MASK (0x3 << PXPMSC_PM_DATA_SCALE_OFFS)
74445+
74446+#define PXPMSC_PME_STAT BIT15/* PME Status */
74447+
74448+#define PXPMSC_PM_DATA_OFFS 24 /* State Data */
74449+#define PXPMSC_PM_DATA_MASK (0xff << PXPMSC_PM_DATA_OFFS)
74450+
74451+
74452+/* PCI Express MSI Message Control Register*/
74453+/*PEX_MSI_MESSAGE_CONTROL (PXMMC)*/
74454+
74455+#define PXMMC_CAP_ID_OFFS 0 /* Capability ID */
74456+#define PXMMC_CAP_ID_MASK (0xff << PXMMC_CAP_ID_OFFS)
74457+
74458+#define PXMMC_NEXT_PTR_OFFS 8 /* Next Item Pointer */
74459+#define PXMMC_NEXT_PTR_MASK (0xff << PXMMC_NEXT_PTR_OFFS)
74460+
74461+#define PXMMC_MSI_EN BIT18 /* MSI Enable */
74462+
74463+#define PXMMC_MULTI_CAP_OFFS 17 /* Multiple Message Capable */
74464+#define PXMMC_MULTI_CAP_MASK (0x7 << PXMMC_MULTI_CAP_OFFS)
74465+
74466+#define PXMMC_MULTI_EN_OFFS 20 /* Multiple Messages Enable */
74467+#define PXMMC_MULTI_EN_MASK (0x7 << PXMMC_MULTI_EN_OFFS)
74468+
74469+#define PXMMC_ADDR64 BIT23 /* 64-bit Addressing Capable */
74470+
74471+
74472+/* PCI Express MSI Message Address Register*/
74473+/*PEX_MSI_MESSAGE_ADDR (PXMMA)*/
74474+
74475+#define PXMMA_MSI_ADDR_OFFS 2 /* Message Address corresponds to
74476+ Address[31:2] of the MSI MWr TLP*/
74477+#define PXMMA_MSI_ADDR_MASK (0x3fffffff << PXMMA_MSI_ADDR_OFFS)
74478+
74479+
74480+/* PCI Express MSI Message Address (High) Register */
74481+/*PEX_MSI_MESSAGE_HIGH_ADDR (PXMMHA)*/
74482+
74483+#define PXMMA_MSI_ADDR_H_OFFS 0 /* Message Upper Address corresponds to
74484+ Address[63:32] of the MSI MWr TLP*/
74485+#define PXMMA_MSI_ADDR_H_MASK (0xffffffff << PXMMA_MSI_ADDR_H_OFFS )
74486+
74487+
74488+/* PCI Express MSI Message Data Register*/
74489+/*PEX_MSI_MESSAGE_DATA (PXMMD)*/
74490+
74491+#define PXMMD_MSI_DATA_OFFS 0 /* Message Data */
74492+#define PXMMD_MSI_DATA_MASK (0xffff << PXMMD_MSI_DATA_OFFS )
74493+
74494+
74495+/* PCI Express Capability Register*/
74496+/*PEX_CAPABILITY_REG (PXCR)*/
74497+
74498+#define PXCR_CAP_ID_OFFS 0 /* Capability ID*/
74499+#define PXCR_CAP_ID_MASK (0xff << PXCR_CAP_ID_OFFS)
74500+
74501+#define PXCR_NEXT_PTR_OFFS 8 /* Next Item Pointer*/
74502+#define PXCR_NEXT_PTR_MASK (0xff << PXCR_NEXT_PTR_OFFS)
74503+
74504+#define PXCR_CAP_VER_OFFS 16 /* Capability Version*/
74505+#define PXCR_CAP_VER_MASK (0xf << PXCR_CAP_VER_OFFS)
74506+
74507+#define PXCR_DEV_TYPE_OFFS 20 /* Device/Port Type*/
74508+#define PXCR_DEV_TYPE_MASK (0xf << PXCR_DEV_TYPE_OFFS)
74509+
74510+#define PXCR_SLOT_IMP BIT24 /* Slot Implemented*/
74511+
74512+#define PXCR_INT_MSG_NUM_OFFS 25 /* Interrupt Message Number*/
74513+#define PXCR_INT_MSG_NUM_MASK (0x1f << PXCR_INT_MSG_NUM_OFFS)
74514+
74515+
74516+/* PCI Express Device Capabilities Register */
74517+/*PEX_DEV_CAPABILITY_REG (PXDCR)*/
74518+
74519+#define PXDCR_MAX_PLD_SIZE_SUP_OFFS 0 /* Maximum Payload Size Supported*/
74520+#define PXDCR_MAX_PLD_SIZE_SUP_MASK (0x7 << PXDCR_MAX_PLD_SIZE_SUP_OFFS)
74521+
74522+#define PXDCR_EP_L0S_ACC_LAT_OFFS 6/* Endpoint L0s Acceptable Latency*/
74523+#define PXDCR_EP_L0S_ACC_LAT_MASK (0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)
74524+#define PXDCR_EP_L0S_ACC_LAT_64NS_LESS (0x0 << PXDCR_EP_L0S_ACC_LAT_OFFS)
74525+#define PXDCR_EP_L0S_ACC_LAT_64NS_128NS (0x1 << PXDCR_EP_L0S_ACC_LAT_OFFS)
74526+#define PXDCR_EP_L0S_ACC_LAT_128NS_256NS (0x2 << PXDCR_EP_L0S_ACC_LAT_OFFS)
74527+#define PXDCR_EP_L0S_ACC_LAT_256NS_512NS (0x3 << PXDCR_EP_L0S_ACC_LAT_OFFS)
74528+#define PXDCR_EP_L0S_ACC_LAT_512NS_1US (0x4 << PXDCR_EP_L0S_ACC_LAT_OFFS)
74529+#define PXDCR_EP_L0S_ACC_LAT_1US_2US (0x5 << PXDCR_EP_L0S_ACC_LAT_OFFS)
74530+#define PXDCR_EP_L0S_ACC_LAT_2US_4US (0x6 << PXDCR_EP_L0S_ACC_LAT_OFFS)
74531+#define PXDCR_EP_L0S_ACC_LAT_4US_MORE (0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)
74532+
74533+#define PXDCR_EP_L1_ACC_LAT_OFFS 9 /* Endpoint L1 Acceptable Latency*/
74534+#define PXDCR_EP_L1_ACC_LAT_MASK (0x7 << PXDCR_EP_L1_ACC_LAT_OFFS)
74535+#define PXDCR_EP_L1_ACC_LAT_64NS_LESS (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS)
74536+#define PXDCR_EP_L1_ACC_LAT_64NS_128NS (0x1 << PXDCR_EP_L1_ACC_LAT_OFFS)
74537+#define PXDCR_EP_L1_ACC_LAT_128NS_256NS (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS)
74538+#define PXDCR_EP_L1_ACC_LAT_256NS_512NS (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS)
74539+#define PXDCR_EP_L1_ACC_LAT_512NS_1US (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS)
74540+#define PXDCR_EP_L1_ACC_LAT_1US_2US (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS)
74541+#define PXDCR_EP_L1_ACC_LAT_2US_4US (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS)
74542+#define PXDCR_EP_L1_ACC_LAT_4US_MORE (0x7 << PXDCR_EP_L1_ACC_LAT_OFFS)
74543+
74544+
74545+#define PXDCR_ATT_BUT_PRS_OFFS 12 /* Attention Button Present*/
74546+#define PXDCR_ATT_BUT_PRS_MASK BIT12
74547+#define PXDCR_ATT_BUT_PRS_IMPLEMENTED BIT12
74548+
74549+#define PXDCR_ATT_IND_PRS_OFFS 13 /* Attention Indicator Present*/
74550+#define PXDCR_ATT_IND_PRS_MASK BIT13
74551+#define PXDCR_ATT_IND_PRS_IMPLEMENTED BIT13
74552+
74553+#define PXDCR_PWR_IND_PRS_OFFS 14/* Power Indicator Present*/
74554+#define PXDCR_PWR_IND_PRS_MASK BIT14
74555+#define PXDCR_PWR_IND_PRS_IMPLEMENTED BIT14
74556+
74557+#define PXDCR_CAP_SPL_VAL_OFFS 18 /*Captured Slot Power Limit
74558+ Value*/
74559+#define PXDCR_CAP_SPL_VAL_MASK (0xff << PXDCR_CAP_SPL_VAL_OFFS)
74560+
74561+#define PXDCR_CAP_SP_LSCL_OFFS 26 /* Captured Slot Power Limit
74562+ Scale */
74563+#define PXDCR_CAP_SP_LSCL_MASK (0x3 << PXDCR_CAP_SP_LSCL_OFFS)
74564+
74565+/* PCI Express Device Control Status Register */
74566+/*PEX_DEV_CTRL_STAT_REG (PXDCSR)*/
74567+
74568+#define PXDCSR_COR_ERR_REP_EN BIT0 /* Correctable Error Reporting Enable*/
74569+#define PXDCSR_NF_ERR_REP_EN BIT1 /* Non-Fatal Error Reporting Enable*/
74570+#define PXDCSR_F_ERR_REP_EN BIT2 /* Fatal Error Reporting Enable*/
74571+#define PXDCSR_UR_REP_EN BIT3 /* Unsupported Request (UR)
74572+ Reporting Enable*/
74573+#define PXDCSR_EN_RO BIT4 /* Enable Relaxed Ordering*/
74574+
74575+#define PXDCSR_MAX_PLD_SZ_OFFS 5 /* Maximum Payload Size*/
74576+#define PXDCSR_MAX_PLD_SZ_MASK (0x7 << PXDCSR_MAX_PLD_SZ_OFFS)
74577+#define PXDCSR_MAX_PLD_SZ_128B (0x0 << PXDCSR_MAX_PLD_SZ_OFFS)
74578+#define PXDCSR_EN_NS BIT11 /* Enable No Snoop*/
74579+
74580+#define PXDCSR_MAX_RD_RQ_SZ_OFFS 12 /* Maximum Read Request Size*/
74581+#define PXDCSR_MAX_RD_RQ_SZ_MASK (0x7 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
74582+#define PXDCSR_MAX_RD_RQ_SZ_128B (0x0 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
74583+#define PXDCSR_MAX_RD_RQ_SZ_256B (0x1 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
74584+#define PXDCSR_MAX_RD_RQ_SZ_512B (0x2 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
74585+#define PXDCSR_MAX_RD_RQ_SZ_1KB (0x3 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
74586+#define PXDCSR_MAX_RD_RQ_SZ_2KB (0x4 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
74587+#define PXDCSR_MAX_RD_RQ_SZ_4KB (0x5 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
74588+
74589+#define PXDCSR_COR_ERR_DET BIT16 /* Correctable Error Detected*/
74590+#define PXDCSR_NF_ERR_DET BIT17 /* Non-Fatal Error Detected.*/
74591+#define PXDCSR_F_ERR_DET BIT18 /* Fatal Error Detected.*/
74592+#define PXDCSR_UR_DET BIT19 /* Unsupported Request Detected */
74593+#define PXDCSR_AUX_PWR_DET BIT20 /* Reserved*/
74594+
74595+#define PXDCSR_TRANS_PEND_OFFS 21 /* Transactions Pending*/
74596+#define PXDCSR_TRANS_PEND_MASK BIT21
74597+#define PXDCSR_TRANS_PEND_NOT_COMPLETED (0x1 << PXDCSR_TRANS_PEND_OFFS)
74598+
74599+
74600+/* PCI Express Link Capabilities Register*/
74601+/*PEX_LINK_CAPABILITY_REG (PXLCR)*/
74602+
74603+#define PXLCR_MAX_LINK_SPD_OFFS 0 /* Maximum Link Speed*/
74604+#define PXLCR_MAX_LINK_SPD_MASK (0xf << PXLCR_MAX_LINK_SPD_OFFS)
74605+
74606+#define PXLCR_MAX_LNK_WDTH_OFFS 3 /* Maximum Link Width*/
74607+#define PXLCR_MAX_LNK_WDTH_MASK (0x3f << PXLCR_MAX_LNK_WDTH_OFFS)
74608+
74609+#define PXLCR_ASPM_SUP_OFFS 10 /* Active State Link PM Support*/
74610+#define PXLCR_ASPM_SUP_MASK (0x3 << PXLCR_ASPM_SUP_OFFS)
74611+
74612+#define PXLCR_L0S_EXT_LAT_OFFS 12 /* L0s Exit Latency*/
74613+#define PXLCR_L0S_EXT_LAT_MASK (0x7 << PXLCR_L0S_EXT_LAT_OFFS)
74614+#define PXLCR_L0S_EXT_LAT_64NS_LESS (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS)
74615+#define PXLCR_L0S_EXT_LAT_64NS_128NS (0x1 << PXDCR_EP_L1_ACC_LAT_OFFS)
74616+#define PXLCR_L0S_EXT_LAT_128NS_256NS (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS)
74617+#define PXLCR_L0S_EXT_LAT_256NS_512NS (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS)
74618+#define PXLCR_L0S_EXT_LAT_512NS_1US (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS)
74619+#define PXLCR_L0S_EXT_LAT_1US_2US (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS)
74620+#define PXLCR_L0S_EXT_LAT_2US_4US (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS)
74621+
74622+#define PXLCR_POR_TNUM_OFFS 24 /* Port Number */
74623+#define PXLCR_POR_TNUM_MASK (0xff << PXLCR_POR_TNUM_OFFS)
74624+
74625+/* PCI Express Link Control Status Register */
74626+/*PEX_LINK_CTRL_STAT_REG (PXLCSR)*/
74627+
74628+#define PXLCSR_ASPM_CNT_OFFS 0 /* Active State Link PM Control */
74629+#define PXLCSR_ASPM_CNT_MASK (0x3 << PXLCSR_ASPM_CNT_OFFS)
74630+#define PXLCSR_ASPM_CNT_DISABLED (0x0 << PXLCSR_ASPM_CNT_OFFS)
74631+#define PXLCSR_ASPM_CNT_L0S_ENT_SUPP (0x1 << PXLCSR_ASPM_CNT_OFFS)
74632+#define PXLCSR_ASPM_CNT_L1S_ENT_SUPP (0x2 << PXLCSR_ASPM_CNT_OFFS)
74633+#define PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP (0x3 << PXLCSR_ASPM_CNT_OFFS)
74634+
74635+#define PXLCSR_RCB_OFFS 3 /* Read Completion Boundary */
74636+#define PXLCSR_RCB_MASK BIT3
74637+#define PXLCSR_RCB_64B (0 << PXLCSR_RCB_OFFS)
74638+#define PXLCSR_RCB_128B (1 << PXLCSR_RCB_OFFS)
74639+
74640+#define PXLCSR_LNK_DIS BIT4 /* Link Disable */
74641+#define PXLCSR_RETRN_LNK BIT5 /* Retrain Link */
74642+#define PXLCSR_CMN_CLK_CFG BIT6 /* Common Clock Configuration */
74643+#define PXLCSR_EXTD_SNC BIT7 /* Extended Sync */
74644+
74645+#define PXLCSR_LNK_SPD_OFFS 16 /* Link Speed */
74646+#define PXLCSR_LNK_SPD_MASK (0xf << PXLCSR_LNK_SPD_OFFS)
74647+
74648+#define PXLCSR_NEG_LNK_WDTH_OFFS 20 /* Negotiated Link Width */
74649+#define PXLCSR_NEG_LNK_WDTH_MASK (0x3f << PXLCSR_NEG_LNK_WDTH_OFFS)
74650+#define PXLCSR_NEG_LNK_WDTH_X1 (0x1 << PXLCSR_NEG_LNK_WDTH_OFFS)
74651+
74652+#define PXLCSR_LNK_TRN BIT27 /* Link Training */
74653+
74654+#define PXLCSR_SLT_CLK_CFG_OFFS 28 /* Slot Clock Configuration */
74655+#define PXLCSR_SLT_CLK_CFG_MASK BIT28
74656+#define PXLCSR_SLT_CLK_CFG_INDPNT (0x0 << PXLCSR_SLT_CLK_CFG_OFFS)
74657+#define PXLCSR_SLT_CLK_CFG_REF (0x1 << PXLCSR_SLT_CLK_CFG_OFFS)
74658+
74659+/* PCI Express Advanced Error Report Header Register */
74660+/*PEX_ADV_ERR_RPRT_HDR_TRGT_REG (PXAERHTR)*/
74661+
74662+/* PCI Express Uncorrectable Error Status Register*/
74663+/*PEX_UNCORRECT_ERR_STAT_REG (PXUESR)*/
74664+
74665+/* PCI Express Uncorrectable Error Mask Register */
74666+/*PEX_UNCORRECT_ERR_MASK_REG (PXUEMR)*/
74667+
74668+/* PCI Express Uncorrectable Error Severity Register */
74669+/*PEX_UNCORRECT_ERR_SERVITY_REG (PXUESR)*/
74670+
74671+/* PCI Express Correctable Error Status Register */
74672+/*PEX_CORRECT_ERR_STAT_REG (PXCESR)*/
74673+
74674+/* PCI Express Correctable Error Mask Register */
74675+/*PEX_CORRECT_ERR_MASK_REG (PXCEMR)*/
74676+
74677+/* PCI Express Advanced Error Capability and Control Register*/
74678+/*PEX_ADV_ERR_CAPABILITY_CTRL_REG (PXAECCR)*/
74679+
74680+/* PCI Express Header Log First DWORD Register*/
74681+/*PEX_HDR_LOG_FIRST_DWORD_REG (PXHLFDR)*/
74682+
74683+/* PCI Express Header Log Second DWORD Register*/
74684+/*PEX_HDR_LOG_SECOND_DWORD_REG (PXHLSDR)*/
74685+
74686+/* PCI Express Header Log Third DWORD Register*/
74687+/*PEX_HDR_LOG_THIRD_DWORD_REG (PXHLTDR)*/
74688+
74689+/* PCI Express Header Log Fourth DWORD Register*/
74690+/*PEX_HDR_LOG_FOURTH_DWORD_REG (PXHLFDR)*/
74691+
74692+#ifdef __cplusplus
74693+}
74694+#endif /* __cplusplus */
74695+
74696+#endif /* #ifndef __INCPEXREGSH */
74697+
74698+
74699diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c b/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c
74700new file mode 100644
74701index 0000000..59d0383
74702--- /dev/null
74703+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c
74704@@ -0,0 +1,313 @@
74705+/*******************************************************************************
74706+Copyright (C) Marvell International Ltd. and its affiliates
74707+
74708+This software file (the "File") is owned and distributed by Marvell
74709+International Ltd. and/or its affiliates ("Marvell") under the following
74710+alternative licensing terms. Once you have made an election to distribute the
74711+File under one of the following license alternatives, please (i) delete this
74712+introductory statement regarding license alternatives, (ii) delete the two
74713+license alternatives that you have not elected to use and (iii) preserve the
74714+Marvell copyright notice above.
74715+
74716+********************************************************************************
74717+Marvell Commercial License Option
74718+
74719+If you received this File from Marvell and you have entered into a commercial
74720+license agreement (a "Commercial License") with Marvell, the File is licensed
74721+to you under the terms of the applicable Commercial License.
74722+
74723+********************************************************************************
74724+Marvell GPL License Option
74725+
74726+If you received this File from Marvell, you may opt to use, redistribute and/or
74727+modify this File in accordance with the terms and conditions of the General
74728+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
74729+available along with the File in the license.txt file or by writing to the Free
74730+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
74731+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
74732+
74733+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
74734+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
74735+DISCLAIMED. The GPL License provides additional details about this warranty
74736+disclaimer.
74737+********************************************************************************
74738+Marvell BSD License Option
74739+
74740+If you received this File from Marvell, you may opt to use, redistribute and/or
74741+modify this File under the following licensing terms.
74742+Redistribution and use in source and binary forms, with or without modification,
74743+are permitted provided that the following conditions are met:
74744+
74745+ * Redistributions of source code must retain the above copyright notice,
74746+ this list of conditions and the following disclaimer.
74747+
74748+ * Redistributions in binary form must reproduce the above copyright
74749+ notice, this list of conditions and the following disclaimer in the
74750+ documentation and/or other materials provided with the distribution.
74751+
74752+ * Neither the name of Marvell nor the names of its contributors may be
74753+ used to endorse or promote products derived from this software without
74754+ specific prior written permission.
74755+
74756+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
74757+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
74758+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74759+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
74760+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
74761+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
74762+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
74763+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74764+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74765+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74766+
74767+*******************************************************************************/
74768+
74769+#include "mvPex.h"
74770+
74771+//#define MV_DEBUG
74772+/* defines */
74773+#ifdef MV_DEBUG
74774+ #define DB(x) x
74775+#else
74776+ #define DB(x)
74777+#endif
74778+
74779+/* locals */
74780+typedef struct
74781+{
74782+ MV_U32 data;
74783+ MV_U32 mask;
74784+}PEX_HEADER_DATA;
74785+
74786+/* local function forwad decleration */
74787+MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
74788+ MV_U32 regOff);
74789+MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
74790+ MV_U32 func, MV_U32 regOff, MV_U32 data);
74791+void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev);
74792+
74793+
74794+PEX_HEADER_DATA configHdr[16] =
74795+{
74796+{0x888811ab, 0x00000000}, /*[device ID, vendor ID] */
74797+{0x00100007, 0x0000ffff}, /*[status register, command register] */
74798+{0x0604000e, 0x00000000}, /*[programming interface, sub class code, class code, revision ID] */
74799+{0x00010008, 0x00000000}, /*[BIST, header type, latency time, cache line] */
74800+{0x00000000, 0x00000000}, /*[base address 0] */
74801+{0x00000000, 0x00000000}, /*[base address 1] */
74802+{0x00000000, 0x00ffffff}, /*[secondary latency timersubordinate bus number, secondary bus number, primary bus number] */
74803+{0x0000f101, 0x00000000}, /*[secondary status ,IO limit, IO base] */
74804+{0x9ff0a000, 0x00000000}, /*[memory limit, memory base] */
74805+{0x0001fff1, 0x00000000}, /*[prefetch memory limit, prefetch memory base] */
74806+{0xffffffff, 0x00000000}, /*[prefetch memory base upper] */
74807+{0x00000000, 0x00000000}, /*[prefetch memory limit upper] */
74808+{0xeffff000, 0x00000000}, /*[IO limit upper 16 bits, IO base upper 16 bits] */
74809+{0x00000000, 0x00000000}, /*[reserved, capability pointer] */
74810+{0x00000000, 0x00000000}, /*[expansion ROM base address] */
74811+{0x00000000, 0x000000FF}, /*[bridge control, interrupt pin, interrupt line] */
74812+};
74813+
74814+
74815+#define HEADER_WRITE(data, offset) configHdr[offset/4].data = ((configHdr[offset/4].data & ~configHdr[offset/4].mask) | \
74816+ (data & configHdr[offset/4].mask))
74817+#define HEADER_READ(offset) configHdr[offset/4].data
74818+
74819+/*******************************************************************************
74820+* mvVrtBrgPexInit - Initialize PEX interfaces
74821+*
74822+* DESCRIPTION:
74823+*
74824+* This function is responsible of intialization of the Pex Interface , It
74825+* configure the Pex Bars and Windows in the following manner:
74826+*
74827+* Assumptions :
74828+* Bar0 is always internal registers bar
74829+* Bar1 is always the DRAM bar
74830+* Bar2 is always the Device bar
74831+*
74832+* 1) Sets the Internal registers bar base by obtaining the base from
74833+* the CPU Interface
74834+* 2) Sets the DRAM bar base and size by getting the base and size from
74835+* the CPU Interface when the size is the sum of all enabled DRAM
74836+* chip selects and the base is the base of CS0 .
74837+* 3) Sets the Device bar base and size by getting these values from the
74838+* CPU Interface when the base is the base of the lowest base of the
74839+* Device chip selects, and the
74840+*
74841+*
74842+* INPUT:
74843+*
74844+* pexIf - PEX interface number.
74845+*
74846+*
74847+* OUTPUT:
74848+* None.
74849+*
74850+* RETURN:
74851+* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
74852+*
74853+*******************************************************************************/
74854+MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf)
74855+{
74856+ /* reset PEX tree to recover previous U-boot/Boot configurations */
74857+ MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
74858+
74859+
74860+ resetPexConfig(pexIf, localBus, 1);
74861+ return MV_OK;
74862+}
74863+
74864+
74865+MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
74866+ MV_U32 regOff)
74867+{
74868+
74869+ MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
74870+ MV_U32 localDev = mvPexLocalDevNumGet(pexIf);
74871+ MV_U32 val;
74872+ if(bus == localBus)
74873+ {
74874+ if(dev > 1)
74875+ {
74876+/* on the local device allow only device #0 & #1 */
74877+ return 0xffffffff;
74878+ }
74879+ else
74880+ if (dev == localDev)
74881+ {
74882+ /* read the memory controller registers */
74883+ return mvPexHwConfigRead (pexIf, bus, dev, func, regOff);
74884+ }
74885+ else
74886+ {
74887+ /* access the virtual brg header */
74888+ return HEADER_READ(regOff);
74889+ }
74890+ }
74891+ else
74892+ if(bus == (localBus + 1))
74893+ {
74894+ /* access the device behind the virtual bridge */
74895+ if((dev == localDev) || (dev > 1))
74896+ {
74897+ return 0xffffffff;
74898+ }
74899+ else
74900+ {
74901+ /* access the device behind the virtual bridge, in this case
74902+ * change the bus number to the local bus number in order to
74903+ * generate type 0 config cycle
74904+ */
74905+ mvPexLocalBusNumSet(pexIf, bus);
74906+ mvPexLocalDevNumSet(pexIf, 1);
74907+ val = mvPexHwConfigRead (pexIf, bus, 0, func, regOff);
74908+ mvPexLocalBusNumSet(pexIf, localBus);
74909+ mvPexLocalDevNumSet(pexIf, localDev);
74910+ return val;
74911+ }
74912+ }
74913+ /* for all other devices use the HW function to get the
74914+ * requested registers
74915+ */
74916+ mvPexLocalDevNumSet(pexIf, 1);
74917+ val = mvPexHwConfigRead (pexIf, bus, dev, func, regOff);
74918+ mvPexLocalDevNumSet(pexIf, localDev);
74919+ return val;
74920+}
74921+
74922+
74923+MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
74924+ MV_U32 func, MV_U32 regOff, MV_U32 data)
74925+{
74926+ MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
74927+ MV_U32 localDev = mvPexLocalDevNumGet(pexIf);
74928+ MV_STATUS status;
74929+
74930+ if(bus == localBus)
74931+ {
74932+ if(dev > 1)
74933+ {
74934+ /* on the local device allow only device #0 & #1 */
74935+ return MV_ERROR;
74936+ }
74937+ else
74938+ if (dev == localDev)
74939+ {
74940+ /* read the memory controller registers */
74941+ return mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);
74942+ }
74943+ else
74944+ {
74945+ /* access the virtual brg header */
74946+ HEADER_WRITE(data, regOff);
74947+ return MV_OK;
74948+ }
74949+ }
74950+ else
74951+ if(bus == (localBus + 1))
74952+ {
74953+ /* access the device behind the virtual bridge */
74954+ if((dev == localDev) || (dev > 1))
74955+ {
74956+ return MV_ERROR;
74957+ }
74958+ else
74959+ {
74960+ /* access the device behind the virtual bridge, in this case
74961+ * change the bus number to the local bus number in order to
74962+ * generate type 0 config cycle
74963+ */
74964+ //return mvPexHwConfigWrite (pexIf, localBus, dev, func, regOff, data);
74965+ mvPexLocalBusNumSet(pexIf, bus);
74966+ mvPexLocalDevNumSet(pexIf, 1);
74967+ status = mvPexHwConfigWrite (pexIf, bus, 0, func, regOff, data);
74968+ mvPexLocalBusNumSet(pexIf, localBus);
74969+ mvPexLocalDevNumSet(pexIf, localDev);
74970+ return status;
74971+
74972+ }
74973+ }
74974+ /* for all other devices use the HW function to get the
74975+ * requested registers
74976+ */
74977+ mvPexLocalDevNumSet(pexIf, 1);
74978+ status = mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);
74979+ mvPexLocalDevNumSet(pexIf, localDev);
74980+ return status;
74981+}
74982+
74983+
74984+
74985+
74986+void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev)
74987+{
74988+ MV_U32 tData;
74989+ MV_U32 i;
74990+
74991+ /* restore the PEX configuration to initialization state */
74992+ /* in case PEX P2P call recursive and reset config */
74993+ tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x0);
74994+ if(tData != 0xffffffff)
74995+ {
74996+ /* agent had been found - check whether P2P */
74997+ tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x8);
74998+ if((tData & 0xffff0000) == 0x06040000)
74999+ {/* P2P */
75000+ /* get the sec bus and the subordinate */
75001+ MV_U32 secBus;
75002+ tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x18);
75003+ secBus = ((tData >> 8) & 0xff);
75004+ /* now scan on sec bus */
75005+ for(i = 0;i < 0xff;i++)
75006+ {
75007+ resetPexConfig(pexIf, secBus, i);
75008+ }
75009+ /* now reset this device */
75010+ DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));
75011+ mvPexHwConfigWrite(pexIf, bus, dev, 0x0, 0x18, 0x0);
75012+ DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));
75013+ }
75014+ }
75015+}
75016+
75017+
75018diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h b/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h
75019new file mode 100644
75020index 0000000..0741713
75021--- /dev/null
75022+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h
75023@@ -0,0 +1,82 @@
75024+/*******************************************************************************
75025+Copyright (C) Marvell International Ltd. and its affiliates
75026+
75027+This software file (the "File") is owned and distributed by Marvell
75028+International Ltd. and/or its affiliates ("Marvell") under the following
75029+alternative licensing terms. Once you have made an election to distribute the
75030+File under one of the following license alternatives, please (i) delete this
75031+introductory statement regarding license alternatives, (ii) delete the two
75032+license alternatives that you have not elected to use and (iii) preserve the
75033+Marvell copyright notice above.
75034+
75035+********************************************************************************
75036+Marvell Commercial License Option
75037+
75038+If you received this File from Marvell and you have entered into a commercial
75039+license agreement (a "Commercial License") with Marvell, the File is licensed
75040+to you under the terms of the applicable Commercial License.
75041+
75042+********************************************************************************
75043+Marvell GPL License Option
75044+
75045+If you received this File from Marvell, you may opt to use, redistribute and/or
75046+modify this File in accordance with the terms and conditions of the General
75047+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
75048+available along with the File in the license.txt file or by writing to the Free
75049+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
75050+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
75051+
75052+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
75053+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
75054+DISCLAIMED. The GPL License provides additional details about this warranty
75055+disclaimer.
75056+********************************************************************************
75057+Marvell BSD License Option
75058+
75059+If you received this File from Marvell, you may opt to use, redistribute and/or
75060+modify this File under the following licensing terms.
75061+Redistribution and use in source and binary forms, with or without modification,
75062+are permitted provided that the following conditions are met:
75063+
75064+ * Redistributions of source code must retain the above copyright notice,
75065+ this list of conditions and the following disclaimer.
75066+
75067+ * Redistributions in binary form must reproduce the above copyright
75068+ notice, this list of conditions and the following disclaimer in the
75069+ documentation and/or other materials provided with the distribution.
75070+
75071+ * Neither the name of Marvell nor the names of its contributors may be
75072+ used to endorse or promote products derived from this software without
75073+ specific prior written permission.
75074+
75075+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
75076+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75077+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75078+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
75079+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75080+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75081+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
75082+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75083+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75084+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75085+
75086+*******************************************************************************/
75087+
75088+#ifndef __INCVRTBRGPEXH
75089+#define __INCVRTBRGPEXH
75090+
75091+
75092+/* Global Functions prototypes */
75093+/* mvPexInit - Initialize PEX interfaces*/
75094+MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf);
75095+
75096+/* mvPexConfigRead - Read from configuration space */
75097+MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
75098+ MV_U32 func,MV_U32 regOff);
75099+
75100+/* mvPexConfigWrite - Write to configuration space */
75101+MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
75102+ MV_U32 func, MV_U32 regOff, MV_U32 data);
75103+
75104+
75105+#endif /* #ifndef __INCPEXH */
75106diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c b/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c
75107new file mode 100644
75108index 0000000..2643699
75109--- /dev/null
75110+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c
75111@@ -0,0 +1,1522 @@
75112+/*******************************************************************************
75113+Copyright (C) Marvell International Ltd. and its affiliates
75114+
75115+This software file (the "File") is owned and distributed by Marvell
75116+International Ltd. and/or its affiliates ("Marvell") under the following
75117+alternative licensing terms. Once you have made an election to distribute the
75118+File under one of the following license alternatives, please (i) delete this
75119+introductory statement regarding license alternatives, (ii) delete the two
75120+license alternatives that you have not elected to use and (iii) preserve the
75121+Marvell copyright notice above.
75122+
75123+********************************************************************************
75124+Marvell Commercial License Option
75125+
75126+If you received this File from Marvell and you have entered into a commercial
75127+license agreement (a "Commercial License") with Marvell, the File is licensed
75128+to you under the terms of the applicable Commercial License.
75129+
75130+********************************************************************************
75131+Marvell GPL License Option
75132+
75133+If you received this File from Marvell, you may opt to use, redistribute and/or
75134+modify this File in accordance with the terms and conditions of the General
75135+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
75136+available along with the File in the license.txt file or by writing to the Free
75137+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
75138+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
75139+
75140+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
75141+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
75142+DISCLAIMED. The GPL License provides additional details about this warranty
75143+disclaimer.
75144+********************************************************************************
75145+Marvell BSD License Option
75146+
75147+If you received this File from Marvell, you may opt to use, redistribute and/or
75148+modify this File under the following licensing terms.
75149+Redistribution and use in source and binary forms, with or without modification,
75150+are permitted provided that the following conditions are met:
75151+
75152+ * Redistributions of source code must retain the above copyright notice,
75153+ this list of conditions and the following disclaimer.
75154+
75155+ * Redistributions in binary form must reproduce the above copyright
75156+ notice, this list of conditions and the following disclaimer in the
75157+ documentation and/or other materials provided with the distribution.
75158+
75159+ * Neither the name of Marvell nor the names of its contributors may be
75160+ used to endorse or promote products derived from this software without
75161+ specific prior written permission.
75162+
75163+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
75164+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75165+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75166+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
75167+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75168+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75169+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
75170+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75171+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75172+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75173+
75174+*******************************************************************************/
75175+#include "mvOs.h"
75176+#include "sflash/mvSFlash.h"
75177+#include "sflash/mvSFlashSpec.h"
75178+#include "spi/mvSpi.h"
75179+#include "spi/mvSpiCmnd.h"
75180+#include "ctrlEnv/mvCtrlEnvLib.h"
75181+
75182+/*#define MV_DEBUG*/
75183+#ifdef MV_DEBUG
75184+#define DB(x) x
75185+#else
75186+#define DB(x)
75187+#endif
75188+
75189+/* Globals */
75190+static MV_SFLASH_DEVICE_PARAMS sflash[] = {
75191+ /* ST M25P32 SPI flash, 4MB, 64 sectors of 64K each */
75192+ {
75193+ MV_M25P_WREN_CMND_OPCD,
75194+ MV_M25P_WRDI_CMND_OPCD,
75195+ MV_M25P_RDID_CMND_OPCD,
75196+ MV_M25P_RDSR_CMND_OPCD,
75197+ MV_M25P_WRSR_CMND_OPCD,
75198+ MV_M25P_READ_CMND_OPCD,
75199+ MV_M25P_FAST_RD_CMND_OPCD,
75200+ MV_M25P_PP_CMND_OPCD,
75201+ MV_M25P_SE_CMND_OPCD,
75202+ MV_M25P_BE_CMND_OPCD,
75203+ MV_M25P_RES_CMND_OPCD,
75204+ MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
75205+ MV_M25P32_SECTOR_SIZE,
75206+ MV_M25P32_SECTOR_NUMBER,
75207+ MV_M25P_PAGE_SIZE,
75208+ "ST M25P32",
75209+ MV_M25PXXX_ST_MANF_ID,
75210+ MV_M25P32_DEVICE_ID,
75211+ MV_M25P32_MAX_SPI_FREQ,
75212+ MV_M25P32_MAX_FAST_SPI_FREQ,
75213+ MV_M25P32_FAST_READ_DUMMY_BYTES
75214+ },
75215+ /* ST M25P64 SPI flash, 8MB, 128 sectors of 64K each */
75216+ {
75217+ MV_M25P_WREN_CMND_OPCD,
75218+ MV_M25P_WRDI_CMND_OPCD,
75219+ MV_M25P_RDID_CMND_OPCD,
75220+ MV_M25P_RDSR_CMND_OPCD,
75221+ MV_M25P_WRSR_CMND_OPCD,
75222+ MV_M25P_READ_CMND_OPCD,
75223+ MV_M25P_FAST_RD_CMND_OPCD,
75224+ MV_M25P_PP_CMND_OPCD,
75225+ MV_M25P_SE_CMND_OPCD,
75226+ MV_M25P_BE_CMND_OPCD,
75227+ MV_M25P_RES_CMND_OPCD,
75228+ MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
75229+ MV_M25P64_SECTOR_SIZE,
75230+ MV_M25P64_SECTOR_NUMBER,
75231+ MV_M25P_PAGE_SIZE,
75232+ "ST M25P64",
75233+ MV_M25PXXX_ST_MANF_ID,
75234+ MV_M25P64_DEVICE_ID,
75235+ MV_M25P64_MAX_SPI_FREQ,
75236+ MV_M25P64_MAX_FAST_SPI_FREQ,
75237+ MV_M25P64_FAST_READ_DUMMY_BYTES
75238+ },
75239+ /* ST M25P128 SPI flash, 16MB, 64 sectors of 256K each */
75240+ {
75241+ MV_M25P_WREN_CMND_OPCD,
75242+ MV_M25P_WRDI_CMND_OPCD,
75243+ MV_M25P_RDID_CMND_OPCD,
75244+ MV_M25P_RDSR_CMND_OPCD,
75245+ MV_M25P_WRSR_CMND_OPCD,
75246+ MV_M25P_READ_CMND_OPCD,
75247+ MV_M25P_FAST_RD_CMND_OPCD,
75248+ MV_M25P_PP_CMND_OPCD,
75249+ MV_M25P_SE_CMND_OPCD,
75250+ MV_M25P_BE_CMND_OPCD,
75251+ MV_M25P_RES_CMND_OPCD,
75252+ MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
75253+ MV_M25P128_SECTOR_SIZE,
75254+ MV_M25P128_SECTOR_NUMBER,
75255+ MV_M25P_PAGE_SIZE,
75256+ "ST M25P128",
75257+ MV_M25PXXX_ST_MANF_ID,
75258+ MV_M25P128_DEVICE_ID,
75259+ MV_M25P128_MAX_SPI_FREQ,
75260+ MV_M25P128_MAX_FAST_SPI_FREQ,
75261+ MV_M25P128_FAST_READ_DUMMY_BYTES
75262+ },
75263+ /* Macronix MXIC MX25L6405 SPI flash, 8MB, 128 sectors of 64K each */
75264+ {
75265+ MV_MX25L_WREN_CMND_OPCD,
75266+ MV_MX25L_WRDI_CMND_OPCD,
75267+ MV_MX25L_RDID_CMND_OPCD,
75268+ MV_MX25L_RDSR_CMND_OPCD,
75269+ MV_MX25L_WRSR_CMND_OPCD,
75270+ MV_MX25L_READ_CMND_OPCD,
75271+ MV_MX25L_FAST_RD_CMND_OPCD,
75272+ MV_MX25L_PP_CMND_OPCD,
75273+ MV_MX25L_SE_CMND_OPCD,
75274+ MV_MX25L_BE_CMND_OPCD,
75275+ MV_MX25L_RES_CMND_OPCD,
75276+ MV_MX25L_DP_CMND_OPCD,
75277+ MV_MX25L6405_SECTOR_SIZE,
75278+ MV_MX25L6405_SECTOR_NUMBER,
75279+ MV_MXIC_PAGE_SIZE,
75280+ "MXIC MX25L6405",
75281+ MV_MXIC_MANF_ID,
75282+ MV_MX25L6405_DEVICE_ID,
75283+ MV_MX25L6405_MAX_SPI_FREQ,
75284+ MV_MX25L6405_MAX_FAST_SPI_FREQ,
75285+ MV_MX25L6405_FAST_READ_DUMMY_BYTES
75286+ },
75287+ /* SPANSION S25FL128P SPI flash, 16MB, 64 sectors of 256K each */
75288+ {
75289+ MV_S25FL_WREN_CMND_OPCD,
75290+ MV_S25FL_WRDI_CMND_OPCD,
75291+ MV_S25FL_RDID_CMND_OPCD,
75292+ MV_S25FL_RDSR_CMND_OPCD,
75293+ MV_S25FL_WRSR_CMND_OPCD,
75294+ MV_S25FL_READ_CMND_OPCD,
75295+ MV_S25FL_FAST_RD_CMND_OPCD,
75296+ MV_S25FL_PP_CMND_OPCD,
75297+ MV_S25FL_SE_CMND_OPCD,
75298+ MV_S25FL_BE_CMND_OPCD,
75299+ MV_S25FL_RES_CMND_OPCD,
75300+ MV_S25FL_DP_CMND_OPCD,
75301+ MV_S25FL128_SECTOR_SIZE,
75302+ MV_S25FL128_SECTOR_NUMBER,
75303+ MV_S25FL_PAGE_SIZE,
75304+ "SPANSION S25FL128",
75305+ MV_SPANSION_MANF_ID,
75306+ MV_S25FL128_DEVICE_ID,
75307+ MV_S25FL128_MAX_SPI_FREQ,
75308+ MV_M25P128_MAX_FAST_SPI_FREQ,
75309+ MV_M25P128_FAST_READ_DUMMY_BYTES
75310+ }
75311+};
75312+
75313+/* Static Functions */
75314+static MV_STATUS mvWriteEnable (MV_SFLASH_INFO * pFlinfo);
75315+static MV_STATUS mvStatusRegGet (MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg);
75316+static MV_STATUS mvStatusRegSet (MV_SFLASH_INFO * pFlinfo, MV_U8 sr);
75317+static MV_STATUS mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo);
75318+static MV_STATUS mvSFlashPageWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset, \
75319+ MV_U8* pPageBuff, MV_U32 buffSize);
75320+static MV_STATUS mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, \
75321+ MV_U8* manId, MV_U16* devId);
75322+
75323+/*******************************************************************************
75324+* mvWriteEnable - serialize the write enable sequence
75325+*
75326+* DESCRIPTION:
75327+* transmit the sequence for write enable
75328+*
75329+********************************************************************************/
75330+static MV_STATUS mvWriteEnable(MV_SFLASH_INFO * pFlinfo)
75331+{
75332+ MV_U8 cmd[MV_SFLASH_WREN_CMND_LENGTH];
75333+
75334+
75335+ cmd[0] = sflash[pFlinfo->index].opcdWREN;
75336+
75337+ return mvSpiWriteThenRead(cmd, MV_SFLASH_WREN_CMND_LENGTH, NULL, 0, 0);
75338+}
75339+
75340+/*******************************************************************************
75341+* mvStatusRegGet - Retrieve the value of the status register
75342+*
75343+* DESCRIPTION:
75344+* perform the RDSR sequence to get the 8bit status register
75345+*
75346+********************************************************************************/
75347+static MV_STATUS mvStatusRegGet(MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg)
75348+{
75349+ MV_STATUS ret;
75350+ MV_U8 cmd[MV_SFLASH_RDSR_CMND_LENGTH];
75351+ MV_U8 sr[MV_SFLASH_RDSR_REPLY_LENGTH];
75352+
75353+
75354+
75355+
75356+ cmd[0] = sflash[pFlinfo->index].opcdRDSR;
75357+
75358+ if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDSR_CMND_LENGTH, sr,
75359+ MV_SFLASH_RDSR_REPLY_LENGTH,0)) != MV_OK)
75360+ return ret;
75361+
75362+ *pStatReg = sr[0];
75363+
75364+ return MV_OK;
75365+}
75366+
75367+/*******************************************************************************
75368+* mvWaitOnWipClear - Block waiting for the WIP (write in progress) to be cleared
75369+*
75370+* DESCRIPTION:
75371+* Block waiting for the WIP (write in progress) to be cleared
75372+*
75373+********************************************************************************/
75374+static MV_STATUS mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo)
75375+{
75376+ MV_STATUS ret;
75377+ MV_U32 i;
75378+ MV_U8 stat;
75379+
75380+ for (i=0; i<MV_SFLASH_MAX_WAIT_LOOP; i++)
75381+ {
75382+ if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)
75383+ return ret;
75384+
75385+ if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)
75386+ return MV_OK;
75387+ }
75388+
75389+ DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)
75390+ return MV_TIMEOUT;
75391+}
75392+
75393+/*******************************************************************************
75394+* mvWaitOnChipEraseDone - Block waiting for the WIP (write in progress) to be
75395+* cleared after a chip erase command which is supposed
75396+* to take about 2:30 minutes
75397+*
75398+* DESCRIPTION:
75399+* Block waiting for the WIP (write in progress) to be cleared
75400+*
75401+********************************************************************************/
75402+static MV_STATUS mvWaitOnChipEraseDone(MV_SFLASH_INFO * pFlinfo)
75403+{
75404+ MV_STATUS ret;
75405+ MV_U32 i;
75406+ MV_U8 stat;
75407+
75408+ for (i=0; i<MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP; i++)
75409+ {
75410+ if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)
75411+ return ret;
75412+
75413+ if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)
75414+ return MV_OK;
75415+ }
75416+
75417+ DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)
75418+ return MV_TIMEOUT;
75419+}
75420+
75421+/*******************************************************************************
75422+* mvStatusRegSet - Set the value of the 8bit status register
75423+*
75424+* DESCRIPTION:
75425+* Set the value of the 8bit status register
75426+*
75427+********************************************************************************/
75428+static MV_STATUS mvStatusRegSet(MV_SFLASH_INFO * pFlinfo, MV_U8 sr)
75429+{
75430+ MV_STATUS ret;
75431+ MV_U8 cmd[MV_SFLASH_WRSR_CMND_LENGTH];
75432+
75433+
75434+ /* Issue the Write enable command prior the WRSR command */
75435+ if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
75436+ return ret;
75437+
75438+ /* Write the SR with the new values */
75439+ cmd[0] = sflash[pFlinfo->index].opcdWRSR;
75440+ cmd[1] = sr;
75441+
75442+ if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_WRSR_CMND_LENGTH, NULL, 0, 0)) != MV_OK)
75443+ return ret;
75444+
75445+ if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
75446+ return ret;
75447+
75448+ mvOsDelay(1);
75449+
75450+ return MV_OK;
75451+}
75452+
75453+/*******************************************************************************
75454+* mvSFlashPageWr - Write up to 256 Bytes in the same page
75455+*
75456+* DESCRIPTION:
75457+* Write a buffer up to the page size in length provided that the whole address
75458+* range is within the same page (alligned to page bounderies)
75459+*
75460+*******************************************************************************/
75461+static MV_STATUS mvSFlashPageWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
75462+ MV_U8* pPageBuff, MV_U32 buffSize)
75463+{
75464+ MV_STATUS ret;
75465+ MV_U8 cmd[MV_SFLASH_PP_CMND_LENGTH];
75466+
75467+
75468+ /* Protection - check if the model was detected */
75469+ if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
75470+ {
75471+ DB(mvOsPrintf("%s WARNING: Invalid parameter device index!\n", __FUNCTION__);)
75472+ return MV_BAD_PARAM;
75473+ }
75474+
75475+ /* check that we do not cross the page bounderies */
75476+ if (((offset & (sflash[pFlinfo->index].pageSize - 1)) + buffSize) >
75477+ sflash[pFlinfo->index].pageSize)
75478+ {
75479+ DB(mvOsPrintf("%s WARNING: Page allignment problem!\n", __FUNCTION__);)
75480+ return MV_OUT_OF_RANGE;
75481+ }
75482+
75483+ /* Issue the Write enable command prior the page program command */
75484+ if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
75485+ return ret;
75486+
75487+ cmd[0] = sflash[pFlinfo->index].opcdPP;
75488+ cmd[1] = ((offset >> 16) & 0xFF);
75489+ cmd[2] = ((offset >> 8) & 0xFF);
75490+ cmd[3] = (offset & 0xFF);
75491+
75492+ if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_PP_CMND_LENGTH, pPageBuff, buffSize)) != MV_OK)
75493+ return ret;
75494+
75495+ if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
75496+ return ret;
75497+
75498+ return MV_OK;
75499+}
75500+
75501+/*******************************************************************************
75502+* mvSFlashWithDefaultsIdGet - Try to read the manufacturer and Device IDs from
75503+* the device using the default RDID opcode and the default WREN opcode.
75504+*
75505+* DESCRIPTION:
75506+* This is used to detect a generic device that uses the default opcodes
75507+* for the WREN and RDID.
75508+*
75509+********************************************************************************/
75510+static MV_STATUS mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* manId, MV_U16* devId)
75511+{
75512+ MV_STATUS ret;
75513+ MV_U8 cmdRDID[MV_SFLASH_RDID_CMND_LENGTH];
75514+ MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];
75515+
75516+
75517+
75518+ /* Use the default RDID opcode to read the IDs */
75519+ cmdRDID[0] = MV_SFLASH_DEFAULT_RDID_OPCD; /* unknown model try default */
75520+ if ((ret = mvSpiWriteThenRead(cmdRDID, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)
75521+ return ret;
75522+
75523+ *manId = id[0];
75524+ *devId = 0;
75525+ *devId |= (id[1] << 8);
75526+ *devId |= id[2];
75527+
75528+ return MV_OK;
75529+}
75530+
75531+/*
75532+#####################################################################################
75533+#####################################################################################
75534+*/
75535+
75536+/*******************************************************************************
75537+* mvSFlashInit - Initialize the serial flash device
75538+*
75539+* DESCRIPTION:
75540+* Perform the neccessary initialization and configuration
75541+*
75542+* INPUT:
75543+* pFlinfo: pointer to the Flash information structure
75544+* pFlinfo->baseAddr: base address in fast mode.
75545+* pFlinfo->index: Index of the flash in the sflash tabel. If the SPI
75546+* flash device does not support read Id command with
75547+* the standard opcode, then the user should supply this
75548+* as an input to skip the autodetection process!!!!
75549+*
75550+* OUTPUT:
75551+* pFlinfo: pointer to the Flash information structure after detection
75552+* pFlinfo->manufacturerId: Manufacturer ID
75553+* pFlinfo->deviceId: Device ID
75554+* pFlinfo->sectorSize: size of the sector (all sectors are the same).
75555+* pFlinfo->sectorNumber: number of sectors.
75556+* pFlinfo->pageSize: size of the page.
75557+* pFlinfo->index: Index of the detected flash in the sflash tabel
75558+*
75559+* RETURN:
75560+* Success or Error code.
75561+*
75562+*
75563+*******************************************************************************/
75564+MV_STATUS mvSFlashInit (MV_SFLASH_INFO * pFlinfo)
75565+{
75566+ MV_STATUS ret;
75567+ MV_U8 manf;
75568+ MV_U16 dev;
75569+ MV_U32 indx;
75570+ MV_BOOL detectFlag = MV_FALSE;
75571+
75572+ /* check for NULL pointer */
75573+ if (pFlinfo == NULL)
75574+ {
75575+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
75576+ return MV_BAD_PARAM;
75577+ }
75578+
75579+ /* Initialize the SPI interface with low frequency to make sure that the read ID succeeds */
75580+ if ((ret = mvSpiInit(MV_SFLASH_BASIC_SPI_FREQ)) != MV_OK)
75581+ {
75582+ mvOsPrintf("%s ERROR: Failed to initialize the SPI interface!\n", __FUNCTION__);
75583+ return ret;
75584+ }
75585+
75586+ /* First try to read the Manufacturer and Device IDs */
75587+ if ((ret = mvSFlashIdGet(pFlinfo, &manf, &dev)) != MV_OK)
75588+ {
75589+ mvOsPrintf("%s ERROR: Failed to get the SFlash ID!\n", __FUNCTION__);
75590+ return ret;
75591+ }
75592+
75593+ /* loop over the whole table and look for the appropriate SFLASH */
75594+ for (indx=0; indx<MV_ARRAY_SIZE(sflash); indx++)
75595+ {
75596+ if ((manf == sflash[indx].manufacturerId) && (dev == sflash[indx].deviceId))
75597+ {
75598+ pFlinfo->manufacturerId = manf;
75599+ pFlinfo->deviceId = dev;
75600+ pFlinfo->index = indx;
75601+ detectFlag = MV_TRUE;
75602+ }
75603+ }
75604+
75605+ if(!detectFlag)
75606+ {
75607+ mvOsPrintf("%s ERROR: Unknown SPI flash device!\n", __FUNCTION__);
75608+ return MV_FAIL;
75609+ }
75610+
75611+ /* fill the info based on the model detected */
75612+ pFlinfo->sectorSize = sflash[pFlinfo->index].sectorSize;
75613+ pFlinfo->sectorNumber = sflash[pFlinfo->index].sectorNumber;
75614+ pFlinfo->pageSize = sflash[pFlinfo->index].pageSize;
75615+
75616+ /* Set the SPI frequency to the MAX allowed for the device for best performance */
75617+ if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)
75618+ {
75619+ mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);
75620+ return ret;
75621+ }
75622+
75623+ /* As default lock the SR */
75624+ if ((ret = mvSFlashStatRegLock(pFlinfo, MV_TRUE)) != MV_OK)
75625+ return ret;
75626+
75627+ return MV_OK;
75628+}
75629+
75630+/*******************************************************************************
75631+* mvSFlashSectorErase - Erasse a single sector of the serial flash
75632+*
75633+* DESCRIPTION:
75634+* Issue the erase sector command and address
75635+*
75636+* INPUT:
75637+* pFlinfo: pointer to the Flash information structure
75638+* secNumber: sector Number to erase (0 -> (sectorNumber-1))
75639+*
75640+* OUTPUT:
75641+* None
75642+*
75643+* RETURN:
75644+* Success or Error code.
75645+*
75646+*
75647+*******************************************************************************/
75648+MV_STATUS mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber)
75649+{
75650+ MV_STATUS ret;
75651+ MV_U8 cmd[MV_SFLASH_SE_CMND_LENGTH];
75652+
75653+ MV_U32 secAddr = (secNumber * pFlinfo->sectorSize);
75654+#if 0
75655+ MV_U32 i;
75656+ MV_U32 * pW = (MV_U32*) (secAddr + pFlinfo->baseAddr);
75657+ MV_U32 erasedWord = 0xFFFFFFFF;
75658+ MV_U32 wordsPerSector = (pFlinfo->sectorSize / sizeof(MV_U32));
75659+ MV_BOOL eraseNeeded = MV_FALSE;
75660+#endif
75661+ /* check for NULL pointer */
75662+ if (pFlinfo == NULL)
75663+ {
75664+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
75665+ return MV_BAD_PARAM;
75666+ }
75667+
75668+ /* Protection - check if the model was detected */
75669+ if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
75670+ {
75671+ DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
75672+ return MV_BAD_PARAM;
75673+ }
75674+
75675+ /* check that the sector number is valid */
75676+ if (secNumber >= pFlinfo->sectorNumber)
75677+ {
75678+ DB(mvOsPrintf("%s WARNING: Invaild parameter sector number!\n", __FUNCTION__);)
75679+ return MV_BAD_PARAM;
75680+ }
75681+
75682+ /* we don't want to access SPI in direct mode from in-direct API,
75683+ becasue of timing issue between CS asserts. */
75684+#if 0
75685+ /* First compare to FF and check if erase is needed */
75686+ for (i=0; i<wordsPerSector; i++)
75687+ {
75688+ if (memcmp(pW, &erasedWord, sizeof(MV_U32)) != 0)
75689+ {
75690+ eraseNeeded = MV_TRUE;
75691+ break;
75692+ }
75693+
75694+ ++pW;
75695+ }
75696+ if (!eraseNeeded)
75697+ return MV_OK;
75698+#endif
75699+
75700+ cmd[0] = sflash[pFlinfo->index].opcdSE;
75701+ cmd[1] = ((secAddr >> 16) & 0xFF);
75702+ cmd[2] = ((secAddr >> 8) & 0xFF);
75703+ cmd[3] = (secAddr & 0xFF);
75704+
75705+ /* Issue the Write enable command prior the sector erase command */
75706+ if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
75707+ return ret;
75708+
75709+ if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_SE_CMND_LENGTH, NULL, 0)) != MV_OK)
75710+ return ret;
75711+
75712+ if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
75713+ return ret;
75714+
75715+ return MV_OK;
75716+}
75717+
75718+/*******************************************************************************
75719+* mvSFlashChipErase - Erasse the whole serial flash
75720+*
75721+* DESCRIPTION:
75722+* Issue the bulk (chip) erase command
75723+*
75724+* INPUT:
75725+* pFlinfo: pointer to the Flash information structure
75726+*
75727+* OUTPUT:
75728+* None
75729+*
75730+* RETURN:
75731+* Success or Error code.
75732+*
75733+*
75734+*******************************************************************************/
75735+MV_STATUS mvSFlashChipErase (MV_SFLASH_INFO * pFlinfo)
75736+{
75737+ MV_STATUS ret;
75738+ MV_U8 cmd[MV_SFLASH_BE_CMND_LENGTH];
75739+
75740+
75741+ /* check for NULL pointer */
75742+ if (pFlinfo == NULL)
75743+ {
75744+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
75745+ return MV_BAD_PARAM;
75746+ }
75747+
75748+ /* Protection - check if the model was detected */
75749+ if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
75750+ {
75751+ DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
75752+ return MV_BAD_PARAM;
75753+ }
75754+
75755+ cmd[0] = sflash[pFlinfo->index].opcdBE;
75756+
75757+ /* Issue the Write enable command prior the Bulk erase command */
75758+ if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
75759+ return ret;
75760+
75761+ if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_BE_CMND_LENGTH, NULL, 0)) != MV_OK)
75762+ return ret;
75763+
75764+ if ((ret = mvWaitOnChipEraseDone(pFlinfo)) != MV_OK)
75765+ return ret;
75766+
75767+ return MV_OK;
75768+}
75769+
75770+/*******************************************************************************
75771+* mvSFlashBlockRd - Read from the serial flash
75772+*
75773+* DESCRIPTION:
75774+* Issue the read command and address then perfom the needed read
75775+*
75776+* INPUT:
75777+* pFlinfo: pointer to the Flash information structure
75778+* offset: byte offset with the flash to start reading from
75779+* pReadBuff: pointer to the buffer to read the data in
75780+* buffSize: size of the buffer to read.
75781+*
75782+* OUTPUT:
75783+* pReadBuff: pointer to the buffer containing the read data
75784+*
75785+* RETURN:
75786+* Success or Error code.
75787+*
75788+*
75789+*******************************************************************************/
75790+MV_STATUS mvSFlashBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
75791+ MV_U8* pReadBuff, MV_U32 buffSize)
75792+{
75793+ MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];
75794+
75795+
75796+ /* check for NULL pointer */
75797+ if ((pFlinfo == NULL) || (pReadBuff == NULL))
75798+ {
75799+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
75800+ return MV_BAD_PARAM;
75801+ }
75802+
75803+ /* Protection - check if the model was detected */
75804+ if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
75805+ {
75806+ DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
75807+ return MV_BAD_PARAM;
75808+ }
75809+
75810+ cmd[0] = sflash[pFlinfo->index].opcdREAD;
75811+ cmd[1] = ((offset >> 16) & 0xFF);
75812+ cmd[2] = ((offset >> 8) & 0xFF);
75813+ cmd[3] = (offset & 0xFF);
75814+
75815+ return mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize, 0);
75816+}
75817+
75818+/*******************************************************************************
75819+* mvSFlashFastBlockRd - Fast read from the serial flash
75820+*
75821+* DESCRIPTION:
75822+* Issue the fast read command and address then perfom the needed read
75823+*
75824+* INPUT:
75825+* pFlinfo: pointer to the Flash information structure
75826+* offset: byte offset with the flash to start reading from
75827+* pReadBuff: pointer to the buffer to read the data in
75828+* buffSize: size of the buffer to read.
75829+*
75830+* OUTPUT:
75831+* pReadBuff: pointer to the buffer containing the read data
75832+*
75833+* RETURN:
75834+* Success or Error code.
75835+*
75836+*
75837+*******************************************************************************/
75838+MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
75839+ MV_U8* pReadBuff, MV_U32 buffSize)
75840+{
75841+ MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];
75842+ MV_STATUS ret;
75843+
75844+ /* check for NULL pointer */
75845+ if ((pFlinfo == NULL) || (pReadBuff == NULL))
75846+ {
75847+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
75848+ return MV_BAD_PARAM;
75849+ }
75850+
75851+ /* Protection - check if the model was detected */
75852+ if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
75853+ {
75854+ DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
75855+ return MV_BAD_PARAM;
75856+ }
75857+
75858+ /* Set the SPI frequency to the MAX allowed for fast-read operations */
75859+ mvOsPrintf("Setting freq to %d.\n",sflash[pFlinfo->index].spiMaxFastFreq);
75860+ if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFastFreq)) != MV_OK)
75861+ {
75862+ mvOsPrintf("%s ERROR: Failed to set the SPI fast frequency!\n", __FUNCTION__);
75863+ return ret;
75864+ }
75865+
75866+ cmd[0] = sflash[pFlinfo->index].opcdFSTRD;
75867+ cmd[1] = ((offset >> 16) & 0xFF);
75868+ cmd[2] = ((offset >> 8) & 0xFF);
75869+ cmd[3] = (offset & 0xFF);
75870+
75871+
75872+ ret = mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize,
75873+ sflash[pFlinfo->index].spiFastRdDummyBytes);
75874+
75875+ /* Reset the SPI frequency to the MAX allowed for the device for best performance */
75876+ if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)
75877+ {
75878+ mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);
75879+ return ret;
75880+ }
75881+
75882+ return ret;
75883+}
75884+
75885+
75886+/*******************************************************************************
75887+* mvSFlashBlockWr - Write a buffer with any size
75888+*
75889+* DESCRIPTION:
75890+* write regardless of the page boundaries and size limit per Page
75891+* program command
75892+*
75893+* INPUT:
75894+* pFlinfo: pointer to the Flash information structure
75895+* offset: byte offset within the flash region
75896+* pWriteBuff: pointer to the buffer holding the data to program
75897+* buffSize: size of the buffer to write
75898+*
75899+* OUTPUT:
75900+* None
75901+*
75902+* RETURN:
75903+* Success or Error code.
75904+*
75905+*
75906+*******************************************************************************/
75907+MV_STATUS mvSFlashBlockWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
75908+ MV_U8* pWriteBuff, MV_U32 buffSize)
75909+{
75910+ MV_STATUS ret;
75911+ MV_U32 data2write = buffSize;
75912+ MV_U32 preAllOffset = (offset & MV_SFLASH_PAGE_ALLIGN_MASK(MV_M25P_PAGE_SIZE));
75913+ MV_U32 preAllSz = (preAllOffset ? (MV_M25P_PAGE_SIZE - preAllOffset) : 0);
75914+ MV_U32 writeOffset = offset;
75915+
75916+ /* check for NULL pointer */
75917+#ifndef CONFIG_MARVELL
75918+ if(NULL == pWriteBuff)
75919+ {
75920+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
75921+ return MV_BAD_PARAM;
75922+ }
75923+#endif
75924+
75925+ if (pFlinfo == NULL)
75926+ {
75927+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
75928+ return MV_BAD_PARAM;
75929+ }
75930+
75931+ /* Protection - check if the model was detected */
75932+ if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
75933+ {
75934+ DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
75935+ return MV_BAD_PARAM;
75936+ }
75937+
75938+ /* check that the buffer size does not exceed the flash size */
75939+ if ((offset + buffSize) > mvSFlashSizeGet(pFlinfo))
75940+ {
75941+ DB(mvOsPrintf("%s WARNING: Write exceeds flash size!\n", __FUNCTION__);)
75942+ return MV_OUT_OF_RANGE;
75943+ }
75944+
75945+ /* check if the total block size is less than the first chunk remainder */
75946+ if (data2write < preAllSz)
75947+ preAllSz = data2write;
75948+
75949+ /* check if programing does not start at a 64byte alligned offset */
75950+ if (preAllSz)
75951+ {
75952+ if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, preAllSz)) != MV_OK)
75953+ return ret;
75954+
75955+ /* increment pointers and counters */
75956+ writeOffset += preAllSz;
75957+ data2write -= preAllSz;
75958+ pWriteBuff += preAllSz;
75959+ }
75960+
75961+ /* program the data that fits in complete page chunks */
75962+ while (data2write >= sflash[pFlinfo->index].pageSize)
75963+ {
75964+ if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, sflash[pFlinfo->index].pageSize)) != MV_OK)
75965+ return ret;
75966+
75967+ /* increment pointers and counters */
75968+ writeOffset += sflash[pFlinfo->index].pageSize;
75969+ data2write -= sflash[pFlinfo->index].pageSize;
75970+ pWriteBuff += sflash[pFlinfo->index].pageSize;
75971+ }
75972+
75973+ /* program the last partial chunk */
75974+ if (data2write)
75975+ {
75976+ if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, data2write)) != MV_OK)
75977+ return ret;
75978+ }
75979+
75980+ return MV_OK;
75981+}
75982+
75983+/*******************************************************************************
75984+* mvSFlashIdGet - Get the manufacturer and device IDs.
75985+*
75986+* DESCRIPTION:
75987+* Get the Manufacturer and device IDs from the serial flash through
75988+* writing the RDID command then reading 3 bytes of data. In case that
75989+* this command was called for the first time in order to detect the
75990+* manufacturer and device IDs, then the default RDID opcode will be used
75991+* unless the device index is indicated by the user (in case the SPI flash
75992+* does not use the default RDID opcode).
75993+*
75994+* INPUT:
75995+* pFlinfo: pointer to the Flash information structure
75996+* pManId: pointer to the 8bit variable to hold the manufacturing ID
75997+* pDevId: pointer to the 16bit variable to hold the device ID
75998+*
75999+* OUTPUT:
76000+* pManId: pointer to the 8bit variable holding the manufacturing ID
76001+* pDevId: pointer to the 16bit variable holding the device ID
76002+*
76003+* RETURN:
76004+* Success or Error code.
76005+*
76006+*
76007+*******************************************************************************/
76008+MV_STATUS mvSFlashIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId)
76009+{
76010+ MV_STATUS ret;
76011+ MV_U8 cmd[MV_SFLASH_RDID_CMND_LENGTH];
76012+ MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];
76013+
76014+
76015+
76016+ /* check for NULL pointer */
76017+ if ((pFlinfo == NULL) || (pManId == NULL) || (pDevId == NULL))
76018+ {
76019+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
76020+ return MV_BAD_PARAM;
76021+ }
76022+
76023+ if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
76024+ return mvSFlashWithDefaultsIdGet(pFlinfo, pManId, pDevId);
76025+ else
76026+ cmd[0] = sflash[pFlinfo->index].opcdRDID;
76027+
76028+ if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)
76029+ return ret;
76030+
76031+ *pManId = id[0];
76032+ *pDevId = 0;
76033+ *pDevId |= (id[1] << 8);
76034+ *pDevId |= id[2];
76035+
76036+ return MV_OK;
76037+}
76038+
76039+/*******************************************************************************
76040+* mvSFlashWpRegionSet - Set the Write-Protected region
76041+*
76042+* DESCRIPTION:
76043+* Set the Write-Protected region
76044+*
76045+* INPUT:
76046+* pFlinfo: pointer to the Flash information structure
76047+* wpRegion: which region will be protected
76048+*
76049+* OUTPUT:
76050+* None
76051+*
76052+* RETURN:
76053+* Success or Error code.
76054+*
76055+*
76056+*******************************************************************************/
76057+MV_STATUS mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion)
76058+{
76059+ MV_U8 wpMask;
76060+
76061+ /* check for NULL pointer */
76062+ if (pFlinfo == NULL)
76063+ {
76064+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
76065+ return MV_BAD_PARAM;
76066+ }
76067+
76068+ /* Protection - check if the model was detected */
76069+ if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
76070+ {
76071+ DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
76072+ return MV_BAD_PARAM;
76073+ }
76074+
76075+ /* Check if the chip is an ST flash; then WP supports only 3 bits */
76076+ if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)
76077+ {
76078+ switch (wpRegion)
76079+ {
76080+ case MV_WP_NONE:
76081+ wpMask = MV_M25P_STATUS_BP_NONE;
76082+ break;
76083+
76084+ case MV_WP_UPR_1OF128:
76085+ DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)
76086+ return MV_NOT_SUPPORTED;
76087+
76088+ case MV_WP_UPR_1OF64:
76089+ wpMask = MV_M25P_STATUS_BP_1_OF_64;
76090+ break;
76091+
76092+ case MV_WP_UPR_1OF32:
76093+ wpMask = MV_M25P_STATUS_BP_1_OF_32;
76094+ break;
76095+
76096+ case MV_WP_UPR_1OF16:
76097+ wpMask = MV_M25P_STATUS_BP_1_OF_16;
76098+ break;
76099+
76100+ case MV_WP_UPR_1OF8:
76101+ wpMask = MV_M25P_STATUS_BP_1_OF_8;
76102+ break;
76103+
76104+ case MV_WP_UPR_1OF4:
76105+ wpMask = MV_M25P_STATUS_BP_1_OF_4;
76106+ break;
76107+
76108+ case MV_WP_UPR_1OF2:
76109+ wpMask = MV_M25P_STATUS_BP_1_OF_2;
76110+ break;
76111+
76112+ case MV_WP_ALL:
76113+ wpMask = MV_M25P_STATUS_BP_ALL;
76114+ break;
76115+
76116+ default:
76117+ DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
76118+ return MV_BAD_PARAM;
76119+ }
76120+ }
76121+ /* check if the manufacturer is MXIC then the WP is 4bits */
76122+ else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)
76123+ {
76124+ switch (wpRegion)
76125+ {
76126+ case MV_WP_NONE:
76127+ wpMask = MV_MX25L_STATUS_BP_NONE;
76128+ break;
76129+
76130+ case MV_WP_UPR_1OF128:
76131+ wpMask = MV_MX25L_STATUS_BP_1_OF_128;
76132+ break;
76133+
76134+ case MV_WP_UPR_1OF64:
76135+ wpMask = MV_MX25L_STATUS_BP_1_OF_64;
76136+ break;
76137+
76138+ case MV_WP_UPR_1OF32:
76139+ wpMask = MV_MX25L_STATUS_BP_1_OF_32;
76140+ break;
76141+
76142+ case MV_WP_UPR_1OF16:
76143+ wpMask = MV_MX25L_STATUS_BP_1_OF_16;
76144+ break;
76145+
76146+ case MV_WP_UPR_1OF8:
76147+ wpMask = MV_MX25L_STATUS_BP_1_OF_8;
76148+ break;
76149+
76150+ case MV_WP_UPR_1OF4:
76151+ wpMask = MV_MX25L_STATUS_BP_1_OF_4;
76152+ break;
76153+
76154+ case MV_WP_UPR_1OF2:
76155+ wpMask = MV_MX25L_STATUS_BP_1_OF_2;
76156+ break;
76157+
76158+ case MV_WP_ALL:
76159+ wpMask = MV_MX25L_STATUS_BP_ALL;
76160+ break;
76161+
76162+ default:
76163+ DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
76164+ return MV_BAD_PARAM;
76165+ }
76166+ }
76167+ /* check if the manufacturer is SPANSION then the WP is 4bits */
76168+ else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)
76169+ {
76170+ switch (wpRegion)
76171+ {
76172+ case MV_WP_NONE:
76173+ wpMask = MV_S25FL_STATUS_BP_NONE;
76174+ break;
76175+
76176+ case MV_WP_UPR_1OF128:
76177+ DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)
76178+ return MV_NOT_SUPPORTED;
76179+
76180+ case MV_WP_UPR_1OF64:
76181+ wpMask = MV_S25FL_STATUS_BP_1_OF_64;
76182+ break;
76183+
76184+ case MV_WP_UPR_1OF32:
76185+ wpMask = MV_S25FL_STATUS_BP_1_OF_32;
76186+ break;
76187+
76188+ case MV_WP_UPR_1OF16:
76189+ wpMask = MV_S25FL_STATUS_BP_1_OF_16;
76190+ break;
76191+
76192+ case MV_WP_UPR_1OF8:
76193+ wpMask = MV_S25FL_STATUS_BP_1_OF_8;
76194+ break;
76195+
76196+ case MV_WP_UPR_1OF4:
76197+ wpMask = MV_S25FL_STATUS_BP_1_OF_4;
76198+ break;
76199+
76200+ case MV_WP_UPR_1OF2:
76201+ wpMask = MV_S25FL_STATUS_BP_1_OF_2;
76202+ break;
76203+
76204+ case MV_WP_ALL:
76205+ wpMask = MV_S25FL_STATUS_BP_ALL;
76206+ break;
76207+
76208+
76209+ default:
76210+ DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
76211+ return MV_BAD_PARAM;
76212+ }
76213+ }
76214+ else
76215+ {
76216+ DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)
76217+ return MV_BAD_PARAM;
76218+ }
76219+
76220+ /* Verify that the SRWD bit is always set - register is s/w locked */
76221+ wpMask |= MV_SFLASH_STATUS_REG_SRWD_MASK;
76222+
76223+ return mvStatusRegSet(pFlinfo, wpMask);
76224+}
76225+
76226+/*******************************************************************************
76227+* mvSFlashWpRegionGet - Get the Write-Protected region configured
76228+*
76229+* DESCRIPTION:
76230+* Get from the chip the Write-Protected region configured
76231+*
76232+* INPUT:
76233+* pFlinfo: pointer to the Flash information structure
76234+* pWpRegion: pointer to the variable to return the WP region in
76235+*
76236+* OUTPUT:
76237+* wpRegion: pointer to the variable holding the WP region configured
76238+*
76239+* RETURN:
76240+* Success or Error code.
76241+*
76242+*
76243+*******************************************************************************/
76244+MV_STATUS mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion)
76245+{
76246+ MV_STATUS ret;
76247+ MV_U8 reg;
76248+
76249+ /* check for NULL pointer */
76250+ if ((pFlinfo == NULL) || (pWpRegion == NULL))
76251+ {
76252+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
76253+ return MV_BAD_PARAM;
76254+ }
76255+
76256+ /* Protection - check if the model was detected */
76257+ if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
76258+ {
76259+ DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
76260+ return MV_BAD_PARAM;
76261+ }
76262+
76263+ if ((ret = mvStatusRegGet(pFlinfo, &reg)) != MV_OK)
76264+ return ret;
76265+
76266+ /* Check if the chip is an ST flash; then WP supports only 3 bits */
76267+ if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)
76268+ {
76269+ switch ((reg & MV_M25P_STATUS_REG_WP_MASK))
76270+ {
76271+ case MV_M25P_STATUS_BP_NONE:
76272+ *pWpRegion = MV_WP_NONE;
76273+ break;
76274+
76275+ case MV_M25P_STATUS_BP_1_OF_64:
76276+ *pWpRegion = MV_WP_UPR_1OF64;
76277+ break;
76278+
76279+ case MV_M25P_STATUS_BP_1_OF_32:
76280+ *pWpRegion = MV_WP_UPR_1OF32;
76281+ break;
76282+
76283+ case MV_M25P_STATUS_BP_1_OF_16:
76284+ *pWpRegion = MV_WP_UPR_1OF16;
76285+ break;
76286+
76287+ case MV_M25P_STATUS_BP_1_OF_8:
76288+ *pWpRegion = MV_WP_UPR_1OF8;
76289+ break;
76290+
76291+ case MV_M25P_STATUS_BP_1_OF_4:
76292+ *pWpRegion = MV_WP_UPR_1OF4;
76293+ break;
76294+
76295+ case MV_M25P_STATUS_BP_1_OF_2:
76296+ *pWpRegion = MV_WP_UPR_1OF2;
76297+ break;
76298+
76299+ case MV_M25P_STATUS_BP_ALL:
76300+ *pWpRegion = MV_WP_ALL;
76301+ break;
76302+
76303+ default:
76304+ DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
76305+ return MV_BAD_VALUE;
76306+ }
76307+ }
76308+ /* check if the manufacturer is MXIC then the WP is 4bits */
76309+ else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)
76310+ {
76311+ switch ((reg & MV_MX25L_STATUS_REG_WP_MASK))
76312+ {
76313+ case MV_MX25L_STATUS_BP_NONE:
76314+ *pWpRegion = MV_WP_NONE;
76315+ break;
76316+
76317+ case MV_MX25L_STATUS_BP_1_OF_128:
76318+ *pWpRegion = MV_WP_UPR_1OF128;
76319+ break;
76320+
76321+ case MV_MX25L_STATUS_BP_1_OF_64:
76322+ *pWpRegion = MV_WP_UPR_1OF64;
76323+ break;
76324+
76325+ case MV_MX25L_STATUS_BP_1_OF_32:
76326+ *pWpRegion = MV_WP_UPR_1OF32;
76327+ break;
76328+
76329+ case MV_MX25L_STATUS_BP_1_OF_16:
76330+ *pWpRegion = MV_WP_UPR_1OF16;
76331+ break;
76332+
76333+ case MV_MX25L_STATUS_BP_1_OF_8:
76334+ *pWpRegion = MV_WP_UPR_1OF8;
76335+ break;
76336+
76337+ case MV_MX25L_STATUS_BP_1_OF_4:
76338+ *pWpRegion = MV_WP_UPR_1OF4;
76339+ break;
76340+
76341+ case MV_MX25L_STATUS_BP_1_OF_2:
76342+ *pWpRegion = MV_WP_UPR_1OF2;
76343+ break;
76344+
76345+ case MV_MX25L_STATUS_BP_ALL:
76346+ *pWpRegion = MV_WP_ALL;
76347+ break;
76348+
76349+ default:
76350+ DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
76351+ return MV_BAD_VALUE;
76352+ }
76353+ }
76354+ /* Check if the chip is an SPANSION flash; then WP supports only 3 bits */
76355+ else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)
76356+ {
76357+ switch ((reg & MV_S25FL_STATUS_REG_WP_MASK))
76358+ {
76359+ case MV_S25FL_STATUS_BP_NONE:
76360+ *pWpRegion = MV_WP_NONE;
76361+ break;
76362+
76363+ case MV_S25FL_STATUS_BP_1_OF_64:
76364+ *pWpRegion = MV_WP_UPR_1OF64;
76365+ break;
76366+
76367+ case MV_S25FL_STATUS_BP_1_OF_32:
76368+ *pWpRegion = MV_WP_UPR_1OF32;
76369+ break;
76370+
76371+ case MV_S25FL_STATUS_BP_1_OF_16:
76372+ *pWpRegion = MV_WP_UPR_1OF16;
76373+ break;
76374+
76375+ case MV_S25FL_STATUS_BP_1_OF_8:
76376+ *pWpRegion = MV_WP_UPR_1OF8;
76377+ break;
76378+
76379+ case MV_S25FL_STATUS_BP_1_OF_4:
76380+ *pWpRegion = MV_WP_UPR_1OF4;
76381+ break;
76382+
76383+ case MV_S25FL_STATUS_BP_1_OF_2:
76384+ *pWpRegion = MV_WP_UPR_1OF2;
76385+ break;
76386+
76387+ case MV_S25FL_STATUS_BP_ALL:
76388+ *pWpRegion = MV_WP_ALL;
76389+ break;
76390+
76391+ default:
76392+ DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
76393+ return MV_BAD_VALUE;
76394+ }
76395+ }
76396+ else
76397+ {
76398+ DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)
76399+ return MV_BAD_PARAM;
76400+ }
76401+
76402+ return MV_OK;
76403+}
76404+
76405+/*******************************************************************************
76406+* mvSFlashStatRegLock - Lock the status register for writing - W/Vpp
76407+* pin should be low to take effect
76408+*
76409+* DESCRIPTION:
76410+* Lock the access to the Status Register for writing. This will
76411+* cause the flash to enter the hardware protection mode if the W/Vpp
76412+* is low. If the W/Vpp is hi, the chip will be in soft protection mode, but
76413+* the register will continue to be writable if WREN sequence was used.
76414+*
76415+* INPUT:
76416+* pFlinfo: pointer to the Flash information structure
76417+* srLock: enable/disable (MV_TRUE/MV_FALSE) status registor lock mechanism
76418+*
76419+* OUTPUT:
76420+* None
76421+*
76422+* RETURN:
76423+* Success or Error code.
76424+*
76425+*
76426+*******************************************************************************/
76427+MV_STATUS mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock)
76428+{
76429+ MV_STATUS ret;
76430+ MV_U8 reg;
76431+
76432+ /* check for NULL pointer */
76433+ if (pFlinfo == NULL)
76434+ {
76435+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
76436+ return MV_BAD_PARAM;
76437+ }
76438+
76439+ /* Protection - check if the model was detected */
76440+ if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
76441+ {
76442+ DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
76443+ return MV_BAD_PARAM;
76444+ }
76445+
76446+ if ((ret = mvStatusRegGet(pFlinfo, &reg)) != MV_OK)
76447+ return ret;
76448+
76449+ if (srLock)
76450+ reg |= MV_SFLASH_STATUS_REG_SRWD_MASK;
76451+ else
76452+ reg &= ~MV_SFLASH_STATUS_REG_SRWD_MASK;
76453+
76454+ return mvStatusRegSet(pFlinfo, reg);
76455+}
76456+
76457+/*******************************************************************************
76458+* mvSFlashSizeGet - Get the size of the SPI flash
76459+*
76460+* DESCRIPTION:
76461+* based on the sector number and size of each sector calculate the total
76462+* size of the flash memory.
76463+*
76464+* INPUT:
76465+* pFlinfo: pointer to the Flash information structure
76466+*
76467+* OUTPUT:
76468+* None.
76469+*
76470+* RETURN:
76471+* Size of the flash in bytes.
76472+*
76473+*
76474+*******************************************************************************/
76475+MV_U32 mvSFlashSizeGet (MV_SFLASH_INFO * pFlinfo)
76476+{
76477+ /* check for NULL pointer */
76478+ if (pFlinfo == NULL)
76479+ {
76480+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
76481+ return 0;
76482+ }
76483+
76484+ return (pFlinfo->sectorSize * pFlinfo->sectorNumber);
76485+}
76486+
76487+/*******************************************************************************
76488+* mvSFlashPowerSaveEnter - Cause the falsh device to go into power save mode
76489+*
76490+* DESCRIPTION:
76491+* Enter a special power save mode.
76492+*
76493+* INPUT:
76494+* pFlinfo: pointer to the Flash information structure
76495+*
76496+* OUTPUT:
76497+* None.
76498+*
76499+* RETURN:
76500+* Size of the flash in bytes.
76501+*
76502+*
76503+*******************************************************************************/
76504+MV_STATUS mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo)
76505+{
76506+ MV_STATUS ret;
76507+ MV_U8 cmd[MV_SFLASH_DP_CMND_LENGTH];
76508+
76509+
76510+ /* check for NULL pointer */
76511+ if (pFlinfo == NULL)
76512+ {
76513+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
76514+ return 0;
76515+ }
76516+
76517+ /* Protection - check if the model was detected */
76518+ if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
76519+ {
76520+ DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
76521+ return MV_BAD_PARAM;
76522+ }
76523+
76524+ /* check that power save mode is supported in the specific device */
76525+ if (sflash[pFlinfo->index].opcdPwrSave == MV_SFLASH_NO_SPECIFIC_OPCD)
76526+ {
76527+ DB(mvOsPrintf("%s WARNING: Power save not supported for this device!\n", __FUNCTION__);)
76528+ return MV_NOT_SUPPORTED;
76529+ }
76530+
76531+ cmd[0] = sflash[pFlinfo->index].opcdPwrSave;
76532+
76533+ if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_DP_CMND_LENGTH, NULL, 0)) != MV_OK)
76534+ return ret;
76535+
76536+ return MV_OK;
76537+
76538+}
76539+
76540+/*******************************************************************************
76541+* mvSFlashPowerSaveExit - Cause the falsh device to exit the power save mode
76542+*
76543+* DESCRIPTION:
76544+* Exit the deep power save mode.
76545+*
76546+* INPUT:
76547+* pFlinfo: pointer to the Flash information structure
76548+*
76549+* OUTPUT:
76550+* None.
76551+*
76552+* RETURN:
76553+* Size of the flash in bytes.
76554+*
76555+*
76556+*******************************************************************************/
76557+MV_STATUS mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo)
76558+{
76559+ MV_STATUS ret;
76560+ MV_U8 cmd[MV_SFLASH_RES_CMND_LENGTH];
76561+
76562+
76563+ /* check for NULL pointer */
76564+ if (pFlinfo == NULL)
76565+ {
76566+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
76567+ return 0;
76568+ }
76569+
76570+ /* Protection - check if the model was detected */
76571+ if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
76572+ {
76573+ DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
76574+ return MV_BAD_PARAM;
76575+ }
76576+
76577+ /* check that power save mode is supported in the specific device */
76578+ if (sflash[pFlinfo->index].opcdRES == MV_SFLASH_NO_SPECIFIC_OPCD)
76579+ {
76580+ DB(mvOsPrintf("%s WARNING: Read Electronic Signature not supported for this device!\n", __FUNCTION__);)
76581+ return MV_NOT_SUPPORTED;
76582+ }
76583+
76584+ cmd[0] = sflash[pFlinfo->index].opcdRES;
76585+
76586+ if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_RES_CMND_LENGTH, NULL, 0)) != MV_OK)
76587+ return ret;
76588+
76589+ /* add the delay needed for the device to wake up */
76590+ mvOsDelay(MV_MXIC_DP_EXIT_DELAY); /* 30 ms */
76591+
76592+ return MV_OK;
76593+
76594+}
76595+
76596+/*******************************************************************************
76597+* mvSFlashModelGet - Retreive the string with the device manufacturer and model
76598+*
76599+* DESCRIPTION:
76600+* Retreive the string with the device manufacturer and model
76601+*
76602+* INPUT:
76603+* pFlinfo: pointer to the Flash information structure
76604+*
76605+* OUTPUT:
76606+* None.
76607+*
76608+* RETURN:
76609+* pointer to the string indicating the device manufacturer and model
76610+*
76611+*
76612+*******************************************************************************/
76613+const MV_8 * mvSFlashModelGet (MV_SFLASH_INFO * pFlinfo)
76614+{
76615+ static const MV_8 * unknModel = (const MV_8 *)"Unknown";
76616+
76617+ /* check for NULL pointer */
76618+ if (pFlinfo == NULL)
76619+ {
76620+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
76621+ return 0;
76622+ }
76623+
76624+ /* Protection - check if the model was detected */
76625+ if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
76626+ {
76627+ DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
76628+ return unknModel;
76629+ }
76630+
76631+ return sflash[pFlinfo->index].deviceModel;
76632+}
76633+
76634diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h b/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h
76635new file mode 100644
76636index 0000000..5bb160b
76637--- /dev/null
76638+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h
76639@@ -0,0 +1,166 @@
76640+/*******************************************************************************
76641+Copyright (C) Marvell International Ltd. and its affiliates
76642+
76643+This software file (the "File") is owned and distributed by Marvell
76644+International Ltd. and/or its affiliates ("Marvell") under the following
76645+alternative licensing terms. Once you have made an election to distribute the
76646+File under one of the following license alternatives, please (i) delete this
76647+introductory statement regarding license alternatives, (ii) delete the two
76648+license alternatives that you have not elected to use and (iii) preserve the
76649+Marvell copyright notice above.
76650+
76651+********************************************************************************
76652+Marvell Commercial License Option
76653+
76654+If you received this File from Marvell and you have entered into a commercial
76655+license agreement (a "Commercial License") with Marvell, the File is licensed
76656+to you under the terms of the applicable Commercial License.
76657+
76658+********************************************************************************
76659+Marvell GPL License Option
76660+
76661+If you received this File from Marvell, you may opt to use, redistribute and/or
76662+modify this File in accordance with the terms and conditions of the General
76663+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
76664+available along with the File in the license.txt file or by writing to the Free
76665+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
76666+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
76667+
76668+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
76669+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
76670+DISCLAIMED. The GPL License provides additional details about this warranty
76671+disclaimer.
76672+********************************************************************************
76673+Marvell BSD License Option
76674+
76675+If you received this File from Marvell, you may opt to use, redistribute and/or
76676+modify this File under the following licensing terms.
76677+Redistribution and use in source and binary forms, with or without modification,
76678+are permitted provided that the following conditions are met:
76679+
76680+ * Redistributions of source code must retain the above copyright notice,
76681+ this list of conditions and the following disclaimer.
76682+
76683+ * Redistributions in binary form must reproduce the above copyright
76684+ notice, this list of conditions and the following disclaimer in the
76685+ documentation and/or other materials provided with the distribution.
76686+
76687+ * Neither the name of Marvell nor the names of its contributors may be
76688+ used to endorse or promote products derived from this software without
76689+ specific prior written permission.
76690+
76691+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
76692+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76693+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76694+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
76695+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76696+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76697+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
76698+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76699+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76700+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76701+
76702+*******************************************************************************/
76703+
76704+#ifndef __INCmvSFlashH
76705+#define __INCmvSFlashH
76706+
76707+#include "mvTypes.h"
76708+
76709+/* MCAROS */
76710+#define MV_SFLASH_PAGE_ALLIGN_MASK(pgSz) (pgSz-1)
76711+#define MV_ARRAY_SIZE(a) ((sizeof(a)) / (sizeof(a[0])))
76712+
76713+/* Constants */
76714+#define MV_INVALID_DEVICE_NUMBER 0xFFFFFFFF
76715+/* 10 MHz is the minimum possible SPI frequency when tclk is set 200MHz*/
76716+#define MV_SFLASH_BASIC_SPI_FREQ 10000000
76717+/* enumerations */
76718+typedef enum
76719+{
76720+ MV_WP_NONE, /* Unprotect the whole chip */
76721+ MV_WP_UPR_1OF128, /* Write protect the upper 1/128 part */
76722+ MV_WP_UPR_1OF64, /* Write protect the upper 1/64 part */
76723+ MV_WP_UPR_1OF32, /* Write protect the upper 1/32 part */
76724+ MV_WP_UPR_1OF16, /* Write protect the upper 1/16 part */
76725+ MV_WP_UPR_1OF8, /* Write protect the upper 1/8 part */
76726+ MV_WP_UPR_1OF4, /* Write protect the upper 1/4 part */
76727+ MV_WP_UPR_1OF2, /* Write protect the upper 1/2 part */
76728+ MV_WP_ALL /* Write protect the whole chip */
76729+} MV_SFLASH_WP_REGION;
76730+
76731+/* Type Definitions */
76732+typedef struct
76733+{
76734+ MV_U8 opcdWREN; /* Write enable opcode */
76735+ MV_U8 opcdWRDI; /* Write disable opcode */
76736+ MV_U8 opcdRDID; /* Read ID opcode */
76737+ MV_U8 opcdRDSR; /* Read Status Register opcode */
76738+ MV_U8 opcdWRSR; /* Write Status register opcode */
76739+ MV_U8 opcdREAD; /* Read opcode */
76740+ MV_U8 opcdFSTRD; /* Fast Read opcode */
76741+ MV_U8 opcdPP; /* Page program opcode */
76742+ MV_U8 opcdSE; /* Sector erase opcode */
76743+ MV_U8 opcdBE; /* Bulk erase opcode */
76744+ MV_U8 opcdRES; /* Read electronic signature */
76745+ MV_U8 opcdPwrSave; /* Go into power save mode */
76746+ MV_U32 sectorSize; /* Size of each sector */
76747+ MV_U32 sectorNumber; /* Number of sectors */
76748+ MV_U32 pageSize; /* size of each page */
76749+ const char * deviceModel; /* string with the device model */
76750+ MV_U32 manufacturerId; /* The manufacturer ID */
76751+ MV_U32 deviceId; /* Device ID */
76752+ MV_U32 spiMaxFreq; /* The MAX frequency that can be used with the device */
76753+ MV_U32 spiMaxFastFreq; /* The MAX frequency that can be used with the device for fast reads */
76754+ MV_U32 spiFastRdDummyBytes; /* Number of dumy bytes to read before real data when working in fast read mode. */
76755+} MV_SFLASH_DEVICE_PARAMS;
76756+
76757+typedef struct
76758+{
76759+ MV_U32 baseAddr; /* Flash Base Address used in fast mode */
76760+ MV_U8 manufacturerId; /* Manufacturer ID */
76761+ MV_U16 deviceId; /* Device ID */
76762+ MV_U32 sectorSize; /* Size of each sector - all the same */
76763+ MV_U32 sectorNumber; /* Number of sectors */
76764+ MV_U32 pageSize; /* Page size - affect allignment */
76765+ MV_U32 index; /* index of the device in the sflash table (internal parameter) */
76766+} MV_SFLASH_INFO;
76767+
76768+/* Function Prototypes */
76769+/* Init */
76770+MV_STATUS mvSFlashInit (MV_SFLASH_INFO * pFlinfo);
76771+
76772+/* erase */
76773+MV_STATUS mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber);
76774+MV_STATUS mvSFlashChipErase (MV_SFLASH_INFO * pFlinfo);
76775+
76776+/* Read */
76777+MV_STATUS mvSFlashBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
76778+ MV_U8* pReadBuff, MV_U32 buffSize);
76779+MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
76780+ MV_U8* pReadBuff, MV_U32 buffSize);
76781+
76782+/* write regardless of the page boundaries and size limit per Page program command */
76783+MV_STATUS mvSFlashBlockWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
76784+ MV_U8* pWriteBuff, MV_U32 buffSize);
76785+/* Get IDs */
76786+MV_STATUS mvSFlashIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId);
76787+
76788+/* Set and Get the Write Protection region - if the Status register is not locked */
76789+MV_STATUS mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion);
76790+MV_STATUS mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion);
76791+
76792+/* Lock the status register for writing - W/Vpp pin should be low to take effect */
76793+MV_STATUS mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock);
76794+
76795+/* Get the regions sizes */
76796+MV_U32 mvSFlashSizeGet (MV_SFLASH_INFO * pFlinfo);
76797+
76798+/* Cause the falsh device to go into power save mode */
76799+MV_STATUS mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo);
76800+MV_STATUS mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo);
76801+
76802+/* Retreive the string with the device manufacturer and model */
76803+const MV_8 * mvSFlashModelGet (MV_SFLASH_INFO * pFlinfo);
76804+
76805+#endif /* __INCmvSFlashH */
76806diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h b/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h
76807new file mode 100644
76808index 0000000..cef4255
76809--- /dev/null
76810+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h
76811@@ -0,0 +1,233 @@
76812+/*******************************************************************************
76813+Copyright (C) Marvell International Ltd. and its affiliates
76814+
76815+This software file (the "File") is owned and distributed by Marvell
76816+International Ltd. and/or its affiliates ("Marvell") under the following
76817+alternative licensing terms. Once you have made an election to distribute the
76818+File under one of the following license alternatives, please (i) delete this
76819+introductory statement regarding license alternatives, (ii) delete the two
76820+license alternatives that you have not elected to use and (iii) preserve the
76821+Marvell copyright notice above.
76822+
76823+********************************************************************************
76824+Marvell Commercial License Option
76825+
76826+If you received this File from Marvell and you have entered into a commercial
76827+license agreement (a "Commercial License") with Marvell, the File is licensed
76828+to you under the terms of the applicable Commercial License.
76829+
76830+********************************************************************************
76831+Marvell GPL License Option
76832+
76833+If you received this File from Marvell, you may opt to use, redistribute and/or
76834+modify this File in accordance with the terms and conditions of the General
76835+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
76836+available along with the File in the license.txt file or by writing to the Free
76837+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
76838+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
76839+
76840+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
76841+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
76842+DISCLAIMED. The GPL License provides additional details about this warranty
76843+disclaimer.
76844+********************************************************************************
76845+Marvell BSD License Option
76846+
76847+If you received this File from Marvell, you may opt to use, redistribute and/or
76848+modify this File under the following licensing terms.
76849+Redistribution and use in source and binary forms, with or without modification,
76850+are permitted provided that the following conditions are met:
76851+
76852+ * Redistributions of source code must retain the above copyright notice,
76853+ this list of conditions and the following disclaimer.
76854+
76855+ * Redistributions in binary form must reproduce the above copyright
76856+ notice, this list of conditions and the following disclaimer in the
76857+ documentation and/or other materials provided with the distribution.
76858+
76859+ * Neither the name of Marvell nor the names of its contributors may be
76860+ used to endorse or promote products derived from this software without
76861+ specific prior written permission.
76862+
76863+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
76864+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76865+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76866+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
76867+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76868+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76869+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
76870+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76871+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76872+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76873+
76874+*******************************************************************************/
76875+
76876+#ifndef __INCmvSFlashSpecH
76877+#define __INCmvSFlashSpecH
76878+
76879+/* Constants */
76880+#define MV_SFLASH_READ_CMND_LENGTH 4 /* 1B opcode + 3B address */
76881+#define MV_SFLASH_SE_CMND_LENGTH 4 /* 1B opcode + 3B address */
76882+#define MV_SFLASH_BE_CMND_LENGTH 1 /* 1B opcode */
76883+#define MV_SFLASH_PP_CMND_LENGTH 4 /* 1B opcode + 3B address */
76884+#define MV_SFLASH_WREN_CMND_LENGTH 1 /* 1B opcode */
76885+#define MV_SFLASH_WRDI_CMND_LENGTH 1 /* 1B opcode */
76886+#define MV_SFLASH_RDID_CMND_LENGTH 1 /* 1B opcode */
76887+#define MV_SFLASH_RDID_REPLY_LENGTH 3 /* 1B manf ID and 2B device ID */
76888+#define MV_SFLASH_RDSR_CMND_LENGTH 1 /* 1B opcode */
76889+#define MV_SFLASH_RDSR_REPLY_LENGTH 1 /* 1B status */
76890+#define MV_SFLASH_WRSR_CMND_LENGTH 2 /* 1B opcode + 1B status value */
76891+#define MV_SFLASH_DP_CMND_LENGTH 1 /* 1B opcode */
76892+#define MV_SFLASH_RES_CMND_LENGTH 1 /* 1B opcode */
76893+
76894+/* Status Register Bit Masks */
76895+#define MV_SFLASH_STATUS_REG_WIP_OFFSET 0 /* bit 0; write in progress */
76896+#define MV_SFLASH_STATUS_REG_WP_OFFSET 2 /* bit 2-4; write protect option */
76897+#define MV_SFLASH_STATUS_REG_SRWD_OFFSET 7 /* bit 7; lock status register write */
76898+#define MV_SFLASH_STATUS_REG_WIP_MASK (0x1 << MV_SFLASH_STATUS_REG_WIP_OFFSET)
76899+#define MV_SFLASH_STATUS_REG_SRWD_MASK (0x1 << MV_SFLASH_STATUS_REG_SRWD_OFFSET)
76900+
76901+#define MV_SFLASH_MAX_WAIT_LOOP 1000000
76902+#define MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP 0x50000000
76903+
76904+#define MV_SFLASH_DEFAULT_RDID_OPCD 0x9F /* Default Read ID */
76905+#define MV_SFLASH_DEFAULT_WREN_OPCD 0x06 /* Default Write Enable */
76906+#define MV_SFLASH_NO_SPECIFIC_OPCD 0x00
76907+
76908+/********************************/
76909+/* ST M25Pxxx Device Specific */
76910+/********************************/
76911+
76912+/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
76913+#define MV_M25PXXX_ST_MANF_ID 0x20
76914+#define MV_M25P32_DEVICE_ID 0x2016
76915+#define MV_M25P32_MAX_SPI_FREQ 20000000 /* 20MHz */
76916+#define MV_M25P32_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
76917+#define MV_M25P32_FAST_READ_DUMMY_BYTES 1
76918+#define MV_M25P64_DEVICE_ID 0x2017
76919+#define MV_M25P64_MAX_SPI_FREQ 20000000 /* 20MHz */
76920+#define MV_M25P64_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
76921+#define MV_M25P64_FAST_READ_DUMMY_BYTES 1
76922+#define MV_M25P128_DEVICE_ID 0x2018
76923+#define MV_M25P128_MAX_SPI_FREQ 20000000 /* 20MHz */
76924+#define MV_M25P128_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
76925+#define MV_M25P128_FAST_READ_DUMMY_BYTES 1
76926+
76927+
76928+/* Sector Sizes and population per device model*/
76929+#define MV_M25P32_SECTOR_SIZE 0x10000 /* 64K */
76930+#define MV_M25P64_SECTOR_SIZE 0x10000 /* 64K */
76931+#define MV_M25P128_SECTOR_SIZE 0x40000 /* 256K */
76932+#define MV_M25P32_SECTOR_NUMBER 64
76933+#define MV_M25P64_SECTOR_NUMBER 128
76934+#define MV_M25P128_SECTOR_NUMBER 64
76935+#define MV_M25P_PAGE_SIZE 0x100 /* 256 byte */
76936+
76937+#define MV_M25P_WREN_CMND_OPCD 0x06 /* Write Enable */
76938+#define MV_M25P_WRDI_CMND_OPCD 0x04 /* Write Disable */
76939+#define MV_M25P_RDID_CMND_OPCD 0x9F /* Read ID */
76940+#define MV_M25P_RDSR_CMND_OPCD 0x05 /* Read Status Register */
76941+#define MV_M25P_WRSR_CMND_OPCD 0x01 /* Write Status Register */
76942+#define MV_M25P_READ_CMND_OPCD 0x03 /* Sequential Read */
76943+#define MV_M25P_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
76944+#define MV_M25P_PP_CMND_OPCD 0x02 /* Page Program */
76945+#define MV_M25P_SE_CMND_OPCD 0xD8 /* Sector Erase */
76946+#define MV_M25P_BE_CMND_OPCD 0xC7 /* Bulk Erase */
76947+#define MV_M25P_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
76948+
76949+/* Status Register Write Protect Bit Masks - 3bits */
76950+#define MV_M25P_STATUS_REG_WP_MASK (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76951+#define MV_M25P_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76952+#define MV_M25P_STATUS_BP_1_OF_64 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76953+#define MV_M25P_STATUS_BP_1_OF_32 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76954+#define MV_M25P_STATUS_BP_1_OF_16 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76955+#define MV_M25P_STATUS_BP_1_OF_8 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76956+#define MV_M25P_STATUS_BP_1_OF_4 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76957+#define MV_M25P_STATUS_BP_1_OF_2 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76958+#define MV_M25P_STATUS_BP_ALL (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76959+
76960+/************************************/
76961+/* MXIC MX25L6405 Device Specific */
76962+/************************************/
76963+
76964+/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
76965+#define MV_MXIC_MANF_ID 0xC2
76966+#define MV_MX25L6405_DEVICE_ID 0x2017
76967+#define MV_MX25L6405_MAX_SPI_FREQ 20000000 /* 20MHz */
76968+#define MV_MX25L6405_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
76969+#define MV_MX25L6405_FAST_READ_DUMMY_BYTES 1
76970+#define MV_MXIC_DP_EXIT_DELAY 30 /* 30 ms */
76971+
76972+/* Sector Sizes and population per device model*/
76973+#define MV_MX25L6405_SECTOR_SIZE 0x10000 /* 64K */
76974+#define MV_MX25L6405_SECTOR_NUMBER 128
76975+#define MV_MXIC_PAGE_SIZE 0x100 /* 256 byte */
76976+
76977+#define MV_MX25L_WREN_CMND_OPCD 0x06 /* Write Enable */
76978+#define MV_MX25L_WRDI_CMND_OPCD 0x04 /* Write Disable */
76979+#define MV_MX25L_RDID_CMND_OPCD 0x9F /* Read ID */
76980+#define MV_MX25L_RDSR_CMND_OPCD 0x05 /* Read Status Register */
76981+#define MV_MX25L_WRSR_CMND_OPCD 0x01 /* Write Status Register */
76982+#define MV_MX25L_READ_CMND_OPCD 0x03 /* Sequential Read */
76983+#define MV_MX25L_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
76984+#define MV_MX25L_PP_CMND_OPCD 0x02 /* Page Program */
76985+#define MV_MX25L_SE_CMND_OPCD 0xD8 /* Sector Erase */
76986+#define MV_MX25L_BE_CMND_OPCD 0xC7 /* Bulk Erase */
76987+#define MV_MX25L_DP_CMND_OPCD 0xB9 /* Deep Power Down */
76988+#define MV_MX25L_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
76989+
76990+/* Status Register Write Protect Bit Masks - 4bits */
76991+#define MV_MX25L_STATUS_REG_WP_MASK (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
76992+#define MV_MX25L_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76993+#define MV_MX25L_STATUS_BP_1_OF_128 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76994+#define MV_MX25L_STATUS_BP_1_OF_64 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76995+#define MV_MX25L_STATUS_BP_1_OF_32 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76996+#define MV_MX25L_STATUS_BP_1_OF_16 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76997+#define MV_MX25L_STATUS_BP_1_OF_8 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76998+#define MV_MX25L_STATUS_BP_1_OF_4 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
76999+#define MV_MX25L_STATUS_BP_1_OF_2 (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
77000+#define MV_MX25L_STATUS_BP_ALL (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
77001+
77002+/************************************/
77003+/* SPANSION S25FL128P Device Specific */
77004+/************************************/
77005+
77006+/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
77007+#define MV_SPANSION_MANF_ID 0x01
77008+#define MV_S25FL128_DEVICE_ID 0x2018
77009+#define MV_S25FL128_MAX_SPI_FREQ 33000000 /* 33MHz */
77010+#define MV_S25FL128_MAX_FAST_SPI_FREQ 104000000 /* 104MHz */
77011+#define MV_S25FL128_FAST_READ_DUMMY_BYTES 1
77012+
77013+/* Sector Sizes and population per device model*/
77014+#define MV_S25FL128_SECTOR_SIZE 0x40000 /* 256K */
77015+#define MV_S25FL128_SECTOR_NUMBER 64
77016+#define MV_S25FL_PAGE_SIZE 0x100 /* 256 byte */
77017+
77018+#define MV_S25FL_WREN_CMND_OPCD 0x06 /* Write Enable */
77019+#define MV_S25FL_WRDI_CMND_OPCD 0x04 /* Write Disable */
77020+#define MV_S25FL_RDID_CMND_OPCD 0x9F /* Read ID */
77021+#define MV_S25FL_RDSR_CMND_OPCD 0x05 /* Read Status Register */
77022+#define MV_S25FL_WRSR_CMND_OPCD 0x01 /* Write Status Register */
77023+#define MV_S25FL_READ_CMND_OPCD 0x03 /* Sequential Read */
77024+#define MV_S25FL_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
77025+#define MV_S25FL_PP_CMND_OPCD 0x02 /* Page Program */
77026+#define MV_S25FL_SE_CMND_OPCD 0xD8 /* Sector Erase */
77027+#define MV_S25FL_BE_CMND_OPCD 0xC7 /* Bulk Erase */
77028+#define MV_S25FL_DP_CMND_OPCD 0xB9 /* Deep Power Down */
77029+#define MV_S25FL_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
77030+
77031+/* Status Register Write Protect Bit Masks - 4bits */
77032+#define MV_S25FL_STATUS_REG_WP_MASK (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
77033+#define MV_S25FL_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
77034+#define MV_S25FL_STATUS_BP_1_OF_128 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
77035+#define MV_S25FL_STATUS_BP_1_OF_64 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
77036+#define MV_S25FL_STATUS_BP_1_OF_32 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
77037+#define MV_S25FL_STATUS_BP_1_OF_16 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
77038+#define MV_S25FL_STATUS_BP_1_OF_8 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
77039+#define MV_S25FL_STATUS_BP_1_OF_4 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
77040+#define MV_S25FL_STATUS_BP_1_OF_2 (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
77041+#define MV_S25FL_STATUS_BP_ALL (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
77042+
77043+#endif /* __INCmvSFlashSpecH */
77044+
77045diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c b/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c
77046new file mode 100644
77047index 0000000..efdd6ae
77048--- /dev/null
77049+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c
77050@@ -0,0 +1,576 @@
77051+/*******************************************************************************
77052+Copyright (C) Marvell International Ltd. and its affiliates
77053+
77054+This software file (the "File") is owned and distributed by Marvell
77055+International Ltd. and/or its affiliates ("Marvell") under the following
77056+alternative licensing terms. Once you have made an election to distribute the
77057+File under one of the following license alternatives, please (i) delete this
77058+introductory statement regarding license alternatives, (ii) delete the two
77059+license alternatives that you have not elected to use and (iii) preserve the
77060+Marvell copyright notice above.
77061+
77062+********************************************************************************
77063+Marvell Commercial License Option
77064+
77065+If you received this File from Marvell and you have entered into a commercial
77066+license agreement (a "Commercial License") with Marvell, the File is licensed
77067+to you under the terms of the applicable Commercial License.
77068+
77069+********************************************************************************
77070+Marvell GPL License Option
77071+
77072+If you received this File from Marvell, you may opt to use, redistribute and/or
77073+modify this File in accordance with the terms and conditions of the General
77074+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
77075+available along with the File in the license.txt file or by writing to the Free
77076+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
77077+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
77078+
77079+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
77080+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
77081+DISCLAIMED. The GPL License provides additional details about this warranty
77082+disclaimer.
77083+********************************************************************************
77084+Marvell BSD License Option
77085+
77086+If you received this File from Marvell, you may opt to use, redistribute and/or
77087+modify this File under the following licensing terms.
77088+Redistribution and use in source and binary forms, with or without modification,
77089+are permitted provided that the following conditions are met:
77090+
77091+ * Redistributions of source code must retain the above copyright notice,
77092+ this list of conditions and the following disclaimer.
77093+
77094+ * Redistributions in binary form must reproduce the above copyright
77095+ notice, this list of conditions and the following disclaimer in the
77096+ documentation and/or other materials provided with the distribution.
77097+
77098+ * Neither the name of Marvell nor the names of its contributors may be
77099+ used to endorse or promote products derived from this software without
77100+ specific prior written permission.
77101+
77102+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
77103+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77104+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77105+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
77106+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77107+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77108+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
77109+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77110+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77111+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77112+
77113+*******************************************************************************/
77114+
77115+#include "spi/mvSpi.h"
77116+#include "spi/mvSpiSpec.h"
77117+
77118+#include "ctrlEnv/mvCtrlEnvLib.h"
77119+
77120+/* #define MV_DEBUG */
77121+#ifdef MV_DEBUG
77122+#define DB(x) x
77123+#define mvOsPrintf printf
77124+#else
77125+#define DB(x)
77126+#endif
77127+
77128+
77129+/*******************************************************************************
77130+* mvSpi16bitDataTxRx - Transmt and receive data
77131+*
77132+* DESCRIPTION:
77133+* Tx data and block waiting for data to be transmitted
77134+*
77135+********************************************************************************/
77136+static MV_STATUS mvSpi16bitDataTxRx (MV_U16 txData, MV_U16 * pRxData)
77137+{
77138+ MV_U32 i;
77139+ MV_BOOL ready = MV_FALSE;
77140+
77141+ /* First clear the bit in the interrupt cause register */
77142+ MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);
77143+
77144+ /* Transmit data */
77145+ MV_REG_WRITE(MV_SPI_DATA_OUT_REG, MV_16BIT_LE(txData));
77146+
77147+ /* wait with timeout for memory ready */
77148+ for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)
77149+ {
77150+ if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))
77151+ {
77152+ ready = MV_TRUE;
77153+ break;
77154+ }
77155+#ifdef MV_SPI_SLEEP_ON_WAIT
77156+ mvOsSleep(1);
77157+#endif /* MV_SPI_SLEEP_ON_WAIT */
77158+ }
77159+
77160+ if (!ready)
77161+ return MV_TIMEOUT;
77162+
77163+ /* check that the RX data is needed */
77164+ if (pRxData)
77165+ {
77166+ if ((MV_U32)pRxData & 0x1) /* check if address is not alligned to 16bit */
77167+ {
77168+#if defined(MV_CPU_LE)
77169+ /* perform the data write to the buffer in two stages with 8bit each */
77170+ MV_U8 * bptr = (MV_U8*)pRxData;
77171+ MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
77172+ *bptr = (data & 0xFF);
77173+ ++bptr;
77174+ *bptr = ((data >> 8) & 0xFF);
77175+
77176+#elif defined(MV_CPU_BE)
77177+
77178+ /* perform the data write to the buffer in two stages with 8bit each */
77179+ MV_U8 * bptr = (MV_U8 *)pRxData;
77180+ MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
77181+ *bptr = ((data >> 8) & 0xFF);
77182+ ++bptr;
77183+ *bptr = (data & 0xFF);
77184+
77185+#else
77186+ #error "CPU endianess isn't defined!\n"
77187+#endif
77188+
77189+ }
77190+ else
77191+ *pRxData = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
77192+ }
77193+
77194+ return MV_OK;
77195+}
77196+
77197+
77198+/*******************************************************************************
77199+* mvSpi8bitDataTxRx - Transmt and receive data (8bits)
77200+*
77201+* DESCRIPTION:
77202+* Tx data and block waiting for data to be transmitted
77203+*
77204+********************************************************************************/
77205+static MV_STATUS mvSpi8bitDataTxRx (MV_U8 txData, MV_U8 * pRxData)
77206+{
77207+ MV_U32 i;
77208+ MV_BOOL ready = MV_FALSE;
77209+
77210+ /* First clear the bit in the interrupt cause register */
77211+ MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);
77212+
77213+ /* Transmit data */
77214+ MV_REG_WRITE(MV_SPI_DATA_OUT_REG, txData);
77215+
77216+ /* wait with timeout for memory ready */
77217+ for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)
77218+ {
77219+ if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))
77220+ {
77221+ ready = MV_TRUE;
77222+ break;
77223+ }
77224+#ifdef MV_SPI_SLEEP_ON_WAIT
77225+ mvOsSleep(1);
77226+#endif /* MV_SPI_SLEEP_ON_WAIT */
77227+ }
77228+
77229+ if (!ready)
77230+ return MV_TIMEOUT;
77231+
77232+ /* check that the RX data is needed */
77233+ if (pRxData)
77234+ *pRxData = MV_REG_READ(MV_SPI_DATA_IN_REG);
77235+
77236+ return MV_OK;
77237+}
77238+
77239+/*
77240+#####################################################################################
77241+#####################################################################################
77242+*/
77243+
77244+/*******************************************************************************
77245+* mvSpiInit - Initialize the SPI controller
77246+*
77247+* DESCRIPTION:
77248+* Perform the neccessary initialization in order to be able to send an
77249+* receive over the SPI interface.
77250+*
77251+* INPUT:
77252+* serialBaudRate: Baud rate (SPI clock frequency)
77253+* use16BitMode: Whether to use 2bytes (MV_TRUE) or 1bytes (MV_FALSE)
77254+*
77255+* OUTPUT:
77256+* None.
77257+*
77258+* RETURN:
77259+* Success or Error code.
77260+*
77261+*
77262+*******************************************************************************/
77263+MV_STATUS mvSpiInit (MV_U32 serialBaudRate)
77264+{
77265+ MV_STATUS ret;
77266+
77267+ /* Set the serial clock */
77268+ if ((ret = mvSpiBaudRateSet(serialBaudRate)) != MV_OK)
77269+ return ret;
77270+
77271+ /* For devices in which the SPI is muxed on the MPP with other interfaces*/
77272+ mvMPPConfigToSPI();
77273+
77274+ /* Configure the default SPI mode to be 16bit */
77275+ MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
77276+
77277+ /* Fix ac timing on SPI in 6183, 6183L and 78x00 only */
77278+ if ( (mvCtrlModelGet() == MV_6183_DEV_ID) ||
77279+ (mvCtrlModelGet() == MV_6183L_DEV_ID) ||
77280+ (mvCtrlModelGet() == MV_78100_DEV_ID) ||
77281+ (mvCtrlModelGet() == MV_78200_DEV_ID) ||
77282+ (mvCtrlModelGet() == MV_76100_DEV_ID))
77283+ MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, BIT14);
77284+
77285+ /* Verify that the CS is deasserted */
77286+ mvSpiCsDeassert();
77287+
77288+ return MV_OK;
77289+}
77290+
77291+/*******************************************************************************
77292+* mvSpiBaudRateSet - Set the Frequency of the SPI clock
77293+*
77294+* DESCRIPTION:
77295+* Set the Prescale bits to adapt to the requested baud rate (the clock
77296+* used for thr SPI).
77297+*
77298+* INPUT:
77299+* serialBaudRate: Baud rate (SPI clock frequency)
77300+*
77301+* OUTPUT:
77302+* None.
77303+*
77304+* RETURN:
77305+* Success or Error code.
77306+*
77307+*
77308+*******************************************************************************/
77309+MV_STATUS mvSpiBaudRateSet (MV_U32 serialBaudRate)
77310+{
77311+ MV_U8 i;
77312+ /* MV_U8 preScale[32] = {1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
77313+ 2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
77314+ */
77315+ MV_U8 preScale[14] = { 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
77316+ MV_U8 bestPrescaleIndx = 100;
77317+ MV_U32 minBaudOffset = 0xFFFFFFFF;
77318+ MV_U32 cpuClk = mvBoardTclkGet(); /*mvCpuPclkGet();*/
77319+ MV_U32 tempReg;
77320+
77321+ /* Find the best prescale configuration - less or equal */
77322+ for (i=0; i<14; i++)
77323+ {
77324+ /* check for higher - irrelevent */
77325+ if ((cpuClk / preScale[i]) > serialBaudRate)
77326+ continue;
77327+
77328+ /* check for exact fit */
77329+ if ((cpuClk / preScale[i]) == serialBaudRate)
77330+ {
77331+ bestPrescaleIndx = i;
77332+ break;
77333+ }
77334+
77335+ /* check if this is better than the previous one */
77336+ if ((serialBaudRate - (cpuClk / preScale[i])) < minBaudOffset)
77337+ {
77338+ minBaudOffset = (serialBaudRate - (cpuClk / preScale[i]));
77339+ bestPrescaleIndx = i;
77340+ }
77341+ }
77342+
77343+ if (bestPrescaleIndx > 14)
77344+ {
77345+ mvOsPrintf("%s ERROR: SPI baud rate prescale error!\n", __FUNCTION__);
77346+ return MV_OUT_OF_RANGE;
77347+ }
77348+
77349+ /* configure the Prescale */
77350+ tempReg = MV_REG_READ(MV_SPI_IF_CONFIG_REG);
77351+ tempReg = ((tempReg & ~MV_SPI_CLK_PRESCALE_MASK) | (bestPrescaleIndx + 0x12));
77352+ MV_REG_WRITE(MV_SPI_IF_CONFIG_REG, tempReg);
77353+
77354+ return MV_OK;
77355+}
77356+
77357+/*******************************************************************************
77358+* mvSpiCsAssert - Assert the Chip Select pin indicating a new transfer
77359+*
77360+* DESCRIPTION:
77361+* Assert The chip select - used to select an external SPI device
77362+*
77363+* INPUT:
77364+* None.
77365+*
77366+* OUTPUT:
77367+* None.
77368+*
77369+* RETURN:
77370+* Success or Error code.
77371+*
77372+********************************************************************************/
77373+MV_VOID mvSpiCsAssert(MV_VOID)
77374+{
77375+ /* For devices in which the SPI is muxed on the MPP with other interfaces*/
77376+ mvMPPConfigToSPI();
77377+ mvOsUDelay(1);
77378+ MV_REG_BIT_SET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);
77379+}
77380+
77381+/*******************************************************************************
77382+* mvSpiCsDeassert - DeAssert the Chip Select pin indicating the end of a
77383+* SPI transfer sequence
77384+*
77385+* DESCRIPTION:
77386+* DeAssert the chip select pin
77387+*
77388+* INPUT:
77389+* None.
77390+*
77391+* OUTPUT:
77392+* None.
77393+*
77394+* RETURN:
77395+* Success or Error code.
77396+*
77397+********************************************************************************/
77398+MV_VOID mvSpiCsDeassert(MV_VOID)
77399+{
77400+ MV_REG_BIT_RESET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);
77401+
77402+ /* For devices in which the SPI is muxed on the MPP with other interfaces*/
77403+ mvMPPConfigToDefault();
77404+}
77405+
77406+/*******************************************************************************
77407+* mvSpiRead - Read a buffer over the SPI interface
77408+*
77409+* DESCRIPTION:
77410+* Receive (read) a buffer over the SPI interface in 16bit chunks. If the
77411+* buffer size is odd, then the last chunk will be 8bits. Chip select is not
77412+* handled at this level.
77413+*
77414+* INPUT:
77415+* pRxBuff: Pointer to the buffer to hold the received data
77416+* buffSize: length of the pRxBuff
77417+*
77418+* OUTPUT:
77419+* pRxBuff: Pointer to the buffer with the received data
77420+*
77421+* RETURN:
77422+* Success or Error code.
77423+*
77424+*
77425+*******************************************************************************/
77426+MV_STATUS mvSpiRead (MV_U8* pRxBuff, MV_U32 buffSize)
77427+{
77428+ MV_STATUS ret;
77429+ MV_U32 bytesLeft = buffSize;
77430+ MV_U16* rxPtr = (MV_U16*)pRxBuff;
77431+
77432+ /* check for null parameters */
77433+ if (pRxBuff == NULL)
77434+ {
77435+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
77436+ return MV_BAD_PARAM;
77437+ }
77438+
77439+ /* Check that the buffer pointer and the buffer size are 16bit aligned */
77440+ if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))
77441+ {
77442+ /* Verify that the SPI mode is in 16bit mode */
77443+ MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
77444+
77445+ /* TX/RX as long we have complete 16bit chunks */
77446+ while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
77447+ {
77448+ /* Transmitted and wait for the transfer to be completed */
77449+ if ((ret = mvSpi16bitDataTxRx(MV_SPI_DUMMY_WRITE_16BITS, rxPtr)) != MV_OK)
77450+ return ret;
77451+
77452+ /* increment the pointers */
77453+ rxPtr++;
77454+ bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
77455+ }
77456+
77457+ }
77458+ else
77459+ {
77460+ /* Verify that the SPI mode is in 8bit mode */
77461+ MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
77462+
77463+ /* TX/RX in 8bit chanks */
77464+ while (bytesLeft > 0)
77465+ {
77466+ /* Transmitted and wait for the transfer to be completed */
77467+ if ((ret = mvSpi8bitDataTxRx(MV_SPI_DUMMY_WRITE_8BITS, pRxBuff)) != MV_OK)
77468+ return ret;
77469+ /* increment the pointers */
77470+ pRxBuff++;
77471+ bytesLeft--;
77472+ }
77473+ }
77474+
77475+ return MV_OK;
77476+}
77477+
77478+/*******************************************************************************
77479+* mvSpiWrite - Transmit a buffer over the SPI interface
77480+*
77481+* DESCRIPTION:
77482+* Transmit a buffer over the SPI interface in 16bit chunks. If the
77483+* buffer size is odd, then the last chunk will be 8bits. No chip select
77484+* action is taken.
77485+*
77486+* INPUT:
77487+* pTxBuff: Pointer to the buffer holding the TX data
77488+* buffSize: length of the pTxBuff
77489+*
77490+* OUTPUT:
77491+* None.
77492+*
77493+* RETURN:
77494+* Success or Error code.
77495+*
77496+*
77497+*******************************************************************************/
77498+MV_STATUS mvSpiWrite(MV_U8* pTxBuff, MV_U32 buffSize)
77499+{
77500+ MV_STATUS ret;
77501+ MV_U32 bytesLeft = buffSize;
77502+ MV_U16* txPtr = (MV_U16*)pTxBuff;
77503+
77504+ /* check for null parameters */
77505+ if (pTxBuff == NULL)
77506+ {
77507+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
77508+ return MV_BAD_PARAM;
77509+ }
77510+
77511+ /* Check that the buffer pointer and the buffer size are 16bit aligned */
77512+ if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0))
77513+ {
77514+ /* Verify that the SPI mode is in 16bit mode */
77515+ MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
77516+
77517+ /* TX/RX as long we have complete 16bit chunks */
77518+ while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
77519+ {
77520+ /* Transmitted and wait for the transfer to be completed */
77521+ if ((ret = mvSpi16bitDataTxRx(*txPtr, NULL)) != MV_OK)
77522+ return ret;
77523+
77524+ /* increment the pointers */
77525+ txPtr++;
77526+ bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
77527+ }
77528+ }
77529+ else
77530+ {
77531+
77532+ /* Verify that the SPI mode is in 8bit mode */
77533+ MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
77534+
77535+ /* TX/RX in 8bit chanks */
77536+ while (bytesLeft > 0)
77537+ {
77538+ /* Transmitted and wait for the transfer to be completed */
77539+ if ((ret = mvSpi8bitDataTxRx(*pTxBuff, NULL)) != MV_OK)
77540+ return ret;
77541+
77542+ /* increment the pointers */
77543+ pTxBuff++;
77544+ bytesLeft--;
77545+ }
77546+ }
77547+
77548+ return MV_OK;
77549+}
77550+
77551+
77552+/*******************************************************************************
77553+* mvSpiReadWrite - Read and Write a buffer simultanuosely
77554+*
77555+* DESCRIPTION:
77556+* Transmit and receive a buffer over the SPI in 16bit chunks. If the
77557+* buffer size is odd, then the last chunk will be 8bits. The SPI chip
77558+* select is not handled implicitely.
77559+*
77560+* INPUT:
77561+* pRxBuff: Pointer to the buffer to write the RX info in
77562+* pTxBuff: Pointer to the buffer holding the TX info
77563+* buffSize: length of both the pTxBuff and pRxBuff
77564+*
77565+* OUTPUT:
77566+* pRxBuff: Pointer of the buffer holding the RX data
77567+*
77568+* RETURN:
77569+* Success or Error code.
77570+*
77571+*
77572+*******************************************************************************/
77573+MV_STATUS mvSpiReadWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)
77574+{
77575+ MV_STATUS ret;
77576+ MV_U32 bytesLeft = buffSize;
77577+ MV_U16* txPtr = (MV_U16*)pTxBuff;
77578+ MV_U16* rxPtr = (MV_U16*)pRxBuff;
77579+
77580+ /* check for null parameters */
77581+ if ((pRxBuff == NULL) || (pTxBuff == NULL))
77582+ {
77583+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
77584+ return MV_BAD_PARAM;
77585+ }
77586+
77587+ /* Check that the buffer pointer and the buffer size are 16bit aligned */
77588+ if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))
77589+ {
77590+ /* Verify that the SPI mode is in 16bit mode */
77591+ MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
77592+
77593+ /* TX/RX as long we have complete 16bit chunks */
77594+ while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
77595+ {
77596+ /* Transmitted and wait for the transfer to be completed */
77597+ if ((ret = mvSpi16bitDataTxRx(*txPtr, rxPtr)) != MV_OK)
77598+ return ret;
77599+
77600+ /* increment the pointers */
77601+ txPtr++;
77602+ rxPtr++;
77603+ bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
77604+ }
77605+ }
77606+ else
77607+ {
77608+ /* Verify that the SPI mode is in 8bit mode */
77609+ MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
77610+
77611+ /* TX/RX in 8bit chanks */
77612+ while (bytesLeft > 0)
77613+ {
77614+ /* Transmitted and wait for the transfer to be completed */
77615+ if ( (ret = mvSpi8bitDataTxRx(*pTxBuff, pRxBuff) ) != MV_OK)
77616+ return ret;
77617+ pRxBuff++;
77618+ pTxBuff++;
77619+ bytesLeft--;
77620+ }
77621+ }
77622+
77623+ return MV_OK;
77624+}
77625+
77626+
77627diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h b/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h
77628new file mode 100644
77629index 0000000..c3db297
77630--- /dev/null
77631+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h
77632@@ -0,0 +1,94 @@
77633+/*******************************************************************************
77634+Copyright (C) Marvell International Ltd. and its affiliates
77635+
77636+This software file (the "File") is owned and distributed by Marvell
77637+International Ltd. and/or its affiliates ("Marvell") under the following
77638+alternative licensing terms. Once you have made an election to distribute the
77639+File under one of the following license alternatives, please (i) delete this
77640+introductory statement regarding license alternatives, (ii) delete the two
77641+license alternatives that you have not elected to use and (iii) preserve the
77642+Marvell copyright notice above.
77643+
77644+********************************************************************************
77645+Marvell Commercial License Option
77646+
77647+If you received this File from Marvell and you have entered into a commercial
77648+license agreement (a "Commercial License") with Marvell, the File is licensed
77649+to you under the terms of the applicable Commercial License.
77650+
77651+********************************************************************************
77652+Marvell GPL License Option
77653+
77654+If you received this File from Marvell, you may opt to use, redistribute and/or
77655+modify this File in accordance with the terms and conditions of the General
77656+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
77657+available along with the File in the license.txt file or by writing to the Free
77658+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
77659+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
77660+
77661+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
77662+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
77663+DISCLAIMED. The GPL License provides additional details about this warranty
77664+disclaimer.
77665+********************************************************************************
77666+Marvell BSD License Option
77667+
77668+If you received this File from Marvell, you may opt to use, redistribute and/or
77669+modify this File under the following licensing terms.
77670+Redistribution and use in source and binary forms, with or without modification,
77671+are permitted provided that the following conditions are met:
77672+
77673+ * Redistributions of source code must retain the above copyright notice,
77674+ this list of conditions and the following disclaimer.
77675+
77676+ * Redistributions in binary form must reproduce the above copyright
77677+ notice, this list of conditions and the following disclaimer in the
77678+ documentation and/or other materials provided with the distribution.
77679+
77680+ * Neither the name of Marvell nor the names of its contributors may be
77681+ used to endorse or promote products derived from this software without
77682+ specific prior written permission.
77683+
77684+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
77685+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77686+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77687+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
77688+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77689+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77690+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
77691+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77692+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77693+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77694+
77695+*******************************************************************************/
77696+
77697+#ifndef __INCmvSpihH
77698+#define __INCmvSpihH
77699+
77700+#include "mvCommon.h"
77701+#include "mvOs.h"
77702+#include "ctrlEnv/mvCtrlEnvSpec.h"
77703+
77704+/* Function Prototypes */
77705+/* Init */
77706+MV_STATUS mvSpiInit (MV_U32 serialBaudRate);
77707+
77708+/* Set the Frequency of the Spi clock */
77709+MV_STATUS mvSpiBaudRateSet(MV_U32 serialBaudRate);
77710+
77711+/* Assert the SPI chip select */
77712+MV_VOID mvSpiCsAssert (MV_VOID);
77713+
77714+/* De-assert the SPI chip select */
77715+MV_VOID mvSpiCsDeassert (MV_VOID);
77716+
77717+/* Simultanuous Read and write */
77718+MV_STATUS mvSpiReadWrite (MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);
77719+
77720+/* serialize a buffer on the TX line - Rx is ignored */
77721+MV_STATUS mvSpiWrite (MV_U8* pTxBuff, MV_U32 buffSize);
77722+
77723+/* read from the RX line by writing dummy values to the TX line */
77724+MV_STATUS mvSpiRead (MV_U8* pRxBuff, MV_U32 buffSize);
77725+
77726+#endif /* __INCmvSpihH */
77727diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c b/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c
77728new file mode 100644
77729index 0000000..a5d5a64
77730--- /dev/null
77731+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c
77732@@ -0,0 +1,249 @@
77733+/*******************************************************************************
77734+Copyright (C) Marvell International Ltd. and its affiliates
77735+
77736+This software file (the "File") is owned and distributed by Marvell
77737+International Ltd. and/or its affiliates ("Marvell") under the following
77738+alternative licensing terms. Once you have made an election to distribute the
77739+File under one of the following license alternatives, please (i) delete this
77740+introductory statement regarding license alternatives, (ii) delete the two
77741+license alternatives that you have not elected to use and (iii) preserve the
77742+Marvell copyright notice above.
77743+
77744+********************************************************************************
77745+Marvell Commercial License Option
77746+
77747+If you received this File from Marvell and you have entered into a commercial
77748+license agreement (a "Commercial License") with Marvell, the File is licensed
77749+to you under the terms of the applicable Commercial License.
77750+
77751+********************************************************************************
77752+Marvell GPL License Option
77753+
77754+If you received this File from Marvell, you may opt to use, redistribute and/or
77755+modify this File in accordance with the terms and conditions of the General
77756+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
77757+available along with the File in the license.txt file or by writing to the Free
77758+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
77759+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
77760+
77761+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
77762+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
77763+DISCLAIMED. The GPL License provides additional details about this warranty
77764+disclaimer.
77765+********************************************************************************
77766+Marvell BSD License Option
77767+
77768+If you received this File from Marvell, you may opt to use, redistribute and/or
77769+modify this File under the following licensing terms.
77770+Redistribution and use in source and binary forms, with or without modification,
77771+are permitted provided that the following conditions are met:
77772+
77773+ * Redistributions of source code must retain the above copyright notice,
77774+ this list of conditions and the following disclaimer.
77775+
77776+ * Redistributions in binary form must reproduce the above copyright
77777+ notice, this list of conditions and the following disclaimer in the
77778+ documentation and/or other materials provided with the distribution.
77779+
77780+ * Neither the name of Marvell nor the names of its contributors may be
77781+ used to endorse or promote products derived from this software without
77782+ specific prior written permission.
77783+
77784+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
77785+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77786+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77787+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
77788+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77789+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77790+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
77791+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77792+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77793+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77794+
77795+*******************************************************************************/
77796+
77797+#include "spi/mvSpi.h"
77798+#include "spi/mvSpiSpec.h"
77799+
77800+/*#define MV_DEBUG*/
77801+#ifdef MV_DEBUG
77802+#define DB(x) x
77803+#else
77804+#define DB(x)
77805+#endif
77806+
77807+
77808+/*******************************************************************************
77809+* mvSpiReadAndWrite - Read and Write a buffer simultanuousely
77810+*
77811+* DESCRIPTION:
77812+* Transmit and receive a buffer over the SPI in 16bit chunks. If the
77813+* buffer size is odd, then the last chunk will be 8bits.
77814+*
77815+* INPUT:
77816+* pRxBuff: Pointer to the buffer to write the RX info in
77817+* pTxBuff: Pointer to the buffer holding the TX info
77818+* buffSize: length of both the pTxBuff and pRxBuff
77819+*
77820+* OUTPUT:
77821+* pRxBuff: Pointer of the buffer holding the RX data
77822+*
77823+* RETURN:
77824+* Success or Error code.
77825+*
77826+*
77827+*******************************************************************************/
77828+MV_STATUS mvSpiReadAndWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)
77829+{
77830+ MV_STATUS ret;
77831+
77832+ /* check for null parameters */
77833+ if ((pRxBuff == NULL) || (pTxBuff == NULL) || (buffSize == 0))
77834+ {
77835+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
77836+ return MV_BAD_PARAM;
77837+ }
77838+
77839+ /* First assert the chip select */
77840+ mvSpiCsAssert();
77841+
77842+ ret = mvSpiReadWrite(pRxBuff, pTxBuff, buffSize);
77843+
77844+ /* Finally deassert the chip select */
77845+ mvSpiCsDeassert();
77846+
77847+ return ret;
77848+}
77849+
77850+/*******************************************************************************
77851+* mvSpiWriteThenWrite - Serialize a command followed by the data over the TX line
77852+*
77853+* DESCRIPTION:
77854+* Assert the chip select line. Transmit the command buffer followed by
77855+* the data buffer. Then deassert the CS line.
77856+*
77857+* INPUT:
77858+* pCmndBuff: Pointer to the command buffer to transmit
77859+* cmndSize: length of the command size
77860+* pTxDataBuff: Pointer to the data buffer to transmit
77861+* txDataSize: length of the data buffer
77862+*
77863+* OUTPUT:
77864+* None.
77865+*
77866+* RETURN:
77867+* Success or Error code.
77868+*
77869+*
77870+*******************************************************************************/
77871+MV_STATUS mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff,
77872+ MV_U32 txDataSize)
77873+{
77874+ MV_STATUS ret = MV_OK, tempRet;
77875+
77876+ /* check for null parameters */
77877+#ifndef CONFIG_MARVELL
77878+ if(NULL == pTxDataBuff)
77879+ {
77880+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
77881+ return MV_BAD_PARAM;
77882+ }
77883+#endif
77884+
77885+ if (pCmndBuff == NULL)
77886+ {
77887+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
77888+ return MV_BAD_PARAM;
77889+ }
77890+
77891+ /* First assert the chip select */
77892+ mvSpiCsAssert();
77893+
77894+ /* first write the command */
77895+ if ((cmndSize) && (pCmndBuff != NULL))
77896+ {
77897+ if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)
77898+ ret = tempRet;
77899+ }
77900+
77901+ /* Then write the data buffer */
77902+#ifndef CONFIG_MARVELL
77903+ if (txDataSize)
77904+#else
77905+ if ((txDataSize) && (pTxDataBuff != NULL))
77906+#endif
77907+ {
77908+ if ((tempRet = mvSpiWrite(pTxDataBuff, txDataSize)) != MV_OK)
77909+ ret = tempRet;
77910+ }
77911+
77912+ /* Finally deassert the chip select */
77913+ mvSpiCsDeassert();
77914+
77915+ return ret;
77916+}
77917+
77918+/*******************************************************************************
77919+* mvSpiWriteThenRead - Serialize a command then read a data buffer
77920+*
77921+* DESCRIPTION:
77922+* Assert the chip select line. Transmit the command buffer then read
77923+* the data buffer. Then deassert the CS line.
77924+*
77925+* INPUT:
77926+* pCmndBuff: Pointer to the command buffer to transmit
77927+* cmndSize: length of the command size
77928+* pRxDataBuff: Pointer to the buffer to read the data in
77929+* txDataSize: length of the data buffer
77930+*
77931+* OUTPUT:
77932+* pRxDataBuff: Pointer to the buffer holding the data
77933+*
77934+* RETURN:
77935+* Success or Error code.
77936+*
77937+*
77938+*******************************************************************************/
77939+MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,
77940+ MV_U32 rxDataSize,MV_U32 dummyBytesToRead)
77941+{
77942+ MV_STATUS ret = MV_OK, tempRet;
77943+ MV_U8 dummyByte;
77944+
77945+ /* check for null parameters */
77946+ if ((pCmndBuff == NULL) && (pRxDataBuff == NULL))
77947+ {
77948+ mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
77949+ return MV_BAD_PARAM;
77950+ }
77951+
77952+ /* First assert the chip select */
77953+ mvSpiCsAssert();
77954+
77955+ /* first write the command */
77956+ if ((cmndSize) && (pCmndBuff != NULL))
77957+ {
77958+ if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)
77959+ ret = tempRet;
77960+ }
77961+
77962+ /* Read dummy bytes before real data. */
77963+ while(dummyBytesToRead)
77964+ {
77965+ mvSpiRead(&dummyByte,1);
77966+ dummyBytesToRead--;
77967+ }
77968+
77969+ /* Then write the data buffer */
77970+ if ((rxDataSize) && (pRxDataBuff != NULL))
77971+ {
77972+ if ((tempRet = mvSpiRead(pRxDataBuff, rxDataSize)) != MV_OK)
77973+ ret = tempRet;
77974+ }
77975+
77976+ /* Finally deassert the chip select */
77977+ mvSpiCsDeassert();
77978+
77979+ return ret;
77980+}
77981+
77982diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h b/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h
77983new file mode 100644
77984index 0000000..329e26b
77985--- /dev/null
77986+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h
77987@@ -0,0 +1,82 @@
77988+/*******************************************************************************
77989+Copyright (C) Marvell International Ltd. and its affiliates
77990+
77991+This software file (the "File") is owned and distributed by Marvell
77992+International Ltd. and/or its affiliates ("Marvell") under the following
77993+alternative licensing terms. Once you have made an election to distribute the
77994+File under one of the following license alternatives, please (i) delete this
77995+introductory statement regarding license alternatives, (ii) delete the two
77996+license alternatives that you have not elected to use and (iii) preserve the
77997+Marvell copyright notice above.
77998+
77999+********************************************************************************
78000+Marvell Commercial License Option
78001+
78002+If you received this File from Marvell and you have entered into a commercial
78003+license agreement (a "Commercial License") with Marvell, the File is licensed
78004+to you under the terms of the applicable Commercial License.
78005+
78006+********************************************************************************
78007+Marvell GPL License Option
78008+
78009+If you received this File from Marvell, you may opt to use, redistribute and/or
78010+modify this File in accordance with the terms and conditions of the General
78011+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
78012+available along with the File in the license.txt file or by writing to the Free
78013+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
78014+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
78015+
78016+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
78017+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
78018+DISCLAIMED. The GPL License provides additional details about this warranty
78019+disclaimer.
78020+********************************************************************************
78021+Marvell BSD License Option
78022+
78023+If you received this File from Marvell, you may opt to use, redistribute and/or
78024+modify this File under the following licensing terms.
78025+Redistribution and use in source and binary forms, with or without modification,
78026+are permitted provided that the following conditions are met:
78027+
78028+ * Redistributions of source code must retain the above copyright notice,
78029+ this list of conditions and the following disclaimer.
78030+
78031+ * Redistributions in binary form must reproduce the above copyright
78032+ notice, this list of conditions and the following disclaimer in the
78033+ documentation and/or other materials provided with the distribution.
78034+
78035+ * Neither the name of Marvell nor the names of its contributors may be
78036+ used to endorse or promote products derived from this software without
78037+ specific prior written permission.
78038+
78039+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
78040+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
78041+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
78042+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
78043+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78044+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78045+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
78046+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78047+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
78048+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78049+
78050+*******************************************************************************/
78051+
78052+#ifndef __INCmvSpiCmndhH
78053+#define __INCmvSpiCmndhH
78054+
78055+#include "mvTypes.h"
78056+
78057+/* Function Prototypes */
78058+
78059+/* Simultanuous Read and write */
78060+MV_STATUS mvSpiReadAndWrite (MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);
78061+
78062+/* write command - write a command and then write data */
78063+MV_STATUS mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff, MV_U32 txDataSize);
78064+
78065+/* read command - write a command and then read data by writing dummy data */
78066+MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,
78067+ MV_U32 rxDataSize,MV_U32 dummyBytesToRead);
78068+
78069+#endif /* __INCmvSpiCmndhH */
78070diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h b/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h
78071new file mode 100644
78072index 0000000..e943787
78073--- /dev/null
78074+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h
78075@@ -0,0 +1,98 @@
78076+/*******************************************************************************
78077+Copyright (C) Marvell International Ltd. and its affiliates
78078+
78079+This software file (the "File") is owned and distributed by Marvell
78080+International Ltd. and/or its affiliates ("Marvell") under the following
78081+alternative licensing terms. Once you have made an election to distribute the
78082+File under one of the following license alternatives, please (i) delete this
78083+introductory statement regarding license alternatives, (ii) delete the two
78084+license alternatives that you have not elected to use and (iii) preserve the
78085+Marvell copyright notice above.
78086+
78087+********************************************************************************
78088+Marvell Commercial License Option
78089+
78090+If you received this File from Marvell and you have entered into a commercial
78091+license agreement (a "Commercial License") with Marvell, the File is licensed
78092+to you under the terms of the applicable Commercial License.
78093+
78094+********************************************************************************
78095+Marvell GPL License Option
78096+
78097+If you received this File from Marvell, you may opt to use, redistribute and/or
78098+modify this File in accordance with the terms and conditions of the General
78099+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
78100+available along with the File in the license.txt file or by writing to the Free
78101+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
78102+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
78103+
78104+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
78105+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
78106+DISCLAIMED. The GPL License provides additional details about this warranty
78107+disclaimer.
78108+********************************************************************************
78109+Marvell BSD License Option
78110+
78111+If you received this File from Marvell, you may opt to use, redistribute and/or
78112+modify this File under the following licensing terms.
78113+Redistribution and use in source and binary forms, with or without modification,
78114+are permitted provided that the following conditions are met:
78115+
78116+ * Redistributions of source code must retain the above copyright notice,
78117+ this list of conditions and the following disclaimer.
78118+
78119+ * Redistributions in binary form must reproduce the above copyright
78120+ notice, this list of conditions and the following disclaimer in the
78121+ documentation and/or other materials provided with the distribution.
78122+
78123+ * Neither the name of Marvell nor the names of its contributors may be
78124+ used to endorse or promote products derived from this software without
78125+ specific prior written permission.
78126+
78127+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
78128+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
78129+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
78130+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
78131+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78132+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78133+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
78134+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78135+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
78136+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78137+
78138+*******************************************************************************/
78139+
78140+#ifndef __INCmvSpiSpecH
78141+#define __INCmvSpiSpecH
78142+
78143+/* Constants */
78144+#define MV_SPI_WAIT_RDY_MAX_LOOP 100000
78145+#define MV_SPI_16_BIT_CHUNK_SIZE 2
78146+#define MV_SPI_DUMMY_WRITE_16BITS 0xFFFF
78147+#define MV_SPI_DUMMY_WRITE_8BITS 0xFF
78148+
78149+/* Marvell Flash Device Controller Registers */
78150+#define MV_SPI_CTRLR_OFST 0x10600
78151+#define MV_SPI_IF_CTRL_REG (MV_SPI_CTRLR_OFST + 0x00)
78152+#define MV_SPI_IF_CONFIG_REG (MV_SPI_CTRLR_OFST + 0x04)
78153+#define MV_SPI_DATA_OUT_REG (MV_SPI_CTRLR_OFST + 0x08)
78154+#define MV_SPI_DATA_IN_REG (MV_SPI_CTRLR_OFST + 0x0c)
78155+#define MV_SPI_INT_CAUSE_REG (MV_SPI_CTRLR_OFST + 0x10)
78156+#define MV_SPI_INT_CAUSE_MASK_REG (MV_SPI_CTRLR_OFST + 0x14)
78157+
78158+/* Serial Memory Interface Control Register Masks */
78159+#define MV_SPI_CS_ENABLE_OFFSET 0 /* bit 0 */
78160+#define MV_SPI_MEMORY_READY_OFFSET 1 /* bit 1 */
78161+#define MV_SPI_CS_ENABLE_MASK (0x1 << MV_SPI_CS_ENABLE_OFFSET)
78162+#define MV_SPI_MEMORY_READY_MASK (0x1 << MV_SPI_MEMORY_READY_OFFSET)
78163+
78164+/* Serial Memory Interface Configuration Register Masks */
78165+#define MV_SPI_CLK_PRESCALE_OFFSET 0 /* bit 0-4 */
78166+#define MV_SPI_BYTE_LENGTH_OFFSET 5 /* bit 5 */
78167+#define MV_SPI_ADDRESS_BURST_LENGTH_OFFSET 8 /* bit 8-9 */
78168+#define MV_SPI_CLK_PRESCALE_MASK (0x1F << MV_SPI_CLK_PRESCALE_OFFSET)
78169+#define MV_SPI_BYTE_LENGTH_MASK (0x1 << MV_SPI_BYTE_LENGTH_OFFSET)
78170+#define MV_SPI_ADDRESS_BURST_LENGTH_MASK (0x3 << MV_SPI_ADDRESS_BURST_LENGTH_OFFSET)
78171+
78172+#endif /* __INCmvSpiSpecH */
78173+
78174diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c b/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c
78175new file mode 100644
78176index 0000000..12d27b3
78177--- /dev/null
78178+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c
78179@@ -0,0 +1,1023 @@
78180+/*******************************************************************************
78181+Copyright (C) Marvell International Ltd. and its affiliates
78182+
78183+This software file (the "File") is owned and distributed by Marvell
78184+International Ltd. and/or its affiliates ("Marvell") under the following
78185+alternative licensing terms. Once you have made an election to distribute the
78186+File under one of the following license alternatives, please (i) delete this
78187+introductory statement regarding license alternatives, (ii) delete the two
78188+license alternatives that you have not elected to use and (iii) preserve the
78189+Marvell copyright notice above.
78190+
78191+********************************************************************************
78192+Marvell Commercial License Option
78193+
78194+If you received this File from Marvell and you have entered into a commercial
78195+license agreement (a "Commercial License") with Marvell, the File is licensed
78196+to you under the terms of the applicable Commercial License.
78197+
78198+********************************************************************************
78199+Marvell GPL License Option
78200+
78201+If you received this File from Marvell, you may opt to use, redistribute and/or
78202+modify this File in accordance with the terms and conditions of the General
78203+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
78204+available along with the File in the license.txt file or by writing to the Free
78205+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
78206+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
78207+
78208+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
78209+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
78210+DISCLAIMED. The GPL License provides additional details about this warranty
78211+disclaimer.
78212+********************************************************************************
78213+Marvell BSD License Option
78214+
78215+If you received this File from Marvell, you may opt to use, redistribute and/or
78216+modify this File under the following licensing terms.
78217+Redistribution and use in source and binary forms, with or without modification,
78218+are permitted provided that the following conditions are met:
78219+
78220+ * Redistributions of source code must retain the above copyright notice,
78221+ this list of conditions and the following disclaimer.
78222+
78223+ * Redistributions in binary form must reproduce the above copyright
78224+ notice, this list of conditions and the following disclaimer in the
78225+ documentation and/or other materials provided with the distribution.
78226+
78227+ * Neither the name of Marvell nor the names of its contributors may be
78228+ used to endorse or promote products derived from this software without
78229+ specific prior written permission.
78230+
78231+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
78232+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
78233+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
78234+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
78235+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78236+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78237+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
78238+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78239+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
78240+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78241+
78242+*******************************************************************************/
78243+
78244+
78245+#include "mvTwsi.h"
78246+#include "mvTwsiSpec.h"
78247+#include "cpu/mvCpu.h"
78248+
78249+
78250+/*#define MV_DEBUG*/
78251+#ifdef MV_DEBUG
78252+#define DB(x) x
78253+#else
78254+#define DB(x)
78255+#endif
78256+
78257+static MV_VOID twsiIntFlgClr(MV_U8 chanNum);
78258+static MV_BOOL twsiMainIntGet(MV_U8 chanNum);
78259+static MV_VOID twsiAckBitSet(MV_U8 chanNum);
78260+static MV_U32 twsiStsGet(MV_U8 chanNum);
78261+static MV_VOID twsiReset(MV_U8 chanNum);
78262+static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);
78263+static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);
78264+static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);
78265+static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);
78266+static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset,MV_BOOL moreThen256);
78267+
78268+
78269+static MV_BOOL twsiTimeoutChk(MV_U32 timeout, const MV_8 *pString)
78270+{
78271+ if(timeout >= TWSI_TIMEOUT_VALUE)
78272+ {
78273+ DB(mvOsPrintf("%s",pString));
78274+ return MV_TRUE;
78275+ }
78276+ return MV_FALSE;
78277+
78278+}
78279+/*******************************************************************************
78280+* mvTwsiStartBitSet - Set start bit on the bus
78281+*
78282+* DESCRIPTION:
78283+* This routine sets the start bit on the TWSI bus.
78284+* The routine first checks for interrupt flag condition, then it sets
78285+* the start bit in the TWSI Control register.
78286+* If the interrupt flag condition check previously was set, the function
78287+* will clear it.
78288+* The function then wait for the start bit to be cleared by the HW.
78289+* Then it waits for the interrupt flag to be set and eventually, the
78290+* TWSI status is checked to be 0x8 or 0x10(repeated start bit).
78291+*
78292+* INPUT:
78293+* chanNum - TWSI channel.
78294+*
78295+* OUTPUT:
78296+* None.
78297+*
78298+* RETURN:
78299+* MV_OK is start bit was set successfuly on the bus.
78300+* MV_FAIL if interrupt flag was set before setting start bit.
78301+*
78302+*******************************************************************************/
78303+MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum)
78304+{
78305+ MV_BOOL isIntFlag = MV_FALSE;
78306+ MV_U32 timeout, temp;
78307+
78308+ DB(mvOsPrintf("TWSI: mvTwsiStartBitSet \n"));
78309+ /* check Int flag */
78310+ if(twsiMainIntGet(chanNum))
78311+ isIntFlag = MV_TRUE;
78312+ /* set start Bit */
78313+ temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
78314+ MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_START_BIT);
78315+
78316+ /* in case that the int flag was set before i.e. repeated start bit */
78317+ if(isIntFlag){
78318+ DB(mvOsPrintf("TWSI: mvTwsiStartBitSet repeated start Bit\n"));
78319+ twsiIntFlgClr(chanNum);
78320+ }
78321+
78322+ /* wait for interrupt */
78323+ timeout = 0;
78324+ while(!twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
78325+
78326+ /* check for timeout */
78327+ if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStartBitSet ERROR - Start Clear bit TimeOut .\n"))
78328+ return MV_TIMEOUT;
78329+
78330+
78331+ /* check that start bit went down */
78332+ if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_START_BIT) != 0)
78333+ {
78334+ mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - start bit didn't went down\n");
78335+ return MV_FAIL;
78336+ }
78337+
78338+ /* check the status */
78339+ temp = twsiStsGet(chanNum);
78340+ if(( temp != TWSI_START_CON_TRA ) && ( temp != TWSI_REPEATED_START_CON_TRA ))
78341+ {
78342+ mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - status %x after Set Start Bit. \n",temp);
78343+ return MV_FAIL;
78344+ }
78345+
78346+ return MV_OK;
78347+
78348+}
78349+
78350+/*******************************************************************************
78351+* mvTwsiStopBitSet - Set stop bit on the bus
78352+*
78353+* DESCRIPTION:
78354+* This routine set the stop bit on the TWSI bus.
78355+* The function then wait for the stop bit to be cleared by the HW.
78356+* Finally the function checks for status of 0xF8.
78357+*
78358+* INPUT:
78359+* chanNum - TWSI channel
78360+*
78361+* OUTPUT:
78362+* None.
78363+*
78364+* RETURN:
78365+* MV_TRUE is stop bit was set successfuly on the bus.
78366+*
78367+*******************************************************************************/
78368+MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum)
78369+{
78370+ MV_U32 timeout, temp;
78371+
78372+ /* Generate stop bit */
78373+ temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
78374+ MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_STOP_BIT);
78375+
78376+ twsiIntFlgClr(chanNum);
78377+
78378+ /* wait for stop bit to come down */
78379+ timeout = 0;
78380+ while( ((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0) && (timeout++ < TWSI_TIMEOUT_VALUE));
78381+
78382+ /* check for timeout */
78383+ if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStopBitSet ERROR - Stop bit TimeOut .\n"))
78384+ return MV_TIMEOUT;
78385+
78386+ /* check that the stop bit went down */
78387+ if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0)
78388+ {
78389+ mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - stop bit didn't went down. \n");
78390+ return MV_FAIL;
78391+ }
78392+
78393+ /* check the status */
78394+ temp = twsiStsGet(chanNum);
78395+ if( temp != TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0){
78396+ mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - status %x after Stop Bit. \n", temp);
78397+ return MV_FAIL;
78398+ }
78399+
78400+ return MV_OK;
78401+}
78402+
78403+/*******************************************************************************
78404+* twsiMainIntGet - Get twsi bit from main Interrupt cause.
78405+*
78406+* DESCRIPTION:
78407+* This routine returns the twsi interrupt flag value.
78408+*
78409+* INPUT:
78410+* None.
78411+*
78412+* OUTPUT:
78413+* None.
78414+*
78415+* RETURN:
78416+* MV_TRUE is interrupt flag is set, MV_FALSE otherwise.
78417+*
78418+*******************************************************************************/
78419+static MV_BOOL twsiMainIntGet(MV_U8 chanNum)
78420+{
78421+ MV_U32 temp;
78422+
78423+ /* get the int flag bit */
78424+
78425+ temp = MV_REG_READ(TWSI_CPU_MAIN_INT_CAUSE_REG);
78426+ if (temp & (TWSI0_CPU_MAIN_INT_BIT << chanNum))
78427+ return MV_TRUE;
78428+
78429+ return MV_FALSE;
78430+}
78431+/*******************************************************************************
78432+* twsiIntFlgClr - Clear Interrupt flag.
78433+*
78434+* DESCRIPTION:
78435+* This routine clears the interrupt flag. It does NOT poll the interrupt
78436+* to make sure the clear. After clearing the interrupt, it waits for at
78437+* least 1 miliseconds.
78438+*
78439+* INPUT:
78440+* chanNum - TWSI channel
78441+*
78442+* OUTPUT:
78443+* None.
78444+*
78445+* RETURN:
78446+* None.
78447+*
78448+*******************************************************************************/
78449+static MV_VOID twsiIntFlgClr(MV_U8 chanNum)
78450+{
78451+ MV_U32 temp;
78452+
78453+ /* wait for 1 mili to prevent TWSI register write after write problems */
78454+ mvOsDelay(1);
78455+ /* clear the int flag bit */
78456+ temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
78457+ MV_REG_WRITE(TWSI_CONTROL_REG(chanNum),temp & ~(TWSI_CONTROL_INT_FLAG_SET));
78458+
78459+ /* wait for 1 mili sec for the clear to take effect */
78460+ mvOsDelay(1);
78461+
78462+ return;
78463+}
78464+
78465+
78466+/*******************************************************************************
78467+* twsiAckBitSet - Set acknowledge bit on the bus
78468+*
78469+* DESCRIPTION:
78470+* This routine set the acknowledge bit on the TWSI bus.
78471+*
78472+* INPUT:
78473+* None.
78474+*
78475+* OUTPUT:
78476+* None.
78477+*
78478+* RETURN:
78479+* None.
78480+*
78481+*******************************************************************************/
78482+static MV_VOID twsiAckBitSet(MV_U8 chanNum)
78483+{
78484+ MV_U32 temp;
78485+
78486+ /*Set the Ack bit */
78487+ temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
78488+ MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_ACK);
78489+
78490+ /* Add delay of 1ms */
78491+ mvOsDelay(1);
78492+ return;
78493+}
78494+
78495+
78496+/*******************************************************************************
78497+* twsiInit - Initialize TWSI interface
78498+*
78499+* DESCRIPTION:
78500+* This routine:
78501+* -Reset the TWSI.
78502+* -Initialize the TWSI clock baud rate according to given frequancy
78503+* parameter based on Tclk frequancy and enables TWSI slave.
78504+* -Set the ack bit.
78505+* -Assign the TWSI slave address according to the TWSI address Type.
78506+*
78507+*
78508+* INPUT:
78509+* chanNum - TWSI channel
78510+* frequancy - TWSI frequancy in KHz. (up to 100KHZ)
78511+*
78512+* OUTPUT:
78513+* None.
78514+*
78515+* RETURN:
78516+* Actual frequancy.
78517+*
78518+*******************************************************************************/
78519+MV_U32 mvTwsiInit(MV_U8 chanNum, MV_HZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *pTwsiAddr, MV_BOOL generalCallEnable)
78520+{
78521+ MV_U32 n,m,freq,margin,minMargin = 0xffffffff;
78522+ MV_U32 power;
78523+ MV_U32 actualFreq = 0,actualN = 0,actualM = 0,val;
78524+
78525+ if(frequancy > 100000)
78526+ {
78527+ mvOsPrintf("Warning TWSI frequancy is too high, please use up tp 100Khz. \n");
78528+ }
78529+
78530+ DB(mvOsPrintf("TWSI: mvTwsiInit - Tclk = %d freq = %d\n",Tclk,frequancy));
78531+ /* Calucalte N and M for the TWSI clock baud rate */
78532+ for(n = 0 ; n < 8 ; n++)
78533+ {
78534+ for(m = 0 ; m < 16 ; m++)
78535+ {
78536+ power = 2 << n; /* power = 2^(n+1) */
78537+ freq = Tclk/(10*(m+1)*power);
78538+ margin = MV_ABS(frequancy - freq);
78539+ if(margin < minMargin)
78540+ {
78541+ minMargin = margin;
78542+ actualFreq = freq;
78543+ actualN = n;
78544+ actualM = m;
78545+ }
78546+ }
78547+ }
78548+ DB(mvOsPrintf("TWSI: mvTwsiInit - actN %d actM %d actFreq %d\n",actualN , actualM, actualFreq));
78549+ /* Reset the TWSI logic */
78550+ twsiReset(chanNum);
78551+
78552+ /* Set the baud rate */
78553+ val = ((actualM<< TWSI_BAUD_RATE_M_OFFS) | actualN << TWSI_BAUD_RATE_N_OFFS);
78554+ MV_REG_WRITE(TWSI_STATUS_BAUDE_RATE_REG(chanNum),val);
78555+
78556+ /* Enable the TWSI and slave */
78557+ MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), TWSI_CONTROL_ENA | TWSI_CONTROL_ACK);
78558+
78559+ /* set the TWSI slave address */
78560+ if( pTwsiAddr->type == ADDR10_BIT )/* 10 Bit deviceAddress */
78561+ {
78562+ /* writing the 2 most significant bits of the 10 bit address*/
78563+ val = ((pTwsiAddr->address & TWSI_SLAVE_ADDR_10BIT_MASK) >> TWSI_SLAVE_ADDR_10BIT_OFFS );
78564+ /* bits 7:3 must be 0x11110 */
78565+ val |= TWSI_SLAVE_ADDR_10BIT_CONST;
78566+ /* set GCE bit */
78567+ if(generalCallEnable)
78568+ val |= TWSI_SLAVE_ADDR_GCE_ENA;
78569+ /* write slave address */
78570+ MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum),val);
78571+
78572+ /* writing the 8 least significant bits of the 10 bit address*/
78573+ val = (pTwsiAddr->address << TWSI_EXTENDED_SLAVE_OFFS) & TWSI_EXTENDED_SLAVE_MASK;
78574+ MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum), val);
78575+ }
78576+ else /*7 bit address*/
78577+ {
78578+ /* set the 7 Bits address */
78579+ MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum),0x0);
78580+ val = (pTwsiAddr->address << TWSI_SLAVE_ADDR_7BIT_OFFS) & TWSI_SLAVE_ADDR_7BIT_MASK;
78581+ MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum), val);
78582+ }
78583+
78584+ /* unmask twsi int */
78585+ val = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
78586+ MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), val | TWSI_CONTROL_INT_ENA);
78587+ /* Add delay of 1ms */
78588+ mvOsDelay(1);
78589+
78590+ return actualFreq;
78591+}
78592+
78593+
78594+/*******************************************************************************
78595+* twsiStsGet - Get the TWSI status value.
78596+*
78597+* DESCRIPTION:
78598+* This routine returns the TWSI status value.
78599+*
78600+* INPUT:
78601+* chanNum - TWSI channel
78602+*
78603+* OUTPUT:
78604+* None.
78605+*
78606+* RETURN:
78607+* MV_U32 - the TWSI status.
78608+*
78609+*******************************************************************************/
78610+static MV_U32 twsiStsGet(MV_U8 chanNum)
78611+{
78612+ return MV_REG_READ(TWSI_STATUS_BAUDE_RATE_REG(chanNum));
78613+
78614+}
78615+
78616+/*******************************************************************************
78617+* twsiReset - Reset the TWSI.
78618+*
78619+* DESCRIPTION:
78620+* Resets the TWSI logic and sets all TWSI registers to their reset values.
78621+*
78622+* INPUT:
78623+* chanNum - TWSI channel
78624+*
78625+* OUTPUT:
78626+* None.
78627+*
78628+* RETURN:
78629+* None
78630+*
78631+*******************************************************************************/
78632+static MV_VOID twsiReset(MV_U8 chanNum)
78633+{
78634+ /* Reset the TWSI logic */
78635+ MV_REG_WRITE(TWSI_SOFT_RESET_REG(chanNum),0);
78636+
78637+ /* wait for 2 mili sec */
78638+ mvOsDelay(2);
78639+
78640+ return;
78641+}
78642+
78643+
78644+
78645+
78646+/******************************* POLICY ****************************************/
78647+
78648+
78649+
78650+/*******************************************************************************
78651+* mvTwsiAddrSet - Set address on TWSI bus.
78652+*
78653+* DESCRIPTION:
78654+* This function Set address (7 or 10 Bit address) on the Twsi Bus.
78655+*
78656+* INPUT:
78657+* chanNum - TWSI channel
78658+* pTwsiAddr - twsi address.
78659+* command - read / write .
78660+*
78661+* OUTPUT:
78662+* None.
78663+*
78664+* RETURN:
78665+* MV_OK - if setting the address completed succesfully.
78666+* MV_FAIL otherwmise.
78667+*
78668+*******************************************************************************/
78669+MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *pTwsiAddr, MV_TWSI_CMD command)
78670+{
78671+ DB(mvOsPrintf("TWSI: mvTwsiAddr7BitSet addr %x , type %d, cmd is %s\n",pTwsiAddr->address,\
78672+ pTwsiAddr->type, ((command==MV_TWSI_WRITE)?"Write":"Read") ));
78673+ /* 10 Bit address */
78674+ if(pTwsiAddr->type == ADDR10_BIT)
78675+ {
78676+ return twsiAddr10BitSet(chanNum, pTwsiAddr->address,command);
78677+ }
78678+ /* 7 Bit address */
78679+ else
78680+ {
78681+ return twsiAddr7BitSet(chanNum, pTwsiAddr->address,command);
78682+ }
78683+
78684+}
78685+
78686+/*******************************************************************************
78687+* twsiAddr10BitSet - Set 10 Bit address on TWSI bus.
78688+*
78689+* DESCRIPTION:
78690+* There are two address phases:
78691+* 1) Write '11110' to data register bits [7:3] and 10-bit address MSB
78692+* (bits [9:8]) to data register bits [2:1] plus a write(0) or read(1) bit
78693+* to the Data register. Then it clears interrupt flag which drive
78694+* the address on the TWSI bus. The function then waits for interrupt
78695+* flag to be active and status 0x18 (write) or 0x40 (read) to be set.
78696+* 2) write the rest of 10-bit address to data register and clears
78697+* interrupt flag which drive the address on the TWSI bus. The
78698+* function then waits for interrupt flag to be active and status
78699+* 0xD0 (write) or 0xE0 (read) to be set.
78700+*
78701+* INPUT:
78702+* chanNum - TWSI channel
78703+* deviceAddress - twsi address.
78704+* command - read / write .
78705+*
78706+* OUTPUT:
78707+* None.
78708+*
78709+* RETURN:
78710+* MV_OK - if setting the address completed succesfully.
78711+* MV_FAIL otherwmise.
78712+*
78713+*******************************************************************************/
78714+static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)
78715+{
78716+ MV_U32 val,timeout;
78717+
78718+ /* writing the 2 most significant bits of the 10 bit address*/
78719+ val = ((deviceAddress & TWSI_DATA_ADDR_10BIT_MASK) >> TWSI_DATA_ADDR_10BIT_OFFS );
78720+ /* bits 7:3 must be 0x11110 */
78721+ val |= TWSI_DATA_ADDR_10BIT_CONST;
78722+ /* set command */
78723+ val |= command;
78724+ MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
78725+ /* WA add a delay */
78726+ mvOsDelay(1);
78727+
78728+ /* clear Int flag */
78729+ twsiIntFlgClr(chanNum);
78730+
78731+ /* wait for Int to be Set */
78732+ timeout = 0;
78733+ while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
78734+
78735+ /* check for timeout */
78736+ if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 1st addr (10Bit) Int TimeOut.\n"))
78737+ return MV_TIMEOUT;
78738+
78739+ /* check the status */
78740+ val = twsiStsGet(chanNum);
78741+ if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
78742+ ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
78743+ {
78744+ mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 1st addr (10 Bit) in %s mode.\n"\
78745+ ,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );
78746+ return MV_FAIL;
78747+ }
78748+
78749+ /* set 8 LSB of the address */
78750+ val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;
78751+ MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
78752+
78753+ /* clear Int flag */
78754+ twsiIntFlgClr(chanNum);
78755+
78756+ /* wait for Int to be Set */
78757+ timeout = 0;
78758+ while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
78759+
78760+ /* check for timeout */
78761+ if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 2nd (10 Bit) Int TimOut.\n"))
78762+ return MV_TIMEOUT;
78763+
78764+ /* check the status */
78765+ val = twsiStsGet(chanNum);
78766+ if(( (val != TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
78767+ ( (val != TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
78768+ {
78769+ mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 2nd addr(10 Bit) in %s mode.\n"\
78770+ ,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );
78771+ return MV_FAIL;
78772+ }
78773+
78774+ return MV_OK;
78775+}
78776+
78777+/*******************************************************************************
78778+* twsiAddr7BitSet - Set 7 Bit address on TWSI bus.
78779+*
78780+* DESCRIPTION:
78781+* This function writes 7 bit address plus a write or read bit to the
78782+* Data register. Then it clears interrupt flag which drive the address on
78783+* the TWSI bus. The function then waits for interrupt flag to be active
78784+* and status 0x18 (write) or 0x40 (read) to be set.
78785+*
78786+* INPUT:
78787+* chanNum - TWSI channel
78788+* deviceAddress - twsi address.
78789+* command - read / write .
78790+*
78791+* OUTPUT:
78792+* None.
78793+*
78794+* RETURN:
78795+* MV_OK - if setting the address completed succesfully.
78796+* MV_FAIL otherwmise.
78797+*
78798+*******************************************************************************/
78799+static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)
78800+{
78801+ MV_U32 val,timeout;
78802+
78803+ /* set the address */
78804+ val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;
78805+ /* set command */
78806+ val |= command;
78807+ MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
78808+ /* WA add a delay */
78809+ mvOsDelay(1);
78810+
78811+ /* clear Int flag */
78812+ twsiIntFlgClr(chanNum);
78813+
78814+ /* wait for Int to be Set */
78815+ timeout = 0;
78816+ while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
78817+
78818+ /* check for timeout */
78819+ if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr7BitSet ERROR - Addr (7 Bit) int TimeOut.\n"))
78820+ return MV_TIMEOUT;
78821+
78822+ /* check the status */
78823+ val = twsiStsGet(chanNum);
78824+ if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
78825+ ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
78826+ {
78827+ /* only in debug, since in boot we try to read the SPD of both DRAM, and we don't
78828+ want error messeges in case DIMM doesn't exist. */
78829+ DB(mvOsPrintf("TWSI: twsiAddr7BitSet ERROR - status %x addr (7 Bit) in %s mode.\n"\
78830+ ,val,((command==MV_TWSI_WRITE)?"Write":"Read") ));
78831+ return MV_FAIL;
78832+ }
78833+
78834+ return MV_OK;
78835+}
78836+
78837+/*******************************************************************************
78838+* twsiDataWrite - Trnasmit a data block over TWSI bus.
78839+*
78840+* DESCRIPTION:
78841+* This function writes a given data block to TWSI bus in 8 bit granularity.
78842+* first The function waits for interrupt flag to be active then
78843+* For each 8-bit data:
78844+* The function writes data to data register. It then clears
78845+* interrupt flag which drives the data on the TWSI bus.
78846+* The function then waits for interrupt flag to be active and status
78847+* 0x28 to be set.
78848+*
78849+*
78850+* INPUT:
78851+* chanNum - TWSI channel
78852+* pBlock - Data block.
78853+* blockSize - number of chars in pBlock.
78854+*
78855+* OUTPUT:
78856+* None.
78857+*
78858+* RETURN:
78859+* MV_OK - if transmiting the block completed succesfully,
78860+* MV_BAD_PARAM - if pBlock is NULL,
78861+* MV_FAIL otherwmise.
78862+*
78863+*******************************************************************************/
78864+static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)
78865+{
78866+ MV_U32 timeout, temp, blockSizeWr = blockSize;
78867+
78868+ if(NULL == pBlock)
78869+ return MV_BAD_PARAM;
78870+
78871+ /* wait for Int to be Set */
78872+ timeout = 0;
78873+ while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
78874+
78875+ /* check for timeout */
78876+ if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))
78877+ return MV_TIMEOUT;
78878+
78879+ while(blockSizeWr)
78880+ {
78881+ /* write the data*/
78882+ MV_REG_WRITE(TWSI_DATA_REG(chanNum),(MV_U32)*pBlock);
78883+ DB(mvOsPrintf("TWSI: twsiDataTransmit place = %d write %x \n",\
78884+ blockSize - blockSizeWr, *pBlock));
78885+ pBlock++;
78886+ blockSizeWr--;
78887+
78888+ twsiIntFlgClr(chanNum);
78889+
78890+ /* wait for Int to be Set */
78891+ timeout = 0;
78892+ while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
78893+
78894+ /* check for timeout */
78895+ if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))
78896+ return MV_TIMEOUT;
78897+
78898+ /* check the status */
78899+ temp = twsiStsGet(chanNum);
78900+ if(temp != TWSI_M_TRAN_DATA_BYTE_ACK_REC)
78901+ {
78902+ mvOsPrintf("TWSI: twsiDataTransmit ERROR - status %x in write trans\n",temp);
78903+ return MV_FAIL;
78904+ }
78905+
78906+ }
78907+
78908+ return MV_OK;
78909+}
78910+
78911+/*******************************************************************************
78912+* twsiDataReceive - Receive data block from TWSI bus.
78913+*
78914+* DESCRIPTION:
78915+* This function receive data block from TWSI bus in 8bit granularity
78916+* into pBlock buffer.
78917+* first The function waits for interrupt flag to be active then
78918+* For each 8-bit data:
78919+* It clears the interrupt flag which allows the next data to be
78920+* received from TWSI bus.
78921+* The function waits for interrupt flag to be active,
78922+* and status reg is 0x50.
78923+* Then the function reads data from data register, and copies it to
78924+* the given buffer.
78925+*
78926+* INPUT:
78927+* chanNum - TWSI channel
78928+* blockSize - number of bytes to read.
78929+*
78930+* OUTPUT:
78931+* pBlock - Data block.
78932+*
78933+* RETURN:
78934+* MV_OK - if receive transaction completed succesfully,
78935+* MV_BAD_PARAM - if pBlock is NULL,
78936+* MV_FAIL otherwmise.
78937+*
78938+*******************************************************************************/
78939+static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)
78940+{
78941+ MV_U32 timeout, temp, blockSizeRd = blockSize;
78942+ if(NULL == pBlock)
78943+ return MV_BAD_PARAM;
78944+
78945+ /* wait for Int to be Set */
78946+ timeout = 0;
78947+ while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
78948+
78949+ /* check for timeout */
78950+ if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data int Time out .\n"))
78951+ return MV_TIMEOUT;
78952+
78953+ while(blockSizeRd)
78954+ {
78955+ if(blockSizeRd == 1)
78956+ {
78957+ /* clear ack and Int flag */
78958+ temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
78959+ temp &= ~(TWSI_CONTROL_ACK);
78960+ MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp);
78961+ }
78962+ twsiIntFlgClr(chanNum);
78963+ /* wait for Int to be Set */
78964+ timeout = 0;
78965+ while( (!twsiMainIntGet(chanNum)) && (timeout++ < TWSI_TIMEOUT_VALUE));
78966+
78967+ /* check for timeout */
78968+ if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data Int Time out .\n"))
78969+ return MV_TIMEOUT;
78970+
78971+ /* check the status */
78972+ temp = twsiStsGet(chanNum);
78973+ if((temp != TWSI_M_REC_RD_DATA_ACK_TRA) && (blockSizeRd !=1))
78974+ {
78975+ mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in read trans \n",temp);
78976+ return MV_FAIL;
78977+ }
78978+ else if((temp != TWSI_M_REC_RD_DATA_ACK_NOT_TRA) && (blockSizeRd ==1))
78979+ {
78980+ mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in Rd Terminate\n",temp);
78981+ return MV_FAIL;
78982+ }
78983+
78984+ /* read the data*/
78985+ *pBlock = (MV_U8)MV_REG_READ(TWSI_DATA_REG(chanNum));
78986+ DB(mvOsPrintf("TWSI: twsiDataReceive place %d read %x \n",\
78987+ blockSize - blockSizeRd,*pBlock));
78988+ pBlock++;
78989+ blockSizeRd--;
78990+ }
78991+
78992+ return MV_OK;
78993+}
78994+
78995+
78996+
78997+/*******************************************************************************
78998+* twsiTargetOffsSet - Set TWST target offset on TWSI bus.
78999+*
79000+* DESCRIPTION:
79001+* The function support TWSI targets that have inside address space (for
79002+* example EEPROMs). The function:
79003+* 1) Convert the given offset into pBlock and size.
79004+* in case the offset should be set to a TWSI slave which support
79005+* more then 256 bytes offset, the offset setting will be done
79006+* in 2 transactions.
79007+* 2) Use twsiDataTransmit to place those on the bus.
79008+*
79009+* INPUT:
79010+* chanNum - TWSI channel
79011+* offset - offset to be set on the EEPROM device.
79012+* moreThen256 - whether the EEPROM device support more then 256 byte offset.
79013+*
79014+* OUTPUT:
79015+* None.
79016+*
79017+* RETURN:
79018+* MV_OK - if setting the offset completed succesfully.
79019+* MV_FAIL otherwmise.
79020+*
79021+*******************************************************************************/
79022+static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset, MV_BOOL moreThen256)
79023+{
79024+ MV_U8 offBlock[2];
79025+ MV_U32 offSize;
79026+
79027+ if(moreThen256 == MV_TRUE)
79028+ {
79029+ offBlock[0] = (offset >> 8) & 0xff;
79030+ offBlock[1] = offset & 0xff;
79031+ offSize = 2;
79032+ }
79033+ else
79034+ {
79035+ offBlock[0] = offset & 0xff;
79036+ offSize = 1;
79037+ }
79038+ DB(mvOsPrintf("TWSI: twsiTargetOffsSet offSize = %x addr1 = %x addr2 = %x\n",\
79039+ offSize,offBlock[0],offBlock[1]));
79040+ return twsiDataTransmit(chanNum, offBlock, offSize);
79041+
79042+}
79043+
79044+/*******************************************************************************
79045+* mvTwsiRead - Read data block from a TWSI Slave.
79046+*
79047+* DESCRIPTION:
79048+* The function calls the following functions:
79049+* -) mvTwsiStartBitSet();
79050+* if(EEPROM device)
79051+* -) mvTwsiAddrSet(w);
79052+* -) twsiTargetOffsSet();
79053+* -) mvTwsiStartBitSet();
79054+* -) mvTwsiAddrSet(r);
79055+* -) twsiDataReceive();
79056+* -) mvTwsiStopBitSet();
79057+*
79058+* INPUT:
79059+* chanNum - TWSI channel
79060+* pTwsiSlave - Twsi Slave structure.
79061+* blockSize - number of bytes to read.
79062+*
79063+* OUTPUT:
79064+* pBlock - Data block.
79065+*
79066+* RETURN:
79067+* MV_OK - if EEPROM read transaction completed succesfully,
79068+* MV_BAD_PARAM - if pBlock is NULL,
79069+* MV_FAIL otherwmise.
79070+*
79071+*******************************************************************************/
79072+MV_STATUS mvTwsiRead(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)
79073+{
79074+ if((NULL == pBlock) || (NULL == pTwsiSlave))
79075+ return MV_BAD_PARAM;
79076+ if(MV_OK != mvTwsiStartBitSet(chanNum))
79077+ {
79078+ mvTwsiStopBitSet(chanNum);
79079+ return MV_FAIL;
79080+ }
79081+
79082+ DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));
79083+
79084+ /* in case offset exsist (i.e. eeprom ) */
79085+ if(MV_TRUE == pTwsiSlave->validOffset)
79086+ {
79087+ if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE))
79088+ {
79089+ mvTwsiStopBitSet(chanNum);
79090+ return MV_FAIL;
79091+ }
79092+ DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));
79093+ if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256))
79094+ {
79095+ mvTwsiStopBitSet(chanNum);
79096+ return MV_FAIL;
79097+ }
79098+ DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiTargetOffsSet\n"));
79099+ if(MV_OK != mvTwsiStartBitSet(chanNum))
79100+ {
79101+ mvTwsiStopBitSet(chanNum);
79102+ return MV_FAIL;
79103+ }
79104+ DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));
79105+ }
79106+ if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_READ))
79107+ {
79108+ mvTwsiStopBitSet(chanNum);
79109+ return MV_FAIL;
79110+ }
79111+ DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));
79112+ if(MV_OK != twsiDataReceive(chanNum, pBlock, blockSize))
79113+ {
79114+ mvTwsiStopBitSet(chanNum);
79115+ return MV_FAIL;
79116+ }
79117+ DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiDataReceive\n"));
79118+
79119+ if(MV_OK != mvTwsiStopBitSet(chanNum))
79120+ {
79121+ return MV_FAIL;
79122+ }
79123+
79124+ twsiAckBitSet(chanNum);
79125+
79126+ DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStopBitSet\n"));
79127+
79128+ return MV_OK;
79129+}
79130+
79131+/*******************************************************************************
79132+* mvTwsiWrite - Write data block to a TWSI Slave.
79133+*
79134+* DESCRIPTION:
79135+* The function calls the following functions:
79136+* -) mvTwsiStartBitSet();
79137+* -) mvTwsiAddrSet();
79138+* -)if(EEPROM device)
79139+* -) twsiTargetOffsSet();
79140+* -) twsiDataTransmit();
79141+* -) mvTwsiStopBitSet();
79142+*
79143+* INPUT:
79144+* chanNum - TWSI channel
79145+* eepromAddress - eeprom address.
79146+* blockSize - number of bytes to write.
79147+* pBlock - Data block.
79148+*
79149+* OUTPUT:
79150+* None
79151+*
79152+* RETURN:
79153+* MV_OK - if EEPROM read transaction completed succesfully.
79154+* MV_BAD_PARAM - if pBlock is NULL,
79155+* MV_FAIL otherwmise.
79156+*
79157+* NOTE: Part of the EEPROM, required that the offset will be aligned to the
79158+* max write burst supported.
79159+*******************************************************************************/
79160+MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)
79161+{
79162+ if((NULL == pBlock) || (NULL == pTwsiSlave))
79163+ return MV_BAD_PARAM;
79164+
79165+ if(MV_OK != mvTwsiStartBitSet(chanNum))
79166+ {
79167+ mvTwsiStopBitSet(chanNum);
79168+ return MV_FAIL;
79169+ }
79170+
79171+ DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStartBitSet\n"));
79172+ if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE))
79173+ {
79174+ mvTwsiStopBitSet(chanNum);
79175+ return MV_FAIL;
79176+ }
79177+ DB(mvOsPrintf("TWSI :mvTwsiEepromWrite after mvTwsiAddrSet\n"));
79178+
79179+ /* in case offset exsist (i.e. eeprom ) */
79180+ if(MV_TRUE == pTwsiSlave->validOffset)
79181+ {
79182+ if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256))
79183+ {
79184+ mvTwsiStopBitSet(chanNum);
79185+ return MV_FAIL;
79186+ }
79187+ DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiTargetOffsSet\n"));
79188+ }
79189+ if(MV_OK != twsiDataTransmit(chanNum, pBlock, blockSize))
79190+ {
79191+ mvTwsiStopBitSet(chanNum);
79192+ return MV_FAIL;
79193+ }
79194+ DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiDataTransmit\n"));
79195+ if(MV_OK != mvTwsiStopBitSet(chanNum))
79196+ {
79197+ return MV_FAIL;
79198+ }
79199+ DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStopBitSet\n"));
79200+
79201+ return MV_OK;
79202+}
79203diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h b/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h
79204new file mode 100644
79205index 0000000..c3eddd1
79206--- /dev/null
79207+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h
79208@@ -0,0 +1,121 @@
79209+/*******************************************************************************
79210+Copyright (C) Marvell International Ltd. and its affiliates
79211+
79212+This software file (the "File") is owned and distributed by Marvell
79213+International Ltd. and/or its affiliates ("Marvell") under the following
79214+alternative licensing terms. Once you have made an election to distribute the
79215+File under one of the following license alternatives, please (i) delete this
79216+introductory statement regarding license alternatives, (ii) delete the two
79217+license alternatives that you have not elected to use and (iii) preserve the
79218+Marvell copyright notice above.
79219+
79220+********************************************************************************
79221+Marvell Commercial License Option
79222+
79223+If you received this File from Marvell and you have entered into a commercial
79224+license agreement (a "Commercial License") with Marvell, the File is licensed
79225+to you under the terms of the applicable Commercial License.
79226+
79227+********************************************************************************
79228+Marvell GPL License Option
79229+
79230+If you received this File from Marvell, you may opt to use, redistribute and/or
79231+modify this File in accordance with the terms and conditions of the General
79232+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
79233+available along with the File in the license.txt file or by writing to the Free
79234+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
79235+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
79236+
79237+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
79238+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
79239+DISCLAIMED. The GPL License provides additional details about this warranty
79240+disclaimer.
79241+********************************************************************************
79242+Marvell BSD License Option
79243+
79244+If you received this File from Marvell, you may opt to use, redistribute and/or
79245+modify this File under the following licensing terms.
79246+Redistribution and use in source and binary forms, with or without modification,
79247+are permitted provided that the following conditions are met:
79248+
79249+ * Redistributions of source code must retain the above copyright notice,
79250+ this list of conditions and the following disclaimer.
79251+
79252+ * Redistributions in binary form must reproduce the above copyright
79253+ notice, this list of conditions and the following disclaimer in the
79254+ documentation and/or other materials provided with the distribution.
79255+
79256+ * Neither the name of Marvell nor the names of its contributors may be
79257+ used to endorse or promote products derived from this software without
79258+ specific prior written permission.
79259+
79260+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
79261+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
79262+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
79263+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
79264+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
79265+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
79266+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
79267+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
79268+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
79269+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79270+
79271+*******************************************************************************/
79272+#ifndef __INCmvTwsiH
79273+#define __INCmvTwsiH
79274+
79275+#ifdef __cplusplus
79276+extern "C" {
79277+#endif /* __cplusplus */
79278+
79279+/* need to update this includes */
79280+#include "twsi/mvTwsiSpec.h"
79281+#include "ctrlEnv/mvCtrlEnvLib.h"
79282+
79283+
79284+/* The TWSI interface supports both 7-bit and 10-bit addressing. */
79285+/* This enumerator describes addressing type. */
79286+typedef enum _mvTwsiAddrType
79287+{
79288+ ADDR7_BIT, /* 7 bit address */
79289+ ADDR10_BIT /* 10 bit address */
79290+}MV_TWSI_ADDR_TYPE;
79291+
79292+/* This structure describes TWSI address. */
79293+typedef struct _mvTwsiAddr
79294+{
79295+ MV_U32 address; /* address */
79296+ MV_TWSI_ADDR_TYPE type; /* Address type */
79297+}MV_TWSI_ADDR;
79298+
79299+/* This structure describes a TWSI slave. */
79300+typedef struct _mvTwsiSlave
79301+{
79302+ MV_TWSI_ADDR slaveAddr;
79303+ MV_BOOL validOffset; /* whether the slave has offset (i.e. Eeprom etc.) */
79304+ MV_U32 offset; /* offset in the slave. */
79305+ MV_BOOL moreThen256; /* whether the ofset is bigger then 256 */
79306+}MV_TWSI_SLAVE;
79307+
79308+/* This enumerator describes TWSI protocol commands. */
79309+typedef enum _mvTwsiCmd
79310+{
79311+ MV_TWSI_WRITE, /* TWSI write command - 0 according to spec */
79312+ MV_TWSI_READ /* TWSI read command - 1 according to spec */
79313+}MV_TWSI_CMD;
79314+
79315+MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum);
79316+MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum);
79317+MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *twsiAddr, MV_TWSI_CMD command);
79318+
79319+MV_U32 mvTwsiInit(MV_U8 chanNum, MV_KHZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *twsiAddr, MV_BOOL generalCallEnable);
79320+MV_STATUS mvTwsiRead (MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);
79321+MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);
79322+
79323+
79324+#ifdef __cplusplus
79325+}
79326+#endif /* __cplusplus */
79327+
79328+#endif /* __INCmvTwsiH */
79329+
79330diff --git a/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h b/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h
79331new file mode 100644
79332index 0000000..ebb6db7
79333--- /dev/null
79334+++ b/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h
79335@@ -0,0 +1,160 @@
79336+/*******************************************************************************
79337+Copyright (C) Marvell International Ltd. and its affiliates
79338+
79339+This software file (the "File") is owned and distributed by Marvell
79340+International Ltd. and/or its affiliates ("Marvell") under the following
79341+alternative licensing terms. Once you have made an election to distribute the
79342+File under one of the following license alternatives, please (i) delete this
79343+introductory statement regarding license alternatives, (ii) delete the two
79344+license alternatives that you have not elected to use and (iii) preserve the
79345+Marvell copyright notice above.
79346+
79347+********************************************************************************
79348+Marvell Commercial License Option
79349+
79350+If you received this File from Marvell and you have entered into a commercial
79351+license agreement (a "Commercial License") with Marvell, the File is licensed
79352+to you under the terms of the applicable Commercial License.
79353+
79354+********************************************************************************
79355+Marvell GPL License Option
79356+
79357+If you received this File from Marvell, you may opt to use, redistribute and/or
79358+modify this File in accordance with the terms and conditions of the General
79359+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
79360+available along with the File in the license.txt file or by writing to the Free
79361+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
79362+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
79363+
79364+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
79365+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
79366+DISCLAIMED. The GPL License provides additional details about this warranty
79367+disclaimer.
79368+********************************************************************************
79369+Marvell BSD License Option
79370+
79371+If you received this File from Marvell, you may opt to use, redistribute and/or
79372+modify this File under the following licensing terms.
79373+Redistribution and use in source and binary forms, with or without modification,
79374+are permitted provided that the following conditions are met:
79375+
79376+ * Redistributions of source code must retain the above copyright notice,
79377+ this list of conditions and the following disclaimer.
79378+
79379+ * Redistributions in binary form must reproduce the above copyright
79380+ notice, this list of conditions and the following disclaimer in the
79381+ documentation and/or other materials provided with the distribution.
79382+
79383+ * Neither the name of Marvell nor the names of its contributors may be
79384+ used to endorse or promote products derived from this software without
79385+ specific prior written permission.
79386+
79387+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
79388+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
79389+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
79390+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
79391+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
79392+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
79393+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
79394+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
79395+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
79396+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79397+
79398+*******************************************************************************/
79399+/****************************************/
79400+/* TWSI Registers */
79401+/****************************************/
79402+#ifndef __INCmvTwsiSpech
79403+#define __INCmvTwsiSpech
79404+
79405+#ifdef __cplusplus
79406+extern "C" {
79407+#endif /* __cplusplus */
79408+
79409+/* defines */
79410+#define TWSI_SLAVE_ADDR_REG(chanNum) (TWSI_SLAVE_BASE(chanNum)+ 0x00)
79411+
79412+#define TWSI_SLAVE_ADDR_GCE_ENA BIT0
79413+#define TWSI_SLAVE_ADDR_7BIT_OFFS 0x1
79414+#define TWSI_SLAVE_ADDR_7BIT_MASK (0xFF << TWSI_SLAVE_ADDR_7BIT_OFFS)
79415+#define TWSI_SLAVE_ADDR_10BIT_OFFS 0x7
79416+#define TWSI_SLAVE_ADDR_10BIT_MASK 0x300
79417+#define TWSI_SLAVE_ADDR_10BIT_CONST 0xF0
79418+
79419+
79420+#define TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x10)
79421+#define TWSI_EXTENDED_SLAVE_OFFS 0
79422+#define TWSI_EXTENDED_SLAVE_MASK (0xFF << TWSI_EXTENDED_SLAVE_OFFS)
79423+
79424+
79425+#define TWSI_DATA_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x04)
79426+#define TWSI_DATA_COMMAND_OFFS 0x0
79427+#define TWSI_DATA_COMMAND_MASK (0x1 << TWSI_DATA_COMMAND_OFFS)
79428+#define TWSI_DATA_COMMAND_WR (0x1 << TWSI_DATA_COMMAND_OFFS)
79429+#define TWSI_DATA_COMMAND_RD (0x0 << TWSI_DATA_COMMAND_OFFS)
79430+#define TWSI_DATA_ADDR_7BIT_OFFS 0x1
79431+#define TWSI_DATA_ADDR_7BIT_MASK (0xFF << TWSI_DATA_ADDR_7BIT_OFFS)
79432+#define TWSI_DATA_ADDR_10BIT_OFFS 0x7
79433+#define TWSI_DATA_ADDR_10BIT_MASK 0x300
79434+#define TWSI_DATA_ADDR_10BIT_CONST 0xF0
79435+
79436+
79437+#define TWSI_CONTROL_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x08)
79438+#define TWSI_CONTROL_ACK BIT2
79439+#define TWSI_CONTROL_INT_FLAG_SET BIT3
79440+#define TWSI_CONTROL_STOP_BIT BIT4
79441+#define TWSI_CONTROL_START_BIT BIT5
79442+#define TWSI_CONTROL_ENA BIT6
79443+#define TWSI_CONTROL_INT_ENA BIT7
79444+
79445+
79446+#define TWSI_STATUS_BAUDE_RATE_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x0c)
79447+#define TWSI_BAUD_RATE_N_OFFS 0
79448+#define TWSI_BAUD_RATE_N_MASK (0x7 << TWSI_BAUD_RATE_N_OFFS)
79449+#define TWSI_BAUD_RATE_M_OFFS 3
79450+#define TWSI_BAUD_RATE_M_MASK (0xF << TWSI_BAUD_RATE_M_OFFS)
79451+
79452+#define TWSI_SOFT_RESET_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x1c)
79453+
79454+/* defines */
79455+#define TWSI_TIMEOUT_VALUE 0x500
79456+
79457+/* TWSI status codes */
79458+#define TWSI_BUS_ERROR 0x00
79459+#define TWSI_START_CON_TRA 0x08
79460+#define TWSI_REPEATED_START_CON_TRA 0x10
79461+#define TWSI_AD_PLS_WR_BIT_TRA_ACK_REC 0x18
79462+#define TWSI_AD_PLS_WR_BIT_TRA_ACK_NOT_REC 0x20
79463+#define TWSI_M_TRAN_DATA_BYTE_ACK_REC 0x28
79464+#define TWSI_M_TRAN_DATA_BYTE_ACK_NOT_REC 0x30
79465+#define TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA 0x38
79466+#define TWSI_AD_PLS_RD_BIT_TRA_ACK_REC 0x40
79467+#define TWSI_AD_PLS_RD_BIT_TRA_ACK_NOT_REC 0x48
79468+#define TWSI_M_REC_RD_DATA_ACK_TRA 0x50
79469+#define TWSI_M_REC_RD_DATA_ACK_NOT_TRA 0x58
79470+#define TWSI_SLA_REC_AD_PLS_WR_BIT_ACK_TRA 0x60
79471+#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_W 0x68
79472+#define TWSI_GNL_CALL_REC_ACK_TRA 0x70
79473+#define TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA 0x78
79474+#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_TRAN 0x80
79475+#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_NOT_TRAN 0x88
79476+#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_TRAN 0x90
79477+#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_NOT_TRAN 0x98
79478+#define TWSI_SLA_REC_STOP_OR_REPEATED_STRT_CON 0xA0
79479+#define TWSI_SLA_REC_AD_PLS_RD_BIT_ACK_TRA 0xA8
79480+#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_R 0xB0
79481+#define TWSI_SLA_TRA_RD_DATA_ACK_REC 0xB8
79482+#define TWSI_SLA_TRA_RD_DATA_ACK_NOT_REC 0xC0
79483+#define TWSI_SLA_TRA_LAST_RD_DATA_ACK_REC 0xC8
79484+#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC 0xD0
79485+#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_NOT_REC 0xD8
79486+#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC 0xE0
79487+#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_NOT_REC 0xE8
79488+#define TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0 0xF8
79489+
79490+
79491+#ifdef __cplusplus
79492+}
79493+#endif /* __cplusplus */
79494+
79495+#endif /* __INCmvTwsiSpech */
79496diff --git a/crypto/ocf/ocf-bench.c b/crypto/ocf/ocf-bench.c
79497new file mode 100644
79498index 0000000..d325231
79499--- /dev/null
79500+++ b/crypto/ocf/ocf-bench.c
79501@@ -0,0 +1,436 @@
79502+/*
79503+ * A loadable module that benchmarks the OCF crypto speed from kernel space.
79504+ *
79505+ * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
79506+ *
79507+ * LICENSE TERMS
79508+ *
79509+ * The free distribution and use of this software in both source and binary
79510+ * form is allowed (with or without changes) provided that:
79511+ *
79512+ * 1. distributions of this source code include the above copyright
79513+ * notice, this list of conditions and the following disclaimer;
79514+ *
79515+ * 2. distributions in binary form include the above copyright
79516+ * notice, this list of conditions and the following disclaimer
79517+ * in the documentation and/or other associated materials;
79518+ *
79519+ * 3. the copyright holder's name is not used to endorse products
79520+ * built using this software without specific written permission.
79521+ *
79522+ * ALTERNATIVELY, provided that this notice is retained in full, this product
79523+ * may be distributed under the terms of the GNU General Public License (GPL),
79524+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
79525+ *
79526+ * DISCLAIMER
79527+ *
79528+ * This software is provided 'as is' with no explicit or implied warranties
79529+ * in respect of its properties, including, but not limited to, correctness
79530+ * and/or fitness for purpose.
79531+ */
79532+
79533+
79534+#ifndef AUTOCONF_INCLUDED
79535+#include <linux/config.h>
79536+#endif
79537+#include <linux/module.h>
79538+#include <linux/init.h>
79539+#include <linux/list.h>
79540+#include <linux/slab.h>
79541+#include <linux/wait.h>
79542+#include <linux/sched.h>
79543+#include <linux/spinlock.h>
79544+#include <linux/version.h>
79545+#include <linux/interrupt.h>
79546+#include <cryptodev.h>
79547+
79548+#ifdef I_HAVE_AN_XSCALE_WITH_INTEL_SDK
79549+#define BENCH_IXP_ACCESS_LIB 1
79550+#endif
79551+#ifdef BENCH_IXP_ACCESS_LIB
79552+#include <IxTypes.h>
79553+#include <IxOsBuffMgt.h>
79554+#include <IxNpeDl.h>
79555+#include <IxCryptoAcc.h>
79556+#include <IxQMgr.h>
79557+#include <IxOsServices.h>
79558+#include <IxOsCacheMMU.h>
79559+#endif
79560+
79561+/*
79562+ * support for access lib version 1.4
79563+ */
79564+#ifndef IX_MBUF_PRIV
79565+#define IX_MBUF_PRIV(x) ((x)->priv)
79566+#endif
79567+
79568+/*
79569+ * the number of simultaneously active requests
79570+ */
79571+static int request_q_len = 20;
79572+module_param(request_q_len, int, 0);
79573+MODULE_PARM_DESC(request_q_len, "Number of outstanding requests");
79574+/*
79575+ * how many requests we want to have processed
79576+ */
79577+static int request_num = 1024;
79578+module_param(request_num, int, 0);
79579+MODULE_PARM_DESC(request_num, "run for at least this many requests");
79580+/*
79581+ * the size of each request
79582+ */
79583+static int request_size = 1500;
79584+module_param(request_size, int, 0);
79585+MODULE_PARM_DESC(request_size, "size of each request");
79586+
79587+/*
79588+ * a structure for each request
79589+ */
79590+typedef struct {
79591+ struct work_struct work;
79592+#ifdef BENCH_IXP_ACCESS_LIB
79593+ IX_MBUF mbuf;
79594+#endif
79595+ unsigned char *buffer;
79596+} request_t;
79597+
79598+static request_t *requests;
79599+
79600+static int outstanding;
79601+static int total;
79602+
79603+/*************************************************************************/
79604+/*
79605+ * OCF benchmark routines
79606+ */
79607+
79608+static uint64_t ocf_cryptoid;
79609+static int ocf_init(void);
79610+static int ocf_cb(struct cryptop *crp);
79611+static void ocf_request(void *arg);
79612+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
79613+static void ocf_request_wq(struct work_struct *work);
79614+#endif
79615+
79616+static int
79617+ocf_init(void)
79618+{
79619+ int error;
79620+ struct cryptoini crie, cria;
79621+ struct cryptodesc crda, crde;
79622+
79623+ memset(&crie, 0, sizeof(crie));
79624+ memset(&cria, 0, sizeof(cria));
79625+ memset(&crde, 0, sizeof(crde));
79626+ memset(&crda, 0, sizeof(crda));
79627+
79628+ cria.cri_alg = CRYPTO_SHA1_HMAC;
79629+ cria.cri_klen = 20 * 8;
79630+ cria.cri_key = "0123456789abcdefghij";
79631+
79632+ crie.cri_alg = CRYPTO_3DES_CBC;
79633+ crie.cri_klen = 24 * 8;
79634+ crie.cri_key = "0123456789abcdefghijklmn";
79635+
79636+ crie.cri_next = &cria;
79637+
79638+ error = crypto_newsession(&ocf_cryptoid, &crie, 0);
79639+ if (error) {
79640+ printk("crypto_newsession failed %d\n", error);
79641+ return -1;
79642+ }
79643+ return 0;
79644+}
79645+
79646+static int
79647+ocf_cb(struct cryptop *crp)
79648+{
79649+ request_t *r = (request_t *) crp->crp_opaque;
79650+
79651+ if (crp->crp_etype)
79652+ printk("Error in OCF processing: %d\n", crp->crp_etype);
79653+ total++;
79654+ crypto_freereq(crp);
79655+ crp = NULL;
79656+
79657+ if (total > request_num) {
79658+ outstanding--;
79659+ return 0;
79660+ }
79661+
79662+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
79663+ INIT_WORK(&r->work, ocf_request_wq);
79664+#else
79665+ INIT_WORK(&r->work, ocf_request, r);
79666+#endif
79667+ schedule_work(&r->work);
79668+ return 0;
79669+}
79670+
79671+
79672+static void
79673+ocf_request(void *arg)
79674+{
79675+ request_t *r = arg;
79676+ struct cryptop *crp = crypto_getreq(2);
79677+ struct cryptodesc *crde, *crda;
79678+
79679+ if (!crp) {
79680+ outstanding--;
79681+ return;
79682+ }
79683+
79684+ crde = crp->crp_desc;
79685+ crda = crde->crd_next;
79686+
79687+ crda->crd_skip = 0;
79688+ crda->crd_flags = 0;
79689+ crda->crd_len = request_size;
79690+ crda->crd_inject = request_size;
79691+ crda->crd_alg = CRYPTO_SHA1_HMAC;
79692+ crda->crd_key = "0123456789abcdefghij";
79693+ crda->crd_klen = 20 * 8;
79694+
79695+ crde->crd_skip = 0;
79696+ crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_ENCRYPT;
79697+ crde->crd_len = request_size;
79698+ crde->crd_inject = request_size;
79699+ crde->crd_alg = CRYPTO_3DES_CBC;
79700+ crde->crd_key = "0123456789abcdefghijklmn";
79701+ crde->crd_klen = 24 * 8;
79702+
79703+ crp->crp_ilen = request_size + 64;
79704+ crp->crp_flags = CRYPTO_F_CBIMM;
79705+ crp->crp_buf = (caddr_t) r->buffer;
79706+ crp->crp_callback = ocf_cb;
79707+ crp->crp_sid = ocf_cryptoid;
79708+ crp->crp_opaque = (caddr_t) r;
79709+ crypto_dispatch(crp);
79710+}
79711+
79712+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
79713+static void
79714+ocf_request_wq(struct work_struct *work)
79715+{
79716+ request_t *r = container_of(work, request_t, work);
79717+ ocf_request(r);
79718+}
79719+#endif
79720+
79721+/*************************************************************************/
79722+#ifdef BENCH_IXP_ACCESS_LIB
79723+/*************************************************************************/
79724+/*
79725+ * CryptoAcc benchmark routines
79726+ */
79727+
79728+static IxCryptoAccCtx ixp_ctx;
79729+static UINT32 ixp_ctx_id;
79730+static IX_MBUF ixp_pri;
79731+static IX_MBUF ixp_sec;
79732+static int ixp_registered = 0;
79733+
79734+static void ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp,
79735+ IxCryptoAccStatus status);
79736+static void ixp_perform_cb(UINT32 ctx_id, IX_MBUF *sbufp, IX_MBUF *dbufp,
79737+ IxCryptoAccStatus status);
79738+static void ixp_request(void *arg);
79739+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
79740+static void ixp_request_wq(struct work_struct *work);
79741+#endif
79742+
79743+static int
79744+ixp_init(void)
79745+{
79746+ IxCryptoAccStatus status;
79747+
79748+ ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
79749+ ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
79750+ ixp_ctx.cipherCtx.cipherKeyLen = 24;
79751+ ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
79752+ ixp_ctx.cipherCtx.cipherInitialVectorLen = IX_CRYPTO_ACC_DES_IV_64;
79753+ memcpy(ixp_ctx.cipherCtx.key.cipherKey, "0123456789abcdefghijklmn", 24);
79754+
79755+ ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
79756+ ixp_ctx.authCtx.authDigestLen = 12;
79757+ ixp_ctx.authCtx.aadLen = 0;
79758+ ixp_ctx.authCtx.authKeyLen = 20;
79759+ memcpy(ixp_ctx.authCtx.key.authKey, "0123456789abcdefghij", 20);
79760+
79761+ ixp_ctx.useDifferentSrcAndDestMbufs = 0;
79762+ ixp_ctx.operation = IX_CRYPTO_ACC_OP_ENCRYPT_AUTH ;
79763+
79764+ IX_MBUF_MLEN(&ixp_pri) = IX_MBUF_PKT_LEN(&ixp_pri) = 128;
79765+ IX_MBUF_MDATA(&ixp_pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
79766+ IX_MBUF_MLEN(&ixp_sec) = IX_MBUF_PKT_LEN(&ixp_sec) = 128;
79767+ IX_MBUF_MDATA(&ixp_sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
79768+
79769+ status = ixCryptoAccCtxRegister(&ixp_ctx, &ixp_pri, &ixp_sec,
79770+ ixp_register_cb, ixp_perform_cb, &ixp_ctx_id);
79771+
79772+ if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {
79773+ while (!ixp_registered)
79774+ schedule();
79775+ return ixp_registered < 0 ? -1 : 0;
79776+ }
79777+
79778+ printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
79779+ return -1;
79780+}
79781+
79782+static void
79783+ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
79784+{
79785+ if (bufp) {
79786+ IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
79787+ kfree(IX_MBUF_MDATA(bufp));
79788+ IX_MBUF_MDATA(bufp) = NULL;
79789+ }
79790+
79791+ if (IX_CRYPTO_ACC_STATUS_WAIT == status)
79792+ return;
79793+ if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
79794+ ixp_registered = 1;
79795+ else
79796+ ixp_registered = -1;
79797+}
79798+
79799+static void
79800+ixp_perform_cb(
79801+ UINT32 ctx_id,
79802+ IX_MBUF *sbufp,
79803+ IX_MBUF *dbufp,
79804+ IxCryptoAccStatus status)
79805+{
79806+ request_t *r = NULL;
79807+
79808+ total++;
79809+ if (total > request_num) {
79810+ outstanding--;
79811+ return;
79812+ }
79813+
79814+ if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {
79815+ printk("crappo %p %p\n", sbufp, r);
79816+ outstanding--;
79817+ return;
79818+ }
79819+
79820+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
79821+ INIT_WORK(&r->work, ixp_request_wq);
79822+#else
79823+ INIT_WORK(&r->work, ixp_request, r);
79824+#endif
79825+ schedule_work(&r->work);
79826+}
79827+
79828+static void
79829+ixp_request(void *arg)
79830+{
79831+ request_t *r = arg;
79832+ IxCryptoAccStatus status;
79833+
79834+ memset(&r->mbuf, 0, sizeof(r->mbuf));
79835+ IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;
79836+ IX_MBUF_MDATA(&r->mbuf) = r->buffer;
79837+ IX_MBUF_PRIV(&r->mbuf) = r;
79838+ status = ixCryptoAccAuthCryptPerform(ixp_ctx_id, &r->mbuf, NULL,
79839+ 0, request_size, 0, request_size, request_size, r->buffer);
79840+ if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
79841+ printk("status1 = %d\n", status);
79842+ outstanding--;
79843+ return;
79844+ }
79845+ return;
79846+}
79847+
79848+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
79849+static void
79850+ixp_request_wq(struct work_struct *work)
79851+{
79852+ request_t *r = container_of(work, request_t, work);
79853+ ixp_request(r);
79854+}
79855+#endif
79856+
79857+/*************************************************************************/
79858+#endif /* BENCH_IXP_ACCESS_LIB */
79859+/*************************************************************************/
79860+
79861+int
79862+ocfbench_init(void)
79863+{
79864+ int i, jstart, jstop;
79865+
79866+ printk("Crypto Speed tests\n");
79867+
79868+ requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);
79869+ if (!requests) {
79870+ printk("malloc failed\n");
79871+ return -EINVAL;
79872+ }
79873+
79874+ for (i = 0; i < request_q_len; i++) {
79875+ /* +64 for return data */
79876+ requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
79877+ if (!requests[i].buffer) {
79878+ printk("malloc failed\n");
79879+ return -EINVAL;
79880+ }
79881+ memset(requests[i].buffer, '0' + i, request_size + 128);
79882+ }
79883+
79884+ /*
79885+ * OCF benchmark
79886+ */
79887+ printk("OCF: testing ...\n");
79888+ ocf_init();
79889+ total = outstanding = 0;
79890+ jstart = jiffies;
79891+ for (i = 0; i < request_q_len; i++) {
79892+ outstanding++;
79893+ ocf_request(&requests[i]);
79894+ }
79895+ while (outstanding > 0)
79896+ schedule();
79897+ jstop = jiffies;
79898+
79899+ printk("OCF: %d requests of %d bytes in %d jiffies\n", total, request_size,
79900+ jstop - jstart);
79901+
79902+#ifdef BENCH_IXP_ACCESS_LIB
79903+ /*
79904+ * IXP benchmark
79905+ */
79906+ printk("IXP: testing ...\n");
79907+ ixp_init();
79908+ total = outstanding = 0;
79909+ jstart = jiffies;
79910+ for (i = 0; i < request_q_len; i++) {
79911+ outstanding++;
79912+ ixp_request(&requests[i]);
79913+ }
79914+ while (outstanding > 0)
79915+ schedule();
79916+ jstop = jiffies;
79917+
79918+ printk("IXP: %d requests of %d bytes in %d jiffies\n", total, request_size,
79919+ jstop - jstart);
79920+#endif /* BENCH_IXP_ACCESS_LIB */
79921+
79922+ for (i = 0; i < request_q_len; i++)
79923+ kfree(requests[i].buffer);
79924+ kfree(requests);
79925+ return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */
79926+}
79927+
79928+static void __exit ocfbench_exit(void)
79929+{
79930+}
79931+
79932+module_init(ocfbench_init);
79933+module_exit(ocfbench_exit);
79934+
79935+MODULE_LICENSE("BSD");
79936+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
79937+MODULE_DESCRIPTION("Benchmark various in-kernel crypto speeds");
79938diff --git a/crypto/ocf/ocf-compat.h b/crypto/ocf/ocf-compat.h
79939new file mode 100644
79940index 0000000..212f971
79941--- /dev/null
79942+++ b/crypto/ocf/ocf-compat.h
79943@@ -0,0 +1,294 @@
79944+#ifndef _BSD_COMPAT_H_
79945+#define _BSD_COMPAT_H_ 1
79946+/****************************************************************************/
79947+/*
79948+ * Provide compat routines for older linux kernels and BSD kernels
79949+ *
79950+ * Written by David McCullough <david_mccullough@mcafee.com>
79951+ * Copyright (C) 2010 David McCullough <david_mccullough@mcafee.com>
79952+ *
79953+ * LICENSE TERMS
79954+ *
79955+ * The free distribution and use of this software in both source and binary
79956+ * form is allowed (with or without changes) provided that:
79957+ *
79958+ * 1. distributions of this source code include the above copyright
79959+ * notice, this list of conditions and the following disclaimer;
79960+ *
79961+ * 2. distributions in binary form include the above copyright
79962+ * notice, this list of conditions and the following disclaimer
79963+ * in the documentation and/or other associated materials;
79964+ *
79965+ * 3. the copyright holder's name is not used to endorse products
79966+ * built using this software without specific written permission.
79967+ *
79968+ * ALTERNATIVELY, provided that this notice is retained in full, this file
79969+ * may be distributed under the terms of the GNU General Public License (GPL),
79970+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
79971+ *
79972+ * DISCLAIMER
79973+ *
79974+ * This software is provided 'as is' with no explicit or implied warranties
79975+ * in respect of its properties, including, but not limited to, correctness
79976+ * and/or fitness for purpose.
79977+ */
79978+/****************************************************************************/
79979+#ifdef __KERNEL__
79980+/*
79981+ * fake some BSD driver interface stuff specifically for OCF use
79982+ */
79983+
79984+typedef struct ocf_device *device_t;
79985+
79986+typedef struct {
79987+ int (*cryptodev_newsession)(device_t dev, u_int32_t *sidp, struct cryptoini *cri);
79988+ int (*cryptodev_freesession)(device_t dev, u_int64_t tid);
79989+ int (*cryptodev_process)(device_t dev, struct cryptop *crp, int hint);
79990+ int (*cryptodev_kprocess)(device_t dev, struct cryptkop *krp, int hint);
79991+} device_method_t;
79992+#define DEVMETHOD(id, func) id: func
79993+
79994+struct ocf_device {
79995+ char name[32]; /* the driver name */
79996+ char nameunit[32]; /* the driver name + HW instance */
79997+ int unit;
79998+ device_method_t methods;
79999+ void *softc;
80000+};
80001+
80002+#define CRYPTODEV_NEWSESSION(dev, sid, cri) \
80003+ ((*(dev)->methods.cryptodev_newsession)(dev,sid,cri))
80004+#define CRYPTODEV_FREESESSION(dev, sid) \
80005+ ((*(dev)->methods.cryptodev_freesession)(dev, sid))
80006+#define CRYPTODEV_PROCESS(dev, crp, hint) \
80007+ ((*(dev)->methods.cryptodev_process)(dev, crp, hint))
80008+#define CRYPTODEV_KPROCESS(dev, krp, hint) \
80009+ ((*(dev)->methods.cryptodev_kprocess)(dev, krp, hint))
80010+
80011+#define device_get_name(dev) ((dev)->name)
80012+#define device_get_nameunit(dev) ((dev)->nameunit)
80013+#define device_get_unit(dev) ((dev)->unit)
80014+#define device_get_softc(dev) ((dev)->softc)
80015+
80016+#define softc_device_decl \
80017+ struct ocf_device _device; \
80018+ device_t
80019+
80020+#define softc_device_init(_sc, _name, _unit, _methods) \
80021+ if (1) {\
80022+ strncpy((_sc)->_device.name, _name, sizeof((_sc)->_device.name) - 1); \
80023+ snprintf((_sc)->_device.nameunit, sizeof((_sc)->_device.name), "%s%d", _name, _unit); \
80024+ (_sc)->_device.unit = _unit; \
80025+ (_sc)->_device.methods = _methods; \
80026+ (_sc)->_device.softc = (void *) _sc; \
80027+ *(device_t *)((softc_get_device(_sc))+1) = &(_sc)->_device; \
80028+ } else
80029+
80030+#define softc_get_device(_sc) (&(_sc)->_device)
80031+
80032+/*
80033+ * iomem support for 2.4 and 2.6 kernels
80034+ */
80035+#include <linux/version.h>
80036+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
80037+#define ocf_iomem_t unsigned long
80038+
80039+/*
80040+ * implement simple workqueue like support for older kernels
80041+ */
80042+
80043+#include <linux/tqueue.h>
80044+
80045+#define work_struct tq_struct
80046+
80047+#define INIT_WORK(wp, fp, ap) \
80048+ do { \
80049+ (wp)->sync = 0; \
80050+ (wp)->routine = (fp); \
80051+ (wp)->data = (ap); \
80052+ } while (0)
80053+
80054+#define schedule_work(wp) \
80055+ do { \
80056+ queue_task((wp), &tq_immediate); \
80057+ mark_bh(IMMEDIATE_BH); \
80058+ } while (0)
80059+
80060+#define flush_scheduled_work() run_task_queue(&tq_immediate)
80061+
80062+#else
80063+#define ocf_iomem_t void __iomem *
80064+
80065+#include <linux/workqueue.h>
80066+
80067+#endif
80068+
80069+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
80070+#include <linux/fdtable.h>
80071+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
80072+#define files_fdtable(files) (files)
80073+#endif
80074+
80075+#ifdef MODULE_PARM
80076+#undef module_param /* just in case */
80077+#define module_param(a,b,c) MODULE_PARM(a,"i")
80078+#endif
80079+
80080+#define bzero(s,l) memset(s,0,l)
80081+#define bcopy(s,d,l) memcpy(d,s,l)
80082+#define bcmp(x, y, l) memcmp(x,y,l)
80083+
80084+#define MIN(x,y) ((x) < (y) ? (x) : (y))
80085+
80086+#define device_printf(dev, a...) ({ \
80087+ printk("%s: ", device_get_nameunit(dev)); printk(a); \
80088+ })
80089+
80090+#undef printf
80091+#define printf(fmt...) printk(fmt)
80092+
80093+#define KASSERT(c,p) if (!(c)) { printk p ; } else
80094+
80095+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
80096+#define ocf_daemonize(str) \
80097+ daemonize(); \
80098+ spin_lock_irq(&current->sigmask_lock); \
80099+ sigemptyset(&current->blocked); \
80100+ recalc_sigpending(current); \
80101+ spin_unlock_irq(&current->sigmask_lock); \
80102+ sprintf(current->comm, str);
80103+#else
80104+#define ocf_daemonize(str) daemonize(str);
80105+#endif
80106+
80107+#define TAILQ_INSERT_TAIL(q,d,m) list_add_tail(&(d)->m, (q))
80108+#define TAILQ_EMPTY(q) list_empty(q)
80109+#define TAILQ_FOREACH(v, q, m) list_for_each_entry(v, q, m)
80110+
80111+#define read_random(p,l) get_random_bytes(p,l)
80112+
80113+#define DELAY(x) ((x) > 2000 ? mdelay((x)/1000) : udelay(x))
80114+#define strtoul simple_strtoul
80115+
80116+#define pci_get_vendor(dev) ((dev)->vendor)
80117+#define pci_get_device(dev) ((dev)->device)
80118+
80119+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
80120+#define pci_set_consistent_dma_mask(dev, mask) (0)
80121+#endif
80122+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
80123+#define pci_dma_sync_single_for_cpu pci_dma_sync_single
80124+#endif
80125+
80126+#ifndef DMA_32BIT_MASK
80127+#define DMA_32BIT_MASK 0x00000000ffffffffULL
80128+#endif
80129+
80130+#ifndef htole32
80131+#define htole32(x) cpu_to_le32(x)
80132+#endif
80133+#ifndef htobe32
80134+#define htobe32(x) cpu_to_be32(x)
80135+#endif
80136+#ifndef htole16
80137+#define htole16(x) cpu_to_le16(x)
80138+#endif
80139+#ifndef htobe16
80140+#define htobe16(x) cpu_to_be16(x)
80141+#endif
80142+
80143+/* older kernels don't have these */
80144+
80145+#include <asm/irq.h>
80146+#if !defined(IRQ_NONE) && !defined(IRQ_RETVAL)
80147+#define IRQ_NONE
80148+#define IRQ_HANDLED
80149+#define IRQ_WAKE_THREAD
80150+#define IRQ_RETVAL
80151+#define irqreturn_t void
80152+typedef irqreturn_t (*irq_handler_t)(int irq, void *arg, struct pt_regs *regs);
80153+#endif
80154+#ifndef IRQF_SHARED
80155+#define IRQF_SHARED SA_SHIRQ
80156+#endif
80157+
80158+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
80159+# define strlcpy(dest,src,len) \
80160+ ({strncpy(dest,src,(len)-1); ((char *)dest)[(len)-1] = '\0'; })
80161+#endif
80162+
80163+#ifndef MAX_ERRNO
80164+#define MAX_ERRNO 4095
80165+#endif
80166+#ifndef IS_ERR_VALUE
80167+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,5)
80168+#include <linux/err.h>
80169+#endif
80170+#ifndef IS_ERR_VALUE
80171+#define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-MAX_ERRNO)
80172+#endif
80173+#endif
80174+
80175+/*
80176+ * common debug for all
80177+ */
80178+#if 1
80179+#define dprintk(a...) do { if (debug) printk(a); } while(0)
80180+#else
80181+#define dprintk(a...)
80182+#endif
80183+
80184+#ifndef SLAB_ATOMIC
80185+/* Changed in 2.6.20, must use GFP_ATOMIC now */
80186+#define SLAB_ATOMIC GFP_ATOMIC
80187+#endif
80188+
80189+/*
80190+ * need some additional support for older kernels */
80191+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,2)
80192+#define pci_register_driver_compat(driver, rc) \
80193+ do { \
80194+ if ((rc) > 0) { \
80195+ (rc) = 0; \
80196+ } else if (rc == 0) { \
80197+ (rc) = -ENODEV; \
80198+ } else { \
80199+ pci_unregister_driver(driver); \
80200+ } \
80201+ } while (0)
80202+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
80203+#define pci_register_driver_compat(driver,rc) ((rc) = (rc) < 0 ? (rc) : 0)
80204+#else
80205+#define pci_register_driver_compat(driver,rc)
80206+#endif
80207+
80208+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
80209+
80210+#include <linux/mm.h>
80211+#include <asm/scatterlist.h>
80212+
80213+static inline void sg_set_page(struct scatterlist *sg, struct page *page,
80214+ unsigned int len, unsigned int offset)
80215+{
80216+ sg->page = page;
80217+ sg->offset = offset;
80218+ sg->length = len;
80219+}
80220+
80221+static inline void *sg_virt(struct scatterlist *sg)
80222+{
80223+ return page_address(sg->page) + sg->offset;
80224+}
80225+
80226+#define sg_init_table(sg, n)
80227+
80228+#endif
80229+
80230+#ifndef late_initcall
80231+#define late_initcall(init) module_init(init)
80232+#endif
80233+
80234+#endif /* __KERNEL__ */
80235+
80236+/****************************************************************************/
80237+#endif /* _BSD_COMPAT_H_ */
80238diff --git a/crypto/ocf/ocfnull/Makefile b/crypto/ocf/ocfnull/Makefile
80239new file mode 100644
80240index 0000000..044bcac
80241--- /dev/null
80242+++ b/crypto/ocf/ocfnull/Makefile
80243@@ -0,0 +1,12 @@
80244+# for SGlinux builds
80245+-include $(ROOTDIR)/modules/.config
80246+
80247+obj-$(CONFIG_OCF_OCFNULL) += ocfnull.o
80248+
80249+obj ?= .
80250+EXTRA_CFLAGS += -I$(obj)/..
80251+
80252+ifdef TOPDIR
80253+-include $(TOPDIR)/Rules.make
80254+endif
80255+
80256diff --git a/crypto/ocf/ocfnull/ocfnull.c b/crypto/ocf/ocfnull/ocfnull.c
80257new file mode 100644
80258index 0000000..3df150d
80259--- /dev/null
80260+++ b/crypto/ocf/ocfnull/ocfnull.c
80261@@ -0,0 +1,203 @@
80262+/*
80263+ * An OCF module for determining the cost of crypto versus the cost of
80264+ * IPSec processing outside of OCF. This modules gives us the effect of
80265+ * zero cost encryption, of course you will need to run it at both ends
80266+ * since it does no crypto at all.
80267+ *
80268+ * Written by David McCullough <david_mccullough@mcafee.com>
80269+ * Copyright (C) 2006-2010 David McCullough
80270+ *
80271+ * LICENSE TERMS
80272+ *
80273+ * The free distribution and use of this software in both source and binary
80274+ * form is allowed (with or without changes) provided that:
80275+ *
80276+ * 1. distributions of this source code include the above copyright
80277+ * notice, this list of conditions and the following disclaimer;
80278+ *
80279+ * 2. distributions in binary form include the above copyright
80280+ * notice, this list of conditions and the following disclaimer
80281+ * in the documentation and/or other associated materials;
80282+ *
80283+ * 3. the copyright holder's name is not used to endorse products
80284+ * built using this software without specific written permission.
80285+ *
80286+ * ALTERNATIVELY, provided that this notice is retained in full, this product
80287+ * may be distributed under the terms of the GNU General Public License (GPL),
80288+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
80289+ *
80290+ * DISCLAIMER
80291+ *
80292+ * This software is provided 'as is' with no explicit or implied warranties
80293+ * in respect of its properties, including, but not limited to, correctness
80294+ * and/or fitness for purpose.
80295+ */
80296+
80297+#ifndef AUTOCONF_INCLUDED
80298+#include <linux/config.h>
80299+#endif
80300+#include <linux/module.h>
80301+#include <linux/init.h>
80302+#include <linux/list.h>
80303+#include <linux/slab.h>
80304+#include <linux/sched.h>
80305+#include <linux/wait.h>
80306+#include <linux/crypto.h>
80307+#include <linux/interrupt.h>
80308+
80309+#include <cryptodev.h>
80310+#include <uio.h>
80311+
80312+static int32_t null_id = -1;
80313+static u_int32_t null_sesnum = 0;
80314+
80315+static int null_process(device_t, struct cryptop *, int);
80316+static int null_newsession(device_t, u_int32_t *, struct cryptoini *);
80317+static int null_freesession(device_t, u_int64_t);
80318+
80319+#define debug ocfnull_debug
80320+int ocfnull_debug = 0;
80321+module_param(ocfnull_debug, int, 0644);
80322+MODULE_PARM_DESC(ocfnull_debug, "Enable debug");
80323+
80324+/*
80325+ * dummy device structure
80326+ */
80327+
80328+static struct {
80329+ softc_device_decl sc_dev;
80330+} nulldev;
80331+
80332+static device_method_t null_methods = {
80333+ /* crypto device methods */
80334+ DEVMETHOD(cryptodev_newsession, null_newsession),
80335+ DEVMETHOD(cryptodev_freesession,null_freesession),
80336+ DEVMETHOD(cryptodev_process, null_process),
80337+};
80338+
80339+/*
80340+ * Generate a new software session.
80341+ */
80342+static int
80343+null_newsession(device_t arg, u_int32_t *sid, struct cryptoini *cri)
80344+{
80345+ dprintk("%s()\n", __FUNCTION__);
80346+ if (sid == NULL || cri == NULL) {
80347+ dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
80348+ return EINVAL;
80349+ }
80350+
80351+ if (null_sesnum == 0)
80352+ null_sesnum++;
80353+ *sid = null_sesnum++;
80354+ return 0;
80355+}
80356+
80357+
80358+/*
80359+ * Free a session.
80360+ */
80361+static int
80362+null_freesession(device_t arg, u_int64_t tid)
80363+{
80364+ u_int32_t sid = CRYPTO_SESID2LID(tid);
80365+
80366+ dprintk("%s()\n", __FUNCTION__);
80367+ if (sid > null_sesnum) {
80368+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
80369+ return EINVAL;
80370+ }
80371+
80372+ /* Silently accept and return */
80373+ if (sid == 0)
80374+ return 0;
80375+ return 0;
80376+}
80377+
80378+
80379+/*
80380+ * Process a request.
80381+ */
80382+static int
80383+null_process(device_t arg, struct cryptop *crp, int hint)
80384+{
80385+ unsigned int lid;
80386+
80387+ dprintk("%s()\n", __FUNCTION__);
80388+
80389+ /* Sanity check */
80390+ if (crp == NULL) {
80391+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
80392+ return EINVAL;
80393+ }
80394+
80395+ crp->crp_etype = 0;
80396+
80397+ if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
80398+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
80399+ crp->crp_etype = EINVAL;
80400+ goto done;
80401+ }
80402+
80403+ /*
80404+ * find the session we are using
80405+ */
80406+
80407+ lid = crp->crp_sid & 0xffffffff;
80408+ if (lid >= null_sesnum || lid == 0) {
80409+ crp->crp_etype = ENOENT;
80410+ dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
80411+ goto done;
80412+ }
80413+
80414+done:
80415+ crypto_done(crp);
80416+ return 0;
80417+}
80418+
80419+
80420+/*
80421+ * our driver startup and shutdown routines
80422+ */
80423+
80424+static int
80425+null_init(void)
80426+{
80427+ dprintk("%s(%p)\n", __FUNCTION__, null_init);
80428+
80429+ memset(&nulldev, 0, sizeof(nulldev));
80430+ softc_device_init(&nulldev, "ocfnull", 0, null_methods);
80431+
80432+ null_id = crypto_get_driverid(softc_get_device(&nulldev),
80433+ CRYPTOCAP_F_HARDWARE);
80434+ if (null_id < 0)
80435+ panic("ocfnull: crypto device cannot initialize!");
80436+
80437+#define REGISTER(alg) \
80438+ crypto_register(null_id,alg,0,0)
80439+ REGISTER(CRYPTO_DES_CBC);
80440+ REGISTER(CRYPTO_3DES_CBC);
80441+ REGISTER(CRYPTO_RIJNDAEL128_CBC);
80442+ REGISTER(CRYPTO_MD5);
80443+ REGISTER(CRYPTO_SHA1);
80444+ REGISTER(CRYPTO_MD5_HMAC);
80445+ REGISTER(CRYPTO_SHA1_HMAC);
80446+#undef REGISTER
80447+
80448+ return 0;
80449+}
80450+
80451+static void
80452+null_exit(void)
80453+{
80454+ dprintk("%s()\n", __FUNCTION__);
80455+ crypto_unregister_all(null_id);
80456+ null_id = -1;
80457+}
80458+
80459+module_init(null_init);
80460+module_exit(null_exit);
80461+
80462+MODULE_LICENSE("Dual BSD/GPL");
80463+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
80464+MODULE_DESCRIPTION("ocfnull - claims a lot but does nothing");
80465diff --git a/crypto/ocf/pasemi/Makefile b/crypto/ocf/pasemi/Makefile
80466new file mode 100644
80467index 0000000..b0a3980
80468--- /dev/null
80469+++ b/crypto/ocf/pasemi/Makefile
80470@@ -0,0 +1,12 @@
80471+# for SGlinux builds
80472+-include $(ROOTDIR)/modules/.config
80473+
80474+obj-$(CONFIG_OCF_PASEMI) += pasemi.o
80475+
80476+obj ?= .
80477+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
80478+
80479+ifdef TOPDIR
80480+-include $(TOPDIR)/Rules.make
80481+endif
80482+
80483diff --git a/crypto/ocf/pasemi/pasemi.c b/crypto/ocf/pasemi/pasemi.c
80484new file mode 100644
80485index 0000000..c3bb931
80486--- /dev/null
80487+++ b/crypto/ocf/pasemi/pasemi.c
80488@@ -0,0 +1,1009 @@
80489+/*
80490+ * Copyright (C) 2007 PA Semi, Inc
80491+ *
80492+ * Driver for the PA Semi PWRficient DMA Crypto Engine
80493+ *
80494+ * This program is free software; you can redistribute it and/or modify
80495+ * it under the terms of the GNU General Public License version 2 as
80496+ * published by the Free Software Foundation.
80497+ *
80498+ * This program is distributed in the hope that it will be useful,
80499+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
80500+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
80501+ * GNU General Public License for more details.
80502+ *
80503+ * You should have received a copy of the GNU General Public License
80504+ * along with this program; if not, write to the Free Software
80505+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
80506+ */
80507+
80508+#ifndef AUTOCONF_INCLUDED
80509+#include <linux/config.h>
80510+#endif
80511+#include <linux/module.h>
80512+#include <linux/init.h>
80513+#include <linux/interrupt.h>
80514+#include <linux/timer.h>
80515+#include <linux/random.h>
80516+#include <linux/skbuff.h>
80517+#include <asm/scatterlist.h>
80518+#include <linux/moduleparam.h>
80519+#include <linux/pci.h>
80520+#include <cryptodev.h>
80521+#include <uio.h>
80522+#include "pasemi_fnu.h"
80523+
80524+#define DRV_NAME "pasemi"
80525+
80526+#define TIMER_INTERVAL 1000
80527+
80528+static void __devexit pasemi_dma_remove(struct pci_dev *pdev);
80529+static struct pasdma_status volatile * dma_status;
80530+
80531+static int debug;
80532+module_param(debug, int, 0644);
80533+MODULE_PARM_DESC(debug, "Enable debug");
80534+
80535+static void pasemi_desc_start(struct pasemi_desc *desc, u64 hdr)
80536+{
80537+ desc->postop = 0;
80538+ desc->quad[0] = hdr;
80539+ desc->quad_cnt = 1;
80540+ desc->size = 1;
80541+}
80542+
80543+static void pasemi_desc_build(struct pasemi_desc *desc, u64 val)
80544+{
80545+ desc->quad[desc->quad_cnt++] = val;
80546+ desc->size = (desc->quad_cnt + 1) / 2;
80547+}
80548+
80549+static void pasemi_desc_hdr(struct pasemi_desc *desc, u64 hdr)
80550+{
80551+ desc->quad[0] |= hdr;
80552+}
80553+
80554+static int pasemi_desc_size(struct pasemi_desc *desc)
80555+{
80556+ return desc->size;
80557+}
80558+
80559+static void pasemi_ring_add_desc(
80560+ struct pasemi_fnu_txring *ring,
80561+ struct pasemi_desc *desc,
80562+ struct cryptop *crp) {
80563+ int i;
80564+ int ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
80565+
80566+ TX_DESC_INFO(ring, ring->next_to_fill).desc_size = desc->size;
80567+ TX_DESC_INFO(ring, ring->next_to_fill).desc_postop = desc->postop;
80568+ TX_DESC_INFO(ring, ring->next_to_fill).cf_crp = crp;
80569+
80570+ for (i = 0; i < desc->quad_cnt; i += 2) {
80571+ ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
80572+ ring->desc[ring_index] = desc->quad[i];
80573+ ring->desc[ring_index + 1] = desc->quad[i + 1];
80574+ ring->next_to_fill++;
80575+ }
80576+
80577+ if (desc->quad_cnt & 1)
80578+ ring->desc[ring_index + 1] = 0;
80579+}
80580+
80581+static void pasemi_ring_incr(struct pasemi_softc *sc, int chan_index, int incr)
80582+{
80583+ out_le32(sc->dma_regs + PAS_DMA_TXCHAN_INCR(sc->base_chan + chan_index),
80584+ incr);
80585+}
80586+
80587+/*
80588+ * Generate a new software session.
80589+ */
80590+static int
80591+pasemi_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
80592+{
80593+ struct cryptoini *c, *encini = NULL, *macini = NULL;
80594+ struct pasemi_softc *sc = device_get_softc(dev);
80595+ struct pasemi_session *ses = NULL, **sespp;
80596+ int sesn, blksz = 0;
80597+ u64 ccmd = 0;
80598+ unsigned long flags;
80599+ struct pasemi_desc init_desc;
80600+ struct pasemi_fnu_txring *txring;
80601+
80602+ DPRINTF("%s()\n", __FUNCTION__);
80603+ if (sidp == NULL || cri == NULL || sc == NULL) {
80604+ DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
80605+ return -EINVAL;
80606+ }
80607+ for (c = cri; c != NULL; c = c->cri_next) {
80608+ if (ALG_IS_SIG(c->cri_alg)) {
80609+ if (macini)
80610+ return -EINVAL;
80611+ macini = c;
80612+ } else if (ALG_IS_CIPHER(c->cri_alg)) {
80613+ if (encini)
80614+ return -EINVAL;
80615+ encini = c;
80616+ } else {
80617+ DPRINTF("UNKNOWN c->cri_alg %d\n", c->cri_alg);
80618+ return -EINVAL;
80619+ }
80620+ }
80621+ if (encini == NULL && macini == NULL)
80622+ return -EINVAL;
80623+ if (encini) {
80624+ /* validate key length */
80625+ switch (encini->cri_alg) {
80626+ case CRYPTO_DES_CBC:
80627+ if (encini->cri_klen != 64)
80628+ return -EINVAL;
80629+ ccmd = DMA_CALGO_DES;
80630+ break;
80631+ case CRYPTO_3DES_CBC:
80632+ if (encini->cri_klen != 192)
80633+ return -EINVAL;
80634+ ccmd = DMA_CALGO_3DES;
80635+ break;
80636+ case CRYPTO_AES_CBC:
80637+ if (encini->cri_klen != 128 &&
80638+ encini->cri_klen != 192 &&
80639+ encini->cri_klen != 256)
80640+ return -EINVAL;
80641+ ccmd = DMA_CALGO_AES;
80642+ break;
80643+ case CRYPTO_ARC4:
80644+ if (encini->cri_klen != 128)
80645+ return -EINVAL;
80646+ ccmd = DMA_CALGO_ARC;
80647+ break;
80648+ default:
80649+ DPRINTF("UNKNOWN encini->cri_alg %d\n",
80650+ encini->cri_alg);
80651+ return -EINVAL;
80652+ }
80653+ }
80654+
80655+ if (macini) {
80656+ switch (macini->cri_alg) {
80657+ case CRYPTO_MD5:
80658+ case CRYPTO_MD5_HMAC:
80659+ blksz = 16;
80660+ break;
80661+ case CRYPTO_SHA1:
80662+ case CRYPTO_SHA1_HMAC:
80663+ blksz = 20;
80664+ break;
80665+ default:
80666+ DPRINTF("UNKNOWN macini->cri_alg %d\n",
80667+ macini->cri_alg);
80668+ return -EINVAL;
80669+ }
80670+ if (((macini->cri_klen + 7) / 8) > blksz) {
80671+ DPRINTF("key length %d bigger than blksize %d not supported\n",
80672+ ((macini->cri_klen + 7) / 8), blksz);
80673+ return -EINVAL;
80674+ }
80675+ }
80676+
80677+ for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
80678+ if (sc->sc_sessions[sesn] == NULL) {
80679+ sc->sc_sessions[sesn] = (struct pasemi_session *)
80680+ kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
80681+ ses = sc->sc_sessions[sesn];
80682+ break;
80683+ } else if (sc->sc_sessions[sesn]->used == 0) {
80684+ ses = sc->sc_sessions[sesn];
80685+ break;
80686+ }
80687+ }
80688+
80689+ if (ses == NULL) {
80690+ sespp = (struct pasemi_session **)
80691+ kzalloc(sc->sc_nsessions * 2 *
80692+ sizeof(struct pasemi_session *), GFP_ATOMIC);
80693+ if (sespp == NULL)
80694+ return -ENOMEM;
80695+ memcpy(sespp, sc->sc_sessions,
80696+ sc->sc_nsessions * sizeof(struct pasemi_session *));
80697+ kfree(sc->sc_sessions);
80698+ sc->sc_sessions = sespp;
80699+ sesn = sc->sc_nsessions;
80700+ ses = sc->sc_sessions[sesn] = (struct pasemi_session *)
80701+ kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
80702+ if (ses == NULL)
80703+ return -ENOMEM;
80704+ sc->sc_nsessions *= 2;
80705+ }
80706+
80707+ ses->used = 1;
80708+
80709+ ses->dma_addr = pci_map_single(sc->dma_pdev, (void *) ses->civ,
80710+ sizeof(struct pasemi_session), DMA_TO_DEVICE);
80711+
80712+ /* enter the channel scheduler */
80713+ spin_lock_irqsave(&sc->sc_chnlock, flags);
80714+
80715+ /* ARC4 has to be processed by the even channel */
80716+ if (encini && (encini->cri_alg == CRYPTO_ARC4))
80717+ ses->chan = sc->sc_lastchn & ~1;
80718+ else
80719+ ses->chan = sc->sc_lastchn;
80720+ sc->sc_lastchn = (sc->sc_lastchn + 1) % sc->sc_num_channels;
80721+
80722+ spin_unlock_irqrestore(&sc->sc_chnlock, flags);
80723+
80724+ txring = &sc->tx[ses->chan];
80725+
80726+ if (encini) {
80727+ ses->ccmd = ccmd;
80728+
80729+ /* get an IV */
80730+ /* XXX may read fewer than requested */
80731+ get_random_bytes(ses->civ, sizeof(ses->civ));
80732+
80733+ ses->keysz = (encini->cri_klen - 63) / 64;
80734+ memcpy(ses->key, encini->cri_key, (ses->keysz + 1) * 8);
80735+
80736+ pasemi_desc_start(&init_desc,
80737+ XCT_CTRL_HDR(ses->chan, (encini && macini) ? 0x68 : 0x40, DMA_FN_CIV0));
80738+ pasemi_desc_build(&init_desc,
80739+ XCT_FUN_SRC_PTR((encini && macini) ? 0x68 : 0x40, ses->dma_addr));
80740+ }
80741+ if (macini) {
80742+ if (macini->cri_alg == CRYPTO_MD5_HMAC ||
80743+ macini->cri_alg == CRYPTO_SHA1_HMAC)
80744+ memcpy(ses->hkey, macini->cri_key, blksz);
80745+ else {
80746+ /* Load initialization constants(RFC 1321, 3174) */
80747+ ses->hiv[0] = 0x67452301efcdab89ULL;
80748+ ses->hiv[1] = 0x98badcfe10325476ULL;
80749+ ses->hiv[2] = 0xc3d2e1f000000000ULL;
80750+ }
80751+ ses->hseq = 0ULL;
80752+ }
80753+
80754+ spin_lock_irqsave(&txring->fill_lock, flags);
80755+
80756+ if (((txring->next_to_fill + pasemi_desc_size(&init_desc)) -
80757+ txring->next_to_clean) > TX_RING_SIZE) {
80758+ spin_unlock_irqrestore(&txring->fill_lock, flags);
80759+ return ERESTART;
80760+ }
80761+
80762+ if (encini) {
80763+ pasemi_ring_add_desc(txring, &init_desc, NULL);
80764+ pasemi_ring_incr(sc, ses->chan,
80765+ pasemi_desc_size(&init_desc));
80766+ }
80767+
80768+ txring->sesn = sesn;
80769+ spin_unlock_irqrestore(&txring->fill_lock, flags);
80770+
80771+ *sidp = PASEMI_SID(sesn);
80772+ return 0;
80773+}
80774+
80775+/*
80776+ * Deallocate a session.
80777+ */
80778+static int
80779+pasemi_freesession(device_t dev, u_int64_t tid)
80780+{
80781+ struct pasemi_softc *sc = device_get_softc(dev);
80782+ int session;
80783+ u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
80784+
80785+ DPRINTF("%s()\n", __FUNCTION__);
80786+
80787+ if (sc == NULL)
80788+ return -EINVAL;
80789+ session = PASEMI_SESSION(sid);
80790+ if (session >= sc->sc_nsessions || !sc->sc_sessions[session])
80791+ return -EINVAL;
80792+
80793+ pci_unmap_single(sc->dma_pdev,
80794+ sc->sc_sessions[session]->dma_addr,
80795+ sizeof(struct pasemi_session), DMA_TO_DEVICE);
80796+ memset(sc->sc_sessions[session], 0,
80797+ sizeof(struct pasemi_session));
80798+
80799+ return 0;
80800+}
80801+
80802+static int
80803+pasemi_process(device_t dev, struct cryptop *crp, int hint)
80804+{
80805+
80806+ int err = 0, ivsize, srclen = 0, reinit = 0, reinit_size = 0, chsel;
80807+ struct pasemi_softc *sc = device_get_softc(dev);
80808+ struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
80809+ caddr_t ivp;
80810+ struct pasemi_desc init_desc, work_desc;
80811+ struct pasemi_session *ses;
80812+ struct sk_buff *skb;
80813+ struct uio *uiop;
80814+ unsigned long flags;
80815+ struct pasemi_fnu_txring *txring;
80816+
80817+ DPRINTF("%s()\n", __FUNCTION__);
80818+
80819+ if (crp == NULL || crp->crp_callback == NULL || sc == NULL)
80820+ return -EINVAL;
80821+
80822+ crp->crp_etype = 0;
80823+ if (PASEMI_SESSION(crp->crp_sid) >= sc->sc_nsessions)
80824+ return -EINVAL;
80825+
80826+ ses = sc->sc_sessions[PASEMI_SESSION(crp->crp_sid)];
80827+
80828+ crd1 = crp->crp_desc;
80829+ if (crd1 == NULL) {
80830+ err = -EINVAL;
80831+ goto errout;
80832+ }
80833+ crd2 = crd1->crd_next;
80834+
80835+ if (ALG_IS_SIG(crd1->crd_alg)) {
80836+ maccrd = crd1;
80837+ if (crd2 == NULL)
80838+ enccrd = NULL;
80839+ else if (ALG_IS_CIPHER(crd2->crd_alg) &&
80840+ (crd2->crd_flags & CRD_F_ENCRYPT) == 0)
80841+ enccrd = crd2;
80842+ else
80843+ goto erralg;
80844+ } else if (ALG_IS_CIPHER(crd1->crd_alg)) {
80845+ enccrd = crd1;
80846+ if (crd2 == NULL)
80847+ maccrd = NULL;
80848+ else if (ALG_IS_SIG(crd2->crd_alg) &&
80849+ (crd1->crd_flags & CRD_F_ENCRYPT))
80850+ maccrd = crd2;
80851+ else
80852+ goto erralg;
80853+ } else
80854+ goto erralg;
80855+
80856+ chsel = ses->chan;
80857+
80858+ txring = &sc->tx[chsel];
80859+
80860+ if (enccrd && !maccrd) {
80861+ if (enccrd->crd_alg == CRYPTO_ARC4)
80862+ reinit = 1;
80863+ reinit_size = 0x40;
80864+ srclen = crp->crp_ilen;
80865+
80866+ pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I
80867+ | XCT_FUN_FUN(chsel));
80868+ if (enccrd->crd_flags & CRD_F_ENCRYPT)
80869+ pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_ENC);
80870+ else
80871+ pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_DEC);
80872+ } else if (enccrd && maccrd) {
80873+ if (enccrd->crd_alg == CRYPTO_ARC4)
80874+ reinit = 1;
80875+ reinit_size = 0x68;
80876+
80877+ if (enccrd->crd_flags & CRD_F_ENCRYPT) {
80878+ /* Encrypt -> Authenticate */
80879+ pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_ENC_SIG
80880+ | XCT_FUN_A | XCT_FUN_FUN(chsel));
80881+ srclen = maccrd->crd_skip + maccrd->crd_len;
80882+ } else {
80883+ /* Authenticate -> Decrypt */
80884+ pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG_DEC
80885+ | XCT_FUN_24BRES | XCT_FUN_FUN(chsel));
80886+ pasemi_desc_build(&work_desc, 0);
80887+ pasemi_desc_build(&work_desc, 0);
80888+ pasemi_desc_build(&work_desc, 0);
80889+ work_desc.postop = PASEMI_CHECK_SIG;
80890+ srclen = crp->crp_ilen;
80891+ }
80892+
80893+ pasemi_desc_hdr(&work_desc, XCT_FUN_SHL(maccrd->crd_skip / 4));
80894+ pasemi_desc_hdr(&work_desc, XCT_FUN_CHL(enccrd->crd_skip - maccrd->crd_skip));
80895+ } else if (!enccrd && maccrd) {
80896+ srclen = maccrd->crd_len;
80897+
80898+ pasemi_desc_start(&init_desc,
80899+ XCT_CTRL_HDR(chsel, 0x58, DMA_FN_HKEY0));
80900+ pasemi_desc_build(&init_desc,
80901+ XCT_FUN_SRC_PTR(0x58, ((struct pasemi_session *)ses->dma_addr)->hkey));
80902+
80903+ pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG
80904+ | XCT_FUN_A | XCT_FUN_FUN(chsel));
80905+ }
80906+
80907+ if (enccrd) {
80908+ switch (enccrd->crd_alg) {
80909+ case CRYPTO_3DES_CBC:
80910+ pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_3DES |
80911+ XCT_FUN_BCM_CBC);
80912+ ivsize = sizeof(u64);
80913+ break;
80914+ case CRYPTO_DES_CBC:
80915+ pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_DES |
80916+ XCT_FUN_BCM_CBC);
80917+ ivsize = sizeof(u64);
80918+ break;
80919+ case CRYPTO_AES_CBC:
80920+ pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_AES |
80921+ XCT_FUN_BCM_CBC);
80922+ ivsize = 2 * sizeof(u64);
80923+ break;
80924+ case CRYPTO_ARC4:
80925+ pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_ARC);
80926+ ivsize = 0;
80927+ break;
80928+ default:
80929+ printk(DRV_NAME ": unimplemented enccrd->crd_alg %d\n",
80930+ enccrd->crd_alg);
80931+ err = -EINVAL;
80932+ goto errout;
80933+ }
80934+
80935+ ivp = (ivsize == sizeof(u64)) ? (caddr_t) &ses->civ[1] : (caddr_t) &ses->civ[0];
80936+ if (enccrd->crd_flags & CRD_F_ENCRYPT) {
80937+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
80938+ memcpy(ivp, enccrd->crd_iv, ivsize);
80939+ /* If IV is not present in the buffer already, it has to be copied there */
80940+ if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0)
80941+ crypto_copyback(crp->crp_flags, crp->crp_buf,
80942+ enccrd->crd_inject, ivsize, ivp);
80943+ } else {
80944+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
80945+ /* IV is provided expicitly in descriptor */
80946+ memcpy(ivp, enccrd->crd_iv, ivsize);
80947+ else
80948+ /* IV is provided in the packet */
80949+ crypto_copydata(crp->crp_flags, crp->crp_buf,
80950+ enccrd->crd_inject, ivsize,
80951+ ivp);
80952+ }
80953+ }
80954+
80955+ if (maccrd) {
80956+ switch (maccrd->crd_alg) {
80957+ case CRYPTO_MD5:
80958+ pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_MD5 |
80959+ XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
80960+ break;
80961+ case CRYPTO_SHA1:
80962+ pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_SHA1 |
80963+ XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
80964+ break;
80965+ case CRYPTO_MD5_HMAC:
80966+ pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_MD5 |
80967+ XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
80968+ break;
80969+ case CRYPTO_SHA1_HMAC:
80970+ pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_SHA1 |
80971+ XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
80972+ break;
80973+ default:
80974+ printk(DRV_NAME ": unimplemented maccrd->crd_alg %d\n",
80975+ maccrd->crd_alg);
80976+ err = -EINVAL;
80977+ goto errout;
80978+ }
80979+ }
80980+
80981+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
80982+ /* using SKB buffers */
80983+ skb = (struct sk_buff *)crp->crp_buf;
80984+ if (skb_shinfo(skb)->nr_frags) {
80985+ printk(DRV_NAME ": skb frags unimplemented\n");
80986+ err = -EINVAL;
80987+ goto errout;
80988+ }
80989+ pasemi_desc_build(
80990+ &work_desc,
80991+ XCT_FUN_DST_PTR(skb->len, pci_map_single(
80992+ sc->dma_pdev, skb->data,
80993+ skb->len, DMA_TO_DEVICE)));
80994+ pasemi_desc_build(
80995+ &work_desc,
80996+ XCT_FUN_SRC_PTR(
80997+ srclen, pci_map_single(
80998+ sc->dma_pdev, skb->data,
80999+ srclen, DMA_TO_DEVICE)));
81000+ pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
81001+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
81002+ /* using IOV buffers */
81003+ uiop = (struct uio *)crp->crp_buf;
81004+ if (uiop->uio_iovcnt > 1) {
81005+ printk(DRV_NAME ": iov frags unimplemented\n");
81006+ err = -EINVAL;
81007+ goto errout;
81008+ }
81009+
81010+ /* crp_olen is never set; always use crp_ilen */
81011+ pasemi_desc_build(
81012+ &work_desc,
81013+ XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
81014+ sc->dma_pdev,
81015+ uiop->uio_iov->iov_base,
81016+ crp->crp_ilen, DMA_TO_DEVICE)));
81017+ pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
81018+
81019+ pasemi_desc_build(
81020+ &work_desc,
81021+ XCT_FUN_SRC_PTR(srclen, pci_map_single(
81022+ sc->dma_pdev,
81023+ uiop->uio_iov->iov_base,
81024+ srclen, DMA_TO_DEVICE)));
81025+ } else {
81026+ /* using contig buffers */
81027+ pasemi_desc_build(
81028+ &work_desc,
81029+ XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
81030+ sc->dma_pdev,
81031+ crp->crp_buf,
81032+ crp->crp_ilen, DMA_TO_DEVICE)));
81033+ pasemi_desc_build(
81034+ &work_desc,
81035+ XCT_FUN_SRC_PTR(srclen, pci_map_single(
81036+ sc->dma_pdev,
81037+ crp->crp_buf, srclen,
81038+ DMA_TO_DEVICE)));
81039+ pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
81040+ }
81041+
81042+ spin_lock_irqsave(&txring->fill_lock, flags);
81043+
81044+ if (txring->sesn != PASEMI_SESSION(crp->crp_sid)) {
81045+ txring->sesn = PASEMI_SESSION(crp->crp_sid);
81046+ reinit = 1;
81047+ }
81048+
81049+ if (enccrd) {
81050+ pasemi_desc_start(&init_desc,
81051+ XCT_CTRL_HDR(chsel, reinit ? reinit_size : 0x10, DMA_FN_CIV0));
81052+ pasemi_desc_build(&init_desc,
81053+ XCT_FUN_SRC_PTR(reinit ? reinit_size : 0x10, ses->dma_addr));
81054+ }
81055+
81056+ if (((txring->next_to_fill + pasemi_desc_size(&init_desc) +
81057+ pasemi_desc_size(&work_desc)) -
81058+ txring->next_to_clean) > TX_RING_SIZE) {
81059+ spin_unlock_irqrestore(&txring->fill_lock, flags);
81060+ err = ERESTART;
81061+ goto errout;
81062+ }
81063+
81064+ pasemi_ring_add_desc(txring, &init_desc, NULL);
81065+ pasemi_ring_add_desc(txring, &work_desc, crp);
81066+
81067+ pasemi_ring_incr(sc, chsel,
81068+ pasemi_desc_size(&init_desc) +
81069+ pasemi_desc_size(&work_desc));
81070+
81071+ spin_unlock_irqrestore(&txring->fill_lock, flags);
81072+
81073+ mod_timer(&txring->crypto_timer, jiffies + TIMER_INTERVAL);
81074+
81075+ return 0;
81076+
81077+erralg:
81078+ printk(DRV_NAME ": unsupported algorithm or algorithm order alg1 %d alg2 %d\n",
81079+ crd1->crd_alg, crd2->crd_alg);
81080+ err = -EINVAL;
81081+
81082+errout:
81083+ if (err != ERESTART) {
81084+ crp->crp_etype = err;
81085+ crypto_done(crp);
81086+ }
81087+ return err;
81088+}
81089+
81090+static int pasemi_clean_tx(struct pasemi_softc *sc, int chan)
81091+{
81092+ int i, j, ring_idx;
81093+ struct pasemi_fnu_txring *ring = &sc->tx[chan];
81094+ u16 delta_cnt;
81095+ int flags, loops = 10;
81096+ int desc_size;
81097+ struct cryptop *crp;
81098+
81099+ spin_lock_irqsave(&ring->clean_lock, flags);
81100+
81101+ while ((delta_cnt = (dma_status->tx_sta[sc->base_chan + chan]
81102+ & PAS_STATUS_PCNT_M) - ring->total_pktcnt)
81103+ && loops--) {
81104+
81105+ for (i = 0; i < delta_cnt; i++) {
81106+ desc_size = TX_DESC_INFO(ring, ring->next_to_clean).desc_size;
81107+ crp = TX_DESC_INFO(ring, ring->next_to_clean).cf_crp;
81108+ if (crp) {
81109+ ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
81110+ if (TX_DESC_INFO(ring, ring->next_to_clean).desc_postop & PASEMI_CHECK_SIG) {
81111+ /* Need to make sure signature matched,
81112+ * if not - return error */
81113+ if (!(ring->desc[ring_idx + 1] & (1ULL << 63)))
81114+ crp->crp_etype = -EINVAL;
81115+ }
81116+ crypto_done(TX_DESC_INFO(ring,
81117+ ring->next_to_clean).cf_crp);
81118+ TX_DESC_INFO(ring, ring->next_to_clean).cf_crp = NULL;
81119+ pci_unmap_single(
81120+ sc->dma_pdev,
81121+ XCT_PTR_ADDR_LEN(ring->desc[ring_idx + 1]),
81122+ PCI_DMA_TODEVICE);
81123+
81124+ ring->desc[ring_idx] = ring->desc[ring_idx + 1] = 0;
81125+
81126+ ring->next_to_clean++;
81127+ for (j = 1; j < desc_size; j++) {
81128+ ring_idx = 2 *
81129+ (ring->next_to_clean &
81130+ (TX_RING_SIZE-1));
81131+ pci_unmap_single(
81132+ sc->dma_pdev,
81133+ XCT_PTR_ADDR_LEN(ring->desc[ring_idx]),
81134+ PCI_DMA_TODEVICE);
81135+ if (ring->desc[ring_idx + 1])
81136+ pci_unmap_single(
81137+ sc->dma_pdev,
81138+ XCT_PTR_ADDR_LEN(
81139+ ring->desc[
81140+ ring_idx + 1]),
81141+ PCI_DMA_TODEVICE);
81142+ ring->desc[ring_idx] =
81143+ ring->desc[ring_idx + 1] = 0;
81144+ ring->next_to_clean++;
81145+ }
81146+ } else {
81147+ for (j = 0; j < desc_size; j++) {
81148+ ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
81149+ ring->desc[ring_idx] =
81150+ ring->desc[ring_idx + 1] = 0;
81151+ ring->next_to_clean++;
81152+ }
81153+ }
81154+ }
81155+
81156+ ring->total_pktcnt += delta_cnt;
81157+ }
81158+ spin_unlock_irqrestore(&ring->clean_lock, flags);
81159+
81160+ return 0;
81161+}
81162+
81163+static void sweepup_tx(struct pasemi_softc *sc)
81164+{
81165+ int i;
81166+
81167+ for (i = 0; i < sc->sc_num_channels; i++)
81168+ pasemi_clean_tx(sc, i);
81169+}
81170+
81171+static irqreturn_t pasemi_intr(int irq, void *arg, struct pt_regs *regs)
81172+{
81173+ struct pasemi_softc *sc = arg;
81174+ unsigned int reg;
81175+ int chan = irq - sc->base_irq;
81176+ int chan_index = sc->base_chan + chan;
81177+ u64 stat = dma_status->tx_sta[chan_index];
81178+
81179+ DPRINTF("%s()\n", __FUNCTION__);
81180+
81181+ if (!(stat & PAS_STATUS_CAUSE_M))
81182+ return IRQ_NONE;
81183+
81184+ pasemi_clean_tx(sc, chan);
81185+
81186+ stat = dma_status->tx_sta[chan_index];
81187+
81188+ reg = PAS_IOB_DMA_TXCH_RESET_PINTC |
81189+ PAS_IOB_DMA_TXCH_RESET_PCNT(sc->tx[chan].total_pktcnt);
81190+
81191+ if (stat & PAS_STATUS_SOFT)
81192+ reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
81193+
81194+ out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), reg);
81195+
81196+
81197+ return IRQ_HANDLED;
81198+}
81199+
81200+static int pasemi_dma_setup_tx_resources(struct pasemi_softc *sc, int chan)
81201+{
81202+ u32 val;
81203+ int chan_index = chan + sc->base_chan;
81204+ int ret;
81205+ struct pasemi_fnu_txring *ring;
81206+
81207+ ring = &sc->tx[chan];
81208+
81209+ spin_lock_init(&ring->fill_lock);
81210+ spin_lock_init(&ring->clean_lock);
81211+
81212+ ring->desc_info = kzalloc(sizeof(struct pasemi_desc_info) *
81213+ TX_RING_SIZE, GFP_KERNEL);
81214+ if (!ring->desc_info)
81215+ return -ENOMEM;
81216+
81217+ /* Allocate descriptors */
81218+ ring->desc = dma_alloc_coherent(&sc->dma_pdev->dev,
81219+ TX_RING_SIZE *
81220+ 2 * sizeof(u64),
81221+ &ring->dma, GFP_KERNEL);
81222+ if (!ring->desc)
81223+ return -ENOMEM;
81224+
81225+ memset((void *) ring->desc, 0, TX_RING_SIZE * 2 * sizeof(u64));
81226+
81227+ out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), 0x30);
81228+
81229+ ring->total_pktcnt = 0;
81230+
81231+ out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEL(chan_index),
81232+ PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
81233+
81234+ val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
81235+ val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2);
81236+
81237+ out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEU(chan_index), val);
81238+
81239+ out_le32(sc->dma_regs + PAS_DMA_TXCHAN_CFG(chan_index),
81240+ PAS_DMA_TXCHAN_CFG_TY_FUNC |
81241+ PAS_DMA_TXCHAN_CFG_TATTR(chan) |
81242+ PAS_DMA_TXCHAN_CFG_WT(2));
81243+
81244+ /* enable tx channel */
81245+ out_le32(sc->dma_regs +
81246+ PAS_DMA_TXCHAN_TCMDSTA(chan_index),
81247+ PAS_DMA_TXCHAN_TCMDSTA_EN);
81248+
81249+ out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_CFG(chan_index),
81250+ PAS_IOB_DMA_TXCH_CFG_CNTTH(1000));
81251+
81252+ ring->next_to_fill = 0;
81253+ ring->next_to_clean = 0;
81254+
81255+ snprintf(ring->irq_name, sizeof(ring->irq_name),
81256+ "%s%d", "crypto", chan);
81257+
81258+ ring->irq = irq_create_mapping(NULL, sc->base_irq + chan);
81259+ ret = request_irq(ring->irq, (irq_handler_t)
81260+ pasemi_intr, IRQF_DISABLED, ring->irq_name, sc);
81261+ if (ret) {
81262+ printk(KERN_ERR DRV_NAME ": failed to hook irq %d ret %d\n",
81263+ ring->irq, ret);
81264+ ring->irq = -1;
81265+ return ret;
81266+ }
81267+
81268+ setup_timer(&ring->crypto_timer, (void *) sweepup_tx, (unsigned long) sc);
81269+
81270+ return 0;
81271+}
81272+
81273+static device_method_t pasemi_methods = {
81274+ /* crypto device methods */
81275+ DEVMETHOD(cryptodev_newsession, pasemi_newsession),
81276+ DEVMETHOD(cryptodev_freesession, pasemi_freesession),
81277+ DEVMETHOD(cryptodev_process, pasemi_process),
81278+};
81279+
81280+/* Set up the crypto device structure, private data,
81281+ * and anything else we need before we start */
81282+
81283+static int __devinit
81284+pasemi_dma_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
81285+{
81286+ struct pasemi_softc *sc;
81287+ int ret, i;
81288+
81289+ DPRINTF(KERN_ERR "%s()\n", __FUNCTION__);
81290+
81291+ sc = kzalloc(sizeof(*sc), GFP_KERNEL);
81292+ if (!sc)
81293+ return -ENOMEM;
81294+
81295+ softc_device_init(sc, DRV_NAME, 1, pasemi_methods);
81296+
81297+ pci_set_drvdata(pdev, sc);
81298+
81299+ spin_lock_init(&sc->sc_chnlock);
81300+
81301+ sc->sc_sessions = (struct pasemi_session **)
81302+ kzalloc(PASEMI_INITIAL_SESSIONS *
81303+ sizeof(struct pasemi_session *), GFP_ATOMIC);
81304+ if (sc->sc_sessions == NULL) {
81305+ ret = -ENOMEM;
81306+ goto out;
81307+ }
81308+
81309+ sc->sc_nsessions = PASEMI_INITIAL_SESSIONS;
81310+ sc->sc_lastchn = 0;
81311+ sc->base_irq = pdev->irq + 6;
81312+ sc->base_chan = 6;
81313+ sc->sc_cid = -1;
81314+ sc->dma_pdev = pdev;
81315+
81316+ sc->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
81317+ if (!sc->iob_pdev) {
81318+ dev_err(&pdev->dev, "Can't find I/O Bridge\n");
81319+ ret = -ENODEV;
81320+ goto out;
81321+ }
81322+
81323+ /* This is hardcoded and ugly, but we have some firmware versions
81324+ * who don't provide the register space in the device tree. Luckily
81325+ * they are at well-known locations so we can just do the math here.
81326+ */
81327+ sc->dma_regs =
81328+ ioremap(0xe0000000 + (sc->dma_pdev->devfn << 12), 0x2000);
81329+ sc->iob_regs =
81330+ ioremap(0xe0000000 + (sc->iob_pdev->devfn << 12), 0x2000);
81331+ if (!sc->dma_regs || !sc->iob_regs) {
81332+ dev_err(&pdev->dev, "Can't map registers\n");
81333+ ret = -ENODEV;
81334+ goto out;
81335+ }
81336+
81337+ dma_status = __ioremap(0xfd800000, 0x1000, 0);
81338+ if (!dma_status) {
81339+ ret = -ENODEV;
81340+ dev_err(&pdev->dev, "Can't map dmastatus space\n");
81341+ goto out;
81342+ }
81343+
81344+ sc->tx = (struct pasemi_fnu_txring *)
81345+ kzalloc(sizeof(struct pasemi_fnu_txring)
81346+ * 8, GFP_KERNEL);
81347+ if (!sc->tx) {
81348+ ret = -ENOMEM;
81349+ goto out;
81350+ }
81351+
81352+ /* Initialize the h/w */
81353+ out_le32(sc->dma_regs + PAS_DMA_COM_CFG,
81354+ (in_le32(sc->dma_regs + PAS_DMA_COM_CFG) |
81355+ PAS_DMA_COM_CFG_FWF));
81356+ out_le32(sc->dma_regs + PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
81357+
81358+ for (i = 0; i < PASEMI_FNU_CHANNELS; i++) {
81359+ sc->sc_num_channels++;
81360+ ret = pasemi_dma_setup_tx_resources(sc, i);
81361+ if (ret)
81362+ goto out;
81363+ }
81364+
81365+ sc->sc_cid = crypto_get_driverid(softc_get_device(sc),
81366+ CRYPTOCAP_F_HARDWARE);
81367+ if (sc->sc_cid < 0) {
81368+ printk(KERN_ERR DRV_NAME ": could not get crypto driver id\n");
81369+ ret = -ENXIO;
81370+ goto out;
81371+ }
81372+
81373+ /* register algorithms with the framework */
81374+ printk(DRV_NAME ":");
81375+
81376+ crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
81377+ crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
81378+ crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
81379+ crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
81380+ crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
81381+ crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
81382+ crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
81383+ crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
81384+
81385+ return 0;
81386+
81387+out:
81388+ pasemi_dma_remove(pdev);
81389+ return ret;
81390+}
81391+
81392+#define MAX_RETRIES 5000
81393+
81394+static void pasemi_free_tx_resources(struct pasemi_softc *sc, int chan)
81395+{
81396+ struct pasemi_fnu_txring *ring = &sc->tx[chan];
81397+ int chan_index = chan + sc->base_chan;
81398+ int retries;
81399+ u32 stat;
81400+
81401+ /* Stop the channel */
81402+ out_le32(sc->dma_regs +
81403+ PAS_DMA_TXCHAN_TCMDSTA(chan_index),
81404+ PAS_DMA_TXCHAN_TCMDSTA_ST);
81405+
81406+ for (retries = 0; retries < MAX_RETRIES; retries++) {
81407+ stat = in_le32(sc->dma_regs +
81408+ PAS_DMA_TXCHAN_TCMDSTA(chan_index));
81409+ if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
81410+ break;
81411+ cond_resched();
81412+ }
81413+
81414+ if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
81415+ dev_err(&sc->dma_pdev->dev, "Failed to stop tx channel %d\n",
81416+ chan_index);
81417+
81418+ /* Disable the channel */
81419+ out_le32(sc->dma_regs +
81420+ PAS_DMA_TXCHAN_TCMDSTA(chan_index),
81421+ 0);
81422+
81423+ if (ring->desc_info)
81424+ kfree((void *) ring->desc_info);
81425+ if (ring->desc)
81426+ dma_free_coherent(&sc->dma_pdev->dev,
81427+ TX_RING_SIZE *
81428+ 2 * sizeof(u64),
81429+ (void *) ring->desc, ring->dma);
81430+ if (ring->irq != -1)
81431+ free_irq(ring->irq, sc);
81432+
81433+ del_timer(&ring->crypto_timer);
81434+}
81435+
81436+static void __devexit pasemi_dma_remove(struct pci_dev *pdev)
81437+{
81438+ struct pasemi_softc *sc = pci_get_drvdata(pdev);
81439+ int i;
81440+
81441+ DPRINTF("%s()\n", __FUNCTION__);
81442+
81443+ if (sc->sc_cid >= 0) {
81444+ crypto_unregister_all(sc->sc_cid);
81445+ }
81446+
81447+ if (sc->tx) {
81448+ for (i = 0; i < sc->sc_num_channels; i++)
81449+ pasemi_free_tx_resources(sc, i);
81450+
81451+ kfree(sc->tx);
81452+ }
81453+ if (sc->sc_sessions) {
81454+ for (i = 0; i < sc->sc_nsessions; i++)
81455+ kfree(sc->sc_sessions[i]);
81456+ kfree(sc->sc_sessions);
81457+ }
81458+ if (sc->iob_pdev)
81459+ pci_dev_put(sc->iob_pdev);
81460+ if (sc->dma_regs)
81461+ iounmap(sc->dma_regs);
81462+ if (sc->iob_regs)
81463+ iounmap(sc->iob_regs);
81464+ kfree(sc);
81465+}
81466+
81467+static struct pci_device_id pasemi_dma_pci_tbl[] = {
81468+ { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa007) },
81469+};
81470+
81471+MODULE_DEVICE_TABLE(pci, pasemi_dma_pci_tbl);
81472+
81473+static struct pci_driver pasemi_dma_driver = {
81474+ .name = "pasemi_dma",
81475+ .id_table = pasemi_dma_pci_tbl,
81476+ .probe = pasemi_dma_probe,
81477+ .remove = __devexit_p(pasemi_dma_remove),
81478+};
81479+
81480+static void __exit pasemi_dma_cleanup_module(void)
81481+{
81482+ pci_unregister_driver(&pasemi_dma_driver);
81483+ __iounmap(dma_status);
81484+ dma_status = NULL;
81485+}
81486+
81487+int pasemi_dma_init_module(void)
81488+{
81489+ return pci_register_driver(&pasemi_dma_driver);
81490+}
81491+
81492+module_init(pasemi_dma_init_module);
81493+module_exit(pasemi_dma_cleanup_module);
81494+
81495+MODULE_LICENSE("Dual BSD/GPL");
81496+MODULE_AUTHOR("Egor Martovetsky egor@pasemi.com");
81497+MODULE_DESCRIPTION("OCF driver for PA Semi PWRficient DMA Crypto Engine");
81498diff --git a/crypto/ocf/pasemi/pasemi_fnu.h b/crypto/ocf/pasemi/pasemi_fnu.h
81499new file mode 100644
81500index 0000000..1a0dcc8
81501--- /dev/null
81502+++ b/crypto/ocf/pasemi/pasemi_fnu.h
81503@@ -0,0 +1,410 @@
81504+/*
81505+ * Copyright (C) 2007 PA Semi, Inc
81506+ *
81507+ * Driver for the PA Semi PWRficient DMA Crypto Engine, soft state and
81508+ * hardware register layouts.
81509+ *
81510+ * This program is free software; you can redistribute it and/or modify
81511+ * it under the terms of the GNU General Public License version 2 as
81512+ * published by the Free Software Foundation.
81513+ *
81514+ * This program is distributed in the hope that it will be useful,
81515+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
81516+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
81517+ * GNU General Public License for more details.
81518+ *
81519+ * You should have received a copy of the GNU General Public License
81520+ * along with this program; if not, write to the Free Software
81521+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
81522+ */
81523+
81524+#ifndef PASEMI_FNU_H
81525+#define PASEMI_FNU_H
81526+
81527+#include <linux/spinlock.h>
81528+
81529+#define PASEMI_SESSION(sid) ((sid) & 0xffffffff)
81530+#define PASEMI_SID(sesn) ((sesn) & 0xffffffff)
81531+#define DPRINTF(a...) if (debug) { printk(DRV_NAME ": " a); }
81532+
81533+/* Must be a power of two */
81534+#define RX_RING_SIZE 512
81535+#define TX_RING_SIZE 512
81536+#define TX_DESC(ring, num) ((ring)->desc[2 * (num & (TX_RING_SIZE-1))])
81537+#define TX_DESC_INFO(ring, num) ((ring)->desc_info[(num) & (TX_RING_SIZE-1)])
81538+#define MAX_DESC_SIZE 8
81539+#define PASEMI_INITIAL_SESSIONS 10
81540+#define PASEMI_FNU_CHANNELS 8
81541+
81542+/* DMA descriptor */
81543+struct pasemi_desc {
81544+ u64 quad[2*MAX_DESC_SIZE];
81545+ int quad_cnt;
81546+ int size;
81547+ int postop;
81548+};
81549+
81550+/*
81551+ * Holds per descriptor data
81552+ */
81553+struct pasemi_desc_info {
81554+ int desc_size;
81555+ int desc_postop;
81556+#define PASEMI_CHECK_SIG 0x1
81557+
81558+ struct cryptop *cf_crp;
81559+};
81560+
81561+/*
81562+ * Holds per channel data
81563+ */
81564+struct pasemi_fnu_txring {
81565+ volatile u64 *desc;
81566+ volatile struct
81567+ pasemi_desc_info *desc_info;
81568+ dma_addr_t dma;
81569+ struct timer_list crypto_timer;
81570+ spinlock_t fill_lock;
81571+ spinlock_t clean_lock;
81572+ unsigned int next_to_fill;
81573+ unsigned int next_to_clean;
81574+ u16 total_pktcnt;
81575+ int irq;
81576+ int sesn;
81577+ char irq_name[10];
81578+};
81579+
81580+/*
81581+ * Holds data specific to a single pasemi device.
81582+ */
81583+struct pasemi_softc {
81584+ softc_device_decl sc_cdev;
81585+ struct pci_dev *dma_pdev; /* device backpointer */
81586+ struct pci_dev *iob_pdev; /* device backpointer */
81587+ void __iomem *dma_regs;
81588+ void __iomem *iob_regs;
81589+ int base_irq;
81590+ int base_chan;
81591+ int32_t sc_cid; /* crypto tag */
81592+ int sc_nsessions;
81593+ struct pasemi_session **sc_sessions;
81594+ int sc_num_channels;/* number of crypto channels */
81595+
81596+ /* pointer to the array of txring datastructures, one txring per channel */
81597+ struct pasemi_fnu_txring *tx;
81598+
81599+ /*
81600+ * mutual exclusion for the channel scheduler
81601+ */
81602+ spinlock_t sc_chnlock;
81603+ /* last channel used, for now use round-robin to allocate channels */
81604+ int sc_lastchn;
81605+};
81606+
81607+struct pasemi_session {
81608+ u64 civ[2];
81609+ u64 keysz;
81610+ u64 key[4];
81611+ u64 ccmd;
81612+ u64 hkey[4];
81613+ u64 hseq;
81614+ u64 giv[2];
81615+ u64 hiv[4];
81616+
81617+ int used;
81618+ dma_addr_t dma_addr;
81619+ int chan;
81620+};
81621+
81622+/* status register layout in IOB region, at 0xfd800000 */
81623+struct pasdma_status {
81624+ u64 rx_sta[64];
81625+ u64 tx_sta[20];
81626+};
81627+
81628+#define ALG_IS_CIPHER(alg) ((alg == CRYPTO_DES_CBC) || \
81629+ (alg == CRYPTO_3DES_CBC) || \
81630+ (alg == CRYPTO_AES_CBC) || \
81631+ (alg == CRYPTO_ARC4) || \
81632+ (alg == CRYPTO_NULL_CBC))
81633+
81634+#define ALG_IS_SIG(alg) ((alg == CRYPTO_MD5) || \
81635+ (alg == CRYPTO_MD5_HMAC) || \
81636+ (alg == CRYPTO_SHA1) || \
81637+ (alg == CRYPTO_SHA1_HMAC) || \
81638+ (alg == CRYPTO_NULL_HMAC))
81639+
81640+enum {
81641+ PAS_DMA_COM_TXCMD = 0x100, /* Transmit Command Register */
81642+ PAS_DMA_COM_TXSTA = 0x104, /* Transmit Status Register */
81643+ PAS_DMA_COM_RXCMD = 0x108, /* Receive Command Register */
81644+ PAS_DMA_COM_RXSTA = 0x10c, /* Receive Status Register */
81645+ PAS_DMA_COM_CFG = 0x114, /* DMA Configuration Register */
81646+};
81647+
81648+/* All these registers live in the PCI configuration space for the DMA PCI
81649+ * device. Use the normal PCI config access functions for them.
81650+ */
81651+
81652+#define PAS_DMA_COM_CFG_FWF 0x18000000
81653+
81654+#define PAS_DMA_COM_TXCMD_EN 0x00000001 /* enable */
81655+#define PAS_DMA_COM_TXSTA_ACT 0x00000001 /* active */
81656+#define PAS_DMA_COM_RXCMD_EN 0x00000001 /* enable */
81657+#define PAS_DMA_COM_RXSTA_ACT 0x00000001 /* active */
81658+
81659+#define _PAS_DMA_TXCHAN_STRIDE 0x20 /* Size per channel */
81660+#define _PAS_DMA_TXCHAN_TCMDSTA 0x300 /* Command / Status */
81661+#define _PAS_DMA_TXCHAN_CFG 0x304 /* Configuration */
81662+#define _PAS_DMA_TXCHAN_DSCRBU 0x308 /* Descriptor BU Allocation */
81663+#define _PAS_DMA_TXCHAN_INCR 0x310 /* Descriptor increment */
81664+#define _PAS_DMA_TXCHAN_CNT 0x314 /* Descriptor count/offset */
81665+#define _PAS_DMA_TXCHAN_BASEL 0x318 /* Descriptor ring base (low) */
81666+#define _PAS_DMA_TXCHAN_BASEU 0x31c /* (high) */
81667+#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE)
81668+#define PAS_DMA_TXCHAN_TCMDSTA_EN 0x00000001 /* Enabled */
81669+#define PAS_DMA_TXCHAN_TCMDSTA_ST 0x00000002 /* Stop interface */
81670+#define PAS_DMA_TXCHAN_TCMDSTA_ACT 0x00010000 /* Active */
81671+#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
81672+#define PAS_DMA_TXCHAN_CFG_TY_FUNC 0x00000002 /* Type = interface */
81673+#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */
81674+#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c
81675+#define PAS_DMA_TXCHAN_CFG_TATTR_S 2
81676+#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
81677+ PAS_DMA_TXCHAN_CFG_TATTR_M)
81678+#define PAS_DMA_TXCHAN_CFG_WT_M 0x000001c0
81679+#define PAS_DMA_TXCHAN_CFG_WT_S 6
81680+#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
81681+ PAS_DMA_TXCHAN_CFG_WT_M)
81682+#define PAS_DMA_TXCHAN_CFG_LPSQ_FAST 0x00000400
81683+#define PAS_DMA_TXCHAN_CFG_LPDQ_FAST 0x00000800
81684+#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */
81685+#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */
81686+#define PAS_DMA_TXCHAN_CFG_UP 0x00004000 /* update tx descr when sent */
81687+#define PAS_DMA_TXCHAN_INCR(c) (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
81688+#define PAS_DMA_TXCHAN_BASEL(c) (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
81689+#define PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0
81690+#define PAS_DMA_TXCHAN_BASEL_BRBL_S 0
81691+#define PAS_DMA_TXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \
81692+ PAS_DMA_TXCHAN_BASEL_BRBL_M)
81693+#define PAS_DMA_TXCHAN_BASEU(c) (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE)
81694+#define PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff
81695+#define PAS_DMA_TXCHAN_BASEU_BRBH_S 0
81696+#define PAS_DMA_TXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \
81697+ PAS_DMA_TXCHAN_BASEU_BRBH_M)
81698+/* # of cache lines worth of buffer ring */
81699+#define PAS_DMA_TXCHAN_BASEU_SIZ_M 0x3fff0000
81700+#define PAS_DMA_TXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */
81701+#define PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \
81702+ PAS_DMA_TXCHAN_BASEU_SIZ_M)
81703+
81704+#define PAS_STATUS_PCNT_M 0x000000000000ffffull
81705+#define PAS_STATUS_PCNT_S 0
81706+#define PAS_STATUS_DCNT_M 0x00000000ffff0000ull
81707+#define PAS_STATUS_DCNT_S 16
81708+#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull
81709+#define PAS_STATUS_BPCNT_S 32
81710+#define PAS_STATUS_CAUSE_M 0xf000000000000000ull
81711+#define PAS_STATUS_TIMER 0x1000000000000000ull
81712+#define PAS_STATUS_ERROR 0x2000000000000000ull
81713+#define PAS_STATUS_SOFT 0x4000000000000000ull
81714+#define PAS_STATUS_INT 0x8000000000000000ull
81715+
81716+#define PAS_IOB_DMA_RXCH_CFG(i) (0x1100 + (i)*4)
81717+#define PAS_IOB_DMA_RXCH_CFG_CNTTH_M 0x00000fff
81718+#define PAS_IOB_DMA_RXCH_CFG_CNTTH_S 0
81719+#define PAS_IOB_DMA_RXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \
81720+ PAS_IOB_DMA_RXCH_CFG_CNTTH_M)
81721+#define PAS_IOB_DMA_TXCH_CFG(i) (0x1200 + (i)*4)
81722+#define PAS_IOB_DMA_TXCH_CFG_CNTTH_M 0x00000fff
81723+#define PAS_IOB_DMA_TXCH_CFG_CNTTH_S 0
81724+#define PAS_IOB_DMA_TXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \
81725+ PAS_IOB_DMA_TXCH_CFG_CNTTH_M)
81726+#define PAS_IOB_DMA_RXCH_STAT(i) (0x1300 + (i)*4)
81727+#define PAS_IOB_DMA_RXCH_STAT_INTGEN 0x00001000
81728+#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_M 0x00000fff
81729+#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_S 0
81730+#define PAS_IOB_DMA_RXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\
81731+ PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
81732+#define PAS_IOB_DMA_TXCH_STAT(i) (0x1400 + (i)*4)
81733+#define PAS_IOB_DMA_TXCH_STAT_INTGEN 0x00001000
81734+#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_M 0x00000fff
81735+#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_S 0
81736+#define PAS_IOB_DMA_TXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\
81737+ PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
81738+#define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4)
81739+#define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000
81740+#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 16
81741+#define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \
81742+ PAS_IOB_DMA_RXCH_RESET_PCNT_M)
81743+#define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020
81744+#define PAS_IOB_DMA_RXCH_RESET_DCNTRST 0x00000010
81745+#define PAS_IOB_DMA_RXCH_RESET_TINTC 0x00000008
81746+#define PAS_IOB_DMA_RXCH_RESET_DINTC 0x00000004
81747+#define PAS_IOB_DMA_RXCH_RESET_SINTC 0x00000002
81748+#define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001
81749+#define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4)
81750+#define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000
81751+#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 16
81752+#define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \
81753+ PAS_IOB_DMA_TXCH_RESET_PCNT_M)
81754+#define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020
81755+#define PAS_IOB_DMA_TXCH_RESET_DCNTRST 0x00000010
81756+#define PAS_IOB_DMA_TXCH_RESET_TINTC 0x00000008
81757+#define PAS_IOB_DMA_TXCH_RESET_DINTC 0x00000004
81758+#define PAS_IOB_DMA_TXCH_RESET_SINTC 0x00000002
81759+#define PAS_IOB_DMA_TXCH_RESET_PINTC 0x00000001
81760+
81761+#define PAS_IOB_DMA_COM_TIMEOUTCFG 0x1700
81762+#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M 0x00ffffff
81763+#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S 0
81764+#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x) (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \
81765+ PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M)
81766+
81767+/* Transmit descriptor fields */
81768+#define XCT_MACTX_T 0x8000000000000000ull
81769+#define XCT_MACTX_ST 0x4000000000000000ull
81770+#define XCT_MACTX_NORES 0x0000000000000000ull
81771+#define XCT_MACTX_8BRES 0x1000000000000000ull
81772+#define XCT_MACTX_24BRES 0x2000000000000000ull
81773+#define XCT_MACTX_40BRES 0x3000000000000000ull
81774+#define XCT_MACTX_I 0x0800000000000000ull
81775+#define XCT_MACTX_O 0x0400000000000000ull
81776+#define XCT_MACTX_E 0x0200000000000000ull
81777+#define XCT_MACTX_VLAN_M 0x0180000000000000ull
81778+#define XCT_MACTX_VLAN_NOP 0x0000000000000000ull
81779+#define XCT_MACTX_VLAN_REMOVE 0x0080000000000000ull
81780+#define XCT_MACTX_VLAN_INSERT 0x0100000000000000ull
81781+#define XCT_MACTX_VLAN_REPLACE 0x0180000000000000ull
81782+#define XCT_MACTX_CRC_M 0x0060000000000000ull
81783+#define XCT_MACTX_CRC_NOP 0x0000000000000000ull
81784+#define XCT_MACTX_CRC_INSERT 0x0020000000000000ull
81785+#define XCT_MACTX_CRC_PAD 0x0040000000000000ull
81786+#define XCT_MACTX_CRC_REPLACE 0x0060000000000000ull
81787+#define XCT_MACTX_SS 0x0010000000000000ull
81788+#define XCT_MACTX_LLEN_M 0x00007fff00000000ull
81789+#define XCT_MACTX_LLEN_S 32ull
81790+#define XCT_MACTX_LLEN(x) ((((long)(x)) << XCT_MACTX_LLEN_S) & \
81791+ XCT_MACTX_LLEN_M)
81792+#define XCT_MACTX_IPH_M 0x00000000f8000000ull
81793+#define XCT_MACTX_IPH_S 27ull
81794+#define XCT_MACTX_IPH(x) ((((long)(x)) << XCT_MACTX_IPH_S) & \
81795+ XCT_MACTX_IPH_M)
81796+#define XCT_MACTX_IPO_M 0x0000000007c00000ull
81797+#define XCT_MACTX_IPO_S 22ull
81798+#define XCT_MACTX_IPO(x) ((((long)(x)) << XCT_MACTX_IPO_S) & \
81799+ XCT_MACTX_IPO_M)
81800+#define XCT_MACTX_CSUM_M 0x0000000000000060ull
81801+#define XCT_MACTX_CSUM_NOP 0x0000000000000000ull
81802+#define XCT_MACTX_CSUM_TCP 0x0000000000000040ull
81803+#define XCT_MACTX_CSUM_UDP 0x0000000000000060ull
81804+#define XCT_MACTX_V6 0x0000000000000010ull
81805+#define XCT_MACTX_C 0x0000000000000004ull
81806+#define XCT_MACTX_AL2 0x0000000000000002ull
81807+
81808+#define XCT_PTR_T 0x8000000000000000ull
81809+#define XCT_PTR_LEN_M 0x7ffff00000000000ull
81810+#define XCT_PTR_LEN_S 44
81811+#define XCT_PTR_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & \
81812+ XCT_PTR_LEN_M)
81813+#define XCT_PTR_ADDR_M 0x00000fffffffffffull
81814+#define XCT_PTR_ADDR_S 0
81815+#define XCT_PTR_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & \
81816+ XCT_PTR_ADDR_M)
81817+
81818+/* Function descriptor fields */
81819+#define XCT_FUN_T 0x8000000000000000ull
81820+#define XCT_FUN_ST 0x4000000000000000ull
81821+#define XCT_FUN_NORES 0x0000000000000000ull
81822+#define XCT_FUN_8BRES 0x1000000000000000ull
81823+#define XCT_FUN_24BRES 0x2000000000000000ull
81824+#define XCT_FUN_40BRES 0x3000000000000000ull
81825+#define XCT_FUN_I 0x0800000000000000ull
81826+#define XCT_FUN_O 0x0400000000000000ull
81827+#define XCT_FUN_E 0x0200000000000000ull
81828+#define XCT_FUN_FUN_S 54
81829+#define XCT_FUN_FUN_M 0x01c0000000000000ull
81830+#define XCT_FUN_FUN(num) ((((long)(num)) << XCT_FUN_FUN_S) & \
81831+ XCT_FUN_FUN_M)
81832+#define XCT_FUN_CRM_NOP 0x0000000000000000ull
81833+#define XCT_FUN_CRM_SIG 0x0008000000000000ull
81834+#define XCT_FUN_CRM_ENC 0x0010000000000000ull
81835+#define XCT_FUN_CRM_DEC 0x0018000000000000ull
81836+#define XCT_FUN_CRM_SIG_ENC 0x0020000000000000ull
81837+#define XCT_FUN_CRM_ENC_SIG 0x0028000000000000ull
81838+#define XCT_FUN_CRM_SIG_DEC 0x0030000000000000ull
81839+#define XCT_FUN_CRM_DEC_SIG 0x0038000000000000ull
81840+#define XCT_FUN_LLEN_M 0x0007ffff00000000ull
81841+#define XCT_FUN_LLEN_S 32ULL
81842+#define XCT_FUN_LLEN(x) ((((long)(x)) << XCT_FUN_LLEN_S) & \
81843+ XCT_FUN_LLEN_M)
81844+#define XCT_FUN_SHL_M 0x00000000f8000000ull
81845+#define XCT_FUN_SHL_S 27ull
81846+#define XCT_FUN_SHL(x) ((((long)(x)) << XCT_FUN_SHL_S) & \
81847+ XCT_FUN_SHL_M)
81848+#define XCT_FUN_CHL_M 0x0000000007c00000ull
81849+#define XCT_FUN_CHL_S 22ull
81850+#define XCT_FUN_CHL(x) ((((long)(x)) << XCT_FUN_CHL_S) & \
81851+ XCT_FUN_CHL_M)
81852+#define XCT_FUN_HSZ_M 0x00000000003c0000ull
81853+#define XCT_FUN_HSZ_S 18ull
81854+#define XCT_FUN_HSZ(x) ((((long)(x)) << XCT_FUN_HSZ_S) & \
81855+ XCT_FUN_HSZ_M)
81856+#define XCT_FUN_ALG_DES 0x0000000000000000ull
81857+#define XCT_FUN_ALG_3DES 0x0000000000008000ull
81858+#define XCT_FUN_ALG_AES 0x0000000000010000ull
81859+#define XCT_FUN_ALG_ARC 0x0000000000018000ull
81860+#define XCT_FUN_ALG_KASUMI 0x0000000000020000ull
81861+#define XCT_FUN_BCM_ECB 0x0000000000000000ull
81862+#define XCT_FUN_BCM_CBC 0x0000000000001000ull
81863+#define XCT_FUN_BCM_CFB 0x0000000000002000ull
81864+#define XCT_FUN_BCM_OFB 0x0000000000003000ull
81865+#define XCT_FUN_BCM_CNT 0x0000000000003800ull
81866+#define XCT_FUN_BCM_KAS_F8 0x0000000000002800ull
81867+#define XCT_FUN_BCM_KAS_F9 0x0000000000001800ull
81868+#define XCT_FUN_BCP_NO_PAD 0x0000000000000000ull
81869+#define XCT_FUN_BCP_ZRO 0x0000000000000200ull
81870+#define XCT_FUN_BCP_PL 0x0000000000000400ull
81871+#define XCT_FUN_BCP_INCR 0x0000000000000600ull
81872+#define XCT_FUN_SIG_MD5 (0ull << 4)
81873+#define XCT_FUN_SIG_SHA1 (2ull << 4)
81874+#define XCT_FUN_SIG_HMAC_MD5 (8ull << 4)
81875+#define XCT_FUN_SIG_HMAC_SHA1 (10ull << 4)
81876+#define XCT_FUN_A 0x0000000000000008ull
81877+#define XCT_FUN_C 0x0000000000000004ull
81878+#define XCT_FUN_AL2 0x0000000000000002ull
81879+#define XCT_FUN_SE 0x0000000000000001ull
81880+
81881+#define XCT_FUN_SRC_PTR(len, addr) (XCT_PTR_LEN(len) | XCT_PTR_ADDR(addr))
81882+#define XCT_FUN_DST_PTR(len, addr) (XCT_FUN_SRC_PTR(len, addr) | \
81883+ 0x8000000000000000ull)
81884+
81885+#define XCT_CTRL_HDR_FUN_NUM_M 0x01c0000000000000ull
81886+#define XCT_CTRL_HDR_FUN_NUM_S 54
81887+#define XCT_CTRL_HDR_LEN_M 0x0007ffff00000000ull
81888+#define XCT_CTRL_HDR_LEN_S 32
81889+#define XCT_CTRL_HDR_REG_M 0x00000000000000ffull
81890+#define XCT_CTRL_HDR_REG_S 0
81891+
81892+#define XCT_CTRL_HDR(funcN,len,reg) (0x9400000000000000ull | \
81893+ ((((long)(funcN)) << XCT_CTRL_HDR_FUN_NUM_S) \
81894+ & XCT_CTRL_HDR_FUN_NUM_M) | \
81895+ ((((long)(len)) << \
81896+ XCT_CTRL_HDR_LEN_S) & XCT_CTRL_HDR_LEN_M) | \
81897+ ((((long)(reg)) << \
81898+ XCT_CTRL_HDR_REG_S) & XCT_CTRL_HDR_REG_M))
81899+
81900+/* Function config command options */
81901+#define DMA_CALGO_DES 0x00
81902+#define DMA_CALGO_3DES 0x01
81903+#define DMA_CALGO_AES 0x02
81904+#define DMA_CALGO_ARC 0x03
81905+
81906+#define DMA_FN_CIV0 0x02
81907+#define DMA_FN_CIV1 0x03
81908+#define DMA_FN_HKEY0 0x0a
81909+
81910+#define XCT_PTR_ADDR_LEN(ptr) ((ptr) & XCT_PTR_ADDR_M), \
81911+ (((ptr) & XCT_PTR_LEN_M) >> XCT_PTR_LEN_S)
81912+
81913+#endif /* PASEMI_FNU_H */
81914diff --git a/crypto/ocf/random.c b/crypto/ocf/random.c
81915new file mode 100644
81916index 0000000..b5d97e1
81917--- /dev/null
81918+++ b/crypto/ocf/random.c
81919@@ -0,0 +1,322 @@
81920+/*
81921+ * A system independant way of adding entropy to the kernels pool
81922+ * this way the drivers can focus on the real work and we can take
81923+ * care of pushing it to the appropriate place in the kernel.
81924+ *
81925+ * This should be fast and callable from timers/interrupts
81926+ *
81927+ * Written by David McCullough <david_mccullough@mcafee.com>
81928+ * Copyright (C) 2006-2010 David McCullough
81929+ * Copyright (C) 2004-2005 Intel Corporation.
81930+ *
81931+ * LICENSE TERMS
81932+ *
81933+ * The free distribution and use of this software in both source and binary
81934+ * form is allowed (with or without changes) provided that:
81935+ *
81936+ * 1. distributions of this source code include the above copyright
81937+ * notice, this list of conditions and the following disclaimer;
81938+ *
81939+ * 2. distributions in binary form include the above copyright
81940+ * notice, this list of conditions and the following disclaimer
81941+ * in the documentation and/or other associated materials;
81942+ *
81943+ * 3. the copyright holder's name is not used to endorse products
81944+ * built using this software without specific written permission.
81945+ *
81946+ * ALTERNATIVELY, provided that this notice is retained in full, this product
81947+ * may be distributed under the terms of the GNU General Public License (GPL),
81948+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
81949+ *
81950+ * DISCLAIMER
81951+ *
81952+ * This software is provided 'as is' with no explicit or implied warranties
81953+ * in respect of its properties, including, but not limited to, correctness
81954+ * and/or fitness for purpose.
81955+ */
81956+
81957+#ifndef AUTOCONF_INCLUDED
81958+#include <linux/config.h>
81959+#endif
81960+#include <linux/module.h>
81961+#include <linux/init.h>
81962+#include <linux/list.h>
81963+#include <linux/slab.h>
81964+#include <linux/wait.h>
81965+#include <linux/sched.h>
81966+#include <linux/spinlock.h>
81967+#include <linux/version.h>
81968+#include <linux/unistd.h>
81969+#include <linux/poll.h>
81970+#include <linux/random.h>
81971+#include <cryptodev.h>
81972+
81973+#ifdef CONFIG_OCF_FIPS
81974+#include "rndtest.h"
81975+#endif
81976+
81977+#ifndef HAS_RANDOM_INPUT_WAIT
81978+#error "Please do not enable OCF_RANDOMHARVEST unless you have applied patches"
81979+#endif
81980+
81981+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
81982+#include <linux/sched.h>
81983+#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
81984+#endif
81985+
81986+/*
81987+ * a hack to access the debug levels from the crypto driver
81988+ */
81989+extern int crypto_debug;
81990+#define debug crypto_debug
81991+
81992+/*
81993+ * a list of all registered random providers
81994+ */
81995+static LIST_HEAD(random_ops);
81996+static int started = 0;
81997+static int initted = 0;
81998+
81999+struct random_op {
82000+ struct list_head random_list;
82001+ u_int32_t driverid;
82002+ int (*read_random)(void *arg, u_int32_t *buf, int len);
82003+ void *arg;
82004+};
82005+
82006+static int random_proc(void *arg);
82007+
82008+static pid_t randomproc = (pid_t) -1;
82009+static spinlock_t random_lock;
82010+
82011+/*
82012+ * just init the spin locks
82013+ */
82014+static int
82015+crypto_random_init(void)
82016+{
82017+ spin_lock_init(&random_lock);
82018+ initted = 1;
82019+ return(0);
82020+}
82021+
82022+/*
82023+ * Add the given random reader to our list (if not present)
82024+ * and start the thread (if not already started)
82025+ *
82026+ * we have to assume that driver id is ok for now
82027+ */
82028+int
82029+crypto_rregister(
82030+ u_int32_t driverid,
82031+ int (*read_random)(void *arg, u_int32_t *buf, int len),
82032+ void *arg)
82033+{
82034+ unsigned long flags;
82035+ int ret = 0;
82036+ struct random_op *rops, *tmp;
82037+
82038+ dprintk("%s,%d: %s(0x%x, %p, %p)\n", __FILE__, __LINE__,
82039+ __FUNCTION__, driverid, read_random, arg);
82040+
82041+ if (!initted)
82042+ crypto_random_init();
82043+
82044+#if 0
82045+ struct cryptocap *cap;
82046+
82047+ cap = crypto_checkdriver(driverid);
82048+ if (!cap)
82049+ return EINVAL;
82050+#endif
82051+
82052+ list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
82053+ if (rops->driverid == driverid && rops->read_random == read_random)
82054+ return EEXIST;
82055+ }
82056+
82057+ rops = (struct random_op *) kmalloc(sizeof(*rops), GFP_KERNEL);
82058+ if (!rops)
82059+ return ENOMEM;
82060+
82061+ rops->driverid = driverid;
82062+ rops->read_random = read_random;
82063+ rops->arg = arg;
82064+
82065+ spin_lock_irqsave(&random_lock, flags);
82066+ list_add_tail(&rops->random_list, &random_ops);
82067+ if (!started) {
82068+ randomproc = kernel_thread(random_proc, NULL, CLONE_FS|CLONE_FILES);
82069+ if (randomproc < 0) {
82070+ ret = randomproc;
82071+ printk("crypto: crypto_rregister cannot start random thread; "
82072+ "error %d", ret);
82073+ } else
82074+ started = 1;
82075+ }
82076+ spin_unlock_irqrestore(&random_lock, flags);
82077+
82078+ return ret;
82079+}
82080+EXPORT_SYMBOL(crypto_rregister);
82081+
82082+int
82083+crypto_runregister_all(u_int32_t driverid)
82084+{
82085+ struct random_op *rops, *tmp;
82086+ unsigned long flags;
82087+
82088+ dprintk("%s,%d: %s(0x%x)\n", __FILE__, __LINE__, __FUNCTION__, driverid);
82089+
82090+ list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
82091+ if (rops->driverid == driverid) {
82092+ list_del(&rops->random_list);
82093+ kfree(rops);
82094+ }
82095+ }
82096+
82097+ spin_lock_irqsave(&random_lock, flags);
82098+ if (list_empty(&random_ops) && started)
82099+ kill_proc(randomproc, SIGKILL, 1);
82100+ spin_unlock_irqrestore(&random_lock, flags);
82101+ return(0);
82102+}
82103+EXPORT_SYMBOL(crypto_runregister_all);
82104+
82105+/*
82106+ * while we can add entropy to random.c continue to read random data from
82107+ * the drivers and push it to random.
82108+ */
82109+static int
82110+random_proc(void *arg)
82111+{
82112+ int n;
82113+ int wantcnt;
82114+ int bufcnt = 0;
82115+ int retval = 0;
82116+ int *buf = NULL;
82117+
82118+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
82119+ daemonize();
82120+ spin_lock_irq(&current->sigmask_lock);
82121+ sigemptyset(&current->blocked);
82122+ recalc_sigpending(current);
82123+ spin_unlock_irq(&current->sigmask_lock);
82124+ sprintf(current->comm, "ocf-random");
82125+#else
82126+ daemonize("ocf-random");
82127+ allow_signal(SIGKILL);
82128+#endif
82129+
82130+ (void) get_fs();
82131+ set_fs(get_ds());
82132+
82133+#ifdef CONFIG_OCF_FIPS
82134+#define NUM_INT (RNDTEST_NBYTES/sizeof(int))
82135+#else
82136+#define NUM_INT 32
82137+#endif
82138+
82139+ /*
82140+ * some devices can transferr their RNG data direct into memory,
82141+ * so make sure it is device friendly
82142+ */
82143+ buf = kmalloc(NUM_INT * sizeof(int), GFP_DMA);
82144+ if (NULL == buf) {
82145+ printk("crypto: RNG could not allocate memory\n");
82146+ retval = -ENOMEM;
82147+ goto bad_alloc;
82148+ }
82149+
82150+ wantcnt = NUM_INT; /* start by adding some entropy */
82151+
82152+ /*
82153+ * its possible due to errors or driver removal that we no longer
82154+ * have anything to do, if so exit or we will consume all the CPU
82155+ * doing nothing
82156+ */
82157+ while (!list_empty(&random_ops)) {
82158+ struct random_op *rops, *tmp;
82159+
82160+#ifdef CONFIG_OCF_FIPS
82161+ if (wantcnt)
82162+ wantcnt = NUM_INT; /* FIPs mode can do 20000 bits or none */
82163+#endif
82164+
82165+ /* see if we can get enough entropy to make the world
82166+ * a better place.
82167+ */
82168+ while (bufcnt < wantcnt && bufcnt < NUM_INT) {
82169+ list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
82170+
82171+ n = (*rops->read_random)(rops->arg, &buf[bufcnt],
82172+ NUM_INT - bufcnt);
82173+
82174+ /* on failure remove the random number generator */
82175+ if (n == -1) {
82176+ list_del(&rops->random_list);
82177+ printk("crypto: RNG (driverid=0x%x) failed, disabling\n",
82178+ rops->driverid);
82179+ kfree(rops);
82180+ } else if (n > 0)
82181+ bufcnt += n;
82182+ }
82183+ /* give up CPU for a bit, just in case as this is a loop */
82184+ schedule();
82185+ }
82186+
82187+
82188+#ifdef CONFIG_OCF_FIPS
82189+ if (bufcnt > 0 && rndtest_buf((unsigned char *) &buf[0])) {
82190+ dprintk("crypto: buffer had fips errors, discarding\n");
82191+ bufcnt = 0;
82192+ }
82193+#endif
82194+
82195+ /*
82196+ * if we have a certified buffer, we can send some data
82197+ * to /dev/random and move along
82198+ */
82199+ if (bufcnt > 0) {
82200+ /* add what we have */
82201+ random_input_words(buf, bufcnt, bufcnt*sizeof(int)*8);
82202+ bufcnt = 0;
82203+ }
82204+
82205+ /* give up CPU for a bit so we don't hog while filling */
82206+ schedule();
82207+
82208+ /* wait for needing more */
82209+ wantcnt = random_input_wait();
82210+
82211+ if (wantcnt <= 0)
82212+ wantcnt = 0; /* try to get some info again */
82213+ else
82214+ /* round up to one word or we can loop forever */
82215+ wantcnt = (wantcnt + (sizeof(int)*8)) / (sizeof(int)*8);
82216+ if (wantcnt > NUM_INT) {
82217+ wantcnt = NUM_INT;
82218+ }
82219+
82220+ if (signal_pending(current)) {
82221+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
82222+ spin_lock_irq(&current->sigmask_lock);
82223+#endif
82224+ flush_signals(current);
82225+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
82226+ spin_unlock_irq(&current->sigmask_lock);
82227+#endif
82228+ }
82229+ }
82230+
82231+ kfree(buf);
82232+
82233+bad_alloc:
82234+ spin_lock_irq(&random_lock);
82235+ randomproc = (pid_t) -1;
82236+ started = 0;
82237+ spin_unlock_irq(&random_lock);
82238+
82239+ return retval;
82240+}
82241+
82242diff --git a/crypto/ocf/rndtest.c b/crypto/ocf/rndtest.c
82243new file mode 100644
82244index 0000000..b31e1a6
82245--- /dev/null
82246+++ b/crypto/ocf/rndtest.c
82247@@ -0,0 +1,300 @@
82248+/* $OpenBSD$ */
82249+
82250+/*
82251+ * OCF/Linux port done by David McCullough <david_mccullough@mcafee.com>
82252+ * Copyright (C) 2006-2010 David McCullough
82253+ * Copyright (C) 2004-2005 Intel Corporation.
82254+ * The license and original author are listed below.
82255+ *
82256+ * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
82257+ * All rights reserved.
82258+ *
82259+ * Redistribution and use in source and binary forms, with or without
82260+ * modification, are permitted provided that the following conditions
82261+ * are met:
82262+ * 1. Redistributions of source code must retain the above copyright
82263+ * notice, this list of conditions and the following disclaimer.
82264+ * 2. Redistributions in binary form must reproduce the above copyright
82265+ * notice, this list of conditions and the following disclaimer in the
82266+ * documentation and/or other materials provided with the distribution.
82267+ * 3. All advertising materials mentioning features or use of this software
82268+ * must display the following acknowledgement:
82269+ * This product includes software developed by Jason L. Wright
82270+ * 4. The name of the author may not be used to endorse or promote products
82271+ * derived from this software without specific prior written permission.
82272+ *
82273+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
82274+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
82275+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
82276+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
82277+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
82278+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
82279+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
82280+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
82281+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
82282+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
82283+ * POSSIBILITY OF SUCH DAMAGE.
82284+ */
82285+
82286+#ifndef AUTOCONF_INCLUDED
82287+#include <linux/config.h>
82288+#endif
82289+#include <linux/module.h>
82290+#include <linux/list.h>
82291+#include <linux/wait.h>
82292+#include <linux/time.h>
82293+#include <linux/version.h>
82294+#include <linux/unistd.h>
82295+#include <linux/kernel.h>
82296+#include <linux/string.h>
82297+#include <linux/time.h>
82298+#include <cryptodev.h>
82299+#include "rndtest.h"
82300+
82301+static struct rndtest_stats rndstats;
82302+
82303+static void rndtest_test(struct rndtest_state *);
82304+
82305+/* The tests themselves */
82306+static int rndtest_monobit(struct rndtest_state *);
82307+static int rndtest_runs(struct rndtest_state *);
82308+static int rndtest_longruns(struct rndtest_state *);
82309+static int rndtest_chi_4(struct rndtest_state *);
82310+
82311+static int rndtest_runs_check(struct rndtest_state *, int, int *);
82312+static void rndtest_runs_record(struct rndtest_state *, int, int *);
82313+
82314+static const struct rndtest_testfunc {
82315+ int (*test)(struct rndtest_state *);
82316+} rndtest_funcs[] = {
82317+ { rndtest_monobit },
82318+ { rndtest_runs },
82319+ { rndtest_chi_4 },
82320+ { rndtest_longruns },
82321+};
82322+
82323+#define RNDTEST_NTESTS (sizeof(rndtest_funcs)/sizeof(rndtest_funcs[0]))
82324+
82325+static void
82326+rndtest_test(struct rndtest_state *rsp)
82327+{
82328+ int i, rv = 0;
82329+
82330+ rndstats.rst_tests++;
82331+ for (i = 0; i < RNDTEST_NTESTS; i++)
82332+ rv |= (*rndtest_funcs[i].test)(rsp);
82333+ rsp->rs_discard = (rv != 0);
82334+}
82335+
82336+
82337+extern int crypto_debug;
82338+#define rndtest_verbose 2
82339+#define rndtest_report(rsp, failure, fmt, a...) \
82340+ { if (failure || crypto_debug) { printk("rng_test: " fmt "\n", a); } else; }
82341+
82342+#define RNDTEST_MONOBIT_MINONES 9725
82343+#define RNDTEST_MONOBIT_MAXONES 10275
82344+
82345+static int
82346+rndtest_monobit(struct rndtest_state *rsp)
82347+{
82348+ int i, ones = 0, j;
82349+ u_int8_t r;
82350+
82351+ for (i = 0; i < RNDTEST_NBYTES; i++) {
82352+ r = rsp->rs_buf[i];
82353+ for (j = 0; j < 8; j++, r <<= 1)
82354+ if (r & 0x80)
82355+ ones++;
82356+ }
82357+ if (ones > RNDTEST_MONOBIT_MINONES &&
82358+ ones < RNDTEST_MONOBIT_MAXONES) {
82359+ if (rndtest_verbose > 1)
82360+ rndtest_report(rsp, 0, "monobit pass (%d < %d < %d)",
82361+ RNDTEST_MONOBIT_MINONES, ones,
82362+ RNDTEST_MONOBIT_MAXONES);
82363+ return (0);
82364+ } else {
82365+ if (rndtest_verbose)
82366+ rndtest_report(rsp, 1,
82367+ "monobit failed (%d ones)", ones);
82368+ rndstats.rst_monobit++;
82369+ return (-1);
82370+ }
82371+}
82372+
82373+#define RNDTEST_RUNS_NINTERVAL 6
82374+
82375+static const struct rndtest_runs_tabs {
82376+ u_int16_t min, max;
82377+} rndtest_runs_tab[] = {
82378+ { 2343, 2657 },
82379+ { 1135, 1365 },
82380+ { 542, 708 },
82381+ { 251, 373 },
82382+ { 111, 201 },
82383+ { 111, 201 },
82384+};
82385+
82386+static int
82387+rndtest_runs(struct rndtest_state *rsp)
82388+{
82389+ int i, j, ones, zeros, rv = 0;
82390+ int onei[RNDTEST_RUNS_NINTERVAL], zeroi[RNDTEST_RUNS_NINTERVAL];
82391+ u_int8_t c;
82392+
82393+ bzero(onei, sizeof(onei));
82394+ bzero(zeroi, sizeof(zeroi));
82395+ ones = zeros = 0;
82396+ for (i = 0; i < RNDTEST_NBYTES; i++) {
82397+ c = rsp->rs_buf[i];
82398+ for (j = 0; j < 8; j++, c <<= 1) {
82399+ if (c & 0x80) {
82400+ ones++;
82401+ rndtest_runs_record(rsp, zeros, zeroi);
82402+ zeros = 0;
82403+ } else {
82404+ zeros++;
82405+ rndtest_runs_record(rsp, ones, onei);
82406+ ones = 0;
82407+ }
82408+ }
82409+ }
82410+ rndtest_runs_record(rsp, ones, onei);
82411+ rndtest_runs_record(rsp, zeros, zeroi);
82412+
82413+ rv |= rndtest_runs_check(rsp, 0, zeroi);
82414+ rv |= rndtest_runs_check(rsp, 1, onei);
82415+
82416+ if (rv)
82417+ rndstats.rst_runs++;
82418+
82419+ return (rv);
82420+}
82421+
82422+static void
82423+rndtest_runs_record(struct rndtest_state *rsp, int len, int *intrv)
82424+{
82425+ if (len == 0)
82426+ return;
82427+ if (len > RNDTEST_RUNS_NINTERVAL)
82428+ len = RNDTEST_RUNS_NINTERVAL;
82429+ len -= 1;
82430+ intrv[len]++;
82431+}
82432+
82433+static int
82434+rndtest_runs_check(struct rndtest_state *rsp, int val, int *src)
82435+{
82436+ int i, rv = 0;
82437+
82438+ for (i = 0; i < RNDTEST_RUNS_NINTERVAL; i++) {
82439+ if (src[i] < rndtest_runs_tab[i].min ||
82440+ src[i] > rndtest_runs_tab[i].max) {
82441+ rndtest_report(rsp, 1,
82442+ "%s interval %d failed (%d, %d-%d)",
82443+ val ? "ones" : "zeros",
82444+ i + 1, src[i], rndtest_runs_tab[i].min,
82445+ rndtest_runs_tab[i].max);
82446+ rv = -1;
82447+ } else {
82448+ rndtest_report(rsp, 0,
82449+ "runs pass %s interval %d (%d < %d < %d)",
82450+ val ? "ones" : "zeros",
82451+ i + 1, rndtest_runs_tab[i].min, src[i],
82452+ rndtest_runs_tab[i].max);
82453+ }
82454+ }
82455+ return (rv);
82456+}
82457+
82458+static int
82459+rndtest_longruns(struct rndtest_state *rsp)
82460+{
82461+ int i, j, ones = 0, zeros = 0, maxones = 0, maxzeros = 0;
82462+ u_int8_t c;
82463+
82464+ for (i = 0; i < RNDTEST_NBYTES; i++) {
82465+ c = rsp->rs_buf[i];
82466+ for (j = 0; j < 8; j++, c <<= 1) {
82467+ if (c & 0x80) {
82468+ zeros = 0;
82469+ ones++;
82470+ if (ones > maxones)
82471+ maxones = ones;
82472+ } else {
82473+ ones = 0;
82474+ zeros++;
82475+ if (zeros > maxzeros)
82476+ maxzeros = zeros;
82477+ }
82478+ }
82479+ }
82480+
82481+ if (maxones < 26 && maxzeros < 26) {
82482+ rndtest_report(rsp, 0, "longruns pass (%d ones, %d zeros)",
82483+ maxones, maxzeros);
82484+ return (0);
82485+ } else {
82486+ rndtest_report(rsp, 1, "longruns fail (%d ones, %d zeros)",
82487+ maxones, maxzeros);
82488+ rndstats.rst_longruns++;
82489+ return (-1);
82490+ }
82491+}
82492+
82493+/*
82494+ * chi^2 test over 4 bits: (this is called the poker test in FIPS 140-2,
82495+ * but it is really the chi^2 test over 4 bits (the poker test as described
82496+ * by Knuth vol 2 is something different, and I take him as authoritative
82497+ * on nomenclature over NIST).
82498+ */
82499+#define RNDTEST_CHI4_K 16
82500+#define RNDTEST_CHI4_K_MASK (RNDTEST_CHI4_K - 1)
82501+
82502+/*
82503+ * The unnormalized values are used so that we don't have to worry about
82504+ * fractional precision. The "real" value is found by:
82505+ * (V - 1562500) * (16 / 5000) = Vn (where V is the unnormalized value)
82506+ */
82507+#define RNDTEST_CHI4_VMIN 1563181 /* 2.1792 */
82508+#define RNDTEST_CHI4_VMAX 1576929 /* 46.1728 */
82509+
82510+static int
82511+rndtest_chi_4(struct rndtest_state *rsp)
82512+{
82513+ unsigned int freq[RNDTEST_CHI4_K], i, sum;
82514+
82515+ for (i = 0; i < RNDTEST_CHI4_K; i++)
82516+ freq[i] = 0;
82517+
82518+ /* Get number of occurances of each 4 bit pattern */
82519+ for (i = 0; i < RNDTEST_NBYTES; i++) {
82520+ freq[(rsp->rs_buf[i] >> 4) & RNDTEST_CHI4_K_MASK]++;
82521+ freq[(rsp->rs_buf[i] >> 0) & RNDTEST_CHI4_K_MASK]++;
82522+ }
82523+
82524+ for (i = 0, sum = 0; i < RNDTEST_CHI4_K; i++)
82525+ sum += freq[i] * freq[i];
82526+
82527+ if (sum >= 1563181 && sum <= 1576929) {
82528+ rndtest_report(rsp, 0, "chi^2(4): pass (sum %u)", sum);
82529+ return (0);
82530+ } else {
82531+ rndtest_report(rsp, 1, "chi^2(4): failed (sum %u)", sum);
82532+ rndstats.rst_chi++;
82533+ return (-1);
82534+ }
82535+}
82536+
82537+int
82538+rndtest_buf(unsigned char *buf)
82539+{
82540+ struct rndtest_state rsp;
82541+
82542+ memset(&rsp, 0, sizeof(rsp));
82543+ rsp.rs_buf = buf;
82544+ rndtest_test(&rsp);
82545+ return(rsp.rs_discard);
82546+}
82547+
82548diff --git a/crypto/ocf/rndtest.h b/crypto/ocf/rndtest.h
82549new file mode 100644
82550index 0000000..e9d8ec8
82551--- /dev/null
82552+++ b/crypto/ocf/rndtest.h
82553@@ -0,0 +1,54 @@
82554+/* $FreeBSD: src/sys/dev/rndtest/rndtest.h,v 1.1 2003/03/11 22:54:44 sam Exp $ */
82555+/* $OpenBSD$ */
82556+
82557+/*
82558+ * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
82559+ * All rights reserved.
82560+ *
82561+ * Redistribution and use in source and binary forms, with or without
82562+ * modification, are permitted provided that the following conditions
82563+ * are met:
82564+ * 1. Redistributions of source code must retain the above copyright
82565+ * notice, this list of conditions and the following disclaimer.
82566+ * 2. Redistributions in binary form must reproduce the above copyright
82567+ * notice, this list of conditions and the following disclaimer in the
82568+ * documentation and/or other materials provided with the distribution.
82569+ * 3. All advertising materials mentioning features or use of this software
82570+ * must display the following acknowledgement:
82571+ * This product includes software developed by Jason L. Wright
82572+ * 4. The name of the author may not be used to endorse or promote products
82573+ * derived from this software without specific prior written permission.
82574+ *
82575+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
82576+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
82577+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
82578+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
82579+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
82580+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
82581+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
82582+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
82583+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
82584+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
82585+ * POSSIBILITY OF SUCH DAMAGE.
82586+ */
82587+
82588+
82589+/* Some of the tests depend on these values */
82590+#define RNDTEST_NBYTES 2500
82591+#define RNDTEST_NBITS (8 * RNDTEST_NBYTES)
82592+
82593+struct rndtest_state {
82594+ int rs_discard; /* discard/accept random data */
82595+ u_int8_t *rs_buf;
82596+};
82597+
82598+struct rndtest_stats {
82599+ u_int32_t rst_discard; /* number of bytes discarded */
82600+ u_int32_t rst_tests; /* number of test runs */
82601+ u_int32_t rst_monobit; /* monobit test failures */
82602+ u_int32_t rst_runs; /* 0/1 runs failures */
82603+ u_int32_t rst_longruns; /* longruns failures */
82604+ u_int32_t rst_chi; /* chi^2 failures */
82605+};
82606+
82607+extern int rndtest_buf(unsigned char *buf);
82608diff --git a/crypto/ocf/safe/Makefile b/crypto/ocf/safe/Makefile
82609new file mode 100644
82610index 0000000..9a36b08
82611--- /dev/null
82612+++ b/crypto/ocf/safe/Makefile
82613@@ -0,0 +1,12 @@
82614+# for SGlinux builds
82615+-include $(ROOTDIR)/modules/.config
82616+
82617+obj-$(CONFIG_OCF_SAFE) += safe.o
82618+
82619+obj ?= .
82620+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
82621+
82622+ifdef TOPDIR
82623+-include $(TOPDIR)/Rules.make
82624+endif
82625+
82626diff --git a/crypto/ocf/safe/md5.c b/crypto/ocf/safe/md5.c
82627new file mode 100644
82628index 0000000..fa10789
82629--- /dev/null
82630+++ b/crypto/ocf/safe/md5.c
82631@@ -0,0 +1,308 @@
82632+/* $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
82633+/*
82634+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
82635+ * All rights reserved.
82636+ *
82637+ * Redistribution and use in source and binary forms, with or without
82638+ * modification, are permitted provided that the following conditions
82639+ * are met:
82640+ * 1. Redistributions of source code must retain the above copyright
82641+ * notice, this list of conditions and the following disclaimer.
82642+ * 2. Redistributions in binary form must reproduce the above copyright
82643+ * notice, this list of conditions and the following disclaimer in the
82644+ * documentation and/or other materials provided with the distribution.
82645+ * 3. Neither the name of the project nor the names of its contributors
82646+ * may be used to endorse or promote products derived from this software
82647+ * without specific prior written permission.
82648+ *
82649+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
82650+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
82651+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
82652+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
82653+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
82654+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
82655+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
82656+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
82657+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82658+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
82659+ * SUCH DAMAGE.
82660+ */
82661+
82662+#if 0
82663+#include <sys/cdefs.h>
82664+__FBSDID("$FreeBSD: src/sys/crypto/md5.c,v 1.9 2004/01/27 19:49:19 des Exp $");
82665+
82666+#include <sys/types.h>
82667+#include <sys/cdefs.h>
82668+#include <sys/time.h>
82669+#include <sys/systm.h>
82670+#include <crypto/md5.h>
82671+#endif
82672+
82673+#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
82674+
82675+#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
82676+#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
82677+#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
82678+#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
82679+
82680+#define ROUND1(a, b, c, d, k, s, i) { \
82681+ (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
82682+ (a) = SHIFT((a), (s)); \
82683+ (a) = (b) + (a); \
82684+}
82685+
82686+#define ROUND2(a, b, c, d, k, s, i) { \
82687+ (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
82688+ (a) = SHIFT((a), (s)); \
82689+ (a) = (b) + (a); \
82690+}
82691+
82692+#define ROUND3(a, b, c, d, k, s, i) { \
82693+ (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
82694+ (a) = SHIFT((a), (s)); \
82695+ (a) = (b) + (a); \
82696+}
82697+
82698+#define ROUND4(a, b, c, d, k, s, i) { \
82699+ (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
82700+ (a) = SHIFT((a), (s)); \
82701+ (a) = (b) + (a); \
82702+}
82703+
82704+#define Sa 7
82705+#define Sb 12
82706+#define Sc 17
82707+#define Sd 22
82708+
82709+#define Se 5
82710+#define Sf 9
82711+#define Sg 14
82712+#define Sh 20
82713+
82714+#define Si 4
82715+#define Sj 11
82716+#define Sk 16
82717+#define Sl 23
82718+
82719+#define Sm 6
82720+#define Sn 10
82721+#define So 15
82722+#define Sp 21
82723+
82724+#define MD5_A0 0x67452301
82725+#define MD5_B0 0xefcdab89
82726+#define MD5_C0 0x98badcfe
82727+#define MD5_D0 0x10325476
82728+
82729+/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
82730+static const u_int32_t T[65] = {
82731+ 0,
82732+ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
82733+ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
82734+ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
82735+ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
82736+
82737+ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
82738+ 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
82739+ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
82740+ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
82741+
82742+ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
82743+ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
82744+ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
82745+ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
82746+
82747+ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
82748+ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
82749+ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
82750+ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
82751+};
82752+
82753+static const u_int8_t md5_paddat[MD5_BUFLEN] = {
82754+ 0x80, 0, 0, 0, 0, 0, 0, 0,
82755+ 0, 0, 0, 0, 0, 0, 0, 0,
82756+ 0, 0, 0, 0, 0, 0, 0, 0,
82757+ 0, 0, 0, 0, 0, 0, 0, 0,
82758+ 0, 0, 0, 0, 0, 0, 0, 0,
82759+ 0, 0, 0, 0, 0, 0, 0, 0,
82760+ 0, 0, 0, 0, 0, 0, 0, 0,
82761+ 0, 0, 0, 0, 0, 0, 0, 0,
82762+};
82763+
82764+static void md5_calc(u_int8_t *, md5_ctxt *);
82765+
82766+void md5_init(ctxt)
82767+ md5_ctxt *ctxt;
82768+{
82769+ ctxt->md5_n = 0;
82770+ ctxt->md5_i = 0;
82771+ ctxt->md5_sta = MD5_A0;
82772+ ctxt->md5_stb = MD5_B0;
82773+ ctxt->md5_stc = MD5_C0;
82774+ ctxt->md5_std = MD5_D0;
82775+ bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
82776+}
82777+
82778+void md5_loop(ctxt, input, len)
82779+ md5_ctxt *ctxt;
82780+ u_int8_t *input;
82781+ u_int len; /* number of bytes */
82782+{
82783+ u_int gap, i;
82784+
82785+ ctxt->md5_n += len * 8; /* byte to bit */
82786+ gap = MD5_BUFLEN - ctxt->md5_i;
82787+
82788+ if (len >= gap) {
82789+ bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
82790+ gap);
82791+ md5_calc(ctxt->md5_buf, ctxt);
82792+
82793+ for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
82794+ md5_calc((u_int8_t *)(input + i), ctxt);
82795+ }
82796+
82797+ ctxt->md5_i = len - i;
82798+ bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
82799+ } else {
82800+ bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
82801+ len);
82802+ ctxt->md5_i += len;
82803+ }
82804+}
82805+
82806+void md5_pad(ctxt)
82807+ md5_ctxt *ctxt;
82808+{
82809+ u_int gap;
82810+
82811+ /* Don't count up padding. Keep md5_n. */
82812+ gap = MD5_BUFLEN - ctxt->md5_i;
82813+ if (gap > 8) {
82814+ bcopy(md5_paddat,
82815+ (void *)(ctxt->md5_buf + ctxt->md5_i),
82816+ gap - sizeof(ctxt->md5_n));
82817+ } else {
82818+ /* including gap == 8 */
82819+ bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
82820+ gap);
82821+ md5_calc(ctxt->md5_buf, ctxt);
82822+ bcopy((md5_paddat + gap),
82823+ (void *)ctxt->md5_buf,
82824+ MD5_BUFLEN - sizeof(ctxt->md5_n));
82825+ }
82826+
82827+ /* 8 byte word */
82828+#if BYTE_ORDER == LITTLE_ENDIAN
82829+ bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
82830+#endif
82831+#if BYTE_ORDER == BIG_ENDIAN
82832+ ctxt->md5_buf[56] = ctxt->md5_n8[7];
82833+ ctxt->md5_buf[57] = ctxt->md5_n8[6];
82834+ ctxt->md5_buf[58] = ctxt->md5_n8[5];
82835+ ctxt->md5_buf[59] = ctxt->md5_n8[4];
82836+ ctxt->md5_buf[60] = ctxt->md5_n8[3];
82837+ ctxt->md5_buf[61] = ctxt->md5_n8[2];
82838+ ctxt->md5_buf[62] = ctxt->md5_n8[1];
82839+ ctxt->md5_buf[63] = ctxt->md5_n8[0];
82840+#endif
82841+
82842+ md5_calc(ctxt->md5_buf, ctxt);
82843+}
82844+
82845+void md5_result(digest, ctxt)
82846+ u_int8_t *digest;
82847+ md5_ctxt *ctxt;
82848+{
82849+ /* 4 byte words */
82850+#if BYTE_ORDER == LITTLE_ENDIAN
82851+ bcopy(&ctxt->md5_st8[0], digest, 16);
82852+#endif
82853+#if BYTE_ORDER == BIG_ENDIAN
82854+ digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
82855+ digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
82856+ digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
82857+ digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
82858+ digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
82859+ digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
82860+ digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
82861+ digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
82862+#endif
82863+}
82864+
82865+static void md5_calc(b64, ctxt)
82866+ u_int8_t *b64;
82867+ md5_ctxt *ctxt;
82868+{
82869+ u_int32_t A = ctxt->md5_sta;
82870+ u_int32_t B = ctxt->md5_stb;
82871+ u_int32_t C = ctxt->md5_stc;
82872+ u_int32_t D = ctxt->md5_std;
82873+#if BYTE_ORDER == LITTLE_ENDIAN
82874+ u_int32_t *X = (u_int32_t *)b64;
82875+#endif
82876+#if BYTE_ORDER == BIG_ENDIAN
82877+ /* 4 byte words */
82878+ /* what a brute force but fast! */
82879+ u_int32_t X[16];
82880+ u_int8_t *y = (u_int8_t *)X;
82881+ y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
82882+ y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
82883+ y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
82884+ y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
82885+ y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
82886+ y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
82887+ y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
82888+ y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
82889+ y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
82890+ y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
82891+ y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
82892+ y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
82893+ y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
82894+ y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
82895+ y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
82896+ y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
82897+#endif
82898+
82899+ ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
82900+ ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
82901+ ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
82902+ ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
82903+ ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
82904+ ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
82905+ ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
82906+ ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
82907+
82908+ ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
82909+ ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
82910+ ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
82911+ ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
82912+ ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
82913+ ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
82914+ ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
82915+ ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
82916+
82917+ ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
82918+ ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
82919+ ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
82920+ ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
82921+ ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
82922+ ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
82923+ ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
82924+ ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
82925+
82926+ ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
82927+ ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
82928+ ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
82929+ ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
82930+ ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
82931+ ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
82932+ ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
82933+ ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
82934+
82935+ ctxt->md5_sta += A;
82936+ ctxt->md5_stb += B;
82937+ ctxt->md5_stc += C;
82938+ ctxt->md5_std += D;
82939+}
82940diff --git a/crypto/ocf/safe/md5.h b/crypto/ocf/safe/md5.h
82941new file mode 100644
82942index 0000000..690f5bf
82943--- /dev/null
82944+++ b/crypto/ocf/safe/md5.h
82945@@ -0,0 +1,76 @@
82946+/* $FreeBSD: src/sys/crypto/md5.h,v 1.4 2002/03/20 05:13:50 alfred Exp $ */
82947+/* $KAME: md5.h,v 1.4 2000/03/27 04:36:22 sumikawa Exp $ */
82948+
82949+/*
82950+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
82951+ * All rights reserved.
82952+ *
82953+ * Redistribution and use in source and binary forms, with or without
82954+ * modification, are permitted provided that the following conditions
82955+ * are met:
82956+ * 1. Redistributions of source code must retain the above copyright
82957+ * notice, this list of conditions and the following disclaimer.
82958+ * 2. Redistributions in binary form must reproduce the above copyright
82959+ * notice, this list of conditions and the following disclaimer in the
82960+ * documentation and/or other materials provided with the distribution.
82961+ * 3. Neither the name of the project nor the names of its contributors
82962+ * may be used to endorse or promote products derived from this software
82963+ * without specific prior written permission.
82964+ *
82965+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
82966+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
82967+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
82968+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
82969+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
82970+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
82971+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
82972+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
82973+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82974+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
82975+ * SUCH DAMAGE.
82976+ */
82977+
82978+#ifndef _NETINET6_MD5_H_
82979+#define _NETINET6_MD5_H_
82980+
82981+#define MD5_BUFLEN 64
82982+
82983+typedef struct {
82984+ union {
82985+ u_int32_t md5_state32[4];
82986+ u_int8_t md5_state8[16];
82987+ } md5_st;
82988+
82989+#define md5_sta md5_st.md5_state32[0]
82990+#define md5_stb md5_st.md5_state32[1]
82991+#define md5_stc md5_st.md5_state32[2]
82992+#define md5_std md5_st.md5_state32[3]
82993+#define md5_st8 md5_st.md5_state8
82994+
82995+ union {
82996+ u_int64_t md5_count64;
82997+ u_int8_t md5_count8[8];
82998+ } md5_count;
82999+#define md5_n md5_count.md5_count64
83000+#define md5_n8 md5_count.md5_count8
83001+
83002+ u_int md5_i;
83003+ u_int8_t md5_buf[MD5_BUFLEN];
83004+} md5_ctxt;
83005+
83006+extern void md5_init(md5_ctxt *);
83007+extern void md5_loop(md5_ctxt *, u_int8_t *, u_int);
83008+extern void md5_pad(md5_ctxt *);
83009+extern void md5_result(u_int8_t *, md5_ctxt *);
83010+
83011+/* compatibility */
83012+#define MD5_CTX md5_ctxt
83013+#define MD5Init(x) md5_init((x))
83014+#define MD5Update(x, y, z) md5_loop((x), (y), (z))
83015+#define MD5Final(x, y) \
83016+do { \
83017+ md5_pad((y)); \
83018+ md5_result((x), (y)); \
83019+} while (0)
83020+
83021+#endif /* ! _NETINET6_MD5_H_*/
83022diff --git a/crypto/ocf/safe/safe.c b/crypto/ocf/safe/safe.c
83023new file mode 100644
83024index 0000000..87984f7
83025--- /dev/null
83026+++ b/crypto/ocf/safe/safe.c
83027@@ -0,0 +1,2288 @@
83028+/*-
83029+ * Linux port done by David McCullough <david_mccullough@mcafee.com>
83030+ * Copyright (C) 2004-2010 David McCullough
83031+ * The license and original author are listed below.
83032+ *
83033+ * Copyright (c) 2003 Sam Leffler, Errno Consulting
83034+ * Copyright (c) 2003 Global Technology Associates, Inc.
83035+ * All rights reserved.
83036+ *
83037+ * Redistribution and use in source and binary forms, with or without
83038+ * modification, are permitted provided that the following conditions
83039+ * are met:
83040+ * 1. Redistributions of source code must retain the above copyright
83041+ * notice, this list of conditions and the following disclaimer.
83042+ * 2. Redistributions in binary form must reproduce the above copyright
83043+ * notice, this list of conditions and the following disclaimer in the
83044+ * documentation and/or other materials provided with the distribution.
83045+ *
83046+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
83047+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
83048+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
83049+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
83050+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
83051+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
83052+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
83053+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
83054+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
83055+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
83056+ * SUCH DAMAGE.
83057+ *
83058+__FBSDID("$FreeBSD: src/sys/dev/safe/safe.c,v 1.18 2007/03/21 03:42:50 sam Exp $");
83059+ */
83060+
83061+#ifndef AUTOCONF_INCLUDED
83062+#include <linux/config.h>
83063+#endif
83064+#include <linux/module.h>
83065+#include <linux/kernel.h>
83066+#include <linux/init.h>
83067+#include <linux/list.h>
83068+#include <linux/slab.h>
83069+#include <linux/wait.h>
83070+#include <linux/sched.h>
83071+#include <linux/pci.h>
83072+#include <linux/delay.h>
83073+#include <linux/interrupt.h>
83074+#include <linux/spinlock.h>
83075+#include <linux/random.h>
83076+#include <linux/version.h>
83077+#include <linux/skbuff.h>
83078+#include <asm/io.h>
83079+
83080+/*
83081+ * SafeNet SafeXcel-1141 hardware crypto accelerator
83082+ */
83083+
83084+#include <cryptodev.h>
83085+#include <uio.h>
83086+#include <safe/safereg.h>
83087+#include <safe/safevar.h>
83088+
83089+#if 1
83090+#define DPRINTF(a) do { \
83091+ if (debug) { \
83092+ printk("%s: ", sc ? \
83093+ device_get_nameunit(sc->sc_dev) : "safe"); \
83094+ printk a; \
83095+ } \
83096+ } while (0)
83097+#else
83098+#define DPRINTF(a)
83099+#endif
83100+
83101+/*
83102+ * until we find a cleaner way, include the BSD md5/sha1 code
83103+ * here
83104+ */
83105+#define HMAC_HACK 1
83106+#ifdef HMAC_HACK
83107+#define LITTLE_ENDIAN 1234
83108+#define BIG_ENDIAN 4321
83109+#ifdef __LITTLE_ENDIAN
83110+#define BYTE_ORDER LITTLE_ENDIAN
83111+#endif
83112+#ifdef __BIG_ENDIAN
83113+#define BYTE_ORDER BIG_ENDIAN
83114+#endif
83115+#include <safe/md5.h>
83116+#include <safe/md5.c>
83117+#include <safe/sha1.h>
83118+#include <safe/sha1.c>
83119+
83120+u_int8_t hmac_ipad_buffer[64] = {
83121+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
83122+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
83123+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
83124+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
83125+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
83126+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
83127+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
83128+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
83129+};
83130+
83131+u_int8_t hmac_opad_buffer[64] = {
83132+ 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
83133+ 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
83134+ 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
83135+ 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
83136+ 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
83137+ 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
83138+ 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
83139+ 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
83140+};
83141+#endif /* HMAC_HACK */
83142+
83143+/* add proc entry for this */
83144+struct safe_stats safestats;
83145+
83146+#define debug safe_debug
83147+int safe_debug = 0;
83148+module_param(safe_debug, int, 0644);
83149+MODULE_PARM_DESC(safe_debug, "Enable debug");
83150+
83151+static void safe_callback(struct safe_softc *, struct safe_ringentry *);
83152+static void safe_feed(struct safe_softc *, struct safe_ringentry *);
83153+#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
83154+static void safe_rng_init(struct safe_softc *);
83155+int safe_rngbufsize = 8; /* 32 bytes each read */
83156+module_param(safe_rngbufsize, int, 0644);
83157+MODULE_PARM_DESC(safe_rngbufsize, "RNG polling buffer size (32-bit words)");
83158+int safe_rngmaxalarm = 8; /* max alarms before reset */
83159+module_param(safe_rngmaxalarm, int, 0644);
83160+MODULE_PARM_DESC(safe_rngmaxalarm, "RNG max alarms before reset");
83161+#endif /* SAFE_NO_RNG */
83162+
83163+static void safe_totalreset(struct safe_softc *sc);
83164+static int safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op);
83165+static int safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op);
83166+static int safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re);
83167+static int safe_kprocess(device_t dev, struct cryptkop *krp, int hint);
83168+static int safe_kstart(struct safe_softc *sc);
83169+static int safe_ksigbits(struct safe_softc *sc, struct crparam *cr);
83170+static void safe_kfeed(struct safe_softc *sc);
83171+static void safe_kpoll(unsigned long arg);
83172+static void safe_kload_reg(struct safe_softc *sc, u_int32_t off,
83173+ u_int32_t len, struct crparam *n);
83174+
83175+static int safe_newsession(device_t, u_int32_t *, struct cryptoini *);
83176+static int safe_freesession(device_t, u_int64_t);
83177+static int safe_process(device_t, struct cryptop *, int);
83178+
83179+static device_method_t safe_methods = {
83180+ /* crypto device methods */
83181+ DEVMETHOD(cryptodev_newsession, safe_newsession),
83182+ DEVMETHOD(cryptodev_freesession,safe_freesession),
83183+ DEVMETHOD(cryptodev_process, safe_process),
83184+ DEVMETHOD(cryptodev_kprocess, safe_kprocess),
83185+};
83186+
83187+#define READ_REG(sc,r) readl((sc)->sc_base_addr + (r))
83188+#define WRITE_REG(sc,r,val) writel((val), (sc)->sc_base_addr + (r))
83189+
83190+#define SAFE_MAX_CHIPS 8
83191+static struct safe_softc *safe_chip_idx[SAFE_MAX_CHIPS];
83192+
83193+/*
83194+ * split our buffers up into safe DMAable byte fragments to avoid lockup
83195+ * bug in 1141 HW on rev 1.0.
83196+ */
83197+
83198+static int
83199+pci_map_linear(
83200+ struct safe_softc *sc,
83201+ struct safe_operand *buf,
83202+ void *addr,
83203+ int len)
83204+{
83205+ dma_addr_t tmp;
83206+ int chunk, tlen = len;
83207+
83208+ tmp = pci_map_single(sc->sc_pcidev, addr, len, PCI_DMA_BIDIRECTIONAL);
83209+
83210+ buf->mapsize += len;
83211+ while (len > 0) {
83212+ chunk = (len > sc->sc_max_dsize) ? sc->sc_max_dsize : len;
83213+ buf->segs[buf->nsegs].ds_addr = tmp;
83214+ buf->segs[buf->nsegs].ds_len = chunk;
83215+ buf->segs[buf->nsegs].ds_tlen = tlen;
83216+ buf->nsegs++;
83217+ tmp += chunk;
83218+ len -= chunk;
83219+ tlen = 0;
83220+ }
83221+ return 0;
83222+}
83223+
83224+/*
83225+ * map in a given uio buffer (great on some arches :-)
83226+ */
83227+
83228+static int
83229+pci_map_uio(struct safe_softc *sc, struct safe_operand *buf, struct uio *uio)
83230+{
83231+ struct iovec *iov = uio->uio_iov;
83232+ int n;
83233+
83234+ DPRINTF(("%s()\n", __FUNCTION__));
83235+
83236+ buf->mapsize = 0;
83237+ buf->nsegs = 0;
83238+
83239+ for (n = 0; n < uio->uio_iovcnt; n++) {
83240+ pci_map_linear(sc, buf, iov->iov_base, iov->iov_len);
83241+ iov++;
83242+ }
83243+
83244+ /* identify this buffer by the first segment */
83245+ buf->map = (void *) buf->segs[0].ds_addr;
83246+ return(0);
83247+}
83248+
83249+/*
83250+ * map in a given sk_buff
83251+ */
83252+
83253+static int
83254+pci_map_skb(struct safe_softc *sc,struct safe_operand *buf,struct sk_buff *skb)
83255+{
83256+ int i;
83257+
83258+ DPRINTF(("%s()\n", __FUNCTION__));
83259+
83260+ buf->mapsize = 0;
83261+ buf->nsegs = 0;
83262+
83263+ pci_map_linear(sc, buf, skb->data, skb_headlen(skb));
83264+
83265+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
83266+ pci_map_linear(sc, buf,
83267+ page_address(skb_shinfo(skb)->frags[i].page) +
83268+ skb_shinfo(skb)->frags[i].page_offset,
83269+ skb_shinfo(skb)->frags[i].size);
83270+ }
83271+
83272+ /* identify this buffer by the first segment */
83273+ buf->map = (void *) buf->segs[0].ds_addr;
83274+ return(0);
83275+}
83276+
83277+
83278+#if 0 /* not needed at this time */
83279+static void
83280+pci_sync_operand(struct safe_softc *sc, struct safe_operand *buf)
83281+{
83282+ int i;
83283+
83284+ DPRINTF(("%s()\n", __FUNCTION__));
83285+ for (i = 0; i < buf->nsegs; i++)
83286+ pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
83287+ buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
83288+}
83289+#endif
83290+
83291+static void
83292+pci_unmap_operand(struct safe_softc *sc, struct safe_operand *buf)
83293+{
83294+ int i;
83295+ DPRINTF(("%s()\n", __FUNCTION__));
83296+ for (i = 0; i < buf->nsegs; i++) {
83297+ if (buf->segs[i].ds_tlen) {
83298+ DPRINTF(("%s - unmap %d 0x%x %d\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
83299+ pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
83300+ buf->segs[i].ds_tlen, PCI_DMA_BIDIRECTIONAL);
83301+ DPRINTF(("%s - unmap %d 0x%x %d done\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
83302+ }
83303+ buf->segs[i].ds_addr = 0;
83304+ buf->segs[i].ds_len = 0;
83305+ buf->segs[i].ds_tlen = 0;
83306+ }
83307+ buf->nsegs = 0;
83308+ buf->mapsize = 0;
83309+ buf->map = 0;
83310+}
83311+
83312+
83313+/*
83314+ * SafeXcel Interrupt routine
83315+ */
83316+static irqreturn_t
83317+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
83318+safe_intr(int irq, void *arg)
83319+#else
83320+safe_intr(int irq, void *arg, struct pt_regs *regs)
83321+#endif
83322+{
83323+ struct safe_softc *sc = arg;
83324+ int stat;
83325+ unsigned long flags;
83326+
83327+ stat = READ_REG(sc, SAFE_HM_STAT);
83328+
83329+ DPRINTF(("%s(stat=0x%x)\n", __FUNCTION__, stat));
83330+
83331+ if (stat == 0) /* shared irq, not for us */
83332+ return IRQ_NONE;
83333+
83334+ WRITE_REG(sc, SAFE_HI_CLR, stat); /* IACK */
83335+
83336+ if ((stat & SAFE_INT_PE_DDONE)) {
83337+ /*
83338+ * Descriptor(s) done; scan the ring and
83339+ * process completed operations.
83340+ */
83341+ spin_lock_irqsave(&sc->sc_ringmtx, flags);
83342+ while (sc->sc_back != sc->sc_front) {
83343+ struct safe_ringentry *re = sc->sc_back;
83344+
83345+#ifdef SAFE_DEBUG
83346+ if (debug) {
83347+ safe_dump_ringstate(sc, __func__);
83348+ safe_dump_request(sc, __func__, re);
83349+ }
83350+#endif
83351+ /*
83352+ * safe_process marks ring entries that were allocated
83353+ * but not used with a csr of zero. This insures the
83354+ * ring front pointer never needs to be set backwards
83355+ * in the event that an entry is allocated but not used
83356+ * because of a setup error.
83357+ */
83358+ DPRINTF(("%s re->re_desc.d_csr=0x%x\n", __FUNCTION__, re->re_desc.d_csr));
83359+ if (re->re_desc.d_csr != 0) {
83360+ if (!SAFE_PE_CSR_IS_DONE(re->re_desc.d_csr)) {
83361+ DPRINTF(("%s !CSR_IS_DONE\n", __FUNCTION__));
83362+ break;
83363+ }
83364+ if (!SAFE_PE_LEN_IS_DONE(re->re_desc.d_len)) {
83365+ DPRINTF(("%s !LEN_IS_DONE\n", __FUNCTION__));
83366+ break;
83367+ }
83368+ sc->sc_nqchip--;
83369+ safe_callback(sc, re);
83370+ }
83371+ if (++(sc->sc_back) == sc->sc_ringtop)
83372+ sc->sc_back = sc->sc_ring;
83373+ }
83374+ spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
83375+ }
83376+
83377+ /*
83378+ * Check to see if we got any DMA Error
83379+ */
83380+ if (stat & SAFE_INT_PE_ERROR) {
83381+ printk("%s: dmaerr dmastat %08x\n", device_get_nameunit(sc->sc_dev),
83382+ (int)READ_REG(sc, SAFE_PE_DMASTAT));
83383+ safestats.st_dmaerr++;
83384+ safe_totalreset(sc);
83385+#if 0
83386+ safe_feed(sc);
83387+#endif
83388+ }
83389+
83390+ if (sc->sc_needwakeup) { /* XXX check high watermark */
83391+ int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
83392+ DPRINTF(("%s: wakeup crypto %x\n", __func__,
83393+ sc->sc_needwakeup));
83394+ sc->sc_needwakeup &= ~wakeup;
83395+ crypto_unblock(sc->sc_cid, wakeup);
83396+ }
83397+
83398+ return IRQ_HANDLED;
83399+}
83400+
83401+/*
83402+ * safe_feed() - post a request to chip
83403+ */
83404+static void
83405+safe_feed(struct safe_softc *sc, struct safe_ringentry *re)
83406+{
83407+ DPRINTF(("%s()\n", __FUNCTION__));
83408+#ifdef SAFE_DEBUG
83409+ if (debug) {
83410+ safe_dump_ringstate(sc, __func__);
83411+ safe_dump_request(sc, __func__, re);
83412+ }
83413+#endif
83414+ sc->sc_nqchip++;
83415+ if (sc->sc_nqchip > safestats.st_maxqchip)
83416+ safestats.st_maxqchip = sc->sc_nqchip;
83417+ /* poke h/w to check descriptor ring, any value can be written */
83418+ WRITE_REG(sc, SAFE_HI_RD_DESCR, 0);
83419+}
83420+
83421+#define N(a) (sizeof(a) / sizeof (a[0]))
83422+static void
83423+safe_setup_enckey(struct safe_session *ses, caddr_t key)
83424+{
83425+ int i;
83426+
83427+ bcopy(key, ses->ses_key, ses->ses_klen / 8);
83428+
83429+ /* PE is little-endian, insure proper byte order */
83430+ for (i = 0; i < N(ses->ses_key); i++)
83431+ ses->ses_key[i] = htole32(ses->ses_key[i]);
83432+}
83433+
83434+static void
83435+safe_setup_mackey(struct safe_session *ses, int algo, caddr_t key, int klen)
83436+{
83437+#ifdef HMAC_HACK
83438+ MD5_CTX md5ctx;
83439+ SHA1_CTX sha1ctx;
83440+ int i;
83441+
83442+
83443+ for (i = 0; i < klen; i++)
83444+ key[i] ^= HMAC_IPAD_VAL;
83445+
83446+ if (algo == CRYPTO_MD5_HMAC) {
83447+ MD5Init(&md5ctx);
83448+ MD5Update(&md5ctx, key, klen);
83449+ MD5Update(&md5ctx, hmac_ipad_buffer, MD5_HMAC_BLOCK_LEN - klen);
83450+ bcopy(md5ctx.md5_st8, ses->ses_hminner, sizeof(md5ctx.md5_st8));
83451+ } else {
83452+ SHA1Init(&sha1ctx);
83453+ SHA1Update(&sha1ctx, key, klen);
83454+ SHA1Update(&sha1ctx, hmac_ipad_buffer,
83455+ SHA1_HMAC_BLOCK_LEN - klen);
83456+ bcopy(sha1ctx.h.b32, ses->ses_hminner, sizeof(sha1ctx.h.b32));
83457+ }
83458+
83459+ for (i = 0; i < klen; i++)
83460+ key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
83461+
83462+ if (algo == CRYPTO_MD5_HMAC) {
83463+ MD5Init(&md5ctx);
83464+ MD5Update(&md5ctx, key, klen);
83465+ MD5Update(&md5ctx, hmac_opad_buffer, MD5_HMAC_BLOCK_LEN - klen);
83466+ bcopy(md5ctx.md5_st8, ses->ses_hmouter, sizeof(md5ctx.md5_st8));
83467+ } else {
83468+ SHA1Init(&sha1ctx);
83469+ SHA1Update(&sha1ctx, key, klen);
83470+ SHA1Update(&sha1ctx, hmac_opad_buffer,
83471+ SHA1_HMAC_BLOCK_LEN - klen);
83472+ bcopy(sha1ctx.h.b32, ses->ses_hmouter, sizeof(sha1ctx.h.b32));
83473+ }
83474+
83475+ for (i = 0; i < klen; i++)
83476+ key[i] ^= HMAC_OPAD_VAL;
83477+
83478+#if 0
83479+ /*
83480+ * this code prevents SHA working on a BE host,
83481+ * so it is obviously wrong. I think the byte
83482+ * swap setup we do with the chip fixes this for us
83483+ */
83484+
83485+ /* PE is little-endian, insure proper byte order */
83486+ for (i = 0; i < N(ses->ses_hminner); i++) {
83487+ ses->ses_hminner[i] = htole32(ses->ses_hminner[i]);
83488+ ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]);
83489+ }
83490+#endif
83491+#else /* HMAC_HACK */
83492+ printk("safe: md5/sha not implemented\n");
83493+#endif /* HMAC_HACK */
83494+}
83495+#undef N
83496+
83497+/*
83498+ * Allocate a new 'session' and return an encoded session id. 'sidp'
83499+ * contains our registration id, and should contain an encoded session
83500+ * id on successful allocation.
83501+ */
83502+static int
83503+safe_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
83504+{
83505+ struct safe_softc *sc = device_get_softc(dev);
83506+ struct cryptoini *c, *encini = NULL, *macini = NULL;
83507+ struct safe_session *ses = NULL;
83508+ int sesn;
83509+
83510+ DPRINTF(("%s()\n", __FUNCTION__));
83511+
83512+ if (sidp == NULL || cri == NULL || sc == NULL)
83513+ return (EINVAL);
83514+
83515+ for (c = cri; c != NULL; c = c->cri_next) {
83516+ if (c->cri_alg == CRYPTO_MD5_HMAC ||
83517+ c->cri_alg == CRYPTO_SHA1_HMAC ||
83518+ c->cri_alg == CRYPTO_NULL_HMAC) {
83519+ if (macini)
83520+ return (EINVAL);
83521+ macini = c;
83522+ } else if (c->cri_alg == CRYPTO_DES_CBC ||
83523+ c->cri_alg == CRYPTO_3DES_CBC ||
83524+ c->cri_alg == CRYPTO_AES_CBC ||
83525+ c->cri_alg == CRYPTO_NULL_CBC) {
83526+ if (encini)
83527+ return (EINVAL);
83528+ encini = c;
83529+ } else
83530+ return (EINVAL);
83531+ }
83532+ if (encini == NULL && macini == NULL)
83533+ return (EINVAL);
83534+ if (encini) { /* validate key length */
83535+ switch (encini->cri_alg) {
83536+ case CRYPTO_DES_CBC:
83537+ if (encini->cri_klen != 64)
83538+ return (EINVAL);
83539+ break;
83540+ case CRYPTO_3DES_CBC:
83541+ if (encini->cri_klen != 192)
83542+ return (EINVAL);
83543+ break;
83544+ case CRYPTO_AES_CBC:
83545+ if (encini->cri_klen != 128 &&
83546+ encini->cri_klen != 192 &&
83547+ encini->cri_klen != 256)
83548+ return (EINVAL);
83549+ break;
83550+ }
83551+ }
83552+
83553+ if (sc->sc_sessions == NULL) {
83554+ ses = sc->sc_sessions = (struct safe_session *)
83555+ kmalloc(sizeof(struct safe_session), SLAB_ATOMIC);
83556+ if (ses == NULL)
83557+ return (ENOMEM);
83558+ memset(ses, 0, sizeof(struct safe_session));
83559+ sesn = 0;
83560+ sc->sc_nsessions = 1;
83561+ } else {
83562+ for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
83563+ if (sc->sc_sessions[sesn].ses_used == 0) {
83564+ ses = &sc->sc_sessions[sesn];
83565+ break;
83566+ }
83567+ }
83568+
83569+ if (ses == NULL) {
83570+ sesn = sc->sc_nsessions;
83571+ ses = (struct safe_session *)
83572+ kmalloc((sesn + 1) * sizeof(struct safe_session), SLAB_ATOMIC);
83573+ if (ses == NULL)
83574+ return (ENOMEM);
83575+ memset(ses, 0, (sesn + 1) * sizeof(struct safe_session));
83576+ bcopy(sc->sc_sessions, ses, sesn *
83577+ sizeof(struct safe_session));
83578+ bzero(sc->sc_sessions, sesn *
83579+ sizeof(struct safe_session));
83580+ kfree(sc->sc_sessions);
83581+ sc->sc_sessions = ses;
83582+ ses = &sc->sc_sessions[sesn];
83583+ sc->sc_nsessions++;
83584+ }
83585+ }
83586+
83587+ bzero(ses, sizeof(struct safe_session));
83588+ ses->ses_used = 1;
83589+
83590+ if (encini) {
83591+ /* get an IV */
83592+ /* XXX may read fewer than requested */
83593+ read_random(ses->ses_iv, sizeof(ses->ses_iv));
83594+
83595+ ses->ses_klen = encini->cri_klen;
83596+ if (encini->cri_key != NULL)
83597+ safe_setup_enckey(ses, encini->cri_key);
83598+ }
83599+
83600+ if (macini) {
83601+ ses->ses_mlen = macini->cri_mlen;
83602+ if (ses->ses_mlen == 0) {
83603+ if (macini->cri_alg == CRYPTO_MD5_HMAC)
83604+ ses->ses_mlen = MD5_HASH_LEN;
83605+ else
83606+ ses->ses_mlen = SHA1_HASH_LEN;
83607+ }
83608+
83609+ if (macini->cri_key != NULL) {
83610+ safe_setup_mackey(ses, macini->cri_alg, macini->cri_key,
83611+ macini->cri_klen / 8);
83612+ }
83613+ }
83614+
83615+ *sidp = SAFE_SID(device_get_unit(sc->sc_dev), sesn);
83616+ return (0);
83617+}
83618+
83619+/*
83620+ * Deallocate a session.
83621+ */
83622+static int
83623+safe_freesession(device_t dev, u_int64_t tid)
83624+{
83625+ struct safe_softc *sc = device_get_softc(dev);
83626+ int session, ret;
83627+ u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
83628+
83629+ DPRINTF(("%s()\n", __FUNCTION__));
83630+
83631+ if (sc == NULL)
83632+ return (EINVAL);
83633+
83634+ session = SAFE_SESSION(sid);
83635+ if (session < sc->sc_nsessions) {
83636+ bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
83637+ ret = 0;
83638+ } else
83639+ ret = EINVAL;
83640+ return (ret);
83641+}
83642+
83643+
83644+static int
83645+safe_process(device_t dev, struct cryptop *crp, int hint)
83646+{
83647+ struct safe_softc *sc = device_get_softc(dev);
83648+ int err = 0, i, nicealign, uniform;
83649+ struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
83650+ int bypass, oplen, ivsize;
83651+ caddr_t iv;
83652+ int16_t coffset;
83653+ struct safe_session *ses;
83654+ struct safe_ringentry *re;
83655+ struct safe_sarec *sa;
83656+ struct safe_pdesc *pd;
83657+ u_int32_t cmd0, cmd1, staterec;
83658+ unsigned long flags;
83659+
83660+ DPRINTF(("%s()\n", __FUNCTION__));
83661+
83662+ if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
83663+ safestats.st_invalid++;
83664+ return (EINVAL);
83665+ }
83666+ if (SAFE_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
83667+ safestats.st_badsession++;
83668+ return (EINVAL);
83669+ }
83670+
83671+ spin_lock_irqsave(&sc->sc_ringmtx, flags);
83672+ if (sc->sc_front == sc->sc_back && sc->sc_nqchip != 0) {
83673+ safestats.st_ringfull++;
83674+ sc->sc_needwakeup |= CRYPTO_SYMQ;
83675+ spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
83676+ return (ERESTART);
83677+ }
83678+ re = sc->sc_front;
83679+
83680+ staterec = re->re_sa.sa_staterec; /* save */
83681+ /* NB: zero everything but the PE descriptor */
83682+ bzero(&re->re_sa, sizeof(struct safe_ringentry) - sizeof(re->re_desc));
83683+ re->re_sa.sa_staterec = staterec; /* restore */
83684+
83685+ re->re_crp = crp;
83686+ re->re_sesn = SAFE_SESSION(crp->crp_sid);
83687+
83688+ re->re_src.nsegs = 0;
83689+ re->re_dst.nsegs = 0;
83690+
83691+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
83692+ re->re_src_skb = (struct sk_buff *)crp->crp_buf;
83693+ re->re_dst_skb = (struct sk_buff *)crp->crp_buf;
83694+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
83695+ re->re_src_io = (struct uio *)crp->crp_buf;
83696+ re->re_dst_io = (struct uio *)crp->crp_buf;
83697+ } else {
83698+ safestats.st_badflags++;
83699+ err = EINVAL;
83700+ goto errout; /* XXX we don't handle contiguous blocks! */
83701+ }
83702+
83703+ sa = &re->re_sa;
83704+ ses = &sc->sc_sessions[re->re_sesn];
83705+
83706+ crd1 = crp->crp_desc;
83707+ if (crd1 == NULL) {
83708+ safestats.st_nodesc++;
83709+ err = EINVAL;
83710+ goto errout;
83711+ }
83712+ crd2 = crd1->crd_next;
83713+
83714+ cmd0 = SAFE_SA_CMD0_BASIC; /* basic group operation */
83715+ cmd1 = 0;
83716+ if (crd2 == NULL) {
83717+ if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
83718+ crd1->crd_alg == CRYPTO_SHA1_HMAC ||
83719+ crd1->crd_alg == CRYPTO_NULL_HMAC) {
83720+ maccrd = crd1;
83721+ enccrd = NULL;
83722+ cmd0 |= SAFE_SA_CMD0_OP_HASH;
83723+ } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
83724+ crd1->crd_alg == CRYPTO_3DES_CBC ||
83725+ crd1->crd_alg == CRYPTO_AES_CBC ||
83726+ crd1->crd_alg == CRYPTO_NULL_CBC) {
83727+ maccrd = NULL;
83728+ enccrd = crd1;
83729+ cmd0 |= SAFE_SA_CMD0_OP_CRYPT;
83730+ } else {
83731+ safestats.st_badalg++;
83732+ err = EINVAL;
83733+ goto errout;
83734+ }
83735+ } else {
83736+ if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
83737+ crd1->crd_alg == CRYPTO_SHA1_HMAC ||
83738+ crd1->crd_alg == CRYPTO_NULL_HMAC) &&
83739+ (crd2->crd_alg == CRYPTO_DES_CBC ||
83740+ crd2->crd_alg == CRYPTO_3DES_CBC ||
83741+ crd2->crd_alg == CRYPTO_AES_CBC ||
83742+ crd2->crd_alg == CRYPTO_NULL_CBC) &&
83743+ ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
83744+ maccrd = crd1;
83745+ enccrd = crd2;
83746+ } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
83747+ crd1->crd_alg == CRYPTO_3DES_CBC ||
83748+ crd1->crd_alg == CRYPTO_AES_CBC ||
83749+ crd1->crd_alg == CRYPTO_NULL_CBC) &&
83750+ (crd2->crd_alg == CRYPTO_MD5_HMAC ||
83751+ crd2->crd_alg == CRYPTO_SHA1_HMAC ||
83752+ crd2->crd_alg == CRYPTO_NULL_HMAC) &&
83753+ (crd1->crd_flags & CRD_F_ENCRYPT)) {
83754+ enccrd = crd1;
83755+ maccrd = crd2;
83756+ } else {
83757+ safestats.st_badalg++;
83758+ err = EINVAL;
83759+ goto errout;
83760+ }
83761+ cmd0 |= SAFE_SA_CMD0_OP_BOTH;
83762+ }
83763+
83764+ if (enccrd) {
83765+ if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
83766+ safe_setup_enckey(ses, enccrd->crd_key);
83767+
83768+ if (enccrd->crd_alg == CRYPTO_DES_CBC) {
83769+ cmd0 |= SAFE_SA_CMD0_DES;
83770+ cmd1 |= SAFE_SA_CMD1_CBC;
83771+ ivsize = 2*sizeof(u_int32_t);
83772+ } else if (enccrd->crd_alg == CRYPTO_3DES_CBC) {
83773+ cmd0 |= SAFE_SA_CMD0_3DES;
83774+ cmd1 |= SAFE_SA_CMD1_CBC;
83775+ ivsize = 2*sizeof(u_int32_t);
83776+ } else if (enccrd->crd_alg == CRYPTO_AES_CBC) {
83777+ cmd0 |= SAFE_SA_CMD0_AES;
83778+ cmd1 |= SAFE_SA_CMD1_CBC;
83779+ if (ses->ses_klen == 128)
83780+ cmd1 |= SAFE_SA_CMD1_AES128;
83781+ else if (ses->ses_klen == 192)
83782+ cmd1 |= SAFE_SA_CMD1_AES192;
83783+ else
83784+ cmd1 |= SAFE_SA_CMD1_AES256;
83785+ ivsize = 4*sizeof(u_int32_t);
83786+ } else {
83787+ cmd0 |= SAFE_SA_CMD0_CRYPT_NULL;
83788+ ivsize = 0;
83789+ }
83790+
83791+ /*
83792+ * Setup encrypt/decrypt state. When using basic ops
83793+ * we can't use an inline IV because hash/crypt offset
83794+ * must be from the end of the IV to the start of the
83795+ * crypt data and this leaves out the preceding header
83796+ * from the hash calculation. Instead we place the IV
83797+ * in the state record and set the hash/crypt offset to
83798+ * copy both the header+IV.
83799+ */
83800+ if (enccrd->crd_flags & CRD_F_ENCRYPT) {
83801+ cmd0 |= SAFE_SA_CMD0_OUTBOUND;
83802+
83803+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
83804+ iv = enccrd->crd_iv;
83805+ else
83806+ iv = (caddr_t) ses->ses_iv;
83807+ if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
83808+ crypto_copyback(crp->crp_flags, crp->crp_buf,
83809+ enccrd->crd_inject, ivsize, iv);
83810+ }
83811+ bcopy(iv, re->re_sastate.sa_saved_iv, ivsize);
83812+ /* make iv LE */
83813+ for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
83814+ re->re_sastate.sa_saved_iv[i] =
83815+ cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
83816+ cmd0 |= SAFE_SA_CMD0_IVLD_STATE | SAFE_SA_CMD0_SAVEIV;
83817+ re->re_flags |= SAFE_QFLAGS_COPYOUTIV;
83818+ } else {
83819+ cmd0 |= SAFE_SA_CMD0_INBOUND;
83820+
83821+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
83822+ bcopy(enccrd->crd_iv,
83823+ re->re_sastate.sa_saved_iv, ivsize);
83824+ } else {
83825+ crypto_copydata(crp->crp_flags, crp->crp_buf,
83826+ enccrd->crd_inject, ivsize,
83827+ (caddr_t)re->re_sastate.sa_saved_iv);
83828+ }
83829+ /* make iv LE */
83830+ for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
83831+ re->re_sastate.sa_saved_iv[i] =
83832+ cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
83833+ cmd0 |= SAFE_SA_CMD0_IVLD_STATE;
83834+ }
83835+ /*
83836+ * For basic encryption use the zero pad algorithm.
83837+ * This pads results to an 8-byte boundary and
83838+ * suppresses padding verification for inbound (i.e.
83839+ * decrypt) operations.
83840+ *
83841+ * NB: Not sure if the 8-byte pad boundary is a problem.
83842+ */
83843+ cmd0 |= SAFE_SA_CMD0_PAD_ZERO;
83844+
83845+ /* XXX assert key bufs have the same size */
83846+ bcopy(ses->ses_key, sa->sa_key, sizeof(sa->sa_key));
83847+ }
83848+
83849+ if (maccrd) {
83850+ if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
83851+ safe_setup_mackey(ses, maccrd->crd_alg,
83852+ maccrd->crd_key, maccrd->crd_klen / 8);
83853+ }
83854+
83855+ if (maccrd->crd_alg == CRYPTO_MD5_HMAC) {
83856+ cmd0 |= SAFE_SA_CMD0_MD5;
83857+ cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
83858+ } else if (maccrd->crd_alg == CRYPTO_SHA1_HMAC) {
83859+ cmd0 |= SAFE_SA_CMD0_SHA1;
83860+ cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
83861+ } else {
83862+ cmd0 |= SAFE_SA_CMD0_HASH_NULL;
83863+ }
83864+ /*
83865+ * Digest data is loaded from the SA and the hash
83866+ * result is saved to the state block where we
83867+ * retrieve it for return to the caller.
83868+ */
83869+ /* XXX assert digest bufs have the same size */
83870+ bcopy(ses->ses_hminner, sa->sa_indigest,
83871+ sizeof(sa->sa_indigest));
83872+ bcopy(ses->ses_hmouter, sa->sa_outdigest,
83873+ sizeof(sa->sa_outdigest));
83874+
83875+ cmd0 |= SAFE_SA_CMD0_HSLD_SA | SAFE_SA_CMD0_SAVEHASH;
83876+ re->re_flags |= SAFE_QFLAGS_COPYOUTICV;
83877+ }
83878+
83879+ if (enccrd && maccrd) {
83880+ /*
83881+ * The offset from hash data to the start of
83882+ * crypt data is the difference in the skips.
83883+ */
83884+ bypass = maccrd->crd_skip;
83885+ coffset = enccrd->crd_skip - maccrd->crd_skip;
83886+ if (coffset < 0) {
83887+ DPRINTF(("%s: hash does not precede crypt; "
83888+ "mac skip %u enc skip %u\n",
83889+ __func__, maccrd->crd_skip, enccrd->crd_skip));
83890+ safestats.st_skipmismatch++;
83891+ err = EINVAL;
83892+ goto errout;
83893+ }
83894+ oplen = enccrd->crd_skip + enccrd->crd_len;
83895+ if (maccrd->crd_skip + maccrd->crd_len != oplen) {
83896+ DPRINTF(("%s: hash amount %u != crypt amount %u\n",
83897+ __func__, maccrd->crd_skip + maccrd->crd_len,
83898+ oplen));
83899+ safestats.st_lenmismatch++;
83900+ err = EINVAL;
83901+ goto errout;
83902+ }
83903+#ifdef SAFE_DEBUG
83904+ if (debug) {
83905+ printf("mac: skip %d, len %d, inject %d\n",
83906+ maccrd->crd_skip, maccrd->crd_len,
83907+ maccrd->crd_inject);
83908+ printf("enc: skip %d, len %d, inject %d\n",
83909+ enccrd->crd_skip, enccrd->crd_len,
83910+ enccrd->crd_inject);
83911+ printf("bypass %d coffset %d oplen %d\n",
83912+ bypass, coffset, oplen);
83913+ }
83914+#endif
83915+ if (coffset & 3) { /* offset must be 32-bit aligned */
83916+ DPRINTF(("%s: coffset %u misaligned\n",
83917+ __func__, coffset));
83918+ safestats.st_coffmisaligned++;
83919+ err = EINVAL;
83920+ goto errout;
83921+ }
83922+ coffset >>= 2;
83923+ if (coffset > 255) { /* offset must be <256 dwords */
83924+ DPRINTF(("%s: coffset %u too big\n",
83925+ __func__, coffset));
83926+ safestats.st_cofftoobig++;
83927+ err = EINVAL;
83928+ goto errout;
83929+ }
83930+ /*
83931+ * Tell the hardware to copy the header to the output.
83932+ * The header is defined as the data from the end of
83933+ * the bypass to the start of data to be encrypted.
83934+ * Typically this is the inline IV. Note that you need
83935+ * to do this even if src+dst are the same; it appears
83936+ * that w/o this bit the crypted data is written
83937+ * immediately after the bypass data.
83938+ */
83939+ cmd1 |= SAFE_SA_CMD1_HDRCOPY;
83940+ /*
83941+ * Disable IP header mutable bit handling. This is
83942+ * needed to get correct HMAC calculations.
83943+ */
83944+ cmd1 |= SAFE_SA_CMD1_MUTABLE;
83945+ } else {
83946+ if (enccrd) {
83947+ bypass = enccrd->crd_skip;
83948+ oplen = bypass + enccrd->crd_len;
83949+ } else {
83950+ bypass = maccrd->crd_skip;
83951+ oplen = bypass + maccrd->crd_len;
83952+ }
83953+ coffset = 0;
83954+ }
83955+ /* XXX verify multiple of 4 when using s/g */
83956+ if (bypass > 96) { /* bypass offset must be <= 96 bytes */
83957+ DPRINTF(("%s: bypass %u too big\n", __func__, bypass));
83958+ safestats.st_bypasstoobig++;
83959+ err = EINVAL;
83960+ goto errout;
83961+ }
83962+
83963+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
83964+ if (pci_map_skb(sc, &re->re_src, re->re_src_skb)) {
83965+ safestats.st_noload++;
83966+ err = ENOMEM;
83967+ goto errout;
83968+ }
83969+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
83970+ if (pci_map_uio(sc, &re->re_src, re->re_src_io)) {
83971+ safestats.st_noload++;
83972+ err = ENOMEM;
83973+ goto errout;
83974+ }
83975+ }
83976+ nicealign = safe_dmamap_aligned(sc, &re->re_src);
83977+ uniform = safe_dmamap_uniform(sc, &re->re_src);
83978+
83979+ DPRINTF(("src nicealign %u uniform %u nsegs %u\n",
83980+ nicealign, uniform, re->re_src.nsegs));
83981+ if (re->re_src.nsegs > 1) {
83982+ re->re_desc.d_src = sc->sc_spalloc.dma_paddr +
83983+ ((caddr_t) sc->sc_spfree - (caddr_t) sc->sc_spring);
83984+ for (i = 0; i < re->re_src_nsegs; i++) {
83985+ /* NB: no need to check if there's space */
83986+ pd = sc->sc_spfree;
83987+ if (++(sc->sc_spfree) == sc->sc_springtop)
83988+ sc->sc_spfree = sc->sc_spring;
83989+
83990+ KASSERT((pd->pd_flags&3) == 0 ||
83991+ (pd->pd_flags&3) == SAFE_PD_DONE,
83992+ ("bogus source particle descriptor; flags %x",
83993+ pd->pd_flags));
83994+ pd->pd_addr = re->re_src_segs[i].ds_addr;
83995+ pd->pd_size = re->re_src_segs[i].ds_len;
83996+ pd->pd_flags = SAFE_PD_READY;
83997+ }
83998+ cmd0 |= SAFE_SA_CMD0_IGATHER;
83999+ } else {
84000+ /*
84001+ * No need for gather, reference the operand directly.
84002+ */
84003+ re->re_desc.d_src = re->re_src_segs[0].ds_addr;
84004+ }
84005+
84006+ if (enccrd == NULL && maccrd != NULL) {
84007+ /*
84008+ * Hash op; no destination needed.
84009+ */
84010+ } else {
84011+ if (crp->crp_flags & (CRYPTO_F_IOV|CRYPTO_F_SKBUF)) {
84012+ if (!nicealign) {
84013+ safestats.st_iovmisaligned++;
84014+ err = EINVAL;
84015+ goto errout;
84016+ }
84017+ if (uniform != 1) {
84018+ device_printf(sc->sc_dev, "!uniform source\n");
84019+ if (!uniform) {
84020+ /*
84021+ * There's no way to handle the DMA
84022+ * requirements with this uio. We
84023+ * could create a separate DMA area for
84024+ * the result and then copy it back,
84025+ * but for now we just bail and return
84026+ * an error. Note that uio requests
84027+ * > SAFE_MAX_DSIZE are handled because
84028+ * the DMA map and segment list for the
84029+ * destination wil result in a
84030+ * destination particle list that does
84031+ * the necessary scatter DMA.
84032+ */
84033+ safestats.st_iovnotuniform++;
84034+ err = EINVAL;
84035+ goto errout;
84036+ }
84037+ } else
84038+ re->re_dst = re->re_src;
84039+ } else {
84040+ safestats.st_badflags++;
84041+ err = EINVAL;
84042+ goto errout;
84043+ }
84044+
84045+ if (re->re_dst.nsegs > 1) {
84046+ re->re_desc.d_dst = sc->sc_dpalloc.dma_paddr +
84047+ ((caddr_t) sc->sc_dpfree - (caddr_t) sc->sc_dpring);
84048+ for (i = 0; i < re->re_dst_nsegs; i++) {
84049+ pd = sc->sc_dpfree;
84050+ KASSERT((pd->pd_flags&3) == 0 ||
84051+ (pd->pd_flags&3) == SAFE_PD_DONE,
84052+ ("bogus dest particle descriptor; flags %x",
84053+ pd->pd_flags));
84054+ if (++(sc->sc_dpfree) == sc->sc_dpringtop)
84055+ sc->sc_dpfree = sc->sc_dpring;
84056+ pd->pd_addr = re->re_dst_segs[i].ds_addr;
84057+ pd->pd_flags = SAFE_PD_READY;
84058+ }
84059+ cmd0 |= SAFE_SA_CMD0_OSCATTER;
84060+ } else {
84061+ /*
84062+ * No need for scatter, reference the operand directly.
84063+ */
84064+ re->re_desc.d_dst = re->re_dst_segs[0].ds_addr;
84065+ }
84066+ }
84067+
84068+ /*
84069+ * All done with setup; fillin the SA command words
84070+ * and the packet engine descriptor. The operation
84071+ * is now ready for submission to the hardware.
84072+ */
84073+ sa->sa_cmd0 = cmd0 | SAFE_SA_CMD0_IPCI | SAFE_SA_CMD0_OPCI;
84074+ sa->sa_cmd1 = cmd1
84075+ | (coffset << SAFE_SA_CMD1_OFFSET_S)
84076+ | SAFE_SA_CMD1_SAREV1 /* Rev 1 SA data structure */
84077+ | SAFE_SA_CMD1_SRPCI
84078+ ;
84079+ /*
84080+ * NB: the order of writes is important here. In case the
84081+ * chip is scanning the ring because of an outstanding request
84082+ * it might nab this one too. In that case we need to make
84083+ * sure the setup is complete before we write the length
84084+ * field of the descriptor as it signals the descriptor is
84085+ * ready for processing.
84086+ */
84087+ re->re_desc.d_csr = SAFE_PE_CSR_READY | SAFE_PE_CSR_SAPCI;
84088+ if (maccrd)
84089+ re->re_desc.d_csr |= SAFE_PE_CSR_LOADSA | SAFE_PE_CSR_HASHFINAL;
84090+ wmb();
84091+ re->re_desc.d_len = oplen
84092+ | SAFE_PE_LEN_READY
84093+ | (bypass << SAFE_PE_LEN_BYPASS_S)
84094+ ;
84095+
84096+ safestats.st_ipackets++;
84097+ safestats.st_ibytes += oplen;
84098+
84099+ if (++(sc->sc_front) == sc->sc_ringtop)
84100+ sc->sc_front = sc->sc_ring;
84101+
84102+ /* XXX honor batching */
84103+ safe_feed(sc, re);
84104+ spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
84105+ return (0);
84106+
84107+errout:
84108+ if (re->re_src.map != re->re_dst.map)
84109+ pci_unmap_operand(sc, &re->re_dst);
84110+ if (re->re_src.map)
84111+ pci_unmap_operand(sc, &re->re_src);
84112+ spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
84113+ if (err != ERESTART) {
84114+ crp->crp_etype = err;
84115+ crypto_done(crp);
84116+ } else {
84117+ sc->sc_needwakeup |= CRYPTO_SYMQ;
84118+ }
84119+ return (err);
84120+}
84121+
84122+static void
84123+safe_callback(struct safe_softc *sc, struct safe_ringentry *re)
84124+{
84125+ struct cryptop *crp = (struct cryptop *)re->re_crp;
84126+ struct cryptodesc *crd;
84127+
84128+ DPRINTF(("%s()\n", __FUNCTION__));
84129+
84130+ safestats.st_opackets++;
84131+ safestats.st_obytes += re->re_dst.mapsize;
84132+
84133+ if (re->re_desc.d_csr & SAFE_PE_CSR_STATUS) {
84134+ device_printf(sc->sc_dev, "csr 0x%x cmd0 0x%x cmd1 0x%x\n",
84135+ re->re_desc.d_csr,
84136+ re->re_sa.sa_cmd0, re->re_sa.sa_cmd1);
84137+ safestats.st_peoperr++;
84138+ crp->crp_etype = EIO; /* something more meaningful? */
84139+ }
84140+
84141+ if (re->re_dst.map != NULL && re->re_dst.map != re->re_src.map)
84142+ pci_unmap_operand(sc, &re->re_dst);
84143+ pci_unmap_operand(sc, &re->re_src);
84144+
84145+ /*
84146+ * If result was written to a differet mbuf chain, swap
84147+ * it in as the return value and reclaim the original.
84148+ */
84149+ if ((crp->crp_flags & CRYPTO_F_SKBUF) && re->re_src_skb != re->re_dst_skb) {
84150+ device_printf(sc->sc_dev, "no CRYPTO_F_SKBUF swapping support\n");
84151+ /* kfree_skb(skb) */
84152+ /* crp->crp_buf = (caddr_t)re->re_dst_skb */
84153+ return;
84154+ }
84155+
84156+ if (re->re_flags & SAFE_QFLAGS_COPYOUTIV) {
84157+ /* copy out IV for future use */
84158+ for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
84159+ int i;
84160+ int ivsize;
84161+
84162+ if (crd->crd_alg == CRYPTO_DES_CBC ||
84163+ crd->crd_alg == CRYPTO_3DES_CBC) {
84164+ ivsize = 2*sizeof(u_int32_t);
84165+ } else if (crd->crd_alg == CRYPTO_AES_CBC) {
84166+ ivsize = 4*sizeof(u_int32_t);
84167+ } else
84168+ continue;
84169+ crypto_copydata(crp->crp_flags, crp->crp_buf,
84170+ crd->crd_skip + crd->crd_len - ivsize, ivsize,
84171+ (caddr_t)sc->sc_sessions[re->re_sesn].ses_iv);
84172+ for (i = 0;
84173+ i < ivsize/sizeof(sc->sc_sessions[re->re_sesn].ses_iv[0]);
84174+ i++)
84175+ sc->sc_sessions[re->re_sesn].ses_iv[i] =
84176+ cpu_to_le32(sc->sc_sessions[re->re_sesn].ses_iv[i]);
84177+ break;
84178+ }
84179+ }
84180+
84181+ if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) {
84182+ /* copy out ICV result */
84183+ for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
84184+ if (!(crd->crd_alg == CRYPTO_MD5_HMAC ||
84185+ crd->crd_alg == CRYPTO_SHA1_HMAC ||
84186+ crd->crd_alg == CRYPTO_NULL_HMAC))
84187+ continue;
84188+ if (crd->crd_alg == CRYPTO_SHA1_HMAC) {
84189+ /*
84190+ * SHA-1 ICV's are byte-swapped; fix 'em up
84191+ * before copy them to their destination.
84192+ */
84193+ re->re_sastate.sa_saved_indigest[0] =
84194+ cpu_to_be32(re->re_sastate.sa_saved_indigest[0]);
84195+ re->re_sastate.sa_saved_indigest[1] =
84196+ cpu_to_be32(re->re_sastate.sa_saved_indigest[1]);
84197+ re->re_sastate.sa_saved_indigest[2] =
84198+ cpu_to_be32(re->re_sastate.sa_saved_indigest[2]);
84199+ } else {
84200+ re->re_sastate.sa_saved_indigest[0] =
84201+ cpu_to_le32(re->re_sastate.sa_saved_indigest[0]);
84202+ re->re_sastate.sa_saved_indigest[1] =
84203+ cpu_to_le32(re->re_sastate.sa_saved_indigest[1]);
84204+ re->re_sastate.sa_saved_indigest[2] =
84205+ cpu_to_le32(re->re_sastate.sa_saved_indigest[2]);
84206+ }
84207+ crypto_copyback(crp->crp_flags, crp->crp_buf,
84208+ crd->crd_inject,
84209+ sc->sc_sessions[re->re_sesn].ses_mlen,
84210+ (caddr_t)re->re_sastate.sa_saved_indigest);
84211+ break;
84212+ }
84213+ }
84214+ crypto_done(crp);
84215+}
84216+
84217+
84218+#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
84219+#define SAFE_RNG_MAXWAIT 1000
84220+
84221+static void
84222+safe_rng_init(struct safe_softc *sc)
84223+{
84224+ u_int32_t w, v;
84225+ int i;
84226+
84227+ DPRINTF(("%s()\n", __FUNCTION__));
84228+
84229+ WRITE_REG(sc, SAFE_RNG_CTRL, 0);
84230+ /* use default value according to the manual */
84231+ WRITE_REG(sc, SAFE_RNG_CNFG, 0x834); /* magic from SafeNet */
84232+ WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
84233+
84234+ /*
84235+ * There is a bug in rev 1.0 of the 1140 that when the RNG
84236+ * is brought out of reset the ready status flag does not
84237+ * work until the RNG has finished its internal initialization.
84238+ *
84239+ * So in order to determine the device is through its
84240+ * initialization we must read the data register, using the
84241+ * status reg in the read in case it is initialized. Then read
84242+ * the data register until it changes from the first read.
84243+ * Once it changes read the data register until it changes
84244+ * again. At this time the RNG is considered initialized.
84245+ * This could take between 750ms - 1000ms in time.
84246+ */
84247+ i = 0;
84248+ w = READ_REG(sc, SAFE_RNG_OUT);
84249+ do {
84250+ v = READ_REG(sc, SAFE_RNG_OUT);
84251+ if (v != w) {
84252+ w = v;
84253+ break;
84254+ }
84255+ DELAY(10);
84256+ } while (++i < SAFE_RNG_MAXWAIT);
84257+
84258+ /* Wait Until data changes again */
84259+ i = 0;
84260+ do {
84261+ v = READ_REG(sc, SAFE_RNG_OUT);
84262+ if (v != w)
84263+ break;
84264+ DELAY(10);
84265+ } while (++i < SAFE_RNG_MAXWAIT);
84266+}
84267+
84268+static __inline void
84269+safe_rng_disable_short_cycle(struct safe_softc *sc)
84270+{
84271+ DPRINTF(("%s()\n", __FUNCTION__));
84272+
84273+ WRITE_REG(sc, SAFE_RNG_CTRL,
84274+ READ_REG(sc, SAFE_RNG_CTRL) &~ SAFE_RNG_CTRL_SHORTEN);
84275+}
84276+
84277+static __inline void
84278+safe_rng_enable_short_cycle(struct safe_softc *sc)
84279+{
84280+ DPRINTF(("%s()\n", __FUNCTION__));
84281+
84282+ WRITE_REG(sc, SAFE_RNG_CTRL,
84283+ READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN);
84284+}
84285+
84286+static __inline u_int32_t
84287+safe_rng_read(struct safe_softc *sc)
84288+{
84289+ int i;
84290+
84291+ i = 0;
84292+ while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT)
84293+ ;
84294+ return READ_REG(sc, SAFE_RNG_OUT);
84295+}
84296+
84297+static int
84298+safe_read_random(void *arg, u_int32_t *buf, int maxwords)
84299+{
84300+ struct safe_softc *sc = (struct safe_softc *) arg;
84301+ int i, rc;
84302+
84303+ DPRINTF(("%s()\n", __FUNCTION__));
84304+
84305+ safestats.st_rng++;
84306+ /*
84307+ * Fetch the next block of data.
84308+ */
84309+ if (maxwords > safe_rngbufsize)
84310+ maxwords = safe_rngbufsize;
84311+ if (maxwords > SAFE_RNG_MAXBUFSIZ)
84312+ maxwords = SAFE_RNG_MAXBUFSIZ;
84313+retry:
84314+ /* read as much as we can */
84315+ for (rc = 0; rc < maxwords; rc++) {
84316+ if (READ_REG(sc, SAFE_RNG_STAT) != 0)
84317+ break;
84318+ buf[rc] = READ_REG(sc, SAFE_RNG_OUT);
84319+ }
84320+ if (rc == 0)
84321+ return 0;
84322+ /*
84323+ * Check the comparator alarm count and reset the h/w if
84324+ * it exceeds our threshold. This guards against the
84325+ * hardware oscillators resonating with external signals.
84326+ */
84327+ if (READ_REG(sc, SAFE_RNG_ALM_CNT) > safe_rngmaxalarm) {
84328+ u_int32_t freq_inc, w;
84329+
84330+ DPRINTF(("%s: alarm count %u exceeds threshold %u\n", __func__,
84331+ (unsigned)READ_REG(sc, SAFE_RNG_ALM_CNT), safe_rngmaxalarm));
84332+ safestats.st_rngalarm++;
84333+ safe_rng_enable_short_cycle(sc);
84334+ freq_inc = 18;
84335+ for (i = 0; i < 64; i++) {
84336+ w = READ_REG(sc, SAFE_RNG_CNFG);
84337+ freq_inc = ((w + freq_inc) & 0x3fL);
84338+ w = ((w & ~0x3fL) | freq_inc);
84339+ WRITE_REG(sc, SAFE_RNG_CNFG, w);
84340+
84341+ WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
84342+
84343+ (void) safe_rng_read(sc);
84344+ DELAY(25);
84345+
84346+ if (READ_REG(sc, SAFE_RNG_ALM_CNT) == 0) {
84347+ safe_rng_disable_short_cycle(sc);
84348+ goto retry;
84349+ }
84350+ freq_inc = 1;
84351+ }
84352+ safe_rng_disable_short_cycle(sc);
84353+ } else
84354+ WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
84355+
84356+ return(rc);
84357+}
84358+#endif /* defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG) */
84359+
84360+
84361+/*
84362+ * Resets the board. Values in the regesters are left as is
84363+ * from the reset (i.e. initial values are assigned elsewhere).
84364+ */
84365+static void
84366+safe_reset_board(struct safe_softc *sc)
84367+{
84368+ u_int32_t v;
84369+ /*
84370+ * Reset the device. The manual says no delay
84371+ * is needed between marking and clearing reset.
84372+ */
84373+ DPRINTF(("%s()\n", __FUNCTION__));
84374+
84375+ v = READ_REG(sc, SAFE_PE_DMACFG) &~
84376+ (SAFE_PE_DMACFG_PERESET | SAFE_PE_DMACFG_PDRRESET |
84377+ SAFE_PE_DMACFG_SGRESET);
84378+ WRITE_REG(sc, SAFE_PE_DMACFG, v
84379+ | SAFE_PE_DMACFG_PERESET
84380+ | SAFE_PE_DMACFG_PDRRESET
84381+ | SAFE_PE_DMACFG_SGRESET);
84382+ WRITE_REG(sc, SAFE_PE_DMACFG, v);
84383+}
84384+
84385+/*
84386+ * Initialize registers we need to touch only once.
84387+ */
84388+static void
84389+safe_init_board(struct safe_softc *sc)
84390+{
84391+ u_int32_t v, dwords;
84392+
84393+ DPRINTF(("%s()\n", __FUNCTION__));
84394+
84395+ v = READ_REG(sc, SAFE_PE_DMACFG);
84396+ v &=~ ( SAFE_PE_DMACFG_PEMODE
84397+ | SAFE_PE_DMACFG_FSENA /* failsafe enable */
84398+ | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
84399+ | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
84400+ | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
84401+ | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
84402+ | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
84403+ | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
84404+ );
84405+ v |= SAFE_PE_DMACFG_FSENA /* failsafe enable */
84406+ | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
84407+ | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
84408+ | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
84409+ | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
84410+ | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
84411+#if 0
84412+ | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
84413+#endif
84414+ ;
84415+ WRITE_REG(sc, SAFE_PE_DMACFG, v);
84416+
84417+#ifdef __BIG_ENDIAN
84418+ /* tell the safenet that we are 4321 and not 1234 */
84419+ WRITE_REG(sc, SAFE_ENDIAN, 0xe4e41b1b);
84420+#endif
84421+
84422+ if (sc->sc_chiprev == SAFE_REV(1,0)) {
84423+ /*
84424+ * Avoid large PCI DMA transfers. Rev 1.0 has a bug where
84425+ * "target mode transfers" done while the chip is DMA'ing
84426+ * >1020 bytes cause the hardware to lockup. To avoid this
84427+ * we reduce the max PCI transfer size and use small source
84428+ * particle descriptors (<= 256 bytes).
84429+ */
84430+ WRITE_REG(sc, SAFE_DMA_CFG, 256);
84431+ device_printf(sc->sc_dev,
84432+ "Reduce max DMA size to %u words for rev %u.%u WAR\n",
84433+ (unsigned) ((READ_REG(sc, SAFE_DMA_CFG)>>2) & 0xff),
84434+ (unsigned) SAFE_REV_MAJ(sc->sc_chiprev),
84435+ (unsigned) SAFE_REV_MIN(sc->sc_chiprev));
84436+ sc->sc_max_dsize = 256;
84437+ } else {
84438+ sc->sc_max_dsize = SAFE_MAX_DSIZE;
84439+ }
84440+
84441+ /* NB: operands+results are overlaid */
84442+ WRITE_REG(sc, SAFE_PE_PDRBASE, sc->sc_ringalloc.dma_paddr);
84443+ WRITE_REG(sc, SAFE_PE_RDRBASE, sc->sc_ringalloc.dma_paddr);
84444+ /*
84445+ * Configure ring entry size and number of items in the ring.
84446+ */
84447+ KASSERT((sizeof(struct safe_ringentry) % sizeof(u_int32_t)) == 0,
84448+ ("PE ring entry not 32-bit aligned!"));
84449+ dwords = sizeof(struct safe_ringentry) / sizeof(u_int32_t);
84450+ WRITE_REG(sc, SAFE_PE_RINGCFG,
84451+ (dwords << SAFE_PE_RINGCFG_OFFSET_S) | SAFE_MAX_NQUEUE);
84452+ WRITE_REG(sc, SAFE_PE_RINGPOLL, 0); /* disable polling */
84453+
84454+ WRITE_REG(sc, SAFE_PE_GRNGBASE, sc->sc_spalloc.dma_paddr);
84455+ WRITE_REG(sc, SAFE_PE_SRNGBASE, sc->sc_dpalloc.dma_paddr);
84456+ WRITE_REG(sc, SAFE_PE_PARTSIZE,
84457+ (SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART);
84458+ /*
84459+ * NB: destination particles are fixed size. We use
84460+ * an mbuf cluster and require all results go to
84461+ * clusters or smaller.
84462+ */
84463+ WRITE_REG(sc, SAFE_PE_PARTCFG, sc->sc_max_dsize);
84464+
84465+ /* it's now safe to enable PE mode, do it */
84466+ WRITE_REG(sc, SAFE_PE_DMACFG, v | SAFE_PE_DMACFG_PEMODE);
84467+
84468+ /*
84469+ * Configure hardware to use level-triggered interrupts and
84470+ * to interrupt after each descriptor is processed.
84471+ */
84472+ WRITE_REG(sc, SAFE_HI_CFG, SAFE_HI_CFG_LEVEL);
84473+ WRITE_REG(sc, SAFE_HI_CLR, 0xffffffff);
84474+ WRITE_REG(sc, SAFE_HI_DESC_CNT, 1);
84475+ WRITE_REG(sc, SAFE_HI_MASK, SAFE_INT_PE_DDONE | SAFE_INT_PE_ERROR);
84476+}
84477+
84478+
84479+/*
84480+ * Clean up after a chip crash.
84481+ * It is assumed that the caller in splimp()
84482+ */
84483+static void
84484+safe_cleanchip(struct safe_softc *sc)
84485+{
84486+ DPRINTF(("%s()\n", __FUNCTION__));
84487+
84488+ if (sc->sc_nqchip != 0) {
84489+ struct safe_ringentry *re = sc->sc_back;
84490+
84491+ while (re != sc->sc_front) {
84492+ if (re->re_desc.d_csr != 0)
84493+ safe_free_entry(sc, re);
84494+ if (++re == sc->sc_ringtop)
84495+ re = sc->sc_ring;
84496+ }
84497+ sc->sc_back = re;
84498+ sc->sc_nqchip = 0;
84499+ }
84500+}
84501+
84502+/*
84503+ * free a safe_q
84504+ * It is assumed that the caller is within splimp().
84505+ */
84506+static int
84507+safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re)
84508+{
84509+ struct cryptop *crp;
84510+
84511+ DPRINTF(("%s()\n", __FUNCTION__));
84512+
84513+ /*
84514+ * Free header MCR
84515+ */
84516+ if ((re->re_dst_skb != NULL) && (re->re_src_skb != re->re_dst_skb))
84517+#ifdef NOTYET
84518+ m_freem(re->re_dst_m);
84519+#else
84520+ printk("%s,%d: SKB not supported\n", __FILE__, __LINE__);
84521+#endif
84522+
84523+ crp = (struct cryptop *)re->re_crp;
84524+
84525+ re->re_desc.d_csr = 0;
84526+
84527+ crp->crp_etype = EFAULT;
84528+ crypto_done(crp);
84529+ return(0);
84530+}
84531+
84532+/*
84533+ * Routine to reset the chip and clean up.
84534+ * It is assumed that the caller is in splimp()
84535+ */
84536+static void
84537+safe_totalreset(struct safe_softc *sc)
84538+{
84539+ DPRINTF(("%s()\n", __FUNCTION__));
84540+
84541+ safe_reset_board(sc);
84542+ safe_init_board(sc);
84543+ safe_cleanchip(sc);
84544+}
84545+
84546+/*
84547+ * Is the operand suitable aligned for direct DMA. Each
84548+ * segment must be aligned on a 32-bit boundary and all
84549+ * but the last segment must be a multiple of 4 bytes.
84550+ */
84551+static int
84552+safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op)
84553+{
84554+ int i;
84555+
84556+ DPRINTF(("%s()\n", __FUNCTION__));
84557+
84558+ for (i = 0; i < op->nsegs; i++) {
84559+ if (op->segs[i].ds_addr & 3)
84560+ return (0);
84561+ if (i != (op->nsegs - 1) && (op->segs[i].ds_len & 3))
84562+ return (0);
84563+ }
84564+ return (1);
84565+}
84566+
84567+/*
84568+ * Is the operand suitable for direct DMA as the destination
84569+ * of an operation. The hardware requires that each ``particle''
84570+ * but the last in an operation result have the same size. We
84571+ * fix that size at SAFE_MAX_DSIZE bytes. This routine returns
84572+ * 0 if some segment is not a multiple of of this size, 1 if all
84573+ * segments are exactly this size, or 2 if segments are at worst
84574+ * a multple of this size.
84575+ */
84576+static int
84577+safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op)
84578+{
84579+ int result = 1;
84580+
84581+ DPRINTF(("%s()\n", __FUNCTION__));
84582+
84583+ if (op->nsegs > 0) {
84584+ int i;
84585+
84586+ for (i = 0; i < op->nsegs-1; i++) {
84587+ if (op->segs[i].ds_len % sc->sc_max_dsize)
84588+ return (0);
84589+ if (op->segs[i].ds_len != sc->sc_max_dsize)
84590+ result = 2;
84591+ }
84592+ }
84593+ return (result);
84594+}
84595+
84596+static int
84597+safe_kprocess(device_t dev, struct cryptkop *krp, int hint)
84598+{
84599+ struct safe_softc *sc = device_get_softc(dev);
84600+ struct safe_pkq *q;
84601+ unsigned long flags;
84602+
84603+ DPRINTF(("%s()\n", __FUNCTION__));
84604+
84605+ if (sc == NULL) {
84606+ krp->krp_status = EINVAL;
84607+ goto err;
84608+ }
84609+
84610+ if (krp->krp_op != CRK_MOD_EXP) {
84611+ krp->krp_status = EOPNOTSUPP;
84612+ goto err;
84613+ }
84614+
84615+ q = (struct safe_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
84616+ if (q == NULL) {
84617+ krp->krp_status = ENOMEM;
84618+ goto err;
84619+ }
84620+ memset(q, 0, sizeof(*q));
84621+ q->pkq_krp = krp;
84622+ INIT_LIST_HEAD(&q->pkq_list);
84623+
84624+ spin_lock_irqsave(&sc->sc_pkmtx, flags);
84625+ list_add_tail(&q->pkq_list, &sc->sc_pkq);
84626+ safe_kfeed(sc);
84627+ spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
84628+ return (0);
84629+
84630+err:
84631+ crypto_kdone(krp);
84632+ return (0);
84633+}
84634+
84635+#define SAFE_CRK_PARAM_BASE 0
84636+#define SAFE_CRK_PARAM_EXP 1
84637+#define SAFE_CRK_PARAM_MOD 2
84638+
84639+static int
84640+safe_kstart(struct safe_softc *sc)
84641+{
84642+ struct cryptkop *krp = sc->sc_pkq_cur->pkq_krp;
84643+ int exp_bits, mod_bits, base_bits;
84644+ u_int32_t op, a_off, b_off, c_off, d_off;
84645+
84646+ DPRINTF(("%s()\n", __FUNCTION__));
84647+
84648+ if (krp->krp_iparams < 3 || krp->krp_oparams != 1) {
84649+ krp->krp_status = EINVAL;
84650+ return (1);
84651+ }
84652+
84653+ base_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_BASE]);
84654+ if (base_bits > 2048)
84655+ goto too_big;
84656+ if (base_bits <= 0) /* 5. base not zero */
84657+ goto too_small;
84658+
84659+ exp_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_EXP]);
84660+ if (exp_bits > 2048)
84661+ goto too_big;
84662+ if (exp_bits <= 0) /* 1. exponent word length > 0 */
84663+ goto too_small; /* 4. exponent not zero */
84664+
84665+ mod_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_MOD]);
84666+ if (mod_bits > 2048)
84667+ goto too_big;
84668+ if (mod_bits <= 32) /* 2. modulus word length > 1 */
84669+ goto too_small; /* 8. MSW of modulus != zero */
84670+ if (mod_bits < exp_bits) /* 3 modulus len >= exponent len */
84671+ goto too_small;
84672+ if ((krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p[0] & 1) == 0)
84673+ goto bad_domain; /* 6. modulus is odd */
84674+ if (mod_bits > krp->krp_param[krp->krp_iparams].crp_nbits)
84675+ goto too_small; /* make sure result will fit */
84676+
84677+ /* 7. modulus > base */
84678+ if (mod_bits < base_bits)
84679+ goto too_small;
84680+ if (mod_bits == base_bits) {
84681+ u_int8_t *basep, *modp;
84682+ int i;
84683+
84684+ basep = krp->krp_param[SAFE_CRK_PARAM_BASE].crp_p +
84685+ ((base_bits + 7) / 8) - 1;
84686+ modp = krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p +
84687+ ((mod_bits + 7) / 8) - 1;
84688+
84689+ for (i = 0; i < (mod_bits + 7) / 8; i++, basep--, modp--) {
84690+ if (*modp < *basep)
84691+ goto too_small;
84692+ if (*modp > *basep)
84693+ break;
84694+ }
84695+ }
84696+
84697+ /* And on the 9th step, he rested. */
84698+
84699+ WRITE_REG(sc, SAFE_PK_A_LEN, (exp_bits + 31) / 32);
84700+ WRITE_REG(sc, SAFE_PK_B_LEN, (mod_bits + 31) / 32);
84701+ if (mod_bits > 1024) {
84702+ op = SAFE_PK_FUNC_EXP4;
84703+ a_off = 0x000;
84704+ b_off = 0x100;
84705+ c_off = 0x200;
84706+ d_off = 0x300;
84707+ } else {
84708+ op = SAFE_PK_FUNC_EXP16;
84709+ a_off = 0x000;
84710+ b_off = 0x080;
84711+ c_off = 0x100;
84712+ d_off = 0x180;
84713+ }
84714+ sc->sc_pk_reslen = b_off - a_off;
84715+ sc->sc_pk_resoff = d_off;
84716+
84717+ /* A is exponent, B is modulus, C is base, D is result */
84718+ safe_kload_reg(sc, a_off, b_off - a_off,
84719+ &krp->krp_param[SAFE_CRK_PARAM_EXP]);
84720+ WRITE_REG(sc, SAFE_PK_A_ADDR, a_off >> 2);
84721+ safe_kload_reg(sc, b_off, b_off - a_off,
84722+ &krp->krp_param[SAFE_CRK_PARAM_MOD]);
84723+ WRITE_REG(sc, SAFE_PK_B_ADDR, b_off >> 2);
84724+ safe_kload_reg(sc, c_off, b_off - a_off,
84725+ &krp->krp_param[SAFE_CRK_PARAM_BASE]);
84726+ WRITE_REG(sc, SAFE_PK_C_ADDR, c_off >> 2);
84727+ WRITE_REG(sc, SAFE_PK_D_ADDR, d_off >> 2);
84728+
84729+ WRITE_REG(sc, SAFE_PK_FUNC, op | SAFE_PK_FUNC_RUN);
84730+
84731+ return (0);
84732+
84733+too_big:
84734+ krp->krp_status = E2BIG;
84735+ return (1);
84736+too_small:
84737+ krp->krp_status = ERANGE;
84738+ return (1);
84739+bad_domain:
84740+ krp->krp_status = EDOM;
84741+ return (1);
84742+}
84743+
84744+static int
84745+safe_ksigbits(struct safe_softc *sc, struct crparam *cr)
84746+{
84747+ u_int plen = (cr->crp_nbits + 7) / 8;
84748+ int i, sig = plen * 8;
84749+ u_int8_t c, *p = cr->crp_p;
84750+
84751+ DPRINTF(("%s()\n", __FUNCTION__));
84752+
84753+ for (i = plen - 1; i >= 0; i--) {
84754+ c = p[i];
84755+ if (c != 0) {
84756+ while ((c & 0x80) == 0) {
84757+ sig--;
84758+ c <<= 1;
84759+ }
84760+ break;
84761+ }
84762+ sig -= 8;
84763+ }
84764+ return (sig);
84765+}
84766+
84767+static void
84768+safe_kfeed(struct safe_softc *sc)
84769+{
84770+ struct safe_pkq *q, *tmp;
84771+
84772+ DPRINTF(("%s()\n", __FUNCTION__));
84773+
84774+ if (list_empty(&sc->sc_pkq) && sc->sc_pkq_cur == NULL)
84775+ return;
84776+ if (sc->sc_pkq_cur != NULL)
84777+ return;
84778+ list_for_each_entry_safe(q, tmp, &sc->sc_pkq, pkq_list) {
84779+ sc->sc_pkq_cur = q;
84780+ list_del(&q->pkq_list);
84781+ if (safe_kstart(sc) != 0) {
84782+ crypto_kdone(q->pkq_krp);
84783+ kfree(q);
84784+ sc->sc_pkq_cur = NULL;
84785+ } else {
84786+ /* op started, start polling */
84787+ mod_timer(&sc->sc_pkto, jiffies + 1);
84788+ break;
84789+ }
84790+ }
84791+}
84792+
84793+static void
84794+safe_kpoll(unsigned long arg)
84795+{
84796+ struct safe_softc *sc = NULL;
84797+ struct safe_pkq *q;
84798+ struct crparam *res;
84799+ int i;
84800+ u_int32_t buf[64];
84801+ unsigned long flags;
84802+
84803+ DPRINTF(("%s()\n", __FUNCTION__));
84804+
84805+ if (arg >= SAFE_MAX_CHIPS)
84806+ return;
84807+ sc = safe_chip_idx[arg];
84808+ if (!sc) {
84809+ DPRINTF(("%s() - bad callback\n", __FUNCTION__));
84810+ return;
84811+ }
84812+
84813+ spin_lock_irqsave(&sc->sc_pkmtx, flags);
84814+ if (sc->sc_pkq_cur == NULL)
84815+ goto out;
84816+ if (READ_REG(sc, SAFE_PK_FUNC) & SAFE_PK_FUNC_RUN) {
84817+ /* still running, check back later */
84818+ mod_timer(&sc->sc_pkto, jiffies + 1);
84819+ goto out;
84820+ }
84821+
84822+ q = sc->sc_pkq_cur;
84823+ res = &q->pkq_krp->krp_param[q->pkq_krp->krp_iparams];
84824+ bzero(buf, sizeof(buf));
84825+ bzero(res->crp_p, (res->crp_nbits + 7) / 8);
84826+ for (i = 0; i < sc->sc_pk_reslen >> 2; i++)
84827+ buf[i] = le32_to_cpu(READ_REG(sc, SAFE_PK_RAM_START +
84828+ sc->sc_pk_resoff + (i << 2)));
84829+ bcopy(buf, res->crp_p, (res->crp_nbits + 7) / 8);
84830+ /*
84831+ * reduce the bits that need copying if possible
84832+ */
84833+ res->crp_nbits = min(res->crp_nbits,sc->sc_pk_reslen * 8);
84834+ res->crp_nbits = safe_ksigbits(sc, res);
84835+
84836+ for (i = SAFE_PK_RAM_START; i < SAFE_PK_RAM_END; i += 4)
84837+ WRITE_REG(sc, i, 0);
84838+
84839+ crypto_kdone(q->pkq_krp);
84840+ kfree(q);
84841+ sc->sc_pkq_cur = NULL;
84842+
84843+ safe_kfeed(sc);
84844+out:
84845+ spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
84846+}
84847+
84848+static void
84849+safe_kload_reg(struct safe_softc *sc, u_int32_t off, u_int32_t len,
84850+ struct crparam *n)
84851+{
84852+ u_int32_t buf[64], i;
84853+
84854+ DPRINTF(("%s()\n", __FUNCTION__));
84855+
84856+ bzero(buf, sizeof(buf));
84857+ bcopy(n->crp_p, buf, (n->crp_nbits + 7) / 8);
84858+
84859+ for (i = 0; i < len >> 2; i++)
84860+ WRITE_REG(sc, SAFE_PK_RAM_START + off + (i << 2),
84861+ cpu_to_le32(buf[i]));
84862+}
84863+
84864+#ifdef SAFE_DEBUG
84865+static void
84866+safe_dump_dmastatus(struct safe_softc *sc, const char *tag)
84867+{
84868+ printf("%s: ENDIAN 0x%x SRC 0x%x DST 0x%x STAT 0x%x\n"
84869+ , tag
84870+ , READ_REG(sc, SAFE_DMA_ENDIAN)
84871+ , READ_REG(sc, SAFE_DMA_SRCADDR)
84872+ , READ_REG(sc, SAFE_DMA_DSTADDR)
84873+ , READ_REG(sc, SAFE_DMA_STAT)
84874+ );
84875+}
84876+
84877+static void
84878+safe_dump_intrstate(struct safe_softc *sc, const char *tag)
84879+{
84880+ printf("%s: HI_CFG 0x%x HI_MASK 0x%x HI_DESC_CNT 0x%x HU_STAT 0x%x HM_STAT 0x%x\n"
84881+ , tag
84882+ , READ_REG(sc, SAFE_HI_CFG)
84883+ , READ_REG(sc, SAFE_HI_MASK)
84884+ , READ_REG(sc, SAFE_HI_DESC_CNT)
84885+ , READ_REG(sc, SAFE_HU_STAT)
84886+ , READ_REG(sc, SAFE_HM_STAT)
84887+ );
84888+}
84889+
84890+static void
84891+safe_dump_ringstate(struct safe_softc *sc, const char *tag)
84892+{
84893+ u_int32_t estat = READ_REG(sc, SAFE_PE_ERNGSTAT);
84894+
84895+ /* NB: assume caller has lock on ring */
84896+ printf("%s: ERNGSTAT %x (next %u) back %lu front %lu\n",
84897+ tag,
84898+ estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S),
84899+ (unsigned long)(sc->sc_back - sc->sc_ring),
84900+ (unsigned long)(sc->sc_front - sc->sc_ring));
84901+}
84902+
84903+static void
84904+safe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re)
84905+{
84906+ int ix, nsegs;
84907+
84908+ ix = re - sc->sc_ring;
84909+ printf("%s: %p (%u): csr %x src %x dst %x sa %x len %x\n"
84910+ , tag
84911+ , re, ix
84912+ , re->re_desc.d_csr
84913+ , re->re_desc.d_src
84914+ , re->re_desc.d_dst
84915+ , re->re_desc.d_sa
84916+ , re->re_desc.d_len
84917+ );
84918+ if (re->re_src.nsegs > 1) {
84919+ ix = (re->re_desc.d_src - sc->sc_spalloc.dma_paddr) /
84920+ sizeof(struct safe_pdesc);
84921+ for (nsegs = re->re_src.nsegs; nsegs; nsegs--) {
84922+ printf(" spd[%u] %p: %p size %u flags %x"
84923+ , ix, &sc->sc_spring[ix]
84924+ , (caddr_t)(uintptr_t) sc->sc_spring[ix].pd_addr
84925+ , sc->sc_spring[ix].pd_size
84926+ , sc->sc_spring[ix].pd_flags
84927+ );
84928+ if (sc->sc_spring[ix].pd_size == 0)
84929+ printf(" (zero!)");
84930+ printf("\n");
84931+ if (++ix == SAFE_TOTAL_SPART)
84932+ ix = 0;
84933+ }
84934+ }
84935+ if (re->re_dst.nsegs > 1) {
84936+ ix = (re->re_desc.d_dst - sc->sc_dpalloc.dma_paddr) /
84937+ sizeof(struct safe_pdesc);
84938+ for (nsegs = re->re_dst.nsegs; nsegs; nsegs--) {
84939+ printf(" dpd[%u] %p: %p flags %x\n"
84940+ , ix, &sc->sc_dpring[ix]
84941+ , (caddr_t)(uintptr_t) sc->sc_dpring[ix].pd_addr
84942+ , sc->sc_dpring[ix].pd_flags
84943+ );
84944+ if (++ix == SAFE_TOTAL_DPART)
84945+ ix = 0;
84946+ }
84947+ }
84948+ printf("sa: cmd0 %08x cmd1 %08x staterec %x\n",
84949+ re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec);
84950+ printf("sa: key %x %x %x %x %x %x %x %x\n"
84951+ , re->re_sa.sa_key[0]
84952+ , re->re_sa.sa_key[1]
84953+ , re->re_sa.sa_key[2]
84954+ , re->re_sa.sa_key[3]
84955+ , re->re_sa.sa_key[4]
84956+ , re->re_sa.sa_key[5]
84957+ , re->re_sa.sa_key[6]
84958+ , re->re_sa.sa_key[7]
84959+ );
84960+ printf("sa: indigest %x %x %x %x %x\n"
84961+ , re->re_sa.sa_indigest[0]
84962+ , re->re_sa.sa_indigest[1]
84963+ , re->re_sa.sa_indigest[2]
84964+ , re->re_sa.sa_indigest[3]
84965+ , re->re_sa.sa_indigest[4]
84966+ );
84967+ printf("sa: outdigest %x %x %x %x %x\n"
84968+ , re->re_sa.sa_outdigest[0]
84969+ , re->re_sa.sa_outdigest[1]
84970+ , re->re_sa.sa_outdigest[2]
84971+ , re->re_sa.sa_outdigest[3]
84972+ , re->re_sa.sa_outdigest[4]
84973+ );
84974+ printf("sr: iv %x %x %x %x\n"
84975+ , re->re_sastate.sa_saved_iv[0]
84976+ , re->re_sastate.sa_saved_iv[1]
84977+ , re->re_sastate.sa_saved_iv[2]
84978+ , re->re_sastate.sa_saved_iv[3]
84979+ );
84980+ printf("sr: hashbc %u indigest %x %x %x %x %x\n"
84981+ , re->re_sastate.sa_saved_hashbc
84982+ , re->re_sastate.sa_saved_indigest[0]
84983+ , re->re_sastate.sa_saved_indigest[1]
84984+ , re->re_sastate.sa_saved_indigest[2]
84985+ , re->re_sastate.sa_saved_indigest[3]
84986+ , re->re_sastate.sa_saved_indigest[4]
84987+ );
84988+}
84989+
84990+static void
84991+safe_dump_ring(struct safe_softc *sc, const char *tag)
84992+{
84993+ unsigned long flags;
84994+
84995+ spin_lock_irqsave(&sc->sc_ringmtx, flags);
84996+ printf("\nSafeNet Ring State:\n");
84997+ safe_dump_intrstate(sc, tag);
84998+ safe_dump_dmastatus(sc, tag);
84999+ safe_dump_ringstate(sc, tag);
85000+ if (sc->sc_nqchip) {
85001+ struct safe_ringentry *re = sc->sc_back;
85002+ do {
85003+ safe_dump_request(sc, tag, re);
85004+ if (++re == sc->sc_ringtop)
85005+ re = sc->sc_ring;
85006+ } while (re != sc->sc_front);
85007+ }
85008+ spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
85009+}
85010+#endif /* SAFE_DEBUG */
85011+
85012+
85013+static int safe_probe(struct pci_dev *dev, const struct pci_device_id *ent)
85014+{
85015+ struct safe_softc *sc = NULL;
85016+ u32 mem_start, mem_len, cmd;
85017+ int i, rc, devinfo;
85018+ dma_addr_t raddr;
85019+ static int num_chips = 0;
85020+
85021+ DPRINTF(("%s()\n", __FUNCTION__));
85022+
85023+ if (pci_enable_device(dev) < 0)
85024+ return(-ENODEV);
85025+
85026+ if (!dev->irq) {
85027+ printk("safe: found device with no IRQ assigned. check BIOS settings!");
85028+ pci_disable_device(dev);
85029+ return(-ENODEV);
85030+ }
85031+
85032+ if (pci_set_mwi(dev)) {
85033+ printk("safe: pci_set_mwi failed!");
85034+ return(-ENODEV);
85035+ }
85036+
85037+ sc = (struct safe_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
85038+ if (!sc)
85039+ return(-ENOMEM);
85040+ memset(sc, 0, sizeof(*sc));
85041+
85042+ softc_device_init(sc, "safe", num_chips, safe_methods);
85043+
85044+ sc->sc_irq = -1;
85045+ sc->sc_cid = -1;
85046+ sc->sc_pcidev = dev;
85047+ if (num_chips < SAFE_MAX_CHIPS) {
85048+ safe_chip_idx[device_get_unit(sc->sc_dev)] = sc;
85049+ num_chips++;
85050+ }
85051+
85052+ INIT_LIST_HEAD(&sc->sc_pkq);
85053+ spin_lock_init(&sc->sc_pkmtx);
85054+
85055+ pci_set_drvdata(sc->sc_pcidev, sc);
85056+
85057+ /* we read its hardware registers as memory */
85058+ mem_start = pci_resource_start(sc->sc_pcidev, 0);
85059+ mem_len = pci_resource_len(sc->sc_pcidev, 0);
85060+
85061+ sc->sc_base_addr = (ocf_iomem_t) ioremap(mem_start, mem_len);
85062+ if (!sc->sc_base_addr) {
85063+ device_printf(sc->sc_dev, "failed to ioremap 0x%x-0x%x\n",
85064+ mem_start, mem_start + mem_len - 1);
85065+ goto out;
85066+ }
85067+
85068+ /* fix up the bus size */
85069+ if (pci_set_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
85070+ device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
85071+ goto out;
85072+ }
85073+ if (pci_set_consistent_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
85074+ device_printf(sc->sc_dev, "No usable consistent DMA configuration, aborting.\n");
85075+ goto out;
85076+ }
85077+
85078+ pci_set_master(sc->sc_pcidev);
85079+
85080+ pci_read_config_dword(sc->sc_pcidev, PCI_COMMAND, &cmd);
85081+
85082+ if (!(cmd & PCI_COMMAND_MEMORY)) {
85083+ device_printf(sc->sc_dev, "failed to enable memory mapping\n");
85084+ goto out;
85085+ }
85086+
85087+ if (!(cmd & PCI_COMMAND_MASTER)) {
85088+ device_printf(sc->sc_dev, "failed to enable bus mastering\n");
85089+ goto out;
85090+ }
85091+
85092+ rc = request_irq(dev->irq, safe_intr, IRQF_SHARED, "safe", sc);
85093+ if (rc) {
85094+ device_printf(sc->sc_dev, "failed to hook irq %d\n", sc->sc_irq);
85095+ goto out;
85096+ }
85097+ sc->sc_irq = dev->irq;
85098+
85099+ sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) &
85100+ (SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN);
85101+
85102+ /*
85103+ * Allocate packet engine descriptors.
85104+ */
85105+ sc->sc_ringalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
85106+ SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
85107+ &sc->sc_ringalloc.dma_paddr);
85108+ if (!sc->sc_ringalloc.dma_vaddr) {
85109+ device_printf(sc->sc_dev, "cannot allocate PE descriptor ring\n");
85110+ goto out;
85111+ }
85112+
85113+ /*
85114+ * Hookup the static portion of all our data structures.
85115+ */
85116+ sc->sc_ring = (struct safe_ringentry *) sc->sc_ringalloc.dma_vaddr;
85117+ sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE;
85118+ sc->sc_front = sc->sc_ring;
85119+ sc->sc_back = sc->sc_ring;
85120+ raddr = sc->sc_ringalloc.dma_paddr;
85121+ bzero(sc->sc_ring, SAFE_MAX_NQUEUE * sizeof(struct safe_ringentry));
85122+ for (i = 0; i < SAFE_MAX_NQUEUE; i++) {
85123+ struct safe_ringentry *re = &sc->sc_ring[i];
85124+
85125+ re->re_desc.d_sa = raddr +
85126+ offsetof(struct safe_ringentry, re_sa);
85127+ re->re_sa.sa_staterec = raddr +
85128+ offsetof(struct safe_ringentry, re_sastate);
85129+
85130+ raddr += sizeof (struct safe_ringentry);
85131+ }
85132+ spin_lock_init(&sc->sc_ringmtx);
85133+
85134+ /*
85135+ * Allocate scatter and gather particle descriptors.
85136+ */
85137+ sc->sc_spalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
85138+ SAFE_TOTAL_SPART * sizeof (struct safe_pdesc),
85139+ &sc->sc_spalloc.dma_paddr);
85140+ if (!sc->sc_spalloc.dma_vaddr) {
85141+ device_printf(sc->sc_dev, "cannot allocate source particle descriptor ring\n");
85142+ goto out;
85143+ }
85144+ sc->sc_spring = (struct safe_pdesc *) sc->sc_spalloc.dma_vaddr;
85145+ sc->sc_springtop = sc->sc_spring + SAFE_TOTAL_SPART;
85146+ sc->sc_spfree = sc->sc_spring;
85147+ bzero(sc->sc_spring, SAFE_TOTAL_SPART * sizeof(struct safe_pdesc));
85148+
85149+ sc->sc_dpalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
85150+ SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
85151+ &sc->sc_dpalloc.dma_paddr);
85152+ if (!sc->sc_dpalloc.dma_vaddr) {
85153+ device_printf(sc->sc_dev, "cannot allocate destination particle descriptor ring\n");
85154+ goto out;
85155+ }
85156+ sc->sc_dpring = (struct safe_pdesc *) sc->sc_dpalloc.dma_vaddr;
85157+ sc->sc_dpringtop = sc->sc_dpring + SAFE_TOTAL_DPART;
85158+ sc->sc_dpfree = sc->sc_dpring;
85159+ bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc));
85160+
85161+ sc->sc_cid = crypto_get_driverid(softc_get_device(sc), CRYPTOCAP_F_HARDWARE);
85162+ if (sc->sc_cid < 0) {
85163+ device_printf(sc->sc_dev, "could not get crypto driver id\n");
85164+ goto out;
85165+ }
85166+
85167+ printf("%s:", device_get_nameunit(sc->sc_dev));
85168+
85169+ devinfo = READ_REG(sc, SAFE_DEVINFO);
85170+ if (devinfo & SAFE_DEVINFO_RNG) {
85171+ sc->sc_flags |= SAFE_FLAGS_RNG;
85172+ printf(" rng");
85173+ }
85174+ if (devinfo & SAFE_DEVINFO_PKEY) {
85175+ printf(" key");
85176+ sc->sc_flags |= SAFE_FLAGS_KEY;
85177+ crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0);
85178+#if 0
85179+ crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0);
85180+#endif
85181+ init_timer(&sc->sc_pkto);
85182+ sc->sc_pkto.function = safe_kpoll;
85183+ sc->sc_pkto.data = (unsigned long) device_get_unit(sc->sc_dev);
85184+ }
85185+ if (devinfo & SAFE_DEVINFO_DES) {
85186+ printf(" des/3des");
85187+ crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
85188+ crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
85189+ }
85190+ if (devinfo & SAFE_DEVINFO_AES) {
85191+ printf(" aes");
85192+ crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
85193+ }
85194+ if (devinfo & SAFE_DEVINFO_MD5) {
85195+ printf(" md5");
85196+ crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
85197+ }
85198+ if (devinfo & SAFE_DEVINFO_SHA1) {
85199+ printf(" sha1");
85200+ crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
85201+ }
85202+ printf(" null");
85203+ crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0);
85204+ crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0);
85205+ /* XXX other supported algorithms */
85206+ printf("\n");
85207+
85208+ safe_reset_board(sc); /* reset h/w */
85209+ safe_init_board(sc); /* init h/w */
85210+
85211+#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
85212+ if (sc->sc_flags & SAFE_FLAGS_RNG) {
85213+ safe_rng_init(sc);
85214+ crypto_rregister(sc->sc_cid, safe_read_random, sc);
85215+ }
85216+#endif /* SAFE_NO_RNG */
85217+
85218+ return (0);
85219+
85220+out:
85221+ if (sc->sc_cid >= 0)
85222+ crypto_unregister_all(sc->sc_cid);
85223+ if (sc->sc_irq != -1)
85224+ free_irq(sc->sc_irq, sc);
85225+ if (sc->sc_ringalloc.dma_vaddr)
85226+ pci_free_consistent(sc->sc_pcidev,
85227+ SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
85228+ sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
85229+ if (sc->sc_spalloc.dma_vaddr)
85230+ pci_free_consistent(sc->sc_pcidev,
85231+ SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
85232+ sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
85233+ if (sc->sc_dpalloc.dma_vaddr)
85234+ pci_free_consistent(sc->sc_pcidev,
85235+ SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
85236+ sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
85237+ kfree(sc);
85238+ return(-ENODEV);
85239+}
85240+
85241+static void safe_remove(struct pci_dev *dev)
85242+{
85243+ struct safe_softc *sc = pci_get_drvdata(dev);
85244+
85245+ DPRINTF(("%s()\n", __FUNCTION__));
85246+
85247+ /* XXX wait/abort active ops */
85248+
85249+ WRITE_REG(sc, SAFE_HI_MASK, 0); /* disable interrupts */
85250+
85251+ del_timer_sync(&sc->sc_pkto);
85252+
85253+ crypto_unregister_all(sc->sc_cid);
85254+
85255+ safe_cleanchip(sc);
85256+
85257+ if (sc->sc_irq != -1)
85258+ free_irq(sc->sc_irq, sc);
85259+ if (sc->sc_ringalloc.dma_vaddr)
85260+ pci_free_consistent(sc->sc_pcidev,
85261+ SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
85262+ sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
85263+ if (sc->sc_spalloc.dma_vaddr)
85264+ pci_free_consistent(sc->sc_pcidev,
85265+ SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
85266+ sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
85267+ if (sc->sc_dpalloc.dma_vaddr)
85268+ pci_free_consistent(sc->sc_pcidev,
85269+ SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
85270+ sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
85271+ sc->sc_irq = -1;
85272+ sc->sc_ringalloc.dma_vaddr = NULL;
85273+ sc->sc_spalloc.dma_vaddr = NULL;
85274+ sc->sc_dpalloc.dma_vaddr = NULL;
85275+}
85276+
85277+static struct pci_device_id safe_pci_tbl[] = {
85278+ { PCI_VENDOR_SAFENET, PCI_PRODUCT_SAFEXCEL,
85279+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
85280+ { },
85281+};
85282+MODULE_DEVICE_TABLE(pci, safe_pci_tbl);
85283+
85284+static struct pci_driver safe_driver = {
85285+ .name = "safe",
85286+ .id_table = safe_pci_tbl,
85287+ .probe = safe_probe,
85288+ .remove = safe_remove,
85289+ /* add PM stuff here one day */
85290+};
85291+
85292+static int __init safe_init (void)
85293+{
85294+ struct safe_softc *sc = NULL;
85295+ int rc;
85296+
85297+ DPRINTF(("%s(%p)\n", __FUNCTION__, safe_init));
85298+
85299+ rc = pci_register_driver(&safe_driver);
85300+ pci_register_driver_compat(&safe_driver, rc);
85301+
85302+ return rc;
85303+}
85304+
85305+static void __exit safe_exit (void)
85306+{
85307+ pci_unregister_driver(&safe_driver);
85308+}
85309+
85310+module_init(safe_init);
85311+module_exit(safe_exit);
85312+
85313+MODULE_LICENSE("BSD");
85314+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
85315+MODULE_DESCRIPTION("OCF driver for safenet PCI crypto devices");
85316diff --git a/crypto/ocf/safe/safereg.h b/crypto/ocf/safe/safereg.h
85317new file mode 100644
85318index 0000000..d3461f9
85319--- /dev/null
85320+++ b/crypto/ocf/safe/safereg.h
85321@@ -0,0 +1,421 @@
85322+/*-
85323+ * Copyright (c) 2003 Sam Leffler, Errno Consulting
85324+ * Copyright (c) 2003 Global Technology Associates, Inc.
85325+ * All rights reserved.
85326+ *
85327+ * Redistribution and use in source and binary forms, with or without
85328+ * modification, are permitted provided that the following conditions
85329+ * are met:
85330+ * 1. Redistributions of source code must retain the above copyright
85331+ * notice, this list of conditions and the following disclaimer.
85332+ * 2. Redistributions in binary form must reproduce the above copyright
85333+ * notice, this list of conditions and the following disclaimer in the
85334+ * documentation and/or other materials provided with the distribution.
85335+ *
85336+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
85337+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
85338+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
85339+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
85340+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
85341+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
85342+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
85343+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
85344+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
85345+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85346+ * SUCH DAMAGE.
85347+ *
85348+ * $FreeBSD: src/sys/dev/safe/safereg.h,v 1.1 2003/07/21 21:46:07 sam Exp $
85349+ */
85350+#ifndef _SAFE_SAFEREG_H_
85351+#define _SAFE_SAFEREG_H_
85352+
85353+/*
85354+ * Register definitions for SafeNet SafeXcel-1141 crypto device.
85355+ * Definitions from revision 1.3 (Nov 6 2002) of the User's Manual.
85356+ */
85357+
85358+#define BS_BAR 0x10 /* DMA base address register */
85359+#define BS_TRDY_TIMEOUT 0x40 /* TRDY timeout */
85360+#define BS_RETRY_TIMEOUT 0x41 /* DMA retry timeout */
85361+
85362+#define PCI_VENDOR_SAFENET 0x16ae /* SafeNet, Inc. */
85363+
85364+/* SafeNet */
85365+#define PCI_PRODUCT_SAFEXCEL 0x1141 /* 1141 */
85366+
85367+#define SAFE_PE_CSR 0x0000 /* Packet Enginge Ctrl/Status */
85368+#define SAFE_PE_SRC 0x0004 /* Packet Engine Source */
85369+#define SAFE_PE_DST 0x0008 /* Packet Engine Destination */
85370+#define SAFE_PE_SA 0x000c /* Packet Engine SA */
85371+#define SAFE_PE_LEN 0x0010 /* Packet Engine Length */
85372+#define SAFE_PE_DMACFG 0x0040 /* Packet Engine DMA Configuration */
85373+#define SAFE_PE_DMASTAT 0x0044 /* Packet Engine DMA Status */
85374+#define SAFE_PE_PDRBASE 0x0048 /* Packet Engine Descriptor Ring Base */
85375+#define SAFE_PE_RDRBASE 0x004c /* Packet Engine Result Ring Base */
85376+#define SAFE_PE_RINGCFG 0x0050 /* Packet Engine Ring Configuration */
85377+#define SAFE_PE_RINGPOLL 0x0054 /* Packet Engine Ring Poll */
85378+#define SAFE_PE_IRNGSTAT 0x0058 /* Packet Engine Internal Ring Status */
85379+#define SAFE_PE_ERNGSTAT 0x005c /* Packet Engine External Ring Status */
85380+#define SAFE_PE_IOTHRESH 0x0060 /* Packet Engine I/O Threshold */
85381+#define SAFE_PE_GRNGBASE 0x0064 /* Packet Engine Gather Ring Base */
85382+#define SAFE_PE_SRNGBASE 0x0068 /* Packet Engine Scatter Ring Base */
85383+#define SAFE_PE_PARTSIZE 0x006c /* Packet Engine Particlar Ring Size */
85384+#define SAFE_PE_PARTCFG 0x0070 /* Packet Engine Particle Ring Config */
85385+#define SAFE_CRYPTO_CTRL 0x0080 /* Crypto Control */
85386+#define SAFE_DEVID 0x0084 /* Device ID */
85387+#define SAFE_DEVINFO 0x0088 /* Device Info */
85388+#define SAFE_HU_STAT 0x00a0 /* Host Unmasked Status */
85389+#define SAFE_HM_STAT 0x00a4 /* Host Masked Status (read-only) */
85390+#define SAFE_HI_CLR 0x00a4 /* Host Clear Interrupt (write-only) */
85391+#define SAFE_HI_MASK 0x00a8 /* Host Mask Control */
85392+#define SAFE_HI_CFG 0x00ac /* Interrupt Configuration */
85393+#define SAFE_HI_RD_DESCR 0x00b4 /* Force Descriptor Read */
85394+#define SAFE_HI_DESC_CNT 0x00b8 /* Host Descriptor Done Count */
85395+#define SAFE_DMA_ENDIAN 0x00c0 /* Master Endian Status */
85396+#define SAFE_DMA_SRCADDR 0x00c4 /* DMA Source Address Status */
85397+#define SAFE_DMA_DSTADDR 0x00c8 /* DMA Destination Address Status */
85398+#define SAFE_DMA_STAT 0x00cc /* DMA Current Status */
85399+#define SAFE_DMA_CFG 0x00d4 /* DMA Configuration/Status */
85400+#define SAFE_ENDIAN 0x00e0 /* Endian Configuration */
85401+#define SAFE_PK_A_ADDR 0x0800 /* Public Key A Address */
85402+#define SAFE_PK_B_ADDR 0x0804 /* Public Key B Address */
85403+#define SAFE_PK_C_ADDR 0x0808 /* Public Key C Address */
85404+#define SAFE_PK_D_ADDR 0x080c /* Public Key D Address */
85405+#define SAFE_PK_A_LEN 0x0810 /* Public Key A Length */
85406+#define SAFE_PK_B_LEN 0x0814 /* Public Key B Length */
85407+#define SAFE_PK_SHIFT 0x0818 /* Public Key Shift */
85408+#define SAFE_PK_FUNC 0x081c /* Public Key Function */
85409+#define SAFE_PK_RAM_START 0x1000 /* Public Key RAM start address */
85410+#define SAFE_PK_RAM_END 0x1fff /* Public Key RAM end address */
85411+
85412+#define SAFE_RNG_OUT 0x0100 /* RNG Output */
85413+#define SAFE_RNG_STAT 0x0104 /* RNG Status */
85414+#define SAFE_RNG_CTRL 0x0108 /* RNG Control */
85415+#define SAFE_RNG_A 0x010c /* RNG A */
85416+#define SAFE_RNG_B 0x0110 /* RNG B */
85417+#define SAFE_RNG_X_LO 0x0114 /* RNG X [31:0] */
85418+#define SAFE_RNG_X_MID 0x0118 /* RNG X [63:32] */
85419+#define SAFE_RNG_X_HI 0x011c /* RNG X [80:64] */
85420+#define SAFE_RNG_X_CNTR 0x0120 /* RNG Counter */
85421+#define SAFE_RNG_ALM_CNT 0x0124 /* RNG Alarm Count */
85422+#define SAFE_RNG_CNFG 0x0128 /* RNG Configuration */
85423+#define SAFE_RNG_LFSR1_LO 0x012c /* RNG LFSR1 [31:0] */
85424+#define SAFE_RNG_LFSR1_HI 0x0130 /* RNG LFSR1 [47:32] */
85425+#define SAFE_RNG_LFSR2_LO 0x0134 /* RNG LFSR1 [31:0] */
85426+#define SAFE_RNG_LFSR2_HI 0x0138 /* RNG LFSR1 [47:32] */
85427+
85428+#define SAFE_PE_CSR_READY 0x00000001 /* ready for processing */
85429+#define SAFE_PE_CSR_DONE 0x00000002 /* h/w completed processing */
85430+#define SAFE_PE_CSR_LOADSA 0x00000004 /* load SA digests */
85431+#define SAFE_PE_CSR_HASHFINAL 0x00000010 /* do hash pad & write result */
85432+#define SAFE_PE_CSR_SABUSID 0x000000c0 /* bus id for SA */
85433+#define SAFE_PE_CSR_SAPCI 0x00000040 /* PCI bus id for SA */
85434+#define SAFE_PE_CSR_NXTHDR 0x0000ff00 /* next hdr value for IPsec */
85435+#define SAFE_PE_CSR_FPAD 0x0000ff00 /* fixed pad for basic ops */
85436+#define SAFE_PE_CSR_STATUS 0x00ff0000 /* operation result status */
85437+#define SAFE_PE_CSR_AUTH_FAIL 0x00010000 /* ICV mismatch (inbound) */
85438+#define SAFE_PE_CSR_PAD_FAIL 0x00020000 /* pad verify fail (inbound) */
85439+#define SAFE_PE_CSR_SEQ_FAIL 0x00040000 /* sequence number (inbound) */
85440+#define SAFE_PE_CSR_XERROR 0x00080000 /* extended error follows */
85441+#define SAFE_PE_CSR_XECODE 0x00f00000 /* extended error code */
85442+#define SAFE_PE_CSR_XECODE_S 20
85443+#define SAFE_PE_CSR_XECODE_BADCMD 0 /* invalid command */
85444+#define SAFE_PE_CSR_XECODE_BADALG 1 /* invalid algorithm */
85445+#define SAFE_PE_CSR_XECODE_ALGDIS 2 /* algorithm disabled */
85446+#define SAFE_PE_CSR_XECODE_ZEROLEN 3 /* zero packet length */
85447+#define SAFE_PE_CSR_XECODE_DMAERR 4 /* bus DMA error */
85448+#define SAFE_PE_CSR_XECODE_PIPEABORT 5 /* secondary bus DMA error */
85449+#define SAFE_PE_CSR_XECODE_BADSPI 6 /* IPsec SPI mismatch */
85450+#define SAFE_PE_CSR_XECODE_TIMEOUT 10 /* failsafe timeout */
85451+#define SAFE_PE_CSR_PAD 0xff000000 /* ESP padding control/status */
85452+#define SAFE_PE_CSR_PAD_MIN 0x00000000 /* minimum IPsec padding */
85453+#define SAFE_PE_CSR_PAD_16 0x08000000 /* pad to 16-byte boundary */
85454+#define SAFE_PE_CSR_PAD_32 0x10000000 /* pad to 32-byte boundary */
85455+#define SAFE_PE_CSR_PAD_64 0x20000000 /* pad to 64-byte boundary */
85456+#define SAFE_PE_CSR_PAD_128 0x40000000 /* pad to 128-byte boundary */
85457+#define SAFE_PE_CSR_PAD_256 0x80000000 /* pad to 256-byte boundary */
85458+
85459+/*
85460+ * Check the CSR to see if the PE has returned ownership to
85461+ * the host. Note that before processing a descriptor this
85462+ * must be done followed by a check of the SAFE_PE_LEN register
85463+ * status bits to avoid premature processing of a descriptor
85464+ * on its way back to the host.
85465+ */
85466+#define SAFE_PE_CSR_IS_DONE(_csr) \
85467+ (((_csr) & (SAFE_PE_CSR_READY | SAFE_PE_CSR_DONE)) == SAFE_PE_CSR_DONE)
85468+
85469+#define SAFE_PE_LEN_LENGTH 0x000fffff /* total length (bytes) */
85470+#define SAFE_PE_LEN_READY 0x00400000 /* ready for processing */
85471+#define SAFE_PE_LEN_DONE 0x00800000 /* h/w completed processing */
85472+#define SAFE_PE_LEN_BYPASS 0xff000000 /* bypass offset (bytes) */
85473+#define SAFE_PE_LEN_BYPASS_S 24
85474+
85475+#define SAFE_PE_LEN_IS_DONE(_len) \
85476+ (((_len) & (SAFE_PE_LEN_READY | SAFE_PE_LEN_DONE)) == SAFE_PE_LEN_DONE)
85477+
85478+/* NB: these apply to HU_STAT, HM_STAT, HI_CLR, and HI_MASK */
85479+#define SAFE_INT_PE_CDONE 0x00000002 /* PE context done */
85480+#define SAFE_INT_PE_DDONE 0x00000008 /* PE descriptor done */
85481+#define SAFE_INT_PE_ERROR 0x00000010 /* PE error */
85482+#define SAFE_INT_PE_ODONE 0x00000020 /* PE operation done */
85483+
85484+#define SAFE_HI_CFG_PULSE 0x00000001 /* use pulse interrupt */
85485+#define SAFE_HI_CFG_LEVEL 0x00000000 /* use level interrupt */
85486+#define SAFE_HI_CFG_AUTOCLR 0x00000002 /* auto-clear pulse interrupt */
85487+
85488+#define SAFE_ENDIAN_PASS 0x000000e4 /* straight pass-thru */
85489+#define SAFE_ENDIAN_SWAB 0x0000001b /* swap bytes in 32-bit word */
85490+
85491+#define SAFE_PE_DMACFG_PERESET 0x00000001 /* reset packet engine */
85492+#define SAFE_PE_DMACFG_PDRRESET 0x00000002 /* reset PDR counters/ptrs */
85493+#define SAFE_PE_DMACFG_SGRESET 0x00000004 /* reset scatter/gather cache */
85494+#define SAFE_PE_DMACFG_FSENA 0x00000008 /* enable failsafe reset */
85495+#define SAFE_PE_DMACFG_PEMODE 0x00000100 /* packet engine mode */
85496+#define SAFE_PE_DMACFG_SAPREC 0x00000200 /* SA precedes packet */
85497+#define SAFE_PE_DMACFG_PKFOLL 0x00000400 /* packet follows descriptor */
85498+#define SAFE_PE_DMACFG_GPRBID 0x00003000 /* gather particle ring busid */
85499+#define SAFE_PE_DMACFG_GPRPCI 0x00001000 /* PCI gather particle ring */
85500+#define SAFE_PE_DMACFG_SPRBID 0x0000c000 /* scatter part. ring busid */
85501+#define SAFE_PE_DMACFG_SPRPCI 0x00004000 /* PCI scatter part. ring */
85502+#define SAFE_PE_DMACFG_ESDESC 0x00010000 /* endian swap descriptors */
85503+#define SAFE_PE_DMACFG_ESSA 0x00020000 /* endian swap SA data */
85504+#define SAFE_PE_DMACFG_ESPACKET 0x00040000 /* endian swap packet data */
85505+#define SAFE_PE_DMACFG_ESPDESC 0x00080000 /* endian swap particle desc. */
85506+#define SAFE_PE_DMACFG_NOPDRUP 0x00100000 /* supp. PDR ownership update */
85507+#define SAFE_PD_EDMACFG_PCIMODE 0x01000000 /* PCI target mode */
85508+
85509+#define SAFE_PE_DMASTAT_PEIDONE 0x00000001 /* PE core input done */
85510+#define SAFE_PE_DMASTAT_PEODONE 0x00000002 /* PE core output done */
85511+#define SAFE_PE_DMASTAT_ENCDONE 0x00000004 /* encryption done */
85512+#define SAFE_PE_DMASTAT_IHDONE 0x00000008 /* inner hash done */
85513+#define SAFE_PE_DMASTAT_OHDONE 0x00000010 /* outer hash (HMAC) done */
85514+#define SAFE_PE_DMASTAT_PADFLT 0x00000020 /* crypto pad fault */
85515+#define SAFE_PE_DMASTAT_ICVFLT 0x00000040 /* ICV fault */
85516+#define SAFE_PE_DMASTAT_SPIMIS 0x00000080 /* SPI mismatch */
85517+#define SAFE_PE_DMASTAT_CRYPTO 0x00000100 /* crypto engine timeout */
85518+#define SAFE_PE_DMASTAT_CQACT 0x00000200 /* command queue active */
85519+#define SAFE_PE_DMASTAT_IRACT 0x00000400 /* input request active */
85520+#define SAFE_PE_DMASTAT_ORACT 0x00000800 /* output request active */
85521+#define SAFE_PE_DMASTAT_PEISIZE 0x003ff000 /* PE input size:32-bit words */
85522+#define SAFE_PE_DMASTAT_PEOSIZE 0xffc00000 /* PE out. size:32-bit words */
85523+
85524+#define SAFE_PE_RINGCFG_SIZE 0x000003ff /* ring size (descriptors) */
85525+#define SAFE_PE_RINGCFG_OFFSET 0xffff0000 /* offset btw desc's (dwords) */
85526+#define SAFE_PE_RINGCFG_OFFSET_S 16
85527+
85528+#define SAFE_PE_RINGPOLL_POLL 0x00000fff /* polling frequency/divisor */
85529+#define SAFE_PE_RINGPOLL_RETRY 0x03ff0000 /* polling frequency/divisor */
85530+#define SAFE_PE_RINGPOLL_CONT 0x80000000 /* continuously poll */
85531+
85532+#define SAFE_PE_IRNGSTAT_CQAVAIL 0x00000001 /* command queue available */
85533+
85534+#define SAFE_PE_ERNGSTAT_NEXT 0x03ff0000 /* index of next packet desc. */
85535+#define SAFE_PE_ERNGSTAT_NEXT_S 16
85536+
85537+#define SAFE_PE_IOTHRESH_INPUT 0x000003ff /* input threshold (dwords) */
85538+#define SAFE_PE_IOTHRESH_OUTPUT 0x03ff0000 /* output threshold (dwords) */
85539+
85540+#define SAFE_PE_PARTCFG_SIZE 0x0000ffff /* scatter particle size */
85541+#define SAFE_PE_PARTCFG_GBURST 0x00030000 /* gather particle burst */
85542+#define SAFE_PE_PARTCFG_GBURST_2 0x00000000
85543+#define SAFE_PE_PARTCFG_GBURST_4 0x00010000
85544+#define SAFE_PE_PARTCFG_GBURST_8 0x00020000
85545+#define SAFE_PE_PARTCFG_GBURST_16 0x00030000
85546+#define SAFE_PE_PARTCFG_SBURST 0x000c0000 /* scatter particle burst */
85547+#define SAFE_PE_PARTCFG_SBURST_2 0x00000000
85548+#define SAFE_PE_PARTCFG_SBURST_4 0x00040000
85549+#define SAFE_PE_PARTCFG_SBURST_8 0x00080000
85550+#define SAFE_PE_PARTCFG_SBURST_16 0x000c0000
85551+
85552+#define SAFE_PE_PARTSIZE_SCAT 0xffff0000 /* scatter particle ring size */
85553+#define SAFE_PE_PARTSIZE_GATH 0x0000ffff /* gather particle ring size */
85554+
85555+#define SAFE_CRYPTO_CTRL_3DES 0x00000001 /* enable 3DES support */
85556+#define SAFE_CRYPTO_CTRL_PKEY 0x00010000 /* enable public key support */
85557+#define SAFE_CRYPTO_CTRL_RNG 0x00020000 /* enable RNG support */
85558+
85559+#define SAFE_DEVINFO_REV_MIN 0x0000000f /* minor rev for chip */
85560+#define SAFE_DEVINFO_REV_MAJ 0x000000f0 /* major rev for chip */
85561+#define SAFE_DEVINFO_REV_MAJ_S 4
85562+#define SAFE_DEVINFO_DES 0x00000100 /* DES/3DES support present */
85563+#define SAFE_DEVINFO_ARC4 0x00000200 /* ARC4 support present */
85564+#define SAFE_DEVINFO_AES 0x00000400 /* AES support present */
85565+#define SAFE_DEVINFO_MD5 0x00001000 /* MD5 support present */
85566+#define SAFE_DEVINFO_SHA1 0x00002000 /* SHA-1 support present */
85567+#define SAFE_DEVINFO_RIPEMD 0x00004000 /* RIPEMD support present */
85568+#define SAFE_DEVINFO_DEFLATE 0x00010000 /* Deflate support present */
85569+#define SAFE_DEVINFO_SARAM 0x00100000 /* on-chip SA RAM present */
85570+#define SAFE_DEVINFO_EMIBUS 0x00200000 /* EMI bus present */
85571+#define SAFE_DEVINFO_PKEY 0x00400000 /* public key support present */
85572+#define SAFE_DEVINFO_RNG 0x00800000 /* RNG present */
85573+
85574+#define SAFE_REV(_maj, _min) (((_maj) << SAFE_DEVINFO_REV_MAJ_S) | (_min))
85575+#define SAFE_REV_MAJ(_chiprev) \
85576+ (((_chiprev) & SAFE_DEVINFO_REV_MAJ) >> SAFE_DEVINFO_REV_MAJ_S)
85577+#define SAFE_REV_MIN(_chiprev) ((_chiprev) & SAFE_DEVINFO_REV_MIN)
85578+
85579+#define SAFE_PK_FUNC_MULT 0x00000001 /* Multiply function */
85580+#define SAFE_PK_FUNC_SQUARE 0x00000004 /* Square function */
85581+#define SAFE_PK_FUNC_ADD 0x00000010 /* Add function */
85582+#define SAFE_PK_FUNC_SUB 0x00000020 /* Subtract function */
85583+#define SAFE_PK_FUNC_LSHIFT 0x00000040 /* Left-shift function */
85584+#define SAFE_PK_FUNC_RSHIFT 0x00000080 /* Right-shift function */
85585+#define SAFE_PK_FUNC_DIV 0x00000100 /* Divide function */
85586+#define SAFE_PK_FUNC_CMP 0x00000400 /* Compare function */
85587+#define SAFE_PK_FUNC_COPY 0x00000800 /* Copy function */
85588+#define SAFE_PK_FUNC_EXP16 0x00002000 /* Exponentiate (4-bit ACT) */
85589+#define SAFE_PK_FUNC_EXP4 0x00004000 /* Exponentiate (2-bit ACT) */
85590+#define SAFE_PK_FUNC_RUN 0x00008000 /* start/status */
85591+
85592+#define SAFE_RNG_STAT_BUSY 0x00000001 /* busy, data not valid */
85593+
85594+#define SAFE_RNG_CTRL_PRE_LFSR 0x00000001 /* enable output pre-LFSR */
85595+#define SAFE_RNG_CTRL_TST_MODE 0x00000002 /* enable test mode */
85596+#define SAFE_RNG_CTRL_TST_RUN 0x00000004 /* start test state machine */
85597+#define SAFE_RNG_CTRL_ENA_RING1 0x00000008 /* test entropy oscillator #1 */
85598+#define SAFE_RNG_CTRL_ENA_RING2 0x00000010 /* test entropy oscillator #2 */
85599+#define SAFE_RNG_CTRL_DIS_ALARM 0x00000020 /* disable RNG alarm reports */
85600+#define SAFE_RNG_CTRL_TST_CLOCK 0x00000040 /* enable test clock */
85601+#define SAFE_RNG_CTRL_SHORTEN 0x00000080 /* shorten state timers */
85602+#define SAFE_RNG_CTRL_TST_ALARM 0x00000100 /* simulate alarm state */
85603+#define SAFE_RNG_CTRL_RST_LFSR 0x00000200 /* reset LFSR */
85604+
85605+/*
85606+ * Packet engine descriptor. Note that d_csr is a copy of the
85607+ * SAFE_PE_CSR register and all definitions apply, and d_len
85608+ * is a copy of the SAFE_PE_LEN register and all definitions apply.
85609+ * d_src and d_len may point directly to contiguous data or to a
85610+ * list of ``particle descriptors'' when using scatter/gather i/o.
85611+ */
85612+struct safe_desc {
85613+ u_int32_t d_csr; /* per-packet control/status */
85614+ u_int32_t d_src; /* source address */
85615+ u_int32_t d_dst; /* destination address */
85616+ u_int32_t d_sa; /* SA address */
85617+ u_int32_t d_len; /* length, bypass, status */
85618+};
85619+
85620+/*
85621+ * Scatter/Gather particle descriptor.
85622+ *
85623+ * NB: scatter descriptors do not specify a size; this is fixed
85624+ * by the setting of the SAFE_PE_PARTCFG register.
85625+ */
85626+struct safe_pdesc {
85627+ u_int32_t pd_addr; /* particle address */
85628+#ifdef __BIG_ENDIAN
85629+ u_int16_t pd_flags; /* control word */
85630+ u_int16_t pd_size; /* particle size (bytes) */
85631+#else
85632+ u_int16_t pd_flags; /* control word */
85633+ u_int16_t pd_size; /* particle size (bytes) */
85634+#endif
85635+};
85636+
85637+#define SAFE_PD_READY 0x0001 /* ready for processing */
85638+#define SAFE_PD_DONE 0x0002 /* h/w completed processing */
85639+
85640+/*
85641+ * Security Association (SA) Record (Rev 1). One of these is
85642+ * required for each operation processed by the packet engine.
85643+ */
85644+struct safe_sarec {
85645+ u_int32_t sa_cmd0;
85646+ u_int32_t sa_cmd1;
85647+ u_int32_t sa_resv0;
85648+ u_int32_t sa_resv1;
85649+ u_int32_t sa_key[8]; /* DES/3DES/AES key */
85650+ u_int32_t sa_indigest[5]; /* inner digest */
85651+ u_int32_t sa_outdigest[5]; /* outer digest */
85652+ u_int32_t sa_spi; /* SPI */
85653+ u_int32_t sa_seqnum; /* sequence number */
85654+ u_int32_t sa_seqmask[2]; /* sequence number mask */
85655+ u_int32_t sa_resv2;
85656+ u_int32_t sa_staterec; /* address of state record */
85657+ u_int32_t sa_resv3[2];
85658+ u_int32_t sa_samgmt0; /* SA management field 0 */
85659+ u_int32_t sa_samgmt1; /* SA management field 0 */
85660+};
85661+
85662+#define SAFE_SA_CMD0_OP 0x00000007 /* operation code */
85663+#define SAFE_SA_CMD0_OP_CRYPT 0x00000000 /* encrypt/decrypt (basic) */
85664+#define SAFE_SA_CMD0_OP_BOTH 0x00000001 /* encrypt-hash/hash-decrypto */
85665+#define SAFE_SA_CMD0_OP_HASH 0x00000003 /* hash (outbound-only) */
85666+#define SAFE_SA_CMD0_OP_ESP 0x00000000 /* ESP in/out (proto) */
85667+#define SAFE_SA_CMD0_OP_AH 0x00000001 /* AH in/out (proto) */
85668+#define SAFE_SA_CMD0_INBOUND 0x00000008 /* inbound operation */
85669+#define SAFE_SA_CMD0_OUTBOUND 0x00000000 /* outbound operation */
85670+#define SAFE_SA_CMD0_GROUP 0x00000030 /* operation group */
85671+#define SAFE_SA_CMD0_BASIC 0x00000000 /* basic operation */
85672+#define SAFE_SA_CMD0_PROTO 0x00000010 /* protocol/packet operation */
85673+#define SAFE_SA_CMD0_BUNDLE 0x00000020 /* bundled operation (resvd) */
85674+#define SAFE_SA_CMD0_PAD 0x000000c0 /* crypto pad method */
85675+#define SAFE_SA_CMD0_PAD_IPSEC 0x00000000 /* IPsec padding */
85676+#define SAFE_SA_CMD0_PAD_PKCS7 0x00000040 /* PKCS#7 padding */
85677+#define SAFE_SA_CMD0_PAD_CONS 0x00000080 /* constant padding */
85678+#define SAFE_SA_CMD0_PAD_ZERO 0x000000c0 /* zero padding */
85679+#define SAFE_SA_CMD0_CRYPT_ALG 0x00000f00 /* symmetric crypto algorithm */
85680+#define SAFE_SA_CMD0_DES 0x00000000 /* DES crypto algorithm */
85681+#define SAFE_SA_CMD0_3DES 0x00000100 /* 3DES crypto algorithm */
85682+#define SAFE_SA_CMD0_AES 0x00000300 /* AES crypto algorithm */
85683+#define SAFE_SA_CMD0_CRYPT_NULL 0x00000f00 /* null crypto algorithm */
85684+#define SAFE_SA_CMD0_HASH_ALG 0x0000f000 /* hash algorithm */
85685+#define SAFE_SA_CMD0_MD5 0x00000000 /* MD5 hash algorithm */
85686+#define SAFE_SA_CMD0_SHA1 0x00001000 /* SHA-1 hash algorithm */
85687+#define SAFE_SA_CMD0_HASH_NULL 0x0000f000 /* null hash algorithm */
85688+#define SAFE_SA_CMD0_HDR_PROC 0x00080000 /* header processing */
85689+#define SAFE_SA_CMD0_IBUSID 0x00300000 /* input bus id */
85690+#define SAFE_SA_CMD0_IPCI 0x00100000 /* PCI input bus id */
85691+#define SAFE_SA_CMD0_OBUSID 0x00c00000 /* output bus id */
85692+#define SAFE_SA_CMD0_OPCI 0x00400000 /* PCI output bus id */
85693+#define SAFE_SA_CMD0_IVLD 0x03000000 /* IV loading */
85694+#define SAFE_SA_CMD0_IVLD_NONE 0x00000000 /* IV no load (reuse) */
85695+#define SAFE_SA_CMD0_IVLD_IBUF 0x01000000 /* IV load from input buffer */
85696+#define SAFE_SA_CMD0_IVLD_STATE 0x02000000 /* IV load from state */
85697+#define SAFE_SA_CMD0_HSLD 0x0c000000 /* hash state loading */
85698+#define SAFE_SA_CMD0_HSLD_SA 0x00000000 /* hash state load from SA */
85699+#define SAFE_SA_CMD0_HSLD_STATE 0x08000000 /* hash state load from state */
85700+#define SAFE_SA_CMD0_HSLD_NONE 0x0c000000 /* hash state no load */
85701+#define SAFE_SA_CMD0_SAVEIV 0x10000000 /* save IV */
85702+#define SAFE_SA_CMD0_SAVEHASH 0x20000000 /* save hash state */
85703+#define SAFE_SA_CMD0_IGATHER 0x40000000 /* input gather */
85704+#define SAFE_SA_CMD0_OSCATTER 0x80000000 /* output scatter */
85705+
85706+#define SAFE_SA_CMD1_HDRCOPY 0x00000002 /* copy header to output */
85707+#define SAFE_SA_CMD1_PAYCOPY 0x00000004 /* copy payload to output */
85708+#define SAFE_SA_CMD1_PADCOPY 0x00000008 /* copy pad to output */
85709+#define SAFE_SA_CMD1_IPV4 0x00000000 /* IPv4 protocol */
85710+#define SAFE_SA_CMD1_IPV6 0x00000010 /* IPv6 protocol */
85711+#define SAFE_SA_CMD1_MUTABLE 0x00000020 /* mutable bit processing */
85712+#define SAFE_SA_CMD1_SRBUSID 0x000000c0 /* state record bus id */
85713+#define SAFE_SA_CMD1_SRPCI 0x00000040 /* state record from PCI */
85714+#define SAFE_SA_CMD1_CRMODE 0x00000300 /* crypto mode */
85715+#define SAFE_SA_CMD1_ECB 0x00000000 /* ECB crypto mode */
85716+#define SAFE_SA_CMD1_CBC 0x00000100 /* CBC crypto mode */
85717+#define SAFE_SA_CMD1_OFB 0x00000200 /* OFB crypto mode */
85718+#define SAFE_SA_CMD1_CFB 0x00000300 /* CFB crypto mode */
85719+#define SAFE_SA_CMD1_CRFEEDBACK 0x00000c00 /* crypto feedback mode */
85720+#define SAFE_SA_CMD1_64BIT 0x00000000 /* 64-bit crypto feedback */
85721+#define SAFE_SA_CMD1_8BIT 0x00000400 /* 8-bit crypto feedback */
85722+#define SAFE_SA_CMD1_1BIT 0x00000800 /* 1-bit crypto feedback */
85723+#define SAFE_SA_CMD1_128BIT 0x00000c00 /* 128-bit crypto feedback */
85724+#define SAFE_SA_CMD1_OPTIONS 0x00001000 /* HMAC/options mutable bit */
85725+#define SAFE_SA_CMD1_HMAC SAFE_SA_CMD1_OPTIONS
85726+#define SAFE_SA_CMD1_SAREV1 0x00008000 /* SA Revision 1 */
85727+#define SAFE_SA_CMD1_OFFSET 0x00ff0000 /* hash/crypto offset(dwords) */
85728+#define SAFE_SA_CMD1_OFFSET_S 16
85729+#define SAFE_SA_CMD1_AESKEYLEN 0x0f000000 /* AES key length */
85730+#define SAFE_SA_CMD1_AES128 0x02000000 /* 128-bit AES key */
85731+#define SAFE_SA_CMD1_AES192 0x03000000 /* 192-bit AES key */
85732+#define SAFE_SA_CMD1_AES256 0x04000000 /* 256-bit AES key */
85733+
85734+/*
85735+ * Security Associate State Record (Rev 1).
85736+ */
85737+struct safe_sastate {
85738+ u_int32_t sa_saved_iv[4]; /* saved IV (DES/3DES/AES) */
85739+ u_int32_t sa_saved_hashbc; /* saved hash byte count */
85740+ u_int32_t sa_saved_indigest[5]; /* saved inner digest */
85741+};
85742+#endif /* _SAFE_SAFEREG_H_ */
85743diff --git a/crypto/ocf/safe/safevar.h b/crypto/ocf/safe/safevar.h
85744new file mode 100644
85745index 0000000..9039a5d
85746--- /dev/null
85747+++ b/crypto/ocf/safe/safevar.h
85748@@ -0,0 +1,230 @@
85749+/*-
85750+ * The linux port of this code done by David McCullough
85751+ * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
85752+ * The license and original author are listed below.
85753+ *
85754+ * Copyright (c) 2003 Sam Leffler, Errno Consulting
85755+ * Copyright (c) 2003 Global Technology Associates, Inc.
85756+ * All rights reserved.
85757+ *
85758+ * Redistribution and use in source and binary forms, with or without
85759+ * modification, are permitted provided that the following conditions
85760+ * are met:
85761+ * 1. Redistributions of source code must retain the above copyright
85762+ * notice, this list of conditions and the following disclaimer.
85763+ * 2. Redistributions in binary form must reproduce the above copyright
85764+ * notice, this list of conditions and the following disclaimer in the
85765+ * documentation and/or other materials provided with the distribution.
85766+ *
85767+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
85768+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
85769+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
85770+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
85771+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
85772+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
85773+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
85774+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
85775+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
85776+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85777+ * SUCH DAMAGE.
85778+ *
85779+ * $FreeBSD: src/sys/dev/safe/safevar.h,v 1.2 2006/05/17 18:34:26 pjd Exp $
85780+ */
85781+#ifndef _SAFE_SAFEVAR_H_
85782+#define _SAFE_SAFEVAR_H_
85783+
85784+/* Maximum queue length */
85785+#ifndef SAFE_MAX_NQUEUE
85786+#define SAFE_MAX_NQUEUE 60
85787+#endif
85788+
85789+#define SAFE_MAX_PART 64 /* Maximum scatter/gather depth */
85790+#define SAFE_DMA_BOUNDARY 0 /* No boundary for source DMA ops */
85791+#define SAFE_MAX_DSIZE 2048 /* MCLBYTES Fixed scatter particle size */
85792+#define SAFE_MAX_SSIZE 0x0ffff /* Maximum gather particle size */
85793+#define SAFE_MAX_DMA 0xfffff /* Maximum PE operand size (20 bits) */
85794+/* total src+dst particle descriptors */
85795+#define SAFE_TOTAL_DPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
85796+#define SAFE_TOTAL_SPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
85797+
85798+#define SAFE_RNG_MAXBUFSIZ 128 /* 32-bit words */
85799+
85800+#define SAFE_CARD(sid) (((sid) & 0xf0000000) >> 28)
85801+#define SAFE_SESSION(sid) ( (sid) & 0x0fffffff)
85802+#define SAFE_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
85803+
85804+#define SAFE_DEF_RTY 0xff /* PCI Retry Timeout */
85805+#define SAFE_DEF_TOUT 0xff /* PCI TRDY Timeout */
85806+#define SAFE_DEF_CACHELINE 0x01 /* Cache Line setting */
85807+
85808+#ifdef __KERNEL__
85809+/*
85810+ * State associated with the allocation of each chunk
85811+ * of memory setup for DMA.
85812+ */
85813+struct safe_dma_alloc {
85814+ dma_addr_t dma_paddr;
85815+ void *dma_vaddr;
85816+};
85817+
85818+/*
85819+ * Cryptographic operand state. One of these exists for each
85820+ * source and destination operand passed in from the crypto
85821+ * subsystem. When possible source and destination operands
85822+ * refer to the same memory. More often they are distinct.
85823+ * We track the virtual address of each operand as well as
85824+ * where each is mapped for DMA.
85825+ */
85826+struct safe_operand {
85827+ union {
85828+ struct sk_buff *skb;
85829+ struct uio *io;
85830+ } u;
85831+ void *map;
85832+ int mapsize; /* total number of bytes in segs */
85833+ struct {
85834+ dma_addr_t ds_addr;
85835+ int ds_len;
85836+ int ds_tlen;
85837+ } segs[SAFE_MAX_PART];
85838+ int nsegs;
85839+};
85840+
85841+/*
85842+ * Packet engine ring entry and cryptographic operation state.
85843+ * The packet engine requires a ring of descriptors that contain
85844+ * pointers to various cryptographic state. However the ring
85845+ * configuration register allows you to specify an arbitrary size
85846+ * for ring entries. We use this feature to collect most of the
85847+ * state for each cryptographic request into one spot. Other than
85848+ * ring entries only the ``particle descriptors'' (scatter/gather
85849+ * lists) and the actual operand data are kept separate. The
85850+ * particle descriptors must also be organized in rings. The
85851+ * operand data can be located aribtrarily (modulo alignment constraints).
85852+ *
85853+ * Note that the descriptor ring is mapped onto the PCI bus so
85854+ * the hardware can DMA data. This means the entire ring must be
85855+ * contiguous.
85856+ */
85857+struct safe_ringentry {
85858+ struct safe_desc re_desc; /* command descriptor */
85859+ struct safe_sarec re_sa; /* SA record */
85860+ struct safe_sastate re_sastate; /* SA state record */
85861+
85862+ struct cryptop *re_crp; /* crypto operation */
85863+
85864+ struct safe_operand re_src; /* source operand */
85865+ struct safe_operand re_dst; /* destination operand */
85866+
85867+ int re_sesn; /* crypto session ID */
85868+ int re_flags;
85869+#define SAFE_QFLAGS_COPYOUTIV 0x1 /* copy back on completion */
85870+#define SAFE_QFLAGS_COPYOUTICV 0x2 /* copy back on completion */
85871+};
85872+
85873+#define re_src_skb re_src.u.skb
85874+#define re_src_io re_src.u.io
85875+#define re_src_map re_src.map
85876+#define re_src_nsegs re_src.nsegs
85877+#define re_src_segs re_src.segs
85878+#define re_src_mapsize re_src.mapsize
85879+
85880+#define re_dst_skb re_dst.u.skb
85881+#define re_dst_io re_dst.u.io
85882+#define re_dst_map re_dst.map
85883+#define re_dst_nsegs re_dst.nsegs
85884+#define re_dst_segs re_dst.segs
85885+#define re_dst_mapsize re_dst.mapsize
85886+
85887+struct rndstate_test;
85888+
85889+struct safe_session {
85890+ u_int32_t ses_used;
85891+ u_int32_t ses_klen; /* key length in bits */
85892+ u_int32_t ses_key[8]; /* DES/3DES/AES key */
85893+ u_int32_t ses_mlen; /* hmac length in bytes */
85894+ u_int32_t ses_hminner[5]; /* hmac inner state */
85895+ u_int32_t ses_hmouter[5]; /* hmac outer state */
85896+ u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
85897+};
85898+
85899+struct safe_pkq {
85900+ struct list_head pkq_list;
85901+ struct cryptkop *pkq_krp;
85902+};
85903+
85904+struct safe_softc {
85905+ softc_device_decl sc_dev;
85906+ u32 sc_irq;
85907+
85908+ struct pci_dev *sc_pcidev;
85909+ ocf_iomem_t sc_base_addr;
85910+
85911+ u_int sc_chiprev; /* major/minor chip revision */
85912+ int sc_flags; /* device specific flags */
85913+#define SAFE_FLAGS_KEY 0x01 /* has key accelerator */
85914+#define SAFE_FLAGS_RNG 0x02 /* hardware rng */
85915+ int sc_suspended;
85916+ int sc_needwakeup; /* notify crypto layer */
85917+ int32_t sc_cid; /* crypto tag */
85918+
85919+ struct safe_dma_alloc sc_ringalloc; /* PE ring allocation state */
85920+ struct safe_ringentry *sc_ring; /* PE ring */
85921+ struct safe_ringentry *sc_ringtop; /* PE ring top */
85922+ struct safe_ringentry *sc_front; /* next free entry */
85923+ struct safe_ringentry *sc_back; /* next pending entry */
85924+ int sc_nqchip; /* # passed to chip */
85925+ spinlock_t sc_ringmtx; /* PE ring lock */
85926+ struct safe_pdesc *sc_spring; /* src particle ring */
85927+ struct safe_pdesc *sc_springtop; /* src particle ring top */
85928+ struct safe_pdesc *sc_spfree; /* next free src particle */
85929+ struct safe_dma_alloc sc_spalloc; /* src particle ring state */
85930+ struct safe_pdesc *sc_dpring; /* dest particle ring */
85931+ struct safe_pdesc *sc_dpringtop; /* dest particle ring top */
85932+ struct safe_pdesc *sc_dpfree; /* next free dest particle */
85933+ struct safe_dma_alloc sc_dpalloc; /* dst particle ring state */
85934+ int sc_nsessions; /* # of sessions */
85935+ struct safe_session *sc_sessions; /* sessions */
85936+
85937+ struct timer_list sc_pkto; /* PK polling */
85938+ spinlock_t sc_pkmtx; /* PK lock */
85939+ struct list_head sc_pkq; /* queue of PK requests */
85940+ struct safe_pkq *sc_pkq_cur; /* current processing request */
85941+ u_int32_t sc_pk_reslen, sc_pk_resoff;
85942+
85943+ int sc_max_dsize; /* maximum safe DMA size */
85944+};
85945+#endif /* __KERNEL__ */
85946+
85947+struct safe_stats {
85948+ u_int64_t st_ibytes;
85949+ u_int64_t st_obytes;
85950+ u_int32_t st_ipackets;
85951+ u_int32_t st_opackets;
85952+ u_int32_t st_invalid; /* invalid argument */
85953+ u_int32_t st_badsession; /* invalid session id */
85954+ u_int32_t st_badflags; /* flags indicate !(mbuf | uio) */
85955+ u_int32_t st_nodesc; /* op submitted w/o descriptors */
85956+ u_int32_t st_badalg; /* unsupported algorithm */
85957+ u_int32_t st_ringfull; /* PE descriptor ring full */
85958+ u_int32_t st_peoperr; /* PE marked error */
85959+ u_int32_t st_dmaerr; /* PE DMA error */
85960+ u_int32_t st_bypasstoobig; /* bypass > 96 bytes */
85961+ u_int32_t st_skipmismatch; /* enc part begins before auth part */
85962+ u_int32_t st_lenmismatch; /* enc length different auth length */
85963+ u_int32_t st_coffmisaligned; /* crypto offset not 32-bit aligned */
85964+ u_int32_t st_cofftoobig; /* crypto offset > 255 words */
85965+ u_int32_t st_iovmisaligned; /* iov op not aligned */
85966+ u_int32_t st_iovnotuniform; /* iov op not suitable */
85967+ u_int32_t st_unaligned; /* unaligned src caused copy */
85968+ u_int32_t st_notuniform; /* non-uniform src caused copy */
85969+ u_int32_t st_nomap; /* bus_dmamap_create failed */
85970+ u_int32_t st_noload; /* bus_dmamap_load_* failed */
85971+ u_int32_t st_nombuf; /* MGET* failed */
85972+ u_int32_t st_nomcl; /* MCLGET* failed */
85973+ u_int32_t st_maxqchip; /* max mcr1 ops out for processing */
85974+ u_int32_t st_rng; /* RNG requests */
85975+ u_int32_t st_rngalarm; /* RNG alarm requests */
85976+ u_int32_t st_noicvcopy; /* ICV data copies suppressed */
85977+};
85978+#endif /* _SAFE_SAFEVAR_H_ */
85979diff --git a/crypto/ocf/safe/sha1.c b/crypto/ocf/safe/sha1.c
85980new file mode 100644
85981index 0000000..4e360e2
85982--- /dev/null
85983+++ b/crypto/ocf/safe/sha1.c
85984@@ -0,0 +1,279 @@
85985+/* $KAME: sha1.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
85986+/*
85987+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
85988+ * All rights reserved.
85989+ *
85990+ * Redistribution and use in source and binary forms, with or without
85991+ * modification, are permitted provided that the following conditions
85992+ * are met:
85993+ * 1. Redistributions of source code must retain the above copyright
85994+ * notice, this list of conditions and the following disclaimer.
85995+ * 2. Redistributions in binary form must reproduce the above copyright
85996+ * notice, this list of conditions and the following disclaimer in the
85997+ * documentation and/or other materials provided with the distribution.
85998+ * 3. Neither the name of the project nor the names of its contributors
85999+ * may be used to endorse or promote products derived from this software
86000+ * without specific prior written permission.
86001+ *
86002+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
86003+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
86004+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
86005+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
86006+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
86007+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
86008+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
86009+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
86010+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
86011+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
86012+ * SUCH DAMAGE.
86013+ */
86014+
86015+/*
86016+ * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
86017+ * based on: http://csrc.nist.gov/fips/fip180-1.txt
86018+ * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
86019+ */
86020+
86021+#if 0
86022+#include <sys/cdefs.h>
86023+__FBSDID("$FreeBSD: src/sys/crypto/sha1.c,v 1.9 2003/06/10 21:36:57 obrien Exp $");
86024+
86025+#include <sys/types.h>
86026+#include <sys/cdefs.h>
86027+#include <sys/time.h>
86028+#include <sys/systm.h>
86029+
86030+#include <crypto/sha1.h>
86031+#endif
86032+
86033+/* sanity check */
86034+#if BYTE_ORDER != BIG_ENDIAN
86035+# if BYTE_ORDER != LITTLE_ENDIAN
86036+# define unsupported 1
86037+# endif
86038+#endif
86039+
86040+#ifndef unsupported
86041+
86042+/* constant table */
86043+static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
86044+#define K(t) _K[(t) / 20]
86045+
86046+#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
86047+#define F1(b, c, d) (((b) ^ (c)) ^ (d))
86048+#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
86049+#define F3(b, c, d) (((b) ^ (c)) ^ (d))
86050+
86051+#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
86052+
86053+#undef H
86054+#define H(n) (ctxt->h.b32[(n)])
86055+#define COUNT (ctxt->count)
86056+#define BCOUNT (ctxt->c.b64[0] / 8)
86057+#define W(n) (ctxt->m.b32[(n)])
86058+
86059+#define PUTBYTE(x) { \
86060+ ctxt->m.b8[(COUNT % 64)] = (x); \
86061+ COUNT++; \
86062+ COUNT %= 64; \
86063+ ctxt->c.b64[0] += 8; \
86064+ if (COUNT % 64 == 0) \
86065+ sha1_step(ctxt); \
86066+ }
86067+
86068+#define PUTPAD(x) { \
86069+ ctxt->m.b8[(COUNT % 64)] = (x); \
86070+ COUNT++; \
86071+ COUNT %= 64; \
86072+ if (COUNT % 64 == 0) \
86073+ sha1_step(ctxt); \
86074+ }
86075+
86076+static void sha1_step(struct sha1_ctxt *);
86077+
86078+static void
86079+sha1_step(ctxt)
86080+ struct sha1_ctxt *ctxt;
86081+{
86082+ u_int32_t a, b, c, d, e;
86083+ size_t t, s;
86084+ u_int32_t tmp;
86085+
86086+#if BYTE_ORDER == LITTLE_ENDIAN
86087+ struct sha1_ctxt tctxt;
86088+ bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);
86089+ ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
86090+ ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
86091+ ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
86092+ ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
86093+ ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
86094+ ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
86095+ ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
86096+ ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
86097+ ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
86098+ ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
86099+ ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
86100+ ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
86101+ ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
86102+ ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
86103+ ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
86104+ ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
86105+ ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
86106+ ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
86107+ ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
86108+ ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
86109+ ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
86110+ ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
86111+ ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
86112+ ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
86113+ ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
86114+ ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
86115+ ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
86116+ ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
86117+ ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
86118+ ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
86119+ ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
86120+ ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
86121+#endif
86122+
86123+ a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
86124+
86125+ for (t = 0; t < 20; t++) {
86126+ s = t & 0x0f;
86127+ if (t >= 16) {
86128+ W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
86129+ }
86130+ tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
86131+ e = d; d = c; c = S(30, b); b = a; a = tmp;
86132+ }
86133+ for (t = 20; t < 40; t++) {
86134+ s = t & 0x0f;
86135+ W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
86136+ tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
86137+ e = d; d = c; c = S(30, b); b = a; a = tmp;
86138+ }
86139+ for (t = 40; t < 60; t++) {
86140+ s = t & 0x0f;
86141+ W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
86142+ tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
86143+ e = d; d = c; c = S(30, b); b = a; a = tmp;
86144+ }
86145+ for (t = 60; t < 80; t++) {
86146+ s = t & 0x0f;
86147+ W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
86148+ tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
86149+ e = d; d = c; c = S(30, b); b = a; a = tmp;
86150+ }
86151+
86152+ H(0) = H(0) + a;
86153+ H(1) = H(1) + b;
86154+ H(2) = H(2) + c;
86155+ H(3) = H(3) + d;
86156+ H(4) = H(4) + e;
86157+
86158+ bzero(&ctxt->m.b8[0], 64);
86159+}
86160+
86161+/*------------------------------------------------------------*/
86162+
86163+void
86164+sha1_init(ctxt)
86165+ struct sha1_ctxt *ctxt;
86166+{
86167+ bzero(ctxt, sizeof(struct sha1_ctxt));
86168+ H(0) = 0x67452301;
86169+ H(1) = 0xefcdab89;
86170+ H(2) = 0x98badcfe;
86171+ H(3) = 0x10325476;
86172+ H(4) = 0xc3d2e1f0;
86173+}
86174+
86175+void
86176+sha1_pad(ctxt)
86177+ struct sha1_ctxt *ctxt;
86178+{
86179+ size_t padlen; /*pad length in bytes*/
86180+ size_t padstart;
86181+
86182+ PUTPAD(0x80);
86183+
86184+ padstart = COUNT % 64;
86185+ padlen = 64 - padstart;
86186+ if (padlen < 8) {
86187+ bzero(&ctxt->m.b8[padstart], padlen);
86188+ COUNT += padlen;
86189+ COUNT %= 64;
86190+ sha1_step(ctxt);
86191+ padstart = COUNT % 64; /* should be 0 */
86192+ padlen = 64 - padstart; /* should be 64 */
86193+ }
86194+ bzero(&ctxt->m.b8[padstart], padlen - 8);
86195+ COUNT += (padlen - 8);
86196+ COUNT %= 64;
86197+#if BYTE_ORDER == BIG_ENDIAN
86198+ PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
86199+ PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
86200+ PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
86201+ PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
86202+#else
86203+ PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
86204+ PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
86205+ PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
86206+ PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
86207+#endif
86208+}
86209+
86210+void
86211+sha1_loop(ctxt, input, len)
86212+ struct sha1_ctxt *ctxt;
86213+ const u_int8_t *input;
86214+ size_t len;
86215+{
86216+ size_t gaplen;
86217+ size_t gapstart;
86218+ size_t off;
86219+ size_t copysiz;
86220+
86221+ off = 0;
86222+
86223+ while (off < len) {
86224+ gapstart = COUNT % 64;
86225+ gaplen = 64 - gapstart;
86226+
86227+ copysiz = (gaplen < len - off) ? gaplen : len - off;
86228+ bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz);
86229+ COUNT += copysiz;
86230+ COUNT %= 64;
86231+ ctxt->c.b64[0] += copysiz * 8;
86232+ if (COUNT % 64 == 0)
86233+ sha1_step(ctxt);
86234+ off += copysiz;
86235+ }
86236+}
86237+
86238+void
86239+sha1_result(ctxt, digest0)
86240+ struct sha1_ctxt *ctxt;
86241+ caddr_t digest0;
86242+{
86243+ u_int8_t *digest;
86244+
86245+ digest = (u_int8_t *)digest0;
86246+ sha1_pad(ctxt);
86247+#if BYTE_ORDER == BIG_ENDIAN
86248+ bcopy(&ctxt->h.b8[0], digest, 20);
86249+#else
86250+ digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
86251+ digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
86252+ digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
86253+ digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
86254+ digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
86255+ digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
86256+ digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
86257+ digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
86258+ digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
86259+ digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
86260+#endif
86261+}
86262+
86263+#endif /*unsupported*/
86264diff --git a/crypto/ocf/safe/sha1.h b/crypto/ocf/safe/sha1.h
86265new file mode 100644
86266index 0000000..0e19d90
86267--- /dev/null
86268+++ b/crypto/ocf/safe/sha1.h
86269@@ -0,0 +1,72 @@
86270+/* $FreeBSD: src/sys/crypto/sha1.h,v 1.8 2002/03/20 05:13:50 alfred Exp $ */
86271+/* $KAME: sha1.h,v 1.5 2000/03/27 04:36:23 sumikawa Exp $ */
86272+
86273+/*
86274+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
86275+ * All rights reserved.
86276+ *
86277+ * Redistribution and use in source and binary forms, with or without
86278+ * modification, are permitted provided that the following conditions
86279+ * are met:
86280+ * 1. Redistributions of source code must retain the above copyright
86281+ * notice, this list of conditions and the following disclaimer.
86282+ * 2. Redistributions in binary form must reproduce the above copyright
86283+ * notice, this list of conditions and the following disclaimer in the
86284+ * documentation and/or other materials provided with the distribution.
86285+ * 3. Neither the name of the project nor the names of its contributors
86286+ * may be used to endorse or promote products derived from this software
86287+ * without specific prior written permission.
86288+ *
86289+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
86290+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
86291+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
86292+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
86293+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
86294+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
86295+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
86296+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
86297+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
86298+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
86299+ * SUCH DAMAGE.
86300+ */
86301+/*
86302+ * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
86303+ * based on: http://csrc.nist.gov/fips/fip180-1.txt
86304+ * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
86305+ */
86306+
86307+#ifndef _NETINET6_SHA1_H_
86308+#define _NETINET6_SHA1_H_
86309+
86310+struct sha1_ctxt {
86311+ union {
86312+ u_int8_t b8[20];
86313+ u_int32_t b32[5];
86314+ } h;
86315+ union {
86316+ u_int8_t b8[8];
86317+ u_int64_t b64[1];
86318+ } c;
86319+ union {
86320+ u_int8_t b8[64];
86321+ u_int32_t b32[16];
86322+ } m;
86323+ u_int8_t count;
86324+};
86325+
86326+#ifdef __KERNEL__
86327+extern void sha1_init(struct sha1_ctxt *);
86328+extern void sha1_pad(struct sha1_ctxt *);
86329+extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);
86330+extern void sha1_result(struct sha1_ctxt *, caddr_t);
86331+
86332+/* compatibilty with other SHA1 source codes */
86333+typedef struct sha1_ctxt SHA1_CTX;
86334+#define SHA1Init(x) sha1_init((x))
86335+#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
86336+#define SHA1Final(x, y) sha1_result((y), (x))
86337+#endif /* __KERNEL__ */
86338+
86339+#define SHA1_RESULTLEN (160/8)
86340+
86341+#endif /*_NETINET6_SHA1_H_*/
86342diff --git a/crypto/ocf/talitos/Makefile b/crypto/ocf/talitos/Makefile
86343new file mode 100644
86344index 0000000..2591b8a
86345--- /dev/null
86346+++ b/crypto/ocf/talitos/Makefile
86347@@ -0,0 +1,12 @@
86348+# for SGlinux builds
86349+-include $(ROOTDIR)/modules/.config
86350+
86351+obj-$(CONFIG_OCF_TALITOS) += talitos.o
86352+
86353+obj ?= .
86354+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
86355+
86356+ifdef TOPDIR
86357+-include $(TOPDIR)/Rules.make
86358+endif
86359+
86360diff --git a/crypto/ocf/talitos/talitos.c b/crypto/ocf/talitos/talitos.c
86361new file mode 100644
86362index 0000000..0cef3bd
86363--- /dev/null
86364+++ b/crypto/ocf/talitos/talitos.c
86365@@ -0,0 +1,1359 @@
86366+/*
86367+ * crypto/ocf/talitos/talitos.c
86368+ *
86369+ * An OCF-Linux module that uses Freescale's SEC to do the crypto.
86370+ * Based on crypto/ocf/hifn and crypto/ocf/safe OCF drivers
86371+ *
86372+ * Copyright (c) 2006 Freescale Semiconductor, Inc.
86373+ *
86374+ * This code written by Kim A. B. Phillips <kim.phillips@freescale.com>
86375+ * some code copied from files with the following:
86376+ * Copyright (C) 2004-2007 David McCullough <david_mccullough@mcafee.com>
86377+ *
86378+ * Redistribution and use in source and binary forms, with or without
86379+ * modification, are permitted provided that the following conditions
86380+ * are met:
86381+ *
86382+ * 1. Redistributions of source code must retain the above copyright
86383+ * notice, this list of conditions and the following disclaimer.
86384+ * 2. Redistributions in binary form must reproduce the above copyright
86385+ * notice, this list of conditions and the following disclaimer in the
86386+ * documentation and/or other materials provided with the distribution.
86387+ * 3. The name of the author may not be used to endorse or promote products
86388+ * derived from this software without specific prior written permission.
86389+ *
86390+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
86391+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
86392+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
86393+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
86394+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
86395+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
86396+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
86397+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
86398+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
86399+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
86400+ *
86401+ * ---------------------------------------------------------------------------
86402+ *
86403+ * NOTES:
86404+ *
86405+ * The Freescale SEC (also known as 'talitos') resides on the
86406+ * internal bus, and runs asynchronous to the processor core. It has
86407+ * a wide gamut of cryptographic acceleration features, including single-
86408+ * pass IPsec (also known as algorithm chaining). To properly utilize
86409+ * all of the SEC's performance enhancing features, further reworking
86410+ * of higher level code (framework, applications) will be necessary.
86411+ *
86412+ * The following table shows which SEC version is present in which devices:
86413+ *
86414+ * Devices SEC version
86415+ *
86416+ * 8272, 8248 SEC 1.0
86417+ * 885, 875 SEC 1.2
86418+ * 8555E, 8541E SEC 2.0
86419+ * 8349E SEC 2.01
86420+ * 8548E SEC 2.1
86421+ *
86422+ * The following table shows the features offered by each SEC version:
86423+ *
86424+ * Max. chan-
86425+ * version Bus I/F Clock nels DEU AESU AFEU MDEU PKEU RNG KEU
86426+ *
86427+ * SEC 1.0 internal 64b 100MHz 4 1 1 1 1 1 1 0
86428+ * SEC 1.2 internal 32b 66MHz 1 1 1 0 1 0 0 0
86429+ * SEC 2.0 internal 64b 166MHz 4 1 1 1 1 1 1 0
86430+ * SEC 2.01 internal 64b 166MHz 4 1 1 1 1 1 1 0
86431+ * SEC 2.1 internal 64b 333MHz 4 1 1 1 1 1 1 1
86432+ *
86433+ * Each execution unit in the SEC has two modes of execution; channel and
86434+ * slave/debug. This driver employs the channel infrastructure in the
86435+ * device for convenience. Only the RNG is directly accessed due to the
86436+ * convenience of its random fifo pool. The relationship between the
86437+ * channels and execution units is depicted in the following diagram:
86438+ *
86439+ * ------- ------------
86440+ * ---| ch0 |---| |
86441+ * ------- | |
86442+ * | |------+-------+-------+-------+------------
86443+ * ------- | | | | | | |
86444+ * ---| ch1 |---| | | | | | |
86445+ * ------- | | ------ ------ ------ ------ ------
86446+ * |controller| |DEU | |AESU| |MDEU| |PKEU| ... |RNG |
86447+ * ------- | | ------ ------ ------ ------ ------
86448+ * ---| ch2 |---| | | | | | |
86449+ * ------- | | | | | | |
86450+ * | |------+-------+-------+-------+------------
86451+ * ------- | |
86452+ * ---| ch3 |---| |
86453+ * ------- ------------
86454+ *
86455+ * Channel ch0 may drive an aes operation to the aes unit (AESU),
86456+ * and, at the same time, ch1 may drive a message digest operation
86457+ * to the mdeu. Each channel has an input descriptor FIFO, and the
86458+ * FIFO can contain, e.g. on the 8541E, up to 24 entries, before a
86459+ * a buffer overrun error is triggered. The controller is responsible
86460+ * for fetching the data from descriptor pointers, and passing the
86461+ * data to the appropriate EUs. The controller also writes the
86462+ * cryptographic operation's result to memory. The SEC notifies
86463+ * completion by triggering an interrupt and/or setting the 1st byte
86464+ * of the hdr field to 0xff.
86465+ *
86466+ * TODO:
86467+ * o support more algorithms
86468+ * o support more versions of the SEC
86469+ * o add support for linux 2.4
86470+ * o scatter-gather (sg) support
86471+ * o add support for public key ops (PKEU)
86472+ * o add statistics
86473+ */
86474+
86475+#ifndef AUTOCONF_INCLUDED
86476+#include <linux/config.h>
86477+#endif
86478+#include <linux/module.h>
86479+#include <linux/init.h>
86480+#include <linux/interrupt.h>
86481+#include <linux/spinlock.h>
86482+#include <linux/random.h>
86483+#include <linux/skbuff.h>
86484+#include <asm/scatterlist.h>
86485+#include <linux/dma-mapping.h> /* dma_map_single() */
86486+#include <linux/moduleparam.h>
86487+
86488+#include <linux/version.h>
86489+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
86490+#include <linux/platform_device.h>
86491+#endif
86492+
86493+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
86494+#include <linux/of_platform.h>
86495+#endif
86496+
86497+#include <cryptodev.h>
86498+#include <uio.h>
86499+
86500+#define DRV_NAME "talitos"
86501+
86502+#include "talitos_dev.h"
86503+#include "talitos_soft.h"
86504+
86505+#define read_random(p,l) get_random_bytes(p,l)
86506+
86507+const char talitos_driver_name[] = "Talitos OCF";
86508+const char talitos_driver_version[] = "0.2";
86509+
86510+static int talitos_newsession(device_t dev, u_int32_t *sidp,
86511+ struct cryptoini *cri);
86512+static int talitos_freesession(device_t dev, u_int64_t tid);
86513+static int talitos_process(device_t dev, struct cryptop *crp, int hint);
86514+static void dump_talitos_status(struct talitos_softc *sc);
86515+static int talitos_submit(struct talitos_softc *sc, struct talitos_desc *td,
86516+ int chsel);
86517+static void talitos_doneprocessing(struct talitos_softc *sc);
86518+static void talitos_init_device(struct talitos_softc *sc);
86519+static void talitos_reset_device_master(struct talitos_softc *sc);
86520+static void talitos_reset_device(struct talitos_softc *sc);
86521+static void talitos_errorprocessing(struct talitos_softc *sc);
86522+#ifdef CONFIG_PPC_MERGE
86523+static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match);
86524+static int talitos_remove(struct of_device *ofdev);
86525+#else
86526+static int talitos_probe(struct platform_device *pdev);
86527+static int talitos_remove(struct platform_device *pdev);
86528+#endif
86529+#ifdef CONFIG_OCF_RANDOMHARVEST
86530+static int talitos_read_random(void *arg, u_int32_t *buf, int maxwords);
86531+static void talitos_rng_init(struct talitos_softc *sc);
86532+#endif
86533+
86534+static device_method_t talitos_methods = {
86535+ /* crypto device methods */
86536+ DEVMETHOD(cryptodev_newsession, talitos_newsession),
86537+ DEVMETHOD(cryptodev_freesession,talitos_freesession),
86538+ DEVMETHOD(cryptodev_process, talitos_process),
86539+};
86540+
86541+#define debug talitos_debug
86542+int talitos_debug = 0;
86543+module_param(talitos_debug, int, 0644);
86544+MODULE_PARM_DESC(talitos_debug, "Enable debug");
86545+
86546+static inline void talitos_write(volatile unsigned *addr, u32 val)
86547+{
86548+ out_be32(addr, val);
86549+}
86550+
86551+static inline u32 talitos_read(volatile unsigned *addr)
86552+{
86553+ u32 val;
86554+ val = in_be32(addr);
86555+ return val;
86556+}
86557+
86558+static void dump_talitos_status(struct talitos_softc *sc)
86559+{
86560+ unsigned int v, v_hi, i, *ptr;
86561+ v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
86562+ v_hi = talitos_read(sc->sc_base_addr + TALITOS_MCR_HI);
86563+ printk(KERN_INFO "%s: MCR 0x%08x_%08x\n",
86564+ device_get_nameunit(sc->sc_cdev), v, v_hi);
86565+ v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
86566+ v_hi = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
86567+ printk(KERN_INFO "%s: IMR 0x%08x_%08x\n",
86568+ device_get_nameunit(sc->sc_cdev), v, v_hi);
86569+ v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
86570+ v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
86571+ printk(KERN_INFO "%s: ISR 0x%08x_%08x\n",
86572+ device_get_nameunit(sc->sc_cdev), v, v_hi);
86573+ for (i = 0; i < sc->sc_num_channels; i++) {
86574+ v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
86575+ TALITOS_CH_CDPR);
86576+ v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
86577+ TALITOS_CH_CDPR_HI);
86578+ printk(KERN_INFO "%s: CDPR ch%d 0x%08x_%08x\n",
86579+ device_get_nameunit(sc->sc_cdev), i, v, v_hi);
86580+ }
86581+ for (i = 0; i < sc->sc_num_channels; i++) {
86582+ v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
86583+ TALITOS_CH_CCPSR);
86584+ v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
86585+ TALITOS_CH_CCPSR_HI);
86586+ printk(KERN_INFO "%s: CCPSR ch%d 0x%08x_%08x\n",
86587+ device_get_nameunit(sc->sc_cdev), i, v, v_hi);
86588+ }
86589+ ptr = sc->sc_base_addr + TALITOS_CH_DESCBUF;
86590+ for (i = 0; i < 16; i++) {
86591+ v = talitos_read(ptr++); v_hi = talitos_read(ptr++);
86592+ printk(KERN_INFO "%s: DESCBUF ch0 0x%08x_%08x (tdp%02d)\n",
86593+ device_get_nameunit(sc->sc_cdev), v, v_hi, i);
86594+ }
86595+ return;
86596+}
86597+
86598+
86599+#ifdef CONFIG_OCF_RANDOMHARVEST
86600+/*
86601+ * pull random numbers off the RNG FIFO, not exceeding amount available
86602+ */
86603+static int
86604+talitos_read_random(void *arg, u_int32_t *buf, int maxwords)
86605+{
86606+ struct talitos_softc *sc = (struct talitos_softc *) arg;
86607+ int rc;
86608+ u_int32_t v;
86609+
86610+ DPRINTF("%s()\n", __FUNCTION__);
86611+
86612+ /* check for things like FIFO underflow */
86613+ v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
86614+ if (unlikely(v)) {
86615+ printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
86616+ device_get_nameunit(sc->sc_cdev), v);
86617+ return 0;
86618+ }
86619+ /*
86620+ * OFL is number of available 64-bit words,
86621+ * shift and convert to a 32-bit word count
86622+ */
86623+ v = talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI);
86624+ v = (v & TALITOS_RNGSR_HI_OFL) >> (16 - 1);
86625+ if (maxwords > v)
86626+ maxwords = v;
86627+ for (rc = 0; rc < maxwords; rc++) {
86628+ buf[rc] = talitos_read(sc->sc_base_addr +
86629+ TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
86630+ }
86631+ if (maxwords & 1) {
86632+ /*
86633+ * RNG will complain with an AE in the RNGISR
86634+ * if we don't complete the pairs of 32-bit reads
86635+ * to its 64-bit register based FIFO
86636+ */
86637+ v = talitos_read(sc->sc_base_addr +
86638+ TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
86639+ }
86640+
86641+ return rc;
86642+}
86643+
86644+static void
86645+talitos_rng_init(struct talitos_softc *sc)
86646+{
86647+ u_int32_t v;
86648+
86649+ DPRINTF("%s()\n", __FUNCTION__);
86650+ /* reset RNG EU */
86651+ v = talitos_read(sc->sc_base_addr + TALITOS_RNGRCR_HI);
86652+ v |= TALITOS_RNGRCR_HI_SR;
86653+ talitos_write(sc->sc_base_addr + TALITOS_RNGRCR_HI, v);
86654+ while ((talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI)
86655+ & TALITOS_RNGSR_HI_RD) == 0)
86656+ cpu_relax();
86657+ /*
86658+ * we tell the RNG to start filling the RNG FIFO
86659+ * by writing the RNGDSR
86660+ */
86661+ v = talitos_read(sc->sc_base_addr + TALITOS_RNGDSR_HI);
86662+ talitos_write(sc->sc_base_addr + TALITOS_RNGDSR_HI, v);
86663+ /*
86664+ * 64 bits of data will be pushed onto the FIFO every
86665+ * 256 SEC cycles until the FIFO is full. The RNG then
86666+ * attempts to keep the FIFO full.
86667+ */
86668+ v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
86669+ if (v) {
86670+ printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
86671+ device_get_nameunit(sc->sc_cdev), v);
86672+ return;
86673+ }
86674+ /*
86675+ * n.b. we need to add a FIPS test here - if the RNG is going
86676+ * to fail, it's going to fail at reset time
86677+ */
86678+ return;
86679+}
86680+#endif /* CONFIG_OCF_RANDOMHARVEST */
86681+
86682+/*
86683+ * Generate a new software session.
86684+ */
86685+static int
86686+talitos_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
86687+{
86688+ struct cryptoini *c, *encini = NULL, *macini = NULL;
86689+ struct talitos_softc *sc = device_get_softc(dev);
86690+ struct talitos_session *ses = NULL;
86691+ int sesn;
86692+
86693+ DPRINTF("%s()\n", __FUNCTION__);
86694+ if (sidp == NULL || cri == NULL || sc == NULL) {
86695+ DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
86696+ return EINVAL;
86697+ }
86698+ for (c = cri; c != NULL; c = c->cri_next) {
86699+ if (c->cri_alg == CRYPTO_MD5 ||
86700+ c->cri_alg == CRYPTO_MD5_HMAC ||
86701+ c->cri_alg == CRYPTO_SHA1 ||
86702+ c->cri_alg == CRYPTO_SHA1_HMAC ||
86703+ c->cri_alg == CRYPTO_NULL_HMAC) {
86704+ if (macini)
86705+ return EINVAL;
86706+ macini = c;
86707+ } else if (c->cri_alg == CRYPTO_DES_CBC ||
86708+ c->cri_alg == CRYPTO_3DES_CBC ||
86709+ c->cri_alg == CRYPTO_AES_CBC ||
86710+ c->cri_alg == CRYPTO_NULL_CBC) {
86711+ if (encini)
86712+ return EINVAL;
86713+ encini = c;
86714+ } else {
86715+ DPRINTF("UNKNOWN c->cri_alg %d\n", encini->cri_alg);
86716+ return EINVAL;
86717+ }
86718+ }
86719+ if (encini == NULL && macini == NULL)
86720+ return EINVAL;
86721+ if (encini) {
86722+ /* validate key length */
86723+ switch (encini->cri_alg) {
86724+ case CRYPTO_DES_CBC:
86725+ if (encini->cri_klen != 64)
86726+ return EINVAL;
86727+ break;
86728+ case CRYPTO_3DES_CBC:
86729+ if (encini->cri_klen != 192) {
86730+ return EINVAL;
86731+ }
86732+ break;
86733+ case CRYPTO_AES_CBC:
86734+ if (encini->cri_klen != 128 &&
86735+ encini->cri_klen != 192 &&
86736+ encini->cri_klen != 256)
86737+ return EINVAL;
86738+ break;
86739+ default:
86740+ DPRINTF("UNKNOWN encini->cri_alg %d\n",
86741+ encini->cri_alg);
86742+ return EINVAL;
86743+ }
86744+ }
86745+
86746+ if (sc->sc_sessions == NULL) {
86747+ ses = sc->sc_sessions = (struct talitos_session *)
86748+ kmalloc(sizeof(struct talitos_session), SLAB_ATOMIC);
86749+ if (ses == NULL)
86750+ return ENOMEM;
86751+ memset(ses, 0, sizeof(struct talitos_session));
86752+ sesn = 0;
86753+ sc->sc_nsessions = 1;
86754+ } else {
86755+ for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
86756+ if (sc->sc_sessions[sesn].ses_used == 0) {
86757+ ses = &sc->sc_sessions[sesn];
86758+ break;
86759+ }
86760+ }
86761+
86762+ if (ses == NULL) {
86763+ /* allocating session */
86764+ sesn = sc->sc_nsessions;
86765+ ses = (struct talitos_session *) kmalloc(
86766+ (sesn + 1) * sizeof(struct talitos_session),
86767+ SLAB_ATOMIC);
86768+ if (ses == NULL)
86769+ return ENOMEM;
86770+ memset(ses, 0,
86771+ (sesn + 1) * sizeof(struct talitos_session));
86772+ memcpy(ses, sc->sc_sessions,
86773+ sesn * sizeof(struct talitos_session));
86774+ memset(sc->sc_sessions, 0,
86775+ sesn * sizeof(struct talitos_session));
86776+ kfree(sc->sc_sessions);
86777+ sc->sc_sessions = ses;
86778+ ses = &sc->sc_sessions[sesn];
86779+ sc->sc_nsessions++;
86780+ }
86781+ }
86782+
86783+ ses->ses_used = 1;
86784+
86785+ if (encini) {
86786+ /* get an IV */
86787+ /* XXX may read fewer than requested */
86788+ read_random(ses->ses_iv, sizeof(ses->ses_iv));
86789+
86790+ ses->ses_klen = (encini->cri_klen + 7) / 8;
86791+ memcpy(ses->ses_key, encini->cri_key, ses->ses_klen);
86792+ if (macini) {
86793+ /* doing hash on top of cipher */
86794+ ses->ses_hmac_len = (macini->cri_klen + 7) / 8;
86795+ memcpy(ses->ses_hmac, macini->cri_key,
86796+ ses->ses_hmac_len);
86797+ }
86798+ } else if (macini) {
86799+ /* doing hash */
86800+ ses->ses_klen = (macini->cri_klen + 7) / 8;
86801+ memcpy(ses->ses_key, macini->cri_key, ses->ses_klen);
86802+ }
86803+
86804+ /* back compat way of determining MSC result len */
86805+ if (macini) {
86806+ ses->ses_mlen = macini->cri_mlen;
86807+ if (ses->ses_mlen == 0) {
86808+ if (macini->cri_alg == CRYPTO_MD5_HMAC)
86809+ ses->ses_mlen = MD5_HASH_LEN;
86810+ else
86811+ ses->ses_mlen = SHA1_HASH_LEN;
86812+ }
86813+ }
86814+
86815+ /* really should make up a template td here,
86816+ * and only fill things like i/o and direction in process() */
86817+
86818+ /* assign session ID */
86819+ *sidp = TALITOS_SID(sc->sc_num, sesn);
86820+ return 0;
86821+}
86822+
86823+/*
86824+ * Deallocate a session.
86825+ */
86826+static int
86827+talitos_freesession(device_t dev, u_int64_t tid)
86828+{
86829+ struct talitos_softc *sc = device_get_softc(dev);
86830+ int session, ret;
86831+ u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
86832+
86833+ if (sc == NULL)
86834+ return EINVAL;
86835+ session = TALITOS_SESSION(sid);
86836+ if (session < sc->sc_nsessions) {
86837+ memset(&sc->sc_sessions[session], 0,
86838+ sizeof(sc->sc_sessions[session]));
86839+ ret = 0;
86840+ } else
86841+ ret = EINVAL;
86842+ return ret;
86843+}
86844+
86845+/*
86846+ * launch device processing - it will come back with done notification
86847+ * in the form of an interrupt and/or HDR_DONE_BITS in header
86848+ */
86849+static int
86850+talitos_submit(
86851+ struct talitos_softc *sc,
86852+ struct talitos_desc *td,
86853+ int chsel)
86854+{
86855+ u_int32_t v;
86856+
86857+ v = dma_map_single(NULL, td, sizeof(*td), DMA_TO_DEVICE);
86858+ talitos_write(sc->sc_base_addr +
86859+ chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF, 0);
86860+ talitos_write(sc->sc_base_addr +
86861+ chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF_HI, v);
86862+ return 0;
86863+}
86864+
86865+static int
86866+talitos_process(device_t dev, struct cryptop *crp, int hint)
86867+{
86868+ int i, err = 0, ivsize;
86869+ struct talitos_softc *sc = device_get_softc(dev);
86870+ struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
86871+ caddr_t iv;
86872+ struct talitos_session *ses;
86873+ struct talitos_desc *td;
86874+ unsigned long flags;
86875+ /* descriptor mappings */
86876+ int hmac_key, hmac_data, cipher_iv, cipher_key,
86877+ in_fifo, out_fifo, cipher_iv_out;
86878+ static int chsel = -1;
86879+
86880+ DPRINTF("%s()\n", __FUNCTION__);
86881+
86882+ if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
86883+ return EINVAL;
86884+ }
86885+ crp->crp_etype = 0;
86886+ if (TALITOS_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
86887+ return EINVAL;
86888+ }
86889+
86890+ ses = &sc->sc_sessions[TALITOS_SESSION(crp->crp_sid)];
86891+
86892+ /* enter the channel scheduler */
86893+ spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
86894+
86895+ /* reuse channel that already had/has requests for the required EU */
86896+ for (i = 0; i < sc->sc_num_channels; i++) {
86897+ if (sc->sc_chnlastalg[i] == crp->crp_desc->crd_alg)
86898+ break;
86899+ }
86900+ if (i == sc->sc_num_channels) {
86901+ /*
86902+ * haven't seen this algo the last sc_num_channels or more
86903+ * use round robin in this case
86904+ * nb: sc->sc_num_channels must be power of 2
86905+ */
86906+ chsel = (chsel + 1) & (sc->sc_num_channels - 1);
86907+ } else {
86908+ /*
86909+ * matches channel with same target execution unit;
86910+ * use same channel in this case
86911+ */
86912+ chsel = i;
86913+ }
86914+ sc->sc_chnlastalg[chsel] = crp->crp_desc->crd_alg;
86915+
86916+ /* release the channel scheduler lock */
86917+ spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
86918+
86919+ /* acquire the selected channel fifo lock */
86920+ spin_lock_irqsave(&sc->sc_chnfifolock[chsel], flags);
86921+
86922+ /* find and reserve next available descriptor-cryptop pair */
86923+ for (i = 0; i < sc->sc_chfifo_len; i++) {
86924+ if (sc->sc_chnfifo[chsel][i].cf_desc.hdr == 0) {
86925+ /*
86926+ * ensure correct descriptor formation by
86927+ * avoiding inadvertently setting "optional" entries
86928+ * e.g. not using "optional" dptr2 for MD/HMAC descs
86929+ */
86930+ memset(&sc->sc_chnfifo[chsel][i].cf_desc,
86931+ 0, sizeof(*td));
86932+ /* reserve it with done notification request bit */
86933+ sc->sc_chnfifo[chsel][i].cf_desc.hdr |=
86934+ TALITOS_DONE_NOTIFY;
86935+ break;
86936+ }
86937+ }
86938+ spin_unlock_irqrestore(&sc->sc_chnfifolock[chsel], flags);
86939+
86940+ if (i == sc->sc_chfifo_len) {
86941+ /* fifo full */
86942+ err = ERESTART;
86943+ goto errout;
86944+ }
86945+
86946+ td = &sc->sc_chnfifo[chsel][i].cf_desc;
86947+ sc->sc_chnfifo[chsel][i].cf_crp = crp;
86948+
86949+ crd1 = crp->crp_desc;
86950+ if (crd1 == NULL) {
86951+ err = EINVAL;
86952+ goto errout;
86953+ }
86954+ crd2 = crd1->crd_next;
86955+ /* prevent compiler warning */
86956+ hmac_key = 0;
86957+ hmac_data = 0;
86958+ if (crd2 == NULL) {
86959+ td->hdr |= TD_TYPE_COMMON_NONSNOOP_NO_AFEU;
86960+ /* assign descriptor dword ptr mappings for this desc. type */
86961+ cipher_iv = 1;
86962+ cipher_key = 2;
86963+ in_fifo = 3;
86964+ cipher_iv_out = 5;
86965+ if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
86966+ crd1->crd_alg == CRYPTO_SHA1_HMAC ||
86967+ crd1->crd_alg == CRYPTO_SHA1 ||
86968+ crd1->crd_alg == CRYPTO_MD5) {
86969+ out_fifo = 5;
86970+ maccrd = crd1;
86971+ enccrd = NULL;
86972+ } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
86973+ crd1->crd_alg == CRYPTO_3DES_CBC ||
86974+ crd1->crd_alg == CRYPTO_AES_CBC ||
86975+ crd1->crd_alg == CRYPTO_ARC4) {
86976+ out_fifo = 4;
86977+ maccrd = NULL;
86978+ enccrd = crd1;
86979+ } else {
86980+ DPRINTF("UNKNOWN crd1->crd_alg %d\n", crd1->crd_alg);
86981+ err = EINVAL;
86982+ goto errout;
86983+ }
86984+ } else {
86985+ if (sc->sc_desc_types & TALITOS_HAS_DT_IPSEC_ESP) {
86986+ td->hdr |= TD_TYPE_IPSEC_ESP;
86987+ } else {
86988+ DPRINTF("unimplemented: multiple descriptor ipsec\n");
86989+ err = EINVAL;
86990+ goto errout;
86991+ }
86992+ /* assign descriptor dword ptr mappings for this desc. type */
86993+ hmac_key = 0;
86994+ hmac_data = 1;
86995+ cipher_iv = 2;
86996+ cipher_key = 3;
86997+ in_fifo = 4;
86998+ out_fifo = 5;
86999+ cipher_iv_out = 6;
87000+ if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
87001+ crd1->crd_alg == CRYPTO_SHA1_HMAC ||
87002+ crd1->crd_alg == CRYPTO_MD5 ||
87003+ crd1->crd_alg == CRYPTO_SHA1) &&
87004+ (crd2->crd_alg == CRYPTO_DES_CBC ||
87005+ crd2->crd_alg == CRYPTO_3DES_CBC ||
87006+ crd2->crd_alg == CRYPTO_AES_CBC ||
87007+ crd2->crd_alg == CRYPTO_ARC4) &&
87008+ ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
87009+ maccrd = crd1;
87010+ enccrd = crd2;
87011+ } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
87012+ crd1->crd_alg == CRYPTO_ARC4 ||
87013+ crd1->crd_alg == CRYPTO_3DES_CBC ||
87014+ crd1->crd_alg == CRYPTO_AES_CBC) &&
87015+ (crd2->crd_alg == CRYPTO_MD5_HMAC ||
87016+ crd2->crd_alg == CRYPTO_SHA1_HMAC ||
87017+ crd2->crd_alg == CRYPTO_MD5 ||
87018+ crd2->crd_alg == CRYPTO_SHA1) &&
87019+ (crd1->crd_flags & CRD_F_ENCRYPT)) {
87020+ enccrd = crd1;
87021+ maccrd = crd2;
87022+ } else {
87023+ /* We cannot order the SEC as requested */
87024+ printk("%s: cannot do the order\n",
87025+ device_get_nameunit(sc->sc_cdev));
87026+ err = EINVAL;
87027+ goto errout;
87028+ }
87029+ }
87030+ /* assign in_fifo and out_fifo based on input/output struct type */
87031+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
87032+ /* using SKB buffers */
87033+ struct sk_buff *skb = (struct sk_buff *)crp->crp_buf;
87034+ if (skb_shinfo(skb)->nr_frags) {
87035+ printk("%s: skb frags unimplemented\n",
87036+ device_get_nameunit(sc->sc_cdev));
87037+ err = EINVAL;
87038+ goto errout;
87039+ }
87040+ td->ptr[in_fifo].ptr = dma_map_single(NULL, skb->data,
87041+ skb->len, DMA_TO_DEVICE);
87042+ td->ptr[in_fifo].len = skb->len;
87043+ td->ptr[out_fifo].ptr = dma_map_single(NULL, skb->data,
87044+ skb->len, DMA_TO_DEVICE);
87045+ td->ptr[out_fifo].len = skb->len;
87046+ td->ptr[hmac_data].ptr = dma_map_single(NULL, skb->data,
87047+ skb->len, DMA_TO_DEVICE);
87048+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
87049+ /* using IOV buffers */
87050+ struct uio *uiop = (struct uio *)crp->crp_buf;
87051+ if (uiop->uio_iovcnt > 1) {
87052+ printk("%s: iov frags unimplemented\n",
87053+ device_get_nameunit(sc->sc_cdev));
87054+ err = EINVAL;
87055+ goto errout;
87056+ }
87057+ td->ptr[in_fifo].ptr = dma_map_single(NULL,
87058+ uiop->uio_iov->iov_base, crp->crp_ilen, DMA_TO_DEVICE);
87059+ td->ptr[in_fifo].len = crp->crp_ilen;
87060+ /* crp_olen is never set; always use crp_ilen */
87061+ td->ptr[out_fifo].ptr = dma_map_single(NULL,
87062+ uiop->uio_iov->iov_base,
87063+ crp->crp_ilen, DMA_TO_DEVICE);
87064+ td->ptr[out_fifo].len = crp->crp_ilen;
87065+ } else {
87066+ /* using contig buffers */
87067+ td->ptr[in_fifo].ptr = dma_map_single(NULL,
87068+ crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
87069+ td->ptr[in_fifo].len = crp->crp_ilen;
87070+ td->ptr[out_fifo].ptr = dma_map_single(NULL,
87071+ crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
87072+ td->ptr[out_fifo].len = crp->crp_ilen;
87073+ }
87074+ if (enccrd) {
87075+ switch (enccrd->crd_alg) {
87076+ case CRYPTO_3DES_CBC:
87077+ td->hdr |= TALITOS_MODE0_DEU_3DES;
87078+ /* FALLTHROUGH */
87079+ case CRYPTO_DES_CBC:
87080+ td->hdr |= TALITOS_SEL0_DEU
87081+ | TALITOS_MODE0_DEU_CBC;
87082+ if (enccrd->crd_flags & CRD_F_ENCRYPT)
87083+ td->hdr |= TALITOS_MODE0_DEU_ENC;
87084+ ivsize = 2*sizeof(u_int32_t);
87085+ DPRINTF("%cDES ses %d ch %d len %d\n",
87086+ (td->hdr & TALITOS_MODE0_DEU_3DES)?'3':'1',
87087+ (u32)TALITOS_SESSION(crp->crp_sid),
87088+ chsel, td->ptr[in_fifo].len);
87089+ break;
87090+ case CRYPTO_AES_CBC:
87091+ td->hdr |= TALITOS_SEL0_AESU
87092+ | TALITOS_MODE0_AESU_CBC;
87093+ if (enccrd->crd_flags & CRD_F_ENCRYPT)
87094+ td->hdr |= TALITOS_MODE0_AESU_ENC;
87095+ ivsize = 4*sizeof(u_int32_t);
87096+ DPRINTF("AES ses %d ch %d len %d\n",
87097+ (u32)TALITOS_SESSION(crp->crp_sid),
87098+ chsel, td->ptr[in_fifo].len);
87099+ break;
87100+ default:
87101+ printk("%s: unimplemented enccrd->crd_alg %d\n",
87102+ device_get_nameunit(sc->sc_cdev), enccrd->crd_alg);
87103+ err = EINVAL;
87104+ goto errout;
87105+ }
87106+ /*
87107+ * Setup encrypt/decrypt state. When using basic ops
87108+ * we can't use an inline IV because hash/crypt offset
87109+ * must be from the end of the IV to the start of the
87110+ * crypt data and this leaves out the preceding header
87111+ * from the hash calculation. Instead we place the IV
87112+ * in the state record and set the hash/crypt offset to
87113+ * copy both the header+IV.
87114+ */
87115+ if (enccrd->crd_flags & CRD_F_ENCRYPT) {
87116+ td->hdr |= TALITOS_DIR_OUTBOUND;
87117+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
87118+ iv = enccrd->crd_iv;
87119+ else
87120+ iv = (caddr_t) ses->ses_iv;
87121+ if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
87122+ crypto_copyback(crp->crp_flags, crp->crp_buf,
87123+ enccrd->crd_inject, ivsize, iv);
87124+ }
87125+ } else {
87126+ td->hdr |= TALITOS_DIR_INBOUND;
87127+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
87128+ iv = enccrd->crd_iv;
87129+ bcopy(enccrd->crd_iv, iv, ivsize);
87130+ } else {
87131+ iv = (caddr_t) ses->ses_iv;
87132+ crypto_copydata(crp->crp_flags, crp->crp_buf,
87133+ enccrd->crd_inject, ivsize, iv);
87134+ }
87135+ }
87136+ td->ptr[cipher_iv].ptr = dma_map_single(NULL, iv, ivsize,
87137+ DMA_TO_DEVICE);
87138+ td->ptr[cipher_iv].len = ivsize;
87139+ /*
87140+ * we don't need the cipher iv out length/pointer
87141+ * field to do ESP IPsec. Therefore we set the len field as 0,
87142+ * which tells the SEC not to do anything with this len/ptr
87143+ * field. Previously, when length/pointer as pointing to iv,
87144+ * it gave us corruption of packets.
87145+ */
87146+ td->ptr[cipher_iv_out].len = 0;
87147+ }
87148+ if (enccrd && maccrd) {
87149+ /* this is ipsec only for now */
87150+ td->hdr |= TALITOS_SEL1_MDEU
87151+ | TALITOS_MODE1_MDEU_INIT
87152+ | TALITOS_MODE1_MDEU_PAD;
87153+ switch (maccrd->crd_alg) {
87154+ case CRYPTO_MD5:
87155+ td->hdr |= TALITOS_MODE1_MDEU_MD5;
87156+ break;
87157+ case CRYPTO_MD5_HMAC:
87158+ td->hdr |= TALITOS_MODE1_MDEU_MD5_HMAC;
87159+ break;
87160+ case CRYPTO_SHA1:
87161+ td->hdr |= TALITOS_MODE1_MDEU_SHA1;
87162+ break;
87163+ case CRYPTO_SHA1_HMAC:
87164+ td->hdr |= TALITOS_MODE1_MDEU_SHA1_HMAC;
87165+ break;
87166+ default:
87167+ /* We cannot order the SEC as requested */
87168+ printk("%s: cannot do the order\n",
87169+ device_get_nameunit(sc->sc_cdev));
87170+ err = EINVAL;
87171+ goto errout;
87172+ }
87173+ if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
87174+ (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
87175+ /*
87176+ * The offset from hash data to the start of
87177+ * crypt data is the difference in the skips.
87178+ */
87179+ /* ipsec only for now */
87180+ td->ptr[hmac_key].ptr = dma_map_single(NULL,
87181+ ses->ses_hmac, ses->ses_hmac_len, DMA_TO_DEVICE);
87182+ td->ptr[hmac_key].len = ses->ses_hmac_len;
87183+ td->ptr[in_fifo].ptr += enccrd->crd_skip;
87184+ td->ptr[in_fifo].len = enccrd->crd_len;
87185+ td->ptr[out_fifo].ptr += enccrd->crd_skip;
87186+ td->ptr[out_fifo].len = enccrd->crd_len;
87187+ /* bytes of HMAC to postpend to ciphertext */
87188+ td->ptr[out_fifo].extent = ses->ses_mlen;
87189+ td->ptr[hmac_data].ptr += maccrd->crd_skip;
87190+ td->ptr[hmac_data].len = enccrd->crd_skip - maccrd->crd_skip;
87191+ }
87192+ if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
87193+ printk("%s: CRD_F_KEY_EXPLICIT unimplemented\n",
87194+ device_get_nameunit(sc->sc_cdev));
87195+ }
87196+ }
87197+ if (!enccrd && maccrd) {
87198+ /* single MD5 or SHA */
87199+ td->hdr |= TALITOS_SEL0_MDEU
87200+ | TALITOS_MODE0_MDEU_INIT
87201+ | TALITOS_MODE0_MDEU_PAD;
87202+ switch (maccrd->crd_alg) {
87203+ case CRYPTO_MD5:
87204+ td->hdr |= TALITOS_MODE0_MDEU_MD5;
87205+ DPRINTF("MD5 ses %d ch %d len %d\n",
87206+ (u32)TALITOS_SESSION(crp->crp_sid),
87207+ chsel, td->ptr[in_fifo].len);
87208+ break;
87209+ case CRYPTO_MD5_HMAC:
87210+ td->hdr |= TALITOS_MODE0_MDEU_MD5_HMAC;
87211+ break;
87212+ case CRYPTO_SHA1:
87213+ td->hdr |= TALITOS_MODE0_MDEU_SHA1;
87214+ DPRINTF("SHA1 ses %d ch %d len %d\n",
87215+ (u32)TALITOS_SESSION(crp->crp_sid),
87216+ chsel, td->ptr[in_fifo].len);
87217+ break;
87218+ case CRYPTO_SHA1_HMAC:
87219+ td->hdr |= TALITOS_MODE0_MDEU_SHA1_HMAC;
87220+ break;
87221+ default:
87222+ /* We cannot order the SEC as requested */
87223+ DPRINTF("cannot do the order\n");
87224+ err = EINVAL;
87225+ goto errout;
87226+ }
87227+
87228+ if (crp->crp_flags & CRYPTO_F_IOV)
87229+ td->ptr[out_fifo].ptr += maccrd->crd_inject;
87230+
87231+ if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
87232+ (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
87233+ td->ptr[hmac_key].ptr = dma_map_single(NULL,
87234+ ses->ses_hmac, ses->ses_hmac_len,
87235+ DMA_TO_DEVICE);
87236+ td->ptr[hmac_key].len = ses->ses_hmac_len;
87237+ }
87238+ }
87239+ else {
87240+ /* using process key (session data has duplicate) */
87241+ td->ptr[cipher_key].ptr = dma_map_single(NULL,
87242+ enccrd->crd_key, (enccrd->crd_klen + 7) / 8,
87243+ DMA_TO_DEVICE);
87244+ td->ptr[cipher_key].len = (enccrd->crd_klen + 7) / 8;
87245+ }
87246+ /* descriptor complete - GO! */
87247+ return talitos_submit(sc, td, chsel);
87248+
87249+errout:
87250+ if (err != ERESTART) {
87251+ crp->crp_etype = err;
87252+ crypto_done(crp);
87253+ }
87254+ return err;
87255+}
87256+
87257+/* go through all channels descriptors, notifying OCF what has
87258+ * _and_hasn't_ successfully completed and reset the device
87259+ * (otherwise it's up to decoding desc hdrs!)
87260+ */
87261+static void talitos_errorprocessing(struct talitos_softc *sc)
87262+{
87263+ unsigned long flags;
87264+ int i, j;
87265+
87266+ /* disable further scheduling until under control */
87267+ spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
87268+
87269+ if (debug) dump_talitos_status(sc);
87270+ /* go through descriptors, try and salvage those successfully done,
87271+ * and EIO those that weren't
87272+ */
87273+ for (i = 0; i < sc->sc_num_channels; i++) {
87274+ spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
87275+ for (j = 0; j < sc->sc_chfifo_len; j++) {
87276+ if (sc->sc_chnfifo[i][j].cf_desc.hdr) {
87277+ if ((sc->sc_chnfifo[i][j].cf_desc.hdr
87278+ & TALITOS_HDR_DONE_BITS)
87279+ != TALITOS_HDR_DONE_BITS) {
87280+ /* this one didn't finish */
87281+ /* signify in crp->etype */
87282+ sc->sc_chnfifo[i][j].cf_crp->crp_etype
87283+ = EIO;
87284+ }
87285+ } else
87286+ continue; /* free entry */
87287+ /* either way, notify ocf */
87288+ crypto_done(sc->sc_chnfifo[i][j].cf_crp);
87289+ /* and tag it available again
87290+ *
87291+ * memset to ensure correct descriptor formation by
87292+ * avoiding inadvertently setting "optional" entries
87293+ * e.g. not using "optional" dptr2 MD/HMAC processing
87294+ */
87295+ memset(&sc->sc_chnfifo[i][j].cf_desc,
87296+ 0, sizeof(struct talitos_desc));
87297+ }
87298+ spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
87299+ }
87300+ /* reset and initialize the SEC h/w device */
87301+ talitos_reset_device(sc);
87302+ talitos_init_device(sc);
87303+#ifdef CONFIG_OCF_RANDOMHARVEST
87304+ if (sc->sc_exec_units & TALITOS_HAS_EU_RNG)
87305+ talitos_rng_init(sc);
87306+#endif
87307+
87308+ /* Okay. Stand by. */
87309+ spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
87310+
87311+ return;
87312+}
87313+
87314+/* go through all channels descriptors, notifying OCF what's been done */
87315+static void talitos_doneprocessing(struct talitos_softc *sc)
87316+{
87317+ unsigned long flags;
87318+ int i, j;
87319+
87320+ /* go through descriptors looking for done bits */
87321+ for (i = 0; i < sc->sc_num_channels; i++) {
87322+ spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
87323+ for (j = 0; j < sc->sc_chfifo_len; j++) {
87324+ /* descriptor has done bits set? */
87325+ if ((sc->sc_chnfifo[i][j].cf_desc.hdr
87326+ & TALITOS_HDR_DONE_BITS)
87327+ == TALITOS_HDR_DONE_BITS) {
87328+ /* notify ocf */
87329+ crypto_done(sc->sc_chnfifo[i][j].cf_crp);
87330+ /* and tag it available again
87331+ *
87332+ * memset to ensure correct descriptor formation by
87333+ * avoiding inadvertently setting "optional" entries
87334+ * e.g. not using "optional" dptr2 MD/HMAC processing
87335+ */
87336+ memset(&sc->sc_chnfifo[i][j].cf_desc,
87337+ 0, sizeof(struct talitos_desc));
87338+ }
87339+ }
87340+ spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
87341+ }
87342+ return;
87343+}
87344+
87345+static irqreturn_t
87346+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
87347+talitos_intr(int irq, void *arg)
87348+#else
87349+talitos_intr(int irq, void *arg, struct pt_regs *regs)
87350+#endif
87351+{
87352+ struct talitos_softc *sc = arg;
87353+ u_int32_t v, v_hi;
87354+
87355+ /* ack */
87356+ v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
87357+ v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
87358+ talitos_write(sc->sc_base_addr + TALITOS_ICR, v);
87359+ talitos_write(sc->sc_base_addr + TALITOS_ICR_HI, v_hi);
87360+
87361+ if (unlikely(v & TALITOS_ISR_ERROR)) {
87362+ /* Okay, Houston, we've had a problem here. */
87363+ printk(KERN_DEBUG "%s: got error interrupt - ISR 0x%08x_%08x\n",
87364+ device_get_nameunit(sc->sc_cdev), v, v_hi);
87365+ talitos_errorprocessing(sc);
87366+ } else
87367+ if (likely(v & TALITOS_ISR_DONE)) {
87368+ talitos_doneprocessing(sc);
87369+ }
87370+ return IRQ_HANDLED;
87371+}
87372+
87373+/*
87374+ * Initialize registers we need to touch only once.
87375+ */
87376+static void
87377+talitos_init_device(struct talitos_softc *sc)
87378+{
87379+ u_int32_t v;
87380+ int i;
87381+
87382+ DPRINTF("%s()\n", __FUNCTION__);
87383+
87384+ /* init all channels */
87385+ for (i = 0; i < sc->sc_num_channels; i++) {
87386+ v = talitos_read(sc->sc_base_addr +
87387+ i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI);
87388+ v |= TALITOS_CH_CCCR_HI_CDWE
87389+ | TALITOS_CH_CCCR_HI_CDIE; /* invoke interrupt if done */
87390+ talitos_write(sc->sc_base_addr +
87391+ i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI, v);
87392+ }
87393+ /* enable all interrupts */
87394+ v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
87395+ v |= TALITOS_IMR_ALL;
87396+ talitos_write(sc->sc_base_addr + TALITOS_IMR, v);
87397+ v = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
87398+ v |= TALITOS_IMR_HI_ERRONLY;
87399+ talitos_write(sc->sc_base_addr + TALITOS_IMR_HI, v);
87400+ return;
87401+}
87402+
87403+/*
87404+ * set the master reset bit on the device.
87405+ */
87406+static void
87407+talitos_reset_device_master(struct talitos_softc *sc)
87408+{
87409+ u_int32_t v;
87410+
87411+ /* Reset the device by writing 1 to MCR:SWR and waiting 'til cleared */
87412+ v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
87413+ talitos_write(sc->sc_base_addr + TALITOS_MCR, v | TALITOS_MCR_SWR);
87414+
87415+ while (talitos_read(sc->sc_base_addr + TALITOS_MCR) & TALITOS_MCR_SWR)
87416+ cpu_relax();
87417+
87418+ return;
87419+}
87420+
87421+/*
87422+ * Resets the device. Values in the registers are left as is
87423+ * from the reset (i.e. initial values are assigned elsewhere).
87424+ */
87425+static void
87426+talitos_reset_device(struct talitos_softc *sc)
87427+{
87428+ u_int32_t v;
87429+ int i;
87430+
87431+ DPRINTF("%s()\n", __FUNCTION__);
87432+
87433+ /*
87434+ * Master reset
87435+ * errata documentation: warning: certain SEC interrupts
87436+ * are not fully cleared by writing the MCR:SWR bit,
87437+ * set bit twice to completely reset
87438+ */
87439+ talitos_reset_device_master(sc); /* once */
87440+ talitos_reset_device_master(sc); /* and once again */
87441+
87442+ /* reset all channels */
87443+ for (i = 0; i < sc->sc_num_channels; i++) {
87444+ v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
87445+ TALITOS_CH_CCCR);
87446+ talitos_write(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
87447+ TALITOS_CH_CCCR, v | TALITOS_CH_CCCR_RESET);
87448+ }
87449+}
87450+
87451+/* Set up the crypto device structure, private data,
87452+ * and anything else we need before we start */
87453+#ifdef CONFIG_PPC_MERGE
87454+static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match)
87455+#else
87456+static int talitos_probe(struct platform_device *pdev)
87457+#endif
87458+{
87459+ struct talitos_softc *sc = NULL;
87460+ struct resource *r;
87461+#ifdef CONFIG_PPC_MERGE
87462+ struct device *device = &ofdev->dev;
87463+ struct device_node *np = ofdev->node;
87464+ const unsigned int *prop;
87465+ int err;
87466+ struct resource res;
87467+#endif
87468+ static int num_chips = 0;
87469+ int rc;
87470+ int i;
87471+
87472+ DPRINTF("%s()\n", __FUNCTION__);
87473+
87474+ sc = (struct talitos_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
87475+ if (!sc)
87476+ return -ENOMEM;
87477+ memset(sc, 0, sizeof(*sc));
87478+
87479+ softc_device_init(sc, DRV_NAME, num_chips, talitos_methods);
87480+
87481+ sc->sc_irq = -1;
87482+ sc->sc_cid = -1;
87483+#ifndef CONFIG_PPC_MERGE
87484+ sc->sc_dev = pdev;
87485+#endif
87486+ sc->sc_num = num_chips++;
87487+
87488+#ifdef CONFIG_PPC_MERGE
87489+ dev_set_drvdata(device, sc);
87490+#else
87491+ platform_set_drvdata(sc->sc_dev, sc);
87492+#endif
87493+
87494+ /* get the irq line */
87495+#ifdef CONFIG_PPC_MERGE
87496+ err = of_address_to_resource(np, 0, &res);
87497+ if (err)
87498+ return -EINVAL;
87499+ r = &res;
87500+
87501+ sc->sc_irq = irq_of_parse_and_map(np, 0);
87502+#else
87503+ /* get a pointer to the register memory */
87504+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
87505+
87506+ sc->sc_irq = platform_get_irq(pdev, 0);
87507+#endif
87508+ rc = request_irq(sc->sc_irq, talitos_intr, 0,
87509+ device_get_nameunit(sc->sc_cdev), sc);
87510+ if (rc) {
87511+ printk(KERN_ERR "%s: failed to hook irq %d\n",
87512+ device_get_nameunit(sc->sc_cdev), sc->sc_irq);
87513+ sc->sc_irq = -1;
87514+ goto out;
87515+ }
87516+
87517+ sc->sc_base_addr = (ocf_iomem_t) ioremap(r->start, (r->end - r->start));
87518+ if (!sc->sc_base_addr) {
87519+ printk(KERN_ERR "%s: failed to ioremap\n",
87520+ device_get_nameunit(sc->sc_cdev));
87521+ goto out;
87522+ }
87523+
87524+ /* figure out our SEC's properties and capabilities */
87525+ sc->sc_chiprev = (u64)talitos_read(sc->sc_base_addr + TALITOS_ID) << 32
87526+ | talitos_read(sc->sc_base_addr + TALITOS_ID_HI);
87527+ DPRINTF("sec id 0x%llx\n", sc->sc_chiprev);
87528+
87529+#ifdef CONFIG_PPC_MERGE
87530+ /* get SEC properties from device tree, defaulting to SEC 2.0 */
87531+
87532+ prop = of_get_property(np, "num-channels", NULL);
87533+ sc->sc_num_channels = prop ? *prop : TALITOS_NCHANNELS_SEC_2_0;
87534+
87535+ prop = of_get_property(np, "channel-fifo-len", NULL);
87536+ sc->sc_chfifo_len = prop ? *prop : TALITOS_CHFIFOLEN_SEC_2_0;
87537+
87538+ prop = of_get_property(np, "exec-units-mask", NULL);
87539+ sc->sc_exec_units = prop ? *prop : TALITOS_HAS_EUS_SEC_2_0;
87540+
87541+ prop = of_get_property(np, "descriptor-types-mask", NULL);
87542+ sc->sc_desc_types = prop ? *prop : TALITOS_HAS_DESCTYPES_SEC_2_0;
87543+#else
87544+ /* bulk should go away with openfirmware flat device tree support */
87545+ if (sc->sc_chiprev & TALITOS_ID_SEC_2_0) {
87546+ sc->sc_num_channels = TALITOS_NCHANNELS_SEC_2_0;
87547+ sc->sc_chfifo_len = TALITOS_CHFIFOLEN_SEC_2_0;
87548+ sc->sc_exec_units = TALITOS_HAS_EUS_SEC_2_0;
87549+ sc->sc_desc_types = TALITOS_HAS_DESCTYPES_SEC_2_0;
87550+ } else {
87551+ printk(KERN_ERR "%s: failed to id device\n",
87552+ device_get_nameunit(sc->sc_cdev));
87553+ goto out;
87554+ }
87555+#endif
87556+
87557+ /* + 1 is for the meta-channel lock used by the channel scheduler */
87558+ sc->sc_chnfifolock = (spinlock_t *) kmalloc(
87559+ (sc->sc_num_channels + 1) * sizeof(spinlock_t), GFP_KERNEL);
87560+ if (!sc->sc_chnfifolock)
87561+ goto out;
87562+ for (i = 0; i < sc->sc_num_channels + 1; i++) {
87563+ spin_lock_init(&sc->sc_chnfifolock[i]);
87564+ }
87565+
87566+ sc->sc_chnlastalg = (int *) kmalloc(
87567+ sc->sc_num_channels * sizeof(int), GFP_KERNEL);
87568+ if (!sc->sc_chnlastalg)
87569+ goto out;
87570+ memset(sc->sc_chnlastalg, 0, sc->sc_num_channels * sizeof(int));
87571+
87572+ sc->sc_chnfifo = (struct desc_cryptop_pair **) kmalloc(
87573+ sc->sc_num_channels * sizeof(struct desc_cryptop_pair *),
87574+ GFP_KERNEL);
87575+ if (!sc->sc_chnfifo)
87576+ goto out;
87577+ for (i = 0; i < sc->sc_num_channels; i++) {
87578+ sc->sc_chnfifo[i] = (struct desc_cryptop_pair *) kmalloc(
87579+ sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair),
87580+ GFP_KERNEL);
87581+ if (!sc->sc_chnfifo[i])
87582+ goto out;
87583+ memset(sc->sc_chnfifo[i], 0,
87584+ sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair));
87585+ }
87586+
87587+ /* reset and initialize the SEC h/w device */
87588+ talitos_reset_device(sc);
87589+ talitos_init_device(sc);
87590+
87591+ sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
87592+ if (sc->sc_cid < 0) {
87593+ printk(KERN_ERR "%s: could not get crypto driver id\n",
87594+ device_get_nameunit(sc->sc_cdev));
87595+ goto out;
87596+ }
87597+
87598+ /* register algorithms with the framework */
87599+ printk("%s:", device_get_nameunit(sc->sc_cdev));
87600+
87601+ if (sc->sc_exec_units & TALITOS_HAS_EU_RNG) {
87602+ printk(" rng");
87603+#ifdef CONFIG_OCF_RANDOMHARVEST
87604+ talitos_rng_init(sc);
87605+ crypto_rregister(sc->sc_cid, talitos_read_random, sc);
87606+#endif
87607+ }
87608+ if (sc->sc_exec_units & TALITOS_HAS_EU_DEU) {
87609+ printk(" des/3des");
87610+ crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
87611+ crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
87612+ }
87613+ if (sc->sc_exec_units & TALITOS_HAS_EU_AESU) {
87614+ printk(" aes");
87615+ crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
87616+ }
87617+ if (sc->sc_exec_units & TALITOS_HAS_EU_MDEU) {
87618+ printk(" md5");
87619+ crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
87620+ /* HMAC support only with IPsec for now */
87621+ crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
87622+ printk(" sha1");
87623+ crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
87624+ /* HMAC support only with IPsec for now */
87625+ crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
87626+ }
87627+ printk("\n");
87628+ return 0;
87629+
87630+out:
87631+#ifndef CONFIG_PPC_MERGE
87632+ talitos_remove(pdev);
87633+#endif
87634+ return -ENOMEM;
87635+}
87636+
87637+#ifdef CONFIG_PPC_MERGE
87638+static int talitos_remove(struct of_device *ofdev)
87639+#else
87640+static int talitos_remove(struct platform_device *pdev)
87641+#endif
87642+{
87643+#ifdef CONFIG_PPC_MERGE
87644+ struct talitos_softc *sc = dev_get_drvdata(&ofdev->dev);
87645+#else
87646+ struct talitos_softc *sc = platform_get_drvdata(pdev);
87647+#endif
87648+ int i;
87649+
87650+ DPRINTF("%s()\n", __FUNCTION__);
87651+ if (sc->sc_cid >= 0)
87652+ crypto_unregister_all(sc->sc_cid);
87653+ if (sc->sc_chnfifo) {
87654+ for (i = 0; i < sc->sc_num_channels; i++)
87655+ if (sc->sc_chnfifo[i])
87656+ kfree(sc->sc_chnfifo[i]);
87657+ kfree(sc->sc_chnfifo);
87658+ }
87659+ if (sc->sc_chnlastalg)
87660+ kfree(sc->sc_chnlastalg);
87661+ if (sc->sc_chnfifolock)
87662+ kfree(sc->sc_chnfifolock);
87663+ if (sc->sc_irq != -1)
87664+ free_irq(sc->sc_irq, sc);
87665+ if (sc->sc_base_addr)
87666+ iounmap((void *) sc->sc_base_addr);
87667+ kfree(sc);
87668+ return 0;
87669+}
87670+
87671+#ifdef CONFIG_PPC_MERGE
87672+static struct of_device_id talitos_match[] = {
87673+ {
87674+ .type = "crypto",
87675+ .compatible = "talitos",
87676+ },
87677+ {},
87678+};
87679+
87680+MODULE_DEVICE_TABLE(of, talitos_match);
87681+
87682+static struct of_platform_driver talitos_driver = {
87683+ .name = DRV_NAME,
87684+ .match_table = talitos_match,
87685+ .probe = talitos_probe,
87686+ .remove = talitos_remove,
87687+};
87688+
87689+static int __init talitos_init(void)
87690+{
87691+ return of_register_platform_driver(&talitos_driver);
87692+}
87693+
87694+static void __exit talitos_exit(void)
87695+{
87696+ of_unregister_platform_driver(&talitos_driver);
87697+}
87698+#else
87699+/* Structure for a platform device driver */
87700+static struct platform_driver talitos_driver = {
87701+ .probe = talitos_probe,
87702+ .remove = talitos_remove,
87703+ .driver = {
87704+ .name = "fsl-sec2",
87705+ }
87706+};
87707+
87708+static int __init talitos_init(void)
87709+{
87710+ return platform_driver_register(&talitos_driver);
87711+}
87712+
87713+static void __exit talitos_exit(void)
87714+{
87715+ platform_driver_unregister(&talitos_driver);
87716+}
87717+#endif
87718+
87719+module_init(talitos_init);
87720+module_exit(talitos_exit);
87721+
87722+MODULE_LICENSE("Dual BSD/GPL");
87723+MODULE_AUTHOR("kim.phillips@freescale.com");
87724+MODULE_DESCRIPTION("OCF driver for Freescale SEC (talitos)");
87725diff --git a/crypto/ocf/talitos/talitos_dev.h b/crypto/ocf/talitos/talitos_dev.h
87726new file mode 100644
87727index 0000000..86bb57c
87728--- /dev/null
87729+++ b/crypto/ocf/talitos/talitos_dev.h
87730@@ -0,0 +1,277 @@
87731+/*
87732+ * Freescale SEC (talitos) device dependent data structures
87733+ *
87734+ * Copyright (c) 2006 Freescale Semiconductor, Inc.
87735+ *
87736+ * Redistribution and use in source and binary forms, with or without
87737+ * modification, are permitted provided that the following conditions
87738+ * are met:
87739+ *
87740+ * 1. Redistributions of source code must retain the above copyright
87741+ * notice, this list of conditions and the following disclaimer.
87742+ * 2. Redistributions in binary form must reproduce the above copyright
87743+ * notice, this list of conditions and the following disclaimer in the
87744+ * documentation and/or other materials provided with the distribution.
87745+ * 3. The name of the author may not be used to endorse or promote products
87746+ * derived from this software without specific prior written permission.
87747+ *
87748+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
87749+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
87750+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
87751+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
87752+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
87753+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
87754+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
87755+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87756+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
87757+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87758+ *
87759+ */
87760+
87761+/* device ID register values */
87762+#define TALITOS_ID_SEC_2_0 0x40
87763+#define TALITOS_ID_SEC_2_1 0x40 /* cross ref with IP block revision reg */
87764+
87765+/*
87766+ * following num_channels, channel-fifo-depth, exec-unit-mask, and
87767+ * descriptor-types-mask are for forward-compatibility with openfirmware
87768+ * flat device trees
87769+ */
87770+
87771+/*
87772+ * num_channels : the number of channels available in each SEC version.
87773+ */
87774+
87775+/* n.b. this driver requires these values be a power of 2 */
87776+#define TALITOS_NCHANNELS_SEC_1_0 4
87777+#define TALITOS_NCHANNELS_SEC_1_2 1
87778+#define TALITOS_NCHANNELS_SEC_2_0 4
87779+#define TALITOS_NCHANNELS_SEC_2_01 4
87780+#define TALITOS_NCHANNELS_SEC_2_1 4
87781+#define TALITOS_NCHANNELS_SEC_2_4 4
87782+
87783+/*
87784+ * channel-fifo-depth : The number of descriptor
87785+ * pointers a channel fetch fifo can hold.
87786+ */
87787+#define TALITOS_CHFIFOLEN_SEC_1_0 1
87788+#define TALITOS_CHFIFOLEN_SEC_1_2 1
87789+#define TALITOS_CHFIFOLEN_SEC_2_0 24
87790+#define TALITOS_CHFIFOLEN_SEC_2_01 24
87791+#define TALITOS_CHFIFOLEN_SEC_2_1 24
87792+#define TALITOS_CHFIFOLEN_SEC_2_4 24
87793+
87794+/*
87795+ * exec-unit-mask : The bitmask representing what Execution Units (EUs)
87796+ * are available. EU information should be encoded following the SEC's
87797+ * EU_SEL0 bitfield documentation, i.e. as follows:
87798+ *
87799+ * bit 31 = set if SEC permits no-EU selection (should be always set)
87800+ * bit 30 = set if SEC has the ARC4 EU (AFEU)
87801+ * bit 29 = set if SEC has the des/3des EU (DEU)
87802+ * bit 28 = set if SEC has the message digest EU (MDEU)
87803+ * bit 27 = set if SEC has the random number generator EU (RNG)
87804+ * bit 26 = set if SEC has the public key EU (PKEU)
87805+ * bit 25 = set if SEC has the aes EU (AESU)
87806+ * bit 24 = set if SEC has the Kasumi EU (KEU)
87807+ *
87808+ */
87809+#define TALITOS_HAS_EU_NONE (1<<0)
87810+#define TALITOS_HAS_EU_AFEU (1<<1)
87811+#define TALITOS_HAS_EU_DEU (1<<2)
87812+#define TALITOS_HAS_EU_MDEU (1<<3)
87813+#define TALITOS_HAS_EU_RNG (1<<4)
87814+#define TALITOS_HAS_EU_PKEU (1<<5)
87815+#define TALITOS_HAS_EU_AESU (1<<6)
87816+#define TALITOS_HAS_EU_KEU (1<<7)
87817+
87818+/* the corresponding masks for each SEC version */
87819+#define TALITOS_HAS_EUS_SEC_1_0 0x7f
87820+#define TALITOS_HAS_EUS_SEC_1_2 0x4d
87821+#define TALITOS_HAS_EUS_SEC_2_0 0x7f
87822+#define TALITOS_HAS_EUS_SEC_2_01 0x7f
87823+#define TALITOS_HAS_EUS_SEC_2_1 0xff
87824+#define TALITOS_HAS_EUS_SEC_2_4 0x7f
87825+
87826+/*
87827+ * descriptor-types-mask : The bitmask representing what descriptors
87828+ * are available. Descriptor type information should be encoded
87829+ * following the SEC's Descriptor Header Dword DESC_TYPE field
87830+ * documentation, i.e. as follows:
87831+ *
87832+ * bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type
87833+ * bit 1 = set if SEC supports the ipsec_esp descriptor type
87834+ * bit 2 = set if SEC supports the common_nonsnoop desc. type
87835+ * bit 3 = set if SEC supports the 802.11i AES ccmp desc. type
87836+ * bit 4 = set if SEC supports the hmac_snoop_no_afeu desc. type
87837+ * bit 5 = set if SEC supports the srtp descriptor type
87838+ * bit 6 = set if SEC supports the non_hmac_snoop_no_afeu desc.type
87839+ * bit 7 = set if SEC supports the pkeu_assemble descriptor type
87840+ * bit 8 = set if SEC supports the aesu_key_expand_output desc.type
87841+ * bit 9 = set if SEC supports the pkeu_ptmul descriptor type
87842+ * bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type
87843+ * bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type
87844+ *
87845+ * ..and so on and so forth.
87846+ */
87847+#define TALITOS_HAS_DT_AESU_CTR_NONSNOOP (1<<0)
87848+#define TALITOS_HAS_DT_IPSEC_ESP (1<<1)
87849+#define TALITOS_HAS_DT_COMMON_NONSNOOP (1<<2)
87850+
87851+/* the corresponding masks for each SEC version */
87852+#define TALITOS_HAS_DESCTYPES_SEC_2_0 0x01010ebf
87853+#define TALITOS_HAS_DESCTYPES_SEC_2_1 0x012b0ebf
87854+
87855+/*
87856+ * a TALITOS_xxx_HI address points to the low data bits (32-63) of the register
87857+ */
87858+
87859+/* global register offset addresses */
87860+#define TALITOS_ID 0x1020
87861+#define TALITOS_ID_HI 0x1024
87862+#define TALITOS_MCR 0x1030 /* master control register */
87863+#define TALITOS_MCR_HI 0x1038 /* master control register */
87864+#define TALITOS_MCR_SWR 0x1
87865+#define TALITOS_IMR 0x1008 /* interrupt mask register */
87866+#define TALITOS_IMR_ALL 0x00010fff /* enable all interrupts mask */
87867+#define TALITOS_IMR_ERRONLY 0x00010aaa /* enable error interrupts */
87868+#define TALITOS_IMR_HI 0x100C /* interrupt mask register */
87869+#define TALITOS_IMR_HI_ALL 0x00323333 /* enable all interrupts mask */
87870+#define TALITOS_IMR_HI_ERRONLY 0x00222222 /* enable error interrupts */
87871+#define TALITOS_ISR 0x1010 /* interrupt status register */
87872+#define TALITOS_ISR_ERROR 0x00010faa /* errors mask */
87873+#define TALITOS_ISR_DONE 0x00000055 /* channel(s) done mask */
87874+#define TALITOS_ISR_HI 0x1014 /* interrupt status register */
87875+#define TALITOS_ICR 0x1018 /* interrupt clear register */
87876+#define TALITOS_ICR_HI 0x101C /* interrupt clear register */
87877+
87878+/* channel register address stride */
87879+#define TALITOS_CH_OFFSET 0x100
87880+
87881+/* channel register offset addresses and bits */
87882+#define TALITOS_CH_CCCR 0x1108 /* Crypto-Channel Config Register */
87883+#define TALITOS_CH_CCCR_RESET 0x1 /* Channel Reset bit */
87884+#define TALITOS_CH_CCCR_HI 0x110c /* Crypto-Channel Config Register */
87885+#define TALITOS_CH_CCCR_HI_CDWE 0x10 /* Channel done writeback enable bit */
87886+#define TALITOS_CH_CCCR_HI_NT 0x4 /* Notification type bit */
87887+#define TALITOS_CH_CCCR_HI_CDIE 0x2 /* Channel Done Interrupt Enable bit */
87888+#define TALITOS_CH_CCPSR 0x1110 /* Crypto-Channel Pointer Status Reg */
87889+#define TALITOS_CH_CCPSR_HI 0x1114 /* Crypto-Channel Pointer Status Reg */
87890+#define TALITOS_CH_FF 0x1148 /* Fetch FIFO */
87891+#define TALITOS_CH_FF_HI 0x114c /* Fetch FIFO's FETCH_ADRS */
87892+#define TALITOS_CH_CDPR 0x1140 /* Crypto-Channel Pointer Status Reg */
87893+#define TALITOS_CH_CDPR_HI 0x1144 /* Crypto-Channel Pointer Status Reg */
87894+#define TALITOS_CH_DESCBUF 0x1180 /* (thru 11bf) Crypto-Channel
87895+ * Descriptor Buffer (debug) */
87896+
87897+/* execution unit register offset addresses and bits */
87898+#define TALITOS_DEUSR 0x2028 /* DEU status register */
87899+#define TALITOS_DEUSR_HI 0x202c /* DEU status register */
87900+#define TALITOS_DEUISR 0x2030 /* DEU interrupt status register */
87901+#define TALITOS_DEUISR_HI 0x2034 /* DEU interrupt status register */
87902+#define TALITOS_DEUICR 0x2038 /* DEU interrupt control register */
87903+#define TALITOS_DEUICR_HI 0x203c /* DEU interrupt control register */
87904+#define TALITOS_AESUISR 0x4030 /* AESU interrupt status register */
87905+#define TALITOS_AESUISR_HI 0x4034 /* AESU interrupt status register */
87906+#define TALITOS_AESUICR 0x4038 /* AESU interrupt control register */
87907+#define TALITOS_AESUICR_HI 0x403c /* AESU interrupt control register */
87908+#define TALITOS_MDEUISR 0x6030 /* MDEU interrupt status register */
87909+#define TALITOS_MDEUISR_HI 0x6034 /* MDEU interrupt status register */
87910+#define TALITOS_RNGSR 0xa028 /* RNG status register */
87911+#define TALITOS_RNGSR_HI 0xa02c /* RNG status register */
87912+#define TALITOS_RNGSR_HI_RD 0x1 /* RNG Reset done */
87913+#define TALITOS_RNGSR_HI_OFL 0xff0000/* number of dwords in RNG output FIFO*/
87914+#define TALITOS_RNGDSR 0xa010 /* RNG data size register */
87915+#define TALITOS_RNGDSR_HI 0xa014 /* RNG data size register */
87916+#define TALITOS_RNG_FIFO 0xa800 /* RNG FIFO - pool of random numbers */
87917+#define TALITOS_RNGISR 0xa030 /* RNG Interrupt status register */
87918+#define TALITOS_RNGISR_HI 0xa034 /* RNG Interrupt status register */
87919+#define TALITOS_RNGRCR 0xa018 /* RNG Reset control register */
87920+#define TALITOS_RNGRCR_HI 0xa01c /* RNG Reset control register */
87921+#define TALITOS_RNGRCR_HI_SR 0x1 /* RNG RNGRCR:Software Reset */
87922+
87923+/* descriptor pointer entry */
87924+struct talitos_desc_ptr {
87925+ u16 len; /* length */
87926+ u8 extent; /* jump (to s/g link table) and extent */
87927+ u8 res; /* reserved */
87928+ u32 ptr; /* pointer */
87929+};
87930+
87931+/* descriptor */
87932+struct talitos_desc {
87933+ u32 hdr; /* header */
87934+ u32 res; /* reserved */
87935+ struct talitos_desc_ptr ptr[7]; /* ptr/len pair array */
87936+};
87937+
87938+/* talitos descriptor header (hdr) bits */
87939+
87940+/* primary execution unit select */
87941+#define TALITOS_SEL0_AFEU 0x10000000
87942+#define TALITOS_SEL0_DEU 0x20000000
87943+#define TALITOS_SEL0_MDEU 0x30000000
87944+#define TALITOS_SEL0_RNG 0x40000000
87945+#define TALITOS_SEL0_PKEU 0x50000000
87946+#define TALITOS_SEL0_AESU 0x60000000
87947+
87948+/* primary execution unit mode (MODE0) and derivatives */
87949+#define TALITOS_MODE0_AESU_CBC 0x00200000
87950+#define TALITOS_MODE0_AESU_ENC 0x00100000
87951+#define TALITOS_MODE0_DEU_CBC 0x00400000
87952+#define TALITOS_MODE0_DEU_3DES 0x00200000
87953+#define TALITOS_MODE0_DEU_ENC 0x00100000
87954+#define TALITOS_MODE0_MDEU_INIT 0x01000000 /* init starting regs */
87955+#define TALITOS_MODE0_MDEU_HMAC 0x00800000
87956+#define TALITOS_MODE0_MDEU_PAD 0x00400000 /* PD */
87957+#define TALITOS_MODE0_MDEU_MD5 0x00200000
87958+#define TALITOS_MODE0_MDEU_SHA256 0x00100000
87959+#define TALITOS_MODE0_MDEU_SHA1 0x00000000 /* SHA-160 */
87960+#define TALITOS_MODE0_MDEU_MD5_HMAC \
87961+ (TALITOS_MODE0_MDEU_MD5 | TALITOS_MODE0_MDEU_HMAC)
87962+#define TALITOS_MODE0_MDEU_SHA256_HMAC \
87963+ (TALITOS_MODE0_MDEU_SHA256 | TALITOS_MODE0_MDEU_HMAC)
87964+#define TALITOS_MODE0_MDEU_SHA1_HMAC \
87965+ (TALITOS_MODE0_MDEU_SHA1 | TALITOS_MODE0_MDEU_HMAC)
87966+
87967+/* secondary execution unit select (SEL1) */
87968+/* it's MDEU or nothing */
87969+#define TALITOS_SEL1_MDEU 0x00030000
87970+
87971+/* secondary execution unit mode (MODE1) and derivatives */
87972+#define TALITOS_MODE1_MDEU_INIT 0x00001000 /* init starting regs */
87973+#define TALITOS_MODE1_MDEU_HMAC 0x00000800
87974+#define TALITOS_MODE1_MDEU_PAD 0x00000400 /* PD */
87975+#define TALITOS_MODE1_MDEU_MD5 0x00000200
87976+#define TALITOS_MODE1_MDEU_SHA256 0x00000100
87977+#define TALITOS_MODE1_MDEU_SHA1 0x00000000 /* SHA-160 */
87978+#define TALITOS_MODE1_MDEU_MD5_HMAC \
87979+ (TALITOS_MODE1_MDEU_MD5 | TALITOS_MODE1_MDEU_HMAC)
87980+#define TALITOS_MODE1_MDEU_SHA256_HMAC \
87981+ (TALITOS_MODE1_MDEU_SHA256 | TALITOS_MODE1_MDEU_HMAC)
87982+#define TALITOS_MODE1_MDEU_SHA1_HMAC \
87983+ (TALITOS_MODE1_MDEU_SHA1 | TALITOS_MODE1_MDEU_HMAC)
87984+
87985+/* direction of overall data flow (DIR) */
87986+#define TALITOS_DIR_OUTBOUND 0x00000000
87987+#define TALITOS_DIR_INBOUND 0x00000002
87988+
87989+/* done notification (DN) */
87990+#define TALITOS_DONE_NOTIFY 0x00000001
87991+
87992+/* descriptor types */
87993+/* odd numbers here are valid on SEC2 and greater only (e.g. ipsec_esp) */
87994+#define TD_TYPE_AESU_CTR_NONSNOOP (0 << 3)
87995+#define TD_TYPE_IPSEC_ESP (1 << 3)
87996+#define TD_TYPE_COMMON_NONSNOOP_NO_AFEU (2 << 3)
87997+#define TD_TYPE_HMAC_SNOOP_NO_AFEU (4 << 3)
87998+
87999+#define TALITOS_HDR_DONE_BITS 0xff000000
88000+
88001+#define DPRINTF(a...) do { \
88002+ if (debug) { \
88003+ printk("%s: ", sc ? \
88004+ device_get_nameunit(sc->sc_cdev) : "talitos"); \
88005+ printk(a); \
88006+ } \
88007+ } while (0)
88008diff --git a/crypto/ocf/talitos/talitos_soft.h b/crypto/ocf/talitos/talitos_soft.h
88009new file mode 100644
88010index 0000000..79efdbd
88011--- /dev/null
88012+++ b/crypto/ocf/talitos/talitos_soft.h
88013@@ -0,0 +1,77 @@
88014+/*
88015+ * Freescale SEC data structures for integration with ocf-linux
88016+ *
88017+ * Copyright (c) 2006 Freescale Semiconductor, Inc.
88018+ *
88019+ * Redistribution and use in source and binary forms, with or without
88020+ * modification, are permitted provided that the following conditions
88021+ * are met:
88022+ *
88023+ * 1. Redistributions of source code must retain the above copyright
88024+ * notice, this list of conditions and the following disclaimer.
88025+ * 2. Redistributions in binary form must reproduce the above copyright
88026+ * notice, this list of conditions and the following disclaimer in the
88027+ * documentation and/or other materials provided with the distribution.
88028+ * 3. The name of the author may not be used to endorse or promote products
88029+ * derived from this software without specific prior written permission.
88030+ *
88031+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
88032+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
88033+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
88034+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
88035+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
88036+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
88037+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
88038+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88039+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
88040+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88041+ */
88042+
88043+/*
88044+ * paired descriptor and associated crypto operation
88045+ */
88046+struct desc_cryptop_pair {
88047+ struct talitos_desc cf_desc; /* descriptor ptr */
88048+ struct cryptop *cf_crp; /* cryptop ptr */
88049+};
88050+
88051+/*
88052+ * Holds data specific to a single talitos device.
88053+ */
88054+struct talitos_softc {
88055+ softc_device_decl sc_cdev;
88056+ struct platform_device *sc_dev; /* device backpointer */
88057+ ocf_iomem_t sc_base_addr;
88058+ int sc_irq;
88059+ int sc_num; /* if we have multiple chips */
88060+ int32_t sc_cid; /* crypto tag */
88061+ u64 sc_chiprev; /* major/minor chip revision */
88062+ int sc_nsessions;
88063+ struct talitos_session *sc_sessions;
88064+ int sc_num_channels;/* number of crypto channels */
88065+ int sc_chfifo_len; /* channel fetch fifo len */
88066+ int sc_exec_units; /* execution units mask */
88067+ int sc_desc_types; /* descriptor types mask */
88068+ /*
88069+ * mutual exclusion for intra-channel resources, e.g. fetch fifos
88070+ * the last entry is a meta-channel lock used by the channel scheduler
88071+ */
88072+ spinlock_t *sc_chnfifolock;
88073+ /* sc_chnlastalgo contains last algorithm for that channel */
88074+ int *sc_chnlastalg;
88075+ /* sc_chnfifo holds pending descriptor--crypto operation pairs */
88076+ struct desc_cryptop_pair **sc_chnfifo;
88077+};
88078+
88079+struct talitos_session {
88080+ u_int32_t ses_used;
88081+ u_int32_t ses_klen; /* key length in bits */
88082+ u_int32_t ses_key[8]; /* DES/3DES/AES key */
88083+ u_int32_t ses_hmac[5]; /* hmac inner state */
88084+ u_int32_t ses_hmac_len; /* hmac length */
88085+ u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
88086+ u_int32_t ses_mlen; /* desired hash result len (12=ipsec or 16) */
88087+};
88088+
88089+#define TALITOS_SESSION(sid) ((sid) & 0x0fffffff)
88090+#define TALITOS_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
88091diff --git a/crypto/ocf/uio.h b/crypto/ocf/uio.h
88092new file mode 100644
88093index 0000000..03a6249
88094--- /dev/null
88095+++ b/crypto/ocf/uio.h
88096@@ -0,0 +1,54 @@
88097+#ifndef _OCF_UIO_H_
88098+#define _OCF_UIO_H_
88099+
88100+#include <linux/uio.h>
88101+
88102+/*
88103+ * The linux uio.h doesn't have all we need. To be fully api compatible
88104+ * with the BSD cryptodev, we need to keep this around. Perhaps this can
88105+ * be moved back into the linux/uio.h
88106+ *
88107+ * Linux port done by David McCullough <david_mccullough@mcafee.com>
88108+ * Copyright (C) 2006-2010 David McCullough
88109+ * Copyright (C) 2004-2005 Intel Corporation.
88110+ *
88111+ * LICENSE TERMS
88112+ *
88113+ * The free distribution and use of this software in both source and binary
88114+ * form is allowed (with or without changes) provided that:
88115+ *
88116+ * 1. distributions of this source code include the above copyright
88117+ * notice, this list of conditions and the following disclaimer;
88118+ *
88119+ * 2. distributions in binary form include the above copyright
88120+ * notice, this list of conditions and the following disclaimer
88121+ * in the documentation and/or other associated materials;
88122+ *
88123+ * 3. the copyright holder's name is not used to endorse products
88124+ * built using this software without specific written permission.
88125+ *
88126+ * ALTERNATIVELY, provided that this notice is retained in full, this product
88127+ * may be distributed under the terms of the GNU General Public License (GPL),
88128+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
88129+ *
88130+ * DISCLAIMER
88131+ *
88132+ * This software is provided 'as is' with no explicit or implied warranties
88133+ * in respect of its properties, including, but not limited to, correctness
88134+ * and/or fitness for purpose.
88135+ * ---------------------------------------------------------------------------
88136+ */
88137+
88138+struct uio {
88139+ struct iovec *uio_iov;
88140+ int uio_iovcnt;
88141+ off_t uio_offset;
88142+ int uio_resid;
88143+#if 0
88144+ enum uio_seg uio_segflg;
88145+ enum uio_rw uio_rw;
88146+ struct thread *uio_td;
88147+#endif
88148+};
88149+
88150+#endif
88151diff --git a/drivers/char/random.c b/drivers/char/random.c
88152index 8258982..6509c94 100644
88153--- a/drivers/char/random.c
88154+++ b/drivers/char/random.c
88155@@ -129,6 +129,9 @@
88156 * unsigned int value);
88157 * void add_interrupt_randomness(int irq);
88158 *
88159+ * void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
88160+ * int random_input_wait(void);
88161+ *
88162 * add_input_randomness() uses the input layer interrupt timing, as well as
88163 * the event type information from the hardware.
88164 *
88165@@ -140,6 +143,13 @@
88166 * a better measure, since the timing of the disk interrupts are more
88167 * unpredictable.
88168 *
88169+ * random_input_words() just provides a raw block of entropy to the input
88170+ * pool, such as from a hardware entropy generator.
88171+ *
88172+ * random_input_wait() suspends the caller until such time as the
88173+ * entropy pool falls below the write threshold, and returns a count of how
88174+ * much entropy (in bits) is needed to sustain the pool.
88175+ *
88176 * All of these routines try to estimate how many bits of randomness a
88177 * particular randomness source. They do this by keeping track of the
88178 * first and second order deltas of the event timings.
88179@@ -714,6 +724,61 @@ void add_disk_randomness(struct gendisk *disk)
88180 }
88181 #endif
88182
88183+/*
88184+ * random_input_words - add bulk entropy to pool
88185+ *
88186+ * @buf: buffer to add
88187+ * @wordcount: number of __u32 words to add
88188+ * @ent_count: total amount of entropy (in bits) to credit
88189+ *
88190+ * this provides bulk input of entropy to the input pool
88191+ *
88192+ */
88193+void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
88194+{
88195+ mix_pool_bytes(&input_pool, buf, wordcount*4);
88196+
88197+ credit_entropy_bits(&input_pool, ent_count);
88198+
88199+ DEBUG_ENT("crediting %d bits => %d\n",
88200+ ent_count, input_pool.entropy_count);
88201+ /*
88202+ * Wake up waiting processes if we have enough
88203+ * entropy.
88204+ */
88205+ if (input_pool.entropy_count >= random_read_wakeup_thresh)
88206+ wake_up_interruptible(&random_read_wait);
88207+}
88208+EXPORT_SYMBOL(random_input_words);
88209+
88210+/*
88211+ * random_input_wait - wait until random needs entropy
88212+ *
88213+ * this function sleeps until the /dev/random subsystem actually
88214+ * needs more entropy, and then return the amount of entropy
88215+ * that it would be nice to have added to the system.
88216+ */
88217+int random_input_wait(void)
88218+{
88219+ int count;
88220+
88221+ wait_event_interruptible(random_write_wait,
88222+ input_pool.entropy_count < random_write_wakeup_thresh);
88223+
88224+ count = random_write_wakeup_thresh - input_pool.entropy_count;
88225+
88226+ /* likely we got woken up due to a signal */
88227+ if (count <= 0) count = random_read_wakeup_thresh;
88228+
88229+ DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
88230+ count,
88231+ input_pool.entropy_count, random_write_wakeup_thresh);
88232+
88233+ return count;
88234+}
88235+EXPORT_SYMBOL(random_input_wait);
88236+
88237+
88238 #define EXTRACT_SIZE 10
88239
88240 /*********************************************************************
88241diff --git a/fs/fcntl.c b/fs/fcntl.c
88242index 2cf93ec..1b6d2bb 100644
88243--- a/fs/fcntl.c
88244+++ b/fs/fcntl.c
88245@@ -141,6 +141,7 @@ SYSCALL_DEFINE1(dup, unsigned int, fildes)
88246 }
88247 return ret;
88248 }
88249+EXPORT_SYMBOL(sys_dup);
88250
88251 #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
88252
88253diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
88254index adaf3c1..e961a9a 100644
88255--- a/include/linux/miscdevice.h
88256+++ b/include/linux/miscdevice.h
88257@@ -12,6 +12,7 @@
88258 #define APOLLO_MOUSE_MINOR 7
88259 #define PC110PAD_MINOR 9
88260 /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
88261+#define CRYPTODEV_MINOR 70 /* /dev/crypto */
88262 #define WATCHDOG_MINOR 130 /* Watchdog timer */
88263 #define TEMP_MINOR 131 /* Temperature Sensor */
88264 #define RTC_MINOR 135
88265diff --git a/include/linux/random.h b/include/linux/random.h
88266index 25d02fe..b59ec10 100644
88267--- a/include/linux/random.h
88268+++ b/include/linux/random.h
88269@@ -9,6 +9,7 @@
88270
88271 #include <linux/types.h>
88272 #include <linux/ioctl.h>
88273+#include <linux/types.h> /* for __u32 in user space */
88274 #include <linux/irqnr.h>
88275
88276 /* ioctl()'s for the random number generator */
88277@@ -34,6 +35,30 @@
88278 /* Clear the entropy pool and associated counters. (Superuser only.) */
88279 #define RNDCLEARPOOL _IO( 'R', 0x06 )
88280
88281+#ifdef CONFIG_FIPS_RNG
88282+
88283+/* Size of seed value - equal to AES blocksize */
88284+#define AES_BLOCK_SIZE_BYTES 16
88285+#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
88286+/* Size of AES key */
88287+#define KEY_SIZE_BYTES 16
88288+
88289+/* ioctl() structure used by FIPS 140-2 Tests */
88290+struct rand_fips_test {
88291+ unsigned char key[KEY_SIZE_BYTES]; /* Input */
88292+ unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
88293+ unsigned char seed[SEED_SIZE_BYTES]; /* Input */
88294+ unsigned char result[SEED_SIZE_BYTES]; /* Output */
88295+};
88296+
88297+/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
88298+#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
88299+
88300+/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
88301+#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
88302+
88303+#endif /* #ifdef CONFIG_FIPS_RNG */
88304+
88305 struct rand_pool_info {
88306 int entropy_count;
88307 int buf_size;
88308@@ -50,6 +75,10 @@ extern void add_input_randomness(unsigned int type, unsigned int code,
88309 unsigned int value);
88310 extern void add_interrupt_randomness(int irq);
88311
88312+extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
88313+extern int random_input_wait(void);
88314+#define HAS_RANDOM_INPUT_WAIT 1
88315+
88316 extern void get_random_bytes(void *buf, int nbytes);
88317 void generate_random_uuid(unsigned char uuid_out[16]);
88318
88319diff --git a/kernel/pid.c b/kernel/pid.c
88320index d3f722d..e041b52 100644
88321--- a/kernel/pid.c
88322+++ b/kernel/pid.c
88323@@ -387,6 +387,7 @@ struct task_struct *find_task_by_vpid(pid_t vnr)
88324 {
88325 return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
88326 }
88327+EXPORT_SYMBOL(find_task_by_vpid);
88328
88329 struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
88330 {
88331--
883321.6.6.1
88333