summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFranklin S. Cooper Jr <fcooper@ti.com>2012-10-12 00:14:45 -0500
committerDenys Dmytriyenko <denis@denix.org>2012-10-18 11:35:54 -0400
commite615e05e0f420d7e2411da8a101cb00a8bf78a68 (patch)
tree8f0fa669adba8e018e84cd9bc3389c12dfb494cb
parentfe1242c26539a931e1307b66cbd6cb9760db0d6d (diff)
downloadmeta-ti-e615e05e0f420d7e2411da8a101cb00a8bf78a68.tar.gz
linux-am335x-3.2.0-psp04.06.00.08: Add PSP v04.06.00.08 of the Linux kernel
* Add the PSP release version of the Linux kernel for the am335x-evm * Include a variable called KERNEL_PATCHES which can be used to add patches on top of the PSP release of the Linux kernel. Currently used to apply various patches that add functionality or fixes bugs. Signed-off-by: Franklin S. Cooper Jr <fcooper@ti.com> Signed-off-by: Denys Dmytriyenko <denys@ti.com> Signed-off-by: Denys Dmytriyenko <denis@denix.org>
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am3358-sk-modified-WLAN-enable-and-irq-to-match-boar.patch62
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x-Add-crypto-driver-settings-to-defconfig.patch130
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x-Add-pm_runtime-API-to-crypto-driver.patch405
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x-enable-pullup-on-the-WLAN-enable-pin-fo.patch57
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x_evm_defconfig-turn-off-MUSB-DMA.patch35
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335xevm-using-edge-triggered-interrupts-for-WLAN.patch35
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am33x-Add-memory-addresses-for-crypto-modules.patch41
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am33xx-Add-SmartReflex-support.patch2014
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-mach-omap2-pm33xx-Disable-VT-switch.patch71
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-musb-update-PIO-mode-help-information-in-Kconfig.patch45
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-omap-serial-add-delay-before-suspending.patch42
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-AM335x-OCF-Driver-for-Linux-3.patch7228
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-am335x-Add-suspend-resume-routines-to-crypto-driver.patch147
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-am33x-Add-crypto-device-and-resource-structures.patch111
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-am33xx-Enable-CONFIG_AM33XX_SMARTREFLEX.patch26
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0003-am33x-Add-crypto-device-and-resource-structure-for-T.patch60
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0004-am33x-Add-crypto-drivers-to-Kconfig-and-Makefiles.patch124
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0005-am33x-Create-header-file-for-OMAP4-crypto-modules.patch213
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0006-am33x-Create-driver-for-TRNG-crypto-module.patch324
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0007-am33x-Create-driver-for-AES-crypto-module.patch971
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0008-am33x-Create-driver-for-SHA-MD5-crypto-module.patch1444
-rw-r--r--recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/defconfig2656
-rw-r--r--recipes-kernel/linux/linux-am335x_3.2.0-psp04.06.00.08.bb81
23 files changed, 16322 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am3358-sk-modified-WLAN-enable-and-irq-to-match-boar.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am3358-sk-modified-WLAN-enable-and-irq-to-match-boar.patch
new file mode 100644
index 00000000..25d2fdfd
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am3358-sk-modified-WLAN-enable-and-irq-to-match-boar.patch
@@ -0,0 +1,62 @@
1From 69c82f68876d24e798388fc053c8d6766236ac65 Mon Sep 17 00:00:00 2001
2From: Vita Preskovsky <vitap@ti.com>
3Date: Thu, 28 Jun 2012 14:53:12 +0300
4Subject: [PATCH] am3358-sk: modified WLAN enable and irq to match board revision 1.2
5 * 1. WLAN enable and irq are modified to match board revision 1.2
6 2. support suspend/resume for SK board
7
8Upstream-Status: Pending
9
10Signed-off-by: Vita Preskovsky <vitap@ti.com>
11---
12 arch/arm/mach-omap2/board-am335xevm.c | 11 +++++++----
13 1 files changed, 7 insertions(+), 4 deletions(-)
14
15diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c
16index 64f7547..6ae4e68 100755
17--- a/arch/arm/mach-omap2/board-am335xevm.c
18+++ b/arch/arm/mach-omap2/board-am335xevm.c
19@@ -905,7 +905,7 @@ static struct pinmux_config ecap2_pin_mux[] = {
20
21 #define AM335XEVM_WLAN_PMENA_GPIO GPIO_TO_PIN(1, 30)
22 #define AM335XEVM_WLAN_IRQ_GPIO GPIO_TO_PIN(3, 17)
23-#define AM335XEVM_SK_WLAN_IRQ_GPIO GPIO_TO_PIN(1, 29)
24+#define AM335XEVM_SK_WLAN_IRQ_GPIO GPIO_TO_PIN(0, 31)
25
26 struct wl12xx_platform_data am335xevm_wlan_data = {
27 .irq = OMAP_GPIO_IRQ(AM335XEVM_WLAN_IRQ_GPIO),
28@@ -941,8 +941,8 @@ static struct pinmux_config wl12xx_pin_mux[] = {
29 };
30
31 static struct pinmux_config wl12xx_pin_mux_sk[] = {
32- {"gpmc_wpn.gpio0_31", OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT},
33- {"gpmc_csn0.gpio1_29", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT},
34+ {"gpmc_wpn.gpio0_31", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT},
35+ {"gpmc_csn0.gpio1_29", OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT_PULLUP},
36 {"mcasp0_ahclkx.gpio3_21", OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT},
37 {NULL, 0},
38 };
39@@ -1618,6 +1618,7 @@ static void mmc1_wl12xx_init(int evm_id, int profile)
40 am335x_mmc[1].name = "wl1271";
41 am335x_mmc[1].caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD;
42 am335x_mmc[1].nonremovable = true;
43+ am335x_mmc[1].pm_caps = MMC_PM_KEEP_POWER;
44 am335x_mmc[1].gpio_cd = -EINVAL;
45 am335x_mmc[1].gpio_wp = -EINVAL;
46 am335x_mmc[1].ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34; /* 3V3 */
47@@ -1674,10 +1675,12 @@ static void wl12xx_init(int evm_id, int profile)
48 int ret;
49
50 if (evm_id == EVM_SK) {
51- am335xevm_wlan_data.wlan_enable_gpio = GPIO_TO_PIN(0, 31);
52+ am335xevm_wlan_data.wlan_enable_gpio = GPIO_TO_PIN(1, 29);
53 am335xevm_wlan_data.bt_enable_gpio = GPIO_TO_PIN(3, 21);
54 am335xevm_wlan_data.irq =
55 OMAP_GPIO_IRQ(AM335XEVM_SK_WLAN_IRQ_GPIO);
56+ am335xevm_wlan_data.platform_quirks =
57+ WL12XX_PLATFORM_QUIRK_EDGE_IRQ;
58 setup_pin_mux(wl12xx_pin_mux_sk);
59 } else {
60 setup_pin_mux(wl12xx_pin_mux);
61--
621.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x-Add-crypto-driver-settings-to-defconfig.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x-Add-crypto-driver-settings-to-defconfig.patch
new file mode 100644
index 00000000..46f02cbf
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x-Add-crypto-driver-settings-to-defconfig.patch
@@ -0,0 +1,130 @@
1From 1edc97015f69fac420c32df514e1d1d546041d42 Mon Sep 17 00:00:00 2001
2From: Greg Turner <gregturner@ti.com>
3Date: Fri, 8 Jun 2012 13:54:13 -0500
4Subject: [PATCH] [am335x]: Add crypto driver settings to defconfig
5
6* Add Crypto Driver and configuration to defconfig
7---
8 arch/arm/configs/am335x_evm_defconfig | 39 +++++++++++++++++++++++---------
9 1 files changed, 28 insertions(+), 11 deletions(-)
10 mode change 100644 => 100755 arch/arm/configs/am335x_evm_defconfig
11
12diff --git a/arch/arm/configs/am335x_evm_defconfig b/arch/arm/configs/am335x_evm_defconfig
13old mode 100644
14new mode 100755
15index de1eaad..0bf7efd
16--- a/arch/arm/configs/am335x_evm_defconfig
17+++ b/arch/arm/configs/am335x_evm_defconfig
18@@ -1277,6 +1277,9 @@ CONFIG_SERIAL_OMAP_CONSOLE=y
19 # CONFIG_SERIAL_XILINX_PS_UART is not set
20 # CONFIG_HVC_DCC is not set
21 # CONFIG_IPMI_HANDLER is not set
22+CONFIG_HW_RANDOM=y
23+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
24+CONFIG_HW_RANDOM_OMAP4=y
25 # CONFIG_HW_RANDOM is not set
26 # CONFIG_R3964 is not set
27 # CONFIG_RAW_DRIVER is not set
28@@ -2472,36 +2475,38 @@ CONFIG_CRYPTO=y
29 #
30 CONFIG_CRYPTO_ALGAPI=y
31 CONFIG_CRYPTO_ALGAPI2=y
32+CONFIG_CRYPTO_AEAD=y
33 CONFIG_CRYPTO_AEAD2=y
34 CONFIG_CRYPTO_BLKCIPHER=y
35 CONFIG_CRYPTO_BLKCIPHER2=y
36 CONFIG_CRYPTO_HASH=y
37 CONFIG_CRYPTO_HASH2=y
38+CONFIG_CRYPTO_RNG=y
39 CONFIG_CRYPTO_RNG2=y
40 CONFIG_CRYPTO_PCOMP2=y
41 CONFIG_CRYPTO_MANAGER=y
42 CONFIG_CRYPTO_MANAGER2=y
43 # CONFIG_CRYPTO_USER is not set
44-CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
45+# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
46 # CONFIG_CRYPTO_GF128MUL is not set
47 # CONFIG_CRYPTO_NULL is not set
48 CONFIG_CRYPTO_WORKQUEUE=y
49 # CONFIG_CRYPTO_CRYPTD is not set
50 # CONFIG_CRYPTO_AUTHENC is not set
51-# CONFIG_CRYPTO_TEST is not set
52+CONFIG_CRYPTO_TEST=m
53
54 #
55 # Authenticated Encryption with Associated Data
56 #
57 # CONFIG_CRYPTO_CCM is not set
58 # CONFIG_CRYPTO_GCM is not set
59-# CONFIG_CRYPTO_SEQIV is not set
60+CONFIG_CRYPTO_SEQIV=y
61
62 #
63 # Block modes
64 #
65-# CONFIG_CRYPTO_CBC is not set
66-# CONFIG_CRYPTO_CTR is not set
67+CONFIG_CRYPTO_CBC=y
68+CONFIG_CRYPTO_CTR=y
69 # CONFIG_CRYPTO_CTS is not set
70 CONFIG_CRYPTO_ECB=y
71 # CONFIG_CRYPTO_LRW is not set
72@@ -2511,7 +2516,7 @@ CONFIG_CRYPTO_ECB=y
73 #
74 # Hash modes
75 #
76-# CONFIG_CRYPTO_HMAC is not set
77+CONFIG_CRYPTO_HMAC=y
78 # CONFIG_CRYPTO_XCBC is not set
79 # CONFIG_CRYPTO_VMAC is not set
80
81@@ -2521,14 +2526,14 @@ CONFIG_CRYPTO_ECB=y
82 CONFIG_CRYPTO_CRC32C=y
83 # CONFIG_CRYPTO_GHASH is not set
84 # CONFIG_CRYPTO_MD4 is not set
85-# CONFIG_CRYPTO_MD5 is not set
86+CONFIG_CRYPTO_MD5=y
87 CONFIG_CRYPTO_MICHAEL_MIC=y
88 # CONFIG_CRYPTO_RMD128 is not set
89 # CONFIG_CRYPTO_RMD160 is not set
90 # CONFIG_CRYPTO_RMD256 is not set
91 # CONFIG_CRYPTO_RMD320 is not set
92-# CONFIG_CRYPTO_SHA1 is not set
93-# CONFIG_CRYPTO_SHA256 is not set
94+CONFIG_CRYPTO_SHA1=y
95+CONFIG_CRYPTO_SHA256=y
96 # CONFIG_CRYPTO_SHA512 is not set
97 # CONFIG_CRYPTO_TGR192 is not set
98 # CONFIG_CRYPTO_WP512 is not set
99@@ -2543,7 +2548,7 @@ CONFIG_CRYPTO_ARC4=y
100 # CONFIG_CRYPTO_CAMELLIA is not set
101 # CONFIG_CRYPTO_CAST5 is not set
102 # CONFIG_CRYPTO_CAST6 is not set
103-# CONFIG_CRYPTO_DES is not set
104+CONFIG_CRYPTO_DES=y
105 # CONFIG_CRYPTO_FCRYPT is not set
106 # CONFIG_CRYPTO_KHAZAD is not set
107 # CONFIG_CRYPTO_SALSA20 is not set
108@@ -2565,7 +2570,19 @@ CONFIG_CRYPTO_LZO=y
109 # CONFIG_CRYPTO_ANSI_CPRNG is not set
110 # CONFIG_CRYPTO_USER_API_HASH is not set
111 # CONFIG_CRYPTO_USER_API_SKCIPHER is not set
112-# CONFIG_CRYPTO_HW is not set
113+CONFIG_CRYPTO_HW=y
114+CONFIG_CRYPTO_DEV_OMAP4_AES=y
115+CONFIG_CRYPTO_DEV_OMAP4_SHAM=y
116+
117+#
118+# OCF Configuration
119+#
120+CONFIG_OCF_OCF=y
121+# CONFIG_OCF_RANDOMHARVEST is not set
122+CONFIG_OCF_CRYPTODEV=y
123+CONFIG_OCF_CRYPTOSOFT=y
124+# CONFIG_OCF_OCFNULL is not set
125+# CONFIG_OCF_BENCH is not set
126 # CONFIG_BINARY_PRINTF is not set
127
128 #
129--
1301.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x-Add-pm_runtime-API-to-crypto-driver.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x-Add-pm_runtime-API-to-crypto-driver.patch
new file mode 100644
index 00000000..cef94b70
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x-Add-pm_runtime-API-to-crypto-driver.patch
@@ -0,0 +1,405 @@
1From 7cb6dbae57e2bb5d237bb88f6eb40971cf8fc3b5 Mon Sep 17 00:00:00 2001
2From: Greg Turner <gregturner@ti.com>
3Date: Wed, 18 Jul 2012 09:15:18 -0500
4Subject: [PATCH] [am335x]: Add pm_runtime API to crypto driver
5
6* Add pm_runtime API to crypto driver AES and SHA
7* Mod devices.c file to add pm_runtime for crypto
8* Mod omap_hwmod_33xx_data.c to add resources structures
9* Crypto module clocks are enabled in probe function
10 and disabled only on remove or other error.
11---
12 arch/arm/mach-omap2/devices.c | 66 ++++++++++++++++++++++++++++
13 arch/arm/mach-omap2/omap_hwmod_33xx_data.c | 15 ++++++-
14 drivers/crypto/omap4-aes.c | 52 +++++++++++----------
15 drivers/crypto/omap4-sham.c | 45 ++++++++++---------
16 4 files changed, 131 insertions(+), 47 deletions(-)
17 mode change 100644 => 100755 arch/arm/mach-omap2/devices.c
18 mode change 100644 => 100755 arch/arm/mach-omap2/omap_hwmod_33xx_data.c
19 mode change 100644 => 100755 drivers/crypto/omap4-aes.c
20 mode change 100644 => 100755 drivers/crypto/omap4-sham.c
21
22diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
23old mode 100644
24new mode 100755
25index ebf0d9e..156e363
26--- a/arch/arm/mach-omap2/devices.c
27+++ b/arch/arm/mach-omap2/devices.c
28@@ -751,6 +751,7 @@ static struct platform_device sham_device = {
29 .id = -1,
30 };
31
32+#if 0
33 static void omap_init_sham(void)
34 {
35 sham_device.resource = omap4_sham_resources;
36@@ -758,6 +759,38 @@ static void omap_init_sham(void)
37
38 platform_device_register(&sham_device);
39 }
40+#endif
41+
42+int __init omap_init_sham(void)
43+{
44+ int id = -1;
45+ struct platform_device *pdev;
46+ struct omap_hwmod *oh;
47+ char *oh_name = "sha0";
48+ char *name = "omap4-sham";
49+
50+ oh = omap_hwmod_lookup(oh_name);
51+ if (!oh) {
52+ pr_err("Could not look up %s\n", oh_name);
53+ return -ENODEV;
54+ }
55+
56+ pdev = omap_device_build(name, id, oh, NULL, 0, NULL, 0, 0);
57+ //pdev.resource = omap4_sham_resources;
58+ //pdev.num_resources = omap4_sham_resources_sz;
59+
60+ if (IS_ERR(pdev)) {
61+ WARN(1, "Can't build omap_device for %s:%s.\n",
62+ name, oh->name);
63+ return PTR_ERR(pdev);
64+ }
65+
66+ return 0;
67+}
68+
69+
70+
71+
72
73 #else
74 static inline void omap_init_sham(void) { }
75@@ -853,12 +886,45 @@ static struct platform_device aes_device = {
76 .id = -1,
77 };
78
79+#if 0
80 static void omap_init_aes(void)
81 {
82 aes_device.resource = omap4_aes_resources;
83 aes_device.num_resources = omap4_aes_resources_sz;
84 platform_device_register(&aes_device);
85 }
86+#endif
87+
88+int __init omap_init_aes(void)
89+{
90+ int id = -1;
91+ struct platform_device *pdev;
92+ struct omap_hwmod *oh;
93+ char *oh_name = "aes0";
94+ char *name = "omap4-aes";
95+
96+ oh = omap_hwmod_lookup(oh_name);
97+ if (!oh) {
98+ pr_err("Could not look up %s\n", oh_name);
99+ return -ENODEV;
100+ }
101+
102+ pdev = omap_device_build(name, id, oh, NULL, 0, NULL, 0, 0);
103+ //pdev.resource = omap4_sham_resources;
104+ //pdev.num_resources = omap4_sham_resources_sz;
105+
106+ if (IS_ERR(pdev)) {
107+ WARN(1, "Can't build omap_device for %s:%s.\n",
108+ name, oh->name);
109+ return PTR_ERR(pdev);
110+ }
111+
112+ return 0;
113+}
114+
115+
116+
117+
118
119 #else
120 static inline void omap_init_aes(void) { }
121diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
122old mode 100644
123new mode 100755
124index 995b73f..2f9982c
125--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
126+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
127@@ -434,11 +434,18 @@ static struct omap_hwmod_irq_info am33xx_aes0_irqs[] = {
128 { .irq = -1 }
129 };
130
131+static struct omap_hwmod_dma_info am33xx_aes0_dma[] = {
132+ { .dma_req = AM33XX_DMA_AESEIP36T0_DOUT },
133+ { .dma_req = AM33XX_DMA_AESEIP36T0_DIN },
134+ { .dma_req = -1 }
135+};
136+
137 static struct omap_hwmod am33xx_aes0_hwmod = {
138 .name = "aes0",
139 .class = &am33xx_aes_hwmod_class,
140 .clkdm_name = "l3_clkdm",
141 .mpu_irqs = am33xx_aes0_irqs,
142+ .sdma_reqs = am33xx_aes0_dma,
143 .main_clk = "aes0_fck",
144 .prcm = {
145 .omap4 = {
146@@ -2165,15 +2172,21 @@ static struct omap_hwmod_class am33xx_sha0_hwmod_class = {
147 };
148
149 static struct omap_hwmod_irq_info am33xx_sha0_irqs[] = {
150- { .irq = 108 },
151+ { .irq = AM33XX_IRQ_SHAEIP57t0_P },
152 { .irq = -1 }
153 };
154
155+static struct omap_hwmod_dma_info am33xx_sha0_dma[] = {
156+ { .dma_req = AM33XX_DMA_SHAEIP57T0_DIN },
157+ { .dma_req = -1 }
158+};
159+
160 static struct omap_hwmod am33xx_sha0_hwmod = {
161 .name = "sha0",
162 .class = &am33xx_sha0_hwmod_class,
163 .clkdm_name = "l3_clkdm",
164 .mpu_irqs = am33xx_sha0_irqs,
165+ .sdma_reqs = am33xx_sha0_dma,
166 .main_clk = "sha0_fck",
167 .prcm = {
168 .omap4 = {
169diff --git a/drivers/crypto/omap4-aes.c b/drivers/crypto/omap4-aes.c
170old mode 100644
171new mode 100755
172index f0b3fe2..76f988a
173--- a/drivers/crypto/omap4-aes.c
174+++ b/drivers/crypto/omap4-aes.c
175@@ -32,13 +32,14 @@
176 #include <linux/init.h>
177 #include <linux/errno.h>
178 #include <linux/kernel.h>
179-#include <linux/clk.h>
180 #include <linux/platform_device.h>
181 #include <linux/scatterlist.h>
182 #include <linux/dma-mapping.h>
183 #include <linux/io.h>
184 #include <linux/crypto.h>
185+#include <linux/pm_runtime.h>
186 #include <linux/interrupt.h>
187+#include <linux/delay.h>
188 #include <crypto/scatterwalk.h>
189 #include <crypto/aes.h>
190
191@@ -145,12 +146,6 @@ static void omap4_aes_write_n(struct omap4_aes_dev *dd, u32 offset,
192
193 static int omap4_aes_hw_init(struct omap4_aes_dev *dd)
194 {
195- /*
196- * clocks are enabled when request starts and disabled when finished.
197- * It may be long delays between requests.
198- * Device might go to off mode to save power.
199- */
200- clk_enable(dd->iclk);
201 omap4_aes_write(dd, AES_REG_SYSCFG, 0);
202
203 if (!(dd->flags & FLAGS_INIT)) {
204@@ -494,7 +489,6 @@ static void omap4_aes_finish_req(struct omap4_aes_dev *dd, int err)
205
206 pr_debug("err: %d\n", err);
207
208- clk_disable(dd->iclk);
209 dd->flags &= ~FLAGS_BUSY;
210
211 req->base.complete(&req->base, err);
212@@ -801,13 +795,15 @@ static int omap4_aes_probe(struct platform_device *pdev)
213 crypto_init_queue(&dd->queue, AM33X_AES_QUEUE_LENGTH);
214
215 /* Get the base address */
216- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
217- if (!res) {
218- dev_err(dev, "invalid resource type\n");
219- err = -ENODEV;
220- goto err_res;
221- }
222- dd->phys_base = res->start;
223+ //res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
224+ //if (!res) {
225+ // dev_err(dev, "invalid resource type\n");
226+ // err = -ENODEV;
227+ // goto err_res;
228+ //}
229+
230+ //dd->phys_base = res->start;
231+ dd->phys_base = AM33XX_AES0_P_BASE;
232
233 /* Get the DMA */
234 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
235@@ -823,13 +819,10 @@ static int omap4_aes_probe(struct platform_device *pdev)
236 else
237 dd->dma_in = res->start;
238
239- /* Initializing the clock */
240- dd->iclk = clk_get(dev, "aes0_fck");
241- if (IS_ERR(dd->iclk)) {
242- dev_err(dev, "clock initialization failed.\n");
243- err = PTR_ERR(dd->iclk);
244- goto err_res;
245- }
246+ pm_runtime_enable(dev);
247+ udelay(1);
248+ pm_runtime_get_sync(dev);
249+ udelay(1);
250
251 dd->io_base = ioremap(dd->phys_base, SZ_4K);
252 if (!dd->io_base) {
253@@ -840,7 +833,7 @@ static int omap4_aes_probe(struct platform_device *pdev)
254
255 omap4_aes_hw_init(dd);
256 reg = omap4_aes_read(dd, AES_REG_REV);
257- clk_disable(dd->iclk);
258+
259 dev_info(dev, "AM33X AES hw accel rev: %u.%02u\n",
260 ((reg & AES_REG_REV_X_MAJOR_MASK) >> 8),
261 (reg & AES_REG_REV_Y_MINOR_MASK));
262@@ -879,7 +872,12 @@ err_dma:
263 iounmap(dd->io_base);
264
265 err_io:
266- clk_put(dd->iclk);
267+ pm_runtime_put_sync(dev);
268+ udelay(1);
269+ pm_runtime_disable(dev);
270+ udelay(1);
271+
272+
273 err_res:
274 kfree(dd);
275 dd = NULL;
276@@ -907,7 +905,11 @@ static int omap4_aes_remove(struct platform_device *pdev)
277 tasklet_kill(&dd->queue_task);
278 omap4_aes_dma_cleanup(dd);
279 iounmap(dd->io_base);
280- clk_put(dd->iclk);
281+ pm_runtime_put_sync(&pdev->dev);
282+ udelay(1);
283+ pm_runtime_disable(&pdev->dev);
284+ udelay(1);
285+
286 kfree(dd);
287 dd = NULL;
288
289diff --git a/drivers/crypto/omap4-sham.c b/drivers/crypto/omap4-sham.c
290old mode 100644
291new mode 100755
292index 79f6be9..21f1b48
293--- a/drivers/crypto/omap4-sham.c
294+++ b/drivers/crypto/omap4-sham.c
295@@ -31,7 +31,6 @@
296 #include <linux/errno.h>
297 #include <linux/interrupt.h>
298 #include <linux/kernel.h>
299-#include <linux/clk.h>
300 #include <linux/irq.h>
301 #include <linux/io.h>
302 #include <linux/platform_device.h>
303@@ -40,6 +39,7 @@
304 #include <linux/delay.h>
305 #include <linux/crypto.h>
306 #include <linux/cryptohash.h>
307+#include <linux/pm_runtime.h>
308 #include <crypto/scatterwalk.h>
309 #include <crypto/algapi.h>
310 #include <crypto/sha.h>
311@@ -700,7 +700,6 @@ static void omap4_sham_finish_req(struct ahash_request *req, int err)
312 /* atomic operation is not needed here */
313 dd->dflags &= ~(BIT(FLAGS_BUSY) | BIT(FLAGS_FINAL) | BIT(FLAGS_CPU) |
314 BIT(FLAGS_DMA_READY) | BIT(FLAGS_OUTPUT_READY));
315- clk_disable(dd->iclk);
316
317 if (req->base.complete)
318 req->base.complete(&req->base, err);
319@@ -743,7 +742,6 @@ static int omap4_sham_handle_queue(struct omap4_sham_dev *dd,
320 dev_dbg(dd->dev, "handling new req, op: %lu, nbytes: %d\n",
321 ctx->op, req->nbytes);
322
323- clk_enable(dd->iclk);
324 if (!test_bit(FLAGS_INIT, &dd->dflags)) {
325 set_bit(FLAGS_INIT, &dd->dflags);
326 dd->err = 0;
327@@ -1272,13 +1270,15 @@ static int __devinit omap4_sham_probe(struct platform_device *pdev)
328 dd->irq = -1;
329
330 /* Get the base address */
331- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
332- if (!res) {
333- dev_err(dev, "no MEM resource info\n");
334- err = -ENODEV;
335- goto res_err;
336- }
337- dd->phys_base = res->start;
338+ //res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
339+ //if (!res) {
340+ // dev_err(dev, "no MEM resource info\n");
341+ // err = -ENODEV;
342+ // goto res_err;
343+ //}
344+
345+ //dd->phys_base = res->start;
346+ dd->phys_base = AM33XX_SHA1MD5_P_BASE;
347
348 /* Get the DMA */
349 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
350@@ -1308,13 +1308,10 @@ static int __devinit omap4_sham_probe(struct platform_device *pdev)
351 if (err)
352 goto dma_err;
353
354- /* Initializing the clock */
355- dd->iclk = clk_get(dev, "sha0_fck");
356- if (IS_ERR(dd->iclk)) {
357- dev_err(dev, "clock initialization failed.\n");
358- err = PTR_ERR(dd->iclk);
359- goto clk_err;
360- }
361+ pm_runtime_enable(dev);
362+ udelay(1);
363+ pm_runtime_get_sync(dev);
364+ udelay(1);
365
366 dd->io_base = ioremap(dd->phys_base, SZ_4K);
367 if (!dd->io_base) {
368@@ -1323,9 +1320,7 @@ static int __devinit omap4_sham_probe(struct platform_device *pdev)
369 goto io_err;
370 }
371
372- clk_enable(dd->iclk);
373 reg = omap4_sham_read(dd, SHA_REG_REV);
374- clk_disable(dd->iclk);
375
376 dev_info(dev, "AM33X SHA/MD5 hw accel rev: %u.%02u\n",
377 (reg & SHA_REG_REV_X_MAJOR_MASK) >> 8, reg & SHA_REG_REV_Y_MINOR_MASK);
378@@ -1349,7 +1344,11 @@ err_algs:
379 crypto_unregister_ahash(&algs[j]);
380 iounmap(dd->io_base);
381 io_err:
382- clk_put(dd->iclk);
383+ pm_runtime_put_sync(dev);
384+ udelay(1);
385+ pm_runtime_disable(dev);
386+ udelay(1);
387+
388 clk_err:
389 omap4_sham_dma_cleanup(dd);
390 dma_err:
391@@ -1379,7 +1378,11 @@ static int __devexit omap4_sham_remove(struct platform_device *pdev)
392 crypto_unregister_ahash(&algs[i]);
393 tasklet_kill(&dd->done_task);
394 iounmap(dd->io_base);
395- clk_put(dd->iclk);
396+ pm_runtime_put_sync(&pdev->dev);
397+ udelay(1);
398+ pm_runtime_disable(&pdev->dev);
399+ udelay(1);
400+
401 omap4_sham_dma_cleanup(dd);
402 if (dd->irq >= 0)
403 free_irq(dd->irq, dd);
404--
4051.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x-enable-pullup-on-the-WLAN-enable-pin-fo.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x-enable-pullup-on-the-WLAN-enable-pin-fo.patch
new file mode 100644
index 00000000..863fe378
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x-enable-pullup-on-the-WLAN-enable-pin-fo.patch
@@ -0,0 +1,57 @@
1From f69ffbef6793b7238a8518481735fd53326e0cdf Mon Sep 17 00:00:00 2001
2From: Vita Preskovsky <vitap@ti.com>
3Date: Tue, 24 Jul 2012 20:02:28 +0300
4Subject: [PATCH] am335x: enable pullup on the WLAN enable pin for keeping wlan
5
6 * Enable pullup on the WLAN enable pin for keeping wlan active
7 during suspend in wowlan mode. The fix is relevant only in the case
8 of am335x-SK board.
9
10
11Signed-off-by: Vita Preskovsky <vitap@ti.com>
12---
13 arch/arm/mach-omap2/board-am335xevm.c | 22 ++++++++++++++++++++++
14 1 files changed, 22 insertions(+), 0 deletions(-)
15
16diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c
17index f68710c..f263f84 100644
18--- a/arch/arm/mach-omap2/board-am335xevm.c
19+++ b/arch/arm/mach-omap2/board-am335xevm.c
20@@ -1673,13 +1673,35 @@ static void wl12xx_bluetooth_enable(void)
21 gpio_direction_output(am335xevm_wlan_data.bt_enable_gpio, 0);
22 }
23
24+#define AM33XX_CTRL_REGADDR(reg) \
25+ AM33XX_L4_WK_IO_ADDRESS(AM33XX_SCM_BASE + (reg))
26+
27+/* wlan enable pin */
28+#define AM33XX_CONTROL_PADCONF_GPMC_CSN0_OFFSET 0x087C
29 static int wl12xx_set_power(struct device *dev, int slot, int on, int vdd)
30 {
31+ int pad_mux_value;
32+
33 if (on) {
34 gpio_direction_output(am335xevm_wlan_data.wlan_enable_gpio, 1);
35+
36+ /* Enable pullup on the WLAN enable pin for keeping wlan active during suspend
37+ in wowlan mode */
38+ if ( am335x_evm_get_id() == EVM_SK ) {
39+ pad_mux_value = readl(AM33XX_CTRL_REGADDR(AM33XX_CONTROL_PADCONF_GPMC_CSN0_OFFSET));
40+ pad_mux_value &= (~AM33XX_PULL_DISA);
41+ writel(pad_mux_value, AM33XX_CTRL_REGADDR(AM33XX_CONTROL_PADCONF_GPMC_CSN0_OFFSET));
42+ }
43+
44 mdelay(70);
45 } else {
46 gpio_direction_output(am335xevm_wlan_data.wlan_enable_gpio, 0);
47+ /* Disable pullup on the WLAN enable when WLAN is off */
48+ if ( am335x_evm_get_id() == EVM_SK ) {
49+ pad_mux_value = readl(AM33XX_CTRL_REGADDR(AM33XX_CONTROL_PADCONF_GPMC_CSN0_OFFSET));
50+ pad_mux_value |= AM33XX_PULL_DISA;
51+ writel(pad_mux_value, AM33XX_CTRL_REGADDR(AM33XX_CONTROL_PADCONF_GPMC_CSN0_OFFSET));
52+ }
53 }
54
55 return 0;
56--
571.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x_evm_defconfig-turn-off-MUSB-DMA.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x_evm_defconfig-turn-off-MUSB-DMA.patch
new file mode 100644
index 00000000..6a32c2c3
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335x_evm_defconfig-turn-off-MUSB-DMA.patch
@@ -0,0 +1,35 @@
1From 95eca5a896c96d0af7188c97825a3b3ef5313ed3 Mon Sep 17 00:00:00 2001
2From: Chase Maupin <Chase.Maupin@ti.com>
3Date: Thu, 2 Feb 2012 16:38:51 -0600
4Subject: [PATCH] am335x_evm_defconfig: turn off MUSB DMA
5
6* Turn off the MUSB DMA in the am335x_evm_defconfig. This way
7 we can pull the default defconfig without enabling the
8 faulty USB DMA.
9
10Signed-off-by: Chase Maupin <Chase.Maupin@ti.com>
11---
12 arch/arm/configs/am335x_evm_defconfig | 6 +++---
13 1 files changed, 3 insertions(+), 3 deletions(-)
14
15diff --git a/arch/arm/configs/am335x_evm_defconfig b/arch/arm/configs/am335x_evm_defconfig
16index d105c61..121dc7f 100644
17--- a/arch/arm/configs/am335x_evm_defconfig
18+++ b/arch/arm/configs/am335x_evm_defconfig
19@@ -1982,11 +1982,11 @@ CONFIG_USB_MUSB_TI81XX_GLUE=y
20 CONFIG_USB_MUSB_TI81XX=y
21 # CONFIG_USB_MUSB_BLACKFIN is not set
22 # CONFIG_USB_MUSB_UX500 is not set
23-CONFIG_USB_TI_CPPI41_DMA_HW=y
24-# CONFIG_MUSB_PIO_ONLY is not set
25+# CONFIG_USB_TI_CPPI41_DMA_HW is not set
26+CONFIG_MUSB_PIO_ONLY=y
27 # CONFIG_USB_INVENTRA_DMA is not set
28 # CONFIG_USB_TI_CPPI_DMA is not set
29-CONFIG_USB_TI_CPPI41_DMA=y
30+# CONFIG_USB_TI_CPPI41_DMA is not set
31 # CONFIG_USB_TUSB_OMAP_DMA is not set
32 # CONFIG_USB_UX500_DMA is not set
33 # CONFIG_USB_RENESAS_USBHS is not set
34--
351.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335xevm-using-edge-triggered-interrupts-for-WLAN.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335xevm-using-edge-triggered-interrupts-for-WLAN.patch
new file mode 100644
index 00000000..98b3a311
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am335xevm-using-edge-triggered-interrupts-for-WLAN.patch
@@ -0,0 +1,35 @@
1From be52bac69dfe6a56276b16ccd234970c4f7b1255 Mon Sep 17 00:00:00 2001
2From: Vita Preskovsky <vitap@ti.com>
3Date: Wed, 18 Jul 2012 16:20:36 +0300
4Subject: [PATCH] am335xevm: using edge triggered interrupts for WLAN
5
6 *using edge triggered interrupts instead of default level triggered in
7 all platforms supporting WLAN. This reduces CPU cycles and possibility
8 for missed interrupts.
9
10
11Signed-off-by: Vita Preskovsky <vitap@ti.com>
12---
13 arch/arm/mach-omap2/board-am335xevm.c | 3 +--
14 1 files changed, 1 insertions(+), 2 deletions(-)
15
16diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c
17index 6ae4e68..ac005c8 100644
18--- a/arch/arm/mach-omap2/board-am335xevm.c
19+++ b/arch/arm/mach-omap2/board-am335xevm.c
20@@ -1679,12 +1679,11 @@ static void wl12xx_init(int evm_id, int profile)
21 am335xevm_wlan_data.bt_enable_gpio = GPIO_TO_PIN(3, 21);
22 am335xevm_wlan_data.irq =
23 OMAP_GPIO_IRQ(AM335XEVM_SK_WLAN_IRQ_GPIO);
24- am335xevm_wlan_data.platform_quirks =
25- WL12XX_PLATFORM_QUIRK_EDGE_IRQ;
26 setup_pin_mux(wl12xx_pin_mux_sk);
27 } else {
28 setup_pin_mux(wl12xx_pin_mux);
29 }
30+ am335xevm_wlan_data.platform_quirks = WL12XX_PLATFORM_QUIRK_EDGE_IRQ;
31 wl12xx_bluetooth_enable();
32
33 if (wl12xx_set_platform_data(&am335xevm_wlan_data))
34--
351.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am33x-Add-memory-addresses-for-crypto-modules.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am33x-Add-memory-addresses-for-crypto-modules.patch
new file mode 100644
index 00000000..f92a7fc6
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am33x-Add-memory-addresses-for-crypto-modules.patch
@@ -0,0 +1,41 @@
1From 5f2f17a488aba4319b537aed040ea13607af128b Mon Sep 17 00:00:00 2001
2From: Greg Turner <gregturner@ti.com>
3Date: Thu, 17 May 2012 14:25:40 -0500
4Subject: [PATCH 1/8] am33x: Add memory addresses for crypto modules
5
6* Add base memory addresses to the am33xx.h header file
7
8These addresses are for the HW crypto modules including TRNG, AES, and SHA/MD5
9
10Signed-off-by: Greg Turner <gregturner@ti.com>
11---
12 arch/arm/plat-omap/include/plat/am33xx.h | 11 +++++++++++
13 1 files changed, 11 insertions(+), 0 deletions(-)
14 mode change 100644 => 100755 arch/arm/plat-omap/include/plat/am33xx.h
15
16diff --git a/arch/arm/plat-omap/include/plat/am33xx.h b/arch/arm/plat-omap/include/plat/am33xx.h
17old mode 100644
18new mode 100755
19index a16e72c..96ab1c3
20--- a/arch/arm/plat-omap/include/plat/am33xx.h
21+++ b/arch/arm/plat-omap/include/plat/am33xx.h
22@@ -65,6 +65,17 @@
23
24 #define AM33XX_ELM_BASE 0x48080000
25
26+/* Base address for crypto modules */
27+#define AM33XX_SHA1MD5_S_BASE 0x53000000
28+#define AM33XX_SHA1MD5_P_BASE 0x53100000
29+
30+#define AM33XX_AES0_S_BASE 0x53400000
31+#define AM33XX_AES0_P_BASE 0x53500000
32+#define AM33XX_AES1_S_BASE 0x53600000
33+#define AM33XX_AES1_P_BASE 0x53700000
34+
35+#define AM33XX_RNG_BASE 0x48310000
36+
37 #define AM33XX_ASP0_BASE 0x48038000
38 #define AM33XX_ASP1_BASE 0x4803C000
39
40--
411.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am33xx-Add-SmartReflex-support.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am33xx-Add-SmartReflex-support.patch
new file mode 100644
index 00000000..a17f62cc
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-am33xx-Add-SmartReflex-support.patch
@@ -0,0 +1,2014 @@
1From 35ae6b61d349e5b4efd1c6337a0d1e23b6e86899 Mon Sep 17 00:00:00 2001
2From: Greg Guyotte <gguyotte@ti.com>
3Date: Thu, 7 Jun 2012 18:05:31 -0500
4Subject: [PATCH] am33xx: Add SmartReflex support.
5
6This patch introduces SmartReflex support to AM33XX devices. The
7purpose of SmartReflex is to optimize (lower) voltage based upon
8silicon process and temperature.
9
10The SmartReflex driver requires the silicon to be programmed with
11"nTarget" EFUSE values. If the values are not present (as with
12pre-RTP samples), the driver will simply fail to load and kernel
13boot will continue normally.
14
15The SR driver logs several items in the debugfs at /debug/smartreflex.
16To disable SmartReflex, use the command 'echo 0 > /debug/smartreflex/autocomp'.
17The node /debug/smartreflex/smartreflex0 gives information about
18the CORE voltage domain, and /smartreflex1 is related to the MPU voltage
19domain.
20
21To determine the effectiveness of SmartReflex, you can compare the
22initial voltage with the current voltage for a given OPP. For example,
23'cat /debug/smartreflex/smartreflex1/current_voltage' gives the current
24MPU voltage. Comparing that with 'cat /debug/smartreflex/smartreflex1/
25initial_voltage' will show you the voltage drop associated with SR
26operation.
27
28Signed-off-by: Greg Guyotte <gguyotte@ti.com>
29---
30 arch/arm/mach-omap2/Makefile | 1 +
31 arch/arm/mach-omap2/am33xx-smartreflex-class2.c | 1055 ++++++++++++++++++++
32 arch/arm/mach-omap2/board-am335xevm.c | 7 +
33 arch/arm/mach-omap2/devices.c | 269 +++++
34 arch/arm/mach-omap2/include/mach/board-am335xevm.h | 1 +
35 arch/arm/plat-omap/Kconfig | 21 +
36 arch/arm/plat-omap/include/plat/am33xx.h | 3 +
37 arch/arm/plat-omap/include/plat/smartreflex.h | 431 ++++++++
38 drivers/regulator/core.c | 4 +
39 include/linux/regulator/driver.h | 2 +-
40 include/linux/regulator/machine.h | 3 +-
41 11 files changed, 1795 insertions(+), 2 deletions(-)
42 create mode 100644 arch/arm/mach-omap2/am33xx-smartreflex-class2.c
43 create mode 100644 arch/arm/plat-omap/include/plat/smartreflex.h
44
45diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
46index f275e74..c01b62d 100644
47--- a/arch/arm/mach-omap2/Makefile
48+++ b/arch/arm/mach-omap2/Makefile
49@@ -73,6 +73,7 @@ obj-$(CONFIG_SOC_OMAPAM33XX) += cpuidle33xx.o pm33xx.o \
50 obj-$(CONFIG_PM_DEBUG) += pm-debug.o
51 obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
52 obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
53+obj-$(CONFIG_AM33XX_SMARTREFLEX) += am33xx-smartreflex-class2.o
54
55 AFLAGS_sleep24xx.o :=-Wa,-march=armv6
56 AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec)
57diff --git a/arch/arm/mach-omap2/am33xx-smartreflex-class2.c b/arch/arm/mach-omap2/am33xx-smartreflex-class2.c
58new file mode 100644
59index 0000000..66f98b7
60--- /dev/null
61+++ b/arch/arm/mach-omap2/am33xx-smartreflex-class2.c
62@@ -0,0 +1,1055 @@
63+/*
64+ * SmartReflex Voltage Control driver
65+ *
66+ * Copyright (C) 2012 Texas Instruments, Inc. - http://www.ti.com/
67+ * Author: Greg Guyotte <gguyotte@ti.com> (modified for AM33xx)
68+ *
69+ * Copyright (C) 2011 Texas Instruments, Inc. - http://www.ti.com/
70+ * Author: AnilKumar Ch <anilkumar@ti.com>
71+ *
72+ * This program is free software; you can redistribute it and/or
73+ * modify it under the terms of the GNU General Public License as
74+ * published by the Free Software Foundation version 2.
75+ *
76+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
77+ * kind, whether express or implied; without even the implied warranty
78+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
79+ * GNU General Public License for more details.
80+ */
81+
82+#include <linux/kernel.h>
83+#include <linux/init.h>
84+#include <linux/module.h>
85+#include <linux/interrupt.h>
86+#include <linux/clk.h>
87+#include <linux/io.h>
88+#include <linux/debugfs.h>
89+#include <linux/slab.h>
90+#include <linux/regulator/consumer.h>
91+#include <linux/cpufreq.h>
92+#include <linux/opp.h>
93+
94+#include <plat/common.h>
95+#include <plat/smartreflex.h>
96+
97+#include "control.h"
98+#include "voltage.h"
99+
100+#define CLK_NAME_LEN 40
101+
102+static inline void sr_write_reg(struct am33xx_sr *sr, int offset, u32 value,
103+ u32 srid)
104+{
105+ writel(value, sr->sen[srid].base + offset);
106+}
107+
108+static inline void sr_modify_reg(struct am33xx_sr *sr, int offset, u32 mask,
109+ u32 value, u32 srid)
110+{
111+ u32 reg_val;
112+
113+ reg_val = readl(sr->sen[srid].base + offset);
114+ reg_val &= ~mask;
115+ reg_val |= (value&mask);
116+
117+ writel(reg_val, sr->sen[srid].base + offset);
118+}
119+
120+static inline u32 sr_read_reg(struct am33xx_sr *sr, int offset, u32 srid)
121+{
122+ return readl(sr->sen[srid].base + offset);
123+}
124+
125+static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen) {
126+ u32 gn, rn, mul;
127+
128+ for (gn = 0; gn < GAIN_MAXLIMIT; gn++) {
129+ mul = 1 << (gn + 8);
130+ rn = mul / sensor;
131+ if (rn < R_MAXLIMIT) {
132+ *sengain = gn;
133+ *rnsen = rn;
134+ }
135+ }
136+}
137+
138+static u32 cal_test_nvalue(u32 sennval, u32 senpval) {
139+ u32 senpgain=0, senngain=0;
140+ u32 rnsenp=0, rnsenn=0;
141+
142+ /* Calculating the gain and reciprocal of the SenN and SenP values */
143+ cal_reciprocal(senpval, &senpgain, &rnsenp);
144+ cal_reciprocal(sennval, &senngain, &rnsenn);
145+
146+ return (senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
147+ (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
148+ (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
149+ (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT);
150+}
151+
152+static unsigned int sr_adjust_efuse_nvalue(unsigned int opp_no,
153+ unsigned int orig_opp_nvalue,
154+ unsigned int mv_delta) {
155+ unsigned int new_opp_nvalue;
156+ unsigned int senp_gain, senn_gain, rnsenp, rnsenn, pnt_delta, nnt_delta;
157+ unsigned int new_senn, new_senp, senn, senp;
158+
159+ /* calculate SenN and SenP from the efuse value */
160+ senp_gain = ((orig_opp_nvalue >> 20) & 0xf);
161+ senn_gain = ((orig_opp_nvalue >> 16) & 0xf);
162+ rnsenp = ((orig_opp_nvalue >> 8) & 0xff);
163+ rnsenn = (orig_opp_nvalue & 0xff);
164+
165+ senp = ((1<<(senp_gain+8))/(rnsenp));
166+ senn = ((1<<(senn_gain+8))/(rnsenn));
167+
168+ /* calculate the voltage delta */
169+ pnt_delta = (26 * mv_delta)/10;
170+ nnt_delta = (3 * mv_delta);
171+
172+ /* now lets add the voltage delta to the sensor values */
173+ new_senn = senn + nnt_delta;
174+ new_senp = senp + pnt_delta;
175+
176+ new_opp_nvalue = cal_test_nvalue(new_senn, new_senp);
177+
178+ printk("Compensating OPP%d for %dmV Orig nvalue:0x%x New nvalue:0x%x \n",
179+ opp_no, mv_delta, orig_opp_nvalue, new_opp_nvalue);
180+
181+ return new_opp_nvalue;
182+}
183+
184+/* irq_sr_reenable - Re-enable SR interrupts (triggered by delayed work queue)
185+ * @work: pointer to work_struct embedded in am33xx_sr_sensor struct
186+ *
187+ * While servicing the IRQ, this function is added to the delayed work queue.
188+ * This gives time for the voltage change to settle before we re-enable
189+ * the interrupt.
190+ */
191+static void irq_sr_reenable(struct work_struct *work)
192+{
193+ u32 srid;
194+ struct am33xx_sr_sensor *sens;
195+ struct am33xx_sr *sr;
196+
197+ sens = container_of((void *)work, struct am33xx_sr_sensor,
198+ work_reenable);
199+
200+ srid = sens->sr_id;
201+
202+ sr = container_of((void *)sens, struct am33xx_sr, sen[srid]);
203+
204+ dev_dbg(&sr->pdev->dev, "%s: SR %d\n", __func__, srid);
205+
206+ /* Must clear IRQ status */
207+ sens->irq_status = 0;
208+
209+ /* Re-enable the interrupt */
210+ sr_modify_reg(sr, IRQENABLE_SET, IRQENABLE_MCUBOUNDSINT,
211+ IRQENABLE_MCUBOUNDSINT, srid);
212+
213+ /* Restart the module after voltage set */
214+ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE,
215+ SRCONFIG_SRENABLE, srid);
216+}
217+
218+/* get_errvolt - get error voltage from SR error register
219+ * @sr: contains SR driver data
220+ * @srid: contains the srid, indicates which SR moduel lswe are using
221+ *
222+ * Read the error from SENSOR error register and then convert
223+ * to voltage delta, return value is the voltage delta in micro
224+ * volt.
225+ */
226+static int get_errvolt(struct am33xx_sr *sr, s32 srid)
227+{
228+ struct am33xx_sr_sensor *sens;
229+ int senerror_reg;
230+ s32 uvoltage;
231+ s8 terror;
232+
233+ sens = &sr->sen[srid];
234+
235+ senerror_reg = sr_read_reg(sr, SENERROR_V2, srid);
236+ senerror_reg = (senerror_reg & 0x0000FF00);
237+ terror = (s8)(senerror_reg >> 8);
238+
239+ /* math defined in SR functional spec */
240+ uvoltage = ((terror) * sr->uvoltage_step_size) >> 7;
241+ uvoltage = uvoltage * sens->opp_data[sens->curr_opp].e2v_gain;
242+
243+ return uvoltage;
244+}
245+
246+/* set_voltage - Schedule task for setting the voltage
247+ * @work: pointer to the work structure
248+ *
249+ * Voltage is set based on previous voltage and calculated
250+ * voltage error.
251+ *
252+ * Generic voltage regulator set voltage is used for changing
253+ * the voltage to new value. Could potentially use voltdm_scale
254+ * but at time of testing voltdm was not populated with volt_data.
255+ *
256+ * Disabling the module before changing the voltage, this is
257+ * needed for not generating interrupt during voltage change,
258+ * enabling after voltage change. This will also take care of
259+ * resetting the SR registers.
260+ */
261+static void set_voltage(struct work_struct *work)
262+{
263+ struct am33xx_sr *sr;
264+ int prev_volt, new_volt, i, ret;
265+ s32 delta_v;
266+
267+ sr = container_of((void *)work, struct am33xx_sr, work);
268+
269+ for (i = 0; i < sr->no_of_sens; i++) {
270+ if (sr->sen[i].irq_status != 1)
271+ continue;
272+
273+ /* Get the current voltage from PMIC */
274+ prev_volt = regulator_get_voltage(sr->sen[i].reg);
275+
276+ if (prev_volt < 0) {
277+ dev_err(&sr->pdev->dev,
278+ "%s: SR %d: regulator_get_voltage error %d\n",
279+ __func__, i, prev_volt);
280+
281+ goto reenable;
282+ }
283+
284+ delta_v = get_errvolt(sr, i);
285+ new_volt = prev_volt + delta_v;
286+
287+ /* this is the primary output for debugging SR activity */
288+ dev_dbg(&sr->pdev->dev,
289+ "%s: SR %d: prev volt=%d, delta_v=%d, req_volt=%d\n",
290+ __func__, i, prev_volt, delta_v, new_volt);
291+
292+ /* Clear the counter, SR module disable */
293+ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE,
294+ ~SRCONFIG_SRENABLE, i);
295+
296+ if (delta_v != 0) {
297+ ret = regulator_set_voltage(sr->sen[i].reg, new_volt,
298+ new_volt + sr->uvoltage_step_size);
299+
300+ if (ret < 0)
301+ dev_err(&sr->pdev->dev,
302+ "%s: regulator_set_voltage failed! (err %d)\n",
303+ __func__, ret);
304+ }
305+reenable:
306+ /* allow time for voltage to settle before re-enabling SR
307+ module and interrupt */
308+ schedule_delayed_work(&sr->sen[i].work_reenable,
309+ msecs_to_jiffies(sr->irq_delay));
310+ }
311+}
312+
313+/* sr_class2_irq - sr irq handling
314+ * @irq: Number of the irq serviced
315+ * @data: data contains the SR driver structure
316+ *
317+ * Smartreflex IRQ handling for class2 IP, once the IRQ handler
318+ * is here then disable the interrupt and re-enable after some
319+ * time. This is the work around for handling both interrupts,
320+ * while one got satisfied with the voltage change but not the
321+ * other. The same logic helps the case where PMIC cannot set
322+ * the exact voltage requested by SR IP
323+ *
324+ * Schedule work only if both interrupts are serviced
325+ *
326+ * Note that same irq handler is used for both the interrupts,
327+ * needed for decision making for voltage change
328+ */
329+static irqreturn_t sr_class2_irq(int irq, void *data)
330+{
331+ u32 srid;
332+ struct am33xx_sr *sr;
333+ struct am33xx_sr_sensor *sr_sensor = (struct am33xx_sr_sensor *)data;
334+
335+ srid = sr_sensor->sr_id;
336+
337+ sr = container_of(data, struct am33xx_sr, sen[srid]);
338+
339+ sr->sen[srid].irq_status = 1;
340+
341+ /* Clear MCUBounds Interrupt */
342+ sr_modify_reg(sr, IRQSTATUS, IRQSTATUS_MCBOUNDSINT,
343+ IRQSTATUS_MCBOUNDSINT, srid);
344+
345+ /* Disable the interrupt and re-enable in set_voltage() */
346+ sr_modify_reg(sr, IRQENABLE_CLR, IRQENABLE_MCUBOUNDSINT,
347+ IRQENABLE_MCUBOUNDSINT, srid);
348+
349+ /* Causes set_voltage() to get called at a later time. Set_voltage()
350+ will check the irq_status flags to determine which SR needs to
351+ be serviced. This was previously done with schedule_work, but
352+ I observed a crash in set_voltage() when changing OPPs on weak
353+ silicon, which may have been related to insufficient voltage
354+ settling time for OPP change. This additional delay avoids the
355+ crash. */
356+ schedule_delayed_work(&sr->work,
357+ msecs_to_jiffies(250));
358+
359+ return IRQ_HANDLED;
360+}
361+
362+static int sr_clk_enable(struct am33xx_sr *sr, u32 srid)
363+{
364+ if (clk_enable(sr->sen[srid].fck) != 0) {
365+ dev_err(&sr->pdev->dev, "%s: Could not enable sr_fck\n",
366+ __func__);
367+ return -EINVAL;
368+ }
369+
370+ return 0;
371+}
372+
373+static int sr_clk_disable(struct am33xx_sr *sr, u32 srid)
374+{
375+ clk_disable(sr->sen[srid].fck);
376+
377+ return 0;
378+}
379+
380+static inline int sr_set_nvalues(struct am33xx_sr *sr, u32 srid)
381+{
382+ int i;
383+ struct am33xx_sr_sensor *sens = &sr->sen[srid];
384+
385+ for (i = 0; i < sens->no_of_opps; i++) {
386+ /* Read nTarget value form EFUSE register*/
387+ sens->opp_data[i].nvalue = readl(AM33XX_CTRL_REGADDR
388+ (sens->opp_data[i].efuse_offs)) & 0xFFFFFF;
389+
390+ /* validate nTarget value */
391+ if (sens->opp_data[i].nvalue == 0)
392+ return -EINVAL;
393+
394+ /* adjust nTarget based on margin in mv */
395+ sens->opp_data[i].adj_nvalue = sr_adjust_efuse_nvalue(i,
396+ sens->opp_data[i].nvalue,
397+ sens->opp_data[i].margin);
398+
399+ dev_dbg(&sr->pdev->dev,
400+ "NValueReciprocal value (from efuse) = %08x\n",
401+ sens->opp_data[i].nvalue);
402+
403+ dev_dbg(&sr->pdev->dev,
404+ "Adjusted NValueReciprocal value = %08x\n",
405+ sens->opp_data[i].adj_nvalue);
406+ }
407+ return 0;
408+}
409+
410+/* sr_configure - Configure SR module to work in Error generator mode
411+ * @sr: contains SR driver data
412+ * @srid: contains the srid, specify whether it is CORE or MPU
413+ *
414+ * Configure the corresponding values to SR module registers for
415+ * operating SR module in Error Generator mode.
416+ */
417+static void sr_configure(struct am33xx_sr *sr, u32 srid)
418+{
419+ struct am33xx_sr_sensor *sens = &sr->sen[srid];
420+
421+ /* Configuring the SR module with clock length, enabling the
422+ * error generator, enable SR module, enable individual N and P
423+ * sensors
424+ */
425+ sr_write_reg(sr, SRCONFIG, (SRCLKLENGTH_125MHZ_SYSCLK |
426+ SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
427+ (sens->senn_en << SRCONFIG_SENNENABLE_V2_SHIFT) |
428+ (sens->senp_en << SRCONFIG_SENPENABLE_V2_SHIFT)),
429+ srid);
430+
431+ /* Configuring the Error Generator */
432+ sr_modify_reg(sr, ERRCONFIG_V2, (SR_ERRWEIGHT_MASK |
433+ SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
434+ ((sens->opp_data[sens->curr_opp].err_weight <<
435+ ERRCONFIG_ERRWEIGHT_SHIFT) |
436+ (sens->opp_data[sens->curr_opp].err_maxlimit <<
437+ ERRCONFIG_ERRMAXLIMIT_SHIFT) |
438+ (sens->opp_data[sens->curr_opp].err_minlimit <<
439+ ERRCONFIG_ERRMINLIMIT_SHIFT)),
440+ srid);
441+}
442+
443+/* sr_enable - Enable SR module
444+ * @sr: contains SR driver data
445+ * @srid: contains the srid, specify whether it is CORE or MPU
446+ *
447+ * Enable SR module by writing nTarget values to corresponding SR
448+ * NVALUERECIPROCAL register, enable the interrupt and enable SR
449+ */
450+static void sr_enable(struct am33xx_sr *sr, u32 srid)
451+{
452+ struct am33xx_sr_sensor *sens;
453+
454+ sens = &sr->sen[srid];
455+
456+ /* Check if SR is already enabled. If yes do nothing */
457+ if (sr_read_reg(sr, SRCONFIG, srid) & SRCONFIG_SRENABLE)
458+ return;
459+
460+ if (sens->opp_data[sens->curr_opp].nvalue == 0)
461+ dev_err(&sr->pdev->dev,
462+ "%s: OPP doesn't support SmartReflex\n", __func__);
463+
464+ /* Writing the nReciprocal value to the register */
465+ sr_write_reg(sr, NVALUERECIPROCAL,
466+ sens->opp_data[sens->curr_opp].adj_nvalue, srid);
467+
468+ /* Enable the interrupt */
469+ sr_modify_reg(sr, IRQENABLE_SET, IRQENABLE_MCUBOUNDSINT,
470+ IRQENABLE_MCUBOUNDSINT, srid);
471+
472+ /* SRCONFIG - enable SR */
473+ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE,
474+ SRCONFIG_SRENABLE, srid);
475+}
476+
477+/* sr_disable - Disable SR module
478+ * @sr: contains SR driver data
479+ * @srid: contains the srid, specify whether it is CORE or MPU
480+ *
481+ * Disable SR module by disabling the interrupt and Smartreflex module
482+ */
483+static void sr_disable(struct am33xx_sr *sr, u32 srid)
484+{
485+ /* Disable the interrupt */
486+ sr_modify_reg(sr, IRQENABLE_CLR, IRQENABLE_MCUBOUNDSINT,
487+ IRQENABLE_MCUBOUNDSINT, srid);
488+
489+ /* SRCONFIG - disable SR */
490+ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE,
491+ ~SRCONFIG_SRENABLE, srid);
492+}
493+
494+/* sr_start_vddautocomp - Start VDD auto compensation
495+ * @sr: contains SR driver data
496+ *
497+ * This is the starting point for AVS enable from user space.
498+ * Also used to re-enable SR after OPP change.
499+ */
500+static void sr_start_vddautocomp(struct am33xx_sr *sr)
501+{
502+ int i;
503+
504+ if ((sr->sen[SR_CORE].opp_data[0].nvalue == 0) ||
505+ (sr->sen[SR_MPU].opp_data[0].nvalue == 0)) {
506+ dev_err(&sr->pdev->dev, "SR module not enabled, nTarget"
507+ " values are not found\n");
508+ return;
509+ }
510+
511+ if (sr->autocomp_active == 1) {
512+ dev_warn(&sr->pdev->dev, "SR VDD autocomp already active\n");
513+ return;
514+ }
515+
516+ for (i = 0; i < sr->no_of_sens; i++) {
517+ /* Read current regulator value and voltage */
518+ sr->sen[i].init_volt_mv = regulator_get_voltage(sr->sen[i].reg);
519+
520+ dev_dbg(&sr->pdev->dev, "%s: regulator %d, init_volt = %d\n",
521+ __func__, i, sr->sen[i].init_volt_mv);
522+
523+ if (sr_clk_enable(sr, i))
524+ return;
525+ sr_configure(sr, i);
526+ sr_enable(sr, i);
527+ }
528+
529+ sr->autocomp_active = 1;
530+}
531+
532+/* sr_stop_vddautocomp - Stop VDD auto compensation
533+ * @sr: contains SR driver data
534+ *
535+ * This is the ending point during SR disable from user space.
536+ * Also used to disable SR after OPP change.
537+ */
538+static void sr_stop_vddautocomp(struct am33xx_sr *sr)
539+{
540+ int i;
541+
542+ if (sr->autocomp_active == 0) {
543+ dev_warn(&sr->pdev->dev, "SR VDD autocomp is not active\n");
544+ return;
545+ }
546+
547+ /* cancel bottom half interrupt handlers that haven't run yet */
548+ cancel_delayed_work_sync(&sr->work);
549+
550+ for (i = 0; i < sr->no_of_sens; i++) {
551+ /* cancel any outstanding SR IRQ re-enables on work queue */
552+ cancel_delayed_work_sync(&sr->sen[i].work_reenable);
553+ sr_disable(sr, i);
554+ sr_clk_disable(sr, i);
555+ }
556+
557+ sr->autocomp_active = 0;
558+}
559+
560+/* am33xx_sr_autocomp_show - Store user input value and stop SR
561+ * @data: contains SR driver data
562+ * @val: pointer to store autocomp_active status
563+ *
564+ * This is the Debug Fs enteries to show whether SR is enabled
565+ * or disabled
566+ */
567+static int am33xx_sr_autocomp_show(void *data, u64 *val)
568+{
569+ struct am33xx_sr *sr_info = (struct am33xx_sr *) data;
570+
571+ *val = (u64) sr_info->autocomp_active;
572+
573+ return 0;
574+}
575+
576+static int am33xx_sr_margin_show(void *data, u64 *val)
577+{
578+ struct am33xx_sr_opp_data *sr_opp_data = (struct am33xx_sr_opp_data *)data;
579+
580+ *val = (u64) sr_opp_data->margin;
581+
582+ return 0;
583+}
584+
585+static int am33xx_sr_margin_update(void *data, u64 val)
586+{
587+ struct am33xx_sr_opp_data *sr_opp_data =
588+ (struct am33xx_sr_opp_data *)data;
589+ struct am33xx_sr_sensor *sr_sensor;
590+ struct am33xx_sr *sr_info;
591+
592+ /* work back to the sr_info pointer */
593+ sr_sensor = container_of((void *)sr_opp_data, struct am33xx_sr_sensor,
594+ opp_data[sr_opp_data->opp_id]);
595+
596+ sr_info = container_of((void *)sr_sensor, struct am33xx_sr,
597+ sen[sr_sensor->sr_id]);
598+
599+ /* store the value of margin */
600+ sr_opp_data->margin = (s32)val;
601+
602+ dev_warn(&sr_info->pdev->dev, "%s: new margin=%d, srid=%d, opp=%d\n",
603+ __func__, sr_opp_data->margin, sr_sensor->sr_id,
604+ sr_opp_data->opp_id);
605+
606+ /* updata ntarget values based upon new margin */
607+ if (sr_set_nvalues(sr_info, sr_sensor->sr_id) == -EINVAL)
608+ dev_err(&sr_info->pdev->dev,
609+ "%s: Zero NValue read from EFUSE\n", __func__);
610+
611+ /* restart SmartReflex to adapt to new values */
612+ sr_stop_vddautocomp(sr_info);
613+ sr_start_vddautocomp(sr_info);
614+
615+ return 0;
616+}
617+
618+/* am33xx_sr_autocomp_store - Store user input and start SR
619+ * @data: contains SR driver data
620+ * @val: contains the value pased by user
621+ *
622+ * This is the Debug Fs enteries to store user input and
623+ * enable smartreflex.
624+ */
625+static int am33xx_sr_autocomp_store(void *data, u64 val)
626+{
627+ struct am33xx_sr *sr_info = (struct am33xx_sr *) data;
628+
629+ /* Sanity check */
630+ if (val && (val != 1)) {
631+ dev_warn(&sr_info->pdev->dev, "%s: Invalid argument %llu\n",
632+ __func__, val);
633+ return -EINVAL;
634+ }
635+
636+ if (!val) {
637+ sr_info->disabled_by_user = 1;
638+ sr_stop_vddautocomp(sr_info);
639+ }
640+ else {
641+ sr_info->disabled_by_user = 0;
642+ sr_start_vddautocomp(sr_info);
643+ }
644+
645+ return 0;
646+}
647+
648+DEFINE_SIMPLE_ATTRIBUTE(sr_fops, am33xx_sr_autocomp_show,
649+ am33xx_sr_autocomp_store, "%llu\n");
650+
651+/* sr_curr_volt_show - Show current voltage value
652+ * @data: contains SR driver data
653+ * @val: pointer to store current voltage value
654+ *
655+ * Read the current voltage value and display the same on console
656+ * This is used in debugfs entries
657+ */
658+static int am33xx_sr_curr_volt_show(void *data, u64 *val)
659+{
660+ struct am33xx_sr_sensor *sr_sensor = (struct am33xx_sr_sensor *) data;
661+
662+ *val = (u64) regulator_get_voltage(sr_sensor->reg);
663+
664+ return 0;
665+}
666+
667+DEFINE_SIMPLE_ATTRIBUTE(curr_volt_fops, am33xx_sr_curr_volt_show,
668+ NULL, "%llu\n");
669+
670+DEFINE_SIMPLE_ATTRIBUTE(margin_fops, am33xx_sr_margin_show,
671+ am33xx_sr_margin_update, "%llu\n");
672+
673+#ifdef CONFIG_DEBUG_FS
674+/* sr_debugfs_entries - Create debugfs entries
675+ * @sr_info: contains SR driver data
676+ *
677+ * Create debugfs entries, which is exposed to user for knowing
678+ * the current status. Some of the parameters can change during
679+ * run time
680+ */
681+static int sr_debugfs_entries(struct am33xx_sr *sr_info)
682+{
683+ struct am33xx_sr_sensor *sens;
684+ struct dentry *dbg_dir, *sen_dir, *opp_dir;
685+ int i, j;
686+
687+ dbg_dir = debugfs_create_dir("smartreflex", NULL);
688+ if (IS_ERR(dbg_dir)) {
689+ dev_err(&sr_info->pdev->dev, "%s: Unable to create debugfs"
690+ " directory\n", __func__);
691+ return PTR_ERR(dbg_dir);
692+ }
693+
694+ (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUGO, dbg_dir,
695+ (void *)sr_info, &sr_fops);
696+ (void) debugfs_create_u32("interrupt_delay", S_IRUGO | S_IWUGO,
697+ dbg_dir, &sr_info->irq_delay);
698+
699+ for (i = 0; i < sr_info->no_of_sens; i++) {
700+ sens = &sr_info->sen[i];
701+ sen_dir = debugfs_create_dir(sens->name, dbg_dir);
702+ if (IS_ERR(sen_dir)) {
703+ dev_err(&sr_info->pdev->dev, "%s: Unable to create"
704+ " debugfs directory\n", __func__);
705+ return PTR_ERR(sen_dir);
706+ }
707+
708+ (void)debugfs_create_u32("initial_voltage", S_IRUGO, sen_dir,
709+ &sens->init_volt_mv);
710+ (void)debugfs_create_file("current_voltage", S_IRUGO, sen_dir,
711+ (void *)sens, &curr_volt_fops);
712+
713+ for (j = 0; j < sr_info->sen[i].no_of_opps; j++) {
714+ char tmp[20];
715+
716+ sprintf(&tmp[0], "opp%d", j);
717+ opp_dir = debugfs_create_dir(tmp, sen_dir);
718+ if (IS_ERR(opp_dir)) {
719+ dev_err(&sr_info->pdev->dev,
720+ "%s: Unable to create debugfs directory\n",
721+ __func__);
722+ return PTR_ERR(opp_dir);
723+ }
724+
725+ (void)debugfs_create_file("margin", S_IRUGO | S_IWUGO,
726+ opp_dir, (void *)&sens->opp_data[j],
727+ &margin_fops);
728+ (void)debugfs_create_x32("err2voltgain",
729+ S_IRUGO | S_IWUGO,
730+ opp_dir,
731+ &sens->opp_data[j].e2v_gain);
732+ (void)debugfs_create_x32("nvalue", S_IRUGO,
733+ opp_dir,
734+ &sens->opp_data[j].nvalue);
735+ (void)debugfs_create_x32("adj_nvalue", S_IRUGO,
736+ opp_dir,
737+ &sens->opp_data[j].adj_nvalue);
738+ }
739+ }
740+ return 0;
741+}
742+#else
743+static int sr_debugfs_entries(struct am33xx_sr *sr_info)
744+{
745+ return 0;
746+}
747+#endif
748+
749+#ifdef CONFIG_CPU_FREQ
750+
751+/* Find and return current OPP. This should change to use system APIs,
752+ but voltdm is not currently populated, and opp APIs are also not working. */
753+static int get_current_opp(struct am33xx_sr *sr, u32 srid, u32 freq) {
754+ int i;
755+
756+ for (i = 0; i < sr->sen[srid].no_of_opps; i++) {
757+ if (sr->sen[srid].opp_data[i].frequency == freq)
758+ return i;
759+ }
760+
761+ return -EINVAL;
762+}
763+
764+static int am33xx_sr_cpufreq_transition(struct notifier_block *nb,
765+ unsigned long val, void *data)
766+{
767+ struct am33xx_sr *sr;
768+ struct cpufreq_freqs *cpu;
769+
770+ sr = container_of(nb, struct am33xx_sr, freq_transition);
771+
772+ /* We are required to disable SR while OPP change is occurring */
773+ if (val == CPUFREQ_PRECHANGE) {
774+ dev_dbg(&sr->pdev->dev, "%s: prechange\n", __func__);
775+ sr_stop_vddautocomp(sr);
776+ } else if (val == CPUFREQ_POSTCHANGE) {
777+ cpu = (struct cpufreq_freqs *)data;
778+ dev_dbg(&sr->pdev->dev,
779+ "%s: postchange, cpu=%d, old=%d, new=%d\n",
780+ __func__, cpu->cpu, cpu->old, cpu->new);
781+
782+ /* update current OPP */
783+ sr->sen[SR_MPU].curr_opp = get_current_opp(sr, SR_MPU,
784+ cpu->new*1000);
785+ if (sr->sen[SR_MPU].curr_opp == -EINVAL) {
786+ dev_err(&sr->pdev->dev, "%s: cannot determine opp\n",
787+ __func__);
788+ return -EINVAL;
789+ }
790+
791+ dev_dbg(&sr->pdev->dev, "%s: postchange, new opp=%d\n",
792+ __func__, sr->sen[SR_MPU].curr_opp);
793+
794+ /* this handles the case when the user has disabled SR via
795+ debugfs, therefore we do not want to enable SR */
796+ if (sr->disabled_by_user == 0)
797+ sr_start_vddautocomp(sr);
798+ }
799+
800+ return 0;
801+}
802+
803+static inline int am33xx_sr_cpufreq_register(struct am33xx_sr *sr)
804+{
805+ sr->freq_transition.notifier_call = am33xx_sr_cpufreq_transition;
806+
807+ return cpufreq_register_notifier(&sr->freq_transition,
808+ CPUFREQ_TRANSITION_NOTIFIER);
809+}
810+
811+static inline void am33xx_sr_cpufreq_deregister(struct am33xx_sr *sr)
812+{
813+ cpufreq_unregister_notifier(&sr->freq_transition,
814+ CPUFREQ_TRANSITION_NOTIFIER);
815+}
816+
817+#endif
818+
819+static int __init am33xx_sr_probe(struct platform_device *pdev)
820+{
821+ struct am33xx_sr *sr_info;
822+ struct am33xx_sr_platform_data *pdata;
823+ struct resource *res[MAX_SENSORS];
824+ int irq;
825+ int ret;
826+ int i,j;
827+
828+ sr_info = kzalloc(sizeof(struct am33xx_sr), GFP_KERNEL);
829+ if (!sr_info) {
830+ dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
831+ __func__);
832+ return -ENOMEM;
833+ }
834+
835+ pdata = pdev->dev.platform_data;
836+ if (!pdata) {
837+ dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
838+ ret = -EINVAL;
839+ goto err_free_sr_info;
840+ }
841+
842+ sr_info->pdev = pdev;
843+ sr_info->sen[SR_CORE].name = "smartreflex0";
844+ sr_info->sen[SR_MPU].name = "smartreflex1";
845+ sr_info->ip_type = pdata->ip_type;
846+ sr_info->irq_delay = pdata->irq_delay;
847+ sr_info->no_of_sens = pdata->no_of_sens;
848+ sr_info->no_of_vds = pdata->no_of_vds;
849+ sr_info->uvoltage_step_size = pdata->vstep_size_uv;
850+ sr_info->autocomp_active = false;
851+ sr_info->disabled_by_user = false;
852+
853+ for (i = 0; i < sr_info->no_of_sens; i++) {
854+ u32 curr_freq=0;
855+
856+ sr_info->sen[i].reg_name = pdata->vd_name[i];
857+
858+ /* this should be determined from voltdm or opp layer, but
859+ those approaches are not working */
860+ sr_info->sen[i].no_of_opps = pdata->sr_sdata[i].no_of_opps;
861+ sr_info->sen[i].sr_id = i;
862+
863+ /* Reading per OPP Values */
864+ for (j = 0; j < sr_info->sen[i].no_of_opps; j++) {
865+ sr_info->sen[i].opp_data[j].efuse_offs =
866+ pdata->sr_sdata[i].sr_opp_data[j].efuse_offs;
867+ sr_info->sen[i].opp_data[j].e2v_gain =
868+ pdata->sr_sdata[i].sr_opp_data[j].e2v_gain;
869+ sr_info->sen[i].opp_data[j].err_weight =
870+ pdata->sr_sdata[i].sr_opp_data[j].err_weight;
871+ sr_info->sen[i].opp_data[j].err_minlimit =
872+ pdata->sr_sdata[i].sr_opp_data[j].err_minlimit;
873+ sr_info->sen[i].opp_data[j].err_maxlimit =
874+ pdata->sr_sdata[i].sr_opp_data[j].err_maxlimit;
875+ sr_info->sen[i].opp_data[j].margin =
876+ pdata->sr_sdata[i].sr_opp_data[j].margin;
877+ sr_info->sen[i].opp_data[j].nominal_volt =
878+ pdata->sr_sdata[i].sr_opp_data[j].nominal_volt;
879+ sr_info->sen[i].opp_data[j].frequency =
880+ pdata->sr_sdata[i].sr_opp_data[j].frequency;
881+ sr_info->sen[i].opp_data[j].opp_id = j;
882+ }
883+
884+ if (i == SR_MPU) {
885+ /* hardcoded CPU NR */
886+ curr_freq = cpufreq_get(0);
887+
888+ /* update current OPP */
889+ sr_info->sen[i].curr_opp = get_current_opp(sr_info, i,
890+ curr_freq*1000);
891+ if (sr_info->sen[i].curr_opp == -EINVAL) {
892+ dev_err(&sr_info->pdev->dev,
893+ "%s: cannot determine opp\n",__func__);
894+ ret = -EINVAL;
895+ goto err_free_sr_info;
896+ }
897+ } else {
898+ sr_info->sen[i].curr_opp =
899+ pdata->sr_sdata[i].default_opp;
900+ }
901+
902+ dev_dbg(&pdev->dev,
903+ "%s: SR%d, curr_opp=%d, no_of_opps=%d, step_size=%d\n",
904+ __func__, i, sr_info->sen[i].curr_opp,
905+ sr_info->sen[i].no_of_opps,
906+ sr_info->uvoltage_step_size);
907+
908+ ret = sr_set_nvalues(sr_info, i);
909+ if (ret == -EINVAL) {
910+ dev_err(&sr_info->pdev->dev,
911+ "%s: Zero NValue read from EFUSE\n", __func__);
912+ goto err_free_sr_info;
913+ }
914+
915+ INIT_DELAYED_WORK(&sr_info->sen[i].work_reenable,
916+ irq_sr_reenable);
917+
918+ sr_info->res_name[i] = kzalloc(CLK_NAME_LEN + 1, GFP_KERNEL);
919+
920+ /* resources */
921+ res[i] = platform_get_resource_byname(pdev, IORESOURCE_MEM,
922+ sr_info->sen[i].name);
923+ if (!res[i]) {
924+ dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
925+ ret = -ENOENT;
926+ goto err_free_mem;
927+ }
928+
929+ irq = platform_get_irq_byname(pdev, sr_info->sen[i].name);
930+ if (irq < 0) {
931+ dev_err(&pdev->dev, "Can't get interrupt resource\n");
932+ ret = irq;
933+ goto err_free_mem;
934+ }
935+ sr_info->sen[i].irq = irq;
936+
937+ res[i] = request_mem_region(res[i]->start,
938+ resource_size(res[i]), pdev->name);
939+ if (!res[i]) {
940+ dev_err(&pdev->dev, "can't request mem region\n");
941+ ret = -EBUSY;
942+ goto err_free_mem;
943+ }
944+
945+ sr_info->sen[i].base = ioremap(res[i]->start,
946+ resource_size(res[i]));
947+ if (!sr_info->sen[i].base) {
948+ dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
949+ ret = -ENOMEM;
950+ goto err_release_mem;
951+ }
952+
953+ strcat(sr_info->res_name[i], sr_info->sen[i].name);
954+ strcat(sr_info->res_name[i], "_fck");
955+
956+ sr_info->sen[i].fck = clk_get(NULL, sr_info->res_name[i]);
957+ if (IS_ERR(sr_info->sen[i].fck)) {
958+ dev_err(&pdev->dev, "%s: Could not get sr fck\n",
959+ __func__);
960+ ret = PTR_ERR(sr_info->sen[i].fck);
961+ goto err_unmap;
962+ }
963+
964+ ret = request_irq(sr_info->sen[i].irq, sr_class2_irq,
965+ IRQF_DISABLED, sr_info->sen[i].name,
966+ (void *)&sr_info->sen[i]);
967+ if (ret) {
968+ dev_err(&pdev->dev, "%s: Could not install SR ISR\n",
969+ __func__);
970+ goto err_put_clock;
971+ }
972+
973+ sr_info->sen[i].senn_en = pdata->sr_sdata[i].senn_mod;
974+ sr_info->sen[i].senp_en = pdata->sr_sdata[i].senp_mod;
975+
976+ sr_info->sen[i].reg =
977+ regulator_get(NULL, sr_info->sen[i].reg_name);
978+ if (IS_ERR(sr_info->sen[i].reg)) {
979+ ret = -EINVAL;
980+ goto err_free_irq;
981+ }
982+
983+ /* Read current regulator value and voltage */
984+ sr_info->sen[i].init_volt_mv =
985+ regulator_get_voltage(sr_info->sen[i].reg);
986+
987+ dev_dbg(&pdev->dev, "%s: regulator %d, init_volt = %d\n",
988+ __func__, i, sr_info->sen[i].init_volt_mv);
989+ } /* for() */
990+
991+ /* set_voltage() will be used as the bottom half IRQ handler */
992+ INIT_DELAYED_WORK(&sr_info->work, set_voltage);
993+
994+#ifdef CONFIG_CPU_FREQ
995+ ret = am33xx_sr_cpufreq_register(sr_info);
996+ if (ret) {
997+ dev_err(&pdev->dev, "failed to register cpufreq\n");
998+ goto err_reg_put;
999+ }
1000+#endif
1001+
1002+ /* debugfs entries */
1003+ ret = sr_debugfs_entries(sr_info);
1004+ if (ret)
1005+ dev_warn(&pdev->dev, "%s: Debugfs entries are not created\n",
1006+ __func__);
1007+
1008+ platform_set_drvdata(pdev, sr_info);
1009+
1010+ dev_info(&pdev->dev, "%s: Driver initialized\n", __func__);
1011+
1012+ /* disabled_by_user used to ensure SR doesn't come on via CPUFREQ
1013+ scaling if user has disabled SR via debugfs on enable_on_init */
1014+ if (pdata->enable_on_init)
1015+ sr_start_vddautocomp(sr_info);
1016+ else
1017+ sr_info->disabled_by_user = 1;
1018+
1019+ return ret;
1020+
1021+#ifdef CONFIG_CPU_FREQ
1022+ am33xx_sr_cpufreq_deregister(sr_info);
1023+#endif
1024+
1025+err_reg_put:
1026+ i--; /* back up i by one to walk back through the for loop */
1027+ regulator_put(sr_info->sen[i].reg);
1028+err_free_irq:
1029+ free_irq(sr_info->sen[i].irq, (void *)sr_info);
1030+err_put_clock:
1031+ clk_put(sr_info->sen[i].fck);
1032+err_unmap:
1033+ iounmap(sr_info->sen[i].base);
1034+err_release_mem:
1035+ release_mem_region(res[i]->start, resource_size(res[i]));
1036+err_free_mem:
1037+ kfree(sr_info->res_name[i]);
1038+ /* unwind back through the for loop */
1039+ if (i != 0) {
1040+ goto err_reg_put;
1041+ }
1042+
1043+err_free_sr_info:
1044+ kfree(sr_info);
1045+ return ret;
1046+}
1047+
1048+static int __devexit am33xx_sr_remove(struct platform_device *pdev)
1049+{
1050+ struct am33xx_sr *sr_info;
1051+ struct resource *res[MAX_SENSORS];
1052+ int irq;
1053+ int i;
1054+
1055+ sr_info = dev_get_drvdata(&pdev->dev);
1056+ if (!sr_info) {
1057+ dev_err(&pdev->dev, "%s: sr_info missing\n", __func__);
1058+ return -EINVAL;
1059+ }
1060+
1061+ if (sr_info->autocomp_active)
1062+ sr_stop_vddautocomp(sr_info);
1063+
1064+#ifdef CONFIG_CPU_FREQ
1065+ am33xx_sr_cpufreq_deregister(sr_info);
1066+#endif
1067+
1068+ for (i = 0; i < sr_info->no_of_sens; i++) {
1069+ regulator_put(sr_info->sen[i].reg);
1070+ irq = platform_get_irq_byname(pdev, sr_info->sen[i].name);
1071+ free_irq(irq, (void *)sr_info);
1072+ clk_put(sr_info->sen[i].fck);
1073+ iounmap(sr_info->sen[i].base);
1074+ res[i] = platform_get_resource_byname(pdev,
1075+ IORESOURCE_MEM, sr_info->sen[i].name);
1076+ release_mem_region(res[i]->start, resource_size(res[i]));
1077+ kfree(sr_info->res_name[i]);
1078+ }
1079+
1080+ kfree(sr_info);
1081+
1082+ dev_info(&pdev->dev, "%s: SR has been removed\n", __func__);
1083+ return 0;
1084+}
1085+
1086+static struct platform_driver smartreflex_driver = {
1087+ .driver = {
1088+ .name = "smartreflex",
1089+ .owner = THIS_MODULE,
1090+ },
1091+ .remove = am33xx_sr_remove,
1092+};
1093+
1094+static int __init sr_init(void)
1095+{
1096+ int ret;
1097+
1098+ ret = platform_driver_probe(&smartreflex_driver, am33xx_sr_probe);
1099+ if (ret) {
1100+ pr_err("%s: platform driver register failed\n", __func__);
1101+ return ret;
1102+ }
1103+
1104+ return 0;
1105+}
1106+
1107+static void __exit sr_exit(void)
1108+{
1109+ platform_driver_unregister(&smartreflex_driver);
1110+}
1111+late_initcall(sr_init);
1112+module_exit(sr_exit);
1113+
1114+MODULE_DESCRIPTION("AM33XX Smartreflex Class2 Driver");
1115+MODULE_LICENSE("GPL");
1116+MODULE_ALIAS("platform:" DRIVER_NAME);
1117+MODULE_AUTHOR("Texas Instruments Inc");
1118diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c
1119index 0bcadd7..6e1c026 100644
1120--- a/arch/arm/mach-omap2/board-am335xevm.c
1121+++ b/arch/arm/mach-omap2/board-am335xevm.c
1122@@ -1410,6 +1410,7 @@ static struct regulator_init_data tps65217_regulator_data[] = {
1123 .num_consumer_supplies = ARRAY_SIZE(tps65217_dcdc2_consumers),
1124 .consumer_supplies = tps65217_dcdc2_consumers,
1125 .driver_data = &dcdc2_ramp_delay,
1126+ .ignore_check_consumers = 1,
1127 },
1128
1129 /* dcdc3 */
1130@@ -1424,6 +1425,7 @@ static struct regulator_init_data tps65217_regulator_data[] = {
1131 },
1132 .num_consumer_supplies = ARRAY_SIZE(tps65217_dcdc3_consumers),
1133 .consumer_supplies = tps65217_dcdc3_consumers,
1134+ .ignore_check_consumers = 1,
1135 },
1136
1137 /* ldo1 */
1138@@ -2214,6 +2216,9 @@ static void am335x_evm_setup(struct memory_accessor *mem_acc, void *context)
1139 goto out;
1140 }
1141
1142+ /* SmartReflex also requires board information. */
1143+ am33xx_sr_init();
1144+
1145 return;
1146
1147 out:
1148@@ -2265,6 +2270,7 @@ static struct regulator_init_data am335x_vdd1 = {
1149 },
1150 .num_consumer_supplies = ARRAY_SIZE(am335x_vdd1_supply),
1151 .consumer_supplies = am335x_vdd1_supply,
1152+ .ignore_check_consumers = 1,
1153 };
1154
1155 static struct regulator_consumer_supply am335x_vdd2_supply[] = {
1156@@ -2281,6 +2287,7 @@ static struct regulator_init_data am335x_vdd2 = {
1157 },
1158 .num_consumer_supplies = ARRAY_SIZE(am335x_vdd2_supply),
1159 .consumer_supplies = am335x_vdd2_supply,
1160+ .ignore_check_consumers = 1,
1161 };
1162
1163 static struct tps65910_board am335x_tps65910_info = {
1164diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
1165index 6113654..ebf0d9e 100644
1166--- a/arch/arm/mach-omap2/devices.c
1167+++ b/arch/arm/mach-omap2/devices.c
1168@@ -52,6 +52,7 @@
1169 #include <plat/config_pwm.h>
1170 #include <plat/cpu.h>
1171 #include <plat/gpmc.h>
1172+#include <plat/smartreflex.h>
1173 #include <plat/am33xx.h>
1174
1175 /* LCD controller similar DA8xx */
1176@@ -60,10 +61,28 @@
1177 #include "mux.h"
1178 #include "control.h"
1179 #include "devices.h"
1180+#include "omap_opp_data.h"
1181
1182 #define L3_MODULES_MAX_LEN 12
1183 #define L3_MODULES 3
1184
1185+static unsigned int am33xx_evmid;
1186+
1187+/*
1188+ * am33xx_evmid_fillup - set up board evmid
1189+ * @evmid - evm id which needs to be configured
1190+ *
1191+ * This function is called to configure board evm id.
1192+ * IA Motor Control EVM needs special setting of MAC PHY Id.
1193+ * This function is called when IA Motor Control EVM is detected
1194+ * during boot-up.
1195+ */
1196+void am33xx_evmid_fillup(unsigned int evmid)
1197+{
1198+ am33xx_evmid = evmid;
1199+ return;
1200+}
1201+
1202 static int __init omap3_l3_init(void)
1203 {
1204 int l;
1205@@ -1226,6 +1245,256 @@ static struct platform_device am335x_sgx = {
1206
1207 #endif
1208
1209+#ifdef CONFIG_AM33XX_SMARTREFLEX
1210+
1211+/* smartreflex platform data */
1212+
1213+/* The values below are based upon silicon characterization data.
1214+ * Each OPP and sensor combination potentially has different values.
1215+ * The values of ERR2VOLT_GAIN and ERR_MIN_LIMIT also change based on
1216+ * the PMIC step size. Values have been given to cover the AM335 EVM
1217+ * (12.5mV step) and the Beaglebone (25mV step). If the step
1218+ * size changes, you should update these values, and don't forget to
1219+ * change the step size in the platform data structure, am33xx_sr_pdata.
1220+ */
1221+
1222+#define AM33XX_SR0_OPP50_CNTRL_OFFSET 0x07B8
1223+#define AM33XX_SR0_OPP50_EVM_ERR2VOLT_GAIN 0xC
1224+#define AM33XX_SR0_OPP50_EVM_ERR_MIN_LIMIT 0xF5
1225+#define AM33XX_SR0_OPP50_BB_ERR2VOLT_GAIN 0x6
1226+#define AM33XX_SR0_OPP50_BB_ERR_MIN_LIMIT 0xEA
1227+#define AM33XX_SR0_OPP50_ERR_MAX_LIMIT 0x2
1228+#define AM33XX_SR0_OPP50_ERR_WEIGHT 0x4
1229+#define AM33XX_SR0_OPP50_MARGIN 0
1230+
1231+#define AM33XX_SR0_OPP100_CNTRL_OFFSET 0x07BC
1232+#define AM33XX_SR0_OPP100_EVM_ERR2VOLT_GAIN 0x12
1233+#define AM33XX_SR0_OPP100_EVM_ERR_MIN_LIMIT 0xF8
1234+#define AM33XX_SR0_OPP100_BB_ERR2VOLT_GAIN 0x9
1235+#define AM33XX_SR0_OPP100_BB_ERR_MIN_LIMIT 0xF1
1236+#define AM33XX_SR0_OPP100_ERR_MAX_LIMIT 0x2
1237+#define AM33XX_SR0_OPP100_ERR_WEIGHT 0x4
1238+#define AM33XX_SR0_OPP100_MARGIN 0
1239+
1240+#define AM33XX_SR1_OPP50_CNTRL_OFFSET 0x0770
1241+#define AM33XX_SR1_OPP50_EVM_ERR2VOLT_GAIN 0x5
1242+#define AM33XX_SR1_OPP50_EVM_ERR_MIN_LIMIT 0xE6
1243+#define AM33XX_SR1_OPP50_BB_ERR2VOLT_GAIN 0x2
1244+#define AM33XX_SR1_OPP50_BB_ERR_MIN_LIMIT 0xC0
1245+#define AM33XX_SR1_OPP50_ERR_MAX_LIMIT 0x2
1246+#define AM33XX_SR1_OPP50_ERR_WEIGHT 0x4
1247+#define AM33XX_SR1_OPP50_MARGIN 0
1248+
1249+#define AM33XX_SR1_OPP100_CNTRL_OFFSET 0x0774
1250+#define AM33XX_SR1_OPP100_EVM_ERR2VOLT_GAIN 0x8
1251+#define AM33XX_SR1_OPP100_EVM_ERR_MIN_LIMIT 0xF0
1252+#define AM33XX_SR1_OPP100_BB_ERR2VOLT_GAIN 0x4
1253+#define AM33XX_SR1_OPP100_BB_ERR_MIN_LIMIT 0xDF
1254+#define AM33XX_SR1_OPP100_ERR_MAX_LIMIT 0x2
1255+#define AM33XX_SR1_OPP100_ERR_WEIGHT 0x4
1256+#define AM33XX_SR1_OPP100_MARGIN 0
1257+
1258+#define AM33XX_SR1_OPP120_CNTRL_OFFSET 0x0778
1259+#define AM33XX_SR1_OPP120_EVM_ERR2VOLT_GAIN 0xB
1260+#define AM33XX_SR1_OPP120_EVM_ERR_MIN_LIMIT 0xF4
1261+#define AM33XX_SR1_OPP120_BB_ERR2VOLT_GAIN 0x5
1262+#define AM33XX_SR1_OPP120_BB_ERR_MIN_LIMIT 0xE6
1263+#define AM33XX_SR1_OPP120_ERR_MAX_LIMIT 0x2
1264+#define AM33XX_SR1_OPP120_ERR_WEIGHT 0x4
1265+#define AM33XX_SR1_OPP120_MARGIN 0
1266+
1267+#define AM33XX_SR1_OPPTURBO_CNTRL_OFFSET 0x077C
1268+#define AM33XX_SR1_OPPTURBO_EVM_ERR2VOLT_GAIN 0xC
1269+#define AM33XX_SR1_OPPTURBO_EVM_ERR_MIN_LIMIT 0xF5
1270+#define AM33XX_SR1_OPPTURBO_BB_ERR2VOLT_GAIN 0x6
1271+#define AM33XX_SR1_OPPTURBO_BB_ERR_MIN_LIMIT 0xEA
1272+#define AM33XX_SR1_OPPTURBO_ERR_MAX_LIMIT 0x2
1273+#define AM33XX_SR1_OPPTURBO_ERR_WEIGHT 0x4
1274+#define AM33XX_SR1_OPPTURBO_MARGIN 0
1275+
1276+/* the voltages and frequencies should probably be defined in opp3xxx_data.c.
1277+ Once SR is integrated to the mainline driver, and voltdm is working
1278+ correctly in AM335x, these can be removed. */
1279+#define AM33XX_VDD_MPU_OPP50_UV 950000
1280+#define AM33XX_VDD_MPU_OPP100_UV 1100000
1281+#define AM33XX_VDD_MPU_OPP120_UV 1200000
1282+#define AM33XX_VDD_MPU_OPPTURBO_UV 1260000
1283+#define AM33XX_VDD_CORE_OPP50_UV 950000
1284+#define AM33XX_VDD_CORE_OPP100_UV 1100000
1285+
1286+#define AM33XX_VDD_MPU_OPP50_FREQ 275000000
1287+#define AM33XX_VDD_MPU_OPP100_FREQ 500000000
1288+#define AM33XX_VDD_MPU_OPP120_FREQ 600000000
1289+#define AM33XX_VDD_MPU_OPPTURBO_FREQ 720000000
1290+
1291+static struct am33xx_sr_opp_data sr1_opp_data[] = {
1292+ {
1293+ .efuse_offs = AM33XX_SR1_OPP50_CNTRL_OFFSET,
1294+ .e2v_gain = AM33XX_SR1_OPP50_EVM_ERR2VOLT_GAIN,
1295+ .err_minlimit = AM33XX_SR1_OPP50_EVM_ERR_MIN_LIMIT,
1296+ .err_maxlimit = AM33XX_SR1_OPP50_ERR_MAX_LIMIT,
1297+ .err_weight = AM33XX_SR1_OPP50_ERR_WEIGHT,
1298+ .margin = AM33XX_SR1_OPP50_MARGIN,
1299+ .nominal_volt = AM33XX_VDD_MPU_OPP50_UV,
1300+ .frequency = AM33XX_VDD_MPU_OPP50_FREQ,
1301+ },
1302+ {
1303+ .efuse_offs = AM33XX_SR1_OPP100_CNTRL_OFFSET,
1304+ .e2v_gain = AM33XX_SR1_OPP100_EVM_ERR2VOLT_GAIN,
1305+ .err_minlimit = AM33XX_SR1_OPP100_EVM_ERR_MIN_LIMIT,
1306+ .err_maxlimit = AM33XX_SR1_OPP100_ERR_MAX_LIMIT,
1307+ .err_weight = AM33XX_SR1_OPP100_ERR_WEIGHT,
1308+ .margin = AM33XX_SR1_OPP100_MARGIN,
1309+ .nominal_volt = AM33XX_VDD_MPU_OPP100_UV,
1310+ .frequency = AM33XX_VDD_MPU_OPP100_FREQ,
1311+ },
1312+ {
1313+ .efuse_offs = AM33XX_SR1_OPP120_CNTRL_OFFSET,
1314+ .e2v_gain = AM33XX_SR1_OPP120_EVM_ERR2VOLT_GAIN,
1315+ .err_minlimit = AM33XX_SR1_OPP120_EVM_ERR_MIN_LIMIT,
1316+ .err_maxlimit = AM33XX_SR1_OPP120_ERR_MAX_LIMIT,
1317+ .err_weight = AM33XX_SR1_OPP120_ERR_WEIGHT,
1318+ .margin = AM33XX_SR1_OPP120_MARGIN,
1319+ .nominal_volt = AM33XX_VDD_MPU_OPP120_UV,
1320+ .frequency = AM33XX_VDD_MPU_OPP120_FREQ,
1321+ },
1322+ {
1323+ .efuse_offs = AM33XX_SR1_OPPTURBO_CNTRL_OFFSET,
1324+ .e2v_gain = AM33XX_SR1_OPPTURBO_EVM_ERR2VOLT_GAIN,
1325+ .err_minlimit = AM33XX_SR1_OPPTURBO_EVM_ERR_MIN_LIMIT,
1326+ .err_maxlimit = AM33XX_SR1_OPPTURBO_ERR_MAX_LIMIT,
1327+ .err_weight = AM33XX_SR1_OPPTURBO_ERR_WEIGHT,
1328+ .margin = AM33XX_SR1_OPPTURBO_MARGIN,
1329+ .nominal_volt = AM33XX_VDD_MPU_OPPTURBO_UV,
1330+ .frequency = AM33XX_VDD_MPU_OPPTURBO_FREQ,
1331+ },
1332+};
1333+
1334+static struct am33xx_sr_opp_data sr0_opp_data[] = {
1335+ {
1336+ .efuse_offs = AM33XX_SR0_OPP50_CNTRL_OFFSET,
1337+ .e2v_gain = AM33XX_SR0_OPP50_EVM_ERR2VOLT_GAIN,
1338+ .err_minlimit = AM33XX_SR0_OPP50_EVM_ERR_MIN_LIMIT,
1339+ .err_maxlimit = AM33XX_SR0_OPP50_ERR_MAX_LIMIT,
1340+ .err_weight = AM33XX_SR0_OPP50_ERR_WEIGHT,
1341+ .margin = AM33XX_SR0_OPP50_MARGIN,
1342+ .nominal_volt = AM33XX_VDD_CORE_OPP50_UV,
1343+ },
1344+ {
1345+ .efuse_offs = AM33XX_SR0_OPP100_CNTRL_OFFSET,
1346+ .e2v_gain = AM33XX_SR0_OPP100_EVM_ERR2VOLT_GAIN,
1347+ .err_minlimit = AM33XX_SR0_OPP100_EVM_ERR_MIN_LIMIT,
1348+ .err_maxlimit = AM33XX_SR0_OPP100_ERR_MAX_LIMIT,
1349+ .err_weight = AM33XX_SR0_OPP100_ERR_WEIGHT,
1350+ .margin = AM33XX_SR0_OPP100_MARGIN,
1351+ .nominal_volt = AM33XX_VDD_CORE_OPP100_UV,
1352+ },
1353+};
1354+
1355+static struct am33xx_sr_sdata sr_sensor_data[] = {
1356+ {
1357+ .sr_opp_data = sr0_opp_data,
1358+ /* note that OPP50 is NOT used in Linux kernel for AM335x */
1359+ .no_of_opps = 0x2,
1360+ .default_opp = 0x1,
1361+ .senn_mod = 0x1,
1362+ .senp_mod = 0x1,
1363+ },
1364+ {
1365+ .sr_opp_data = sr1_opp_data,
1366+ /* the opp data below should be determined
1367+ dynamically during SR probe */
1368+ .no_of_opps = 0x4,
1369+ .default_opp = 0x3,
1370+ .senn_mod = 0x1,
1371+ .senp_mod = 0x1,
1372+ },
1373+};
1374+
1375+static struct am33xx_sr_platform_data am33xx_sr_pdata = {
1376+ .vd_name[0] = "vdd_core",
1377+ .vd_name[1] = "vdd_mpu",
1378+ .ip_type = 2,
1379+ .irq_delay = 1000,
1380+ .no_of_vds = 2,
1381+ .no_of_sens = ARRAY_SIZE(sr_sensor_data),
1382+ .vstep_size_uv = 12500,
1383+ .enable_on_init = true,
1384+ .sr_sdata = sr_sensor_data,
1385+};
1386+
1387+static struct resource am33xx_sr_resources[] = {
1388+ {
1389+ .name = "smartreflex0",
1390+ .start = AM33XX_SR0_BASE,
1391+ .end = AM33XX_SR0_BASE + SZ_4K - 1,
1392+ .flags = IORESOURCE_MEM,
1393+ },
1394+ {
1395+ .name = "smartreflex0",
1396+ .start = AM33XX_IRQ_SMARTREFLEX0,
1397+ .end = AM33XX_IRQ_SMARTREFLEX0,
1398+ .flags = IORESOURCE_IRQ,
1399+ },
1400+ {
1401+ .name = "smartreflex1",
1402+ .start = AM33XX_SR1_BASE,
1403+ .end = AM33XX_SR1_BASE + SZ_4K - 1,
1404+ .flags = IORESOURCE_MEM,
1405+ },
1406+ {
1407+ .name = "smartreflex1",
1408+ .start = AM33XX_IRQ_SMARTREFLEX1,
1409+ .end = AM33XX_IRQ_SMARTREFLEX1,
1410+ .flags = IORESOURCE_IRQ,
1411+ },
1412+};
1413+
1414+/* VCORE for SR regulator init */
1415+static struct platform_device am33xx_sr_device = {
1416+ .name = "smartreflex",
1417+ .id = -1,
1418+ .num_resources = ARRAY_SIZE(am33xx_sr_resources),
1419+ .resource = am33xx_sr_resources,
1420+ .dev = {
1421+ .platform_data = &am33xx_sr_pdata,
1422+ },
1423+};
1424+
1425+void __init am33xx_sr_init(void)
1426+{
1427+ /* For beaglebone, update voltage step size and related parameters
1428+ appropriately. All other AM33XX platforms are good with the
1429+ structure defaults as initialized above. */
1430+ if ((am33xx_evmid == BEAGLE_BONE_OLD) ||
1431+ (am33xx_evmid == BEAGLE_BONE_A3)) {
1432+ printk(KERN_ERR "address of pdata = %08x\n", (u32)&am33xx_sr_pdata);
1433+ am33xx_sr_pdata.vstep_size_uv = 25000;
1434+ /* CORE */
1435+ sr0_opp_data[0].e2v_gain = AM33XX_SR0_OPP50_BB_ERR2VOLT_GAIN;
1436+ sr0_opp_data[0].err_minlimit = AM33XX_SR0_OPP50_BB_ERR_MIN_LIMIT;
1437+ sr0_opp_data[1].e2v_gain = AM33XX_SR0_OPP100_BB_ERR2VOLT_GAIN;
1438+ sr0_opp_data[1].err_minlimit = AM33XX_SR0_OPP100_BB_ERR_MIN_LIMIT;
1439+ /* MPU */
1440+ sr1_opp_data[0].e2v_gain = AM33XX_SR1_OPP50_BB_ERR2VOLT_GAIN;
1441+ sr1_opp_data[0].err_minlimit = AM33XX_SR1_OPP50_BB_ERR_MIN_LIMIT;
1442+ sr1_opp_data[1].e2v_gain = AM33XX_SR1_OPP100_BB_ERR2VOLT_GAIN;
1443+ sr1_opp_data[1].err_minlimit = AM33XX_SR1_OPP100_BB_ERR_MIN_LIMIT;
1444+ sr1_opp_data[2].e2v_gain = AM33XX_SR1_OPP120_BB_ERR2VOLT_GAIN;
1445+ sr1_opp_data[2].err_minlimit = AM33XX_SR1_OPP120_BB_ERR_MIN_LIMIT;
1446+ sr1_opp_data[3].e2v_gain = AM33XX_SR1_OPPTURBO_BB_ERR2VOLT_GAIN;
1447+ sr1_opp_data[3].err_minlimit = AM33XX_SR1_OPPTURBO_BB_ERR_MIN_LIMIT;
1448+ }
1449+
1450+ if (platform_device_register(&am33xx_sr_device))
1451+ printk(KERN_ERR "failed to register am33xx_sr device\n");
1452+ else
1453+ printk(KERN_INFO "registered am33xx_sr device\n");
1454+}
1455+#else
1456+inline void am33xx_sr_init(void) {}
1457+#endif
1458+
1459 /*-------------------------------------------------------------------------*/
1460
1461 static int __init omap2_init_devices(void)
1462diff --git a/arch/arm/mach-omap2/include/mach/board-am335xevm.h b/arch/arm/mach-omap2/include/mach/board-am335xevm.h
1463index 1d24495..85a8df0 100644
1464--- a/arch/arm/mach-omap2/include/mach/board-am335xevm.h
1465+++ b/arch/arm/mach-omap2/include/mach/board-am335xevm.h
1466@@ -41,6 +41,7 @@
1467 void am335x_evm_set_id(unsigned int evmid);
1468 int am335x_evm_get_id(void);
1469 void am33xx_cpsw_macidfillup(char *eeprommacid0, char *eeprommacid1);
1470+void am33xx_sr_init(void);
1471 void am33xx_d_can_init(unsigned int instance);
1472
1473 #endif
1474diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
1475index 734009a..33f17f2 100644
1476--- a/arch/arm/plat-omap/Kconfig
1477+++ b/arch/arm/plat-omap/Kconfig
1478@@ -43,6 +43,27 @@ config OMAP_DEBUG_LEDS
1479 depends on OMAP_DEBUG_DEVICES
1480 default y if LEDS_CLASS
1481
1482+config AM33XX_SMARTREFLEX
1483+ bool "AM33XX SmartReflex support"
1484+ depends on (SOC_OMAPAM33XX) && PM
1485+ help
1486+ Say Y if you want to enable SmartReflex.
1487+
1488+ SmartReflex can perform continuous dynamic voltage
1489+ scaling around the nominal operating point voltage
1490+ according to silicon characteristics and operating
1491+ conditions. Enabling SmartReflex reduces active power
1492+ consumption.
1493+
1494+ Please note, that by default SmartReflex is enabled.
1495+ To disable the automatic voltage compensation for
1496+ vdd mpu and vdd core from user space, user must
1497+ write 1 to /debug/smartreflex/autocomp.
1498+
1499+ Optionally autocompensation can be disabled in the kernel
1500+ by default during system init via the enable_on_init flag
1501+ which an be passed as platform data to the smartreflex driver.
1502+
1503 config OMAP_SMARTREFLEX
1504 bool "SmartReflex support"
1505 depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM
1506diff --git a/arch/arm/plat-omap/include/plat/am33xx.h b/arch/arm/plat-omap/include/plat/am33xx.h
1507index 32522df..a628b1f 100644
1508--- a/arch/arm/plat-omap/include/plat/am33xx.h
1509+++ b/arch/arm/plat-omap/include/plat/am33xx.h
1510@@ -43,6 +43,9 @@
1511 #define AM33XX_TSC_BASE 0x44E0D000
1512 #define AM33XX_RTC_BASE 0x44E3E000
1513
1514+#define AM33XX_SR0_BASE 0x44E37000
1515+#define AM33XX_SR1_BASE 0x44E39000
1516+
1517 #define AM33XX_ASP0_BASE 0x48038000
1518 #define AM33XX_ASP1_BASE 0x4803C000
1519
1520diff --git a/arch/arm/plat-omap/include/plat/smartreflex.h b/arch/arm/plat-omap/include/plat/smartreflex.h
1521new file mode 100644
1522index 0000000..36338f7
1523--- /dev/null
1524+++ b/arch/arm/plat-omap/include/plat/smartreflex.h
1525@@ -0,0 +1,431 @@
1526+/*
1527+ * OMAP Smartreflex Defines and Routines
1528+ *
1529+ * Author: Thara Gopinath <thara@ti.com>
1530+ *
1531+ * Copyright (C) 2010 Texas Instruments, Inc.
1532+ * Thara Gopinath <thara@ti.com>
1533+ *
1534+ * Copyright (C) 2008 Nokia Corporation
1535+ * Kalle Jokiniemi
1536+ *
1537+ * Copyright (C) 2007 Texas Instruments, Inc.
1538+ * Lesly A M <x0080970@ti.com>
1539+ *
1540+ * This program is free software; you can redistribute it and/or modify
1541+ * it under the terms of the GNU General Public License version 2 as
1542+ * published by the Free Software Foundation.
1543+ */
1544+
1545+#ifndef __ASM_ARM_OMAP_SMARTREFLEX_H
1546+#define __ASM_ARM_OMAP_SMARTREFLEX_H
1547+
1548+#include <linux/platform_device.h>
1549+#include <plat/voltage.h>
1550+
1551+/*
1552+ * Different Smartreflex IPs version. The v1 is the 65nm version used in
1553+ * OMAP3430. The v2 is the update for the 45nm version of the IP
1554+ * used in OMAP3630 and OMAP4430
1555+ */
1556+#define SR_TYPE_V1 1
1557+#define SR_TYPE_V2 2
1558+
1559+/* SMART REFLEX REG ADDRESS OFFSET */
1560+#define SRCONFIG 0x00
1561+#define SRSTATUS 0x04
1562+#define SENVAL 0x08
1563+#define SENMIN 0x0C
1564+#define SENMAX 0x10
1565+#define SENAVG 0x14
1566+#define AVGWEIGHT 0x18
1567+#define NVALUERECIPROCAL 0x1c
1568+#define SENERROR_V1 0x20
1569+#define ERRCONFIG_V1 0x24
1570+#define IRQ_EOI 0x20
1571+#define IRQSTATUS_RAW 0x24
1572+#define IRQSTATUS 0x28
1573+#define IRQENABLE_SET 0x2C
1574+#define IRQENABLE_CLR 0x30
1575+#define SENERROR_V2 0x34
1576+#define ERRCONFIG_V2 0x38
1577+
1578+/* Bit/Shift Positions */
1579+
1580+/* SRCONFIG */
1581+#define SRCONFIG_ACCUMDATA_SHIFT 22
1582+#define SRCONFIG_SRCLKLENGTH_SHIFT 12
1583+#define SRCONFIG_SENNENABLE_V1_SHIFT 5
1584+#define SRCONFIG_SENPENABLE_V1_SHIFT 3
1585+#define SRCONFIG_SENNENABLE_V2_SHIFT 1
1586+#define SRCONFIG_SENPENABLE_V2_SHIFT 0
1587+#define SRCONFIG_CLKCTRL_SHIFT 0
1588+
1589+#define SRCONFIG_ACCUMDATA_MASK (0x3ff << 22)
1590+
1591+#define SRCONFIG_SRENABLE BIT(11)
1592+#define SRCONFIG_SENENABLE BIT(10)
1593+#define SRCONFIG_ERRGEN_EN BIT(9)
1594+#define SRCONFIG_MINMAXAVG_EN BIT(8)
1595+#define SRCONFIG_DELAYCTRL BIT(2)
1596+
1597+/* AVGWEIGHT */
1598+#define AVGWEIGHT_SENPAVGWEIGHT_SHIFT 2
1599+#define AVGWEIGHT_SENNAVGWEIGHT_SHIFT 0
1600+
1601+/* NVALUERECIPROCAL */
1602+#define NVALUERECIPROCAL_SENPGAIN_SHIFT 20
1603+#define NVALUERECIPROCAL_SENNGAIN_SHIFT 16
1604+#define NVALUERECIPROCAL_RNSENP_SHIFT 8
1605+#define NVALUERECIPROCAL_RNSENN_SHIFT 0
1606+
1607+/* ERRCONFIG */
1608+#define ERRCONFIG_ERRWEIGHT_SHIFT 16
1609+#define ERRCONFIG_ERRMAXLIMIT_SHIFT 8
1610+#define ERRCONFIG_ERRMINLIMIT_SHIFT 0
1611+
1612+#define SR_ERRWEIGHT_MASK (0x07 << 16)
1613+#define SR_ERRMAXLIMIT_MASK (0xff << 8)
1614+#define SR_ERRMINLIMIT_MASK (0xff << 0)
1615+
1616+#define ERRCONFIG_VPBOUNDINTEN_V1 BIT(31)
1617+#define ERRCONFIG_VPBOUNDINTST_V1 BIT(30)
1618+#define ERRCONFIG_MCUACCUMINTEN BIT(29)
1619+#define ERRCONFIG_MCUACCUMINTST BIT(28)
1620+#define ERRCONFIG_MCUVALIDINTEN BIT(27)
1621+#define ERRCONFIG_MCUVALIDINTST BIT(26)
1622+#define ERRCONFIG_MCUBOUNDINTEN BIT(25)
1623+#define ERRCONFIG_MCUBOUNDINTST BIT(24)
1624+#define ERRCONFIG_MCUDISACKINTEN BIT(23)
1625+#define ERRCONFIG_VPBOUNDINTST_V2 BIT(23)
1626+#define ERRCONFIG_MCUDISACKINTST BIT(22)
1627+#define ERRCONFIG_VPBOUNDINTEN_V2 BIT(22)
1628+
1629+#define ERRCONFIG_STATUS_V1_MASK (ERRCONFIG_VPBOUNDINTST_V1 | \
1630+ ERRCONFIG_MCUACCUMINTST | \
1631+ ERRCONFIG_MCUVALIDINTST | \
1632+ ERRCONFIG_MCUBOUNDINTST | \
1633+ ERRCONFIG_MCUDISACKINTST)
1634+/* IRQSTATUS */
1635+#define IRQSTATUS_MCUACCUMINT BIT(3)
1636+#define IRQSTATUS_MCVALIDINT BIT(2)
1637+#define IRQSTATUS_MCBOUNDSINT BIT(1)
1638+#define IRQSTATUS_MCUDISABLEACKINT BIT(0)
1639+
1640+/* IRQENABLE_SET and IRQENABLE_CLEAR */
1641+#define IRQENABLE_MCUACCUMINT BIT(3)
1642+#define IRQENABLE_MCUVALIDINT BIT(2)
1643+#define IRQENABLE_MCUBOUNDSINT BIT(1)
1644+#define IRQENABLE_MCUDISABLEACKINT BIT(0)
1645+
1646+/* Common Bit values */
1647+
1648+#define SRCLKLENGTH_12MHZ_SYSCLK 0x3c
1649+#define SRCLKLENGTH_13MHZ_SYSCLK 0x41
1650+#define SRCLKLENGTH_19MHZ_SYSCLK 0x60
1651+#define SRCLKLENGTH_26MHZ_SYSCLK 0x82
1652+#define SRCLKLENGTH_38MHZ_SYSCLK 0xC0
1653+
1654+/*
1655+ * 3430 specific values. Maybe these should be passed from board file or
1656+ * pmic structures.
1657+ */
1658+#define OMAP3430_SR_ACCUMDATA 0x1f4
1659+
1660+#define OMAP3430_SR1_SENPAVGWEIGHT 0x03
1661+#define OMAP3430_SR1_SENNAVGWEIGHT 0x03
1662+
1663+#define OMAP3430_SR2_SENPAVGWEIGHT 0x01
1664+#define OMAP3430_SR2_SENNAVGWEIGHT 0x01
1665+
1666+#define OMAP3430_SR_ERRWEIGHT 0x04
1667+#define OMAP3430_SR_ERRMAXLIMIT 0x02
1668+
1669+/**
1670+ * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass
1671+ * pmic specific info to smartreflex driver
1672+ *
1673+ * @sr_pmic_init: API to initialize smartreflex on the PMIC side.
1674+ */
1675+struct omap_sr_pmic_data {
1676+ void (*sr_pmic_init) (void);
1677+};
1678+
1679+#ifdef CONFIG_OMAP_SMARTREFLEX
1680+/*
1681+ * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
1682+ * The smartreflex class driver should pass the class type.
1683+ * Should be used to populate the class_type field of the
1684+ * omap_smartreflex_class_data structure.
1685+ */
1686+#define SR_CLASS1 0x1
1687+#define SR_CLASS2 0x2
1688+#define SR_CLASS3 0x3
1689+
1690+/**
1691+ * struct omap_sr_class_data - Smartreflex class driver info
1692+ *
1693+ * @enable: API to enable a particular class smaartreflex.
1694+ * @disable: API to disable a particular class smartreflex.
1695+ * @configure: API to configure a particular class smartreflex.
1696+ * @notify: API to notify the class driver about an event in SR.
1697+ * Not needed for class3.
1698+ * @notify_flags: specify the events to be notified to the class driver
1699+ * @class_type: specify which smartreflex class.
1700+ * Can be used by the SR driver to take any class
1701+ * based decisions.
1702+ */
1703+struct omap_sr_class_data {
1704+ int (*enable)(struct voltagedomain *voltdm);
1705+ int (*disable)(struct voltagedomain *voltdm, int is_volt_reset);
1706+ int (*configure)(struct voltagedomain *voltdm);
1707+ int (*notify)(struct voltagedomain *voltdm, u32 status);
1708+ u8 notify_flags;
1709+ u8 class_type;
1710+};
1711+
1712+/**
1713+ * struct omap_sr_nvalue_table - Smartreflex n-target value info
1714+ *
1715+ * @efuse_offs: The offset of the efuse where n-target values are stored.
1716+ * @nvalue: The n-target value.
1717+ */
1718+struct omap_sr_nvalue_table {
1719+ u32 efuse_offs;
1720+ u32 nvalue;
1721+};
1722+
1723+/**
1724+ * struct omap_sr_data - Smartreflex platform data.
1725+ *
1726+ * @ip_type: Smartreflex IP type.
1727+ * @senp_mod: SENPENABLE value for the sr
1728+ * @senn_mod: SENNENABLE value for sr
1729+ * @nvalue_count: Number of distinct nvalues in the nvalue table
1730+ * @enable_on_init: whether this sr module needs to enabled at
1731+ * boot up or not.
1732+ * @nvalue_table: table containing the efuse offsets and nvalues
1733+ * corresponding to them.
1734+ * @voltdm: Pointer to the voltage domain associated with the SR
1735+ */
1736+struct omap_sr_data {
1737+ int ip_type;
1738+ u32 senp_mod;
1739+ u32 senn_mod;
1740+ int nvalue_count;
1741+ bool enable_on_init;
1742+ struct omap_sr_nvalue_table *nvalue_table;
1743+ struct voltagedomain *voltdm;
1744+};
1745+
1746+/* Smartreflex module enable/disable interface */
1747+void omap_sr_enable(struct voltagedomain *voltdm);
1748+void omap_sr_disable(struct voltagedomain *voltdm);
1749+void omap_sr_disable_reset_volt(struct voltagedomain *voltdm);
1750+
1751+/* API to register the pmic specific data with the smartreflex driver. */
1752+void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data);
1753+
1754+/* Smartreflex driver hooks to be called from Smartreflex class driver */
1755+int sr_enable(struct voltagedomain *voltdm, unsigned long volt);
1756+void sr_disable(struct voltagedomain *voltdm);
1757+int sr_configure_errgen(struct voltagedomain *voltdm);
1758+int sr_configure_minmax(struct voltagedomain *voltdm);
1759+
1760+/* API to register the smartreflex class driver with the smartreflex driver */
1761+int sr_register_class(struct omap_sr_class_data *class_data);
1762+#else
1763+
1764+#ifdef CONFIG_AM33XX_SMARTREFLEX
1765+
1766+#define SR_CORE (0)
1767+#define SR_MPU (1)
1768+#define SRCLKLENGTH_125MHZ_SYSCLK (0x78 << 12)
1769+#define GAIN_MAXLIMIT (16)
1770+#define R_MAXLIMIT (256)
1771+#define MAX_SENSORS 2
1772+/* GG: eventually this should be determined at runtime */
1773+#define AM33XX_OPP_COUNT 4
1774+
1775+/**
1776+ * struct am33xx_sr_opp_data - Smartreflex data per OPP
1777+ * @efuse_offs: The offset of the efuse where n-target values are
1778+ * stored.
1779+ * @nvalue: NTarget as stored in EFUSE.
1780+ * @adj_nvalue: Adjusted NTarget (adjusted by margin)
1781+ * @e2v_gain: Error to voltage gain for changing the percentage
1782+ * error into voltage delta
1783+ * @err_weight: Average sensor error weight
1784+ * @err_minlimit: Minimum error limit of the sensor
1785+ * @err_maxlimit: Maximum error limit of the sensor
1786+ * @margin: Voltage margin to apply
1787+ * @nominal_volt: Nominal voltage for this OPP
1788+ * @frequency: Defined frequency for this OPP (in KHz)
1789+ */
1790+struct am33xx_sr_opp_data {
1791+ u32 efuse_offs;
1792+ u32 nvalue;
1793+ u32 adj_nvalue;
1794+ s32 e2v_gain;
1795+ u32 err_weight;
1796+ u32 err_minlimit;
1797+ u32 err_maxlimit;
1798+ s32 margin;
1799+ u32 nominal_volt; /* nominal_volt and frequency may be removed
1800+ once am33xx voltdm layer works */
1801+ u32 frequency;
1802+ u32 opp_id;
1803+};
1804+
1805+/**
1806+ * struct am33xx_sr_sdata - Smartreflex sensors data
1807+ * @sr_opp_data: Pointer to data structure containing per OPP data
1808+ * for this SR module.
1809+ * @no_of_opps: Number of OPP's supported for this sensor -
1810+ * determined dynamically when possible.
1811+ * @default_opp: Defines the opp to use on startup if OPP is fixed
1812+ * or cannot be determined dynamically.
1813+ * @senn_mod: Enable bit for N sensor
1814+ * @senp_mod: Enable bit for P sensor
1815+ */
1816+struct am33xx_sr_sdata {
1817+ struct am33xx_sr_opp_data *sr_opp_data;
1818+ u32 no_of_opps;
1819+ u32 default_opp;
1820+ u32 senn_mod;
1821+ u32 senp_mod;
1822+};
1823+
1824+struct am33xx_sr_sensor {
1825+ u32 sr_id;
1826+ u32 irq;
1827+ u32 irq_status;
1828+ u32 senn_en;
1829+ u32 senp_en;
1830+ char *name;
1831+ char *reg_name;
1832+ void __iomem *base;
1833+ int init_volt_mv;
1834+ int curr_opp;
1835+ u32 no_of_opps;
1836+ struct delayed_work work_reenable;
1837+ struct regulator *reg;
1838+ struct am33xx_sr_opp_data opp_data[AM33XX_OPP_COUNT];
1839+ struct clk *fck;
1840+ struct voltagedomain *voltdm;
1841+ struct omap_volt_data *volt_data;
1842+};
1843+
1844+struct am33xx_sr {
1845+ u32 autocomp_active;
1846+ u32 sens_per_vd;
1847+ u32 no_of_sens;
1848+ u32 no_of_vds;
1849+ u32 ip_type;
1850+ u32 irq_delay;
1851+ u32 disabled_by_user;
1852+ int uvoltage_step_size;
1853+ char *res_name[MAX_SENSORS];
1854+#ifdef CONFIG_CPU_FREQ
1855+ struct notifier_block freq_transition;
1856+#endif
1857+ /*struct work_struct work;*/
1858+ struct delayed_work work;
1859+ struct sr_platform_data *sr_data;
1860+ struct am33xx_sr_sensor sen[MAX_SENSORS];
1861+ struct platform_device *pdev;
1862+};
1863+
1864+/**
1865+ * struct am33xx_sr_platform_data - Smartreflex platform data.
1866+ * @sr_sdata: SR per sensor details, contains the efuse off-sets,
1867+ * error to voltage gain factor, minimum error limits
1868+ * @vd_name: Name of the voltage domain.
1869+ * @ip_type: Smartreflex IP type, class1 or class2 or class3.
1870+ * @irq_delay: Amount of time required for changed voltage to settle.
1871+ * @no_of_vds: Number of voltage domains to which SR applicable
1872+ * @no_of_sens: Number of SR sensors used to monitor the device
1873+ * performance, temp etc...
1874+ * @vstep_size_uv: PMIC voltage step size in micro volts
1875+ * @enable_on_init: whether this sr module needs to enabled at
1876+ * boot up or not.
1877+ */
1878+struct am33xx_sr_platform_data {
1879+ struct am33xx_sr_sdata *sr_sdata;
1880+ char *vd_name[2];
1881+ u32 ip_type;
1882+ u32 irq_delay;
1883+ u32 no_of_vds;
1884+ u32 no_of_sens;
1885+ u32 vstep_size_uv;
1886+ bool enable_on_init;
1887+};
1888+
1889+#endif /*CONFIG_AM33XX_SMARTREFLEX*/
1890+
1891+#ifdef CONFIG_TI816X_SMARTREFLEX
1892+
1893+#define SRHVT 0
1894+#define SRSVT 1
1895+
1896+/* SRClk = 100KHz */
1897+#define SRCLKLENGTH_125MHZ_SYSCLK (0x271 << 12)
1898+
1899+/**
1900+ * struct ti816x_sr_sdata - Smartreflex sensors data
1901+ * @efuse_offs: The offset of the efuse where n-target values are
1902+ * stored.
1903+ * @e2v_gain: Error to voltage gain for changing the percentage
1904+ * error into voltage delta
1905+ * @err_weight: Average sensor error weight
1906+ * @err_minlimit: Minimum error limit of the sensor
1907+ * @err_maxlimit: Maximum error limit of the sensor
1908+ * @senn_mod: Enable bit for N sensor
1909+ * @senp_mod: Enable bit for P sensor
1910+ */
1911+struct ti816x_sr_sdata {
1912+ u32 efuse_offs;
1913+ u32 e2v_gain;
1914+ u32 err_weight;
1915+ u32 err_minlimit;
1916+ u32 err_maxlimit;
1917+ u32 senn_mod;
1918+ u32 senp_mod;
1919+};
1920+
1921+/**
1922+ * struct ti816x_sr_platform_data - Smartreflex platform data.
1923+ * @sr_sdata: SR per sensor details, contains the efuse off-sets,
1924+ * error to voltage gain factor, minimum error limits
1925+ * @vd_name: Name of the voltage domain.
1926+ * @ip_type: Smartreflex IP type, class1 or class2 or class3.
1927+ * @irq_delay: Time delay between disable and re-enable the
1928+ * interrupts, in msec
1929+ * @no_of_vds: Number of voltage domains to which SR applicable
1930+ * @no_of_sens: Number of SR sensors used to monitor the device
1931+ * performance, temp etc...
1932+ * @vstep_size_uv: PMIC voltage step size in micro volts
1933+ * @enable_on_init: whether this sr module needs to enabled at
1934+ * boot up or not.
1935+ */
1936+struct ti816x_sr_platform_data {
1937+ struct ti816x_sr_sdata *sr_sdata;
1938+ char *vd_name;
1939+ u32 ip_type;
1940+ u32 irq_delay;
1941+ u32 no_of_vds;
1942+ u32 no_of_sens;
1943+ u32 vstep_size_uv;
1944+ bool enable_on_init;
1945+};
1946+
1947+#endif /* CONFIG_TI816X_SMARTREFLEX */
1948+
1949+static inline void omap_sr_enable(struct voltagedomain *voltdm) {}
1950+static inline void omap_sr_disable(struct voltagedomain *voltdm) {}
1951+static inline void omap_sr_disable_reset_volt(
1952+ struct voltagedomain *voltdm) {}
1953+static inline void omap_sr_register_pmic(
1954+ struct omap_sr_pmic_data *pmic_data) {}
1955+#endif
1956+#endif
1957diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
1958index 00706c6..382ce2d 100644
1959--- a/drivers/regulator/core.c
1960+++ b/drivers/regulator/core.c
1961@@ -169,6 +169,9 @@ static int regulator_check_consumers(struct regulator_dev *rdev,
1962 {
1963 struct regulator *regulator;
1964
1965+ if (rdev->ignore_check_consumers)
1966+ return 0;
1967+
1968 list_for_each_entry(regulator, &rdev->consumer_list, list) {
1969 /*
1970 * Assume consumers that didn't say anything are OK
1971@@ -2688,6 +2691,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
1972 rdev->reg_data = driver_data;
1973 rdev->owner = regulator_desc->owner;
1974 rdev->desc = regulator_desc;
1975+ rdev->ignore_check_consumers = init_data->ignore_check_consumers;
1976 INIT_LIST_HEAD(&rdev->consumer_list);
1977 INIT_LIST_HEAD(&rdev->list);
1978 BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
1979diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
1980index 52c89ae..6176167 100644
1981--- a/include/linux/regulator/driver.h
1982+++ b/include/linux/regulator/driver.h
1983@@ -204,7 +204,7 @@ struct regulator_dev {
1984 int deferred_disables;
1985
1986 void *reg_data; /* regulator_dev data */
1987-
1988+ int ignore_check_consumers;
1989 #ifdef CONFIG_DEBUG_FS
1990 struct dentry *debugfs;
1991 #endif
1992diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
1993index f3f13fd..0de52a3 100644
1994--- a/include/linux/regulator/machine.h
1995+++ b/include/linux/regulator/machine.h
1996@@ -169,7 +169,7 @@ struct regulator_consumer_supply {
1997 * be usable.
1998 * @num_consumer_supplies: Number of consumer device supplies.
1999 * @consumer_supplies: Consumer device supply configuration.
2000- *
2001+ * @ignore_check_consumers: If != 0, regulator_check_consumers() is disabled.
2002 * @regulator_init: Callback invoked when the regulator has been registered.
2003 * @driver_data: Data passed to regulator_init.
2004 */
2005@@ -181,6 +181,7 @@ struct regulator_init_data {
2006 int num_consumer_supplies;
2007 struct regulator_consumer_supply *consumer_supplies;
2008
2009+ int ignore_check_consumers;
2010 /* optional regulator machine specific init */
2011 int (*regulator_init)(void *driver_data);
2012 void *driver_data; /* core does not touch this */
2013--
20141.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-mach-omap2-pm33xx-Disable-VT-switch.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-mach-omap2-pm33xx-Disable-VT-switch.patch
new file mode 100644
index 00000000..66c643e9
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-mach-omap2-pm33xx-Disable-VT-switch.patch
@@ -0,0 +1,71 @@
1From 31ec2850e89414efb30accb9d8b5228257e507b1 Mon Sep 17 00:00:00 2001
2From: Chase Maupin <Chase.Maupin@ti.com>
3Date: Wed, 21 Mar 2012 10:18:03 -0500
4Subject: [PATCH 1/1] mach-omap2: pm33xx: Disable VT switch
5
6* Added a new config option TI_PM_DISABLE_VT_SWITCH which
7 disables the VT console switch which normally occurs during
8 suspend. This console switch can cause a hange when performed
9 with applications like Matrix running. The VT switch is
10 considered unnecessary.
11* Modified the am335x_evm_defconfig file to default the
12 TI_PM_DISABLE_VT_SWITCH to "y".
13* Based on a patch for the linux-omap3 kernel by Greg Guyotte
14
15Signed-off-by: Chase Maupin <Chase.Maupin@ti.com>
16---
17 arch/arm/configs/am335x_evm_defconfig | 1 +
18 arch/arm/mach-omap2/Kconfig | 9 +++++++++
19 arch/arm/mach-omap2/pm33xx.c | 5 +++++
20 3 files changed, 15 insertions(+), 0 deletions(-)
21
22diff --git a/arch/arm/configs/am335x_evm_defconfig b/arch/arm/configs/am335x_evm_defconfig
23index 53d1b6a..7a5e7ad 100644
24--- a/arch/arm/configs/am335x_evm_defconfig
25+++ b/arch/arm/configs/am335x_evm_defconfig
26@@ -325,6 +325,7 @@ CONFIG_MACH_TI8148EVM=y
27 CONFIG_MACH_AM335XEVM=y
28 CONFIG_MACH_AM335XIAEVM=y
29 # CONFIG_OMAP3_EMU is not set
30+CONFIG_TI_PM_DISABLE_VT_SWITCH=y
31 # CONFIG_OMAP3_SDRC_AC_TIMING is not set
32 CONFIG_OMAP3_EDMA=y
33
34diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
35index e44e942..f13e9dc 100644
36--- a/arch/arm/mach-omap2/Kconfig
37+++ b/arch/arm/mach-omap2/Kconfig
38@@ -372,6 +372,15 @@ config OMAP3_EMU
39 help
40 Say Y here to enable debugging hardware of omap3
41
42+config TI_PM_DISABLE_VT_SWITCH
43+ bool "TI Disable PM Console Switch"
44+ depends on ARCH_OMAP3
45+ default y
46+ help
47+ This option disables the default PM VT switch behavior for TI devices.
48+ Some platforms hang during suspend due to a failed attempt to
49+ perform the VT switch. The VT switch is unnecessary on many platforms.
50+
51 config OMAP3_SDRC_AC_TIMING
52 bool "Enable SDRC AC timing register changes"
53 depends on ARCH_OMAP3
54diff --git a/arch/arm/mach-omap2/pm33xx.c b/arch/arm/mach-omap2/pm33xx.c
55index 70bcb42..019ae46 100644
56--- a/arch/arm/mach-omap2/pm33xx.c
57+++ b/arch/arm/mach-omap2/pm33xx.c
58@@ -502,6 +502,11 @@ static int __init am33xx_pm_init(void)
59 pr_info("Power Management for AM33XX family\n");
60
61 #ifdef CONFIG_SUSPEND
62+
63+#ifdef CONFIG_TI_PM_DISABLE_VT_SWITCH
64+ pm_set_vt_switch(0);
65+#endif
66+
67 /* Read SDRAM_CONFIG register to determine Memory Type */
68 base = am33xx_get_ram_base();
69 reg = readl(base + EMIF4_0_SDRAM_CONFIG);
70--
711.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-musb-update-PIO-mode-help-information-in-Kconfig.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-musb-update-PIO-mode-help-information-in-Kconfig.patch
new file mode 100644
index 00000000..f7652bdf
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-musb-update-PIO-mode-help-information-in-Kconfig.patch
@@ -0,0 +1,45 @@
1From 214f6b2fee005dba5e01b3b434f184adf4386a25 Mon Sep 17 00:00:00 2001
2From: Chase Maupin <Chase.Maupin@ti.com>
3Date: Thu, 2 Feb 2012 15:52:10 -0600
4Subject: [PATCH] musb: update PIO mode help information in Kconfig
5
6* Updated the Kconfig help information for the PIO mode for MUSB
7 to make it more clear to the customer when to select this option
8 and which devices currently have issues with this option.
9* This is in accordance with the findings for CPPI4.1 DMA usage
10 for MUSB
11
12Upstream-Status: Submitted
13 * Submitted to the PSP team using the lpr list
14
15Signed-off-by: Matt Porter <mporter@ti.com>
16Signed-off-by: Chase Maupin <Chase.Maupin@ti.com>
17---
18 drivers/usb/musb/Kconfig | 12 ++++++++----
19 1 files changed, 8 insertions(+), 4 deletions(-)
20
21diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
22index a06335f..3576afe 100644
23--- a/drivers/usb/musb/Kconfig
24+++ b/drivers/usb/musb/Kconfig
25@@ -159,10 +159,14 @@ config MUSB_PIO_ONLY
26 All data is copied between memory and FIFO by the CPU.
27 DMA controllers are ignored.
28
29- Do not choose this unless DMA support for your SOC or board
30- is unavailable (or unstable). When DMA is enabled at compile time,
31- you can still disable it at run time using the "use_dma=n" module
32- parameter.
33+ Select 'y' here if DMA support for your SOC or board
34+ is unavailable (or unstable). On CPPI 4.1 DMA based
35+ systems (AM335x, AM35x, and AM180x) DMA support is
36+ considered unstable and this option should be enabled
37+ in production systems so that DMA is disabled, unless DMA
38+ has been validated for all use cases. When DMA is enabled at
39+ compile time, you can still disable it at run time using the
40+ "use_dma=n" module parameter.
41
42 endchoice
43
44--
451.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-omap-serial-add-delay-before-suspending.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-omap-serial-add-delay-before-suspending.patch
new file mode 100644
index 00000000..7780786c
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0001-omap-serial-add-delay-before-suspending.patch
@@ -0,0 +1,42 @@
1From 0f62d1f4d4543a315815b8eb15ea9cdad25d16c8 Mon Sep 17 00:00:00 2001
2From: Eyal Reizer <eyalr@ti.com>
3Date: Wed, 27 Jun 2012 16:08:53 +0300
4Subject: [PATCH] omap-serial: add delay before suspending
5
6In case suspending during Bluetooth traffic, after resume the bluetooth is
7stuck.
8It was identified that suspend is happening before the UART buffer was
9fully drained which caused this hang after resume.
10The folliwng delay is a temporary workaround until the issue is resolved
11properly.
12
13Upstream Status: Pending
14
15Signed-off-by: Eyal Reizer <eyalr@ti.com>
16---
17 drivers/tty/serial/omap-serial.c | 10 ++++++++++
18 1 files changed, 10 insertions(+), 0 deletions(-)
19
20diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
21index ca24ab3..108ea2b 100755
22--- a/drivers/tty/serial/omap-serial.c
23+++ b/drivers/tty/serial/omap-serial.c
24@@ -1166,6 +1166,16 @@ static int serial_omap_suspend(struct device *dev)
25 struct uart_omap_port *up = dev_get_drvdata(dev);
26
27 if (up) {
28+ /*
29+ In case suspending during Bluetooth traffic, after resume
30+ the bluetooth is stuck.
31+ It was identified that suspend is happening before the
32+ UART buffer was fully drained which caused this hang after
33+ resume. The following delay is a temporary workaround until
34+ the issue is resolved properly.
35+ */
36+ msleep(10);
37+
38 uart_suspend_port(&serial_omap_reg, &up->port);
39 flush_work_sync(&up->qos_work);
40 }
41--
421.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-AM335x-OCF-Driver-for-Linux-3.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-AM335x-OCF-Driver-for-Linux-3.patch
new file mode 100644
index 00000000..916b190c
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-AM335x-OCF-Driver-for-Linux-3.patch
@@ -0,0 +1,7228 @@
1From a97aac248717d62bdbf322c1d6d422ddfde87de0 Mon Sep 17 00:00:00 2001
2From: Greg Turner <gregturner@ti.com>
3Date: Thu, 3 May 2012 10:33:13 -0500
4Subject: [PATCH 2/2] AM335x OCF Driver for Linux 3
5
6---
7 crypto/Kconfig | 3 +
8 crypto/Makefile | 2 +
9 crypto/ocf/Config.in | 20 +
10 crypto/ocf/Kconfig | 48 ++
11 crypto/ocf/Makefile | 138 ++++
12 crypto/ocf/criov.c | 215 +++++
13 crypto/ocf/crypto.c | 1766 ++++++++++++++++++++++++++++++++++++++++++
14 crypto/ocf/cryptodev.c | 1069 +++++++++++++++++++++++++
15 crypto/ocf/cryptodev.h | 480 ++++++++++++
16 crypto/ocf/cryptosoft.c | 1322 +++++++++++++++++++++++++++++++
17 crypto/ocf/ocf-bench.c | 514 ++++++++++++
18 crypto/ocf/ocf-compat.h | 372 +++++++++
19 crypto/ocf/ocfnull/Makefile | 12 +
20 crypto/ocf/ocfnull/ocfnull.c | 204 +++++
21 crypto/ocf/random.c | 317 ++++++++
22 crypto/ocf/rndtest.c | 300 +++++++
23 crypto/ocf/rndtest.h | 54 ++
24 crypto/ocf/uio.h | 54 ++
25 drivers/char/random.c | 67 ++
26 fs/fcntl.c | 1 +
27 include/linux/miscdevice.h | 1 +
28 include/linux/random.h | 28 +
29 kernel/pid.c | 1 +
30 23 files changed, 6988 insertions(+), 0 deletions(-)
31 create mode 100755 crypto/ocf/Config.in
32 create mode 100755 crypto/ocf/Kconfig
33 create mode 100755 crypto/ocf/Makefile
34 create mode 100644 crypto/ocf/criov.c
35 create mode 100644 crypto/ocf/crypto.c
36 create mode 100644 crypto/ocf/cryptodev.c
37 create mode 100644 crypto/ocf/cryptodev.h
38 create mode 100644 crypto/ocf/cryptosoft.c
39 create mode 100644 crypto/ocf/ocf-bench.c
40 create mode 100644 crypto/ocf/ocf-compat.h
41 create mode 100644 crypto/ocf/ocfnull/Makefile
42 create mode 100644 crypto/ocf/ocfnull/ocfnull.c
43 create mode 100644 crypto/ocf/random.c
44 create mode 100644 crypto/ocf/rndtest.c
45 create mode 100644 crypto/ocf/rndtest.h
46 create mode 100644 crypto/ocf/uio.h
47
48diff --git a/crypto/Kconfig b/crypto/Kconfig
49index 527a857..8871f10 100644
50--- a/crypto/Kconfig
51+++ b/crypto/Kconfig
52@@ -923,3 +923,6 @@ config CRYPTO_USER_API_SKCIPHER
53 source "drivers/crypto/Kconfig"
54
55 endif # if CRYPTO
56+
57+source "crypto/ocf/Kconfig"
58+
59diff --git a/crypto/Makefile b/crypto/Makefile
60index 9e6eee2..3cde9f8 100644
61--- a/crypto/Makefile
62+++ b/crypto/Makefile
63@@ -91,6 +91,8 @@ obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o
64 obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
65 obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
66
67+obj-$(CONFIG_OCF_OCF) += ocf/
68+
69 #
70 # generic algorithms and the async_tx api
71 #
72diff --git a/crypto/ocf/Config.in b/crypto/ocf/Config.in
73new file mode 100755
74index 0000000..423d11f
75--- /dev/null
76+++ b/crypto/ocf/Config.in
77@@ -0,0 +1,20 @@
78+#############################################################################
79+
80+mainmenu_option next_comment
81+comment 'OCF Configuration'
82+tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF
83+dep_mbool ' enable fips RNG checks (fips check on RNG data before use)' \
84+ CONFIG_OCF_FIPS $CONFIG_OCF_OCF
85+dep_mbool ' enable harvesting entropy for /dev/random' \
86+ CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF
87+dep_tristate ' cryptodev (user space support)' \
88+ CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF
89+dep_tristate ' cryptosoft (software crypto engine)' \
90+ CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF
91+dep_tristate ' ocfnull (does no crypto)' \
92+ CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF
93+dep_tristate ' ocf-bench (HW crypto in-kernel benchmark)' \
94+ CONFIG_OCF_BENCH $CONFIG_OCF_OCF
95+endmenu
96+
97+#############################################################################
98diff --git a/crypto/ocf/Kconfig b/crypto/ocf/Kconfig
99new file mode 100755
100index 0000000..44459f4
101--- /dev/null
102+++ b/crypto/ocf/Kconfig
103@@ -0,0 +1,48 @@
104+menu "OCF Configuration"
105+
106+config OCF_OCF
107+ tristate "OCF (Open Cryptograhic Framework)"
108+ help
109+ A linux port of the OpenBSD/FreeBSD crypto framework.
110+
111+config OCF_RANDOMHARVEST
112+ bool "crypto random --- harvest entropy for /dev/random"
113+ depends on OCF_OCF
114+ help
115+ Includes code to harvest random numbers from devices that support it.
116+
117+config OCF_FIPS
118+ bool "enable fips RNG checks"
119+ depends on OCF_OCF && OCF_RANDOMHARVEST
120+ help
121+ Run all RNG provided data through a fips check before
122+ adding it /dev/random's entropy pool.
123+
124+config OCF_CRYPTODEV
125+ tristate "cryptodev (user space support)"
126+ depends on OCF_OCF
127+ help
128+ The user space API to access crypto hardware.
129+
130+config OCF_CRYPTOSOFT
131+ tristate "cryptosoft (software crypto engine)"
132+ depends on OCF_OCF
133+ help
134+ A software driver for the OCF framework that uses
135+ the kernel CryptoAPI.
136+
137+config OCF_OCFNULL
138+ tristate "ocfnull (fake crypto engine)"
139+ depends on OCF_OCF
140+ help
141+ OCF driver for measuring ipsec overheads (does no crypto)
142+
143+config OCF_BENCH
144+ tristate "ocf-bench (HW crypto in-kernel benchmark)"
145+ depends on OCF_OCF
146+ help
147+ A very simple encryption test for the in-kernel interface
148+ of OCF. Also includes code to benchmark the IXP Access library
149+ for comparison.
150+
151+endmenu
152diff --git a/crypto/ocf/Makefile b/crypto/ocf/Makefile
153new file mode 100755
154index 0000000..29ac280
155--- /dev/null
156+++ b/crypto/ocf/Makefile
157@@ -0,0 +1,138 @@
158+# for SGlinux builds
159+-include $(ROOTDIR)/modules/.config
160+
161+OCF_OBJS = crypto.o criov.o
162+
163+ifdef CONFIG_OCF_RANDOMHARVEST
164+ OCF_OBJS += random.o
165+endif
166+
167+ifdef CONFIG_OCF_FIPS
168+ OCF_OBJS += rndtest.o
169+endif
170+
171+# Add in autoconf.h to get #defines for CONFIG_xxx
172+AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h
173+ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))
174+ EXTRA_CFLAGS += -include $(AUTOCONF_H)
175+ export EXTRA_CFLAGS
176+endif
177+
178+ifndef obj
179+ obj ?= .
180+ _obj = subdir
181+ mod-subdirs := safe hifn ixp4xx talitos ocfnull
182+ export-objs += crypto.o criov.o random.o
183+ list-multi += ocf.o
184+ _slash :=
185+else
186+ _obj = obj
187+ _slash := /
188+endif
189+
190+EXTRA_CFLAGS += -I$(obj)/.
191+
192+obj-$(CONFIG_OCF_OCF) += ocf.o
193+obj-$(CONFIG_OCF_CRYPTODEV) += cryptodev.o
194+obj-$(CONFIG_OCF_CRYPTOSOFT) += cryptosoft.o
195+obj-$(CONFIG_OCF_BENCH) += ocf-bench.o
196+
197+$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
198+
199+ocf-objs := $(OCF_OBJS)
200+
201+dummy:
202+ @echo "Please consult the README for how to build OCF."
203+ @echo "If you can't wait then the following should do it:"
204+ @echo ""
205+ @echo " make ocf_modules"
206+ @echo " sudo make ocf_install"
207+ @echo ""
208+ @exit 1
209+
210+$(list-multi) dummy1: $(ocf-objs)
211+ $(LD) -r -o $@ $(ocf-objs)
212+
213+.PHONY:
214+clean:
215+ rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c
216+ rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags
217+ rm -f */modules.order */modules.builtin modules.order modules.builtin
218+
219+ifdef TOPDIR
220+-include $(TOPDIR)/Rules.make
221+endif
222+
223+#
224+# targets to build easily on the current machine
225+#
226+
227+ocf_make:
228+ make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m
229+ make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m CONFIG_OCF_CRYPTOSOFT=m
230+ -make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m CONFIG_OCF_BENCH=m
231+ -make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m CONFIG_OCF_OCFNULL=m
232+ -make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m CONFIG_OCF_HIFN=m
233+
234+ocf_modules:
235+ $(MAKE) ocf_make OCF_TARGET=modules
236+
237+ocf_install:
238+ $(MAKE) ocf_make OCF_TARGET="modules modules_install"
239+ depmod
240+ mkdir -p /usr/include/crypto
241+ cp cryptodev.h /usr/include/crypto/.
242+
243+#
244+# generate full kernel patches for 2.4 and 2.6 kernels to make patching
245+# your kernel easier
246+#
247+
248+.PHONY: patch
249+patch:
250+ patchbase=.; \
251+ [ -d $$patchbase/patches ] || patchbase=..; \
252+ patch=ocf-linux-base.patch; \
253+ patch24=ocf-linux-24.patch; \
254+ patch26=ocf-linux-26.patch; \
255+ patch3=ocf-linux-3.patch; \
256+ ( \
257+ find . -name Makefile; \
258+ find . -name Config.in; \
259+ find . -name Kconfig; \
260+ find . -name README; \
261+ find . -name '*.[ch]' | grep -v '.mod.c'; \
262+ ) | while read t; do \
263+ diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \
264+ done > $$patch; \
265+ cat $$patchbase/patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
266+ cat $$patchbase/patches/linux-2.6.38-ocf.patch $$patch > $$patch26; \
267+ cat $$patchbase/patches/linux-3.2.1-ocf.patch $$patch > $$patch3; \
268+
269+
270+#
271+# this target probably does nothing for anyone but me - davidm
272+#
273+
274+.PHONY: release
275+release:
276+ REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \
277+ CURDIR=`pwd`; \
278+ rm -rf /tmp/ocf-linux-$$REL*; \
279+ mkdir -p $$RELDIR/ocf; \
280+ mkdir -p $$RELDIR/patches; \
281+ mkdir -p $$RELDIR/crypto-tools; \
282+ cp README* $$RELDIR/.; \
283+ cp patches/[!C]* $$RELDIR/patches/.; \
284+ cp tools/[!C]* $$RELDIR/crypto-tools/.; \
285+ cp -r [!C]* Config.in $$RELDIR/ocf/.; \
286+ rm -rf $$RELDIR/ocf/patches $$RELDIR/ocf/tools; \
287+ rm -f $$RELDIR/ocf/README*; \
288+ cp $$CURDIR/../../user/crypto-tools/[!C]* $$RELDIR/crypto-tools/.; \
289+ make -C $$RELDIR/crypto-tools clean; \
290+ make -C $$RELDIR/ocf clean; \
291+ find $$RELDIR/ocf -name CVS | xargs rm -rf; \
292+ cd $$RELDIR/..; \
293+ tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \
294+ gzip -9 ocf-linux-$$REL.tar
295+
296diff --git a/crypto/ocf/criov.c b/crypto/ocf/criov.c
297new file mode 100644
298index 0000000..a8c1a8c
299--- /dev/null
300+++ b/crypto/ocf/criov.c
301@@ -0,0 +1,215 @@
302+/* $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $ */
303+
304+/*
305+ * Linux port done by David McCullough <david_mccullough@mcafee.com>
306+ * Copyright (C) 2006-2010 David McCullough
307+ * Copyright (C) 2004-2005 Intel Corporation.
308+ * The license and original author are listed below.
309+ *
310+ * Copyright (c) 1999 Theo de Raadt
311+ *
312+ * Redistribution and use in source and binary forms, with or without
313+ * modification, are permitted provided that the following conditions
314+ * are met:
315+ *
316+ * 1. Redistributions of source code must retain the above copyright
317+ * notice, this list of conditions and the following disclaimer.
318+ * 2. Redistributions in binary form must reproduce the above copyright
319+ * notice, this list of conditions and the following disclaimer in the
320+ * documentation and/or other materials provided with the distribution.
321+ * 3. The name of the author may not be used to endorse or promote products
322+ * derived from this software without specific prior written permission.
323+ *
324+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
325+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
326+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
327+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
328+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
329+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
330+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
331+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
332+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
333+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
334+ *
335+__FBSDID("$FreeBSD: src/sys/opencrypto/criov.c,v 1.5 2006/06/04 22:15:13 pjd Exp $");
336+ */
337+
338+#include <linux/version.h>
339+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
340+#include <linux/config.h>
341+#endif
342+#include <linux/module.h>
343+#include <linux/init.h>
344+#include <linux/slab.h>
345+#include <linux/uio.h>
346+#include <linux/skbuff.h>
347+#include <linux/kernel.h>
348+#include <linux/mm.h>
349+#include <asm/io.h>
350+
351+#include <uio.h>
352+#include <cryptodev.h>
353+
354+/*
355+ * This macro is only for avoiding code duplication, as we need to skip
356+ * given number of bytes in the same way in three functions below.
357+ */
358+#define CUIO_SKIP() do { \
359+ KASSERT(off >= 0, ("%s: off %d < 0", __func__, off)); \
360+ KASSERT(len >= 0, ("%s: len %d < 0", __func__, len)); \
361+ while (off > 0) { \
362+ KASSERT(iol >= 0, ("%s: empty in skip", __func__)); \
363+ if (off < iov->iov_len) \
364+ break; \
365+ off -= iov->iov_len; \
366+ iol--; \
367+ iov++; \
368+ } \
369+} while (0)
370+
371+void
372+cuio_copydata(struct uio* uio, int off, int len, caddr_t cp)
373+{
374+ struct iovec *iov = uio->uio_iov;
375+ int iol = uio->uio_iovcnt;
376+ unsigned count;
377+
378+ CUIO_SKIP();
379+ while (len > 0) {
380+ KASSERT(iol >= 0, ("%s: empty", __func__));
381+ count = min((int)(iov->iov_len - off), len);
382+ memcpy(cp, ((caddr_t)iov->iov_base) + off, count);
383+ len -= count;
384+ cp += count;
385+ off = 0;
386+ iol--;
387+ iov++;
388+ }
389+}
390+
391+void
392+cuio_copyback(struct uio* uio, int off, int len, caddr_t cp)
393+{
394+ struct iovec *iov = uio->uio_iov;
395+ int iol = uio->uio_iovcnt;
396+ unsigned count;
397+
398+ CUIO_SKIP();
399+ while (len > 0) {
400+ KASSERT(iol >= 0, ("%s: empty", __func__));
401+ count = min((int)(iov->iov_len - off), len);
402+ memcpy(((caddr_t)iov->iov_base) + off, cp, count);
403+ len -= count;
404+ cp += count;
405+ off = 0;
406+ iol--;
407+ iov++;
408+ }
409+}
410+
411+/*
412+ * Return a pointer to iov/offset of location in iovec list.
413+ */
414+struct iovec *
415+cuio_getptr(struct uio *uio, int loc, int *off)
416+{
417+ struct iovec *iov = uio->uio_iov;
418+ int iol = uio->uio_iovcnt;
419+
420+ while (loc >= 0) {
421+ /* Normal end of search */
422+ if (loc < iov->iov_len) {
423+ *off = loc;
424+ return (iov);
425+ }
426+
427+ loc -= iov->iov_len;
428+ if (iol == 0) {
429+ if (loc == 0) {
430+ /* Point at the end of valid data */
431+ *off = iov->iov_len;
432+ return (iov);
433+ } else
434+ return (NULL);
435+ } else {
436+ iov++, iol--;
437+ }
438+ }
439+
440+ return (NULL);
441+}
442+
443+EXPORT_SYMBOL(cuio_copyback);
444+EXPORT_SYMBOL(cuio_copydata);
445+EXPORT_SYMBOL(cuio_getptr);
446+
447+static void
448+skb_copy_bits_back(struct sk_buff *skb, int offset, caddr_t cp, int len)
449+{
450+ int i;
451+ if (offset < skb_headlen(skb)) {
452+ memcpy(skb->data + offset, cp, min_t(int, skb_headlen(skb), len));
453+ len -= skb_headlen(skb);
454+ cp += skb_headlen(skb);
455+ }
456+ offset -= skb_headlen(skb);
457+ for (i = 0; len > 0 && i < skb_shinfo(skb)->nr_frags; i++) {
458+ if (offset < skb_shinfo(skb)->frags[i].size) {
459+ memcpy(page_address(skb_frag_page(&skb_shinfo(skb)->frags[i])) +
460+ skb_shinfo(skb)->frags[i].page_offset,
461+ cp, min_t(int, skb_shinfo(skb)->frags[i].size, len));
462+ len -= skb_shinfo(skb)->frags[i].size;
463+ cp += skb_shinfo(skb)->frags[i].size;
464+ }
465+ offset -= skb_shinfo(skb)->frags[i].size;
466+ }
467+}
468+
469+void
470+crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in)
471+{
472+
473+ if ((flags & CRYPTO_F_SKBUF) != 0)
474+ skb_copy_bits_back((struct sk_buff *)buf, off, in, size);
475+ else if ((flags & CRYPTO_F_IOV) != 0)
476+ cuio_copyback((struct uio *)buf, off, size, in);
477+ else
478+ bcopy(in, buf + off, size);
479+}
480+
481+void
482+crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out)
483+{
484+
485+ if ((flags & CRYPTO_F_SKBUF) != 0)
486+ skb_copy_bits((struct sk_buff *)buf, off, out, size);
487+ else if ((flags & CRYPTO_F_IOV) != 0)
488+ cuio_copydata((struct uio *)buf, off, size, out);
489+ else
490+ bcopy(buf + off, out, size);
491+}
492+
493+int
494+crypto_apply(int flags, caddr_t buf, int off, int len,
495+ int (*f)(void *, void *, u_int), void *arg)
496+{
497+#if 0
498+ int error;
499+
500+ if ((flags & CRYPTO_F_SKBUF) != 0)
501+ error = XXXXXX((struct mbuf *)buf, off, len, f, arg);
502+ else if ((flags & CRYPTO_F_IOV) != 0)
503+ error = cuio_apply((struct uio *)buf, off, len, f, arg);
504+ else
505+ error = (*f)(arg, buf + off, len);
506+ return (error);
507+#else
508+ KASSERT(0, ("crypto_apply not implemented!\n"));
509+#endif
510+ return 0;
511+}
512+
513+EXPORT_SYMBOL(crypto_copyback);
514+EXPORT_SYMBOL(crypto_copydata);
515+EXPORT_SYMBOL(crypto_apply);
516+
517diff --git a/crypto/ocf/crypto.c b/crypto/ocf/crypto.c
518new file mode 100644
519index 0000000..f48210d
520--- /dev/null
521+++ b/crypto/ocf/crypto.c
522@@ -0,0 +1,1766 @@
523+/*-
524+ * Linux port done by David McCullough <david_mccullough@mcafee.com>
525+ * Copyright (C) 2006-2010 David McCullough
526+ * Copyright (C) 2004-2005 Intel Corporation.
527+ * The license and original author are listed below.
528+ *
529+ * Redistribution and use in source and binary forms, with or without
530+ * Copyright (c) 2002-2006 Sam Leffler. All rights reserved.
531+ *
532+ * modification, are permitted provided that the following conditions
533+ * are met:
534+ * 1. Redistributions of source code must retain the above copyright
535+ * notice, this list of conditions and the following disclaimer.
536+ * 2. Redistributions in binary form must reproduce the above copyright
537+ * notice, this list of conditions and the following disclaimer in the
538+ * documentation and/or other materials provided with the distribution.
539+ *
540+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
541+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
542+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
543+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
544+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
545+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
546+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
547+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
548+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
549+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
550+ */
551+
552+#if 0
553+#include <sys/cdefs.h>
554+__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.27 2007/03/21 03:42:51 sam Exp $");
555+#endif
556+
557+/*
558+ * Cryptographic Subsystem.
559+ *
560+ * This code is derived from the Openbsd Cryptographic Framework (OCF)
561+ * that has the copyright shown below. Very little of the original
562+ * code remains.
563+ */
564+/*-
565+ * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
566+ *
567+ * This code was written by Angelos D. Keromytis in Athens, Greece, in
568+ * February 2000. Network Security Technologies Inc. (NSTI) kindly
569+ * supported the development of this code.
570+ *
571+ * Copyright (c) 2000, 2001 Angelos D. Keromytis
572+ *
573+ * Permission to use, copy, and modify this software with or without fee
574+ * is hereby granted, provided that this entire notice is included in
575+ * all source code copies of any software which is or includes a copy or
576+ * modification of this software.
577+ *
578+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
579+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
580+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
581+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
582+ * PURPOSE.
583+ *
584+__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp Exp $");
585+ */
586+
587+
588+#include <linux/version.h>
589+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
590+#include <linux/config.h>
591+#endif
592+#include <linux/module.h>
593+#include <linux/init.h>
594+#include <linux/list.h>
595+#include <linux/slab.h>
596+#include <linux/wait.h>
597+#include <linux/sched.h>
598+#include <linux/spinlock.h>
599+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4)
600+#include <linux/kthread.h>
601+#endif
602+#include <cryptodev.h>
603+
604+/*
605+ * keep track of whether or not we have been initialised, a big
606+ * issue if we are linked into the kernel and a driver gets started before
607+ * us
608+ */
609+static int crypto_initted = 0;
610+
611+/*
612+ * Crypto drivers register themselves by allocating a slot in the
613+ * crypto_drivers table with crypto_get_driverid() and then registering
614+ * each algorithm they support with crypto_register() and crypto_kregister().
615+ */
616+
617+/*
618+ * lock on driver table
619+ * we track its state as spin_is_locked does not do anything on non-SMP boxes
620+ */
621+static spinlock_t crypto_drivers_lock;
622+static int crypto_drivers_locked; /* for non-SMP boxes */
623+
624+#define CRYPTO_DRIVER_LOCK() \
625+ ({ \
626+ spin_lock_irqsave(&crypto_drivers_lock, d_flags); \
627+ crypto_drivers_locked = 1; \
628+ dprintk("%s,%d: DRIVER_LOCK()\n", __FILE__, __LINE__); \
629+ })
630+#define CRYPTO_DRIVER_UNLOCK() \
631+ ({ \
632+ dprintk("%s,%d: DRIVER_UNLOCK()\n", __FILE__, __LINE__); \
633+ crypto_drivers_locked = 0; \
634+ spin_unlock_irqrestore(&crypto_drivers_lock, d_flags); \
635+ })
636+#define CRYPTO_DRIVER_ASSERT() \
637+ ({ \
638+ if (!crypto_drivers_locked) { \
639+ dprintk("%s,%d: DRIVER_ASSERT!\n", __FILE__, __LINE__); \
640+ } \
641+ })
642+
643+/*
644+ * Crypto device/driver capabilities structure.
645+ *
646+ * Synchronization:
647+ * (d) - protected by CRYPTO_DRIVER_LOCK()
648+ * (q) - protected by CRYPTO_Q_LOCK()
649+ * Not tagged fields are read-only.
650+ */
651+struct cryptocap {
652+ device_t cc_dev; /* (d) device/driver */
653+ u_int32_t cc_sessions; /* (d) # of sessions */
654+ u_int32_t cc_koperations; /* (d) # os asym operations */
655+ /*
656+ * Largest possible operator length (in bits) for each type of
657+ * encryption algorithm. XXX not used
658+ */
659+ u_int16_t cc_max_op_len[CRYPTO_ALGORITHM_MAX + 1];
660+ u_int8_t cc_alg[CRYPTO_ALGORITHM_MAX + 1];
661+ u_int8_t cc_kalg[CRK_ALGORITHM_MAX + 1];
662+
663+ int cc_flags; /* (d) flags */
664+#define CRYPTOCAP_F_CLEANUP 0x80000000 /* needs resource cleanup */
665+ int cc_qblocked; /* (q) symmetric q blocked */
666+ int cc_kqblocked; /* (q) asymmetric q blocked */
667+
668+ int cc_unqblocked; /* (q) symmetric q blocked */
669+ int cc_unkqblocked; /* (q) asymmetric q blocked */
670+};
671+static struct cryptocap *crypto_drivers = NULL;
672+static int crypto_drivers_num = 0;
673+
674+/*
675+ * There are two queues for crypto requests; one for symmetric (e.g.
676+ * cipher) operations and one for asymmetric (e.g. MOD)operations.
677+ * A single mutex is used to lock access to both queues. We could
678+ * have one per-queue but having one simplifies handling of block/unblock
679+ * operations.
680+ */
681+static LIST_HEAD(crp_q); /* crypto request queue */
682+static LIST_HEAD(crp_kq); /* asym request queue */
683+
684+static spinlock_t crypto_q_lock;
685+
686+int crypto_all_qblocked = 0; /* protect with Q_LOCK */
687+module_param(crypto_all_qblocked, int, 0444);
688+MODULE_PARM_DESC(crypto_all_qblocked, "Are all crypto queues blocked");
689+
690+int crypto_all_kqblocked = 0; /* protect with Q_LOCK */
691+module_param(crypto_all_kqblocked, int, 0444);
692+MODULE_PARM_DESC(crypto_all_kqblocked, "Are all asym crypto queues blocked");
693+
694+#define CRYPTO_Q_LOCK() \
695+ ({ \
696+ spin_lock_irqsave(&crypto_q_lock, q_flags); \
697+ dprintk("%s,%d: Q_LOCK()\n", __FILE__, __LINE__); \
698+ })
699+#define CRYPTO_Q_UNLOCK() \
700+ ({ \
701+ dprintk("%s,%d: Q_UNLOCK()\n", __FILE__, __LINE__); \
702+ spin_unlock_irqrestore(&crypto_q_lock, q_flags); \
703+ })
704+
705+/*
706+ * There are two queues for processing completed crypto requests; one
707+ * for the symmetric and one for the asymmetric ops. We only need one
708+ * but have two to avoid type futzing (cryptop vs. cryptkop). A single
709+ * mutex is used to lock access to both queues. Note that this lock
710+ * must be separate from the lock on request queues to insure driver
711+ * callbacks don't generate lock order reversals.
712+ */
713+static LIST_HEAD(crp_ret_q); /* callback queues */
714+static LIST_HEAD(crp_ret_kq);
715+
716+static spinlock_t crypto_ret_q_lock;
717+#define CRYPTO_RETQ_LOCK() \
718+ ({ \
719+ spin_lock_irqsave(&crypto_ret_q_lock, r_flags); \
720+ dprintk("%s,%d: RETQ_LOCK\n", __FILE__, __LINE__); \
721+ })
722+#define CRYPTO_RETQ_UNLOCK() \
723+ ({ \
724+ dprintk("%s,%d: RETQ_UNLOCK\n", __FILE__, __LINE__); \
725+ spin_unlock_irqrestore(&crypto_ret_q_lock, r_flags); \
726+ })
727+#define CRYPTO_RETQ_EMPTY() (list_empty(&crp_ret_q) && list_empty(&crp_ret_kq))
728+
729+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
730+static kmem_cache_t *cryptop_zone;
731+static kmem_cache_t *cryptodesc_zone;
732+#else
733+static struct kmem_cache *cryptop_zone;
734+static struct kmem_cache *cryptodesc_zone;
735+#endif
736+
737+#define debug crypto_debug
738+int crypto_debug = 0;
739+module_param(crypto_debug, int, 0644);
740+MODULE_PARM_DESC(crypto_debug, "Enable debug");
741+EXPORT_SYMBOL(crypto_debug);
742+
743+/*
744+ * Maximum number of outstanding crypto requests before we start
745+ * failing requests. We need this to prevent DOS when too many
746+ * requests are arriving for us to keep up. Otherwise we will
747+ * run the system out of memory. Since crypto is slow, we are
748+ * usually the bottleneck that needs to say, enough is enough.
749+ *
750+ * We cannot print errors when this condition occurs, we are already too
751+ * slow, printing anything will just kill us
752+ */
753+
754+static int crypto_q_cnt = 0;
755+module_param(crypto_q_cnt, int, 0444);
756+MODULE_PARM_DESC(crypto_q_cnt,
757+ "Current number of outstanding crypto requests");
758+
759+static int crypto_q_max = 1000;
760+module_param(crypto_q_max, int, 0644);
761+MODULE_PARM_DESC(crypto_q_max,
762+ "Maximum number of outstanding crypto requests");
763+
764+#define bootverbose crypto_verbose
765+static int crypto_verbose = 0;
766+module_param(crypto_verbose, int, 0644);
767+MODULE_PARM_DESC(crypto_verbose,
768+ "Enable verbose crypto startup");
769+
770+int crypto_usercrypto = 1; /* userland may do crypto reqs */
771+module_param(crypto_usercrypto, int, 0644);
772+MODULE_PARM_DESC(crypto_usercrypto,
773+ "Enable/disable user-mode access to crypto support");
774+
775+int crypto_userasymcrypto = 1; /* userland may do asym crypto reqs */
776+module_param(crypto_userasymcrypto, int, 0644);
777+MODULE_PARM_DESC(crypto_userasymcrypto,
778+ "Enable/disable user-mode access to asymmetric crypto support");
779+
780+int crypto_devallowsoft = 0; /* only use hardware crypto */
781+module_param(crypto_devallowsoft, int, 0644);
782+MODULE_PARM_DESC(crypto_devallowsoft,
783+ "Enable/disable use of software crypto support");
784+
785+/*
786+ * This parameter controls the maximum number of crypto operations to
787+ * do consecutively in the crypto kernel thread before scheduling to allow
788+ * other processes to run. Without it, it is possible to get into a
789+ * situation where the crypto thread never allows any other processes to run.
790+ * Default to 1000 which should be less than one second.
791+ */
792+static int crypto_max_loopcount = 1000;
793+module_param(crypto_max_loopcount, int, 0644);
794+MODULE_PARM_DESC(crypto_max_loopcount,
795+ "Maximum number of crypto ops to do before yielding to other processes");
796+
797+#ifndef CONFIG_NR_CPUS
798+#define CONFIG_NR_CPUS 1
799+#endif
800+
801+static struct task_struct *cryptoproc[CONFIG_NR_CPUS];
802+static struct task_struct *cryptoretproc[CONFIG_NR_CPUS];
803+static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait);
804+static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait);
805+
806+static int crypto_proc(void *arg);
807+static int crypto_ret_proc(void *arg);
808+static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);
809+static int crypto_kinvoke(struct cryptkop *krp, int flags);
810+static void crypto_exit(void);
811+static int crypto_init(void);
812+
813+static struct cryptostats cryptostats;
814+
815+static struct cryptocap *
816+crypto_checkdriver(u_int32_t hid)
817+{
818+ if (crypto_drivers == NULL)
819+ return NULL;
820+ return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]);
821+}
822+
823+/*
824+ * Compare a driver's list of supported algorithms against another
825+ * list; return non-zero if all algorithms are supported.
826+ */
827+static int
828+driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri)
829+{
830+ const struct cryptoini *cr;
831+
832+ /* See if all the algorithms are supported. */
833+ for (cr = cri; cr; cr = cr->cri_next)
834+ if (cap->cc_alg[cr->cri_alg] == 0)
835+ return 0;
836+ return 1;
837+}
838+
839+
840+/*
841+ * Select a driver for a new session that supports the specified
842+ * algorithms and, optionally, is constrained according to the flags.
843+ * The algorithm we use here is pretty stupid; just use the
844+ * first driver that supports all the algorithms we need. If there
845+ * are multiple drivers we choose the driver with the fewest active
846+ * sessions. We prefer hardware-backed drivers to software ones.
847+ *
848+ * XXX We need more smarts here (in real life too, but that's
849+ * XXX another story altogether).
850+ */
851+static struct cryptocap *
852+crypto_select_driver(const struct cryptoini *cri, int flags)
853+{
854+ struct cryptocap *cap, *best;
855+ int match, hid;
856+
857+ CRYPTO_DRIVER_ASSERT();
858+
859+ /*
860+ * Look first for hardware crypto devices if permitted.
861+ */
862+ if (flags & CRYPTOCAP_F_HARDWARE)
863+ match = CRYPTOCAP_F_HARDWARE;
864+ else
865+ match = CRYPTOCAP_F_SOFTWARE;
866+ best = NULL;
867+again:
868+ for (hid = 0; hid < crypto_drivers_num; hid++) {
869+ cap = &crypto_drivers[hid];
870+ /*
871+ * If it's not initialized, is in the process of
872+ * going away, or is not appropriate (hardware
873+ * or software based on match), then skip.
874+ */
875+ if (cap->cc_dev == NULL ||
876+ (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
877+ (cap->cc_flags & match) == 0)
878+ continue;
879+
880+ /* verify all the algorithms are supported. */
881+ if (driver_suitable(cap, cri)) {
882+ if (best == NULL ||
883+ cap->cc_sessions < best->cc_sessions)
884+ best = cap;
885+ }
886+ }
887+ if (best != NULL)
888+ return best;
889+ if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
890+ /* sort of an Algol 68-style for loop */
891+ match = CRYPTOCAP_F_SOFTWARE;
892+ goto again;
893+ }
894+ return best;
895+}
896+
897+/*
898+ * Create a new session. The crid argument specifies a crypto
899+ * driver to use or constraints on a driver to select (hardware
900+ * only, software only, either). Whatever driver is selected
901+ * must be capable of the requested crypto algorithms.
902+ */
903+int
904+crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid)
905+{
906+ struct cryptocap *cap;
907+ u_int32_t hid, lid;
908+ int err;
909+ unsigned long d_flags;
910+
911+ CRYPTO_DRIVER_LOCK();
912+ if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
913+ /*
914+ * Use specified driver; verify it is capable.
915+ */
916+ cap = crypto_checkdriver(crid);
917+ if (cap != NULL && !driver_suitable(cap, cri))
918+ cap = NULL;
919+ } else {
920+ /*
921+ * No requested driver; select based on crid flags.
922+ */
923+ cap = crypto_select_driver(cri, crid);
924+ /*
925+ * if NULL then can't do everything in one session.
926+ * XXX Fix this. We need to inject a "virtual" session
927+ * XXX layer right about here.
928+ */
929+ }
930+ if (cap != NULL) {
931+ /* Call the driver initialization routine. */
932+ hid = cap - crypto_drivers;
933+ lid = hid; /* Pass the driver ID. */
934+ cap->cc_sessions++;
935+ CRYPTO_DRIVER_UNLOCK();
936+ err = CRYPTODEV_NEWSESSION(cap->cc_dev, &lid, cri);
937+ CRYPTO_DRIVER_LOCK();
938+ if (err == 0) {
939+ (*sid) = (cap->cc_flags & 0xff000000)
940+ | (hid & 0x00ffffff);
941+ (*sid) <<= 32;
942+ (*sid) |= (lid & 0xffffffff);
943+ } else
944+ cap->cc_sessions--;
945+ } else
946+ err = EINVAL;
947+ CRYPTO_DRIVER_UNLOCK();
948+ return err;
949+}
950+
951+static void
952+crypto_remove(struct cryptocap *cap)
953+{
954+ CRYPTO_DRIVER_ASSERT();
955+ if (cap->cc_sessions == 0 && cap->cc_koperations == 0)
956+ bzero(cap, sizeof(*cap));
957+}
958+
959+/*
960+ * Delete an existing session (or a reserved session on an unregistered
961+ * driver).
962+ */
963+int
964+crypto_freesession(u_int64_t sid)
965+{
966+ struct cryptocap *cap;
967+ u_int32_t hid;
968+ int err = 0;
969+ unsigned long d_flags;
970+
971+ dprintk("%s()\n", __FUNCTION__);
972+ CRYPTO_DRIVER_LOCK();
973+
974+ if (crypto_drivers == NULL) {
975+ err = EINVAL;
976+ goto done;
977+ }
978+
979+ /* Determine two IDs. */
980+ hid = CRYPTO_SESID2HID(sid);
981+
982+ if (hid >= crypto_drivers_num) {
983+ dprintk("%s - INVALID DRIVER NUM %d\n", __FUNCTION__, hid);
984+ err = ENOENT;
985+ goto done;
986+ }
987+ cap = &crypto_drivers[hid];
988+
989+ if (cap->cc_dev) {
990+ CRYPTO_DRIVER_UNLOCK();
991+ /* Call the driver cleanup routine, if available, unlocked. */
992+ err = CRYPTODEV_FREESESSION(cap->cc_dev, sid);
993+ CRYPTO_DRIVER_LOCK();
994+ }
995+
996+ if (cap->cc_sessions)
997+ cap->cc_sessions--;
998+
999+ if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
1000+ crypto_remove(cap);
1001+
1002+done:
1003+ CRYPTO_DRIVER_UNLOCK();
1004+ return err;
1005+}
1006+
1007+/*
1008+ * Return an unused driver id. Used by drivers prior to registering
1009+ * support for the algorithms they handle.
1010+ */
1011+int32_t
1012+crypto_get_driverid(device_t dev, int flags)
1013+{
1014+ struct cryptocap *newdrv;
1015+ int i;
1016+ unsigned long d_flags;
1017+
1018+ if ((flags & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
1019+ printf("%s: no flags specified when registering driver\n",
1020+ device_get_nameunit(dev));
1021+ return -1;
1022+ }
1023+
1024+ CRYPTO_DRIVER_LOCK();
1025+
1026+ for (i = 0; i < crypto_drivers_num; i++) {
1027+ if (crypto_drivers[i].cc_dev == NULL &&
1028+ (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0) {
1029+ break;
1030+ }
1031+ }
1032+
1033+ /* Out of entries, allocate some more. */
1034+ if (i == crypto_drivers_num) {
1035+ /* Be careful about wrap-around. */
1036+ if (2 * crypto_drivers_num <= crypto_drivers_num) {
1037+ CRYPTO_DRIVER_UNLOCK();
1038+ printk("crypto: driver count wraparound!\n");
1039+ return -1;
1040+ }
1041+
1042+ newdrv = kmalloc(2 * crypto_drivers_num * sizeof(struct cryptocap),
1043+ GFP_KERNEL);
1044+ if (newdrv == NULL) {
1045+ CRYPTO_DRIVER_UNLOCK();
1046+ printk("crypto: no space to expand driver table!\n");
1047+ return -1;
1048+ }
1049+
1050+ memcpy(newdrv, crypto_drivers,
1051+ crypto_drivers_num * sizeof(struct cryptocap));
1052+ memset(&newdrv[crypto_drivers_num], 0,
1053+ crypto_drivers_num * sizeof(struct cryptocap));
1054+
1055+ crypto_drivers_num *= 2;
1056+
1057+ kfree(crypto_drivers);
1058+ crypto_drivers = newdrv;
1059+ }
1060+
1061+ /* NB: state is zero'd on free */
1062+ crypto_drivers[i].cc_sessions = 1; /* Mark */
1063+ crypto_drivers[i].cc_dev = dev;
1064+ crypto_drivers[i].cc_flags = flags;
1065+ if (bootverbose)
1066+ printf("crypto: assign %s driver id %u, flags %u\n",
1067+ device_get_nameunit(dev), i, flags);
1068+
1069+ CRYPTO_DRIVER_UNLOCK();
1070+
1071+ return i;
1072+}
1073+
1074+/*
1075+ * Lookup a driver by name. We match against the full device
1076+ * name and unit, and against just the name. The latter gives
1077+ * us a simple widlcarding by device name. On success return the
1078+ * driver/hardware identifier; otherwise return -1.
1079+ */
1080+int
1081+crypto_find_driver(const char *match)
1082+{
1083+ int i, len = strlen(match);
1084+ unsigned long d_flags;
1085+
1086+ CRYPTO_DRIVER_LOCK();
1087+ for (i = 0; i < crypto_drivers_num; i++) {
1088+ device_t dev = crypto_drivers[i].cc_dev;
1089+ if (dev == NULL ||
1090+ (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP))
1091+ continue;
1092+ if (strncmp(match, device_get_nameunit(dev), len) == 0 ||
1093+ strncmp(match, device_get_name(dev), len) == 0)
1094+ break;
1095+ }
1096+ CRYPTO_DRIVER_UNLOCK();
1097+ return i < crypto_drivers_num ? i : -1;
1098+}
1099+
1100+/*
1101+ * Return the device_t for the specified driver or NULL
1102+ * if the driver identifier is invalid.
1103+ */
1104+device_t
1105+crypto_find_device_byhid(int hid)
1106+{
1107+ struct cryptocap *cap = crypto_checkdriver(hid);
1108+ return cap != NULL ? cap->cc_dev : NULL;
1109+}
1110+
1111+/*
1112+ * Return the device/driver capabilities.
1113+ */
1114+int
1115+crypto_getcaps(int hid)
1116+{
1117+ struct cryptocap *cap = crypto_checkdriver(hid);
1118+ return cap != NULL ? cap->cc_flags : 0;
1119+}
1120+
1121+/*
1122+ * Register support for a key-related algorithm. This routine
1123+ * is called once for each algorithm supported a driver.
1124+ */
1125+int
1126+crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags)
1127+{
1128+ struct cryptocap *cap;
1129+ int err;
1130+ unsigned long d_flags;
1131+
1132+ dprintk("%s()\n", __FUNCTION__);
1133+ CRYPTO_DRIVER_LOCK();
1134+
1135+ cap = crypto_checkdriver(driverid);
1136+ if (cap != NULL &&
1137+ (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {
1138+ /*
1139+ * XXX Do some performance testing to determine placing.
1140+ * XXX We probably need an auxiliary data structure that
1141+ * XXX describes relative performances.
1142+ */
1143+
1144+ cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
1145+ if (bootverbose)
1146+ printf("crypto: %s registers key alg %u flags %u\n"
1147+ , device_get_nameunit(cap->cc_dev)
1148+ , kalg
1149+ , flags
1150+ );
1151+ err = 0;
1152+ } else
1153+ err = EINVAL;
1154+
1155+ CRYPTO_DRIVER_UNLOCK();
1156+ return err;
1157+}
1158+
1159+/*
1160+ * Register support for a non-key-related algorithm. This routine
1161+ * is called once for each such algorithm supported by a driver.
1162+ */
1163+int
1164+crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
1165+ u_int32_t flags)
1166+{
1167+ struct cryptocap *cap;
1168+ int err;
1169+ unsigned long d_flags;
1170+
1171+ dprintk("%s(id=0x%x, alg=%d, maxoplen=%d, flags=0x%x)\n", __FUNCTION__,
1172+ driverid, alg, maxoplen, flags);
1173+
1174+ CRYPTO_DRIVER_LOCK();
1175+
1176+ cap = crypto_checkdriver(driverid);
1177+ /* NB: algorithms are in the range [1..max] */
1178+ if (cap != NULL &&
1179+ (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) {
1180+ /*
1181+ * XXX Do some performance testing to determine placing.
1182+ * XXX We probably need an auxiliary data structure that
1183+ * XXX describes relative performances.
1184+ */
1185+
1186+ cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
1187+ cap->cc_max_op_len[alg] = maxoplen;
1188+ if (bootverbose)
1189+ printf("crypto: %s registers alg %u flags %u maxoplen %u\n"
1190+ , device_get_nameunit(cap->cc_dev)
1191+ , alg
1192+ , flags
1193+ , maxoplen
1194+ );
1195+ cap->cc_sessions = 0; /* Unmark */
1196+ err = 0;
1197+ } else
1198+ err = EINVAL;
1199+
1200+ CRYPTO_DRIVER_UNLOCK();
1201+ return err;
1202+}
1203+
1204+static void
1205+driver_finis(struct cryptocap *cap)
1206+{
1207+ u_int32_t ses, kops;
1208+
1209+ CRYPTO_DRIVER_ASSERT();
1210+
1211+ ses = cap->cc_sessions;
1212+ kops = cap->cc_koperations;
1213+ bzero(cap, sizeof(*cap));
1214+ if (ses != 0 || kops != 0) {
1215+ /*
1216+ * If there are pending sessions,
1217+ * just mark as invalid.
1218+ */
1219+ cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
1220+ cap->cc_sessions = ses;
1221+ cap->cc_koperations = kops;
1222+ }
1223+}
1224+
1225+/*
1226+ * Unregister a crypto driver. If there are pending sessions using it,
1227+ * leave enough information around so that subsequent calls using those
1228+ * sessions will correctly detect the driver has been unregistered and
1229+ * reroute requests.
1230+ */
1231+int
1232+crypto_unregister(u_int32_t driverid, int alg)
1233+{
1234+ struct cryptocap *cap;
1235+ int i, err;
1236+ unsigned long d_flags;
1237+
1238+ dprintk("%s()\n", __FUNCTION__);
1239+ CRYPTO_DRIVER_LOCK();
1240+
1241+ cap = crypto_checkdriver(driverid);
1242+ if (cap != NULL &&
1243+ (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) &&
1244+ cap->cc_alg[alg] != 0) {
1245+ cap->cc_alg[alg] = 0;
1246+ cap->cc_max_op_len[alg] = 0;
1247+
1248+ /* Was this the last algorithm ? */
1249+ for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
1250+ if (cap->cc_alg[i] != 0)
1251+ break;
1252+
1253+ if (i == CRYPTO_ALGORITHM_MAX + 1)
1254+ driver_finis(cap);
1255+ err = 0;
1256+ } else
1257+ err = EINVAL;
1258+ CRYPTO_DRIVER_UNLOCK();
1259+ return err;
1260+}
1261+
1262+/*
1263+ * Unregister all algorithms associated with a crypto driver.
1264+ * If there are pending sessions using it, leave enough information
1265+ * around so that subsequent calls using those sessions will
1266+ * correctly detect the driver has been unregistered and reroute
1267+ * requests.
1268+ */
1269+int
1270+crypto_unregister_all(u_int32_t driverid)
1271+{
1272+ struct cryptocap *cap;
1273+ int err;
1274+ unsigned long d_flags;
1275+
1276+ dprintk("%s()\n", __FUNCTION__);
1277+ CRYPTO_DRIVER_LOCK();
1278+ cap = crypto_checkdriver(driverid);
1279+ if (cap != NULL) {
1280+ driver_finis(cap);
1281+ err = 0;
1282+ } else
1283+ err = EINVAL;
1284+ CRYPTO_DRIVER_UNLOCK();
1285+
1286+ return err;
1287+}
1288+
1289+/*
1290+ * Clear blockage on a driver. The what parameter indicates whether
1291+ * the driver is now ready for cryptop's and/or cryptokop's.
1292+ */
1293+int
1294+crypto_unblock(u_int32_t driverid, int what)
1295+{
1296+ struct cryptocap *cap;
1297+ int err;
1298+ unsigned long q_flags;
1299+
1300+ CRYPTO_Q_LOCK();
1301+ cap = crypto_checkdriver(driverid);
1302+ if (cap != NULL) {
1303+ if (what & CRYPTO_SYMQ) {
1304+ cap->cc_qblocked = 0;
1305+ cap->cc_unqblocked = 0;
1306+ crypto_all_qblocked = 0;
1307+ }
1308+ if (what & CRYPTO_ASYMQ) {
1309+ cap->cc_kqblocked = 0;
1310+ cap->cc_unkqblocked = 0;
1311+ crypto_all_kqblocked = 0;
1312+ }
1313+ wake_up_interruptible(&cryptoproc_wait);
1314+ err = 0;
1315+ } else
1316+ err = EINVAL;
1317+ CRYPTO_Q_UNLOCK(); //DAVIDM should this be a driver lock
1318+
1319+ return err;
1320+}
1321+
1322+/*
1323+ * Add a crypto request to a queue, to be processed by the kernel thread.
1324+ */
1325+int
1326+crypto_dispatch(struct cryptop *crp)
1327+{
1328+ struct cryptocap *cap;
1329+ int result = -1;
1330+ unsigned long q_flags;
1331+
1332+ dprintk("%s()\n", __FUNCTION__);
1333+
1334+ cryptostats.cs_ops++;
1335+
1336+ CRYPTO_Q_LOCK();
1337+ if (crypto_q_cnt >= crypto_q_max) {
1338+ cryptostats.cs_drops++;
1339+ CRYPTO_Q_UNLOCK();
1340+ return ENOMEM;
1341+ }
1342+ crypto_q_cnt++;
1343+
1344+ /* make sure we are starting a fresh run on this crp. */
1345+ crp->crp_flags &= ~CRYPTO_F_DONE;
1346+ crp->crp_etype = 0;
1347+
1348+ /*
1349+ * Caller marked the request to be processed immediately; dispatch
1350+ * it directly to the driver unless the driver is currently blocked.
1351+ */
1352+ if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
1353+ int hid = CRYPTO_SESID2HID(crp->crp_sid);
1354+ cap = crypto_checkdriver(hid);
1355+ /* Driver cannot disappear when there is an active session. */
1356+ KASSERT(cap != NULL, ("%s: Driver disappeared.", __func__));
1357+ if (!cap->cc_qblocked) {
1358+ crypto_all_qblocked = 0;
1359+ crypto_drivers[hid].cc_unqblocked = 1;
1360+ CRYPTO_Q_UNLOCK();
1361+ result = crypto_invoke(cap, crp, 0);
1362+ CRYPTO_Q_LOCK();
1363+ if (result == ERESTART)
1364+ if (crypto_drivers[hid].cc_unqblocked)
1365+ crypto_drivers[hid].cc_qblocked = 1;
1366+ crypto_drivers[hid].cc_unqblocked = 0;
1367+ }
1368+ }
1369+ if (result == ERESTART) {
1370+ /*
1371+ * The driver ran out of resources, mark the
1372+ * driver ``blocked'' for cryptop's and put
1373+ * the request back in the queue. It would
1374+ * best to put the request back where we got
1375+ * it but that's hard so for now we put it
1376+ * at the front. This should be ok; putting
1377+ * it at the end does not work.
1378+ */
1379+ list_add(&crp->crp_next, &crp_q);
1380+ cryptostats.cs_blocks++;
1381+ result = 0;
1382+ } else if (result == -1) {
1383+ TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
1384+ result = 0;
1385+ }
1386+ wake_up_interruptible(&cryptoproc_wait);
1387+ CRYPTO_Q_UNLOCK();
1388+ return result;
1389+}
1390+
1391+/*
1392+ * Add an asymetric crypto request to a queue,
1393+ * to be processed by the kernel thread.
1394+ */
1395+int
1396+crypto_kdispatch(struct cryptkop *krp)
1397+{
1398+ int error;
1399+ unsigned long q_flags;
1400+
1401+ cryptostats.cs_kops++;
1402+
1403+ error = crypto_kinvoke(krp, krp->krp_crid);
1404+ if (error == ERESTART) {
1405+ CRYPTO_Q_LOCK();
1406+ TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
1407+ wake_up_interruptible(&cryptoproc_wait);
1408+ CRYPTO_Q_UNLOCK();
1409+ error = 0;
1410+ }
1411+ return error;
1412+}
1413+
1414+/*
1415+ * Verify a driver is suitable for the specified operation.
1416+ */
1417+static __inline int
1418+kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp)
1419+{
1420+ return (cap->cc_kalg[krp->krp_op] & CRYPTO_ALG_FLAG_SUPPORTED) != 0;
1421+}
1422+
1423+/*
1424+ * Select a driver for an asym operation. The driver must
1425+ * support the necessary algorithm. The caller can constrain
1426+ * which device is selected with the flags parameter. The
1427+ * algorithm we use here is pretty stupid; just use the first
1428+ * driver that supports the algorithms we need. If there are
1429+ * multiple suitable drivers we choose the driver with the
1430+ * fewest active operations. We prefer hardware-backed
1431+ * drivers to software ones when either may be used.
1432+ */
1433+static struct cryptocap *
1434+crypto_select_kdriver(const struct cryptkop *krp, int flags)
1435+{
1436+ struct cryptocap *cap, *best, *blocked;
1437+ int match, hid;
1438+
1439+ CRYPTO_DRIVER_ASSERT();
1440+
1441+ /*
1442+ * Look first for hardware crypto devices if permitted.
1443+ */
1444+ if (flags & CRYPTOCAP_F_HARDWARE)
1445+ match = CRYPTOCAP_F_HARDWARE;
1446+ else
1447+ match = CRYPTOCAP_F_SOFTWARE;
1448+ best = NULL;
1449+ blocked = NULL;
1450+again:
1451+ for (hid = 0; hid < crypto_drivers_num; hid++) {
1452+ cap = &crypto_drivers[hid];
1453+ /*
1454+ * If it's not initialized, is in the process of
1455+ * going away, or is not appropriate (hardware
1456+ * or software based on match), then skip.
1457+ */
1458+ if (cap->cc_dev == NULL ||
1459+ (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
1460+ (cap->cc_flags & match) == 0)
1461+ continue;
1462+
1463+ /* verify all the algorithms are supported. */
1464+ if (kdriver_suitable(cap, krp)) {
1465+ if (best == NULL ||
1466+ cap->cc_koperations < best->cc_koperations)
1467+ best = cap;
1468+ }
1469+ }
1470+ if (best != NULL)
1471+ return best;
1472+ if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
1473+ /* sort of an Algol 68-style for loop */
1474+ match = CRYPTOCAP_F_SOFTWARE;
1475+ goto again;
1476+ }
1477+ return best;
1478+}
1479+
1480+/*
1481+ * Dispatch an assymetric crypto request.
1482+ */
1483+static int
1484+crypto_kinvoke(struct cryptkop *krp, int crid)
1485+{
1486+ struct cryptocap *cap = NULL;
1487+ int error;
1488+ unsigned long d_flags;
1489+
1490+ KASSERT(krp != NULL, ("%s: krp == NULL", __func__));
1491+ KASSERT(krp->krp_callback != NULL,
1492+ ("%s: krp->crp_callback == NULL", __func__));
1493+
1494+ CRYPTO_DRIVER_LOCK();
1495+ if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
1496+ cap = crypto_checkdriver(crid);
1497+ if (cap != NULL) {
1498+ /*
1499+ * Driver present, it must support the necessary
1500+ * algorithm and, if s/w drivers are excluded,
1501+ * it must be registered as hardware-backed.
1502+ */
1503+ if (!kdriver_suitable(cap, krp) ||
1504+ (!crypto_devallowsoft &&
1505+ (cap->cc_flags & CRYPTOCAP_F_HARDWARE) == 0))
1506+ cap = NULL;
1507+ }
1508+ } else {
1509+ /*
1510+ * No requested driver; select based on crid flags.
1511+ */
1512+ if (!crypto_devallowsoft) /* NB: disallow s/w drivers */
1513+ crid &= ~CRYPTOCAP_F_SOFTWARE;
1514+ cap = crypto_select_kdriver(krp, crid);
1515+ }
1516+ if (cap != NULL && !cap->cc_kqblocked) {
1517+ krp->krp_hid = cap - crypto_drivers;
1518+ cap->cc_koperations++;
1519+ CRYPTO_DRIVER_UNLOCK();
1520+ error = CRYPTODEV_KPROCESS(cap->cc_dev, krp, 0);
1521+ CRYPTO_DRIVER_LOCK();
1522+ if (error == ERESTART) {
1523+ cap->cc_koperations--;
1524+ CRYPTO_DRIVER_UNLOCK();
1525+ return (error);
1526+ }
1527+ /* return the actual device used */
1528+ krp->krp_crid = krp->krp_hid;
1529+ } else {
1530+ /*
1531+ * NB: cap is !NULL if device is blocked; in
1532+ * that case return ERESTART so the operation
1533+ * is resubmitted if possible.
1534+ */
1535+ error = (cap == NULL) ? ENODEV : ERESTART;
1536+ }
1537+ CRYPTO_DRIVER_UNLOCK();
1538+
1539+ if (error) {
1540+ krp->krp_status = error;
1541+ crypto_kdone(krp);
1542+ }
1543+ return 0;
1544+}
1545+
1546+
1547+/*
1548+ * Dispatch a crypto request to the appropriate crypto devices.
1549+ */
1550+static int
1551+crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint)
1552+{
1553+ KASSERT(crp != NULL, ("%s: crp == NULL", __func__));
1554+ KASSERT(crp->crp_callback != NULL,
1555+ ("%s: crp->crp_callback == NULL", __func__));
1556+ KASSERT(crp->crp_desc != NULL, ("%s: crp->crp_desc == NULL", __func__));
1557+
1558+ dprintk("%s()\n", __FUNCTION__);
1559+
1560+#ifdef CRYPTO_TIMING
1561+ if (crypto_timing)
1562+ crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);
1563+#endif
1564+ if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) {
1565+ struct cryptodesc *crd;
1566+ u_int64_t nid;
1567+
1568+ /*
1569+ * Driver has unregistered; migrate the session and return
1570+ * an error to the caller so they'll resubmit the op.
1571+ *
1572+ * XXX: What if there are more already queued requests for this
1573+ * session?
1574+ */
1575+ crypto_freesession(crp->crp_sid);
1576+
1577+ for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
1578+ crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
1579+
1580+ /* XXX propagate flags from initial session? */
1581+ if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI),
1582+ CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE) == 0)
1583+ crp->crp_sid = nid;
1584+
1585+ crp->crp_etype = EAGAIN;
1586+ crypto_done(crp);
1587+ return 0;
1588+ } else {
1589+ /*
1590+ * Invoke the driver to process the request.
1591+ */
1592+ return CRYPTODEV_PROCESS(cap->cc_dev, crp, hint);
1593+ }
1594+}
1595+
1596+/*
1597+ * Release a set of crypto descriptors.
1598+ */
1599+void
1600+crypto_freereq(struct cryptop *crp)
1601+{
1602+ struct cryptodesc *crd;
1603+
1604+ if (crp == NULL)
1605+ return;
1606+
1607+#ifdef DIAGNOSTIC
1608+ {
1609+ struct cryptop *crp2;
1610+ unsigned long q_flags;
1611+
1612+ CRYPTO_Q_LOCK();
1613+ TAILQ_FOREACH(crp2, &crp_q, crp_next) {
1614+ KASSERT(crp2 != crp,
1615+ ("Freeing cryptop from the crypto queue (%p).",
1616+ crp));
1617+ }
1618+ CRYPTO_Q_UNLOCK();
1619+ CRYPTO_RETQ_LOCK();
1620+ TAILQ_FOREACH(crp2, &crp_ret_q, crp_next) {
1621+ KASSERT(crp2 != crp,
1622+ ("Freeing cryptop from the return queue (%p).",
1623+ crp));
1624+ }
1625+ CRYPTO_RETQ_UNLOCK();
1626+ }
1627+#endif
1628+
1629+ while ((crd = crp->crp_desc) != NULL) {
1630+ crp->crp_desc = crd->crd_next;
1631+ kmem_cache_free(cryptodesc_zone, crd);
1632+ }
1633+ kmem_cache_free(cryptop_zone, crp);
1634+}
1635+
1636+/*
1637+ * Acquire a set of crypto descriptors.
1638+ */
1639+struct cryptop *
1640+crypto_getreq(int num)
1641+{
1642+ struct cryptodesc *crd;
1643+ struct cryptop *crp;
1644+
1645+ crp = kmem_cache_alloc(cryptop_zone, SLAB_ATOMIC);
1646+ if (crp != NULL) {
1647+ memset(crp, 0, sizeof(*crp));
1648+ INIT_LIST_HEAD(&crp->crp_next);
1649+ init_waitqueue_head(&crp->crp_waitq);
1650+ while (num--) {
1651+ crd = kmem_cache_alloc(cryptodesc_zone, SLAB_ATOMIC);
1652+ if (crd == NULL) {
1653+ crypto_freereq(crp);
1654+ return NULL;
1655+ }
1656+ memset(crd, 0, sizeof(*crd));
1657+ crd->crd_next = crp->crp_desc;
1658+ crp->crp_desc = crd;
1659+ }
1660+ }
1661+ return crp;
1662+}
1663+
1664+/*
1665+ * Invoke the callback on behalf of the driver.
1666+ */
1667+void
1668+crypto_done(struct cryptop *crp)
1669+{
1670+ unsigned long q_flags;
1671+
1672+ dprintk("%s()\n", __FUNCTION__);
1673+ if ((crp->crp_flags & CRYPTO_F_DONE) == 0) {
1674+ crp->crp_flags |= CRYPTO_F_DONE;
1675+ CRYPTO_Q_LOCK();
1676+ crypto_q_cnt--;
1677+ CRYPTO_Q_UNLOCK();
1678+ } else
1679+ printk("crypto: crypto_done op already done, flags 0x%x",
1680+ crp->crp_flags);
1681+ if (crp->crp_etype != 0)
1682+ cryptostats.cs_errs++;
1683+ /*
1684+ * CBIMM means unconditionally do the callback immediately;
1685+ * CBIFSYNC means do the callback immediately only if the
1686+ * operation was done synchronously. Both are used to avoid
1687+ * doing extraneous context switches; the latter is mostly
1688+ * used with the software crypto driver.
1689+ */
1690+ if ((crp->crp_flags & CRYPTO_F_CBIMM) ||
1691+ ((crp->crp_flags & CRYPTO_F_CBIFSYNC) &&
1692+ (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC))) {
1693+ /*
1694+ * Do the callback directly. This is ok when the
1695+ * callback routine does very little (e.g. the
1696+ * /dev/crypto callback method just does a wakeup).
1697+ */
1698+ crp->crp_callback(crp);
1699+ } else {
1700+ unsigned long r_flags;
1701+ /*
1702+ * Normal case; queue the callback for the thread.
1703+ */
1704+ CRYPTO_RETQ_LOCK();
1705+ wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
1706+ TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
1707+ CRYPTO_RETQ_UNLOCK();
1708+ }
1709+}
1710+
1711+/*
1712+ * Invoke the callback on behalf of the driver.
1713+ */
1714+void
1715+crypto_kdone(struct cryptkop *krp)
1716+{
1717+ struct cryptocap *cap;
1718+ unsigned long d_flags;
1719+
1720+ if ((krp->krp_flags & CRYPTO_KF_DONE) != 0)
1721+ printk("crypto: crypto_kdone op already done, flags 0x%x",
1722+ krp->krp_flags);
1723+ krp->krp_flags |= CRYPTO_KF_DONE;
1724+ if (krp->krp_status != 0)
1725+ cryptostats.cs_kerrs++;
1726+
1727+ CRYPTO_DRIVER_LOCK();
1728+ /* XXX: What if driver is loaded in the meantime? */
1729+ if (krp->krp_hid < crypto_drivers_num) {
1730+ cap = &crypto_drivers[krp->krp_hid];
1731+ cap->cc_koperations--;
1732+ KASSERT(cap->cc_koperations >= 0, ("cc_koperations < 0"));
1733+ if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
1734+ crypto_remove(cap);
1735+ }
1736+ CRYPTO_DRIVER_UNLOCK();
1737+
1738+ /*
1739+ * CBIMM means unconditionally do the callback immediately;
1740+ * This is used to avoid doing extraneous context switches
1741+ */
1742+ if ((krp->krp_flags & CRYPTO_KF_CBIMM)) {
1743+ /*
1744+ * Do the callback directly. This is ok when the
1745+ * callback routine does very little (e.g. the
1746+ * /dev/crypto callback method just does a wakeup).
1747+ */
1748+ krp->krp_callback(krp);
1749+ } else {
1750+ unsigned long r_flags;
1751+ /*
1752+ * Normal case; queue the callback for the thread.
1753+ */
1754+ CRYPTO_RETQ_LOCK();
1755+ wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
1756+ TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
1757+ CRYPTO_RETQ_UNLOCK();
1758+ }
1759+}
1760+
1761+int
1762+crypto_getfeat(int *featp)
1763+{
1764+ int hid, kalg, feat = 0;
1765+ unsigned long d_flags;
1766+
1767+ CRYPTO_DRIVER_LOCK();
1768+ for (hid = 0; hid < crypto_drivers_num; hid++) {
1769+ const struct cryptocap *cap = &crypto_drivers[hid];
1770+
1771+ if ((cap->cc_flags & CRYPTOCAP_F_SOFTWARE) &&
1772+ !crypto_devallowsoft) {
1773+ continue;
1774+ }
1775+ for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
1776+ if (cap->cc_kalg[kalg] & CRYPTO_ALG_FLAG_SUPPORTED)
1777+ feat |= 1 << kalg;
1778+ }
1779+ CRYPTO_DRIVER_UNLOCK();
1780+ *featp = feat;
1781+ return (0);
1782+}
1783+
1784+/*
1785+ * Crypto thread, dispatches crypto requests.
1786+ */
1787+static int
1788+crypto_proc(void *arg)
1789+{
1790+ struct cryptop *crp, *submit;
1791+ struct cryptkop *krp, *krpp;
1792+ struct cryptocap *cap;
1793+ u_int32_t hid;
1794+ int result, hint;
1795+ unsigned long q_flags;
1796+ int loopcount = 0;
1797+
1798+ set_current_state(TASK_INTERRUPTIBLE);
1799+
1800+ CRYPTO_Q_LOCK();
1801+ for (;;) {
1802+ /*
1803+ * we need to make sure we don't get into a busy loop with nothing
1804+ * to do, the two crypto_all_*blocked vars help us find out when
1805+ * we are all full and can do nothing on any driver or Q. If so we
1806+ * wait for an unblock.
1807+ */
1808+ crypto_all_qblocked = !list_empty(&crp_q);
1809+
1810+ /*
1811+ * Find the first element in the queue that can be
1812+ * processed and look-ahead to see if multiple ops
1813+ * are ready for the same driver.
1814+ */
1815+ submit = NULL;
1816+ hint = 0;
1817+ list_for_each_entry(crp, &crp_q, crp_next) {
1818+ hid = CRYPTO_SESID2HID(crp->crp_sid);
1819+ cap = crypto_checkdriver(hid);
1820+ /*
1821+ * Driver cannot disappear when there is an active
1822+ * session.
1823+ */
1824+ KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
1825+ __func__, __LINE__));
1826+ if (cap == NULL || cap->cc_dev == NULL) {
1827+ /* Op needs to be migrated, process it. */
1828+ if (submit == NULL)
1829+ submit = crp;
1830+ break;
1831+ }
1832+ if (!cap->cc_qblocked) {
1833+ if (submit != NULL) {
1834+ /*
1835+ * We stop on finding another op,
1836+ * regardless whether its for the same
1837+ * driver or not. We could keep
1838+ * searching the queue but it might be
1839+ * better to just use a per-driver
1840+ * queue instead.
1841+ */
1842+ if (CRYPTO_SESID2HID(submit->crp_sid) == hid)
1843+ hint = CRYPTO_HINT_MORE;
1844+ break;
1845+ } else {
1846+ submit = crp;
1847+ if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)
1848+ break;
1849+ /* keep scanning for more are q'd */
1850+ }
1851+ }
1852+ }
1853+ if (submit != NULL) {
1854+ hid = CRYPTO_SESID2HID(submit->crp_sid);
1855+ crypto_all_qblocked = 0;
1856+ list_del(&submit->crp_next);
1857+ crypto_drivers[hid].cc_unqblocked = 1;
1858+ cap = crypto_checkdriver(hid);
1859+ CRYPTO_Q_UNLOCK();
1860+ KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
1861+ __func__, __LINE__));
1862+ result = crypto_invoke(cap, submit, hint);
1863+ CRYPTO_Q_LOCK();
1864+ if (result == ERESTART) {
1865+ /*
1866+ * The driver ran out of resources, mark the
1867+ * driver ``blocked'' for cryptop's and put
1868+ * the request back in the queue. It would
1869+ * best to put the request back where we got
1870+ * it but that's hard so for now we put it
1871+ * at the front. This should be ok; putting
1872+ * it at the end does not work.
1873+ */
1874+ /* XXX validate sid again? */
1875+ list_add(&submit->crp_next, &crp_q);
1876+ cryptostats.cs_blocks++;
1877+ if (crypto_drivers[hid].cc_unqblocked)
1878+ crypto_drivers[hid].cc_qblocked=0;
1879+ crypto_drivers[hid].cc_unqblocked=0;
1880+ }
1881+ crypto_drivers[hid].cc_unqblocked = 0;
1882+ }
1883+
1884+ crypto_all_kqblocked = !list_empty(&crp_kq);
1885+
1886+ /* As above, but for key ops */
1887+ krp = NULL;
1888+ list_for_each_entry(krpp, &crp_kq, krp_next) {
1889+ cap = crypto_checkdriver(krpp->krp_hid);
1890+ if (cap == NULL || cap->cc_dev == NULL) {
1891+ /*
1892+ * Operation needs to be migrated, invalidate
1893+ * the assigned device so it will reselect a
1894+ * new one below. Propagate the original
1895+ * crid selection flags if supplied.
1896+ */
1897+ krp->krp_hid = krp->krp_crid &
1898+ (CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE);
1899+ if (krp->krp_hid == 0)
1900+ krp->krp_hid =
1901+ CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE;
1902+ break;
1903+ }
1904+ if (!cap->cc_kqblocked) {
1905+ krp = krpp;
1906+ break;
1907+ }
1908+ }
1909+ if (krp != NULL) {
1910+ crypto_all_kqblocked = 0;
1911+ list_del(&krp->krp_next);
1912+ crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
1913+ CRYPTO_Q_UNLOCK();
1914+ result = crypto_kinvoke(krp, krp->krp_hid);
1915+ CRYPTO_Q_LOCK();
1916+ if (result == ERESTART) {
1917+ /*
1918+ * The driver ran out of resources, mark the
1919+ * driver ``blocked'' for cryptkop's and put
1920+ * the request back in the queue. It would
1921+ * best to put the request back where we got
1922+ * it but that's hard so for now we put it
1923+ * at the front. This should be ok; putting
1924+ * it at the end does not work.
1925+ */
1926+ /* XXX validate sid again? */
1927+ list_add(&krp->krp_next, &crp_kq);
1928+ cryptostats.cs_kblocks++;
1929+ } else
1930+ crypto_drivers[krp->krp_hid].cc_kqblocked = 0;
1931+ }
1932+
1933+ if (submit == NULL && krp == NULL) {
1934+ /*
1935+ * Nothing more to be processed. Sleep until we're
1936+ * woken because there are more ops to process.
1937+ * This happens either by submission or by a driver
1938+ * becoming unblocked and notifying us through
1939+ * crypto_unblock. Note that when we wakeup we
1940+ * start processing each queue again from the
1941+ * front. It's not clear that it's important to
1942+ * preserve this ordering since ops may finish
1943+ * out of order if dispatched to different devices
1944+ * and some become blocked while others do not.
1945+ */
1946+ dprintk("%s - sleeping (qe=%d qb=%d kqe=%d kqb=%d)\n",
1947+ __FUNCTION__,
1948+ list_empty(&crp_q), crypto_all_qblocked,
1949+ list_empty(&crp_kq), crypto_all_kqblocked);
1950+ loopcount = 0;
1951+ CRYPTO_Q_UNLOCK();
1952+ wait_event_interruptible(cryptoproc_wait,
1953+ !(list_empty(&crp_q) || crypto_all_qblocked) ||
1954+ !(list_empty(&crp_kq) || crypto_all_kqblocked) ||
1955+ kthread_should_stop());
1956+ if (signal_pending (current)) {
1957+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
1958+ spin_lock_irq(&current->sigmask_lock);
1959+#endif
1960+ flush_signals(current);
1961+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
1962+ spin_unlock_irq(&current->sigmask_lock);
1963+#endif
1964+ }
1965+ CRYPTO_Q_LOCK();
1966+ dprintk("%s - awake\n", __FUNCTION__);
1967+ if (kthread_should_stop())
1968+ break;
1969+ cryptostats.cs_intrs++;
1970+ } else if (loopcount > crypto_max_loopcount) {
1971+ /*
1972+ * Give other processes a chance to run if we've
1973+ * been using the CPU exclusively for a while.
1974+ */
1975+ loopcount = 0;
1976+ CRYPTO_Q_UNLOCK();
1977+ schedule();
1978+ CRYPTO_Q_LOCK();
1979+ }
1980+ loopcount++;
1981+ }
1982+ CRYPTO_Q_UNLOCK();
1983+ return 0;
1984+}
1985+
1986+/*
1987+ * Crypto returns thread, does callbacks for processed crypto requests.
1988+ * Callbacks are done here, rather than in the crypto drivers, because
1989+ * callbacks typically are expensive and would slow interrupt handling.
1990+ */
1991+static int
1992+crypto_ret_proc(void *arg)
1993+{
1994+ struct cryptop *crpt;
1995+ struct cryptkop *krpt;
1996+ unsigned long r_flags;
1997+
1998+ set_current_state(TASK_INTERRUPTIBLE);
1999+
2000+ CRYPTO_RETQ_LOCK();
2001+ for (;;) {
2002+ /* Harvest return q's for completed ops */
2003+ crpt = NULL;
2004+ if (!list_empty(&crp_ret_q))
2005+ crpt = list_entry(crp_ret_q.next, typeof(*crpt), crp_next);
2006+ if (crpt != NULL)
2007+ list_del(&crpt->crp_next);
2008+
2009+ krpt = NULL;
2010+ if (!list_empty(&crp_ret_kq))
2011+ krpt = list_entry(crp_ret_kq.next, typeof(*krpt), krp_next);
2012+ if (krpt != NULL)
2013+ list_del(&krpt->krp_next);
2014+
2015+ if (crpt != NULL || krpt != NULL) {
2016+ CRYPTO_RETQ_UNLOCK();
2017+ /*
2018+ * Run callbacks unlocked.
2019+ */
2020+ if (crpt != NULL)
2021+ crpt->crp_callback(crpt);
2022+ if (krpt != NULL)
2023+ krpt->krp_callback(krpt);
2024+ CRYPTO_RETQ_LOCK();
2025+ } else {
2026+ /*
2027+ * Nothing more to be processed. Sleep until we're
2028+ * woken because there are more returns to process.
2029+ */
2030+ dprintk("%s - sleeping\n", __FUNCTION__);
2031+ CRYPTO_RETQ_UNLOCK();
2032+ wait_event_interruptible(cryptoretproc_wait,
2033+ !list_empty(&crp_ret_q) ||
2034+ !list_empty(&crp_ret_kq) ||
2035+ kthread_should_stop());
2036+ if (signal_pending (current)) {
2037+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
2038+ spin_lock_irq(&current->sigmask_lock);
2039+#endif
2040+ flush_signals(current);
2041+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
2042+ spin_unlock_irq(&current->sigmask_lock);
2043+#endif
2044+ }
2045+ CRYPTO_RETQ_LOCK();
2046+ dprintk("%s - awake\n", __FUNCTION__);
2047+ if (kthread_should_stop()) {
2048+ dprintk("%s - EXITING!\n", __FUNCTION__);
2049+ break;
2050+ }
2051+ cryptostats.cs_rets++;
2052+ }
2053+ }
2054+ CRYPTO_RETQ_UNLOCK();
2055+ return 0;
2056+}
2057+
2058+
2059+#if 0 /* should put this into /proc or something */
2060+static void
2061+db_show_drivers(void)
2062+{
2063+ int hid;
2064+
2065+ db_printf("%12s %4s %4s %8s %2s %2s\n"
2066+ , "Device"
2067+ , "Ses"
2068+ , "Kops"
2069+ , "Flags"
2070+ , "QB"
2071+ , "KB"
2072+ );
2073+ for (hid = 0; hid < crypto_drivers_num; hid++) {
2074+ const struct cryptocap *cap = &crypto_drivers[hid];
2075+ if (cap->cc_dev == NULL)
2076+ continue;
2077+ db_printf("%-12s %4u %4u %08x %2u %2u\n"
2078+ , device_get_nameunit(cap->cc_dev)
2079+ , cap->cc_sessions
2080+ , cap->cc_koperations
2081+ , cap->cc_flags
2082+ , cap->cc_qblocked
2083+ , cap->cc_kqblocked
2084+ );
2085+ }
2086+}
2087+
2088+DB_SHOW_COMMAND(crypto, db_show_crypto)
2089+{
2090+ struct cryptop *crp;
2091+
2092+ db_show_drivers();
2093+ db_printf("\n");
2094+
2095+ db_printf("%4s %8s %4s %4s %4s %4s %8s %8s\n",
2096+ "HID", "Caps", "Ilen", "Olen", "Etype", "Flags",
2097+ "Desc", "Callback");
2098+ TAILQ_FOREACH(crp, &crp_q, crp_next) {
2099+ db_printf("%4u %08x %4u %4u %4u %04x %8p %8p\n"
2100+ , (int) CRYPTO_SESID2HID(crp->crp_sid)
2101+ , (int) CRYPTO_SESID2CAPS(crp->crp_sid)
2102+ , crp->crp_ilen, crp->crp_olen
2103+ , crp->crp_etype
2104+ , crp->crp_flags
2105+ , crp->crp_desc
2106+ , crp->crp_callback
2107+ );
2108+ }
2109+ if (!TAILQ_EMPTY(&crp_ret_q)) {
2110+ db_printf("\n%4s %4s %4s %8s\n",
2111+ "HID", "Etype", "Flags", "Callback");
2112+ TAILQ_FOREACH(crp, &crp_ret_q, crp_next) {
2113+ db_printf("%4u %4u %04x %8p\n"
2114+ , (int) CRYPTO_SESID2HID(crp->crp_sid)
2115+ , crp->crp_etype
2116+ , crp->crp_flags
2117+ , crp->crp_callback
2118+ );
2119+ }
2120+ }
2121+}
2122+
2123+DB_SHOW_COMMAND(kcrypto, db_show_kcrypto)
2124+{
2125+ struct cryptkop *krp;
2126+
2127+ db_show_drivers();
2128+ db_printf("\n");
2129+
2130+ db_printf("%4s %5s %4s %4s %8s %4s %8s\n",
2131+ "Op", "Status", "#IP", "#OP", "CRID", "HID", "Callback");
2132+ TAILQ_FOREACH(krp, &crp_kq, krp_next) {
2133+ db_printf("%4u %5u %4u %4u %08x %4u %8p\n"
2134+ , krp->krp_op
2135+ , krp->krp_status
2136+ , krp->krp_iparams, krp->krp_oparams
2137+ , krp->krp_crid, krp->krp_hid
2138+ , krp->krp_callback
2139+ );
2140+ }
2141+ if (!TAILQ_EMPTY(&crp_ret_q)) {
2142+ db_printf("%4s %5s %8s %4s %8s\n",
2143+ "Op", "Status", "CRID", "HID", "Callback");
2144+ TAILQ_FOREACH(krp, &crp_ret_kq, krp_next) {
2145+ db_printf("%4u %5u %08x %4u %8p\n"
2146+ , krp->krp_op
2147+ , krp->krp_status
2148+ , krp->krp_crid, krp->krp_hid
2149+ , krp->krp_callback
2150+ );
2151+ }
2152+ }
2153+}
2154+#endif
2155+
2156+
2157+static int
2158+crypto_init(void)
2159+{
2160+ int error;
2161+ unsigned long cpu;
2162+
2163+ dprintk("%s(%p)\n", __FUNCTION__, (void *) crypto_init);
2164+
2165+ if (crypto_initted)
2166+ return 0;
2167+ crypto_initted = 1;
2168+
2169+ spin_lock_init(&crypto_drivers_lock);
2170+ spin_lock_init(&crypto_q_lock);
2171+ spin_lock_init(&crypto_ret_q_lock);
2172+
2173+ cryptop_zone = kmem_cache_create("cryptop", sizeof(struct cryptop),
2174+ 0, SLAB_HWCACHE_ALIGN, NULL
2175+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
2176+ , NULL
2177+#endif
2178+ );
2179+
2180+ cryptodesc_zone = kmem_cache_create("cryptodesc", sizeof(struct cryptodesc),
2181+ 0, SLAB_HWCACHE_ALIGN, NULL
2182+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
2183+ , NULL
2184+#endif
2185+ );
2186+
2187+ if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
2188+ printk("crypto: crypto_init cannot setup crypto zones\n");
2189+ error = ENOMEM;
2190+ goto bad;
2191+ }
2192+
2193+ crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
2194+ crypto_drivers = kmalloc(crypto_drivers_num * sizeof(struct cryptocap),
2195+ GFP_KERNEL);
2196+ if (crypto_drivers == NULL) {
2197+ printk("crypto: crypto_init cannot setup crypto drivers\n");
2198+ error = ENOMEM;
2199+ goto bad;
2200+ }
2201+
2202+ memset(crypto_drivers, 0, crypto_drivers_num * sizeof(struct cryptocap));
2203+
2204+ ocf_for_each_cpu(cpu) {
2205+ cryptoproc[cpu] = kthread_create(crypto_proc, (void *) cpu,
2206+ "ocf_%d", (int) cpu);
2207+ if (IS_ERR(cryptoproc[cpu])) {
2208+ error = PTR_ERR(cryptoproc[cpu]);
2209+ printk("crypto: crypto_init cannot start crypto thread; error %d",
2210+ error);
2211+ goto bad;
2212+ }
2213+ kthread_bind(cryptoproc[cpu], cpu);
2214+ wake_up_process(cryptoproc[cpu]);
2215+
2216+ cryptoretproc[cpu] = kthread_create(crypto_ret_proc, (void *) cpu,
2217+ "ocf_ret_%d", (int) cpu);
2218+ if (IS_ERR(cryptoretproc[cpu])) {
2219+ error = PTR_ERR(cryptoretproc[cpu]);
2220+ printk("crypto: crypto_init cannot start cryptoret thread; error %d",
2221+ error);
2222+ goto bad;
2223+ }
2224+ kthread_bind(cryptoretproc[cpu], cpu);
2225+ wake_up_process(cryptoretproc[cpu]);
2226+ }
2227+
2228+ return 0;
2229+bad:
2230+ crypto_exit();
2231+ return error;
2232+}
2233+
2234+
2235+static void
2236+crypto_exit(void)
2237+{
2238+ int cpu;
2239+
2240+ dprintk("%s()\n", __FUNCTION__);
2241+
2242+ /*
2243+ * Terminate any crypto threads.
2244+ */
2245+ ocf_for_each_cpu(cpu) {
2246+ kthread_stop(cryptoproc[cpu]);
2247+ kthread_stop(cryptoretproc[cpu]);
2248+ }
2249+
2250+ /*
2251+ * Reclaim dynamically allocated resources.
2252+ */
2253+ if (crypto_drivers != NULL)
2254+ kfree(crypto_drivers);
2255+
2256+ if (cryptodesc_zone != NULL)
2257+ kmem_cache_destroy(cryptodesc_zone);
2258+ if (cryptop_zone != NULL)
2259+ kmem_cache_destroy(cryptop_zone);
2260+}
2261+
2262+
2263+EXPORT_SYMBOL(crypto_newsession);
2264+EXPORT_SYMBOL(crypto_freesession);
2265+EXPORT_SYMBOL(crypto_get_driverid);
2266+EXPORT_SYMBOL(crypto_kregister);
2267+EXPORT_SYMBOL(crypto_register);
2268+EXPORT_SYMBOL(crypto_unregister);
2269+EXPORT_SYMBOL(crypto_unregister_all);
2270+EXPORT_SYMBOL(crypto_unblock);
2271+EXPORT_SYMBOL(crypto_dispatch);
2272+EXPORT_SYMBOL(crypto_kdispatch);
2273+EXPORT_SYMBOL(crypto_freereq);
2274+EXPORT_SYMBOL(crypto_getreq);
2275+EXPORT_SYMBOL(crypto_done);
2276+EXPORT_SYMBOL(crypto_kdone);
2277+EXPORT_SYMBOL(crypto_getfeat);
2278+EXPORT_SYMBOL(crypto_userasymcrypto);
2279+EXPORT_SYMBOL(crypto_getcaps);
2280+EXPORT_SYMBOL(crypto_find_driver);
2281+EXPORT_SYMBOL(crypto_find_device_byhid);
2282+
2283+module_init(crypto_init);
2284+module_exit(crypto_exit);
2285+
2286+MODULE_LICENSE("BSD");
2287+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
2288+MODULE_DESCRIPTION("OCF (OpenBSD Cryptographic Framework)");
2289diff --git a/crypto/ocf/cryptodev.c b/crypto/ocf/cryptodev.c
2290new file mode 100644
2291index 0000000..2ee3618
2292--- /dev/null
2293+++ b/crypto/ocf/cryptodev.c
2294@@ -0,0 +1,1069 @@
2295+/* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */
2296+
2297+/*-
2298+ * Linux port done by David McCullough <david_mccullough@mcafee.com>
2299+ * Copyright (C) 2006-2010 David McCullough
2300+ * Copyright (C) 2004-2005 Intel Corporation.
2301+ * The license and original author are listed below.
2302+ *
2303+ * Copyright (c) 2001 Theo de Raadt
2304+ * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
2305+ *
2306+ * Redistribution and use in source and binary forms, with or without
2307+ * modification, are permitted provided that the following conditions
2308+ * are met:
2309+ *
2310+ * 1. Redistributions of source code must retain the above copyright
2311+ * notice, this list of conditions and the following disclaimer.
2312+ * 2. Redistributions in binary form must reproduce the above copyright
2313+ * notice, this list of conditions and the following disclaimer in the
2314+ * documentation and/or other materials provided with the distribution.
2315+ * 3. The name of the author may not be used to endorse or promote products
2316+ * derived from this software without specific prior written permission.
2317+ *
2318+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2319+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2320+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2321+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2322+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2323+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2324+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2325+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2326+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2327+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2328+ *
2329+ * Effort sponsored in part by the Defense Advanced Research Projects
2330+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
2331+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
2332+ *
2333+__FBSDID("$FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.34 2007/05/09 19:37:02 gnn Exp $");
2334+ */
2335+
2336+#include <linux/version.h>
2337+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
2338+#include <linux/config.h>
2339+#endif
2340+#include <linux/types.h>
2341+#include <linux/time.h>
2342+#include <linux/delay.h>
2343+#include <linux/list.h>
2344+#include <linux/init.h>
2345+#include <linux/sched.h>
2346+#include <linux/unistd.h>
2347+#include <linux/module.h>
2348+#include <linux/wait.h>
2349+#include <linux/slab.h>
2350+#include <linux/fs.h>
2351+#include <linux/dcache.h>
2352+#include <linux/file.h>
2353+#include <linux/mount.h>
2354+#include <linux/miscdevice.h>
2355+#include <asm/uaccess.h>
2356+
2357+#include <cryptodev.h>
2358+#include <uio.h>
2359+
2360+extern asmlinkage long sys_dup(unsigned int fildes);
2361+
2362+#define debug cryptodev_debug
2363+int cryptodev_debug = 0;
2364+module_param(cryptodev_debug, int, 0644);
2365+MODULE_PARM_DESC(cryptodev_debug, "Enable cryptodev debug");
2366+
2367+struct csession_info {
2368+ u_int16_t blocksize;
2369+ u_int16_t minkey, maxkey;
2370+
2371+ u_int16_t keysize;
2372+ /* u_int16_t hashsize; */
2373+ u_int16_t authsize;
2374+ u_int16_t authkey;
2375+ /* u_int16_t ctxsize; */
2376+};
2377+
2378+struct csession {
2379+ struct list_head list;
2380+ u_int64_t sid;
2381+ u_int32_t ses;
2382+
2383+ wait_queue_head_t waitq;
2384+
2385+ u_int32_t cipher;
2386+
2387+ u_int32_t mac;
2388+
2389+ caddr_t key;
2390+ int keylen;
2391+ u_char tmp_iv[EALG_MAX_BLOCK_LEN];
2392+
2393+ caddr_t mackey;
2394+ int mackeylen;
2395+
2396+ struct csession_info info;
2397+
2398+ struct iovec iovec;
2399+ struct uio uio;
2400+ int error;
2401+};
2402+
2403+struct fcrypt {
2404+ struct list_head csessions;
2405+ int sesn;
2406+};
2407+
2408+static struct csession *csefind(struct fcrypt *, u_int);
2409+static int csedelete(struct fcrypt *, struct csession *);
2410+static struct csession *cseadd(struct fcrypt *, struct csession *);
2411+static struct csession *csecreate(struct fcrypt *, u_int64_t,
2412+ struct cryptoini *crie, struct cryptoini *cria, struct csession_info *);
2413+static int csefree(struct csession *);
2414+
2415+static int cryptodev_op(struct csession *, struct crypt_op *);
2416+static int cryptodev_key(struct crypt_kop *);
2417+static int cryptodev_find(struct crypt_find_op *);
2418+
2419+static int cryptodev_cb(void *);
2420+static int cryptodev_open(struct inode *inode, struct file *filp);
2421+
2422+/*
2423+ * Check a crypto identifier to see if it requested
2424+ * a valid crid and it's capabilities match.
2425+ */
2426+static int
2427+checkcrid(int crid)
2428+{
2429+ int hid = crid & ~(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
2430+ int typ = crid & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
2431+ int caps = 0;
2432+
2433+ /* if the user hasn't selected a driver, then just call newsession */
2434+ if (hid == 0 && typ != 0)
2435+ return 0;
2436+
2437+ caps = crypto_getcaps(hid);
2438+
2439+ /* didn't find anything with capabilities */
2440+ if (caps == 0) {
2441+ dprintk("%s: hid=%x typ=%x not matched\n", __FUNCTION__, hid, typ);
2442+ return EINVAL;
2443+ }
2444+
2445+ /* the user didn't specify SW or HW, so the driver is ok */
2446+ if (typ == 0)
2447+ return 0;
2448+
2449+ /* if the type specified didn't match */
2450+ if (typ != (caps & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE))) {
2451+ dprintk("%s: hid=%x typ=%x caps=%x not matched\n", __FUNCTION__,
2452+ hid, typ, caps);
2453+ return EINVAL;
2454+ }
2455+
2456+ return 0;
2457+}
2458+
2459+static int
2460+cryptodev_op(struct csession *cse, struct crypt_op *cop)
2461+{
2462+ struct cryptop *crp = NULL;
2463+ struct cryptodesc *crde = NULL, *crda = NULL;
2464+ int error = 0;
2465+
2466+ dprintk("%s()\n", __FUNCTION__);
2467+ if (cop->len > CRYPTO_MAX_DATA_LEN) {
2468+ dprintk("%s: %d > %d\n", __FUNCTION__, cop->len, CRYPTO_MAX_DATA_LEN);
2469+ return (E2BIG);
2470+ }
2471+
2472+ if (cse->info.blocksize && (cop->len % cse->info.blocksize) != 0) {
2473+ dprintk("%s: blocksize=%d len=%d\n", __FUNCTION__, cse->info.blocksize,
2474+ cop->len);
2475+ return (EINVAL);
2476+ }
2477+
2478+ cse->uio.uio_iov = &cse->iovec;
2479+ cse->uio.uio_iovcnt = 1;
2480+ cse->uio.uio_offset = 0;
2481+#if 0
2482+ cse->uio.uio_resid = cop->len;
2483+ cse->uio.uio_segflg = UIO_SYSSPACE;
2484+ cse->uio.uio_rw = UIO_WRITE;
2485+ cse->uio.uio_td = td;
2486+#endif
2487+ cse->uio.uio_iov[0].iov_len = cop->len;
2488+ if (cse->info.authsize)
2489+ cse->uio.uio_iov[0].iov_len += cse->info.authsize;
2490+ cse->uio.uio_iov[0].iov_base = kmalloc(cse->uio.uio_iov[0].iov_len,
2491+ GFP_KERNEL);
2492+
2493+ if (cse->uio.uio_iov[0].iov_base == NULL) {
2494+ dprintk("%s: iov_base kmalloc(%d) failed\n", __FUNCTION__,
2495+ (int)cse->uio.uio_iov[0].iov_len);
2496+ return (ENOMEM);
2497+ }
2498+
2499+ crp = crypto_getreq((cse->info.blocksize != 0) + (cse->info.authsize != 0));
2500+ if (crp == NULL) {
2501+ dprintk("%s: ENOMEM\n", __FUNCTION__);
2502+ error = ENOMEM;
2503+ goto bail;
2504+ }
2505+
2506+ if (cse->info.authsize && cse->info.blocksize) {
2507+ if (cop->op == COP_ENCRYPT) {
2508+ crde = crp->crp_desc;
2509+ crda = crde->crd_next;
2510+ } else {
2511+ crda = crp->crp_desc;
2512+ crde = crda->crd_next;
2513+ }
2514+ } else if (cse->info.authsize) {
2515+ crda = crp->crp_desc;
2516+ } else if (cse->info.blocksize) {
2517+ crde = crp->crp_desc;
2518+ } else {
2519+ dprintk("%s: bad request\n", __FUNCTION__);
2520+ error = EINVAL;
2521+ goto bail;
2522+ }
2523+
2524+ if ((error = copy_from_user(cse->uio.uio_iov[0].iov_base, cop->src,
2525+ cop->len))) {
2526+ dprintk("%s: bad copy\n", __FUNCTION__);
2527+ goto bail;
2528+ }
2529+
2530+ if (crda) {
2531+ crda->crd_skip = 0;
2532+ crda->crd_len = cop->len;
2533+ crda->crd_inject = cop->len;
2534+
2535+ crda->crd_alg = cse->mac;
2536+ crda->crd_key = cse->mackey;
2537+ crda->crd_klen = cse->mackeylen * 8;
2538+ }
2539+
2540+ if (crde) {
2541+ if (cop->op == COP_ENCRYPT)
2542+ crde->crd_flags |= CRD_F_ENCRYPT;
2543+ else
2544+ crde->crd_flags &= ~CRD_F_ENCRYPT;
2545+ crde->crd_len = cop->len;
2546+ crde->crd_inject = 0;
2547+
2548+ crde->crd_alg = cse->cipher;
2549+ crde->crd_key = cse->key;
2550+ crde->crd_klen = cse->keylen * 8;
2551+ }
2552+
2553+ crp->crp_ilen = cse->uio.uio_iov[0].iov_len;
2554+ crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
2555+ | (cop->flags & COP_F_BATCH);
2556+ crp->crp_buf = (caddr_t)&cse->uio;
2557+ crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;
2558+ crp->crp_sid = cse->sid;
2559+ crp->crp_opaque = (void *)cse;
2560+
2561+ if (cop->iv) {
2562+ if (crde == NULL) {
2563+ error = EINVAL;
2564+ dprintk("%s no crde\n", __FUNCTION__);
2565+ goto bail;
2566+ }
2567+ if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
2568+ error = EINVAL;
2569+ dprintk("%s arc4 with IV\n", __FUNCTION__);
2570+ goto bail;
2571+ }
2572+ if ((error = copy_from_user(cse->tmp_iv, cop->iv,
2573+ cse->info.blocksize))) {
2574+ dprintk("%s bad iv copy\n", __FUNCTION__);
2575+ goto bail;
2576+ }
2577+ memcpy(crde->crd_iv, cse->tmp_iv, cse->info.blocksize);
2578+ crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
2579+ crde->crd_skip = 0;
2580+ } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
2581+ crde->crd_skip = 0;
2582+ } else if (crde) {
2583+ crde->crd_flags |= CRD_F_IV_PRESENT;
2584+ crde->crd_skip = cse->info.blocksize;
2585+ crde->crd_len -= cse->info.blocksize;
2586+ }
2587+
2588+ if (cop->mac && crda == NULL) {
2589+ error = EINVAL;
2590+ dprintk("%s no crda\n", __FUNCTION__);
2591+ goto bail;
2592+ }
2593+
2594+ /*
2595+ * Let the dispatch run unlocked, then, interlock against the
2596+ * callback before checking if the operation completed and going
2597+ * to sleep. This insures drivers don't inherit our lock which
2598+ * results in a lock order reversal between crypto_dispatch forced
2599+ * entry and the crypto_done callback into us.
2600+ */
2601+ error = crypto_dispatch(crp);
2602+ if (error) {
2603+ dprintk("%s error in crypto_dispatch\n", __FUNCTION__);
2604+ goto bail;
2605+ }
2606+
2607+ dprintk("%s about to WAIT\n", __FUNCTION__);
2608+ /*
2609+ * we really need to wait for driver to complete to maintain
2610+ * state, luckily interrupts will be remembered
2611+ */
2612+ do {
2613+ error = wait_event_interruptible(crp->crp_waitq,
2614+ ((crp->crp_flags & CRYPTO_F_DONE) != 0));
2615+ /*
2616+ * we can't break out of this loop or we will leave behind
2617+ * a huge mess, however, staying here means if your driver
2618+ * is broken user applications can hang and not be killed.
2619+ * The solution, fix your driver :-)
2620+ */
2621+ if (error) {
2622+ schedule();
2623+ error = 0;
2624+ }
2625+ } while ((crp->crp_flags & CRYPTO_F_DONE) == 0);
2626+ dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
2627+
2628+ if (crp->crp_etype != 0) {
2629+ error = crp->crp_etype;
2630+ dprintk("%s error in crp processing\n", __FUNCTION__);
2631+ goto bail;
2632+ }
2633+
2634+ if (cse->error) {
2635+ error = cse->error;
2636+ dprintk("%s error in cse processing\n", __FUNCTION__);
2637+ goto bail;
2638+ }
2639+
2640+ if (cop->dst && (error = copy_to_user(cop->dst,
2641+ cse->uio.uio_iov[0].iov_base, cop->len))) {
2642+ dprintk("%s bad dst copy\n", __FUNCTION__);
2643+ goto bail;
2644+ }
2645+
2646+ if (cop->mac &&
2647+ (error=copy_to_user(cop->mac,
2648+ (caddr_t)cse->uio.uio_iov[0].iov_base + cop->len,
2649+ cse->info.authsize))) {
2650+ dprintk("%s bad mac copy\n", __FUNCTION__);
2651+ goto bail;
2652+ }
2653+
2654+bail:
2655+ if (crp)
2656+ crypto_freereq(crp);
2657+ if (cse->uio.uio_iov[0].iov_base)
2658+ kfree(cse->uio.uio_iov[0].iov_base);
2659+
2660+ return (error);
2661+}
2662+
2663+static int
2664+cryptodev_cb(void *op)
2665+{
2666+ struct cryptop *crp = (struct cryptop *) op;
2667+ struct csession *cse = (struct csession *)crp->crp_opaque;
2668+ int error;
2669+
2670+ dprintk("%s()\n", __FUNCTION__);
2671+ error = crp->crp_etype;
2672+ if (error == EAGAIN) {
2673+ crp->crp_flags &= ~CRYPTO_F_DONE;
2674+#ifdef NOTYET
2675+ /*
2676+ * DAVIDM I am fairly sure that we should turn this into a batch
2677+ * request to stop bad karma/lockup, revisit
2678+ */
2679+ crp->crp_flags |= CRYPTO_F_BATCH;
2680+#endif
2681+ return crypto_dispatch(crp);
2682+ }
2683+ if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
2684+ cse->error = error;
2685+ wake_up_interruptible(&crp->crp_waitq);
2686+ }
2687+ return (0);
2688+}
2689+
2690+static int
2691+cryptodevkey_cb(void *op)
2692+{
2693+ struct cryptkop *krp = (struct cryptkop *) op;
2694+ dprintk("%s()\n", __FUNCTION__);
2695+ wake_up_interruptible(&krp->krp_waitq);
2696+ return (0);
2697+}
2698+
2699+static int
2700+cryptodev_key(struct crypt_kop *kop)
2701+{
2702+ struct cryptkop *krp = NULL;
2703+ int error = EINVAL;
2704+ int in, out, size, i;
2705+
2706+ dprintk("%s()\n", __FUNCTION__);
2707+ if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
2708+ dprintk("%s params too big\n", __FUNCTION__);
2709+ return (EFBIG);
2710+ }
2711+
2712+ in = kop->crk_iparams;
2713+ out = kop->crk_oparams;
2714+ switch (kop->crk_op) {
2715+ case CRK_MOD_EXP:
2716+ if (in == 3 && out == 1)
2717+ break;
2718+ return (EINVAL);
2719+ case CRK_MOD_EXP_CRT:
2720+ if (in == 6 && out == 1)
2721+ break;
2722+ return (EINVAL);
2723+ case CRK_DSA_SIGN:
2724+ if (in == 5 && out == 2)
2725+ break;
2726+ return (EINVAL);
2727+ case CRK_DSA_VERIFY:
2728+ if (in == 7 && out == 0)
2729+ break;
2730+ return (EINVAL);
2731+ case CRK_DH_COMPUTE_KEY:
2732+ if (in == 3 && out == 1)
2733+ break;
2734+ return (EINVAL);
2735+ default:
2736+ return (EINVAL);
2737+ }
2738+
2739+ krp = (struct cryptkop *)kmalloc(sizeof *krp, GFP_KERNEL);
2740+ if (!krp)
2741+ return (ENOMEM);
2742+ bzero(krp, sizeof *krp);
2743+ krp->krp_op = kop->crk_op;
2744+ krp->krp_status = kop->crk_status;
2745+ krp->krp_iparams = kop->crk_iparams;
2746+ krp->krp_oparams = kop->crk_oparams;
2747+ krp->krp_crid = kop->crk_crid;
2748+ krp->krp_status = 0;
2749+ krp->krp_flags = CRYPTO_KF_CBIMM;
2750+ krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
2751+ init_waitqueue_head(&krp->krp_waitq);
2752+
2753+ for (i = 0; i < CRK_MAXPARAM; i++)
2754+ krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
2755+ for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
2756+ size = (krp->krp_param[i].crp_nbits + 7) / 8;
2757+ if (size == 0)
2758+ continue;
2759+ krp->krp_param[i].crp_p = (caddr_t) kmalloc(size, GFP_KERNEL);
2760+ if (i >= krp->krp_iparams)
2761+ continue;
2762+ error = copy_from_user(krp->krp_param[i].crp_p,
2763+ kop->crk_param[i].crp_p, size);
2764+ if (error)
2765+ goto fail;
2766+ }
2767+
2768+ error = crypto_kdispatch(krp);
2769+ if (error)
2770+ goto fail;
2771+
2772+ do {
2773+ error = wait_event_interruptible(krp->krp_waitq,
2774+ ((krp->krp_flags & CRYPTO_KF_DONE) != 0));
2775+ /*
2776+ * we can't break out of this loop or we will leave behind
2777+ * a huge mess, however, staying here means if your driver
2778+ * is broken user applications can hang and not be killed.
2779+ * The solution, fix your driver :-)
2780+ */
2781+ if (error) {
2782+ schedule();
2783+ error = 0;
2784+ }
2785+ } while ((krp->krp_flags & CRYPTO_KF_DONE) == 0);
2786+
2787+ dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
2788+
2789+ kop->crk_crid = krp->krp_crid; /* device that did the work */
2790+ if (krp->krp_status != 0) {
2791+ error = krp->krp_status;
2792+ goto fail;
2793+ }
2794+
2795+ for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
2796+ size = (krp->krp_param[i].crp_nbits + 7) / 8;
2797+ if (size == 0)
2798+ continue;
2799+ error = copy_to_user(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p,
2800+ size);
2801+ if (error)
2802+ goto fail;
2803+ }
2804+
2805+fail:
2806+ if (krp) {
2807+ kop->crk_status = krp->krp_status;
2808+ for (i = 0; i < CRK_MAXPARAM; i++) {
2809+ if (krp->krp_param[i].crp_p)
2810+ kfree(krp->krp_param[i].crp_p);
2811+ }
2812+ kfree(krp);
2813+ }
2814+ return (error);
2815+}
2816+
2817+static int
2818+cryptodev_find(struct crypt_find_op *find)
2819+{
2820+ device_t dev;
2821+
2822+ if (find->crid != -1) {
2823+ dev = crypto_find_device_byhid(find->crid);
2824+ if (dev == NULL)
2825+ return (ENOENT);
2826+ strlcpy(find->name, device_get_nameunit(dev),
2827+ sizeof(find->name));
2828+ } else {
2829+ find->crid = crypto_find_driver(find->name);
2830+ if (find->crid == -1)
2831+ return (ENOENT);
2832+ }
2833+ return (0);
2834+}
2835+
2836+static struct csession *
2837+csefind(struct fcrypt *fcr, u_int ses)
2838+{
2839+ struct csession *cse;
2840+
2841+ dprintk("%s()\n", __FUNCTION__);
2842+ list_for_each_entry(cse, &fcr->csessions, list)
2843+ if (cse->ses == ses)
2844+ return (cse);
2845+ return (NULL);
2846+}
2847+
2848+static int
2849+csedelete(struct fcrypt *fcr, struct csession *cse_del)
2850+{
2851+ struct csession *cse;
2852+
2853+ dprintk("%s()\n", __FUNCTION__);
2854+ list_for_each_entry(cse, &fcr->csessions, list) {
2855+ if (cse == cse_del) {
2856+ list_del(&cse->list);
2857+ return (1);
2858+ }
2859+ }
2860+ return (0);
2861+}
2862+
2863+static struct csession *
2864+cseadd(struct fcrypt *fcr, struct csession *cse)
2865+{
2866+ dprintk("%s()\n", __FUNCTION__);
2867+ list_add_tail(&cse->list, &fcr->csessions);
2868+ cse->ses = fcr->sesn++;
2869+ return (cse);
2870+}
2871+
2872+static struct csession *
2873+csecreate(struct fcrypt *fcr, u_int64_t sid, struct cryptoini *crie,
2874+ struct cryptoini *cria, struct csession_info *info)
2875+{
2876+ struct csession *cse;
2877+
2878+ dprintk("%s()\n", __FUNCTION__);
2879+ cse = (struct csession *) kmalloc(sizeof(struct csession), GFP_KERNEL);
2880+ if (cse == NULL)
2881+ return NULL;
2882+ memset(cse, 0, sizeof(struct csession));
2883+
2884+ INIT_LIST_HEAD(&cse->list);
2885+ init_waitqueue_head(&cse->waitq);
2886+
2887+ cse->key = crie->cri_key;
2888+ cse->keylen = crie->cri_klen/8;
2889+ cse->mackey = cria->cri_key;
2890+ cse->mackeylen = cria->cri_klen/8;
2891+ cse->sid = sid;
2892+ cse->cipher = crie->cri_alg;
2893+ cse->mac = cria->cri_alg;
2894+ cse->info = *info;
2895+ cseadd(fcr, cse);
2896+ return (cse);
2897+}
2898+
2899+static int
2900+csefree(struct csession *cse)
2901+{
2902+ int error;
2903+
2904+ dprintk("%s()\n", __FUNCTION__);
2905+ error = crypto_freesession(cse->sid);
2906+ if (cse->key)
2907+ kfree(cse->key);
2908+ if (cse->mackey)
2909+ kfree(cse->mackey);
2910+ kfree(cse);
2911+ return(error);
2912+}
2913+
2914+static int
2915+cryptodev_ioctl(
2916+ struct inode *inode,
2917+ struct file *filp,
2918+ unsigned int cmd,
2919+ unsigned long arg)
2920+{
2921+ struct cryptoini cria, crie;
2922+ struct fcrypt *fcr = filp->private_data;
2923+ struct csession *cse;
2924+ struct csession_info info;
2925+ struct session2_op sop;
2926+ struct crypt_op cop;
2927+ struct crypt_kop kop;
2928+ struct crypt_find_op fop;
2929+ u_int64_t sid;
2930+ u_int32_t ses = 0;
2931+ int feat, fd, error = 0, crid;
2932+ mm_segment_t fs;
2933+
2934+ dprintk("%s(cmd=%x arg=%lx)\n", __FUNCTION__, cmd, arg);
2935+
2936+ switch (cmd) {
2937+
2938+ case CRIOGET: {
2939+ dprintk("%s(CRIOGET)\n", __FUNCTION__);
2940+ fs = get_fs();
2941+ set_fs(get_ds());
2942+ for (fd = 0; fd < files_fdtable(current->files)->max_fds; fd++)
2943+ if (files_fdtable(current->files)->fd[fd] == filp)
2944+ break;
2945+ fd = sys_dup(fd);
2946+ set_fs(fs);
2947+ put_user(fd, (int *) arg);
2948+ return IS_ERR_VALUE(fd) ? fd : 0;
2949+ }
2950+
2951+#define CIOCGSESSSTR (cmd == CIOCGSESSION ? "CIOCGSESSION" : "CIOCGSESSION2")
2952+ case CIOCGSESSION:
2953+ case CIOCGSESSION2:
2954+ dprintk("%s(%s)\n", __FUNCTION__, CIOCGSESSSTR);
2955+ memset(&crie, 0, sizeof(crie));
2956+ memset(&cria, 0, sizeof(cria));
2957+ memset(&info, 0, sizeof(info));
2958+ memset(&sop, 0, sizeof(sop));
2959+
2960+ if (copy_from_user(&sop, (void*)arg, (cmd == CIOCGSESSION) ?
2961+ sizeof(struct session_op) : sizeof(sop))) {
2962+ dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
2963+ error = EFAULT;
2964+ goto bail;
2965+ }
2966+
2967+ switch (sop.cipher) {
2968+ case 0:
2969+ dprintk("%s(%s) - no cipher\n", __FUNCTION__, CIOCGSESSSTR);
2970+ break;
2971+ case CRYPTO_NULL_CBC:
2972+ info.blocksize = NULL_BLOCK_LEN;
2973+ info.minkey = NULL_MIN_KEY_LEN;
2974+ info.maxkey = NULL_MAX_KEY_LEN;
2975+ break;
2976+ case CRYPTO_DES_CBC:
2977+ info.blocksize = DES_BLOCK_LEN;
2978+ info.minkey = DES_MIN_KEY_LEN;
2979+ info.maxkey = DES_MAX_KEY_LEN;
2980+ break;
2981+ case CRYPTO_3DES_CBC:
2982+ info.blocksize = DES3_BLOCK_LEN;
2983+ info.minkey = DES3_MIN_KEY_LEN;
2984+ info.maxkey = DES3_MAX_KEY_LEN;
2985+ break;
2986+ case CRYPTO_BLF_CBC:
2987+ info.blocksize = BLOWFISH_BLOCK_LEN;
2988+ info.minkey = BLOWFISH_MIN_KEY_LEN;
2989+ info.maxkey = BLOWFISH_MAX_KEY_LEN;
2990+ break;
2991+ case CRYPTO_CAST_CBC:
2992+ info.blocksize = CAST128_BLOCK_LEN;
2993+ info.minkey = CAST128_MIN_KEY_LEN;
2994+ info.maxkey = CAST128_MAX_KEY_LEN;
2995+ break;
2996+ case CRYPTO_SKIPJACK_CBC:
2997+ info.blocksize = SKIPJACK_BLOCK_LEN;
2998+ info.minkey = SKIPJACK_MIN_KEY_LEN;
2999+ info.maxkey = SKIPJACK_MAX_KEY_LEN;
3000+ break;
3001+ case CRYPTO_AES_CBC:
3002+ info.blocksize = AES_BLOCK_LEN;
3003+ info.minkey = AES_MIN_KEY_LEN;
3004+ info.maxkey = AES_MAX_KEY_LEN;
3005+ break;
3006+ case CRYPTO_ARC4:
3007+ info.blocksize = ARC4_BLOCK_LEN;
3008+ info.minkey = ARC4_MIN_KEY_LEN;
3009+ info.maxkey = ARC4_MAX_KEY_LEN;
3010+ break;
3011+ case CRYPTO_CAMELLIA_CBC:
3012+ info.blocksize = CAMELLIA_BLOCK_LEN;
3013+ info.minkey = CAMELLIA_MIN_KEY_LEN;
3014+ info.maxkey = CAMELLIA_MAX_KEY_LEN;
3015+ break;
3016+ default:
3017+ dprintk("%s(%s) - bad cipher\n", __FUNCTION__, CIOCGSESSSTR);
3018+ error = EINVAL;
3019+ goto bail;
3020+ }
3021+
3022+ switch (sop.mac) {
3023+ case 0:
3024+ dprintk("%s(%s) - no mac\n", __FUNCTION__, CIOCGSESSSTR);
3025+ break;
3026+ case CRYPTO_NULL_HMAC:
3027+ info.authsize = NULL_HASH_LEN;
3028+ break;
3029+ case CRYPTO_MD5:
3030+ info.authsize = MD5_HASH_LEN;
3031+ break;
3032+ case CRYPTO_SHA1:
3033+ info.authsize = SHA1_HASH_LEN;
3034+ break;
3035+ case CRYPTO_SHA2_256:
3036+ info.authsize = SHA2_256_HASH_LEN;
3037+ break;
3038+ case CRYPTO_SHA2_384:
3039+ info.authsize = SHA2_384_HASH_LEN;
3040+ break;
3041+ case CRYPTO_SHA2_512:
3042+ info.authsize = SHA2_512_HASH_LEN;
3043+ break;
3044+ case CRYPTO_RIPEMD160:
3045+ info.authsize = RIPEMD160_HASH_LEN;
3046+ break;
3047+ case CRYPTO_MD5_HMAC:
3048+ info.authsize = MD5_HASH_LEN;
3049+ info.authkey = 16;
3050+ break;
3051+ case CRYPTO_SHA1_HMAC:
3052+ info.authsize = SHA1_HASH_LEN;
3053+ info.authkey = 20;
3054+ break;
3055+ case CRYPTO_SHA2_256_HMAC:
3056+ info.authsize = SHA2_256_HASH_LEN;
3057+ info.authkey = 32;
3058+ break;
3059+ case CRYPTO_SHA2_384_HMAC:
3060+ info.authsize = SHA2_384_HASH_LEN;
3061+ info.authkey = 48;
3062+ break;
3063+ case CRYPTO_SHA2_512_HMAC:
3064+ info.authsize = SHA2_512_HASH_LEN;
3065+ info.authkey = 64;
3066+ break;
3067+ case CRYPTO_RIPEMD160_HMAC:
3068+ info.authsize = RIPEMD160_HASH_LEN;
3069+ info.authkey = 20;
3070+ break;
3071+ default:
3072+ dprintk("%s(%s) - bad mac\n", __FUNCTION__, CIOCGSESSSTR);
3073+ error = EINVAL;
3074+ goto bail;
3075+ }
3076+
3077+ if (info.blocksize) {
3078+ crie.cri_alg = sop.cipher;
3079+ crie.cri_klen = sop.keylen * 8;
3080+ if ((info.maxkey && sop.keylen > info.maxkey) ||
3081+ sop.keylen < info.minkey) {
3082+ dprintk("%s(%s) - bad key\n", __FUNCTION__, CIOCGSESSSTR);
3083+ error = EINVAL;
3084+ goto bail;
3085+ }
3086+
3087+ crie.cri_key = (u_int8_t *) kmalloc(crie.cri_klen/8+1, GFP_KERNEL);
3088+ if (copy_from_user(crie.cri_key, sop.key,
3089+ crie.cri_klen/8)) {
3090+ dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
3091+ error = EFAULT;
3092+ goto bail;
3093+ }
3094+ if (info.authsize)
3095+ crie.cri_next = &cria;
3096+ }
3097+
3098+ if (info.authsize) {
3099+ cria.cri_alg = sop.mac;
3100+ cria.cri_klen = sop.mackeylen * 8;
3101+ if (info.authkey && sop.mackeylen != info.authkey) {
3102+ dprintk("%s(%s) - mackeylen %d != %d\n", __FUNCTION__,
3103+ CIOCGSESSSTR, sop.mackeylen, info.authkey);
3104+ error = EINVAL;
3105+ goto bail;
3106+ }
3107+
3108+ if (cria.cri_klen) {
3109+ cria.cri_key = (u_int8_t *) kmalloc(cria.cri_klen/8,GFP_KERNEL);
3110+ if (copy_from_user(cria.cri_key, sop.mackey,
3111+ cria.cri_klen / 8)) {
3112+ dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
3113+ error = EFAULT;
3114+ goto bail;
3115+ }
3116+ }
3117+ }
3118+
3119+ /* NB: CIOGSESSION2 has the crid */
3120+ if (cmd == CIOCGSESSION2) {
3121+ crid = sop.crid;
3122+ error = checkcrid(crid);
3123+ if (error) {
3124+ dprintk("%s(%s) - checkcrid %x\n", __FUNCTION__,
3125+ CIOCGSESSSTR, error);
3126+ goto bail;
3127+ }
3128+ } else {
3129+ /* allow either HW or SW to be used */
3130+ crid = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
3131+ }
3132+ error = crypto_newsession(&sid, (info.blocksize ? &crie : &cria), crid);
3133+ if (error) {
3134+ dprintk("%s(%s) - newsession %d\n",__FUNCTION__,CIOCGSESSSTR,error);
3135+ goto bail;
3136+ }
3137+
3138+ cse = csecreate(fcr, sid, &crie, &cria, &info);
3139+ if (cse == NULL) {
3140+ crypto_freesession(sid);
3141+ error = EINVAL;
3142+ dprintk("%s(%s) - csecreate failed\n", __FUNCTION__, CIOCGSESSSTR);
3143+ goto bail;
3144+ }
3145+ sop.ses = cse->ses;
3146+
3147+ if (cmd == CIOCGSESSION2) {
3148+ /* return hardware/driver id */
3149+ sop.crid = CRYPTO_SESID2HID(cse->sid);
3150+ }
3151+
3152+ if (copy_to_user((void*)arg, &sop, (cmd == CIOCGSESSION) ?
3153+ sizeof(struct session_op) : sizeof(sop))) {
3154+ dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
3155+ error = EFAULT;
3156+ }
3157+bail:
3158+ if (error) {
3159+ dprintk("%s(%s) - bail %d\n", __FUNCTION__, CIOCGSESSSTR, error);
3160+ if (crie.cri_key)
3161+ kfree(crie.cri_key);
3162+ if (cria.cri_key)
3163+ kfree(cria.cri_key);
3164+ }
3165+ break;
3166+ case CIOCFSESSION:
3167+ dprintk("%s(CIOCFSESSION)\n", __FUNCTION__);
3168+ get_user(ses, (uint32_t*)arg);
3169+ cse = csefind(fcr, ses);
3170+ if (cse == NULL) {
3171+ error = EINVAL;
3172+ dprintk("%s(CIOCFSESSION) - Fail %d\n", __FUNCTION__, error);
3173+ break;
3174+ }
3175+ csedelete(fcr, cse);
3176+ error = csefree(cse);
3177+ break;
3178+ case CIOCCRYPT:
3179+ dprintk("%s(CIOCCRYPT)\n", __FUNCTION__);
3180+ if(copy_from_user(&cop, (void*)arg, sizeof(cop))) {
3181+ dprintk("%s(CIOCCRYPT) - bad copy\n", __FUNCTION__);
3182+ error = EFAULT;
3183+ goto bail;
3184+ }
3185+ cse = csefind(fcr, cop.ses);
3186+ if (cse == NULL) {
3187+ error = EINVAL;
3188+ dprintk("%s(CIOCCRYPT) - Fail %d\n", __FUNCTION__, error);
3189+ break;
3190+ }
3191+ error = cryptodev_op(cse, &cop);
3192+ if(copy_to_user((void*)arg, &cop, sizeof(cop))) {
3193+ dprintk("%s(CIOCCRYPT) - bad return copy\n", __FUNCTION__);
3194+ error = EFAULT;
3195+ goto bail;
3196+ }
3197+ break;
3198+ case CIOCKEY:
3199+ case CIOCKEY2:
3200+ dprintk("%s(CIOCKEY)\n", __FUNCTION__);
3201+ if (!crypto_userasymcrypto)
3202+ return (EPERM); /* XXX compat? */
3203+ if(copy_from_user(&kop, (void*)arg, sizeof(kop))) {
3204+ dprintk("%s(CIOCKEY) - bad copy\n", __FUNCTION__);
3205+ error = EFAULT;
3206+ goto bail;
3207+ }
3208+ if (cmd == CIOCKEY) {
3209+ /* NB: crypto core enforces s/w driver use */
3210+ kop.crk_crid =
3211+ CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
3212+ }
3213+ error = cryptodev_key(&kop);
3214+ if(copy_to_user((void*)arg, &kop, sizeof(kop))) {
3215+ dprintk("%s(CIOCGKEY) - bad return copy\n", __FUNCTION__);
3216+ error = EFAULT;
3217+ goto bail;
3218+ }
3219+ break;
3220+ case CIOCASYMFEAT:
3221+ dprintk("%s(CIOCASYMFEAT)\n", __FUNCTION__);
3222+ if (!crypto_userasymcrypto) {
3223+ /*
3224+ * NB: if user asym crypto operations are
3225+ * not permitted return "no algorithms"
3226+ * so well-behaved applications will just
3227+ * fallback to doing them in software.
3228+ */
3229+ feat = 0;
3230+ } else
3231+ error = crypto_getfeat(&feat);
3232+ if (!error) {
3233+ error = copy_to_user((void*)arg, &feat, sizeof(feat));
3234+ }
3235+ break;
3236+ case CIOCFINDDEV:
3237+ if (copy_from_user(&fop, (void*)arg, sizeof(fop))) {
3238+ dprintk("%s(CIOCFINDDEV) - bad copy\n", __FUNCTION__);
3239+ error = EFAULT;
3240+ goto bail;
3241+ }
3242+ error = cryptodev_find(&fop);
3243+ if (copy_to_user((void*)arg, &fop, sizeof(fop))) {
3244+ dprintk("%s(CIOCFINDDEV) - bad return copy\n", __FUNCTION__);
3245+ error = EFAULT;
3246+ goto bail;
3247+ }
3248+ break;
3249+ default:
3250+ dprintk("%s(unknown ioctl 0x%x)\n", __FUNCTION__, cmd);
3251+ error = EINVAL;
3252+ break;
3253+ }
3254+ return(-error);
3255+}
3256+
3257+#ifdef HAVE_UNLOCKED_IOCTL
3258+static long
3259+cryptodev_unlocked_ioctl(
3260+ struct file *filp,
3261+ unsigned int cmd,
3262+ unsigned long arg)
3263+{
3264+ return cryptodev_ioctl(NULL, filp, cmd, arg);
3265+}
3266+#endif
3267+
3268+static int
3269+cryptodev_open(struct inode *inode, struct file *filp)
3270+{
3271+ struct fcrypt *fcr;
3272+
3273+ dprintk("%s()\n", __FUNCTION__);
3274+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
3275+ /*
3276+ * on 2.6.35 private_data points to a miscdevice structure, we override
3277+ * it, which is currently safe to do.
3278+ */
3279+ if (filp->private_data) {
3280+ printk("cryptodev: Private data already exists - %p!\n", filp->private_data);
3281+ return(-ENODEV);
3282+ }
3283+#endif
3284+
3285+ fcr = kmalloc(sizeof(*fcr), GFP_KERNEL);
3286+ if (!fcr) {
3287+ dprintk("%s() - malloc failed\n", __FUNCTION__);
3288+ return(-ENOMEM);
3289+ }
3290+ memset(fcr, 0, sizeof(*fcr));
3291+
3292+ INIT_LIST_HEAD(&fcr->csessions);
3293+ filp->private_data = fcr;
3294+ return(0);
3295+}
3296+
3297+static int
3298+cryptodev_release(struct inode *inode, struct file *filp)
3299+{
3300+ struct fcrypt *fcr = filp->private_data;
3301+ struct csession *cse, *tmp;
3302+
3303+ dprintk("%s()\n", __FUNCTION__);
3304+ if (!filp) {
3305+ printk("cryptodev: No private data on release\n");
3306+ return(0);
3307+ }
3308+
3309+ list_for_each_entry_safe(cse, tmp, &fcr->csessions, list) {
3310+ list_del(&cse->list);
3311+ (void)csefree(cse);
3312+ }
3313+ filp->private_data = NULL;
3314+ kfree(fcr);
3315+ return(0);
3316+}
3317+
3318+static struct file_operations cryptodev_fops = {
3319+ .owner = THIS_MODULE,
3320+ .open = cryptodev_open,
3321+ .release = cryptodev_release,
3322+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
3323+ .ioctl = cryptodev_ioctl,
3324+#endif
3325+#ifdef HAVE_UNLOCKED_IOCTL
3326+ .unlocked_ioctl = cryptodev_unlocked_ioctl,
3327+#endif
3328+};
3329+
3330+static struct miscdevice cryptodev = {
3331+ .minor = CRYPTODEV_MINOR,
3332+ .name = "crypto",
3333+ .fops = &cryptodev_fops,
3334+};
3335+
3336+static int __init
3337+cryptodev_init(void)
3338+{
3339+ int rc;
3340+
3341+ dprintk("%s(%p)\n", __FUNCTION__, cryptodev_init);
3342+ rc = misc_register(&cryptodev);
3343+ if (rc) {
3344+ printk(KERN_ERR "cryptodev: registration of /dev/crypto failed\n");
3345+ return(rc);
3346+ }
3347+
3348+ return(0);
3349+}
3350+
3351+static void __exit
3352+cryptodev_exit(void)
3353+{
3354+ dprintk("%s()\n", __FUNCTION__);
3355+ misc_deregister(&cryptodev);
3356+}
3357+
3358+module_init(cryptodev_init);
3359+module_exit(cryptodev_exit);
3360+
3361+MODULE_LICENSE("BSD");
3362+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
3363+MODULE_DESCRIPTION("Cryptodev (user interface to OCF)");
3364diff --git a/crypto/ocf/cryptodev.h b/crypto/ocf/cryptodev.h
3365new file mode 100644
3366index 0000000..cca0ec8
3367--- /dev/null
3368+++ b/crypto/ocf/cryptodev.h
3369@@ -0,0 +1,480 @@
3370+/* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.25 2007/05/09 19:37:02 gnn Exp $ */
3371+/* $OpenBSD: cryptodev.h,v 1.31 2002/06/11 11:14:29 beck Exp $ */
3372+
3373+/*-
3374+ * Linux port done by David McCullough <david_mccullough@mcafee.com>
3375+ * Copyright (C) 2006-2010 David McCullough
3376+ * Copyright (C) 2004-2005 Intel Corporation.
3377+ * The license and original author are listed below.
3378+ *
3379+ * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
3380+ * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
3381+ *
3382+ * This code was written by Angelos D. Keromytis in Athens, Greece, in
3383+ * February 2000. Network Security Technologies Inc. (NSTI) kindly
3384+ * supported the development of this code.
3385+ *
3386+ * Copyright (c) 2000 Angelos D. Keromytis
3387+ *
3388+ * Permission to use, copy, and modify this software with or without fee
3389+ * is hereby granted, provided that this entire notice is included in
3390+ * all source code copies of any software which is or includes a copy or
3391+ * modification of this software.
3392+ *
3393+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
3394+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
3395+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
3396+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
3397+ * PURPOSE.
3398+ *
3399+ * Copyright (c) 2001 Theo de Raadt
3400+ *
3401+ * Redistribution and use in source and binary forms, with or without
3402+ * modification, are permitted provided that the following conditions
3403+ * are met:
3404+ *
3405+ * 1. Redistributions of source code must retain the above copyright
3406+ * notice, this list of conditions and the following disclaimer.
3407+ * 2. Redistributions in binary form must reproduce the above copyright
3408+ * notice, this list of conditions and the following disclaimer in the
3409+ * documentation and/or other materials provided with the distribution.
3410+ * 3. The name of the author may not be used to endorse or promote products
3411+ * derived from this software without specific prior written permission.
3412+ *
3413+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
3414+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
3415+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
3416+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
3417+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
3418+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3419+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3420+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3421+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3422+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3423+ *
3424+ * Effort sponsored in part by the Defense Advanced Research Projects
3425+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
3426+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
3427+ *
3428+ */
3429+
3430+#ifndef _CRYPTO_CRYPTO_H_
3431+#define _CRYPTO_CRYPTO_H_
3432+
3433+/* Some initial values */
3434+#define CRYPTO_DRIVERS_INITIAL 4
3435+#define CRYPTO_SW_SESSIONS 32
3436+
3437+/* Hash values */
3438+#define NULL_HASH_LEN 0
3439+#define MD5_HASH_LEN 16
3440+#define SHA1_HASH_LEN 20
3441+#define RIPEMD160_HASH_LEN 20
3442+#define SHA2_256_HASH_LEN 32
3443+#define SHA2_384_HASH_LEN 48
3444+#define SHA2_512_HASH_LEN 64
3445+#define MD5_KPDK_HASH_LEN 16
3446+#define SHA1_KPDK_HASH_LEN 20
3447+/* Maximum hash algorithm result length */
3448+#define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */
3449+
3450+/* HMAC values */
3451+#define NULL_HMAC_BLOCK_LEN 1
3452+#define MD5_HMAC_BLOCK_LEN 64
3453+#define SHA1_HMAC_BLOCK_LEN 64
3454+#define RIPEMD160_HMAC_BLOCK_LEN 64
3455+#define SHA2_256_HMAC_BLOCK_LEN 64
3456+#define SHA2_384_HMAC_BLOCK_LEN 128
3457+#define SHA2_512_HMAC_BLOCK_LEN 128
3458+/* Maximum HMAC block length */
3459+#define HMAC_MAX_BLOCK_LEN SHA2_512_HMAC_BLOCK_LEN /* Keep this updated */
3460+#define HMAC_IPAD_VAL 0x36
3461+#define HMAC_OPAD_VAL 0x5C
3462+
3463+/* Encryption algorithm block sizes */
3464+#define NULL_BLOCK_LEN 1
3465+#define DES_BLOCK_LEN 8
3466+#define DES3_BLOCK_LEN 8
3467+#define BLOWFISH_BLOCK_LEN 8
3468+#define SKIPJACK_BLOCK_LEN 8
3469+#define CAST128_BLOCK_LEN 8
3470+#define RIJNDAEL128_BLOCK_LEN 16
3471+#define AES_BLOCK_LEN RIJNDAEL128_BLOCK_LEN
3472+#define CAMELLIA_BLOCK_LEN 16
3473+#define ARC4_BLOCK_LEN 1
3474+#define EALG_MAX_BLOCK_LEN AES_BLOCK_LEN /* Keep this updated */
3475+
3476+/* Encryption algorithm min and max key sizes */
3477+#define NULL_MIN_KEY_LEN 0
3478+#define NULL_MAX_KEY_LEN 0
3479+#define DES_MIN_KEY_LEN 8
3480+#define DES_MAX_KEY_LEN 8
3481+#define DES3_MIN_KEY_LEN 24
3482+#define DES3_MAX_KEY_LEN 24
3483+#define BLOWFISH_MIN_KEY_LEN 4
3484+#define BLOWFISH_MAX_KEY_LEN 56
3485+#define SKIPJACK_MIN_KEY_LEN 10
3486+#define SKIPJACK_MAX_KEY_LEN 10
3487+#define CAST128_MIN_KEY_LEN 5
3488+#define CAST128_MAX_KEY_LEN 16
3489+#define RIJNDAEL128_MIN_KEY_LEN 16
3490+#define RIJNDAEL128_MAX_KEY_LEN 32
3491+#define AES_MIN_KEY_LEN RIJNDAEL128_MIN_KEY_LEN
3492+#define AES_MAX_KEY_LEN RIJNDAEL128_MAX_KEY_LEN
3493+#define CAMELLIA_MIN_KEY_LEN 16
3494+#define CAMELLIA_MAX_KEY_LEN 32
3495+#define ARC4_MIN_KEY_LEN 1
3496+#define ARC4_MAX_KEY_LEN 256
3497+
3498+/* Max size of data that can be processed */
3499+#define CRYPTO_MAX_DATA_LEN 64*1024 - 1
3500+
3501+#define CRYPTO_ALGORITHM_MIN 1
3502+#define CRYPTO_DES_CBC 1
3503+#define CRYPTO_3DES_CBC 2
3504+#define CRYPTO_BLF_CBC 3
3505+#define CRYPTO_CAST_CBC 4
3506+#define CRYPTO_SKIPJACK_CBC 5
3507+#define CRYPTO_MD5_HMAC 6
3508+#define CRYPTO_SHA1_HMAC 7
3509+#define CRYPTO_RIPEMD160_HMAC 8
3510+#define CRYPTO_MD5_KPDK 9
3511+#define CRYPTO_SHA1_KPDK 10
3512+#define CRYPTO_RIJNDAEL128_CBC 11 /* 128 bit blocksize */
3513+#define CRYPTO_AES_CBC 11 /* 128 bit blocksize -- the same as above */
3514+#define CRYPTO_ARC4 12
3515+#define CRYPTO_MD5 13
3516+#define CRYPTO_SHA1 14
3517+#define CRYPTO_NULL_HMAC 15
3518+#define CRYPTO_NULL_CBC 16
3519+#define CRYPTO_DEFLATE_COMP 17 /* Deflate compression algorithm */
3520+#define CRYPTO_SHA2_256_HMAC 18
3521+#define CRYPTO_SHA2_384_HMAC 19
3522+#define CRYPTO_SHA2_512_HMAC 20
3523+#define CRYPTO_CAMELLIA_CBC 21
3524+#define CRYPTO_SHA2_256 22
3525+#define CRYPTO_SHA2_384 23
3526+#define CRYPTO_SHA2_512 24
3527+#define CRYPTO_RIPEMD160 25
3528+#define CRYPTO_LZS_COMP 26
3529+#define CRYPTO_ALGORITHM_MAX 26 /* Keep updated - see above */
3530+
3531+/* Algorithm flags */
3532+#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
3533+#define CRYPTO_ALG_FLAG_RNG_ENABLE 0x02 /* Has HW RNG for DH/DSA */
3534+#define CRYPTO_ALG_FLAG_DSA_SHA 0x04 /* Can do SHA on msg */
3535+
3536+/*
3537+ * Crypto driver/device flags. They can set in the crid
3538+ * parameter when creating a session or submitting a key
3539+ * op to affect the device/driver assigned. If neither
3540+ * of these are specified then the crid is assumed to hold
3541+ * the driver id of an existing (and suitable) device that
3542+ * must be used to satisfy the request.
3543+ */
3544+#define CRYPTO_FLAG_HARDWARE 0x01000000 /* hardware accelerated */
3545+#define CRYPTO_FLAG_SOFTWARE 0x02000000 /* software implementation */
3546+
3547+/* NB: deprecated */
3548+struct session_op {
3549+ u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
3550+ u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
3551+
3552+ u_int32_t keylen; /* cipher key */
3553+ caddr_t key;
3554+ int mackeylen; /* mac key */
3555+ caddr_t mackey;
3556+
3557+ u_int32_t ses; /* returns: session # */
3558+};
3559+
3560+struct session2_op {
3561+ u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
3562+ u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
3563+
3564+ u_int32_t keylen; /* cipher key */
3565+ caddr_t key;
3566+ int mackeylen; /* mac key */
3567+ caddr_t mackey;
3568+
3569+ u_int32_t ses; /* returns: session # */
3570+ int crid; /* driver id + flags (rw) */
3571+ int pad[4]; /* for future expansion */
3572+};
3573+
3574+struct crypt_op {
3575+ u_int32_t ses;
3576+ u_int16_t op; /* i.e. COP_ENCRYPT */
3577+#define COP_NONE 0
3578+#define COP_ENCRYPT 1
3579+#define COP_DECRYPT 2
3580+ u_int16_t flags;
3581+#define COP_F_BATCH 0x0008 /* Batch op if possible */
3582+ u_int len;
3583+ caddr_t src, dst; /* become iov[] inside kernel */
3584+ caddr_t mac; /* must be big enough for chosen MAC */
3585+ caddr_t iv;
3586+};
3587+
3588+/*
3589+ * Parameters for looking up a crypto driver/device by
3590+ * device name or by id. The latter are returned for
3591+ * created sessions (crid) and completed key operations.
3592+ */
3593+struct crypt_find_op {
3594+ int crid; /* driver id + flags */
3595+ char name[32]; /* device/driver name */
3596+};
3597+
3598+/* bignum parameter, in packed bytes, ... */
3599+struct crparam {
3600+ caddr_t crp_p;
3601+ u_int crp_nbits;
3602+};
3603+
3604+#define CRK_MAXPARAM 8
3605+
3606+struct crypt_kop {
3607+ u_int crk_op; /* ie. CRK_MOD_EXP or other */
3608+ u_int crk_status; /* return status */
3609+ u_short crk_iparams; /* # of input parameters */
3610+ u_short crk_oparams; /* # of output parameters */
3611+ u_int crk_crid; /* NB: only used by CIOCKEY2 (rw) */
3612+ struct crparam crk_param[CRK_MAXPARAM];
3613+};
3614+#define CRK_ALGORITM_MIN 0
3615+#define CRK_MOD_EXP 0
3616+#define CRK_MOD_EXP_CRT 1
3617+#define CRK_DSA_SIGN 2
3618+#define CRK_DSA_VERIFY 3
3619+#define CRK_DH_COMPUTE_KEY 4
3620+#define CRK_ALGORITHM_MAX 4 /* Keep updated - see below */
3621+
3622+#define CRF_MOD_EXP (1 << CRK_MOD_EXP)
3623+#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT)
3624+#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN)
3625+#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY)
3626+#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
3627+
3628+/*
3629+ * done against open of /dev/crypto, to get a cloned descriptor.
3630+ * Please use F_SETFD against the cloned descriptor.
3631+ */
3632+#define CRIOGET _IOWR('c', 100, u_int32_t)
3633+#define CRIOASYMFEAT CIOCASYMFEAT
3634+#define CRIOFINDDEV CIOCFINDDEV
3635+
3636+/* the following are done against the cloned descriptor */
3637+#define CIOCGSESSION _IOWR('c', 101, struct session_op)
3638+#define CIOCFSESSION _IOW('c', 102, u_int32_t)
3639+#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
3640+#define CIOCKEY _IOWR('c', 104, struct crypt_kop)
3641+#define CIOCASYMFEAT _IOR('c', 105, u_int32_t)
3642+#define CIOCGSESSION2 _IOWR('c', 106, struct session2_op)
3643+#define CIOCKEY2 _IOWR('c', 107, struct crypt_kop)
3644+#define CIOCFINDDEV _IOWR('c', 108, struct crypt_find_op)
3645+
3646+struct cryptotstat {
3647+ struct timespec acc; /* total accumulated time */
3648+ struct timespec min; /* min time */
3649+ struct timespec max; /* max time */
3650+ u_int32_t count; /* number of observations */
3651+};
3652+
3653+struct cryptostats {
3654+ u_int32_t cs_ops; /* symmetric crypto ops submitted */
3655+ u_int32_t cs_errs; /* symmetric crypto ops that failed */
3656+ u_int32_t cs_kops; /* asymetric/key ops submitted */
3657+ u_int32_t cs_kerrs; /* asymetric/key ops that failed */
3658+ u_int32_t cs_intrs; /* crypto swi thread activations */
3659+ u_int32_t cs_rets; /* crypto return thread activations */
3660+ u_int32_t cs_blocks; /* symmetric op driver block */
3661+ u_int32_t cs_kblocks; /* symmetric op driver block */
3662+ /*
3663+ * When CRYPTO_TIMING is defined at compile time and the
3664+ * sysctl debug.crypto is set to 1, the crypto system will
3665+ * accumulate statistics about how long it takes to process
3666+ * crypto requests at various points during processing.
3667+ */
3668+ struct cryptotstat cs_invoke; /* crypto_dipsatch -> crypto_invoke */
3669+ struct cryptotstat cs_done; /* crypto_invoke -> crypto_done */
3670+ struct cryptotstat cs_cb; /* crypto_done -> callback */
3671+ struct cryptotstat cs_finis; /* callback -> callback return */
3672+
3673+ u_int32_t cs_drops; /* crypto ops dropped due to congestion */
3674+};
3675+
3676+#ifdef __KERNEL__
3677+
3678+/* Standard initialization structure beginning */
3679+struct cryptoini {
3680+ int cri_alg; /* Algorithm to use */
3681+ int cri_klen; /* Key length, in bits */
3682+ int cri_mlen; /* Number of bytes we want from the
3683+ entire hash. 0 means all. */
3684+ caddr_t cri_key; /* key to use */
3685+ u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */
3686+ struct cryptoini *cri_next;
3687+};
3688+
3689+/* Describe boundaries of a single crypto operation */
3690+struct cryptodesc {
3691+ int crd_skip; /* How many bytes to ignore from start */
3692+ int crd_len; /* How many bytes to process */
3693+ int crd_inject; /* Where to inject results, if applicable */
3694+ int crd_flags;
3695+
3696+#define CRD_F_ENCRYPT 0x01 /* Set when doing encryption */
3697+#define CRD_F_IV_PRESENT 0x02 /* When encrypting, IV is already in
3698+ place, so don't copy. */
3699+#define CRD_F_IV_EXPLICIT 0x04 /* IV explicitly provided */
3700+#define CRD_F_DSA_SHA_NEEDED 0x08 /* Compute SHA-1 of buffer for DSA */
3701+#define CRD_F_KEY_EXPLICIT 0x10 /* Key explicitly provided */
3702+#define CRD_F_COMP 0x0f /* Set when doing compression */
3703+
3704+ struct cryptoini CRD_INI; /* Initialization/context data */
3705+#define crd_iv CRD_INI.cri_iv
3706+#define crd_key CRD_INI.cri_key
3707+#define crd_alg CRD_INI.cri_alg
3708+#define crd_klen CRD_INI.cri_klen
3709+#define crd_mlen CRD_INI.cri_mlen
3710+
3711+ struct cryptodesc *crd_next;
3712+};
3713+
3714+/* Structure describing complete operation */
3715+struct cryptop {
3716+ struct list_head crp_next;
3717+ wait_queue_head_t crp_waitq;
3718+
3719+ u_int64_t crp_sid; /* Session ID */
3720+ int crp_ilen; /* Input data total length */
3721+ int crp_olen; /* Result total length */
3722+
3723+ int crp_etype; /*
3724+ * Error type (zero means no error).
3725+ * All error codes except EAGAIN
3726+ * indicate possible data corruption (as in,
3727+ * the data have been touched). On all
3728+ * errors, the crp_sid may have changed
3729+ * (reset to a new one), so the caller
3730+ * should always check and use the new
3731+ * value on future requests.
3732+ */
3733+ int crp_flags;
3734+
3735+#define CRYPTO_F_SKBUF 0x0001 /* Input/output are skbuf chains */
3736+#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
3737+#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
3738+#define CRYPTO_F_BATCH 0x0008 /* Batch op if possible */
3739+#define CRYPTO_F_CBIMM 0x0010 /* Do callback immediately */
3740+#define CRYPTO_F_DONE 0x0020 /* Operation completed */
3741+#define CRYPTO_F_CBIFSYNC 0x0040 /* Do CBIMM if op is synchronous */
3742+
3743+ caddr_t crp_buf; /* Data to be processed */
3744+ caddr_t crp_opaque; /* Opaque pointer, passed along */
3745+ struct cryptodesc *crp_desc; /* Linked list of processing descriptors */
3746+
3747+ int (*crp_callback)(struct cryptop *); /* Callback function */
3748+};
3749+
3750+#define CRYPTO_BUF_CONTIG 0x0
3751+#define CRYPTO_BUF_IOV 0x1
3752+#define CRYPTO_BUF_SKBUF 0x2
3753+
3754+#define CRYPTO_OP_DECRYPT 0x0
3755+#define CRYPTO_OP_ENCRYPT 0x1
3756+
3757+/*
3758+ * Hints passed to process methods.
3759+ */
3760+#define CRYPTO_HINT_MORE 0x1 /* more ops coming shortly */
3761+
3762+struct cryptkop {
3763+ struct list_head krp_next;
3764+ wait_queue_head_t krp_waitq;
3765+
3766+ int krp_flags;
3767+#define CRYPTO_KF_DONE 0x0001 /* Operation completed */
3768+#define CRYPTO_KF_CBIMM 0x0002 /* Do callback immediately */
3769+
3770+ u_int krp_op; /* ie. CRK_MOD_EXP or other */
3771+ u_int krp_status; /* return status */
3772+ u_short krp_iparams; /* # of input parameters */
3773+ u_short krp_oparams; /* # of output parameters */
3774+ u_int krp_crid; /* desired device, etc. */
3775+ u_int32_t krp_hid;
3776+ struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
3777+ int (*krp_callback)(struct cryptkop *);
3778+};
3779+
3780+#include <ocf-compat.h>
3781+
3782+/*
3783+ * Session ids are 64 bits. The lower 32 bits contain a "local id" which
3784+ * is a driver-private session identifier. The upper 32 bits contain a
3785+ * "hardware id" used by the core crypto code to identify the driver and
3786+ * a copy of the driver's capabilities that can be used by client code to
3787+ * optimize operation.
3788+ */
3789+#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0x00ffffff)
3790+#define CRYPTO_SESID2CAPS(_sid) (((_sid) >> 32) & 0xff000000)
3791+#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
3792+
3793+extern int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard);
3794+extern int crypto_freesession(u_int64_t sid);
3795+#define CRYPTOCAP_F_HARDWARE CRYPTO_FLAG_HARDWARE
3796+#define CRYPTOCAP_F_SOFTWARE CRYPTO_FLAG_SOFTWARE
3797+#define CRYPTOCAP_F_SYNC 0x04000000 /* operates synchronously */
3798+extern int32_t crypto_get_driverid(device_t dev, int flags);
3799+extern int crypto_find_driver(const char *);
3800+extern device_t crypto_find_device_byhid(int hid);
3801+extern int crypto_getcaps(int hid);
3802+extern int crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
3803+ u_int32_t flags);
3804+extern int crypto_kregister(u_int32_t, int, u_int32_t);
3805+extern int crypto_unregister(u_int32_t driverid, int alg);
3806+extern int crypto_unregister_all(u_int32_t driverid);
3807+extern int crypto_dispatch(struct cryptop *crp);
3808+extern int crypto_kdispatch(struct cryptkop *);
3809+#define CRYPTO_SYMQ 0x1
3810+#define CRYPTO_ASYMQ 0x2
3811+extern int crypto_unblock(u_int32_t, int);
3812+extern void crypto_done(struct cryptop *crp);
3813+extern void crypto_kdone(struct cryptkop *);
3814+extern int crypto_getfeat(int *);
3815+
3816+extern void crypto_freereq(struct cryptop *crp);
3817+extern struct cryptop *crypto_getreq(int num);
3818+
3819+extern int crypto_usercrypto; /* userland may do crypto requests */
3820+extern int crypto_userasymcrypto; /* userland may do asym crypto reqs */
3821+extern int crypto_devallowsoft; /* only use hardware crypto */
3822+
3823+/*
3824+ * random number support, crypto_unregister_all will unregister
3825+ */
3826+extern int crypto_rregister(u_int32_t driverid,
3827+ int (*read_random)(void *arg, u_int32_t *buf, int len), void *arg);
3828+extern int crypto_runregister_all(u_int32_t driverid);
3829+
3830+/*
3831+ * Crypto-related utility routines used mainly by drivers.
3832+ *
3833+ * XXX these don't really belong here; but for now they're
3834+ * kept apart from the rest of the system.
3835+ */
3836+struct uio;
3837+extern void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp);
3838+extern void cuio_copyback(struct uio* uio, int off, int len, caddr_t cp);
3839+extern struct iovec *cuio_getptr(struct uio *uio, int loc, int *off);
3840+
3841+extern void crypto_copyback(int flags, caddr_t buf, int off, int size,
3842+ caddr_t in);
3843+extern void crypto_copydata(int flags, caddr_t buf, int off, int size,
3844+ caddr_t out);
3845+extern int crypto_apply(int flags, caddr_t buf, int off, int len,
3846+ int (*f)(void *, void *, u_int), void *arg);
3847+
3848+#endif /* __KERNEL__ */
3849+#endif /* _CRYPTO_CRYPTO_H_ */
3850diff --git a/crypto/ocf/cryptosoft.c b/crypto/ocf/cryptosoft.c
3851new file mode 100644
3852index 0000000..aa2383d
3853--- /dev/null
3854+++ b/crypto/ocf/cryptosoft.c
3855@@ -0,0 +1,1322 @@
3856+/*
3857+ * An OCF module that uses the linux kernel cryptoapi, based on the
3858+ * original cryptosoft for BSD by Angelos D. Keromytis (angelos@cis.upenn.edu)
3859+ * but is mostly unrecognisable,
3860+ *
3861+ * Written by David McCullough <david_mccullough@mcafee.com>
3862+ * Copyright (C) 2004-2011 David McCullough
3863+ * Copyright (C) 2004-2005 Intel Corporation.
3864+ *
3865+ * LICENSE TERMS
3866+ *
3867+ * The free distribution and use of this software in both source and binary
3868+ * form is allowed (with or without changes) provided that:
3869+ *
3870+ * 1. distributions of this source code include the above copyright
3871+ * notice, this list of conditions and the following disclaimer;
3872+ *
3873+ * 2. distributions in binary form include the above copyright
3874+ * notice, this list of conditions and the following disclaimer
3875+ * in the documentation and/or other associated materials;
3876+ *
3877+ * 3. the copyright holder's name is not used to endorse products
3878+ * built using this software without specific written permission.
3879+ *
3880+ * ALTERNATIVELY, provided that this notice is retained in full, this product
3881+ * may be distributed under the terms of the GNU General Public License (GPL),
3882+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
3883+ *
3884+ * DISCLAIMER
3885+ *
3886+ * This software is provided 'as is' with no explicit or implied warranties
3887+ * in respect of its properties, including, but not limited to, correctness
3888+ * and/or fitness for purpose.
3889+ * ---------------------------------------------------------------------------
3890+ */
3891+
3892+#include <linux/version.h>
3893+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
3894+#include <linux/config.h>
3895+#endif
3896+#include <linux/module.h>
3897+#include <linux/init.h>
3898+#include <linux/list.h>
3899+#include <linux/slab.h>
3900+#include <linux/sched.h>
3901+#include <linux/wait.h>
3902+#include <linux/crypto.h>
3903+#include <linux/mm.h>
3904+#include <linux/skbuff.h>
3905+#include <linux/random.h>
3906+#include <linux/interrupt.h>
3907+#include <linux/spinlock.h>
3908+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
3909+#include <linux/scatterlist.h>
3910+#endif
3911+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
3912+#include <crypto/hash.h>
3913+#endif
3914+
3915+#include <cryptodev.h>
3916+#include <uio.h>
3917+
3918+struct {
3919+ softc_device_decl sc_dev;
3920+} swcr_softc;
3921+
3922+#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
3923+
3924+#define SW_TYPE_CIPHER 0x01
3925+#define SW_TYPE_HMAC 0x02
3926+#define SW_TYPE_HASH 0x04
3927+#define SW_TYPE_COMP 0x08
3928+#define SW_TYPE_BLKCIPHER 0x10
3929+#define SW_TYPE_ALG_MASK 0x1f
3930+
3931+#define SW_TYPE_ASYNC 0x8000
3932+
3933+#define SW_TYPE_INUSE 0x10000000
3934+
3935+/* We change some of the above if we have an async interface */
3936+
3937+#define SW_TYPE_ALG_AMASK (SW_TYPE_ALG_MASK | SW_TYPE_ASYNC)
3938+
3939+#define SW_TYPE_ABLKCIPHER (SW_TYPE_BLKCIPHER | SW_TYPE_ASYNC)
3940+#define SW_TYPE_AHASH (SW_TYPE_HASH | SW_TYPE_ASYNC)
3941+#define SW_TYPE_AHMAC (SW_TYPE_HMAC | SW_TYPE_ASYNC)
3942+
3943+#define SCATTERLIST_MAX 16
3944+
3945+struct swcr_data {
3946+ struct work_struct workq;
3947+ int sw_type;
3948+ int sw_alg;
3949+ struct crypto_tfm *sw_tfm;
3950+ spinlock_t sw_tfm_lock;
3951+ union {
3952+ struct {
3953+ char *sw_key;
3954+ int sw_klen;
3955+ int sw_mlen;
3956+ } hmac;
3957+ void *sw_comp_buf;
3958+ } u;
3959+ struct swcr_data *sw_next;
3960+};
3961+
3962+struct swcr_req {
3963+ struct swcr_data *sw_head;
3964+ struct swcr_data *sw;
3965+ struct cryptop *crp;
3966+ struct cryptodesc *crd;
3967+ struct scatterlist sg[SCATTERLIST_MAX];
3968+ unsigned char iv[EALG_MAX_BLOCK_LEN];
3969+ char result[HASH_MAX_LEN];
3970+ void *crypto_req;
3971+};
3972+
3973+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
3974+static kmem_cache_t *swcr_req_cache;
3975+#else
3976+static struct kmem_cache *swcr_req_cache;
3977+#endif
3978+
3979+#ifndef CRYPTO_TFM_MODE_CBC
3980+/*
3981+ * As of linux-2.6.21 this is no longer defined, and presumably no longer
3982+ * needed to be passed into the crypto core code.
3983+ */
3984+#define CRYPTO_TFM_MODE_CBC 0
3985+#define CRYPTO_TFM_MODE_ECB 0
3986+#endif
3987+
3988+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
3989+ /*
3990+ * Linux 2.6.19 introduced a new Crypto API, setup macro's to convert new
3991+ * API into old API.
3992+ */
3993+
3994+ /* Symmetric/Block Cipher */
3995+ struct blkcipher_desc
3996+ {
3997+ struct crypto_tfm *tfm;
3998+ void *info;
3999+ };
4000+ #define ecb(X) #X , CRYPTO_TFM_MODE_ECB
4001+ #define cbc(X) #X , CRYPTO_TFM_MODE_CBC
4002+ #define crypto_has_blkcipher(X, Y, Z) crypto_alg_available(X, 0)
4003+ #define crypto_blkcipher_cast(X) X
4004+ #define crypto_blkcipher_tfm(X) X
4005+ #define crypto_alloc_blkcipher(X, Y, Z) crypto_alloc_tfm(X, mode)
4006+ #define crypto_blkcipher_ivsize(X) crypto_tfm_alg_ivsize(X)
4007+ #define crypto_blkcipher_blocksize(X) crypto_tfm_alg_blocksize(X)
4008+ #define crypto_blkcipher_setkey(X, Y, Z) crypto_cipher_setkey(X, Y, Z)
4009+ #define crypto_blkcipher_encrypt_iv(W, X, Y, Z) \
4010+ crypto_cipher_encrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
4011+ #define crypto_blkcipher_decrypt_iv(W, X, Y, Z) \
4012+ crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
4013+ #define crypto_blkcipher_set_flags(x, y) /* nop */
4014+ #define crypto_free_blkcipher(x) crypto_free_tfm(x)
4015+ #define crypto_free_comp crypto_free_tfm
4016+ #define crypto_free_hash crypto_free_tfm
4017+
4018+ /* Hash/HMAC/Digest */
4019+ struct hash_desc
4020+ {
4021+ struct crypto_tfm *tfm;
4022+ };
4023+ #define hmac(X) #X , 0
4024+ #define crypto_has_hash(X, Y, Z) crypto_alg_available(X, 0)
4025+ #define crypto_hash_cast(X) X
4026+ #define crypto_hash_tfm(X) X
4027+ #define crypto_alloc_hash(X, Y, Z) crypto_alloc_tfm(X, mode)
4028+ #define crypto_hash_digestsize(X) crypto_tfm_alg_digestsize(X)
4029+ #define crypto_hash_digest(W, X, Y, Z) \
4030+ crypto_digest_digest((W)->tfm, X, sg_num, Z)
4031+
4032+ /* Asymmetric Cipher */
4033+ #define crypto_has_cipher(X, Y, Z) crypto_alg_available(X, 0)
4034+
4035+ /* Compression */
4036+ #define crypto_has_comp(X, Y, Z) crypto_alg_available(X, 0)
4037+ #define crypto_comp_tfm(X) X
4038+ #define crypto_comp_cast(X) X
4039+ #define crypto_alloc_comp(X, Y, Z) crypto_alloc_tfm(X, mode)
4040+ #define plain(X) #X , 0
4041+#else
4042+ #define ecb(X) "ecb(" #X ")" , 0
4043+ #define cbc(X) "cbc(" #X ")" , 0
4044+ #define hmac(X) "hmac(" #X ")" , 0
4045+ #define plain(X) #X , 0
4046+#endif /* if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
4047+
4048+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
4049+/* no ablkcipher in older kernels */
4050+#define crypto_alloc_ablkcipher(a,b,c) (NULL)
4051+#define crypto_ablkcipher_tfm(x) ((struct crypto_tfm *)(x))
4052+#define crypto_ablkcipher_set_flags(a, b) /* nop */
4053+#define crypto_ablkcipher_setkey(x, y, z) (-EINVAL)
4054+#define crypto_has_ablkcipher(a,b,c) (0)
4055+#else
4056+#define HAVE_ABLKCIPHER
4057+#endif
4058+
4059+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
4060+/* no ahash in older kernels */
4061+#define crypto_ahash_tfm(x) ((struct crypto_tfm *)(x))
4062+#define crypto_alloc_ahash(a,b,c) (NULL)
4063+#define crypto_ahash_digestsize(x) 0
4064+#else
4065+#define HAVE_AHASH
4066+#endif
4067+
4068+struct crypto_details {
4069+ char *alg_name;
4070+ int mode;
4071+ int sw_type;
4072+};
4073+
4074+static struct crypto_details crypto_details[] = {
4075+ [CRYPTO_DES_CBC] = { cbc(des), SW_TYPE_BLKCIPHER, },
4076+ [CRYPTO_3DES_CBC] = { cbc(des3_ede), SW_TYPE_BLKCIPHER, },
4077+ [CRYPTO_BLF_CBC] = { cbc(blowfish), SW_TYPE_BLKCIPHER, },
4078+ [CRYPTO_CAST_CBC] = { cbc(cast5), SW_TYPE_BLKCIPHER, },
4079+ [CRYPTO_SKIPJACK_CBC] = { cbc(skipjack), SW_TYPE_BLKCIPHER, },
4080+ [CRYPTO_MD5_HMAC] = { hmac(md5), SW_TYPE_HMAC, },
4081+ [CRYPTO_SHA1_HMAC] = { hmac(sha1), SW_TYPE_HMAC, },
4082+ [CRYPTO_RIPEMD160_HMAC] = { hmac(ripemd160), SW_TYPE_HMAC, },
4083+ [CRYPTO_MD5_KPDK] = { plain(md5-kpdk), SW_TYPE_HASH, },
4084+ [CRYPTO_SHA1_KPDK] = { plain(sha1-kpdk), SW_TYPE_HASH, },
4085+ [CRYPTO_AES_CBC] = { cbc(aes), SW_TYPE_BLKCIPHER, },
4086+ [CRYPTO_ARC4] = { ecb(arc4), SW_TYPE_BLKCIPHER, },
4087+ [CRYPTO_MD5] = { plain(md5), SW_TYPE_HASH, },
4088+ [CRYPTO_SHA1] = { plain(sha1), SW_TYPE_HASH, },
4089+ [CRYPTO_NULL_HMAC] = { hmac(digest_null), SW_TYPE_HMAC, },
4090+ [CRYPTO_NULL_CBC] = { cbc(cipher_null), SW_TYPE_BLKCIPHER, },
4091+ [CRYPTO_DEFLATE_COMP] = { plain(deflate), SW_TYPE_COMP, },
4092+ [CRYPTO_SHA2_256_HMAC] = { hmac(sha256), SW_TYPE_HMAC, },
4093+ [CRYPTO_SHA2_384_HMAC] = { hmac(sha384), SW_TYPE_HMAC, },
4094+ [CRYPTO_SHA2_512_HMAC] = { hmac(sha512), SW_TYPE_HMAC, },
4095+ [CRYPTO_CAMELLIA_CBC] = { cbc(camellia), SW_TYPE_BLKCIPHER, },
4096+ [CRYPTO_SHA2_256] = { plain(sha256), SW_TYPE_HASH, },
4097+ [CRYPTO_SHA2_384] = { plain(sha384), SW_TYPE_HASH, },
4098+ [CRYPTO_SHA2_512] = { plain(sha512), SW_TYPE_HASH, },
4099+ [CRYPTO_RIPEMD160] = { plain(ripemd160), SW_TYPE_HASH, },
4100+};
4101+
4102+int32_t swcr_id = -1;
4103+module_param(swcr_id, int, 0444);
4104+MODULE_PARM_DESC(swcr_id, "Read-Only OCF ID for cryptosoft driver");
4105+
4106+int swcr_fail_if_compression_grows = 1;
4107+module_param(swcr_fail_if_compression_grows, int, 0644);
4108+MODULE_PARM_DESC(swcr_fail_if_compression_grows,
4109+ "Treat compression that results in more data as a failure");
4110+
4111+int swcr_no_ahash = 0;
4112+module_param(swcr_no_ahash, int, 0644);
4113+MODULE_PARM_DESC(swcr_no_ahash,
4114+ "Do not use async hash/hmac even if available");
4115+
4116+int swcr_no_ablk = 0;
4117+module_param(swcr_no_ablk, int, 0644);
4118+MODULE_PARM_DESC(swcr_no_ablk,
4119+ "Do not use async blk ciphers even if available");
4120+
4121+static struct swcr_data **swcr_sessions = NULL;
4122+static u_int32_t swcr_sesnum = 0;
4123+
4124+static int swcr_process(device_t, struct cryptop *, int);
4125+static int swcr_newsession(device_t, u_int32_t *, struct cryptoini *);
4126+static int swcr_freesession(device_t, u_int64_t);
4127+
4128+static device_method_t swcr_methods = {
4129+ /* crypto device methods */
4130+ DEVMETHOD(cryptodev_newsession, swcr_newsession),
4131+ DEVMETHOD(cryptodev_freesession,swcr_freesession),
4132+ DEVMETHOD(cryptodev_process, swcr_process),
4133+};
4134+
4135+#define debug swcr_debug
4136+int swcr_debug = 0;
4137+module_param(swcr_debug, int, 0644);
4138+MODULE_PARM_DESC(swcr_debug, "Enable debug");
4139+
4140+static void swcr_process_req(struct swcr_req *req);
4141+
4142+/*
4143+ * somethings just need to be run with user context no matter whether
4144+ * the kernel compression libs use vmalloc/vfree for example.
4145+ */
4146+
4147+typedef struct {
4148+ struct work_struct wq;
4149+ void (*func)(void *arg);
4150+ void *arg;
4151+} execute_later_t;
4152+
4153+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
4154+static void
4155+doing_it_now(struct work_struct *wq)
4156+{
4157+ execute_later_t *w = container_of(wq, execute_later_t, wq);
4158+ (w->func)(w->arg);
4159+ kfree(w);
4160+}
4161+#else
4162+static void
4163+doing_it_now(void *arg)
4164+{
4165+ execute_later_t *w = (execute_later_t *) arg;
4166+ (w->func)(w->arg);
4167+ kfree(w);
4168+}
4169+#endif
4170+
4171+static void
4172+execute_later(void (fn)(void *), void *arg)
4173+{
4174+ execute_later_t *w;
4175+
4176+ w = (execute_later_t *) kmalloc(sizeof(execute_later_t), SLAB_ATOMIC);
4177+ if (w) {
4178+ memset(w, '\0', sizeof(w));
4179+ w->func = fn;
4180+ w->arg = arg;
4181+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
4182+ INIT_WORK(&w->wq, doing_it_now);
4183+#else
4184+ INIT_WORK(&w->wq, doing_it_now, w);
4185+#endif
4186+ schedule_work(&w->wq);
4187+ }
4188+}
4189+
4190+/*
4191+ * Generate a new software session.
4192+ */
4193+static int
4194+swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
4195+{
4196+ struct swcr_data **swd;
4197+ u_int32_t i;
4198+ int error;
4199+ char *algo;
4200+ int mode;
4201+
4202+ dprintk("%s()\n", __FUNCTION__);
4203+ if (sid == NULL || cri == NULL) {
4204+ dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
4205+ return EINVAL;
4206+ }
4207+
4208+ if (swcr_sessions) {
4209+ for (i = 1; i < swcr_sesnum; i++)
4210+ if (swcr_sessions[i] == NULL)
4211+ break;
4212+ } else
4213+ i = 1; /* NB: to silence compiler warning */
4214+
4215+ if (swcr_sessions == NULL || i == swcr_sesnum) {
4216+ if (swcr_sessions == NULL) {
4217+ i = 1; /* We leave swcr_sessions[0] empty */
4218+ swcr_sesnum = CRYPTO_SW_SESSIONS;
4219+ } else
4220+ swcr_sesnum *= 2;
4221+
4222+ swd = kmalloc(swcr_sesnum * sizeof(struct swcr_data *), SLAB_ATOMIC);
4223+ if (swd == NULL) {
4224+ /* Reset session number */
4225+ if (swcr_sesnum == CRYPTO_SW_SESSIONS)
4226+ swcr_sesnum = 0;
4227+ else
4228+ swcr_sesnum /= 2;
4229+ dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
4230+ return ENOBUFS;
4231+ }
4232+ memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *));
4233+
4234+ /* Copy existing sessions */
4235+ if (swcr_sessions) {
4236+ memcpy(swd, swcr_sessions,
4237+ (swcr_sesnum / 2) * sizeof(struct swcr_data *));
4238+ kfree(swcr_sessions);
4239+ }
4240+
4241+ swcr_sessions = swd;
4242+ }
4243+
4244+ swd = &swcr_sessions[i];
4245+ *sid = i;
4246+
4247+ while (cri) {
4248+ *swd = (struct swcr_data *) kmalloc(sizeof(struct swcr_data),
4249+ SLAB_ATOMIC);
4250+ if (*swd == NULL) {
4251+ swcr_freesession(NULL, i);
4252+ dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
4253+ return ENOBUFS;
4254+ }
4255+ memset(*swd, 0, sizeof(struct swcr_data));
4256+
4257+ if (cri->cri_alg < 0 ||
4258+ cri->cri_alg>=sizeof(crypto_details)/sizeof(crypto_details[0])){
4259+ printk("cryptosoft: Unknown algorithm 0x%x\n", cri->cri_alg);
4260+ swcr_freesession(NULL, i);
4261+ return EINVAL;
4262+ }
4263+
4264+ algo = crypto_details[cri->cri_alg].alg_name;
4265+ if (!algo || !*algo) {
4266+ printk("cryptosoft: Unsupported algorithm 0x%x\n", cri->cri_alg);
4267+ swcr_freesession(NULL, i);
4268+ return EINVAL;
4269+ }
4270+
4271+ mode = crypto_details[cri->cri_alg].mode;
4272+ (*swd)->sw_type = crypto_details[cri->cri_alg].sw_type;
4273+ (*swd)->sw_alg = cri->cri_alg;
4274+
4275+ spin_lock_init(&(*swd)->sw_tfm_lock);
4276+
4277+ /* Algorithm specific configuration */
4278+ switch (cri->cri_alg) {
4279+ case CRYPTO_NULL_CBC:
4280+ cri->cri_klen = 0; /* make it work with crypto API */
4281+ break;
4282+ default:
4283+ break;
4284+ }
4285+
4286+ if ((*swd)->sw_type & SW_TYPE_BLKCIPHER) {
4287+ dprintk("%s crypto_alloc_*blkcipher(%s, 0x%x)\n", __FUNCTION__,
4288+ algo, mode);
4289+
4290+ /* try async first */
4291+ (*swd)->sw_tfm = swcr_no_ablk ? NULL :
4292+ crypto_ablkcipher_tfm(crypto_alloc_ablkcipher(algo, 0, 0));
4293+ if ((*swd)->sw_tfm && !IS_ERR((*swd)->sw_tfm)) {
4294+ dprintk("%s %s cipher is async\n", __FUNCTION__, algo);
4295+ (*swd)->sw_type |= SW_TYPE_ASYNC;
4296+ } else {
4297+ (*swd)->sw_tfm = crypto_blkcipher_tfm(
4298+ crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC));
4299+ if ((*swd)->sw_tfm && !IS_ERR((*swd)->sw_tfm))
4300+ dprintk("%s %s cipher is sync\n", __FUNCTION__, algo);
4301+ }
4302+ if (!(*swd)->sw_tfm || IS_ERR((*swd)->sw_tfm)) {
4303+ int err;
4304+ dprintk("cryptosoft: crypto_alloc_blkcipher failed(%s, 0x%x)\n",
4305+ algo,mode);
4306+ err = IS_ERR((*swd)->sw_tfm) ? -(PTR_ERR((*swd)->sw_tfm)) : EINVAL;
4307+ (*swd)->sw_tfm = NULL; /* ensure NULL */
4308+ swcr_freesession(NULL, i);
4309+ return err;
4310+ }
4311+
4312+ if (debug) {
4313+ dprintk("%s key:cri->cri_klen=%d,(cri->cri_klen + 7)/8=%d",
4314+ __FUNCTION__, cri->cri_klen, (cri->cri_klen + 7) / 8);
4315+ for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
4316+ dprintk("%s0x%x", (i % 8) ? " " : "\n ",
4317+ cri->cri_key[i] & 0xff);
4318+ dprintk("\n");
4319+ }
4320+ if ((*swd)->sw_type & SW_TYPE_ASYNC) {
4321+ /* OCF doesn't enforce keys */
4322+ crypto_ablkcipher_set_flags(
4323+ __crypto_ablkcipher_cast((*swd)->sw_tfm),
4324+ CRYPTO_TFM_REQ_WEAK_KEY);
4325+ error = crypto_ablkcipher_setkey(
4326+ __crypto_ablkcipher_cast((*swd)->sw_tfm),
4327+ cri->cri_key, (cri->cri_klen + 7) / 8);
4328+ } else {
4329+ /* OCF doesn't enforce keys */
4330+ crypto_blkcipher_set_flags(
4331+ crypto_blkcipher_cast((*swd)->sw_tfm),
4332+ CRYPTO_TFM_REQ_WEAK_KEY);
4333+ error = crypto_blkcipher_setkey(
4334+ crypto_blkcipher_cast((*swd)->sw_tfm),
4335+ cri->cri_key, (cri->cri_klen + 7) / 8);
4336+ }
4337+ if (error) {
4338+ printk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n", error,
4339+ (*swd)->sw_tfm->crt_flags);
4340+ swcr_freesession(NULL, i);
4341+ return error;
4342+ }
4343+ } else if ((*swd)->sw_type & (SW_TYPE_HMAC | SW_TYPE_HASH)) {
4344+ dprintk("%s crypto_alloc_*hash(%s, 0x%x)\n", __FUNCTION__,
4345+ algo, mode);
4346+
4347+ /* try async first */
4348+ (*swd)->sw_tfm = swcr_no_ahash ? NULL :
4349+ crypto_ahash_tfm(crypto_alloc_ahash(algo, 0, 0));
4350+ if ((*swd)->sw_tfm) {
4351+ dprintk("%s %s hash is async\n", __FUNCTION__, algo);
4352+ (*swd)->sw_type |= SW_TYPE_ASYNC;
4353+ } else {
4354+ dprintk("%s %s hash is sync\n", __FUNCTION__, algo);
4355+ (*swd)->sw_tfm = crypto_hash_tfm(
4356+ crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC));
4357+ }
4358+
4359+ if (!(*swd)->sw_tfm) {
4360+ dprintk("cryptosoft: crypto_alloc_hash failed(%s,0x%x)\n",
4361+ algo, mode);
4362+ swcr_freesession(NULL, i);
4363+ return EINVAL;
4364+ }
4365+
4366+ (*swd)->u.hmac.sw_klen = (cri->cri_klen + 7) / 8;
4367+ (*swd)->u.hmac.sw_key = (char *)kmalloc((*swd)->u.hmac.sw_klen,
4368+ SLAB_ATOMIC);
4369+ if ((*swd)->u.hmac.sw_key == NULL) {
4370+ swcr_freesession(NULL, i);
4371+ dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
4372+ return ENOBUFS;
4373+ }
4374+ memcpy((*swd)->u.hmac.sw_key, cri->cri_key, (*swd)->u.hmac.sw_klen);
4375+ if (cri->cri_mlen) {
4376+ (*swd)->u.hmac.sw_mlen = cri->cri_mlen;
4377+ } else if ((*swd)->sw_type & SW_TYPE_ASYNC) {
4378+ (*swd)->u.hmac.sw_mlen = crypto_ahash_digestsize(
4379+ __crypto_ahash_cast((*swd)->sw_tfm));
4380+ } else {
4381+ (*swd)->u.hmac.sw_mlen = crypto_hash_digestsize(
4382+ crypto_hash_cast((*swd)->sw_tfm));
4383+ }
4384+ } else if ((*swd)->sw_type & SW_TYPE_COMP) {
4385+ (*swd)->sw_tfm = crypto_comp_tfm(
4386+ crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC));
4387+ if (!(*swd)->sw_tfm) {
4388+ dprintk("cryptosoft: crypto_alloc_comp failed(%s,0x%x)\n",
4389+ algo, mode);
4390+ swcr_freesession(NULL, i);
4391+ return EINVAL;
4392+ }
4393+ (*swd)->u.sw_comp_buf = kmalloc(CRYPTO_MAX_DATA_LEN, SLAB_ATOMIC);
4394+ if ((*swd)->u.sw_comp_buf == NULL) {
4395+ swcr_freesession(NULL, i);
4396+ dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
4397+ return ENOBUFS;
4398+ }
4399+ } else {
4400+ printk("cryptosoft: Unhandled sw_type %d\n", (*swd)->sw_type);
4401+ swcr_freesession(NULL, i);
4402+ return EINVAL;
4403+ }
4404+
4405+ cri = cri->cri_next;
4406+ swd = &((*swd)->sw_next);
4407+ }
4408+ return 0;
4409+}
4410+
4411+/*
4412+ * Free a session.
4413+ */
4414+static int
4415+swcr_freesession(device_t dev, u_int64_t tid)
4416+{
4417+ struct swcr_data *swd;
4418+ u_int32_t sid = CRYPTO_SESID2LID(tid);
4419+
4420+ dprintk("%s()\n", __FUNCTION__);
4421+ if (sid > swcr_sesnum || swcr_sessions == NULL ||
4422+ swcr_sessions[sid] == NULL) {
4423+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
4424+ return(EINVAL);
4425+ }
4426+
4427+ /* Silently accept and return */
4428+ if (sid == 0)
4429+ return(0);
4430+
4431+ while ((swd = swcr_sessions[sid]) != NULL) {
4432+ swcr_sessions[sid] = swd->sw_next;
4433+ if (swd->sw_tfm) {
4434+ switch (swd->sw_type & SW_TYPE_ALG_AMASK) {
4435+#ifdef HAVE_AHASH
4436+ case SW_TYPE_AHMAC:
4437+ case SW_TYPE_AHASH:
4438+ crypto_free_ahash(__crypto_ahash_cast(swd->sw_tfm));
4439+ break;
4440+#endif
4441+#ifdef HAVE_ABLKCIPHER
4442+ case SW_TYPE_ABLKCIPHER:
4443+ crypto_free_ablkcipher(__crypto_ablkcipher_cast(swd->sw_tfm));
4444+ break;
4445+#endif
4446+ case SW_TYPE_BLKCIPHER:
4447+ crypto_free_blkcipher(crypto_blkcipher_cast(swd->sw_tfm));
4448+ break;
4449+ case SW_TYPE_HMAC:
4450+ case SW_TYPE_HASH:
4451+ crypto_free_hash(crypto_hash_cast(swd->sw_tfm));
4452+ break;
4453+ case SW_TYPE_COMP:
4454+ if (in_interrupt())
4455+ execute_later((void (*)(void *))crypto_free_comp, (void *)crypto_comp_cast(swd->sw_tfm));
4456+ else
4457+ crypto_free_comp(crypto_comp_cast(swd->sw_tfm));
4458+ break;
4459+ default:
4460+ crypto_free_tfm(swd->sw_tfm);
4461+ break;
4462+ }
4463+ swd->sw_tfm = NULL;
4464+ }
4465+ if (swd->sw_type & SW_TYPE_COMP) {
4466+ if (swd->u.sw_comp_buf)
4467+ kfree(swd->u.sw_comp_buf);
4468+ } else {
4469+ if (swd->u.hmac.sw_key)
4470+ kfree(swd->u.hmac.sw_key);
4471+ }
4472+ kfree(swd);
4473+ }
4474+ return 0;
4475+}
4476+
4477+static void swcr_process_req_complete(struct swcr_req *req)
4478+{
4479+ dprintk("%s()\n", __FUNCTION__);
4480+
4481+ if (req->sw->sw_type & SW_TYPE_INUSE) {
4482+ unsigned long flags;
4483+ spin_lock_irqsave(&req->sw->sw_tfm_lock, flags);
4484+ req->sw->sw_type &= ~SW_TYPE_INUSE;
4485+ spin_unlock_irqrestore(&req->sw->sw_tfm_lock, flags);
4486+ }
4487+
4488+ if (req->crp->crp_etype)
4489+ goto done;
4490+
4491+ switch (req->sw->sw_type & SW_TYPE_ALG_AMASK) {
4492+#if defined(HAVE_AHASH)
4493+ case SW_TYPE_AHMAC:
4494+ case SW_TYPE_AHASH:
4495+ crypto_copyback(req->crp->crp_flags, req->crp->crp_buf,
4496+ req->crd->crd_inject, req->sw->u.hmac.sw_mlen, req->result);
4497+ ahash_request_free(req->crypto_req);
4498+ break;
4499+#endif
4500+#if defined(HAVE_ABLKCIPHER)
4501+ case SW_TYPE_ABLKCIPHER:
4502+ ablkcipher_request_free(req->crypto_req);
4503+ break;
4504+#endif
4505+ case SW_TYPE_CIPHER:
4506+ case SW_TYPE_HMAC:
4507+ case SW_TYPE_HASH:
4508+ case SW_TYPE_COMP:
4509+ case SW_TYPE_BLKCIPHER:
4510+ break;
4511+ default:
4512+ req->crp->crp_etype = EINVAL;
4513+ goto done;
4514+ }
4515+
4516+ req->crd = req->crd->crd_next;
4517+ if (req->crd) {
4518+ swcr_process_req(req);
4519+ return;
4520+ }
4521+
4522+done:
4523+ dprintk("%s crypto_done %p\n", __FUNCTION__, req);
4524+ crypto_done(req->crp);
4525+ kmem_cache_free(swcr_req_cache, req);
4526+}
4527+
4528+#if defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH)
4529+static void swcr_process_callback(struct crypto_async_request *creq, int err)
4530+{
4531+ struct swcr_req *req = creq->data;
4532+
4533+ dprintk("%s()\n", __FUNCTION__);
4534+ if (err) {
4535+ if (err == -EINPROGRESS)
4536+ return;
4537+ dprintk("%s() fail %d\n", __FUNCTION__, -err);
4538+ req->crp->crp_etype = -err;
4539+ }
4540+
4541+ swcr_process_req_complete(req);
4542+}
4543+#endif /* defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH) */
4544+
4545+
4546+static void swcr_process_req(struct swcr_req *req)
4547+{
4548+ struct swcr_data *sw;
4549+ struct cryptop *crp = req->crp;
4550+ struct cryptodesc *crd = req->crd;
4551+ struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
4552+ struct uio *uiop = (struct uio *) crp->crp_buf;
4553+ int sg_num, sg_len, skip;
4554+
4555+ dprintk("%s()\n", __FUNCTION__);
4556+
4557+ /*
4558+ * Find the crypto context.
4559+ *
4560+ * XXX Note that the logic here prevents us from having
4561+ * XXX the same algorithm multiple times in a session
4562+ * XXX (or rather, we can but it won't give us the right
4563+ * XXX results). To do that, we'd need some way of differentiating
4564+ * XXX between the various instances of an algorithm (so we can
4565+ * XXX locate the correct crypto context).
4566+ */
4567+ for (sw = req->sw_head; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next)
4568+ ;
4569+
4570+ /* No such context ? */
4571+ if (sw == NULL) {
4572+ crp->crp_etype = EINVAL;
4573+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
4574+ goto done;
4575+ }
4576+
4577+ /*
4578+ * for some types we need to ensure only one user as info is stored in
4579+ * the tfm during an operation that can get corrupted
4580+ */
4581+ switch (sw->sw_type & SW_TYPE_ALG_AMASK) {
4582+#ifdef HAVE_AHASH
4583+ case SW_TYPE_AHMAC:
4584+ case SW_TYPE_AHASH:
4585+#endif
4586+ case SW_TYPE_HMAC:
4587+ case SW_TYPE_HASH: {
4588+ unsigned long flags;
4589+ spin_lock_irqsave(&sw->sw_tfm_lock, flags);
4590+ if (sw->sw_type & SW_TYPE_INUSE) {
4591+ spin_unlock_irqrestore(&sw->sw_tfm_lock, flags);
4592+ execute_later((void (*)(void *))swcr_process_req, (void *)req);
4593+ return;
4594+ }
4595+ sw->sw_type |= SW_TYPE_INUSE;
4596+ spin_unlock_irqrestore(&sw->sw_tfm_lock, flags);
4597+ } break;
4598+ }
4599+
4600+ req->sw = sw;
4601+ skip = crd->crd_skip;
4602+
4603+ /*
4604+ * setup the SG list skip from the start of the buffer
4605+ */
4606+ memset(req->sg, 0, sizeof(req->sg));
4607+ sg_init_table(req->sg, SCATTERLIST_MAX);
4608+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
4609+ int i, len;
4610+
4611+ sg_num = 0;
4612+ sg_len = 0;
4613+
4614+ if (skip < skb_headlen(skb)) {
4615+ len = skb_headlen(skb) - skip;
4616+ if (len + sg_len > crd->crd_len)
4617+ len = crd->crd_len - sg_len;
4618+ sg_set_page(&req->sg[sg_num],
4619+ virt_to_page(skb->data + skip), len,
4620+ offset_in_page(skb->data + skip));
4621+ sg_len += len;
4622+ sg_num++;
4623+ skip = 0;
4624+ } else
4625+ skip -= skb_headlen(skb);
4626+
4627+ for (i = 0; sg_len < crd->crd_len &&
4628+ i < skb_shinfo(skb)->nr_frags &&
4629+ sg_num < SCATTERLIST_MAX; i++) {
4630+ if (skip < skb_shinfo(skb)->frags[i].size) {
4631+ len = skb_shinfo(skb)->frags[i].size - skip;
4632+ if (len + sg_len > crd->crd_len)
4633+ len = crd->crd_len - sg_len;
4634+ sg_set_page(&req->sg[sg_num],
4635+ skb_frag_page(&skb_shinfo(skb)->frags[i]),
4636+ len,
4637+ skb_shinfo(skb)->frags[i].page_offset + skip);
4638+ sg_len += len;
4639+ sg_num++;
4640+ skip = 0;
4641+ } else
4642+ skip -= skb_shinfo(skb)->frags[i].size;
4643+ }
4644+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
4645+ int len;
4646+
4647+ sg_len = 0;
4648+ for (sg_num = 0; sg_len < crd->crd_len &&
4649+ sg_num < uiop->uio_iovcnt &&
4650+ sg_num < SCATTERLIST_MAX; sg_num++) {
4651+ if (skip <= uiop->uio_iov[sg_num].iov_len) {
4652+ len = uiop->uio_iov[sg_num].iov_len - skip;
4653+ if (len + sg_len > crd->crd_len)
4654+ len = crd->crd_len - sg_len;
4655+ sg_set_page(&req->sg[sg_num],
4656+ virt_to_page(uiop->uio_iov[sg_num].iov_base+skip),
4657+ len,
4658+ offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
4659+ sg_len += len;
4660+ skip = 0;
4661+ } else
4662+ skip -= uiop->uio_iov[sg_num].iov_len;
4663+ }
4664+ } else {
4665+ sg_len = (crp->crp_ilen - skip);
4666+ if (sg_len > crd->crd_len)
4667+ sg_len = crd->crd_len;
4668+ sg_set_page(&req->sg[0], virt_to_page(crp->crp_buf + skip),
4669+ sg_len, offset_in_page(crp->crp_buf + skip));
4670+ sg_num = 1;
4671+ }
4672+ if (sg_num > 0)
4673+ sg_mark_end(&req->sg[sg_num-1]);
4674+
4675+ switch (sw->sw_type & SW_TYPE_ALG_AMASK) {
4676+
4677+#ifdef HAVE_AHASH
4678+ case SW_TYPE_AHMAC:
4679+ case SW_TYPE_AHASH:
4680+ {
4681+ int ret;
4682+
4683+ /* check we have room for the result */
4684+ if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
4685+ dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
4686+ "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
4687+ crd->crd_inject, sw->u.hmac.sw_mlen);
4688+ crp->crp_etype = EINVAL;
4689+ goto done;
4690+ }
4691+
4692+ req->crypto_req =
4693+ ahash_request_alloc(__crypto_ahash_cast(sw->sw_tfm),GFP_ATOMIC);
4694+ if (!req->crypto_req) {
4695+ crp->crp_etype = ENOMEM;
4696+ dprintk("%s,%d: ENOMEM ahash_request_alloc", __FILE__, __LINE__);
4697+ goto done;
4698+ }
4699+
4700+ ahash_request_set_callback(req->crypto_req,
4701+ CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
4702+
4703+ memset(req->result, 0, sizeof(req->result));
4704+
4705+ if (sw->sw_type & SW_TYPE_AHMAC)
4706+ crypto_ahash_setkey(__crypto_ahash_cast(sw->sw_tfm),
4707+ sw->u.hmac.sw_key, sw->u.hmac.sw_klen);
4708+ ahash_request_set_crypt(req->crypto_req, req->sg, req->result, sg_len);
4709+ ret = crypto_ahash_digest(req->crypto_req);
4710+ switch (ret) {
4711+ case -EINPROGRESS:
4712+ case -EBUSY:
4713+ return;
4714+ default:
4715+ case 0:
4716+ dprintk("hash OP %s %d\n", ret ? "failed" : "success", ret);
4717+ crp->crp_etype = ret;
4718+ goto done;
4719+ }
4720+ } break;
4721+#endif /* HAVE_AHASH */
4722+
4723+#ifdef HAVE_ABLKCIPHER
4724+ case SW_TYPE_ABLKCIPHER: {
4725+ int ret;
4726+ unsigned char *ivp = req->iv;
4727+ int ivsize =
4728+ crypto_ablkcipher_ivsize(__crypto_ablkcipher_cast(sw->sw_tfm));
4729+
4730+ if (sg_len < crypto_ablkcipher_blocksize(
4731+ __crypto_ablkcipher_cast(sw->sw_tfm))) {
4732+ crp->crp_etype = EINVAL;
4733+ dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
4734+ sg_len, crypto_ablkcipher_blocksize(
4735+ __crypto_ablkcipher_cast(sw->sw_tfm)));
4736+ goto done;
4737+ }
4738+
4739+ if (ivsize > sizeof(req->iv)) {
4740+ crp->crp_etype = EINVAL;
4741+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
4742+ goto done;
4743+ }
4744+
4745+ req->crypto_req = ablkcipher_request_alloc(
4746+ __crypto_ablkcipher_cast(sw->sw_tfm), GFP_ATOMIC);
4747+ if (!req->crypto_req) {
4748+ crp->crp_etype = ENOMEM;
4749+ dprintk("%s,%d: ENOMEM ablkcipher_request_alloc",
4750+ __FILE__, __LINE__);
4751+ goto done;
4752+ }
4753+
4754+ ablkcipher_request_set_callback(req->crypto_req,
4755+ CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
4756+
4757+ if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
4758+ int i, error;
4759+
4760+ if (debug) {
4761+ dprintk("%s key:", __FUNCTION__);
4762+ for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
4763+ dprintk("%s0x%x", (i % 8) ? " " : "\n ",
4764+ crd->crd_key[i] & 0xff);
4765+ dprintk("\n");
4766+ }
4767+ /* OCF doesn't enforce keys */
4768+ crypto_ablkcipher_set_flags(__crypto_ablkcipher_cast(sw->sw_tfm),
4769+ CRYPTO_TFM_REQ_WEAK_KEY);
4770+ error = crypto_ablkcipher_setkey(
4771+ __crypto_ablkcipher_cast(sw->sw_tfm), crd->crd_key,
4772+ (crd->crd_klen + 7) / 8);
4773+ if (error) {
4774+ dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
4775+ error, sw->sw_tfm->crt_flags);
4776+ crp->crp_etype = -error;
4777+ }
4778+ }
4779+
4780+ if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
4781+
4782+ if (crd->crd_flags & CRD_F_IV_EXPLICIT)
4783+ ivp = crd->crd_iv;
4784+ else
4785+ get_random_bytes(ivp, ivsize);
4786+ /*
4787+ * do we have to copy the IV back to the buffer ?
4788+ */
4789+ if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
4790+ crypto_copyback(crp->crp_flags, crp->crp_buf,
4791+ crd->crd_inject, ivsize, (caddr_t)ivp);
4792+ }
4793+ ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
4794+ sg_len, ivp);
4795+ ret = crypto_ablkcipher_encrypt(req->crypto_req);
4796+
4797+ } else { /*decrypt */
4798+
4799+ if (crd->crd_flags & CRD_F_IV_EXPLICIT)
4800+ ivp = crd->crd_iv;
4801+ else
4802+ crypto_copydata(crp->crp_flags, crp->crp_buf,
4803+ crd->crd_inject, ivsize, (caddr_t)ivp);
4804+ ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
4805+ sg_len, ivp);
4806+ ret = crypto_ablkcipher_decrypt(req->crypto_req);
4807+ }
4808+
4809+ switch (ret) {
4810+ case -EINPROGRESS:
4811+ case -EBUSY:
4812+ return;
4813+ default:
4814+ case 0:
4815+ dprintk("crypto OP %s %d\n", ret ? "failed" : "success", ret);
4816+ crp->crp_etype = ret;
4817+ goto done;
4818+ }
4819+ } break;
4820+#endif /* HAVE_ABLKCIPHER */
4821+
4822+ case SW_TYPE_BLKCIPHER: {
4823+ unsigned char iv[EALG_MAX_BLOCK_LEN];
4824+ unsigned char *ivp = iv;
4825+ struct blkcipher_desc desc;
4826+ int ivsize = crypto_blkcipher_ivsize(crypto_blkcipher_cast(sw->sw_tfm));
4827+
4828+ if (sg_len < crypto_blkcipher_blocksize(
4829+ crypto_blkcipher_cast(sw->sw_tfm))) {
4830+ crp->crp_etype = EINVAL;
4831+ dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
4832+ sg_len, crypto_blkcipher_blocksize(
4833+ crypto_blkcipher_cast(sw->sw_tfm)));
4834+ goto done;
4835+ }
4836+
4837+ if (ivsize > sizeof(iv)) {
4838+ crp->crp_etype = EINVAL;
4839+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
4840+ goto done;
4841+ }
4842+
4843+ if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
4844+ int i, error;
4845+
4846+ if (debug) {
4847+ dprintk("%s key:", __FUNCTION__);
4848+ for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
4849+ dprintk("%s0x%x", (i % 8) ? " " : "\n ",
4850+ crd->crd_key[i] & 0xff);
4851+ dprintk("\n");
4852+ }
4853+ /* OCF doesn't enforce keys */
4854+ crypto_blkcipher_set_flags(crypto_blkcipher_cast(sw->sw_tfm),
4855+ CRYPTO_TFM_REQ_WEAK_KEY);
4856+ error = crypto_blkcipher_setkey(
4857+ crypto_blkcipher_cast(sw->sw_tfm), crd->crd_key,
4858+ (crd->crd_klen + 7) / 8);
4859+ if (error) {
4860+ dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
4861+ error, sw->sw_tfm->crt_flags);
4862+ crp->crp_etype = -error;
4863+ }
4864+ }
4865+
4866+ memset(&desc, 0, sizeof(desc));
4867+ desc.tfm = crypto_blkcipher_cast(sw->sw_tfm);
4868+
4869+ if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
4870+
4871+ if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
4872+ ivp = crd->crd_iv;
4873+ } else {
4874+ get_random_bytes(ivp, ivsize);
4875+ }
4876+ /*
4877+ * do we have to copy the IV back to the buffer ?
4878+ */
4879+ if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
4880+ crypto_copyback(crp->crp_flags, crp->crp_buf,
4881+ crd->crd_inject, ivsize, (caddr_t)ivp);
4882+ }
4883+ desc.info = ivp;
4884+ crypto_blkcipher_encrypt_iv(&desc, req->sg, req->sg, sg_len);
4885+
4886+ } else { /*decrypt */
4887+
4888+ if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
4889+ ivp = crd->crd_iv;
4890+ } else {
4891+ crypto_copydata(crp->crp_flags, crp->crp_buf,
4892+ crd->crd_inject, ivsize, (caddr_t)ivp);
4893+ }
4894+ desc.info = ivp;
4895+ crypto_blkcipher_decrypt_iv(&desc, req->sg, req->sg, sg_len);
4896+ }
4897+ } break;
4898+
4899+ case SW_TYPE_HMAC:
4900+ case SW_TYPE_HASH:
4901+ {
4902+ char result[HASH_MAX_LEN];
4903+ struct hash_desc desc;
4904+
4905+ /* check we have room for the result */
4906+ if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
4907+ dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
4908+ "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
4909+ crd->crd_inject, sw->u.hmac.sw_mlen);
4910+ crp->crp_etype = EINVAL;
4911+ goto done;
4912+ }
4913+
4914+ memset(&desc, 0, sizeof(desc));
4915+ desc.tfm = crypto_hash_cast(sw->sw_tfm);
4916+
4917+ memset(result, 0, sizeof(result));
4918+
4919+ if (sw->sw_type & SW_TYPE_HMAC) {
4920+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
4921+ crypto_hmac(sw->sw_tfm, sw->u.hmac.sw_key, &sw->u.hmac.sw_klen,
4922+ req->sg, sg_num, result);
4923+#else
4924+ crypto_hash_setkey(desc.tfm, sw->u.hmac.sw_key,
4925+ sw->u.hmac.sw_klen);
4926+ crypto_hash_digest(&desc, req->sg, sg_len, result);
4927+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
4928+
4929+ } else { /* SW_TYPE_HASH */
4930+ crypto_hash_digest(&desc, req->sg, sg_len, result);
4931+ }
4932+
4933+ crypto_copyback(crp->crp_flags, crp->crp_buf,
4934+ crd->crd_inject, sw->u.hmac.sw_mlen, result);
4935+ }
4936+ break;
4937+
4938+ case SW_TYPE_COMP: {
4939+ void *ibuf = NULL;
4940+ void *obuf = sw->u.sw_comp_buf;
4941+ int ilen = sg_len, olen = CRYPTO_MAX_DATA_LEN;
4942+ int ret = 0;
4943+
4944+ /*
4945+ * we need to use an additional copy if there is more than one
4946+ * input chunk since the kernel comp routines do not handle
4947+ * SG yet. Otherwise we just use the input buffer as is.
4948+ * Rather than allocate another buffer we just split the tmp
4949+ * buffer we already have.
4950+ * Perhaps we should just use zlib directly ?
4951+ */
4952+ if (sg_num > 1) {
4953+ int blk;
4954+
4955+ ibuf = obuf;
4956+ for (blk = 0; blk < sg_num; blk++) {
4957+ memcpy(obuf, sg_virt(&req->sg[blk]),
4958+ req->sg[blk].length);
4959+ obuf += req->sg[blk].length;
4960+ }
4961+ olen -= sg_len;
4962+ } else
4963+ ibuf = sg_virt(&req->sg[0]);
4964+
4965+ if (crd->crd_flags & CRD_F_ENCRYPT) { /* compress */
4966+ ret = crypto_comp_compress(crypto_comp_cast(sw->sw_tfm),
4967+ ibuf, ilen, obuf, &olen);
4968+ if (!ret && olen > crd->crd_len) {
4969+ dprintk("cryptosoft: ERANGE compress %d into %d\n",
4970+ crd->crd_len, olen);
4971+ if (swcr_fail_if_compression_grows)
4972+ ret = ERANGE;
4973+ }
4974+ } else { /* decompress */
4975+ ret = crypto_comp_decompress(crypto_comp_cast(sw->sw_tfm),
4976+ ibuf, ilen, obuf, &olen);
4977+ if (!ret && (olen + crd->crd_inject) > crp->crp_olen) {
4978+ dprintk("cryptosoft: ETOOSMALL decompress %d into %d, "
4979+ "space for %d,at offset %d\n",
4980+ crd->crd_len, olen, crp->crp_olen, crd->crd_inject);
4981+ ret = ETOOSMALL;
4982+ }
4983+ }
4984+ if (ret)
4985+ dprintk("%s,%d: ret = %d\n", __FILE__, __LINE__, ret);
4986+
4987+ /*
4988+ * on success copy result back,
4989+ * linux crpyto API returns -errno, we need to fix that
4990+ */
4991+ crp->crp_etype = ret < 0 ? -ret : ret;
4992+ if (ret == 0) {
4993+ /* copy back the result and return it's size */
4994+ crypto_copyback(crp->crp_flags, crp->crp_buf,
4995+ crd->crd_inject, olen, obuf);
4996+ crp->crp_olen = olen;
4997+ }
4998+ } break;
4999+
5000+ default:
5001+ /* Unknown/unsupported algorithm */
5002+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
5003+ crp->crp_etype = EINVAL;
5004+ goto done;
5005+ }
5006+
5007+done:
5008+ swcr_process_req_complete(req);
5009+}
5010+
5011+
5012+/*
5013+ * Process a crypto request.
5014+ */
5015+static int
5016+swcr_process(device_t dev, struct cryptop *crp, int hint)
5017+{
5018+ struct swcr_req *req = NULL;
5019+ u_int32_t lid;
5020+
5021+ dprintk("%s()\n", __FUNCTION__);
5022+ /* Sanity check */
5023+ if (crp == NULL) {
5024+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
5025+ return EINVAL;
5026+ }
5027+
5028+ crp->crp_etype = 0;
5029+
5030+ if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
5031+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
5032+ crp->crp_etype = EINVAL;
5033+ goto done;
5034+ }
5035+
5036+ lid = crp->crp_sid & 0xffffffff;
5037+ if (lid >= swcr_sesnum || lid == 0 || swcr_sessions == NULL ||
5038+ swcr_sessions[lid] == NULL) {
5039+ crp->crp_etype = ENOENT;
5040+ dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
5041+ goto done;
5042+ }
5043+
5044+ /*
5045+ * do some error checking outside of the loop for SKB and IOV processing
5046+ * this leaves us with valid skb or uiop pointers for later
5047+ */
5048+ if (crp->crp_flags & CRYPTO_F_SKBUF) {
5049+ struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
5050+ if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
5051+ printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
5052+ skb_shinfo(skb)->nr_frags);
5053+ goto done;
5054+ }
5055+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
5056+ struct uio *uiop = (struct uio *) crp->crp_buf;
5057+ if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
5058+ printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
5059+ uiop->uio_iovcnt);
5060+ goto done;
5061+ }
5062+ }
5063+
5064+ /*
5065+ * setup a new request ready for queuing
5066+ */
5067+ req = kmem_cache_alloc(swcr_req_cache, SLAB_ATOMIC);
5068+ if (req == NULL) {
5069+ dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
5070+ crp->crp_etype = ENOMEM;
5071+ goto done;
5072+ }
5073+ memset(req, 0, sizeof(*req));
5074+
5075+ req->sw_head = swcr_sessions[lid];
5076+ req->crp = crp;
5077+ req->crd = crp->crp_desc;
5078+
5079+ swcr_process_req(req);
5080+ return 0;
5081+
5082+done:
5083+ crypto_done(crp);
5084+ if (req)
5085+ kmem_cache_free(swcr_req_cache, req);
5086+ return 0;
5087+}
5088+
5089+
5090+static int
5091+cryptosoft_init(void)
5092+{
5093+ int i, sw_type, mode;
5094+ char *algo;
5095+
5096+ dprintk("%s(%p)\n", __FUNCTION__, cryptosoft_init);
5097+
5098+ swcr_req_cache = kmem_cache_create("cryptosoft_req",
5099+ sizeof(struct swcr_req), 0, SLAB_HWCACHE_ALIGN, NULL
5100+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
5101+ , NULL
5102+#endif
5103+ );
5104+ if (!swcr_req_cache) {
5105+ printk("cryptosoft: failed to create request cache\n");
5106+ return -ENOENT;
5107+ }
5108+
5109+ softc_device_init(&swcr_softc, "cryptosoft", 0, swcr_methods);
5110+
5111+ swcr_id = crypto_get_driverid(softc_get_device(&swcr_softc),
5112+ CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
5113+ if (swcr_id < 0) {
5114+ printk("cryptosoft: Software crypto device cannot initialize!");
5115+ return -ENODEV;
5116+ }
5117+
5118+#define REGISTER(alg) \
5119+ crypto_register(swcr_id, alg, 0,0)
5120+
5121+ for (i = 0; i < sizeof(crypto_details)/sizeof(crypto_details[0]); i++) {
5122+ int found;
5123+
5124+ algo = crypto_details[i].alg_name;
5125+ if (!algo || !*algo) {
5126+ dprintk("%s:Algorithm %d not supported\n", __FUNCTION__, i);
5127+ continue;
5128+ }
5129+
5130+ mode = crypto_details[i].mode;
5131+ sw_type = crypto_details[i].sw_type;
5132+
5133+ found = 0;
5134+ switch (sw_type & SW_TYPE_ALG_MASK) {
5135+ case SW_TYPE_CIPHER:
5136+ found = crypto_has_cipher(algo, 0, CRYPTO_ALG_ASYNC);
5137+ break;
5138+ case SW_TYPE_HMAC:
5139+ found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
5140+ break;
5141+ case SW_TYPE_HASH:
5142+ found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
5143+ break;
5144+ case SW_TYPE_COMP:
5145+ found = crypto_has_comp(algo, 0, CRYPTO_ALG_ASYNC);
5146+ break;
5147+ case SW_TYPE_BLKCIPHER:
5148+ found = crypto_has_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);
5149+ if (!found && !swcr_no_ablk)
5150+ found = crypto_has_ablkcipher(algo, 0, 0);
5151+ break;
5152+ }
5153+ if (found) {
5154+ REGISTER(i);
5155+ } else {
5156+ dprintk("%s:Algorithm Type %d not supported (algorithm %d:'%s')\n",
5157+ __FUNCTION__, sw_type, i, algo);
5158+ }
5159+ }
5160+ return 0;
5161+}
5162+
5163+static void
5164+cryptosoft_exit(void)
5165+{
5166+ dprintk("%s()\n", __FUNCTION__);
5167+ crypto_unregister_all(swcr_id);
5168+ swcr_id = -1;
5169+ kmem_cache_destroy(swcr_req_cache);
5170+}
5171+
5172+late_initcall(cryptosoft_init);
5173+module_exit(cryptosoft_exit);
5174+
5175+MODULE_LICENSE("Dual BSD/GPL");
5176+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
5177+MODULE_DESCRIPTION("Cryptosoft (OCF module for kernel crypto)");
5178diff --git a/crypto/ocf/ocf-bench.c b/crypto/ocf/ocf-bench.c
5179new file mode 100644
5180index 0000000..f3fe9d0
5181--- /dev/null
5182+++ b/crypto/ocf/ocf-bench.c
5183@@ -0,0 +1,514 @@
5184+/*
5185+ * A loadable module that benchmarks the OCF crypto speed from kernel space.
5186+ *
5187+ * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
5188+ *
5189+ * LICENSE TERMS
5190+ *
5191+ * The free distribution and use of this software in both source and binary
5192+ * form is allowed (with or without changes) provided that:
5193+ *
5194+ * 1. distributions of this source code include the above copyright
5195+ * notice, this list of conditions and the following disclaimer;
5196+ *
5197+ * 2. distributions in binary form include the above copyright
5198+ * notice, this list of conditions and the following disclaimer
5199+ * in the documentation and/or other associated materials;
5200+ *
5201+ * 3. the copyright holder's name is not used to endorse products
5202+ * built using this software without specific written permission.
5203+ *
5204+ * ALTERNATIVELY, provided that this notice is retained in full, this product
5205+ * may be distributed under the terms of the GNU General Public License (GPL),
5206+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
5207+ *
5208+ * DISCLAIMER
5209+ *
5210+ * This software is provided 'as is' with no explicit or implied warranties
5211+ * in respect of its properties, including, but not limited to, correctness
5212+ * and/or fitness for purpose.
5213+ */
5214+
5215+
5216+#include <linux/version.h>
5217+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
5218+#include <linux/config.h>
5219+#endif
5220+#include <linux/module.h>
5221+#include <linux/init.h>
5222+#include <linux/list.h>
5223+#include <linux/slab.h>
5224+#include <linux/wait.h>
5225+#include <linux/sched.h>
5226+#include <linux/spinlock.h>
5227+#include <linux/interrupt.h>
5228+#include <cryptodev.h>
5229+
5230+#ifdef I_HAVE_AN_XSCALE_WITH_INTEL_SDK
5231+#define BENCH_IXP_ACCESS_LIB 1
5232+#endif
5233+#ifdef BENCH_IXP_ACCESS_LIB
5234+#include <IxTypes.h>
5235+#include <IxOsBuffMgt.h>
5236+#include <IxNpeDl.h>
5237+#include <IxCryptoAcc.h>
5238+#include <IxQMgr.h>
5239+#include <IxOsServices.h>
5240+#include <IxOsCacheMMU.h>
5241+#endif
5242+
5243+/*
5244+ * support for access lib version 1.4
5245+ */
5246+#ifndef IX_MBUF_PRIV
5247+#define IX_MBUF_PRIV(x) ((x)->priv)
5248+#endif
5249+
5250+/*
5251+ * the number of simultaneously active requests
5252+ */
5253+static int request_q_len = 40;
5254+module_param(request_q_len, int, 0);
5255+MODULE_PARM_DESC(request_q_len, "Number of outstanding requests");
5256+
5257+/*
5258+ * how many requests we want to have processed
5259+ */
5260+static int request_num = 1024;
5261+module_param(request_num, int, 0);
5262+MODULE_PARM_DESC(request_num, "run for at least this many requests");
5263+
5264+/*
5265+ * the size of each request
5266+ */
5267+static int request_size = 1488;
5268+module_param(request_size, int, 0);
5269+MODULE_PARM_DESC(request_size, "size of each request");
5270+
5271+/*
5272+ * OCF batching of requests
5273+ */
5274+static int request_batch = 1;
5275+module_param(request_batch, int, 0);
5276+MODULE_PARM_DESC(request_batch, "enable OCF request batching");
5277+
5278+/*
5279+ * OCF immediate callback on completion
5280+ */
5281+static int request_cbimm = 1;
5282+module_param(request_cbimm, int, 0);
5283+MODULE_PARM_DESC(request_cbimm, "enable OCF immediate callback on completion");
5284+
5285+/*
5286+ * a structure for each request
5287+ */
5288+typedef struct {
5289+ struct work_struct work;
5290+#ifdef BENCH_IXP_ACCESS_LIB
5291+ IX_MBUF mbuf;
5292+#endif
5293+ unsigned char *buffer;
5294+} request_t;
5295+
5296+static request_t *requests;
5297+
5298+static spinlock_t ocfbench_counter_lock;
5299+static int outstanding;
5300+static int total;
5301+
5302+/*************************************************************************/
5303+/*
5304+ * OCF benchmark routines
5305+ */
5306+
5307+static uint64_t ocf_cryptoid;
5308+static unsigned long jstart, jstop;
5309+
5310+static int ocf_init(void);
5311+static int ocf_cb(struct cryptop *crp);
5312+static void ocf_request(void *arg);
5313+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
5314+static void ocf_request_wq(struct work_struct *work);
5315+#endif
5316+
5317+static int
5318+ocf_init(void)
5319+{
5320+ int error;
5321+ struct cryptoini crie, cria;
5322+ struct cryptodesc crda, crde;
5323+
5324+ memset(&crie, 0, sizeof(crie));
5325+ memset(&cria, 0, sizeof(cria));
5326+ memset(&crde, 0, sizeof(crde));
5327+ memset(&crda, 0, sizeof(crda));
5328+
5329+ cria.cri_alg = CRYPTO_SHA1_HMAC;
5330+ cria.cri_klen = 20 * 8;
5331+ cria.cri_key = "0123456789abcdefghij";
5332+
5333+ //crie.cri_alg = CRYPTO_3DES_CBC;
5334+ crie.cri_alg = CRYPTO_AES_CBC;
5335+ crie.cri_klen = 24 * 8;
5336+ crie.cri_key = "0123456789abcdefghijklmn";
5337+
5338+ crie.cri_next = &cria;
5339+
5340+ error = crypto_newsession(&ocf_cryptoid, &crie,
5341+ CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE);
5342+ if (error) {
5343+ printk("crypto_newsession failed %d\n", error);
5344+ return -1;
5345+ }
5346+ return 0;
5347+}
5348+
5349+static int
5350+ocf_cb(struct cryptop *crp)
5351+{
5352+ request_t *r = (request_t *) crp->crp_opaque;
5353+ unsigned long flags;
5354+
5355+ if (crp->crp_etype)
5356+ printk("Error in OCF processing: %d\n", crp->crp_etype);
5357+ crypto_freereq(crp);
5358+ crp = NULL;
5359+
5360+ /* do all requests but take at least 1 second */
5361+ spin_lock_irqsave(&ocfbench_counter_lock, flags);
5362+ total++;
5363+ if (total > request_num && jstart + HZ < jiffies) {
5364+ outstanding--;
5365+ spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
5366+ return 0;
5367+ }
5368+ spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
5369+
5370+ schedule_work(&r->work);
5371+ return 0;
5372+}
5373+
5374+
5375+static void
5376+ocf_request(void *arg)
5377+{
5378+ request_t *r = arg;
5379+ struct cryptop *crp = crypto_getreq(2);
5380+ struct cryptodesc *crde, *crda;
5381+ unsigned long flags;
5382+
5383+ if (!crp) {
5384+ spin_lock_irqsave(&ocfbench_counter_lock, flags);
5385+ outstanding--;
5386+ spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
5387+ return;
5388+ }
5389+
5390+ crde = crp->crp_desc;
5391+ crda = crde->crd_next;
5392+
5393+ crda->crd_skip = 0;
5394+ crda->crd_flags = 0;
5395+ crda->crd_len = request_size;
5396+ crda->crd_inject = request_size;
5397+ crda->crd_alg = CRYPTO_SHA1_HMAC;
5398+ crda->crd_key = "0123456789abcdefghij";
5399+ crda->crd_klen = 20 * 8;
5400+
5401+ crde->crd_skip = 0;
5402+ crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_ENCRYPT;
5403+ crde->crd_len = request_size;
5404+ crde->crd_inject = request_size;
5405+ //crde->crd_alg = CRYPTO_3DES_CBC;
5406+ crde->crd_alg = CRYPTO_AES_CBC;
5407+ crde->crd_key = "0123456789abcdefghijklmn";
5408+ crde->crd_klen = 24 * 8;
5409+
5410+ crp->crp_ilen = request_size + 64;
5411+ crp->crp_flags = 0;
5412+ if (request_batch)
5413+ crp->crp_flags |= CRYPTO_F_BATCH;
5414+ if (request_cbimm)
5415+ crp->crp_flags |= CRYPTO_F_CBIMM;
5416+ crp->crp_buf = (caddr_t) r->buffer;
5417+ crp->crp_callback = ocf_cb;
5418+ crp->crp_sid = ocf_cryptoid;
5419+ crp->crp_opaque = (caddr_t) r;
5420+ crypto_dispatch(crp);
5421+}
5422+
5423+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
5424+static void
5425+ocf_request_wq(struct work_struct *work)
5426+{
5427+ request_t *r = container_of(work, request_t, work);
5428+ ocf_request(r);
5429+}
5430+#endif
5431+
5432+static void
5433+ocf_done(void)
5434+{
5435+ crypto_freesession(ocf_cryptoid);
5436+}
5437+
5438+/*************************************************************************/
5439+#ifdef BENCH_IXP_ACCESS_LIB
5440+/*************************************************************************/
5441+/*
5442+ * CryptoAcc benchmark routines
5443+ */
5444+
5445+static IxCryptoAccCtx ixp_ctx;
5446+static UINT32 ixp_ctx_id;
5447+static IX_MBUF ixp_pri;
5448+static IX_MBUF ixp_sec;
5449+static int ixp_registered = 0;
5450+
5451+static void ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp,
5452+ IxCryptoAccStatus status);
5453+static void ixp_perform_cb(UINT32 ctx_id, IX_MBUF *sbufp, IX_MBUF *dbufp,
5454+ IxCryptoAccStatus status);
5455+static void ixp_request(void *arg);
5456+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
5457+static void ixp_request_wq(struct work_struct *work);
5458+#endif
5459+
5460+static int
5461+ixp_init(void)
5462+{
5463+ IxCryptoAccStatus status;
5464+
5465+ ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
5466+ ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
5467+ ixp_ctx.cipherCtx.cipherKeyLen = 24;
5468+ ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
5469+ ixp_ctx.cipherCtx.cipherInitialVectorLen = IX_CRYPTO_ACC_DES_IV_64;
5470+ memcpy(ixp_ctx.cipherCtx.key.cipherKey, "0123456789abcdefghijklmn", 24);
5471+
5472+ ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
5473+ ixp_ctx.authCtx.authDigestLen = 12;
5474+ ixp_ctx.authCtx.aadLen = 0;
5475+ ixp_ctx.authCtx.authKeyLen = 20;
5476+ memcpy(ixp_ctx.authCtx.key.authKey, "0123456789abcdefghij", 20);
5477+
5478+ ixp_ctx.useDifferentSrcAndDestMbufs = 0;
5479+ ixp_ctx.operation = IX_CRYPTO_ACC_OP_ENCRYPT_AUTH ;
5480+
5481+ IX_MBUF_MLEN(&ixp_pri) = IX_MBUF_PKT_LEN(&ixp_pri) = 128;
5482+ IX_MBUF_MDATA(&ixp_pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
5483+ IX_MBUF_MLEN(&ixp_sec) = IX_MBUF_PKT_LEN(&ixp_sec) = 128;
5484+ IX_MBUF_MDATA(&ixp_sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
5485+
5486+ status = ixCryptoAccCtxRegister(&ixp_ctx, &ixp_pri, &ixp_sec,
5487+ ixp_register_cb, ixp_perform_cb, &ixp_ctx_id);
5488+
5489+ if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {
5490+ while (!ixp_registered)
5491+ schedule();
5492+ return ixp_registered < 0 ? -1 : 0;
5493+ }
5494+
5495+ printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
5496+ return -1;
5497+}
5498+
5499+static void
5500+ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
5501+{
5502+ if (bufp) {
5503+ IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
5504+ kfree(IX_MBUF_MDATA(bufp));
5505+ IX_MBUF_MDATA(bufp) = NULL;
5506+ }
5507+
5508+ if (IX_CRYPTO_ACC_STATUS_WAIT == status)
5509+ return;
5510+ if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
5511+ ixp_registered = 1;
5512+ else
5513+ ixp_registered = -1;
5514+}
5515+
5516+static void
5517+ixp_perform_cb(
5518+ UINT32 ctx_id,
5519+ IX_MBUF *sbufp,
5520+ IX_MBUF *dbufp,
5521+ IxCryptoAccStatus status)
5522+{
5523+ request_t *r = NULL;
5524+ unsigned long flags;
5525+
5526+ /* do all requests but take at least 1 second */
5527+ spin_lock_irqsave(&ocfbench_counter_lock, flags);
5528+ total++;
5529+ if (total > request_num && jstart + HZ < jiffies) {
5530+ outstanding--;
5531+ spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
5532+ return;
5533+ }
5534+
5535+ if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {
5536+ printk("crappo %p %p\n", sbufp, r);
5537+ outstanding--;
5538+ spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
5539+ return;
5540+ }
5541+ spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
5542+
5543+ schedule_work(&r->work);
5544+}
5545+
5546+static void
5547+ixp_request(void *arg)
5548+{
5549+ request_t *r = arg;
5550+ IxCryptoAccStatus status;
5551+ unsigned long flags;
5552+
5553+ memset(&r->mbuf, 0, sizeof(r->mbuf));
5554+ IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;
5555+ IX_MBUF_MDATA(&r->mbuf) = r->buffer;
5556+ IX_MBUF_PRIV(&r->mbuf) = r;
5557+ status = ixCryptoAccAuthCryptPerform(ixp_ctx_id, &r->mbuf, NULL,
5558+ 0, request_size, 0, request_size, request_size, r->buffer);
5559+ if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
5560+ printk("status1 = %d\n", status);
5561+ spin_lock_irqsave(&ocfbench_counter_lock, flags);
5562+ outstanding--;
5563+ spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
5564+ return;
5565+ }
5566+ return;
5567+}
5568+
5569+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
5570+static void
5571+ixp_request_wq(struct work_struct *work)
5572+{
5573+ request_t *r = container_of(work, request_t, work);
5574+ ixp_request(r);
5575+}
5576+#endif
5577+
5578+static void
5579+ixp_done(void)
5580+{
5581+ /* we should free the session here but I am lazy :-) */
5582+}
5583+
5584+/*************************************************************************/
5585+#endif /* BENCH_IXP_ACCESS_LIB */
5586+/*************************************************************************/
5587+
5588+int
5589+ocfbench_init(void)
5590+{
5591+ int i;
5592+ unsigned long mbps;
5593+ unsigned long flags;
5594+
5595+ printk("Crypto Speed tests\n");
5596+
5597+ requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);
5598+ if (!requests) {
5599+ printk("malloc failed\n");
5600+ return -EINVAL;
5601+ }
5602+
5603+ for (i = 0; i < request_q_len; i++) {
5604+ /* +64 for return data */
5605+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
5606+ INIT_WORK(&requests[i].work, ocf_request_wq);
5607+#else
5608+ INIT_WORK(&requests[i].work, ocf_request, &requests[i]);
5609+#endif
5610+ requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
5611+ if (!requests[i].buffer) {
5612+ printk("malloc failed\n");
5613+ return -EINVAL;
5614+ }
5615+ memset(requests[i].buffer, '0' + i, request_size + 128);
5616+ }
5617+
5618+ /*
5619+ * OCF benchmark
5620+ */
5621+ printk("OCF: testing ...\n");
5622+ if (ocf_init() == -1)
5623+ return -EINVAL;
5624+
5625+ spin_lock_init(&ocfbench_counter_lock);
5626+ total = outstanding = 0;
5627+ jstart = jiffies;
5628+ for (i = 0; i < request_q_len; i++) {
5629+ spin_lock_irqsave(&ocfbench_counter_lock, flags);
5630+ outstanding++;
5631+ spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
5632+ ocf_request(&requests[i]);
5633+ }
5634+ while (outstanding > 0)
5635+ schedule();
5636+ jstop = jiffies;
5637+
5638+ mbps = 0;
5639+ if (jstop > jstart) {
5640+ mbps = (unsigned long) total * (unsigned long) request_size * 8;
5641+ mbps /= ((jstop - jstart) * 1000) / HZ;
5642+ }
5643+ printk("OCF: %d requests of %d bytes in %d jiffies (%d.%03d Mbps)\n",
5644+ total, request_size, (int)(jstop - jstart),
5645+ ((int)mbps) / 1000, ((int)mbps) % 1000);
5646+ ocf_done();
5647+
5648+#ifdef BENCH_IXP_ACCESS_LIB
5649+ /*
5650+ * IXP benchmark
5651+ */
5652+ printk("IXP: testing ...\n");
5653+ ixp_init();
5654+ total = outstanding = 0;
5655+ jstart = jiffies;
5656+ for (i = 0; i < request_q_len; i++) {
5657+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
5658+ INIT_WORK(&requests[i].work, ixp_request_wq);
5659+#else
5660+ INIT_WORK(&requests[i].work, ixp_request, &requests[i]);
5661+#endif
5662+ spin_lock_irqsave(&ocfbench_counter_lock, flags);
5663+ outstanding++;
5664+ spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
5665+ ixp_request(&requests[i]);
5666+ }
5667+ while (outstanding > 0)
5668+ schedule();
5669+ jstop = jiffies;
5670+
5671+ mbps = 0;
5672+ if (jstop > jstart) {
5673+ mbps = (unsigned long) total * (unsigned long) request_size * 8;
5674+ mbps /= ((jstop - jstart) * 1000) / HZ;
5675+ }
5676+ printk("IXP: %d requests of %d bytes in %d jiffies (%d.%03d Mbps)\n",
5677+ total, request_size, jstop - jstart,
5678+ ((int)mbps) / 1000, ((int)mbps) % 1000);
5679+ ixp_done();
5680+#endif /* BENCH_IXP_ACCESS_LIB */
5681+
5682+ for (i = 0; i < request_q_len; i++)
5683+ kfree(requests[i].buffer);
5684+ kfree(requests);
5685+ return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */
5686+}
5687+
5688+static void __exit ocfbench_exit(void)
5689+{
5690+}
5691+
5692+module_init(ocfbench_init);
5693+module_exit(ocfbench_exit);
5694+
5695+MODULE_LICENSE("BSD");
5696+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
5697+MODULE_DESCRIPTION("Benchmark various in-kernel crypto speeds");
5698diff --git a/crypto/ocf/ocf-compat.h b/crypto/ocf/ocf-compat.h
5699new file mode 100644
5700index 0000000..4ad1223
5701--- /dev/null
5702+++ b/crypto/ocf/ocf-compat.h
5703@@ -0,0 +1,372 @@
5704+#ifndef _BSD_COMPAT_H_
5705+#define _BSD_COMPAT_H_ 1
5706+/****************************************************************************/
5707+/*
5708+ * Provide compat routines for older linux kernels and BSD kernels
5709+ *
5710+ * Written by David McCullough <david_mccullough@mcafee.com>
5711+ * Copyright (C) 2010 David McCullough <david_mccullough@mcafee.com>
5712+ *
5713+ * LICENSE TERMS
5714+ *
5715+ * The free distribution and use of this software in both source and binary
5716+ * form is allowed (with or without changes) provided that:
5717+ *
5718+ * 1. distributions of this source code include the above copyright
5719+ * notice, this list of conditions and the following disclaimer;
5720+ *
5721+ * 2. distributions in binary form include the above copyright
5722+ * notice, this list of conditions and the following disclaimer
5723+ * in the documentation and/or other associated materials;
5724+ *
5725+ * 3. the copyright holder's name is not used to endorse products
5726+ * built using this software without specific written permission.
5727+ *
5728+ * ALTERNATIVELY, provided that this notice is retained in full, this file
5729+ * may be distributed under the terms of the GNU General Public License (GPL),
5730+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
5731+ *
5732+ * DISCLAIMER
5733+ *
5734+ * This software is provided 'as is' with no explicit or implied warranties
5735+ * in respect of its properties, including, but not limited to, correctness
5736+ * and/or fitness for purpose.
5737+ */
5738+/****************************************************************************/
5739+#ifdef __KERNEL__
5740+#include <linux/version.h>
5741+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
5742+#include <linux/config.h>
5743+#endif
5744+
5745+/*
5746+ * fake some BSD driver interface stuff specifically for OCF use
5747+ */
5748+
5749+typedef struct ocf_device *device_t;
5750+
5751+typedef struct {
5752+ int (*cryptodev_newsession)(device_t dev, u_int32_t *sidp, struct cryptoini *cri);
5753+ int (*cryptodev_freesession)(device_t dev, u_int64_t tid);
5754+ int (*cryptodev_process)(device_t dev, struct cryptop *crp, int hint);
5755+ int (*cryptodev_kprocess)(device_t dev, struct cryptkop *krp, int hint);
5756+} device_method_t;
5757+#define DEVMETHOD(id, func) id: func
5758+
5759+struct ocf_device {
5760+ char name[32]; /* the driver name */
5761+ char nameunit[32]; /* the driver name + HW instance */
5762+ int unit;
5763+ device_method_t methods;
5764+ void *softc;
5765+};
5766+
5767+#define CRYPTODEV_NEWSESSION(dev, sid, cri) \
5768+ ((*(dev)->methods.cryptodev_newsession)(dev,sid,cri))
5769+#define CRYPTODEV_FREESESSION(dev, sid) \
5770+ ((*(dev)->methods.cryptodev_freesession)(dev, sid))
5771+#define CRYPTODEV_PROCESS(dev, crp, hint) \
5772+ ((*(dev)->methods.cryptodev_process)(dev, crp, hint))
5773+#define CRYPTODEV_KPROCESS(dev, krp, hint) \
5774+ ((*(dev)->methods.cryptodev_kprocess)(dev, krp, hint))
5775+
5776+#define device_get_name(dev) ((dev)->name)
5777+#define device_get_nameunit(dev) ((dev)->nameunit)
5778+#define device_get_unit(dev) ((dev)->unit)
5779+#define device_get_softc(dev) ((dev)->softc)
5780+
5781+#define softc_device_decl \
5782+ struct ocf_device _device; \
5783+ device_t
5784+
5785+#define softc_device_init(_sc, _name, _unit, _methods) \
5786+ if (1) {\
5787+ strncpy((_sc)->_device.name, _name, sizeof((_sc)->_device.name) - 1); \
5788+ snprintf((_sc)->_device.nameunit, sizeof((_sc)->_device.name), "%s%d", _name, _unit); \
5789+ (_sc)->_device.unit = _unit; \
5790+ (_sc)->_device.methods = _methods; \
5791+ (_sc)->_device.softc = (void *) _sc; \
5792+ *(device_t *)((softc_get_device(_sc))+1) = &(_sc)->_device; \
5793+ } else
5794+
5795+#define softc_get_device(_sc) (&(_sc)->_device)
5796+
5797+/*
5798+ * iomem support for 2.4 and 2.6 kernels
5799+ */
5800+#include <linux/version.h>
5801+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
5802+#define ocf_iomem_t unsigned long
5803+
5804+/*
5805+ * implement simple workqueue like support for older kernels
5806+ */
5807+
5808+#include <linux/tqueue.h>
5809+
5810+#define work_struct tq_struct
5811+
5812+#define INIT_WORK(wp, fp, ap) \
5813+ do { \
5814+ (wp)->sync = 0; \
5815+ (wp)->routine = (fp); \
5816+ (wp)->data = (ap); \
5817+ } while (0)
5818+
5819+#define schedule_work(wp) \
5820+ do { \
5821+ queue_task((wp), &tq_immediate); \
5822+ mark_bh(IMMEDIATE_BH); \
5823+ } while (0)
5824+
5825+#define flush_scheduled_work() run_task_queue(&tq_immediate)
5826+
5827+#else
5828+#define ocf_iomem_t void __iomem *
5829+
5830+#include <linux/workqueue.h>
5831+
5832+#endif
5833+
5834+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
5835+#include <linux/fdtable.h>
5836+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
5837+#define files_fdtable(files) (files)
5838+#endif
5839+
5840+#ifdef MODULE_PARM
5841+#undef module_param /* just in case */
5842+#define module_param(a,b,c) MODULE_PARM(a,"i")
5843+#endif
5844+
5845+#define bzero(s,l) memset(s,0,l)
5846+#define bcopy(s,d,l) memcpy(d,s,l)
5847+#define bcmp(x, y, l) memcmp(x,y,l)
5848+
5849+#define MIN(x,y) ((x) < (y) ? (x) : (y))
5850+
5851+#define device_printf(dev, a...) ({ \
5852+ printk("%s: ", device_get_nameunit(dev)); printk(a); \
5853+ })
5854+
5855+#undef printf
5856+#define printf(fmt...) printk(fmt)
5857+
5858+#define KASSERT(c,p) if (!(c)) { printk p ; } else
5859+
5860+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
5861+#define ocf_daemonize(str) \
5862+ daemonize(); \
5863+ spin_lock_irq(&current->sigmask_lock); \
5864+ sigemptyset(&current->blocked); \
5865+ recalc_sigpending(current); \
5866+ spin_unlock_irq(&current->sigmask_lock); \
5867+ sprintf(current->comm, str);
5868+#else
5869+#define ocf_daemonize(str) daemonize(str);
5870+#endif
5871+
5872+#define TAILQ_INSERT_TAIL(q,d,m) list_add_tail(&(d)->m, (q))
5873+#define TAILQ_EMPTY(q) list_empty(q)
5874+#define TAILQ_FOREACH(v, q, m) list_for_each_entry(v, q, m)
5875+
5876+#define read_random(p,l) get_random_bytes(p,l)
5877+
5878+#define DELAY(x) ((x) > 2000 ? mdelay((x)/1000) : udelay(x))
5879+#define strtoul simple_strtoul
5880+
5881+#define pci_get_vendor(dev) ((dev)->vendor)
5882+#define pci_get_device(dev) ((dev)->device)
5883+
5884+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
5885+#define pci_set_consistent_dma_mask(dev, mask) (0)
5886+#endif
5887+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
5888+#define pci_dma_sync_single_for_cpu pci_dma_sync_single
5889+#endif
5890+
5891+#ifndef DMA_32BIT_MASK
5892+#define DMA_32BIT_MASK 0x00000000ffffffffULL
5893+#endif
5894+
5895+#ifndef htole32
5896+#define htole32(x) cpu_to_le32(x)
5897+#endif
5898+#ifndef htobe32
5899+#define htobe32(x) cpu_to_be32(x)
5900+#endif
5901+#ifndef htole16
5902+#define htole16(x) cpu_to_le16(x)
5903+#endif
5904+#ifndef htobe16
5905+#define htobe16(x) cpu_to_be16(x)
5906+#endif
5907+
5908+/* older kernels don't have these */
5909+
5910+#include <asm/irq.h>
5911+#if !defined(IRQ_NONE) && !defined(IRQ_RETVAL)
5912+#define IRQ_NONE
5913+#define IRQ_HANDLED
5914+#define IRQ_WAKE_THREAD
5915+#define IRQ_RETVAL
5916+#define irqreturn_t void
5917+typedef irqreturn_t (*irq_handler_t)(int irq, void *arg, struct pt_regs *regs);
5918+#endif
5919+#ifndef IRQF_SHARED
5920+#define IRQF_SHARED SA_SHIRQ
5921+#endif
5922+
5923+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5924+# define strlcpy(dest,src,len) \
5925+ ({strncpy(dest,src,(len)-1); ((char *)dest)[(len)-1] = '\0'; })
5926+#endif
5927+
5928+#ifndef MAX_ERRNO
5929+#define MAX_ERRNO 4095
5930+#endif
5931+#ifndef IS_ERR_VALUE
5932+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,5)
5933+#include <linux/err.h>
5934+#endif
5935+#ifndef IS_ERR_VALUE
5936+#define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-MAX_ERRNO)
5937+#endif
5938+#endif
5939+
5940+/*
5941+ * common debug for all
5942+ */
5943+#if 1
5944+#define dprintk(a...) do { if (debug) printk(a); } while(0)
5945+#else
5946+#define dprintk(a...)
5947+#endif
5948+
5949+#ifndef SLAB_ATOMIC
5950+/* Changed in 2.6.20, must use GFP_ATOMIC now */
5951+#define SLAB_ATOMIC GFP_ATOMIC
5952+#endif
5953+
5954+/*
5955+ * need some additional support for older kernels */
5956+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,2)
5957+#define pci_register_driver_compat(driver, rc) \
5958+ do { \
5959+ if ((rc) > 0) { \
5960+ (rc) = 0; \
5961+ } else if (rc == 0) { \
5962+ (rc) = -ENODEV; \
5963+ } else { \
5964+ pci_unregister_driver(driver); \
5965+ } \
5966+ } while (0)
5967+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
5968+#define pci_register_driver_compat(driver,rc) ((rc) = (rc) < 0 ? (rc) : 0)
5969+#else
5970+#define pci_register_driver_compat(driver,rc)
5971+#endif
5972+
5973+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
5974+
5975+#include <linux/mm.h>
5976+#include <asm/scatterlist.h>
5977+
5978+static inline void sg_set_page(struct scatterlist *sg, struct page *page,
5979+ unsigned int len, unsigned int offset)
5980+{
5981+ sg->page = page;
5982+ sg->offset = offset;
5983+ sg->length = len;
5984+}
5985+
5986+static inline void *sg_virt(struct scatterlist *sg)
5987+{
5988+ return page_address(sg->page) + sg->offset;
5989+}
5990+
5991+#define sg_init_table(sg, n)
5992+
5993+#define sg_mark_end(sg)
5994+
5995+#endif
5996+
5997+#ifndef late_initcall
5998+#define late_initcall(init) module_init(init)
5999+#endif
6000+
6001+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) || !defined(CONFIG_SMP)
6002+#define ocf_for_each_cpu(cpu) for ((cpu) = 0; (cpu) == 0; (cpu)++)
6003+#else
6004+#define ocf_for_each_cpu(cpu) for_each_present_cpu(cpu)
6005+#endif
6006+
6007+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
6008+#include <linux/sched.h>
6009+#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
6010+#endif
6011+
6012+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4)
6013+
6014+struct ocf_thread {
6015+ struct task_struct *task;
6016+ int (*func)(void *arg);
6017+ void *arg;
6018+};
6019+
6020+/* thread startup helper func */
6021+static inline int ocf_run_thread(void *arg)
6022+{
6023+ struct ocf_thread *t = (struct ocf_thread *) arg;
6024+ if (!t)
6025+ return -1; /* very bad */
6026+ t->task = current;
6027+ daemonize();
6028+ spin_lock_irq(&current->sigmask_lock);
6029+ sigemptyset(&current->blocked);
6030+ recalc_sigpending(current);
6031+ spin_unlock_irq(&current->sigmask_lock);
6032+ return (*t->func)(t->arg);
6033+}
6034+
6035+#define kthread_create(f,a,fmt...) \
6036+ ({ \
6037+ struct ocf_thread t; \
6038+ pid_t p; \
6039+ t.task = NULL; \
6040+ t.func = (f); \
6041+ t.arg = (a); \
6042+ p = kernel_thread(ocf_run_thread, &t, CLONE_FS|CLONE_FILES); \
6043+ while (p != (pid_t) -1 && t.task == NULL) \
6044+ schedule(); \
6045+ if (t.task) \
6046+ snprintf(t.task->comm, sizeof(t.task->comm), fmt); \
6047+ (t.task); \
6048+ })
6049+
6050+#define kthread_bind(t,cpu) /**/
6051+
6052+#define kthread_should_stop() (strcmp(current->comm, "stopping") == 0)
6053+
6054+#define kthread_stop(t) \
6055+ ({ \
6056+ strcpy((t)->comm, "stopping"); \
6057+ kill_proc((t)->pid, SIGTERM, 1); \
6058+ do { \
6059+ schedule(); \
6060+ } while (kill_proc((t)->pid, SIGTERM, 1) == 0); \
6061+ })
6062+
6063+#else
6064+#include <linux/kthread.h>
6065+#endif
6066+
6067+
6068+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)
6069+#define skb_frag_page(x) ((x)->page)
6070+#endif
6071+
6072+#endif /* __KERNEL__ */
6073+
6074+/****************************************************************************/
6075+#endif /* _BSD_COMPAT_H_ */
6076diff --git a/crypto/ocf/ocfnull/Makefile b/crypto/ocf/ocfnull/Makefile
6077new file mode 100644
6078index 0000000..044bcac
6079--- /dev/null
6080+++ b/crypto/ocf/ocfnull/Makefile
6081@@ -0,0 +1,12 @@
6082+# for SGlinux builds
6083+-include $(ROOTDIR)/modules/.config
6084+
6085+obj-$(CONFIG_OCF_OCFNULL) += ocfnull.o
6086+
6087+obj ?= .
6088+EXTRA_CFLAGS += -I$(obj)/..
6089+
6090+ifdef TOPDIR
6091+-include $(TOPDIR)/Rules.make
6092+endif
6093+
6094diff --git a/crypto/ocf/ocfnull/ocfnull.c b/crypto/ocf/ocfnull/ocfnull.c
6095new file mode 100644
6096index 0000000..9cf3f6e
6097--- /dev/null
6098+++ b/crypto/ocf/ocfnull/ocfnull.c
6099@@ -0,0 +1,204 @@
6100+/*
6101+ * An OCF module for determining the cost of crypto versus the cost of
6102+ * IPSec processing outside of OCF. This modules gives us the effect of
6103+ * zero cost encryption, of course you will need to run it at both ends
6104+ * since it does no crypto at all.
6105+ *
6106+ * Written by David McCullough <david_mccullough@mcafee.com>
6107+ * Copyright (C) 2006-2010 David McCullough
6108+ *
6109+ * LICENSE TERMS
6110+ *
6111+ * The free distribution and use of this software in both source and binary
6112+ * form is allowed (with or without changes) provided that:
6113+ *
6114+ * 1. distributions of this source code include the above copyright
6115+ * notice, this list of conditions and the following disclaimer;
6116+ *
6117+ * 2. distributions in binary form include the above copyright
6118+ * notice, this list of conditions and the following disclaimer
6119+ * in the documentation and/or other associated materials;
6120+ *
6121+ * 3. the copyright holder's name is not used to endorse products
6122+ * built using this software without specific written permission.
6123+ *
6124+ * ALTERNATIVELY, provided that this notice is retained in full, this product
6125+ * may be distributed under the terms of the GNU General Public License (GPL),
6126+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
6127+ *
6128+ * DISCLAIMER
6129+ *
6130+ * This software is provided 'as is' with no explicit or implied warranties
6131+ * in respect of its properties, including, but not limited to, correctness
6132+ * and/or fitness for purpose.
6133+ */
6134+
6135+#include <linux/version.h>
6136+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
6137+#include <linux/config.h>
6138+#endif
6139+#include <linux/module.h>
6140+#include <linux/init.h>
6141+#include <linux/list.h>
6142+#include <linux/slab.h>
6143+#include <linux/sched.h>
6144+#include <linux/wait.h>
6145+#include <linux/crypto.h>
6146+#include <linux/interrupt.h>
6147+
6148+#include <cryptodev.h>
6149+#include <uio.h>
6150+
6151+static int32_t null_id = -1;
6152+static u_int32_t null_sesnum = 0;
6153+
6154+static int null_process(device_t, struct cryptop *, int);
6155+static int null_newsession(device_t, u_int32_t *, struct cryptoini *);
6156+static int null_freesession(device_t, u_int64_t);
6157+
6158+#define debug ocfnull_debug
6159+int ocfnull_debug = 0;
6160+module_param(ocfnull_debug, int, 0644);
6161+MODULE_PARM_DESC(ocfnull_debug, "Enable debug");
6162+
6163+/*
6164+ * dummy device structure
6165+ */
6166+
6167+static struct {
6168+ softc_device_decl sc_dev;
6169+} nulldev;
6170+
6171+static device_method_t null_methods = {
6172+ /* crypto device methods */
6173+ DEVMETHOD(cryptodev_newsession, null_newsession),
6174+ DEVMETHOD(cryptodev_freesession,null_freesession),
6175+ DEVMETHOD(cryptodev_process, null_process),
6176+};
6177+
6178+/*
6179+ * Generate a new software session.
6180+ */
6181+static int
6182+null_newsession(device_t arg, u_int32_t *sid, struct cryptoini *cri)
6183+{
6184+ dprintk("%s()\n", __FUNCTION__);
6185+ if (sid == NULL || cri == NULL) {
6186+ dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
6187+ return EINVAL;
6188+ }
6189+
6190+ if (null_sesnum == 0)
6191+ null_sesnum++;
6192+ *sid = null_sesnum++;
6193+ return 0;
6194+}
6195+
6196+
6197+/*
6198+ * Free a session.
6199+ */
6200+static int
6201+null_freesession(device_t arg, u_int64_t tid)
6202+{
6203+ u_int32_t sid = CRYPTO_SESID2LID(tid);
6204+
6205+ dprintk("%s()\n", __FUNCTION__);
6206+ if (sid > null_sesnum) {
6207+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
6208+ return EINVAL;
6209+ }
6210+
6211+ /* Silently accept and return */
6212+ if (sid == 0)
6213+ return 0;
6214+ return 0;
6215+}
6216+
6217+
6218+/*
6219+ * Process a request.
6220+ */
6221+static int
6222+null_process(device_t arg, struct cryptop *crp, int hint)
6223+{
6224+ unsigned int lid;
6225+
6226+ dprintk("%s()\n", __FUNCTION__);
6227+
6228+ /* Sanity check */
6229+ if (crp == NULL) {
6230+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
6231+ return EINVAL;
6232+ }
6233+
6234+ crp->crp_etype = 0;
6235+
6236+ if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
6237+ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
6238+ crp->crp_etype = EINVAL;
6239+ goto done;
6240+ }
6241+
6242+ /*
6243+ * find the session we are using
6244+ */
6245+
6246+ lid = crp->crp_sid & 0xffffffff;
6247+ if (lid >= null_sesnum || lid == 0) {
6248+ crp->crp_etype = ENOENT;
6249+ dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
6250+ goto done;
6251+ }
6252+
6253+done:
6254+ crypto_done(crp);
6255+ return 0;
6256+}
6257+
6258+
6259+/*
6260+ * our driver startup and shutdown routines
6261+ */
6262+
6263+static int
6264+null_init(void)
6265+{
6266+ dprintk("%s(%p)\n", __FUNCTION__, null_init);
6267+
6268+ memset(&nulldev, 0, sizeof(nulldev));
6269+ softc_device_init(&nulldev, "ocfnull", 0, null_methods);
6270+
6271+ null_id = crypto_get_driverid(softc_get_device(&nulldev),
6272+ CRYPTOCAP_F_HARDWARE);
6273+ if (null_id < 0)
6274+ panic("ocfnull: crypto device cannot initialize!");
6275+
6276+#define REGISTER(alg) \
6277+ crypto_register(null_id,alg,0,0)
6278+ REGISTER(CRYPTO_DES_CBC);
6279+ REGISTER(CRYPTO_3DES_CBC);
6280+ REGISTER(CRYPTO_RIJNDAEL128_CBC);
6281+ REGISTER(CRYPTO_MD5);
6282+ REGISTER(CRYPTO_SHA1);
6283+ REGISTER(CRYPTO_MD5_HMAC);
6284+ REGISTER(CRYPTO_SHA1_HMAC);
6285+#undef REGISTER
6286+
6287+ return 0;
6288+}
6289+
6290+static void
6291+null_exit(void)
6292+{
6293+ dprintk("%s()\n", __FUNCTION__);
6294+ crypto_unregister_all(null_id);
6295+ null_id = -1;
6296+}
6297+
6298+module_init(null_init);
6299+module_exit(null_exit);
6300+
6301+MODULE_LICENSE("Dual BSD/GPL");
6302+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
6303+MODULE_DESCRIPTION("ocfnull - claims a lot but does nothing");
6304diff --git a/crypto/ocf/random.c b/crypto/ocf/random.c
6305new file mode 100644
6306index 0000000..4bb773f
6307--- /dev/null
6308+++ b/crypto/ocf/random.c
6309@@ -0,0 +1,317 @@
6310+/*
6311+ * A system independant way of adding entropy to the kernels pool
6312+ * this way the drivers can focus on the real work and we can take
6313+ * care of pushing it to the appropriate place in the kernel.
6314+ *
6315+ * This should be fast and callable from timers/interrupts
6316+ *
6317+ * Written by David McCullough <david_mccullough@mcafee.com>
6318+ * Copyright (C) 2006-2010 David McCullough
6319+ * Copyright (C) 2004-2005 Intel Corporation.
6320+ *
6321+ * LICENSE TERMS
6322+ *
6323+ * The free distribution and use of this software in both source and binary
6324+ * form is allowed (with or without changes) provided that:
6325+ *
6326+ * 1. distributions of this source code include the above copyright
6327+ * notice, this list of conditions and the following disclaimer;
6328+ *
6329+ * 2. distributions in binary form include the above copyright
6330+ * notice, this list of conditions and the following disclaimer
6331+ * in the documentation and/or other associated materials;
6332+ *
6333+ * 3. the copyright holder's name is not used to endorse products
6334+ * built using this software without specific written permission.
6335+ *
6336+ * ALTERNATIVELY, provided that this notice is retained in full, this product
6337+ * may be distributed under the terms of the GNU General Public License (GPL),
6338+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
6339+ *
6340+ * DISCLAIMER
6341+ *
6342+ * This software is provided 'as is' with no explicit or implied warranties
6343+ * in respect of its properties, including, but not limited to, correctness
6344+ * and/or fitness for purpose.
6345+ */
6346+
6347+#include <linux/version.h>
6348+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
6349+#include <linux/config.h>
6350+#endif
6351+#include <linux/module.h>
6352+#include <linux/init.h>
6353+#include <linux/list.h>
6354+#include <linux/slab.h>
6355+#include <linux/wait.h>
6356+#include <linux/sched.h>
6357+#include <linux/spinlock.h>
6358+#include <linux/unistd.h>
6359+#include <linux/poll.h>
6360+#include <linux/random.h>
6361+#include <cryptodev.h>
6362+
6363+#ifdef CONFIG_OCF_FIPS
6364+#include "rndtest.h"
6365+#endif
6366+
6367+#ifndef HAS_RANDOM_INPUT_WAIT
6368+#error "Please do not enable OCF_RANDOMHARVEST unless you have applied patches"
6369+#endif
6370+
6371+/*
6372+ * a hack to access the debug levels from the crypto driver
6373+ */
6374+extern int crypto_debug;
6375+#define debug crypto_debug
6376+
6377+/*
6378+ * a list of all registered random providers
6379+ */
6380+static LIST_HEAD(random_ops);
6381+static int started = 0;
6382+static int initted = 0;
6383+
6384+struct random_op {
6385+ struct list_head random_list;
6386+ u_int32_t driverid;
6387+ int (*read_random)(void *arg, u_int32_t *buf, int len);
6388+ void *arg;
6389+};
6390+
6391+static int random_proc(void *arg);
6392+
6393+static pid_t randomproc = (pid_t) -1;
6394+static spinlock_t random_lock;
6395+
6396+/*
6397+ * just init the spin locks
6398+ */
6399+static int
6400+crypto_random_init(void)
6401+{
6402+ spin_lock_init(&random_lock);
6403+ initted = 1;
6404+ return(0);
6405+}
6406+
6407+/*
6408+ * Add the given random reader to our list (if not present)
6409+ * and start the thread (if not already started)
6410+ *
6411+ * we have to assume that driver id is ok for now
6412+ */
6413+int
6414+crypto_rregister(
6415+ u_int32_t driverid,
6416+ int (*read_random)(void *arg, u_int32_t *buf, int len),
6417+ void *arg)
6418+{
6419+ unsigned long flags;
6420+ int ret = 0;
6421+ struct random_op *rops, *tmp;
6422+
6423+ dprintk("%s,%d: %s(0x%x, %p, %p)\n", __FILE__, __LINE__,
6424+ __FUNCTION__, driverid, read_random, arg);
6425+
6426+ if (!initted)
6427+ crypto_random_init();
6428+
6429+#if 0
6430+ struct cryptocap *cap;
6431+
6432+ cap = crypto_checkdriver(driverid);
6433+ if (!cap)
6434+ return EINVAL;
6435+#endif
6436+
6437+ list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
6438+ if (rops->driverid == driverid && rops->read_random == read_random)
6439+ return EEXIST;
6440+ }
6441+
6442+ rops = (struct random_op *) kmalloc(sizeof(*rops), GFP_KERNEL);
6443+ if (!rops)
6444+ return ENOMEM;
6445+
6446+ rops->driverid = driverid;
6447+ rops->read_random = read_random;
6448+ rops->arg = arg;
6449+
6450+ spin_lock_irqsave(&random_lock, flags);
6451+ list_add_tail(&rops->random_list, &random_ops);
6452+ if (!started) {
6453+ randomproc = kernel_thread(random_proc, NULL, CLONE_FS|CLONE_FILES);
6454+ if (randomproc < 0) {
6455+ ret = randomproc;
6456+ printk("crypto: crypto_rregister cannot start random thread; "
6457+ "error %d", ret);
6458+ } else
6459+ started = 1;
6460+ }
6461+ spin_unlock_irqrestore(&random_lock, flags);
6462+
6463+ return ret;
6464+}
6465+EXPORT_SYMBOL(crypto_rregister);
6466+
6467+int
6468+crypto_runregister_all(u_int32_t driverid)
6469+{
6470+ struct random_op *rops, *tmp;
6471+ unsigned long flags;
6472+
6473+ dprintk("%s,%d: %s(0x%x)\n", __FILE__, __LINE__, __FUNCTION__, driverid);
6474+
6475+ list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
6476+ if (rops->driverid == driverid) {
6477+ list_del(&rops->random_list);
6478+ kfree(rops);
6479+ }
6480+ }
6481+
6482+ spin_lock_irqsave(&random_lock, flags);
6483+ if (list_empty(&random_ops) && started)
6484+ kill_proc(randomproc, SIGKILL, 1);
6485+ spin_unlock_irqrestore(&random_lock, flags);
6486+ return(0);
6487+}
6488+EXPORT_SYMBOL(crypto_runregister_all);
6489+
6490+/*
6491+ * while we can add entropy to random.c continue to read random data from
6492+ * the drivers and push it to random.
6493+ */
6494+static int
6495+random_proc(void *arg)
6496+{
6497+ int n;
6498+ int wantcnt;
6499+ int bufcnt = 0;
6500+ int retval = 0;
6501+ int *buf = NULL;
6502+
6503+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
6504+ daemonize();
6505+ spin_lock_irq(&current->sigmask_lock);
6506+ sigemptyset(&current->blocked);
6507+ recalc_sigpending(current);
6508+ spin_unlock_irq(&current->sigmask_lock);
6509+ sprintf(current->comm, "ocf-random");
6510+#else
6511+ daemonize("ocf-random");
6512+ allow_signal(SIGKILL);
6513+#endif
6514+
6515+ (void) get_fs();
6516+ set_fs(get_ds());
6517+
6518+#ifdef CONFIG_OCF_FIPS
6519+#define NUM_INT (RNDTEST_NBYTES/sizeof(int))
6520+#else
6521+#define NUM_INT 32
6522+#endif
6523+
6524+ /*
6525+ * some devices can transferr their RNG data direct into memory,
6526+ * so make sure it is device friendly
6527+ */
6528+ buf = kmalloc(NUM_INT * sizeof(int), GFP_DMA);
6529+ if (NULL == buf) {
6530+ printk("crypto: RNG could not allocate memory\n");
6531+ retval = -ENOMEM;
6532+ goto bad_alloc;
6533+ }
6534+
6535+ wantcnt = NUM_INT; /* start by adding some entropy */
6536+
6537+ /*
6538+ * its possible due to errors or driver removal that we no longer
6539+ * have anything to do, if so exit or we will consume all the CPU
6540+ * doing nothing
6541+ */
6542+ while (!list_empty(&random_ops)) {
6543+ struct random_op *rops, *tmp;
6544+
6545+#ifdef CONFIG_OCF_FIPS
6546+ if (wantcnt)
6547+ wantcnt = NUM_INT; /* FIPs mode can do 20000 bits or none */
6548+#endif
6549+
6550+ /* see if we can get enough entropy to make the world
6551+ * a better place.
6552+ */
6553+ while (bufcnt < wantcnt && bufcnt < NUM_INT) {
6554+ list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
6555+
6556+ n = (*rops->read_random)(rops->arg, &buf[bufcnt],
6557+ NUM_INT - bufcnt);
6558+
6559+ /* on failure remove the random number generator */
6560+ if (n == -1) {
6561+ list_del(&rops->random_list);
6562+ printk("crypto: RNG (driverid=0x%x) failed, disabling\n",
6563+ rops->driverid);
6564+ kfree(rops);
6565+ } else if (n > 0)
6566+ bufcnt += n;
6567+ }
6568+ /* give up CPU for a bit, just in case as this is a loop */
6569+ schedule();
6570+ }
6571+
6572+
6573+#ifdef CONFIG_OCF_FIPS
6574+ if (bufcnt > 0 && rndtest_buf((unsigned char *) &buf[0])) {
6575+ dprintk("crypto: buffer had fips errors, discarding\n");
6576+ bufcnt = 0;
6577+ }
6578+#endif
6579+
6580+ /*
6581+ * if we have a certified buffer, we can send some data
6582+ * to /dev/random and move along
6583+ */
6584+ if (bufcnt > 0) {
6585+ /* add what we have */
6586+ random_input_words(buf, bufcnt, bufcnt*sizeof(int)*8);
6587+ bufcnt = 0;
6588+ }
6589+
6590+ /* give up CPU for a bit so we don't hog while filling */
6591+ schedule();
6592+
6593+ /* wait for needing more */
6594+ wantcnt = random_input_wait();
6595+
6596+ if (wantcnt <= 0)
6597+ wantcnt = 0; /* try to get some info again */
6598+ else
6599+ /* round up to one word or we can loop forever */
6600+ wantcnt = (wantcnt + (sizeof(int)*8)) / (sizeof(int)*8);
6601+ if (wantcnt > NUM_INT) {
6602+ wantcnt = NUM_INT;
6603+ }
6604+
6605+ if (signal_pending(current)) {
6606+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
6607+ spin_lock_irq(&current->sigmask_lock);
6608+#endif
6609+ flush_signals(current);
6610+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
6611+ spin_unlock_irq(&current->sigmask_lock);
6612+#endif
6613+ }
6614+ }
6615+
6616+ kfree(buf);
6617+
6618+bad_alloc:
6619+ spin_lock_irq(&random_lock);
6620+ randomproc = (pid_t) -1;
6621+ started = 0;
6622+ spin_unlock_irq(&random_lock);
6623+
6624+ return retval;
6625+}
6626+
6627diff --git a/crypto/ocf/rndtest.c b/crypto/ocf/rndtest.c
6628new file mode 100644
6629index 0000000..7bed6a1
6630--- /dev/null
6631+++ b/crypto/ocf/rndtest.c
6632@@ -0,0 +1,300 @@
6633+/* $OpenBSD$ */
6634+
6635+/*
6636+ * OCF/Linux port done by David McCullough <david_mccullough@mcafee.com>
6637+ * Copyright (C) 2006-2010 David McCullough
6638+ * Copyright (C) 2004-2005 Intel Corporation.
6639+ * The license and original author are listed below.
6640+ *
6641+ * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
6642+ * All rights reserved.
6643+ *
6644+ * Redistribution and use in source and binary forms, with or without
6645+ * modification, are permitted provided that the following conditions
6646+ * are met:
6647+ * 1. Redistributions of source code must retain the above copyright
6648+ * notice, this list of conditions and the following disclaimer.
6649+ * 2. Redistributions in binary form must reproduce the above copyright
6650+ * notice, this list of conditions and the following disclaimer in the
6651+ * documentation and/or other materials provided with the distribution.
6652+ * 3. All advertising materials mentioning features or use of this software
6653+ * must display the following acknowledgement:
6654+ * This product includes software developed by Jason L. Wright
6655+ * 4. The name of the author may not be used to endorse or promote products
6656+ * derived from this software without specific prior written permission.
6657+ *
6658+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
6659+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6660+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6661+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
6662+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6663+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
6664+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
6665+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
6666+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
6667+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
6668+ * POSSIBILITY OF SUCH DAMAGE.
6669+ */
6670+
6671+#include <linux/version.h>
6672+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
6673+#include <linux/config.h>
6674+#endif
6675+#include <linux/module.h>
6676+#include <linux/list.h>
6677+#include <linux/wait.h>
6678+#include <linux/time.h>
6679+#include <linux/unistd.h>
6680+#include <linux/kernel.h>
6681+#include <linux/string.h>
6682+#include <linux/time.h>
6683+#include <cryptodev.h>
6684+#include "rndtest.h"
6685+
6686+static struct rndtest_stats rndstats;
6687+
6688+static void rndtest_test(struct rndtest_state *);
6689+
6690+/* The tests themselves */
6691+static int rndtest_monobit(struct rndtest_state *);
6692+static int rndtest_runs(struct rndtest_state *);
6693+static int rndtest_longruns(struct rndtest_state *);
6694+static int rndtest_chi_4(struct rndtest_state *);
6695+
6696+static int rndtest_runs_check(struct rndtest_state *, int, int *);
6697+static void rndtest_runs_record(struct rndtest_state *, int, int *);
6698+
6699+static const struct rndtest_testfunc {
6700+ int (*test)(struct rndtest_state *);
6701+} rndtest_funcs[] = {
6702+ { rndtest_monobit },
6703+ { rndtest_runs },
6704+ { rndtest_chi_4 },
6705+ { rndtest_longruns },
6706+};
6707+
6708+#define RNDTEST_NTESTS (sizeof(rndtest_funcs)/sizeof(rndtest_funcs[0]))
6709+
6710+static void
6711+rndtest_test(struct rndtest_state *rsp)
6712+{
6713+ int i, rv = 0;
6714+
6715+ rndstats.rst_tests++;
6716+ for (i = 0; i < RNDTEST_NTESTS; i++)
6717+ rv |= (*rndtest_funcs[i].test)(rsp);
6718+ rsp->rs_discard = (rv != 0);
6719+}
6720+
6721+
6722+extern int crypto_debug;
6723+#define rndtest_verbose 2
6724+#define rndtest_report(rsp, failure, fmt, a...) \
6725+ { if (failure || crypto_debug) { printk("rng_test: " fmt "\n", a); } else; }
6726+
6727+#define RNDTEST_MONOBIT_MINONES 9725
6728+#define RNDTEST_MONOBIT_MAXONES 10275
6729+
6730+static int
6731+rndtest_monobit(struct rndtest_state *rsp)
6732+{
6733+ int i, ones = 0, j;
6734+ u_int8_t r;
6735+
6736+ for (i = 0; i < RNDTEST_NBYTES; i++) {
6737+ r = rsp->rs_buf[i];
6738+ for (j = 0; j < 8; j++, r <<= 1)
6739+ if (r & 0x80)
6740+ ones++;
6741+ }
6742+ if (ones > RNDTEST_MONOBIT_MINONES &&
6743+ ones < RNDTEST_MONOBIT_MAXONES) {
6744+ if (rndtest_verbose > 1)
6745+ rndtest_report(rsp, 0, "monobit pass (%d < %d < %d)",
6746+ RNDTEST_MONOBIT_MINONES, ones,
6747+ RNDTEST_MONOBIT_MAXONES);
6748+ return (0);
6749+ } else {
6750+ if (rndtest_verbose)
6751+ rndtest_report(rsp, 1,
6752+ "monobit failed (%d ones)", ones);
6753+ rndstats.rst_monobit++;
6754+ return (-1);
6755+ }
6756+}
6757+
6758+#define RNDTEST_RUNS_NINTERVAL 6
6759+
6760+static const struct rndtest_runs_tabs {
6761+ u_int16_t min, max;
6762+} rndtest_runs_tab[] = {
6763+ { 2343, 2657 },
6764+ { 1135, 1365 },
6765+ { 542, 708 },
6766+ { 251, 373 },
6767+ { 111, 201 },
6768+ { 111, 201 },
6769+};
6770+
6771+static int
6772+rndtest_runs(struct rndtest_state *rsp)
6773+{
6774+ int i, j, ones, zeros, rv = 0;
6775+ int onei[RNDTEST_RUNS_NINTERVAL], zeroi[RNDTEST_RUNS_NINTERVAL];
6776+ u_int8_t c;
6777+
6778+ bzero(onei, sizeof(onei));
6779+ bzero(zeroi, sizeof(zeroi));
6780+ ones = zeros = 0;
6781+ for (i = 0; i < RNDTEST_NBYTES; i++) {
6782+ c = rsp->rs_buf[i];
6783+ for (j = 0; j < 8; j++, c <<= 1) {
6784+ if (c & 0x80) {
6785+ ones++;
6786+ rndtest_runs_record(rsp, zeros, zeroi);
6787+ zeros = 0;
6788+ } else {
6789+ zeros++;
6790+ rndtest_runs_record(rsp, ones, onei);
6791+ ones = 0;
6792+ }
6793+ }
6794+ }
6795+ rndtest_runs_record(rsp, ones, onei);
6796+ rndtest_runs_record(rsp, zeros, zeroi);
6797+
6798+ rv |= rndtest_runs_check(rsp, 0, zeroi);
6799+ rv |= rndtest_runs_check(rsp, 1, onei);
6800+
6801+ if (rv)
6802+ rndstats.rst_runs++;
6803+
6804+ return (rv);
6805+}
6806+
6807+static void
6808+rndtest_runs_record(struct rndtest_state *rsp, int len, int *intrv)
6809+{
6810+ if (len == 0)
6811+ return;
6812+ if (len > RNDTEST_RUNS_NINTERVAL)
6813+ len = RNDTEST_RUNS_NINTERVAL;
6814+ len -= 1;
6815+ intrv[len]++;
6816+}
6817+
6818+static int
6819+rndtest_runs_check(struct rndtest_state *rsp, int val, int *src)
6820+{
6821+ int i, rv = 0;
6822+
6823+ for (i = 0; i < RNDTEST_RUNS_NINTERVAL; i++) {
6824+ if (src[i] < rndtest_runs_tab[i].min ||
6825+ src[i] > rndtest_runs_tab[i].max) {
6826+ rndtest_report(rsp, 1,
6827+ "%s interval %d failed (%d, %d-%d)",
6828+ val ? "ones" : "zeros",
6829+ i + 1, src[i], rndtest_runs_tab[i].min,
6830+ rndtest_runs_tab[i].max);
6831+ rv = -1;
6832+ } else {
6833+ rndtest_report(rsp, 0,
6834+ "runs pass %s interval %d (%d < %d < %d)",
6835+ val ? "ones" : "zeros",
6836+ i + 1, rndtest_runs_tab[i].min, src[i],
6837+ rndtest_runs_tab[i].max);
6838+ }
6839+ }
6840+ return (rv);
6841+}
6842+
6843+static int
6844+rndtest_longruns(struct rndtest_state *rsp)
6845+{
6846+ int i, j, ones = 0, zeros = 0, maxones = 0, maxzeros = 0;
6847+ u_int8_t c;
6848+
6849+ for (i = 0; i < RNDTEST_NBYTES; i++) {
6850+ c = rsp->rs_buf[i];
6851+ for (j = 0; j < 8; j++, c <<= 1) {
6852+ if (c & 0x80) {
6853+ zeros = 0;
6854+ ones++;
6855+ if (ones > maxones)
6856+ maxones = ones;
6857+ } else {
6858+ ones = 0;
6859+ zeros++;
6860+ if (zeros > maxzeros)
6861+ maxzeros = zeros;
6862+ }
6863+ }
6864+ }
6865+
6866+ if (maxones < 26 && maxzeros < 26) {
6867+ rndtest_report(rsp, 0, "longruns pass (%d ones, %d zeros)",
6868+ maxones, maxzeros);
6869+ return (0);
6870+ } else {
6871+ rndtest_report(rsp, 1, "longruns fail (%d ones, %d zeros)",
6872+ maxones, maxzeros);
6873+ rndstats.rst_longruns++;
6874+ return (-1);
6875+ }
6876+}
6877+
6878+/*
6879+ * chi^2 test over 4 bits: (this is called the poker test in FIPS 140-2,
6880+ * but it is really the chi^2 test over 4 bits (the poker test as described
6881+ * by Knuth vol 2 is something different, and I take him as authoritative
6882+ * on nomenclature over NIST).
6883+ */
6884+#define RNDTEST_CHI4_K 16
6885+#define RNDTEST_CHI4_K_MASK (RNDTEST_CHI4_K - 1)
6886+
6887+/*
6888+ * The unnormalized values are used so that we don't have to worry about
6889+ * fractional precision. The "real" value is found by:
6890+ * (V - 1562500) * (16 / 5000) = Vn (where V is the unnormalized value)
6891+ */
6892+#define RNDTEST_CHI4_VMIN 1563181 /* 2.1792 */
6893+#define RNDTEST_CHI4_VMAX 1576929 /* 46.1728 */
6894+
6895+static int
6896+rndtest_chi_4(struct rndtest_state *rsp)
6897+{
6898+ unsigned int freq[RNDTEST_CHI4_K], i, sum;
6899+
6900+ for (i = 0; i < RNDTEST_CHI4_K; i++)
6901+ freq[i] = 0;
6902+
6903+ /* Get number of occurances of each 4 bit pattern */
6904+ for (i = 0; i < RNDTEST_NBYTES; i++) {
6905+ freq[(rsp->rs_buf[i] >> 4) & RNDTEST_CHI4_K_MASK]++;
6906+ freq[(rsp->rs_buf[i] >> 0) & RNDTEST_CHI4_K_MASK]++;
6907+ }
6908+
6909+ for (i = 0, sum = 0; i < RNDTEST_CHI4_K; i++)
6910+ sum += freq[i] * freq[i];
6911+
6912+ if (sum >= 1563181 && sum <= 1576929) {
6913+ rndtest_report(rsp, 0, "chi^2(4): pass (sum %u)", sum);
6914+ return (0);
6915+ } else {
6916+ rndtest_report(rsp, 1, "chi^2(4): failed (sum %u)", sum);
6917+ rndstats.rst_chi++;
6918+ return (-1);
6919+ }
6920+}
6921+
6922+int
6923+rndtest_buf(unsigned char *buf)
6924+{
6925+ struct rndtest_state rsp;
6926+
6927+ memset(&rsp, 0, sizeof(rsp));
6928+ rsp.rs_buf = buf;
6929+ rndtest_test(&rsp);
6930+ return(rsp.rs_discard);
6931+}
6932+
6933diff --git a/crypto/ocf/rndtest.h b/crypto/ocf/rndtest.h
6934new file mode 100644
6935index 0000000..e9d8ec8
6936--- /dev/null
6937+++ b/crypto/ocf/rndtest.h
6938@@ -0,0 +1,54 @@
6939+/* $FreeBSD: src/sys/dev/rndtest/rndtest.h,v 1.1 2003/03/11 22:54:44 sam Exp $ */
6940+/* $OpenBSD$ */
6941+
6942+/*
6943+ * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
6944+ * All rights reserved.
6945+ *
6946+ * Redistribution and use in source and binary forms, with or without
6947+ * modification, are permitted provided that the following conditions
6948+ * are met:
6949+ * 1. Redistributions of source code must retain the above copyright
6950+ * notice, this list of conditions and the following disclaimer.
6951+ * 2. Redistributions in binary form must reproduce the above copyright
6952+ * notice, this list of conditions and the following disclaimer in the
6953+ * documentation and/or other materials provided with the distribution.
6954+ * 3. All advertising materials mentioning features or use of this software
6955+ * must display the following acknowledgement:
6956+ * This product includes software developed by Jason L. Wright
6957+ * 4. The name of the author may not be used to endorse or promote products
6958+ * derived from this software without specific prior written permission.
6959+ *
6960+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
6961+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6962+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6963+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
6964+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6965+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
6966+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
6967+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
6968+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
6969+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
6970+ * POSSIBILITY OF SUCH DAMAGE.
6971+ */
6972+
6973+
6974+/* Some of the tests depend on these values */
6975+#define RNDTEST_NBYTES 2500
6976+#define RNDTEST_NBITS (8 * RNDTEST_NBYTES)
6977+
6978+struct rndtest_state {
6979+ int rs_discard; /* discard/accept random data */
6980+ u_int8_t *rs_buf;
6981+};
6982+
6983+struct rndtest_stats {
6984+ u_int32_t rst_discard; /* number of bytes discarded */
6985+ u_int32_t rst_tests; /* number of test runs */
6986+ u_int32_t rst_monobit; /* monobit test failures */
6987+ u_int32_t rst_runs; /* 0/1 runs failures */
6988+ u_int32_t rst_longruns; /* longruns failures */
6989+ u_int32_t rst_chi; /* chi^2 failures */
6990+};
6991+
6992+extern int rndtest_buf(unsigned char *buf);
6993diff --git a/crypto/ocf/uio.h b/crypto/ocf/uio.h
6994new file mode 100644
6995index 0000000..03a6249
6996--- /dev/null
6997+++ b/crypto/ocf/uio.h
6998@@ -0,0 +1,54 @@
6999+#ifndef _OCF_UIO_H_
7000+#define _OCF_UIO_H_
7001+
7002+#include <linux/uio.h>
7003+
7004+/*
7005+ * The linux uio.h doesn't have all we need. To be fully api compatible
7006+ * with the BSD cryptodev, we need to keep this around. Perhaps this can
7007+ * be moved back into the linux/uio.h
7008+ *
7009+ * Linux port done by David McCullough <david_mccullough@mcafee.com>
7010+ * Copyright (C) 2006-2010 David McCullough
7011+ * Copyright (C) 2004-2005 Intel Corporation.
7012+ *
7013+ * LICENSE TERMS
7014+ *
7015+ * The free distribution and use of this software in both source and binary
7016+ * form is allowed (with or without changes) provided that:
7017+ *
7018+ * 1. distributions of this source code include the above copyright
7019+ * notice, this list of conditions and the following disclaimer;
7020+ *
7021+ * 2. distributions in binary form include the above copyright
7022+ * notice, this list of conditions and the following disclaimer
7023+ * in the documentation and/or other associated materials;
7024+ *
7025+ * 3. the copyright holder's name is not used to endorse products
7026+ * built using this software without specific written permission.
7027+ *
7028+ * ALTERNATIVELY, provided that this notice is retained in full, this product
7029+ * may be distributed under the terms of the GNU General Public License (GPL),
7030+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
7031+ *
7032+ * DISCLAIMER
7033+ *
7034+ * This software is provided 'as is' with no explicit or implied warranties
7035+ * in respect of its properties, including, but not limited to, correctness
7036+ * and/or fitness for purpose.
7037+ * ---------------------------------------------------------------------------
7038+ */
7039+
7040+struct uio {
7041+ struct iovec *uio_iov;
7042+ int uio_iovcnt;
7043+ off_t uio_offset;
7044+ int uio_resid;
7045+#if 0
7046+ enum uio_seg uio_segflg;
7047+ enum uio_rw uio_rw;
7048+ struct thread *uio_td;
7049+#endif
7050+};
7051+
7052+#endif
7053diff --git a/drivers/char/random.c b/drivers/char/random.c
7054index 6035ab8..8c3acdf 100644
7055--- a/drivers/char/random.c
7056+++ b/drivers/char/random.c
7057@@ -130,6 +130,9 @@
7058 * void add_interrupt_randomness(int irq);
7059 * void add_disk_randomness(struct gendisk *disk);
7060 *
7061+ * void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
7062+ * int random_input_wait(void);
7063+ *
7064 * add_input_randomness() uses the input layer interrupt timing, as well as
7065 * the event type information from the hardware.
7066 *
7067@@ -147,6 +150,13 @@
7068 * seek times do not make for good sources of entropy, as their seek
7069 * times are usually fairly consistent.
7070 *
7071+ * random_input_words() just provides a raw block of entropy to the input
7072+ * pool, such as from a hardware entropy generator.
7073+ *
7074+ * random_input_wait() suspends the caller until such time as the
7075+ * entropy pool falls below the write threshold, and returns a count of how
7076+ * much entropy (in bits) is needed to sustain the pool.
7077+ *
7078 * All of these routines try to estimate how many bits of randomness a
7079 * particular randomness source. They do this by keeping track of the
7080 * first and second order deltas of the event timings.
7081@@ -722,6 +732,63 @@ void add_disk_randomness(struct gendisk *disk)
7082 }
7083 #endif
7084
7085+/*
7086+ * random_input_words - add bulk entropy to pool
7087+ *
7088+ * @buf: buffer to add
7089+ * @wordcount: number of __u32 words to add
7090+ * @ent_count: total amount of entropy (in bits) to credit
7091+ *
7092+ * this provides bulk input of entropy to the input pool
7093+ *
7094+ */
7095+void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
7096+{
7097+ mix_pool_bytes(&input_pool, buf, wordcount*4);
7098+
7099+ credit_entropy_bits(&input_pool, ent_count);
7100+
7101+ DEBUG_ENT("crediting %d bits => %d\n",
7102+ ent_count, input_pool.entropy_count);
7103+ /*
7104+ * Wake up waiting processes if we have enough
7105+ * entropy.
7106+ */
7107+ if (input_pool.entropy_count >= random_read_wakeup_thresh)
7108+ wake_up_interruptible(&random_read_wait);
7109+}
7110+EXPORT_SYMBOL(random_input_words);
7111+
7112+/*
7113+ * random_input_wait - wait until random needs entropy
7114+ *
7115+ * this function sleeps until the /dev/random subsystem actually
7116+ * needs more entropy, and then return the amount of entropy
7117+ * that it would be nice to have added to the system.
7118+ */
7119+int random_input_wait(void)
7120+{
7121+ int count;
7122+
7123+ wait_event_interruptible(random_write_wait,
7124+ input_pool.entropy_count < random_write_wakeup_thresh);
7125+
7126+ count = random_write_wakeup_thresh - input_pool.entropy_count;
7127+
7128+ /* likely we got woken up due to a signal */
7129+ if (count <= 0) count = random_read_wakeup_thresh;
7130+
7131+ DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
7132+ count,
7133+ input_pool.entropy_count, random_write_wakeup_thresh);
7134+
7135+ return count;
7136+}
7137+EXPORT_SYMBOL(random_input_wait);
7138+
7139+
7140+#define EXTRACT_SIZE 10
7141+
7142 /*********************************************************************
7143 *
7144 * Entropy extraction routines
7145diff --git a/fs/fcntl.c b/fs/fcntl.c
7146index 22764c7..0ffe61f 100644
7147--- a/fs/fcntl.c
7148+++ b/fs/fcntl.c
7149@@ -142,6 +142,7 @@ SYSCALL_DEFINE1(dup, unsigned int, fildes)
7150 }
7151 return ret;
7152 }
7153+EXPORT_SYMBOL(sys_dup);
7154
7155 #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
7156
7157diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
7158index c41d727..24b73c0 100644
7159--- a/include/linux/miscdevice.h
7160+++ b/include/linux/miscdevice.h
7161@@ -19,6 +19,7 @@
7162 #define APOLLO_MOUSE_MINOR 7
7163 #define PC110PAD_MINOR 9
7164 /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
7165+#define CRYPTODEV_MINOR 70 /* /dev/crypto */
7166 #define WATCHDOG_MINOR 130 /* Watchdog timer */
7167 #define TEMP_MINOR 131 /* Temperature Sensor */
7168 #define RTC_MINOR 135
7169diff --git a/include/linux/random.h b/include/linux/random.h
7170index 8f74538..0ff31a9 100644
7171--- a/include/linux/random.h
7172+++ b/include/linux/random.h
7173@@ -34,6 +34,30 @@
7174 /* Clear the entropy pool and associated counters. (Superuser only.) */
7175 #define RNDCLEARPOOL _IO( 'R', 0x06 )
7176
7177+#ifdef CONFIG_FIPS_RNG
7178+
7179+/* Size of seed value - equal to AES blocksize */
7180+#define AES_BLOCK_SIZE_BYTES 16
7181+#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
7182+/* Size of AES key */
7183+#define KEY_SIZE_BYTES 16
7184+
7185+/* ioctl() structure used by FIPS 140-2 Tests */
7186+struct rand_fips_test {
7187+ unsigned char key[KEY_SIZE_BYTES]; /* Input */
7188+ unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
7189+ unsigned char seed[SEED_SIZE_BYTES]; /* Input */
7190+ unsigned char result[SEED_SIZE_BYTES]; /* Output */
7191+};
7192+
7193+/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
7194+#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
7195+
7196+/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
7197+#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
7198+
7199+#endif /* #ifdef CONFIG_FIPS_RNG */
7200+
7201 struct rand_pool_info {
7202 int entropy_count;
7203 int buf_size;
7204@@ -54,6 +78,10 @@ extern void add_input_randomness(unsigned int type, unsigned int code,
7205 unsigned int value);
7206 extern void add_interrupt_randomness(int irq);
7207
7208+extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
7209+extern int random_input_wait(void);
7210+#define HAS_RANDOM_INPUT_WAIT 1
7211+
7212 extern void get_random_bytes(void *buf, int nbytes);
7213 void generate_random_uuid(unsigned char uuid_out[16]);
7214
7215diff --git a/kernel/pid.c b/kernel/pid.c
7216index fa5f722..2bf49fd 100644
7217--- a/kernel/pid.c
7218+++ b/kernel/pid.c
7219@@ -428,6 +428,7 @@ struct task_struct *find_task_by_vpid(pid_t vnr)
7220 {
7221 return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
7222 }
7223+EXPORT_SYMBOL(find_task_by_vpid);
7224
7225 struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
7226 {
7227--
72281.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-am335x-Add-suspend-resume-routines-to-crypto-driver.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-am335x-Add-suspend-resume-routines-to-crypto-driver.patch
new file mode 100644
index 00000000..6066c0a5
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-am335x-Add-suspend-resume-routines-to-crypto-driver.patch
@@ -0,0 +1,147 @@
1From 0fb328ec0a5ba8a1440336c8dc7a029cfffa4529 Mon Sep 17 00:00:00 2001
2From: Greg Turner <gregturner@ti.com>
3Date: Thu, 19 Jul 2012 15:27:59 -0500
4Subject: [PATCH 2/2] [am335x]: Add suspend resume routines to crypto driver
5
6* Add suspend resume routines to AES crypto driver
7* Add suspend resume routines to SHA crypto driver
8* Cleaned up some build warnings
9---
10 drivers/crypto/omap4-aes.c | 31 ++++++++++++++++++++++++++++---
11 drivers/crypto/omap4-sham.c | 32 +++++++++++++++++++++++++++-----
12 2 files changed, 55 insertions(+), 8 deletions(-)
13
14diff --git a/drivers/crypto/omap4-aes.c b/drivers/crypto/omap4-aes.c
15index 76f988a..c7d08df 100755
16--- a/drivers/crypto/omap4-aes.c
17+++ b/drivers/crypto/omap4-aes.c
18@@ -878,9 +878,9 @@ err_io:
19 udelay(1);
20
21
22-err_res:
23- kfree(dd);
24- dd = NULL;
25+//err_res:
26+ //kfree(dd);
27+ //dd = NULL;
28 err_data:
29 dev_err(dev, "initialization failed.\n");
30 return err;
31@@ -916,12 +916,35 @@ static int omap4_aes_remove(struct platform_device *pdev)
32 return 0;
33 }
34
35+static int omap4_aes_suspend(struct device *dev)
36+{
37+ pr_debug("#### Crypto: Suspend call ####\n");
38+
39+ return 0;
40+}
41+
42+
43+static int omap4_aes_resume(struct device *dev)
44+{
45+ pr_debug("#### Crypto: resume call ####\n");
46+
47+ return 0;
48+}
49+
50+static struct dev_pm_ops omap4_aes_dev_pm_ops = {
51+ .suspend = omap4_aes_suspend,
52+ .resume = omap4_aes_resume,
53+ .runtime_suspend = omap4_aes_suspend,
54+ .runtime_resume = omap4_aes_resume,
55+};
56+
57 static struct platform_driver omap4_aes_driver = {
58 .probe = omap4_aes_probe,
59 .remove = omap4_aes_remove,
60 .driver = {
61 .name = "omap4-aes",
62 .owner = THIS_MODULE,
63+ .pm = &omap4_aes_dev_pm_ops
64 },
65 };
66
67@@ -944,6 +967,8 @@ static void __exit omap4_aes_mod_exit(void)
68 platform_driver_unregister(&omap4_aes_driver);
69 }
70
71+
72+
73 module_init(omap4_aes_mod_init);
74 module_exit(omap4_aes_mod_exit);
75
76diff --git a/drivers/crypto/omap4-sham.c b/drivers/crypto/omap4-sham.c
77index 21f1b48..2fb71b9 100755
78--- a/drivers/crypto/omap4-sham.c
79+++ b/drivers/crypto/omap4-sham.c
80@@ -239,7 +239,7 @@ static void omap4_sham_copy_ready_hash(struct ahash_request *req)
81 struct omap4_sham_reqctx *ctx = ahash_request_ctx(req);
82 u32 *in = (u32 *)ctx->digest;
83 u32 *hash = (u32 *)req->result;
84- int i, d;
85+ int i, d = 0;
86
87 if (!hash)
88 return;
89@@ -1224,8 +1224,6 @@ static void omap4_sham_dma_callback(unsigned int lch, u16 ch_status, void *data)
90
91 static int omap4_sham_dma_init(struct omap4_sham_dev *dd)
92 {
93- int err;
94-
95 dd->dma_lch = -1;
96
97 dd->dma_lch = edma_alloc_channel(dd->dma, omap4_sham_dma_callback, dd, EVENTQ_2);
98@@ -1349,8 +1347,9 @@ io_err:
99 pm_runtime_disable(dev);
100 udelay(1);
101
102-clk_err:
103- omap4_sham_dma_cleanup(dd);
104+//clk_err:
105+// omap4_sham_dma_cleanup(dd);
106+
107 dma_err:
108 if (dd->irq >= 0)
109 free_irq(dd->irq, dd);
110@@ -1392,12 +1391,35 @@ static int __devexit omap4_sham_remove(struct platform_device *pdev)
111 return 0;
112 }
113
114+static int omap4_sham_suspend(struct device *dev)
115+{
116+ pr_debug("#### Crypto: Suspend call ####\n");
117+
118+ return 0;
119+}
120+
121+
122+static int omap4_sham_resume(struct device *dev)
123+{
124+ pr_debug("#### Crypto: resume call ####\n");
125+
126+ return 0;
127+}
128+
129+static struct dev_pm_ops omap4_sham_dev_pm_ops = {
130+ .suspend = omap4_sham_suspend,
131+ .resume = omap4_sham_resume,
132+ .runtime_suspend = omap4_sham_suspend,
133+ .runtime_resume = omap4_sham_resume,
134+};
135+
136 static struct platform_driver omap4_sham_driver = {
137 .probe = omap4_sham_probe,
138 .remove = omap4_sham_remove,
139 .driver = {
140 .name = "omap4-sham",
141 .owner = THIS_MODULE,
142+ .pm = &omap4_sham_dev_pm_ops
143 },
144 };
145
146--
1471.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-am33x-Add-crypto-device-and-resource-structures.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-am33x-Add-crypto-device-and-resource-structures.patch
new file mode 100644
index 00000000..eb0223c3
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-am33x-Add-crypto-device-and-resource-structures.patch
@@ -0,0 +1,111 @@
1From 8c0f7553e75774849463f90b0135874754650386 Mon Sep 17 00:00:00 2001
2From: Greg Turner <gregturner@ti.com>
3Date: Thu, 17 May 2012 14:45:05 -0500
4Subject: [PATCH 2/8] am33x: Add crypto device and resource structures
5
6* Add platform device and resource structures to devices.c
7* Structures are for the AES and SHA/MD5 crypto modules
8* Used in the OMAP4 crypto driver
9
10Signed-off-by: Greg Turner <gregturner@ti.com>
11---
12 arch/arm/mach-omap2/devices.c | 67 +++++++++++++++++++++++++++++++++++++++++
13 1 files changed, 67 insertions(+), 0 deletions(-)
14 mode change 100644 => 100755 arch/arm/mach-omap2/devices.c
15
16diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
17old mode 100644
18new mode 100755
19index 9e029da..5c6e3e2
20--- a/arch/arm/mach-omap2/devices.c
21+++ b/arch/arm/mach-omap2/devices.c
22@@ -47,6 +47,7 @@
23 #include <plat/omap_hwmod.h>
24 #include <plat/omap_device.h>
25 #include <plat/omap4-keypad.h>
26+#include <plat/am33xx.h>
27 #include <plat/config_pwm.h>
28 #include <plat/cpu.h>
29 #include <plat/gpmc.h>
30@@ -702,6 +703,41 @@ static void omap_init_sham(void)
31 }
32 platform_device_register(&sham_device);
33 }
34+
35+#elif defined(CONFIG_CRYPTO_DEV_OMAP4_SHAM) || defined(CONFIG_CRYPTO_DEV_OMAP4_SHAM_MODULE)
36+
37+static struct resource omap4_sham_resources[] = {
38+ {
39+ .start = AM33XX_SHA1MD5_P_BASE,
40+ .end = AM33XX_SHA1MD5_P_BASE + 0x120,
41+ .flags = IORESOURCE_MEM,
42+ },
43+ {
44+ .start = AM33XX_IRQ_SHAEIP57t0_P,
45+ .flags = IORESOURCE_IRQ,
46+ },
47+ {
48+ .start = AM33XX_DMA_SHAEIP57T0_DIN,
49+ .flags = IORESOURCE_DMA,
50+ }
51+};
52+
53+static int omap4_sham_resources_sz = ARRAY_SIZE(omap4_sham_resources);
54+
55+
56+static struct platform_device sham_device = {
57+ .name = "omap4-sham",
58+ .id = -1,
59+};
60+
61+static void omap_init_sham(void)
62+{
63+ sham_device.resource = omap4_sham_resources;
64+ sham_device.num_resources = omap4_sham_resources_sz;
65+
66+ platform_device_register(&sham_device);
67+}
68+
69 #else
70 static inline void omap_init_sham(void) { }
71 #endif
72@@ -772,6 +808,37 @@ static void omap_init_aes(void)
73 platform_device_register(&aes_device);
74 }
75
76+#elif defined(CONFIG_CRYPTO_DEV_OMAP4_AES) || defined(CONFIG_CRYPTO_DEV_OMAP4_AES_MODULE)
77+
78+static struct resource omap4_aes_resources[] = {
79+ {
80+ .start = AM33XX_AES0_P_BASE,
81+ .end = AM33XX_AES0_P_BASE + 0x4C,
82+ .flags = IORESOURCE_MEM,
83+ },
84+ {
85+ .start = AM33XX_DMA_AESEIP36T0_DOUT,
86+ .flags = IORESOURCE_DMA,
87+ },
88+ {
89+ .start = AM33XX_DMA_AESEIP36T0_DIN,
90+ .flags = IORESOURCE_DMA,
91+ }
92+};
93+static int omap4_aes_resources_sz = ARRAY_SIZE(omap4_aes_resources);
94+
95+static struct platform_device aes_device = {
96+ .name = "omap4-aes",
97+ .id = -1,
98+};
99+
100+static void omap_init_aes(void)
101+{
102+ aes_device.resource = omap4_aes_resources;
103+ aes_device.num_resources = omap4_aes_resources_sz;
104+ platform_device_register(&aes_device);
105+}
106+
107 #else
108 static inline void omap_init_aes(void) { }
109 #endif
110--
1111.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-am33xx-Enable-CONFIG_AM33XX_SMARTREFLEX.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-am33xx-Enable-CONFIG_AM33XX_SMARTREFLEX.patch
new file mode 100644
index 00000000..04e3bee4
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0002-am33xx-Enable-CONFIG_AM33XX_SMARTREFLEX.patch
@@ -0,0 +1,26 @@
1From e1b7a67fc82991a633f0ed615d69157c98c1c35d Mon Sep 17 00:00:00 2001
2From: Greg Guyotte <gguyotte@ti.com>
3Date: Thu, 7 Jun 2012 18:15:21 -0500
4Subject: [PATCH 2/2] am33xx: Enable CONFIG_AM33XX_SMARTREFLEX
5
6Simply enables the SmartReflex driver in the defconfig file.
7
8Signed-off-by: Greg Guyotte <gguyotte@ti.com>
9---
10 arch/arm/configs/am335x_evm_defconfig | 1 +
11 1 files changed, 1 insertions(+), 0 deletions(-)
12
13diff --git a/arch/arm/configs/am335x_evm_defconfig b/arch/arm/configs/am335x_evm_defconfig
14index de1eaad..ce5d1d6 100644
15--- a/arch/arm/configs/am335x_evm_defconfig
16+++ b/arch/arm/configs/am335x_evm_defconfig
17@@ -269,6 +269,7 @@ CONFIG_ARCH_OMAP2PLUS=y
18 # OMAP Feature Selections
19 #
20 # CONFIG_OMAP_SMARTREFLEX is not set
21+CONFIG_AM33XX_SMARTREFLEX=y
22 CONFIG_OMAP_RESET_CLOCKS=y
23 CONFIG_OMAP_MUX=y
24 CONFIG_OMAP_MUX_DEBUG=y
25--
261.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0003-am33x-Add-crypto-device-and-resource-structure-for-T.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0003-am33x-Add-crypto-device-and-resource-structure-for-T.patch
new file mode 100644
index 00000000..def61d56
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0003-am33x-Add-crypto-device-and-resource-structure-for-T.patch
@@ -0,0 +1,60 @@
1From b7477dd40221a91af286bffa110879075a498943 Mon Sep 17 00:00:00 2001
2From: Greg Turner <gregturner@ti.com>
3Date: Thu, 17 May 2012 14:49:39 -0500
4Subject: [PATCH 3/8] am33x: Add crypto device and resource structure for TRNG
5
6* Add platform device and resource structure to devices.c
7* Structures are for the TRNG crypto module
8* Used in the OMAP4 crypto driver
9
10Signed-off-by: Greg Turner <gregturner@ti.com>
11---
12 arch/arm/plat-omap/devices.c | 23 +++++++++++++++++++++++
13 1 files changed, 23 insertions(+), 0 deletions(-)
14 mode change 100644 => 100755 arch/arm/plat-omap/devices.c
15
16diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
17old mode 100644
18new mode 100755
19index 1971932..52720b4
20--- a/arch/arm/plat-omap/devices.c
21+++ b/arch/arm/plat-omap/devices.c
22@@ -26,6 +26,7 @@
23 #include <plat/mmc.h>
24 #include <plat/menelaus.h>
25 #include <plat/omap44xx.h>
26+#include <plat/am33xx.h>
27
28 #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
29 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
30@@ -104,6 +105,28 @@ static void omap_init_rng(void)
31 {
32 (void) platform_device_register(&omap_rng_device);
33 }
34+#elif defined(CONFIG_HW_RANDOM_OMAP4) || defined(CONFIG_HW_RANDOM_OMAP4_MODULE)
35+
36+static struct resource rng_resources[] = {
37+ {
38+ .start = AM33XX_RNG_BASE,
39+ .end = AM33XX_RNG_BASE + 0x1FFC,
40+ .flags = IORESOURCE_MEM,
41+ },
42+};
43+
44+static struct platform_device omap4_rng_device = {
45+ .name = "omap4_rng",
46+ .id = -1,
47+ .num_resources = ARRAY_SIZE(rng_resources),
48+ .resource = rng_resources,
49+};
50+
51+static void omap_init_rng(void)
52+{
53+ (void) platform_device_register(&omap4_rng_device);
54+}
55+
56 #else
57 static inline void omap_init_rng(void) {}
58 #endif
59--
601.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0004-am33x-Add-crypto-drivers-to-Kconfig-and-Makefiles.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0004-am33x-Add-crypto-drivers-to-Kconfig-and-Makefiles.patch
new file mode 100644
index 00000000..31d83630
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0004-am33x-Add-crypto-drivers-to-Kconfig-and-Makefiles.patch
@@ -0,0 +1,124 @@
1From e49e6dcff5665cb2f132d9654a060fa43a382810 Mon Sep 17 00:00:00 2001
2From: Greg Turner <gregturner@ti.com>
3Date: Thu, 17 May 2012 14:53:25 -0500
4Subject: [PATCH 4/8] am33x: Add crypto drivers to Kconfig and Makefiles
5
6* Add OMAP4 TRNG driver to hw_random Kconfig and Makefile
7* Add OMAP4 AES and SHA/MD5 driver to crypto Kconfig and Makefile
8* Needed so that drivers can be selected during kernel config
9
10Signed-off-by: Greg Turner <gregturner@ti.com>
11---
12 drivers/char/hw_random/Kconfig | 13 +++++++++++++
13 drivers/char/hw_random/Makefile | 1 +
14 drivers/crypto/Kconfig | 22 ++++++++++++++++++++--
15 drivers/crypto/Makefile | 2 ++
16 4 files changed, 36 insertions(+), 2 deletions(-)
17 mode change 100644 => 100755 drivers/char/hw_random/Kconfig
18 mode change 100644 => 100755 drivers/char/hw_random/Makefile
19 mode change 100644 => 100755 drivers/crypto/Kconfig
20 mode change 100644 => 100755 drivers/crypto/Makefile
21
22diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
23old mode 100644
24new mode 100755
25index 0689bf6..207e3e7
26--- a/drivers/char/hw_random/Kconfig
27+++ b/drivers/char/hw_random/Kconfig
28@@ -139,6 +139,19 @@ config HW_RANDOM_OMAP
29
30 If unsure, say Y.
31
32+config HW_RANDOM_OMAP4
33+ tristate "OMAP4 Random Number Generator support"
34+ depends on HW_RANDOM && SOC_OMAPAM33XX
35+ default HW_RANDOM
36+ ---help---
37+ This driver provides kernel-side support for the Random Number
38+ Generator hardware found on OMAP4 derived processors.
39+
40+ To compile this driver as a module, choose M here: the
41+ module will be called omap4-rng.
42+
43+ If unsure, say Y.
44+
45 config HW_RANDOM_OCTEON
46 tristate "Octeon Random Number Generator support"
47 depends on HW_RANDOM && CPU_CAVIUM_OCTEON
48diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
49old mode 100644
50new mode 100755
51index b2ff526..fecced0
52--- a/drivers/char/hw_random/Makefile
53+++ b/drivers/char/hw_random/Makefile
54@@ -14,6 +14,7 @@ n2-rng-y := n2-drv.o n2-asm.o
55 obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o
56 obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
57 obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
58+obj-$(CONFIG_HW_RANDOM_OMAP4) += omap4-rng.o
59 obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
60 obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
61 obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
62diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
63old mode 100644
64new mode 100755
65index 6d16b4b..6c1331a
66--- a/drivers/crypto/Kconfig
67+++ b/drivers/crypto/Kconfig
68@@ -250,7 +250,7 @@ config CRYPTO_DEV_PPC4XX
69
70 config CRYPTO_DEV_OMAP_SHAM
71 tristate "Support for OMAP SHA1/MD5 hw accelerator"
72- depends on ARCH_OMAP2 || ARCH_OMAP3
73+ depends on (ARCH_OMAP2) || (ARCH_OMAP3) && (!SOC_OMAPAM33XX)
74 select CRYPTO_SHA1
75 select CRYPTO_MD5
76 help
77@@ -259,12 +259,30 @@ config CRYPTO_DEV_OMAP_SHAM
78
79 config CRYPTO_DEV_OMAP_AES
80 tristate "Support for OMAP AES hw engine"
81- depends on ARCH_OMAP2 || ARCH_OMAP3
82+ depends on (ARCH_OMAP2) || (ARCH_OMAP3) && (!SOC_OMAPAM33XX)
83 select CRYPTO_AES
84 help
85 OMAP processors have AES module accelerator. Select this if you
86 want to use the OMAP module for AES algorithms.
87
88+config CRYPTO_DEV_OMAP4_AES
89+ tristate "Support for OMAP4 AES hw engine"
90+ depends on SOC_OMAPAM33XX
91+ select CRYPTO_AES
92+ help
93+ OMAP4 -based processors have AES module accelerators. Select this if you
94+ want to use the OMAP4 module for AES algorithms.
95+
96+config CRYPTO_DEV_OMAP4_SHAM
97+ tristate "Support for OMAP4 SHA/MD5 hw engine"
98+ depends on SOC_OMAPAM33XX
99+ select CRYPTO_SHA1
100+ select CRYPTO_SHA256
101+ select CRYPTO_MD5
102+ help
103+ OMAP4 -based processors have SHA/MD5 module accelerators. Select this if you
104+ want to use the OMAP4 module for SHA/MD5 algorithms.
105+
106 config CRYPTO_DEV_PICOXCELL
107 tristate "Support for picoXcell IPSEC and Layer2 crypto engines"
108 depends on ARCH_PICOXCELL && HAVE_CLK
109diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
110old mode 100644
111new mode 100755
112index 53ea501..5b420a5
113--- a/drivers/crypto/Makefile
114+++ b/drivers/crypto/Makefile
115@@ -11,5 +11,7 @@ obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
116 obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
117 obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
118 obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
119+obj-$(CONFIG_CRYPTO_DEV_OMAP4_AES) += omap4-aes.o
120+obj-$(CONFIG_CRYPTO_DEV_OMAP4_SHAM) += omap4-sham.o
121 obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o
122 obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
123--
1241.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0005-am33x-Create-header-file-for-OMAP4-crypto-modules.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0005-am33x-Create-header-file-for-OMAP4-crypto-modules.patch
new file mode 100644
index 00000000..94d89e53
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0005-am33x-Create-header-file-for-OMAP4-crypto-modules.patch
@@ -0,0 +1,213 @@
1From 2dc9dec7510746b3c3f5420f4f3ab8395cc7b012 Mon Sep 17 00:00:00 2001
2From: Greg Turner <gregturner@ti.com>
3Date: Thu, 17 May 2012 14:59:38 -0500
4Subject: [PATCH 5/8] am33x: Create header file for OMAP4 crypto modules
5
6* This header file defines addresses and macros used to access crypto modules on OMAP4 derivative SOC's like AM335x.
7
8Signed-off-by: Greg Turner <gregturner@ti.com>
9---
10 drivers/crypto/omap4.h | 192 ++++++++++++++++++++++++++++++++++++++++++++++++
11 1 files changed, 192 insertions(+), 0 deletions(-)
12 create mode 100644 drivers/crypto/omap4.h
13
14diff --git a/drivers/crypto/omap4.h b/drivers/crypto/omap4.h
15new file mode 100644
16index 0000000..d9d6315
17--- /dev/null
18+++ b/drivers/crypto/omap4.h
19@@ -0,0 +1,192 @@
20+/*
21+ * drivers/crypto/omap4.h
22+ *
23+ * Copyright © 2011 Texas Instruments Incorporated
24+ * Author: Greg Turner
25+ *
26+ * Adapted from Netra/Centaurus crypto driver
27+ * Copyright © 2011 Texas Instruments Incorporated
28+ * Author: Herman Schuurman
29+ *
30+ * This program is free software; you can redistribute it and/or modify
31+ * it under the terms of the GNU General Public License as published by
32+ * the Free Software Foundation; either version 2 of the License, or
33+ * (at your option) any later version.
34+ *
35+ * This program is distributed in the hope that it will be useful,
36+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
37+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38+ * GNU General Public License for more details.
39+ *
40+ * You should have received a copy of the GNU General Public License
41+ * along with this program; if not, write to the Free Software
42+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
43+ */
44+#ifndef __DRIVERS_CRYPTO_AM33X_H
45+#define __DRIVERS_CRYPTO_AM33X_H
46+
47+/* ==================================================================== */
48+/** Crypto subsystem module layout
49+ */
50+/* ==================================================================== */
51+
52+#define AM33X_AES_CLKCTRL (AM33XX_PRCM_BASE + 0x00000094)
53+#define AM33X_SHA_CLKCTRL (AM33XX_PRCM_BASE + 0x000000A0)
54+
55+#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end))
56+#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
57+
58+/* ==================================================================== */
59+/** AES module layout
60+ */
61+/* ==================================================================== */
62+
63+#define AES_REG_KEY2(x) (0x1C - ((x ^ 0x01) * 0x04))
64+#define AES_REG_KEY1(x) (0x3C - ((x ^ 0x01) * 0x04))
65+#define AES_REG_IV(x) (0x40 + ((x) * 0x04))
66+
67+#define AES_REG_CTRL 0x50
68+#define AES_REG_CTRL_CTX_RDY (1 << 31)
69+#define AES_REG_CTRL_SAVE_CTX_RDY (1 << 30)
70+#define AES_REG_CTRL_SAVE_CTX (1 << 29)
71+#define AES_REG_CTRL_CCM_M_MASK (7 << 22)
72+#define AES_REG_CTRL_CCM_M_SHFT 22
73+#define AES_REG_CTRL_CCM_L_MASK (7 << 19)
74+#define AES_REG_CTRL_CCM_L_SHFT 19
75+#define AES_REG_CTRL_CCM (1 << 18)
76+#define AES_REG_CTRL_GCM (3 << 16)
77+#define AES_REG_CTRL_CBCMAC (1 << 15)
78+#define AES_REG_CTRL_F9 (1 << 14)
79+#define AES_REG_CTRL_F8 (1 << 13)
80+#define AES_REG_CTRL_XTS_MASK (3 << 11)
81+#define AES_REG_CTRL_XTS_01 (1 << 11)
82+#define AES_REG_CTRL_XTS_10 (2 << 11)
83+#define AES_REG_CTRL_XTS_11 (3 << 11)
84+#define AES_REG_CTRL_CFB (1 << 10)
85+#define AES_REG_CTRL_ICM (1 << 9)
86+#define AES_REG_CTRL_CTR_WIDTH_MASK (3 << 7)
87+#define AES_REG_CTRL_CTR_WIDTH_32 (0 << 7)
88+#define AES_REG_CTRL_CTR_WIDTH_64 (1 << 7)
89+#define AES_REG_CTRL_CTR_WIDTH_96 (2 << 7)
90+#define AES_REG_CTRL_CTR_WIDTH_128 (3 << 7)
91+#define AES_REG_CTRL_CTR (1 << 6)
92+#define AES_REG_CTRL_CBC (1 << 5)
93+#define AES_REG_CTRL_KEY_SIZE_MASK (3 << 3)
94+#define AES_REG_CTRL_KEY_SIZE_128 (1 << 3)
95+#define AES_REG_CTRL_KEY_SIZE_192 (2 << 3)
96+#define AES_REG_CTRL_KEY_SIZE_256 (3 << 3)
97+#define AES_REG_CTRL_DIRECTION (1 << 2)
98+#define AES_REG_CTRL_INPUT_RDY (1 << 1)
99+#define AES_REG_CTRL_OUTPUT_RDY (1 << 0)
100+
101+#define AES_REG_LENGTH_N(x) (0x54 + ((x) * 0x04))
102+#define AES_REG_AUTH_LENGTH 0x5C
103+#define AES_REG_DATA 0x60
104+#define AES_REG_DATA_N(x) (0x60 + ((x) * 0x04))
105+#define AES_REG_TAG 0x70
106+#define AES_REG_TAG_N(x) (0x70 + ((x) * 0x04))
107+
108+#define AES_REG_REV 0x80
109+#define AES_REG_REV_SCHEME_MASK (3 << 30)
110+#define AES_REG_REV_FUNC_MASK (0xFFF << 16)
111+#define AES_REG_REV_R_RTL_MASK (0x1F << 11)
112+#define AES_REG_REV_X_MAJOR_MASK (7 << 8)
113+#define AES_REG_REV_CUSTOM_MASK (3 << 6)
114+#define AES_REG_REV_Y_MINOR_MASK (0x3F << 0)
115+
116+#define AES_REG_SYSCFG 0x84
117+#define AES_REG_SYSCFG_K3 (1 << 12)
118+#define AES_REG_SYSCFG_KEY_ENC (1 << 11)
119+#define AES_REG_SYSCFG_KEK_MODE (1 << 10)
120+#define AES_REG_SYSCFG_MAP_CTX_OUT (1 << 9)
121+#define AES_REG_SYSCFG_DREQ_MASK (15 << 5)
122+#define AES_REG_SYSCFG_DREQ_CTX_OUT_EN (1 << 8)
123+#define AES_REG_SYSCFG_DREQ_CTX_IN_EN (1 << 7)
124+#define AES_REG_SYSCFG_DREQ_DATA_OUT_EN (1 << 6)
125+#define AES_REG_SYSCFG_DREQ_DATA_IN_EN (1 << 5)
126+#define AES_REG_SYSCFG_DIRECTBUSEN (1 << 4)
127+#define AES_REG_SYSCFG_SIDLE_MASK (3 << 2)
128+#define AES_REG_SYSCFG_SIDLE_FORCEIDLE (0 << 2)
129+#define AES_REG_SYSCFG_SIDLE_NOIDLE (1 << 2)
130+#define AES_REG_SYSCFG_SIDLE_SMARTIDLE (2 << 2)
131+#define AES_REG_SYSCFG_SOFTRESET (1 << 1)
132+#define AES_REG_SYSCFG_AUTOIDLE (1 << 0)
133+
134+#define AES_REG_SYSSTATUS 0x88
135+#define AES_REG_SYSSTATUS_RESETDONE (1 << 0)
136+
137+#define AES_REG_IRQSTATUS 0x8C
138+#define AES_REG_IRQSTATUS_CTX_OUT (1 << 3)
139+#define AES_REG_IRQSTATUS_DATA_OUT (1 << 2)
140+#define AES_REG_IRQSTATUS_DATA_IN (1 << 1)
141+#define AES_REG_IRQSTATUS_CTX_IN (1 << 0)
142+
143+#define AES_REG_IRQENA 0x90
144+#define AES_REG_IRQENA_CTX_OUT (1 << 3)
145+#define AES_REG_IRQENA_DATA_OUT (1 << 2)
146+#define AES_REG_IRQENA_DATA_IN (1 << 1)
147+#define AES_REG_IRQENA_CTX_IN (1 << 0)
148+
149+/* ==================================================================== */
150+/** SHA / MD5 module layout.
151+ */
152+/* ==================================================================== */
153+
154+#define SHA_REG_ODIGEST 0x00
155+#define SHA_REG_ODIGEST_N(x) (0x00 + ((x) * 0x04))
156+#define SHA_REG_IDIGEST 0x20
157+#define SHA_REG_IDIGEST_N(x) (0x20 + ((x) * 0x04))
158+
159+#define SHA_REG_DIGEST_COUNT 0x40
160+#define SHA_REG_MODE 0x44
161+#define SHA_REG_MODE_HMAC_OUTER_HASH (1 << 7)
162+#define SHA_REG_MODE_HMAC_KEY_PROC (1 << 5)
163+#define SHA_REG_MODE_CLOSE_HASH (1 << 4)
164+#define SHA_REG_MODE_ALGO_CONSTANT (1 << 3)
165+#define SHA_REG_MODE_ALGO_MASK (3 << 1)
166+#define SHA_REG_MODE_ALGO_MD5_128 (0 << 1)
167+#define SHA_REG_MODE_ALGO_SHA1_160 (1 << 1)
168+#define SHA_REG_MODE_ALGO_SHA2_224 (2 << 1)
169+#define SHA_REG_MODE_ALGO_SHA2_256 (3 << 1)
170+
171+#define SHA_REG_LENGTH 0x48
172+
173+#define SHA_REG_DATA 0x80
174+#define SHA_REG_DATA_N(x) (0x80 + ((x) * 0x04))
175+
176+#define SHA_REG_REV 0x100
177+#define SHA_REG_REV_SCHEME_MASK (3 << 30)
178+#define SHA_REG_REV_FUNC_MASK (0xFFF << 16)
179+#define SHA_REG_REV_R_RTL_MASK (0x1F << 11)
180+#define SHA_REG_REV_X_MAJOR_MASK (7 << 8)
181+#define SHA_REG_REV_CUSTOM_MASK (3 << 6)
182+#define SHA_REG_REV_Y_MINOR_MASK (0x3F << 0)
183+
184+#define SHA_REG_SYSCFG 0x110
185+#define SHA_REG_SYSCFG_SADVANCED (1 << 7)
186+#define SHA_REG_SYSCFG_SCONT_SWT (1 << 6)
187+#define SHA_REG_SYSCFG_SIDLE_MASK (3 << 4)
188+#define SHA_REG_SYSCFG_SIDLE_FORCEIDLE (0 << 4)
189+#define SHA_REG_SYSCFG_SIDLE_NOIDLE (1 << 4)
190+#define SHA_REG_SYSCFG_SIDLE_SMARTIDLE (2 << 4)
191+#define SHA_REG_SYSCFG_SDMA_EN (1 << 3)
192+#define SHA_REG_SYSCFG_SIT_EN (1 << 2)
193+#define SHA_REG_SYSCFG_SOFTRESET (1 << 1)
194+#define SHA_REG_SYSCFG_AUTOIDLE (1 << 0)
195+
196+#define SHA_REG_SYSSTATUS 0x114
197+#define SHA_REG_SYSSTATUS_RESETDONE (1 << 0)
198+
199+#define SHA_REG_IRQSTATUS 0x118
200+#define SHA_REG_IRQSTATUS_CTX_RDY (1 << 3)
201+#define SHA_REG_IRQSTATUS_PARTHASH_RDY (1 << 2)
202+#define SHA_REG_IRQSTATUS_INPUT_RDY (1 << 1)
203+#define SHA_REG_IRQSTATUS_OUTPUT_RDY (1 << 0)
204+
205+#define SHA_REG_IRQENA 0x11C
206+#define SHA_REG_IRQENA_CTX_RDY (1 << 3)
207+#define SHA_REG_IRQENA_PARTHASH_RDY (1 << 2)
208+#define SHA_REG_IRQENA_INPUT_RDY (1 << 1)
209+#define SHA_REG_IRQENA_OUTPUT_RDY (1 << 0)
210+
211+#endif /* __DRIVERS_CRYPTO_AM33X_H */
212--
2131.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0006-am33x-Create-driver-for-TRNG-crypto-module.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0006-am33x-Create-driver-for-TRNG-crypto-module.patch
new file mode 100644
index 00000000..7d0023aa
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0006-am33x-Create-driver-for-TRNG-crypto-module.patch
@@ -0,0 +1,324 @@
1From d56c0ab935577ef32ffdf23a62d2e1cecc391730 Mon Sep 17 00:00:00 2001
2From: Greg Turner <gregturner@ti.com>
3Date: Thu, 17 May 2012 15:11:26 -0500
4Subject: [PATCH 6/8] am33x: Create driver for TRNG crypto module
5
6This is the initial version of the driver for the TRNG crypto module for a GP version of OMAP4 derivative SOC's such as AM335x.
7
8Signed-off-by: Greg Turner <gregturner@ti.com>
9---
10 drivers/char/hw_random/omap4-rng.c | 303 ++++++++++++++++++++++++++++++++++++
11 1 files changed, 303 insertions(+), 0 deletions(-)
12 create mode 100755 drivers/char/hw_random/omap4-rng.c
13
14diff --git a/drivers/char/hw_random/omap4-rng.c b/drivers/char/hw_random/omap4-rng.c
15new file mode 100755
16index 0000000..523ec63
17--- /dev/null
18+++ b/drivers/char/hw_random/omap4-rng.c
19@@ -0,0 +1,303 @@
20+/*
21+ * drivers/char/hw_random/omap4-rng.c
22+ *
23+ * Copyright (c) 2012 Texas Instruments
24+ * TRNG driver for OMAP4 derivatives (AM33x, etc) - Herman Schuurman <herman@ti.com>
25+ *
26+ * derived from omap-rng.c.
27+ *
28+ * Author: Deepak Saxena <dsaxena@plexity.net>
29+ *
30+ * Copyright 2005 (c) MontaVista Software, Inc.
31+ *
32+ * Mostly based on original driver:
33+ *
34+ * Copyright (C) 2005 Nokia Corporation
35+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
36+ *
37+ * This file is licensed under the terms of the GNU General Public
38+ * License version 2. This program is licensed "as is" without any
39+ * warranty of any kind, whether express or implied.
40+ */
41+
42+#include <linux/module.h>
43+#include <linux/init.h>
44+#include <linux/random.h>
45+#include <linux/clk.h>
46+#include <linux/err.h>
47+#include <linux/platform_device.h>
48+#include <linux/hw_random.h>
49+#include <linux/delay.h>
50+
51+#include <mach/hardware.h>
52+#include <asm/io.h>
53+
54+/* ==================================================================== */
55+/** RNG module layout.
56+ */
57+/* ==================================================================== */
58+#define RNG_REG_OUTPUT_L 0x00
59+#define RNG_REG_OUTPUT_H 0x04
60+
61+#define RNG_REG_STATUS 0x08
62+#define RNG_REG_STATUS_NEED_CLK (1 << 31)
63+#define RNG_REG_STATUS_SHUTDOWN_OFLO (1 << 1)
64+#define RNG_REG_STATUS_RDY (1 << 0)
65+
66+#define RNG_REG_IMASK 0x0C
67+#define RNG_REG_IMASK_SHUTDOWN_OFLO (1 << 1)
68+#define RNG_REG_IMASK_RDY (1 << 0)
69+
70+#define RNG_REG_INTACK 0x10
71+#define RNG_REG_INTACK_SHUTDOWN_OFLO (1 << 1)
72+#define RNG_REG_INTACK_RDY (1 << 0)
73+
74+#define RNG_REG_CONTROL 0x14
75+#define RNG_REG_CONTROL_STARTUP_MASK 0xFFFF0000
76+#define RNG_REG_CONTROL_ENABLE_TRNG (1 << 10)
77+#define RNG_REG_CONTROL_NO_LFSR_FB (1 << 2)
78+
79+#define RNG_REG_CONFIG 0x18
80+#define RNG_REG_CONFIG_MAX_REFILL_MASK 0xFFFF0000
81+#define RNG_REG_CONFIG_SAMPLE_DIV 0x00000F00
82+#define RNG_REG_CONFIG_MIN_REFILL_MASK 0x000000FF
83+
84+#define RNG_REG_ALARMCNT 0x1C
85+#define RNG_REG_ALARMCNT_SHTDWN_MASK 0x3F000000
86+#define RNG_REG_ALARMCNT_SD_THLD_MASK 0x001F0000
87+#define RNG_REG_ALARMCNT_ALM_THLD_MASK 0x000000FF
88+
89+#define RNG_REG_FROENABLE 0x20
90+#define RNG_REG_FRODETUNE 0x24
91+#define RNG_REG_ALARMMASK 0x28
92+#define RNG_REG_ALARMSTOP 0x2C
93+#define RNG_REG_LFSR_L 0x30
94+#define RNG_REG_LFSR_M 0x34
95+#define RNG_REG_LFSR_H 0x38
96+#define RNG_REG_COUNT 0x3C
97+#define RNG_REG_TEST 0x40
98+
99+#define RNG_REG_OPTIONS 0x78
100+#define RNG_REG_OPTIONS_NUM_FROS_MASK 0x00000FC0
101+
102+#define RNG_REG_EIP_REV 0x7C
103+#define RNG_REG_STATUS_EN 0x1FD8
104+#define RNG_REG_STATUS_EN_SHUTDOWN_OFLO (1 << 1)
105+#define RNG_REG_STATUS_EN_RDY (1 << 0)
106+
107+#define RNG_REG_REV 0x1FE0
108+#define RNG_REG_REV_X_MAJOR_MASK (0x0F << 4)
109+#define RNG_REG_REV_Y_MINOR_MASK (0x0F << 0)
110+
111+#define RNG_REG_SYSCFG 0x1FE4
112+#define RNG_REG_SYSCFG_SIDLEMODE_MASK (3 << 3)
113+#define RNG_REG_SYSCFG_SIDLEMODE_FORCE (0 << 3)
114+#define RNG_REG_SYSCFG_SIDLEMODE_NO (1 << 3)
115+#define RNG_REG_SYSCFG_SIDLEMODE_SMART (2 << 3)
116+#define RNG_REG_SYSCFG_AUTOIDLE (1 << 0)
117+
118+#define RNG_REG_STATUS_SET 0x1FEC
119+#define RNG_REG_STATUS_SET_SHUTDOWN_OFLO (1 << 1)
120+#define RNG_REG_STATUS_SET_RDY (1 << 0)
121+
122+#define RNG_REG_SOFT_RESET 0x1FF0
123+#define RNG_REG_SOFTRESET (1 << 0)
124+
125+#define RNG_REG_IRQ_EOI 0x1FF4
126+#define RNG_REG_IRQ_EOI_PULSE_INT_CLEAR (1 << 0)
127+
128+#define RNG_REG_IRQSTATUS 0x1FF8
129+#define RNG_REG_IRQSTATUS_IRQ_EN (1 << 0)
130+
131+
132+static void __iomem *rng_base;
133+static struct clk *rng_fck;
134+static struct platform_device *rng_dev;
135+
136+#define trng_read(reg) \
137+({ \
138+ u32 __val; \
139+ __val = __raw_readl(rng_base + RNG_REG_##reg); \
140+})
141+
142+#define trng_write(val, reg) \
143+({ \
144+ __raw_writel((val), rng_base + RNG_REG_##reg); \
145+})
146+
147+static int omap4_rng_data_read(struct hwrng *rng, void *buf, size_t max, bool wait)
148+{
149+ int res, i;
150+
151+ for (i = 0; i < 20; i++) {
152+ res = trng_read(STATUS) & RNG_REG_STATUS_RDY;
153+ if (res || !wait)
154+ break;
155+ /* RNG produces data fast enough (2+ MBit/sec, even
156+ * during "rngtest" loads, that these delays don't
157+ * seem to trigger. We *could* use the RNG IRQ, but
158+ * that'd be higher overhead ... so why bother?
159+ */
160+ udelay(10);
161+ }
162+
163+ /* If we have data waiting, collect it... */
164+ if (res) {
165+ *(u32 *)buf = trng_read(OUTPUT_L);
166+ buf += sizeof(u32);
167+ *(u32 *)buf = trng_read(OUTPUT_H);
168+
169+ trng_write(RNG_REG_INTACK_RDY, INTACK);
170+
171+ res = 2 * sizeof(u32);
172+ }
173+ return res;
174+}
175+
176+static struct hwrng omap4_rng_ops = {
177+ .name = "omap4",
178+ .read = omap4_rng_data_read,
179+};
180+
181+static int __devinit omap4_rng_probe(struct platform_device *pdev)
182+{
183+ struct resource *res;
184+ int ret;
185+ u32 reg;
186+
187+ /*
188+ * A bit ugly, and it will never actually happen but there can
189+ * be only one RNG and this catches any bork
190+ */
191+ if (rng_dev)
192+ return -EBUSY;
193+
194+ rng_fck = clk_get(&pdev->dev, "rng_fck");
195+ if (IS_ERR(rng_fck)) {
196+ dev_err(&pdev->dev, "Could not get rng_fck\n");
197+ ret = PTR_ERR(rng_fck);
198+ return ret;
199+ } else
200+ clk_enable(rng_fck);
201+
202+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
203+ if (!res) {
204+ ret = -ENOENT;
205+ goto err_region;
206+ }
207+
208+ if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
209+ ret = -EBUSY;
210+ goto err_region;
211+ }
212+
213+ dev_set_drvdata(&pdev->dev, res);
214+ rng_base = ioremap(res->start, resource_size(res));
215+ if (!rng_base) {
216+ ret = -ENOMEM;
217+ goto err_ioremap;
218+ }
219+
220+ ret = hwrng_register(&omap4_rng_ops);
221+ if (ret)
222+ goto err_register;
223+
224+ reg = trng_read(REV);
225+ dev_info(&pdev->dev, "OMAP4 Random Number Generator ver. %u.%02u\n",
226+ ((reg & RNG_REG_REV_X_MAJOR_MASK) >> 4),
227+ (reg & RNG_REG_REV_Y_MINOR_MASK));
228+
229+ rng_dev = pdev;
230+
231+ /* start TRNG if not running yet */
232+ if (!(trng_read(CONTROL) & RNG_REG_CONTROL_ENABLE_TRNG)) {
233+ trng_write(0x00220021, CONFIG);
234+ trng_write(0x00210400, CONTROL);
235+ }
236+
237+ return 0;
238+
239+err_register:
240+ iounmap(rng_base);
241+ rng_base = NULL;
242+err_ioremap:
243+ release_mem_region(res->start, resource_size(res));
244+err_region:
245+ clk_disable(rng_fck);
246+ clk_put(rng_fck);
247+ return ret;
248+}
249+
250+static int __exit omap4_rng_remove(struct platform_device *pdev)
251+{
252+ struct resource *res = dev_get_drvdata(&pdev->dev);
253+
254+ hwrng_unregister(&omap4_rng_ops);
255+
256+ trng_write(trng_read(CONTROL) & ~RNG_REG_CONTROL_ENABLE_TRNG, CONTROL);
257+
258+ iounmap(rng_base);
259+
260+ clk_disable(rng_fck);
261+ clk_put(rng_fck);
262+ release_mem_region(res->start, resource_size(res));
263+ rng_base = NULL;
264+
265+ return 0;
266+}
267+
268+#ifdef CONFIG_PM
269+
270+static int omap4_rng_suspend(struct platform_device *pdev, pm_message_t message)
271+{
272+ trng_write(trng_read(CONTROL) & ~RNG_REG_CONTROL_ENABLE_TRNG, CONTROL);
273+
274+ return 0;
275+}
276+
277+static int omap4_rng_resume(struct platform_device *pdev)
278+{
279+ trng_write(trng_read(CONTROL) | RNG_REG_CONTROL_ENABLE_TRNG, CONTROL);
280+
281+ return 0;
282+}
283+
284+#else
285+
286+#define omap4_rng_suspend NULL
287+#define omap4_rng_resume NULL
288+
289+#endif
290+
291+/* work with hotplug and coldplug */
292+MODULE_ALIAS("platform:omap4_rng");
293+
294+static struct platform_driver omap4_rng_driver = {
295+ .driver = {
296+ .name = "omap4_rng",
297+ .owner = THIS_MODULE,
298+ },
299+ .probe = omap4_rng_probe,
300+ .remove = __exit_p(omap4_rng_remove),
301+ .suspend = omap4_rng_suspend,
302+ .resume = omap4_rng_resume
303+};
304+
305+static int __init omap4_rng_init(void)
306+{
307+ if (!cpu_is_am33xx() || omap_type() != OMAP2_DEVICE_TYPE_GP)
308+ return -ENODEV;
309+
310+ return platform_driver_register(&omap4_rng_driver);
311+}
312+
313+static void __exit omap4_rng_exit(void)
314+{
315+ platform_driver_unregister(&omap4_rng_driver);
316+}
317+
318+module_init(omap4_rng_init);
319+module_exit(omap4_rng_exit);
320+
321+MODULE_LICENSE("GPL");
322+MODULE_DESCRIPTION("AM33X TRNG driver");
323--
3241.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0007-am33x-Create-driver-for-AES-crypto-module.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0007-am33x-Create-driver-for-AES-crypto-module.patch
new file mode 100644
index 00000000..85173a5f
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0007-am33x-Create-driver-for-AES-crypto-module.patch
@@ -0,0 +1,971 @@
1From 501def5dd499457a38e6284f9780ba169284e530 Mon Sep 17 00:00:00 2001
2From: Greg Turner <gregturner@ti.com>
3Date: Thu, 17 May 2012 15:17:13 -0500
4Subject: [PATCH 7/8] am33x: Create driver for AES crypto module
5
6This is the initial version of the driver for the AES crypto module for a GP version of OMAP4 derivative SOC's such as AM335x.
7
8Signed-off-by: Greg Turner <gregturner@ti.com>
9---
10 drivers/crypto/omap4-aes.c | 950 ++++++++++++++++++++++++++++++++++++++++++++
11 1 files changed, 950 insertions(+), 0 deletions(-)
12 create mode 100755 drivers/crypto/omap4-aes.c
13
14diff --git a/drivers/crypto/omap4-aes.c b/drivers/crypto/omap4-aes.c
15new file mode 100755
16index 0000000..f0b3fe2
17--- /dev/null
18+++ b/drivers/crypto/omap4-aes.c
19@@ -0,0 +1,950 @@
20+/*
21+ * Cryptographic API.
22+ *
23+ * Support for OMAP AES HW acceleration.
24+ *
25+ * Copyright (c) 2010 Nokia Corporation
26+ * Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
27+ *
28+ * This program is free software; you can redistribute it and/or modify
29+ * it under the terms of the GNU General Public License version 2 as published
30+ * by the Free Software Foundation.
31+ *
32+ */
33+/*
34+ * Copyright © 2011 Texas Instruments Incorporated
35+ * Author: Herman Schuurman
36+ * Change: July 2011 - Adapted the omap-aes.c driver to support Netra
37+ * implementation of AES hardware accelerator.
38+ */
39+/*
40+ * Copyright © 2011 Texas Instruments Incorporated
41+ * Author: Greg Turner
42+ * Change: November 2011 - Adapted for AM33x support HW accelerator.
43+ */
44+
45+//#define DEBUG
46+
47+#define pr_fmt(fmt) "%s: " fmt, __func__
48+
49+#include <linux/err.h>
50+#include <linux/module.h>
51+#include <linux/init.h>
52+#include <linux/errno.h>
53+#include <linux/kernel.h>
54+#include <linux/clk.h>
55+#include <linux/platform_device.h>
56+#include <linux/scatterlist.h>
57+#include <linux/dma-mapping.h>
58+#include <linux/io.h>
59+#include <linux/crypto.h>
60+#include <linux/interrupt.h>
61+#include <crypto/scatterwalk.h>
62+#include <crypto/aes.h>
63+
64+#include <plat/cpu.h>
65+#include <plat/dma.h>
66+#include <mach/edma.h>
67+#include <mach/hardware.h>
68+#include "omap4.h"
69+
70+#define DEFAULT_TIMEOUT (5*HZ)
71+
72+#define FLAGS_MODE_MASK 0x000f
73+#define FLAGS_ENCRYPT BIT(0)
74+#define FLAGS_CBC BIT(1)
75+#define FLAGS_CTR BIT(2)
76+#define FLAGS_GIV BIT(3)
77+
78+#define FLAGS_INIT BIT(4)
79+#define FLAGS_FAST BIT(5)
80+#define FLAGS_BUSY BIT(6)
81+
82+struct omap4_aes_ctx {
83+ struct omap4_aes_dev *dd;
84+
85+ int keylen;
86+ u32 key[AES_KEYSIZE_256 / sizeof(u32)];
87+ unsigned long flags;
88+};
89+
90+struct omap4_aes_reqctx {
91+ unsigned long mode;
92+};
93+
94+#define AM33X_AES_QUEUE_LENGTH 1
95+#define AM33X_AES_CACHE_SIZE 0
96+
97+struct omap4_aes_dev {
98+ struct list_head list;
99+ unsigned long phys_base;
100+ void __iomem *io_base;
101+ struct clk *iclk;
102+ struct omap4_aes_ctx *ctx;
103+ struct device *dev;
104+ unsigned long flags;
105+ int err;
106+
107+ spinlock_t lock;
108+ struct crypto_queue queue;
109+
110+ struct tasklet_struct done_task;
111+ struct tasklet_struct queue_task;
112+
113+ struct ablkcipher_request *req;
114+ size_t total;
115+ struct scatterlist *in_sg;
116+ size_t in_offset;
117+ struct scatterlist *out_sg;
118+ size_t out_offset;
119+
120+ size_t buflen;
121+ void *buf_in;
122+ size_t dma_size;
123+ int dma_in;
124+ int dma_lch_in;
125+ dma_addr_t dma_addr_in;
126+ void *buf_out;
127+ int dma_out;
128+ int dma_lch_out;
129+ dma_addr_t dma_addr_out;
130+};
131+
132+/* keep registered devices data here */
133+static LIST_HEAD(dev_list);
134+static DEFINE_SPINLOCK(list_lock);
135+
136+static inline u32 omap4_aes_read(struct omap4_aes_dev *dd, u32 offset)
137+{
138+ return __raw_readl(dd->io_base + offset);
139+}
140+
141+static inline void omap4_aes_write(struct omap4_aes_dev *dd, u32 offset,
142+ u32 value)
143+{
144+ __raw_writel(value, dd->io_base + offset);
145+}
146+
147+static inline void omap4_aes_write_mask(struct omap4_aes_dev *dd, u32 offset,
148+ u32 value, u32 mask)
149+{
150+ u32 val;
151+
152+ val = omap4_aes_read(dd, offset);
153+ val &= ~mask;
154+ val |= value;
155+ omap4_aes_write(dd, offset, val);
156+}
157+
158+static void omap4_aes_write_n(struct omap4_aes_dev *dd, u32 offset,
159+ u32 *value, int count)
160+{
161+ for (; count--; value++, offset += 4)
162+ omap4_aes_write(dd, offset, *value);
163+}
164+
165+static int omap4_aes_hw_init(struct omap4_aes_dev *dd)
166+{
167+ /*
168+ * clocks are enabled when request starts and disabled when finished.
169+ * It may be long delays between requests.
170+ * Device might go to off mode to save power.
171+ */
172+ clk_enable(dd->iclk);
173+ omap4_aes_write(dd, AES_REG_SYSCFG, 0);
174+
175+ if (!(dd->flags & FLAGS_INIT)) {
176+ dd->flags |= FLAGS_INIT;
177+ dd->err = 0;
178+ }
179+
180+ return 0;
181+}
182+
183+static int omap4_aes_write_ctrl(struct omap4_aes_dev *dd)
184+{
185+ unsigned int key32;
186+ int i, err;
187+ u32 val, mask;
188+
189+ err = omap4_aes_hw_init(dd);
190+ if (err)
191+ return err;
192+
193+ pr_debug("Set key\n");
194+ key32 = dd->ctx->keylen / sizeof(u32);
195+
196+ /* set a key */
197+ for (i = 0; i < key32; i++) {
198+ omap4_aes_write(dd, AES_REG_KEY1(i),
199+ __le32_to_cpu(dd->ctx->key[i]));
200+ }
201+
202+ if ((dd->flags & (FLAGS_CBC | FLAGS_CTR)) && dd->req->info)
203+ omap4_aes_write_n(dd, AES_REG_IV(0), dd->req->info, 4);
204+
205+ val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);
206+ if (dd->flags & FLAGS_CBC)
207+ val |= AES_REG_CTRL_CBC;
208+ else if (dd->flags & FLAGS_CTR)
209+ val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_32;
210+ if (dd->flags & FLAGS_ENCRYPT)
211+ val |= AES_REG_CTRL_DIRECTION;
212+
213+ mask = AES_REG_CTRL_CBC | AES_REG_CTRL_CTR | AES_REG_CTRL_DIRECTION |
214+ AES_REG_CTRL_KEY_SIZE_MASK | AES_REG_CTRL_CTR_WIDTH_MASK;
215+
216+ omap4_aes_write_mask(dd, AES_REG_CTRL, val, mask);
217+
218+ return 0;
219+}
220+
221+static struct omap4_aes_dev *omap4_aes_find_dev(struct omap4_aes_ctx *ctx)
222+{
223+ struct omap4_aes_dev *dd = NULL, *tmp;
224+
225+ spin_lock_bh(&list_lock);
226+ if (!ctx->dd) {
227+ list_for_each_entry(tmp, &dev_list, list) {
228+ /* FIXME: take fist available aes core */
229+ dd = tmp;
230+ break;
231+ }
232+ ctx->dd = dd;
233+ } else {
234+ /* already found before */
235+ dd = ctx->dd;
236+ }
237+ spin_unlock_bh(&list_lock);
238+
239+ return dd;
240+}
241+
242+static void omap4_aes_dma_callback(unsigned int lch, u16 ch_status, void *data)
243+{
244+ struct omap4_aes_dev *dd = data;
245+
246+ edma_stop(lch);
247+
248+ if (ch_status != DMA_COMPLETE) {
249+ pr_err("omap4-aes DMA error status: 0x%hx\n", ch_status);
250+ dd->err = -EIO;
251+ dd->flags &= ~FLAGS_INIT; /* request to re-initialize */
252+ } else if (lch == dd->dma_lch_in) {
253+ return;
254+ }
255+
256+ /* dma_lch_out - completed */
257+ tasklet_schedule(&dd->done_task);
258+}
259+
260+static int omap4_aes_dma_init(struct omap4_aes_dev *dd)
261+{
262+ int err = -ENOMEM;
263+
264+ dd->dma_lch_out = -1;
265+ dd->dma_lch_in = -1;
266+
267+ dd->buf_in = (void *)__get_free_pages(GFP_KERNEL, AM33X_AES_CACHE_SIZE);
268+ dd->buf_out = (void *)__get_free_pages(GFP_KERNEL, AM33X_AES_CACHE_SIZE);
269+ dd->buflen = PAGE_SIZE << AM33X_AES_CACHE_SIZE;
270+ dd->buflen &= ~(AES_BLOCK_SIZE - 1);
271+
272+ if (!dd->buf_in || !dd->buf_out) {
273+ dev_err(dd->dev, "unable to alloc pages.\n");
274+ goto err_alloc;
275+ }
276+
277+ /* MAP here */
278+ dd->dma_addr_in = dma_map_single(dd->dev, dd->buf_in, dd->buflen,
279+ DMA_TO_DEVICE);
280+ if (dma_mapping_error(dd->dev, dd->dma_addr_in)) {
281+ dev_err(dd->dev, "dma %d bytes error\n", dd->buflen);
282+ err = -EINVAL;
283+ goto err_map_in;
284+ }
285+
286+ dd->dma_addr_out = dma_map_single(dd->dev, dd->buf_out, dd->buflen,
287+ DMA_FROM_DEVICE);
288+ if (dma_mapping_error(dd->dev, dd->dma_addr_out)) {
289+ dev_err(dd->dev, "dma %d bytes error\n", dd->buflen);
290+ err = -EINVAL;
291+ goto err_map_out;
292+ }
293+
294+ dd->dma_lch_in = edma_alloc_channel(dd->dma_in, omap4_aes_dma_callback,
295+ dd, EVENTQ_DEFAULT);
296+
297+ if (dd->dma_lch_in < 0) {
298+ dev_err(dd->dev, "Unable to request DMA channel\n");
299+ goto err_dma_in;
300+ }
301+
302+ dd->dma_lch_out = edma_alloc_channel(dd->dma_out, omap4_aes_dma_callback, dd, EVENTQ_2);
303+
304+ if (dd->dma_lch_out < 0) {
305+ dev_err(dd->dev, "Unable to request DMA channel\n");
306+ goto err_dma_out;
307+ }
308+
309+ return 0;
310+
311+err_dma_out:
312+ edma_free_channel(dd->dma_lch_in);
313+err_dma_in:
314+ dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen,
315+ DMA_FROM_DEVICE);
316+err_map_out:
317+ dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, DMA_TO_DEVICE);
318+err_map_in:
319+ free_pages((unsigned long)dd->buf_out, AM33X_AES_CACHE_SIZE);
320+ free_pages((unsigned long)dd->buf_in, AM33X_AES_CACHE_SIZE);
321+err_alloc:
322+ if (err)
323+ pr_err("error: %d\n", err);
324+ return err;
325+}
326+
327+static void omap4_aes_dma_cleanup(struct omap4_aes_dev *dd)
328+{
329+ edma_free_channel(dd->dma_lch_out);
330+ edma_free_channel(dd->dma_lch_in);
331+ dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen,
332+ DMA_FROM_DEVICE);
333+ dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, DMA_TO_DEVICE);
334+ free_pages((unsigned long)dd->buf_out, AM33X_AES_CACHE_SIZE);
335+ free_pages((unsigned long)dd->buf_in, AM33X_AES_CACHE_SIZE);
336+}
337+
338+static void sg_copy_buf(void *buf, struct scatterlist *sg,
339+ unsigned int start, unsigned int nbytes, int out)
340+{
341+ struct scatter_walk walk;
342+
343+ if (!nbytes)
344+ return;
345+
346+ scatterwalk_start(&walk, sg);
347+ scatterwalk_advance(&walk, start);
348+ scatterwalk_copychunks(buf, &walk, nbytes, out);
349+ scatterwalk_done(&walk, out, 0);
350+}
351+
352+static int sg_copy(struct scatterlist **sg, size_t *offset, void *buf,
353+ size_t buflen, size_t total, int out)
354+{
355+ unsigned int count, off = 0;
356+
357+ while (buflen && total) {
358+ count = min((*sg)->length - *offset, total);
359+ count = min(count, buflen);
360+
361+ if (!count)
362+ return off;
363+
364+ /*
365+ * buflen and total are AES_BLOCK_SIZE size aligned,
366+ * so count should be also aligned
367+ */
368+
369+ sg_copy_buf(buf + off, *sg, *offset, count, out);
370+
371+ off += count;
372+ buflen -= count;
373+ *offset += count;
374+ total -= count;
375+
376+ if (*offset == (*sg)->length) {
377+ *sg = sg_next(*sg);
378+ if (*sg)
379+ *offset = 0;
380+ else
381+ total = 0;
382+ }
383+ }
384+
385+ return off;
386+}
387+
388+static int omap4_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
389+ dma_addr_t dma_addr_out, int length)
390+{
391+ struct omap4_aes_ctx *ctx = crypto_tfm_ctx(tfm);
392+ struct omap4_aes_dev *dd = ctx->dd;
393+ int nblocks;
394+ struct edmacc_param p_ram;
395+
396+ pr_debug("len: %d\n", length);
397+
398+ dd->dma_size = length;
399+
400+ if (!(dd->flags & FLAGS_FAST))
401+ dma_sync_single_for_device(dd->dev, dma_addr_in, length,
402+ DMA_TO_DEVICE);
403+
404+ nblocks = DIV_ROUND_UP(length, AES_BLOCK_SIZE);
405+
406+ /* EDMA IN */
407+ p_ram.opt = TCINTEN |
408+ EDMA_TCC(EDMA_CHAN_SLOT(dd->dma_lch_in));
409+ p_ram.src = dma_addr_in;
410+ p_ram.a_b_cnt = AES_BLOCK_SIZE | nblocks << 16;
411+ p_ram.dst = dd->phys_base + AES_REG_DATA;
412+ p_ram.src_dst_bidx = AES_BLOCK_SIZE;
413+ p_ram.link_bcntrld = 1 << 16 | 0xFFFF;
414+ p_ram.src_dst_cidx = 0;
415+ p_ram.ccnt = 1;
416+ edma_write_slot(dd->dma_lch_in, &p_ram);
417+
418+ /* EDMA OUT */
419+ p_ram.opt = TCINTEN |
420+ EDMA_TCC(EDMA_CHAN_SLOT(dd->dma_lch_out));
421+ p_ram.src = dd->phys_base + AES_REG_DATA;
422+ p_ram.dst = dma_addr_out;
423+ p_ram.src_dst_bidx = AES_BLOCK_SIZE << 16;
424+ edma_write_slot(dd->dma_lch_out, &p_ram);
425+
426+ edma_start(dd->dma_lch_in);
427+ edma_start(dd->dma_lch_out);
428+
429+ /* write data length info out */
430+ omap4_aes_write(dd, AES_REG_LENGTH_N(0), length);
431+ omap4_aes_write(dd, AES_REG_LENGTH_N(1), 0);
432+ /* start DMA or disable idle mode */
433+ omap4_aes_write_mask(dd, AES_REG_SYSCFG,
434+ AES_REG_SYSCFG_DREQ_DATA_OUT_EN | AES_REG_SYSCFG_DREQ_DATA_IN_EN,
435+ AES_REG_SYSCFG_DREQ_MASK);
436+
437+ return 0;
438+}
439+
440+static int omap4_aes_crypt_dma_start(struct omap4_aes_dev *dd)
441+{
442+ struct crypto_tfm *tfm = crypto_ablkcipher_tfm(
443+ crypto_ablkcipher_reqtfm(dd->req));
444+ int err, fast = 0, in, out;
445+ size_t count;
446+ dma_addr_t addr_in, addr_out;
447+
448+ pr_debug("total: %d\n", dd->total);
449+
450+ if (sg_is_last(dd->in_sg) && sg_is_last(dd->out_sg)) {
451+ /* check for alignment */
452+ in = IS_ALIGNED((u32)dd->in_sg->offset, sizeof(u32));
453+ out = IS_ALIGNED((u32)dd->out_sg->offset, sizeof(u32));
454+
455+ fast = in && out;
456+ }
457+
458+ if (fast) {
459+ count = min(dd->total, sg_dma_len(dd->in_sg));
460+ count = min(count, sg_dma_len(dd->out_sg));
461+
462+ if (count != dd->total) {
463+ pr_err("request length != buffer length\n");
464+ return -EINVAL;
465+ }
466+
467+ pr_debug("fast\n");
468+
469+ err = dma_map_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
470+ if (!err) {
471+ dev_err(dd->dev, "dma_map_sg() error\n");
472+ return -EINVAL;
473+ }
474+
475+ err = dma_map_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE);
476+ if (!err) {
477+ dev_err(dd->dev, "dma_map_sg() error\n");
478+ dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
479+ return -EINVAL;
480+ }
481+
482+ addr_in = sg_dma_address(dd->in_sg);
483+ addr_out = sg_dma_address(dd->out_sg);
484+
485+ dd->flags |= FLAGS_FAST;
486+
487+ } else {
488+ /* use cache buffers */
489+ count = sg_copy(&dd->in_sg, &dd->in_offset, dd->buf_in,
490+ dd->buflen, dd->total, 0);
491+
492+ addr_in = dd->dma_addr_in;
493+ addr_out = dd->dma_addr_out;
494+
495+ dd->flags &= ~FLAGS_FAST;
496+
497+ }
498+
499+ dd->total -= count;
500+
501+ err = omap4_aes_crypt_dma(tfm, addr_in, addr_out, count);
502+ if (err) {
503+ dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
504+ dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE);
505+ }
506+
507+ return err;
508+}
509+
510+static void omap4_aes_finish_req(struct omap4_aes_dev *dd, int err)
511+{
512+ struct ablkcipher_request *req = dd->req;
513+
514+ pr_debug("err: %d\n", err);
515+
516+ clk_disable(dd->iclk);
517+ dd->flags &= ~FLAGS_BUSY;
518+
519+ req->base.complete(&req->base, err);
520+}
521+
522+static int omap4_aes_crypt_dma_stop(struct omap4_aes_dev *dd)
523+{
524+ int err = 0;
525+ size_t count;
526+
527+ pr_debug("total: %d\n", dd->total);
528+
529+ omap4_aes_write_mask(dd, AES_REG_SYSCFG, 0, AES_REG_SYSCFG_DREQ_MASK);
530+
531+ edma_stop(dd->dma_lch_in);
532+ edma_clean_channel(dd->dma_lch_in);
533+ edma_stop(dd->dma_lch_out);
534+ edma_clean_channel(dd->dma_lch_out);
535+
536+ if (dd->flags & FLAGS_FAST) {
537+ dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE);
538+ dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
539+ } else {
540+ dma_sync_single_for_device(dd->dev, dd->dma_addr_out,
541+ dd->dma_size, DMA_FROM_DEVICE);
542+
543+ /* copy data */
544+ count = sg_copy(&dd->out_sg, &dd->out_offset, dd->buf_out,
545+ dd->buflen, dd->dma_size, 1);
546+ if (count != dd->dma_size) {
547+ err = -EINVAL;
548+ pr_err("not all data converted: %u\n", count);
549+ }
550+ }
551+
552+ return err;
553+}
554+
555+static int omap4_aes_handle_queue(struct omap4_aes_dev *dd,
556+ struct ablkcipher_request *req)
557+{
558+ struct crypto_async_request *async_req, *backlog;
559+ struct omap4_aes_ctx *ctx;
560+ struct omap4_aes_reqctx *rctx;
561+ unsigned long flags;
562+ int err, ret = 0;
563+
564+ spin_lock_irqsave(&dd->lock, flags);
565+ if (req)
566+ ret = ablkcipher_enqueue_request(&dd->queue, req);
567+
568+ if (dd->flags & FLAGS_BUSY) {
569+ spin_unlock_irqrestore(&dd->lock, flags);
570+ return ret;
571+ }
572+ backlog = crypto_get_backlog(&dd->queue);
573+ async_req = crypto_dequeue_request(&dd->queue);
574+ if (async_req)
575+ dd->flags |= FLAGS_BUSY;
576+ spin_unlock_irqrestore(&dd->lock, flags);
577+
578+ if (!async_req)
579+ return ret;
580+
581+ if (backlog)
582+ backlog->complete(backlog, -EINPROGRESS);
583+
584+ req = ablkcipher_request_cast(async_req);
585+
586+ /* assign new request to device */
587+ dd->req = req;
588+ dd->total = req->nbytes;
589+ dd->in_offset = 0;
590+ dd->in_sg = req->src;
591+ dd->out_offset = 0;
592+ dd->out_sg = req->dst;
593+
594+ rctx = ablkcipher_request_ctx(req);
595+ ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req));
596+ rctx->mode &= FLAGS_MODE_MASK;
597+ dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode;
598+
599+ dd->ctx = ctx;
600+ ctx->dd = dd;
601+
602+ err = omap4_aes_write_ctrl(dd);
603+ if (!err)
604+ err = omap4_aes_crypt_dma_start(dd);
605+ if (err) {
606+ /* aes_task will not finish it, so do it here */
607+ omap4_aes_finish_req(dd, err);
608+ tasklet_schedule(&dd->queue_task);
609+ }
610+
611+ return ret; /* return ret, which is enqueue return value */
612+}
613+
614+static void omap4_aes_done_task(unsigned long data)
615+{
616+ struct omap4_aes_dev *dd = (struct omap4_aes_dev *)data;
617+ int err;
618+
619+ pr_debug("enter\n");
620+
621+ err = omap4_aes_crypt_dma_stop(dd);
622+
623+ err = dd->err ? : err;
624+
625+ if (dd->total && !err) {
626+ err = omap4_aes_crypt_dma_start(dd);
627+ if (!err)
628+ return; /* DMA started. Not finishing. */
629+ }
630+
631+ omap4_aes_finish_req(dd, err);
632+ omap4_aes_handle_queue(dd, NULL);
633+
634+ pr_debug("exit\n");
635+}
636+
637+static void omap4_aes_queue_task(unsigned long data)
638+{
639+ struct omap4_aes_dev *dd = (struct omap4_aes_dev *)data;
640+
641+ omap4_aes_handle_queue(dd, NULL);
642+}
643+
644+static int omap4_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
645+{
646+ struct omap4_aes_ctx *ctx = crypto_ablkcipher_ctx(
647+ crypto_ablkcipher_reqtfm(req));
648+ struct omap4_aes_reqctx *rctx = ablkcipher_request_ctx(req);
649+ struct omap4_aes_dev *dd;
650+
651+ pr_debug("nbytes: %d, enc: %d, cbc: %d, ctr: %d\n", req->nbytes,
652+ !!(mode & FLAGS_ENCRYPT),
653+ !!(mode & FLAGS_CBC),
654+ !!(mode & FLAGS_CTR));
655+
656+ if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) {
657+ pr_err("request size is not exact amount of AES blocks\n");
658+ return -EINVAL;
659+ }
660+
661+ dd = omap4_aes_find_dev(ctx);
662+ if (!dd)
663+ return -ENODEV;
664+
665+ rctx->mode = mode;
666+
667+ return omap4_aes_handle_queue(dd, req);
668+}
669+
670+/* ********************** ALG API ************************************ */
671+
672+static int omap4_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
673+ unsigned int keylen)
674+{
675+ struct omap4_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
676+
677+ if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 &&
678+ keylen != AES_KEYSIZE_256)
679+ return -EINVAL;
680+
681+ pr_debug("enter, keylen: %d\n", keylen);
682+
683+ memcpy(ctx->key, key, keylen);
684+ ctx->keylen = keylen;
685+
686+ return 0;
687+}
688+
689+static int omap4_aes_ecb_encrypt(struct ablkcipher_request *req)
690+{
691+ return omap4_aes_crypt(req, FLAGS_ENCRYPT);
692+}
693+
694+static int omap4_aes_ecb_decrypt(struct ablkcipher_request *req)
695+{
696+ return omap4_aes_crypt(req, 0);
697+}
698+
699+static int omap4_aes_cbc_encrypt(struct ablkcipher_request *req)
700+{
701+ return omap4_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC);
702+}
703+
704+static int omap4_aes_cbc_decrypt(struct ablkcipher_request *req)
705+{
706+ return omap4_aes_crypt(req, FLAGS_CBC);
707+}
708+
709+static int omap4_aes_ctr_encrypt(struct ablkcipher_request *req)
710+{
711+ return omap4_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CTR);
712+}
713+
714+static int omap4_aes_ctr_decrypt(struct ablkcipher_request *req)
715+{
716+ return omap4_aes_crypt(req, FLAGS_CTR);
717+}
718+
719+static int omap4_aes_cra_init(struct crypto_tfm *tfm)
720+{
721+ pr_debug("enter\n");
722+
723+ tfm->crt_ablkcipher.reqsize = sizeof(struct omap4_aes_reqctx);
724+
725+ return 0;
726+}
727+
728+static void omap4_aes_cra_exit(struct crypto_tfm *tfm)
729+{
730+ pr_debug("enter\n");
731+}
732+
733+/* ********************** ALGS ************************************ */
734+
735+static struct crypto_alg algs[] = {
736+ {
737+ .cra_name = "ecb(aes)",
738+ .cra_driver_name = "ecb-aes-omap4",
739+ .cra_priority = 300,
740+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
741+ .cra_blocksize = AES_BLOCK_SIZE,
742+ .cra_ctxsize = sizeof(struct omap4_aes_ctx),
743+ .cra_alignmask = 0,
744+ .cra_type = &crypto_ablkcipher_type,
745+ .cra_module = THIS_MODULE,
746+ .cra_init = omap4_aes_cra_init,
747+ .cra_exit = omap4_aes_cra_exit,
748+ .cra_u.ablkcipher = {
749+ .min_keysize = AES_MIN_KEY_SIZE,
750+ .max_keysize = AES_MAX_KEY_SIZE,
751+ .setkey = omap4_aes_setkey,
752+ .encrypt = omap4_aes_ecb_encrypt,
753+ .decrypt = omap4_aes_ecb_decrypt,
754+ }
755+ },
756+ {
757+ .cra_name = "cbc(aes)",
758+ .cra_driver_name = "cbc-aes-omap4",
759+ .cra_priority = 300,
760+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
761+ .cra_blocksize = AES_BLOCK_SIZE,
762+ .cra_ctxsize = sizeof(struct omap4_aes_ctx),
763+ .cra_alignmask = 0,
764+ .cra_type = &crypto_ablkcipher_type,
765+ .cra_module = THIS_MODULE,
766+ .cra_init = omap4_aes_cra_init,
767+ .cra_exit = omap4_aes_cra_exit,
768+ .cra_u.ablkcipher = {
769+ .min_keysize = AES_MIN_KEY_SIZE,
770+ .max_keysize = AES_MAX_KEY_SIZE,
771+ .geniv = "eseqiv",
772+ .ivsize = AES_BLOCK_SIZE,
773+ .setkey = omap4_aes_setkey,
774+ .encrypt = omap4_aes_cbc_encrypt,
775+ .decrypt = omap4_aes_cbc_decrypt,
776+
777+ }
778+ },
779+ {
780+ .cra_name = "ctr(aes)",
781+ .cra_driver_name = "ctr-aes-omap4",
782+ .cra_priority = 300,
783+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
784+ .cra_blocksize = AES_BLOCK_SIZE,
785+ .cra_ctxsize = sizeof(struct omap4_aes_ctx),
786+ .cra_alignmask = 0,
787+ .cra_type = &crypto_ablkcipher_type,
788+ .cra_module = THIS_MODULE,
789+ .cra_init = omap4_aes_cra_init,
790+ .cra_exit = omap4_aes_cra_exit,
791+ .cra_u.ablkcipher = {
792+ .min_keysize = AES_MIN_KEY_SIZE,
793+ .max_keysize = AES_MAX_KEY_SIZE,
794+ .geniv = "eseqiv",
795+ .ivsize = AES_BLOCK_SIZE,
796+ .setkey = omap4_aes_setkey,
797+ .encrypt = omap4_aes_ctr_encrypt,
798+ .decrypt = omap4_aes_ctr_decrypt,
799+ }
800+ }
801+};
802+
803+static int omap4_aes_probe(struct platform_device *pdev)
804+{
805+ struct device *dev = &pdev->dev;
806+ struct omap4_aes_dev *dd;
807+ struct resource *res;
808+ int err = -ENOMEM, i, j;
809+ u32 reg;
810+
811+ dd = kzalloc(sizeof(struct omap4_aes_dev), GFP_KERNEL);
812+ if (dd == NULL) {
813+ dev_err(dev, "unable to alloc data struct.\n");
814+ goto err_data;
815+ }
816+ dd->dev = dev;
817+ platform_set_drvdata(pdev, dd);
818+
819+ spin_lock_init(&dd->lock);
820+ crypto_init_queue(&dd->queue, AM33X_AES_QUEUE_LENGTH);
821+
822+ /* Get the base address */
823+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
824+ if (!res) {
825+ dev_err(dev, "invalid resource type\n");
826+ err = -ENODEV;
827+ goto err_res;
828+ }
829+ dd->phys_base = res->start;
830+
831+ /* Get the DMA */
832+ res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
833+ if (!res)
834+ dev_info(dev, "no DMA info\n");
835+ else
836+ dd->dma_out = res->start;
837+
838+ /* Get the DMA */
839+ res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
840+ if (!res)
841+ dev_info(dev, "no DMA info\n");
842+ else
843+ dd->dma_in = res->start;
844+
845+ /* Initializing the clock */
846+ dd->iclk = clk_get(dev, "aes0_fck");
847+ if (IS_ERR(dd->iclk)) {
848+ dev_err(dev, "clock initialization failed.\n");
849+ err = PTR_ERR(dd->iclk);
850+ goto err_res;
851+ }
852+
853+ dd->io_base = ioremap(dd->phys_base, SZ_4K);
854+ if (!dd->io_base) {
855+ dev_err(dev, "can't ioremap\n");
856+ err = -ENOMEM;
857+ goto err_io;
858+ }
859+
860+ omap4_aes_hw_init(dd);
861+ reg = omap4_aes_read(dd, AES_REG_REV);
862+ clk_disable(dd->iclk);
863+ dev_info(dev, "AM33X AES hw accel rev: %u.%02u\n",
864+ ((reg & AES_REG_REV_X_MAJOR_MASK) >> 8),
865+ (reg & AES_REG_REV_Y_MINOR_MASK));
866+
867+ tasklet_init(&dd->done_task, omap4_aes_done_task, (unsigned long)dd);
868+ tasklet_init(&dd->queue_task, omap4_aes_queue_task, (unsigned long)dd);
869+
870+ err = omap4_aes_dma_init(dd);
871+ if (err)
872+ goto err_dma;
873+
874+ INIT_LIST_HEAD(&dd->list);
875+ spin_lock(&list_lock);
876+ list_add_tail(&dd->list, &dev_list);
877+ spin_unlock(&list_lock);
878+
879+ for (i = 0; i < ARRAY_SIZE(algs); i++) {
880+ pr_debug("reg alg: %s\n", algs[i].cra_name);
881+ INIT_LIST_HEAD(&algs[i].cra_list);
882+ err = crypto_register_alg(&algs[i]);
883+ if (err)
884+ goto err_algs;
885+ }
886+
887+ pr_info("probe() done\n");
888+
889+ return 0;
890+
891+err_algs:
892+ for (j = 0; j < i; j++)
893+ crypto_unregister_alg(&algs[j]);
894+ omap4_aes_dma_cleanup(dd);
895+err_dma:
896+ tasklet_kill(&dd->done_task);
897+ tasklet_kill(&dd->queue_task);
898+ iounmap(dd->io_base);
899+
900+err_io:
901+ clk_put(dd->iclk);
902+err_res:
903+ kfree(dd);
904+ dd = NULL;
905+err_data:
906+ dev_err(dev, "initialization failed.\n");
907+ return err;
908+}
909+
910+static int omap4_aes_remove(struct platform_device *pdev)
911+{
912+ struct omap4_aes_dev *dd = platform_get_drvdata(pdev);
913+ int i;
914+
915+ if (!dd)
916+ return -ENODEV;
917+
918+ spin_lock(&list_lock);
919+ list_del(&dd->list);
920+ spin_unlock(&list_lock);
921+
922+ for (i = 0; i < ARRAY_SIZE(algs); i++)
923+ crypto_unregister_alg(&algs[i]);
924+
925+ tasklet_kill(&dd->done_task);
926+ tasklet_kill(&dd->queue_task);
927+ omap4_aes_dma_cleanup(dd);
928+ iounmap(dd->io_base);
929+ clk_put(dd->iclk);
930+ kfree(dd);
931+ dd = NULL;
932+
933+ return 0;
934+}
935+
936+static struct platform_driver omap4_aes_driver = {
937+ .probe = omap4_aes_probe,
938+ .remove = omap4_aes_remove,
939+ .driver = {
940+ .name = "omap4-aes",
941+ .owner = THIS_MODULE,
942+ },
943+};
944+
945+static int __init omap4_aes_mod_init(void)
946+{
947+ pr_info("loading AM33X AES driver\n");
948+
949+ /* This only works on a GP device */
950+ if (!cpu_is_am33xx() || omap_type() != OMAP2_DEVICE_TYPE_GP) {
951+ pr_err("Unsupported cpu\n");
952+ return -ENODEV;
953+ }
954+ return platform_driver_register(&omap4_aes_driver);
955+}
956+
957+static void __exit omap4_aes_mod_exit(void)
958+{
959+ pr_info("unloading AM33X AES driver\n");
960+
961+ platform_driver_unregister(&omap4_aes_driver);
962+}
963+
964+module_init(omap4_aes_mod_init);
965+module_exit(omap4_aes_mod_exit);
966+
967+MODULE_DESCRIPTION("AM33X AES acceleration support.");
968+MODULE_LICENSE("GPL v2");
969+MODULE_AUTHOR("Herman Schuurman");
970--
9711.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0008-am33x-Create-driver-for-SHA-MD5-crypto-module.patch b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0008-am33x-Create-driver-for-SHA-MD5-crypto-module.patch
new file mode 100644
index 00000000..13c7e9ea
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/0008-am33x-Create-driver-for-SHA-MD5-crypto-module.patch
@@ -0,0 +1,1444 @@
1From 31e5e24a1d713b1f8306050e6b6a640ec30b1848 Mon Sep 17 00:00:00 2001
2From: Greg Turner <gregturner@ti.com>
3Date: Thu, 17 May 2012 15:19:26 -0500
4Subject: [PATCH 8/8] am33x: Create driver for SHA/MD5 crypto module
5
6This is the initial version of the SHA/MD5 driver for OMAP4 derivative SOC's such as AM335x.
7
8Signed-off-by: Greg Turner <gregturner@ti.com>
9---
10 drivers/crypto/omap4-sham.c | 1423 +++++++++++++++++++++++++++++++++++++++++++
11 1 files changed, 1423 insertions(+), 0 deletions(-)
12 create mode 100755 drivers/crypto/omap4-sham.c
13
14diff --git a/drivers/crypto/omap4-sham.c b/drivers/crypto/omap4-sham.c
15new file mode 100755
16index 0000000..79f6be9
17--- /dev/null
18+++ b/drivers/crypto/omap4-sham.c
19@@ -0,0 +1,1423 @@
20+/*
21+ * Cryptographic API.
22+ *
23+ * Support for OMAP SHA1/MD5 HW acceleration.
24+ *
25+ * Copyright (c) 2010 Nokia Corporation
26+ * Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
27+ *
28+ * This program is free software; you can redistribute it and/or modify
29+ * it under the terms of the GNU General Public License version 2 as published
30+ * by the Free Software Foundation.
31+ *
32+ * Some ideas are from old omap-sha1-md5.c driver.
33+ */
34+/*
35+ * Copyright © 2011 Texas Instruments Incorporated
36+ * Author: Herman Schuurman
37+ * Change: July 2011 - Adapted the omap-sham.c driver to support Netra
38+ * implementation of SHA/MD5 hardware accelerator.
39+ * Dec 2011 - Updated with latest omap-sham.c driver changes.
40+ */
41+
42+//#define DEBUG
43+
44+#define pr_fmt(fmt) "%s: " fmt, __func__
45+
46+#include <linux/err.h>
47+#include <linux/device.h>
48+#include <linux/module.h>
49+#include <linux/init.h>
50+#include <linux/errno.h>
51+#include <linux/interrupt.h>
52+#include <linux/kernel.h>
53+#include <linux/clk.h>
54+#include <linux/irq.h>
55+#include <linux/io.h>
56+#include <linux/platform_device.h>
57+#include <linux/scatterlist.h>
58+#include <linux/dma-mapping.h>
59+#include <linux/delay.h>
60+#include <linux/crypto.h>
61+#include <linux/cryptohash.h>
62+#include <crypto/scatterwalk.h>
63+#include <crypto/algapi.h>
64+#include <crypto/sha.h>
65+#include <crypto/md5.h>
66+#include <crypto/hash.h>
67+#include <crypto/internal/hash.h>
68+
69+#include <mach/hardware.h>
70+#include <plat/cpu.h>
71+#include <plat/dma.h>
72+#include <mach/edma.h>
73+#include <mach/irqs.h>
74+#include "omap4.h"
75+
76+#define SHA2_MD5_BLOCK_SIZE SHA1_BLOCK_SIZE
77+
78+#define DEFAULT_TIMEOUT_INTERVAL HZ
79+
80+/* device flags */
81+#define FLAGS_BUSY 0
82+#define FLAGS_FINAL 1
83+#define FLAGS_DMA_ACTIVE 2
84+#define FLAGS_OUTPUT_READY 3 /* shared with context flags */
85+#define FLAGS_INIT 4
86+#define FLAGS_CPU 5 /* shared with context flags */
87+#define FLAGS_DMA_READY 6 /* shared with context flags */
88+
89+/* context flags */
90+#define FLAGS_FINUP 16
91+#define FLAGS_SG 17
92+#define FLAGS_MODE_SHIFT 18
93+#define FLAGS_MODE_MASK (SHA_REG_MODE_ALGO_MASK << (FLAGS_MODE_SHIFT - 1))
94+#define FLAGS_MD5 (SHA_REG_MODE_ALGO_MD5_128 << (FLAGS_MODE_SHIFT - 1))
95+#define FLAGS_SHA1 (SHA_REG_MODE_ALGO_SHA1_160 << (FLAGS_MODE_SHIFT - 1))
96+#define FLAGS_SHA224 (SHA_REG_MODE_ALGO_SHA2_224 << (FLAGS_MODE_SHIFT - 1))
97+#define FLAGS_SHA256 (SHA_REG_MODE_ALGO_SHA2_256 << (FLAGS_MODE_SHIFT - 1))
98+#define FLAGS_HMAC 20
99+#define FLAGS_ERROR 21
100+
101+#define OP_UPDATE 1
102+#define OP_FINAL 2
103+
104+#define AM33X_ALIGN_MASK (sizeof(u32)-1)
105+#define AM33X_ALIGNED __attribute__((aligned(sizeof(u32))))
106+
107+#define BUFLEN PAGE_SIZE
108+
109+struct omap4_sham_dev;
110+
111+struct omap4_sham_reqctx {
112+ struct omap4_sham_dev *dd;
113+ unsigned long rflags;
114+ unsigned long op;
115+
116+ u8 digest[SHA256_DIGEST_SIZE] AM33X_ALIGNED;
117+ size_t digcnt; /* total digest byte count */
118+ size_t bufcnt; /* bytes in buffer */
119+ size_t buflen; /* buffer length */
120+ dma_addr_t dma_addr;
121+
122+ /* walk state */
123+ struct scatterlist *sg;
124+ unsigned int offset; /* offset in current sg */
125+ unsigned int total; /* total request */
126+
127+ u8 buffer[0] AM33X_ALIGNED;
128+};
129+
130+/* This structure holds the initial HMAC key value, and subsequently
131+ * the outer digest in the first 32 bytes. The inner digest will be
132+ * kept within the request context to conform to hash only
133+ * computations.
134+ */
135+struct omap4_sham_hmac_ctx {
136+ struct crypto_shash *shash;
137+ u8 keypad[SHA2_MD5_BLOCK_SIZE] AM33X_ALIGNED;
138+ u32 odigest[SHA256_DIGEST_SIZE / sizeof(u32)];
139+};
140+
141+struct omap4_sham_ctx {
142+ struct omap4_sham_dev *dd;
143+
144+ unsigned long cflags;
145+
146+ /* fallback stuff */
147+ struct crypto_shash *fallback;
148+
149+ struct omap4_sham_hmac_ctx base[0];
150+};
151+
152+#define AM33X_SHAM_QUEUE_LENGTH 1
153+
154+struct omap4_sham_dev {
155+ struct list_head list;
156+ unsigned long phys_base;
157+ struct device *dev;
158+ void __iomem *io_base;
159+ int irq;
160+ struct clk *iclk;
161+ spinlock_t lock;
162+ int err;
163+ int dma;
164+ int dma_lch;
165+ struct tasklet_struct done_task;
166+
167+ unsigned long dflags;
168+ struct crypto_queue queue;
169+ struct ahash_request *req;
170+};
171+
172+struct omap4_sham_drv {
173+ struct list_head dev_list;
174+ spinlock_t lock;
175+ unsigned long flags; /* superfluous ???? */
176+};
177+
178+static struct omap4_sham_drv sham = {
179+ .dev_list = LIST_HEAD_INIT(sham.dev_list),
180+ .lock = __SPIN_LOCK_UNLOCKED(sham.lock),
181+};
182+
183+static inline u32 omap4_sham_read(struct omap4_sham_dev *dd, u32 offset)
184+{
185+ return __raw_readl(dd->io_base + offset);
186+}
187+
188+static inline void omap4_sham_write(struct omap4_sham_dev *dd,
189+ u32 offset, u32 value)
190+{
191+ __raw_writel(value, dd->io_base + offset);
192+}
193+
194+static inline void omap4_sham_write_mask(struct omap4_sham_dev *dd, u32 address,
195+ u32 value, u32 mask)
196+{
197+ u32 val;
198+
199+ val = omap4_sham_read(dd, address);
200+ val &= ~mask;
201+ val |= value;
202+ omap4_sham_write(dd, address, val);
203+}
204+
205+static inline void omap4_sham_write_n(struct omap4_sham_dev *dd, u32 offset,
206+ u32 *value, int count)
207+{
208+ for (; count--; value++, offset += 4)
209+ omap4_sham_write(dd, offset, *value);
210+}
211+
212+static inline int omap4_sham_wait(struct omap4_sham_dev *dd, u32 offset, u32 bit)
213+{
214+ unsigned long timeout = jiffies + DEFAULT_TIMEOUT_INTERVAL;
215+
216+ while (!(omap4_sham_read(dd, offset) & bit)) {
217+ if (time_is_before_jiffies(timeout))
218+ return -ETIMEDOUT;
219+ }
220+
221+ return 0;
222+}
223+
224+static void omap4_sham_copy_hash(struct ahash_request *req, int out)
225+{
226+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(req);
227+ u32 *hash = (u32 *)ctx->digest;
228+ int i;
229+
230+ if (ctx->rflags & BIT(FLAGS_HMAC)) {
231+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(ctx->dd->req);
232+ struct omap4_sham_ctx *tctx = crypto_ahash_ctx(tfm);
233+ struct omap4_sham_hmac_ctx *bctx = tctx->base;
234+
235+ for (i = 0; i < SHA256_DIGEST_SIZE / sizeof(u32); i++) {
236+ if (out)
237+ bctx->odigest[i] = omap4_sham_read(ctx->dd,
238+ SHA_REG_ODIGEST_N(i));
239+ else
240+ omap4_sham_write(ctx->dd,
241+ SHA_REG_ODIGEST_N(i), bctx->odigest[i]);
242+ }
243+ }
244+
245+ /* Copy sha256 size to reduce code */
246+ for (i = 0; i < SHA256_DIGEST_SIZE / sizeof(u32); i++) {
247+ if (out)
248+ hash[i] = omap4_sham_read(ctx->dd,
249+ SHA_REG_IDIGEST_N(i));
250+ else
251+ omap4_sham_write(ctx->dd,
252+ SHA_REG_IDIGEST_N(i), hash[i]);
253+ }
254+}
255+
256+static void omap4_sham_copy_ready_hash(struct ahash_request *req)
257+{
258+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(req);
259+ u32 *in = (u32 *)ctx->digest;
260+ u32 *hash = (u32 *)req->result;
261+ int i, d;
262+
263+ if (!hash)
264+ return;
265+
266+ switch (ctx->rflags & FLAGS_MODE_MASK) {
267+ case FLAGS_MD5:
268+ d = MD5_DIGEST_SIZE / sizeof(u32);
269+ break;
270+ case FLAGS_SHA1:
271+ d = SHA1_DIGEST_SIZE / sizeof(u32);
272+ break;
273+ case FLAGS_SHA224:
274+ d = SHA224_DIGEST_SIZE / sizeof(u32);
275+ break;
276+ case FLAGS_SHA256:
277+ d = SHA256_DIGEST_SIZE / sizeof(u32);
278+ break;
279+ }
280+
281+ /* all results are in little endian */
282+ for (i = 0; i < d; i++)
283+ hash[i] = le32_to_cpu(in[i]);
284+}
285+
286+#if 0
287+static int omap4_sham_hw_init(struct omap4_sham_dev *dd)
288+{
289+ omap4_sham_write(dd, SHA_REG_SYSCFG, SHA_REG_SYSCFG_SOFTRESET);
290+ /*
291+ * prevent OCP bus error (SRESP) in case an access to the module
292+ * is performed while the module is coming out of soft reset
293+ */
294+ __asm__ __volatile__("nop");
295+ __asm__ __volatile__("nop");
296+
297+ if (omap4_sham_wait(dd, SHA_REG_SYSSTATUS, SHA_REG_SYSSTATUS_RESETDONE))
298+ return -ETIMEDOUT;
299+
300+ omap4_sham_write(dd, SHA_REG_SYSCFG,
301+ SHA_REG_SYSCFG_SIDLE_SMARTIDLE | SHA_REG_SYSCFG_AUTOIDLE);
302+ set_bit(FLAGS_INIT, &dd->dflags);
303+ dd->err = 0;
304+
305+ return 0;
306+}
307+#endif
308+
309+static void omap4_sham_write_ctrl(struct omap4_sham_dev *dd, int final, int dma)
310+{
311+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(dd->req);
312+ u32 val, mask;
313+
314+ /*
315+ * Setting ALGO_CONST only for the first iteration and
316+ * CLOSE_HASH only for the last one. Note that flags mode bits
317+ * correspond to algorithm encoding in mode register.
318+ */
319+ val = (ctx->rflags & FLAGS_MODE_MASK) >> (FLAGS_MODE_SHIFT - 1);
320+ if (!ctx->digcnt) {
321+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(dd->req);
322+ struct omap4_sham_ctx *tctx = crypto_ahash_ctx(tfm);
323+ struct omap4_sham_hmac_ctx *bctx = tctx->base;
324+
325+ val |= SHA_REG_MODE_ALGO_CONSTANT;
326+ if (ctx->rflags & BIT(FLAGS_HMAC)) {
327+ val |= SHA_REG_MODE_HMAC_KEY_PROC;
328+ omap4_sham_write_n(dd, SHA_REG_ODIGEST, (u32 *) bctx->keypad,
329+ SHA2_MD5_BLOCK_SIZE / sizeof(u32));
330+ ctx->digcnt += SHA2_MD5_BLOCK_SIZE;
331+ }
332+ }
333+ if (final) {
334+ val |= SHA_REG_MODE_CLOSE_HASH;
335+
336+ if (ctx->rflags & BIT(FLAGS_HMAC)) {
337+ val |= SHA_REG_MODE_HMAC_OUTER_HASH;
338+ }
339+ }
340+
341+ mask = SHA_REG_MODE_ALGO_CONSTANT | SHA_REG_MODE_CLOSE_HASH |
342+ SHA_REG_MODE_ALGO_MASK | SHA_REG_MODE_HMAC_OUTER_HASH |
343+ SHA_REG_MODE_HMAC_KEY_PROC;
344+
345+ dev_dbg(dd->dev, "ctrl: %08x, flags: %08lx\n", val, ctx->rflags);
346+ omap4_sham_write_mask(dd, SHA_REG_MODE, val, mask);
347+ omap4_sham_write(dd, SHA_REG_IRQENA, SHA_REG_IRQENA_OUTPUT_RDY);
348+ omap4_sham_write_mask(dd, SHA_REG_SYSCFG,
349+ SHA_REG_SYSCFG_SIT_EN | (dma ? SHA_REG_SYSCFG_SDMA_EN : 0),
350+ SHA_REG_SYSCFG_SIT_EN | SHA_REG_SYSCFG_SDMA_EN);
351+}
352+
353+static int omap4_sham_xmit_cpu(struct omap4_sham_dev *dd, const u8 *buf,
354+ size_t length, int final)
355+{
356+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(dd->req);
357+ int count, len32;
358+ const u32 *buffer = (const u32 *)buf;
359+
360+ dev_dbg(dd->dev, "xmit_cpu: digcnt: %d, length: %d, final: %d\n",
361+ ctx->digcnt, length, final);
362+
363+ if (final)
364+ set_bit(FLAGS_FINAL, &dd->dflags); /* catch last interrupt */
365+
366+ set_bit(FLAGS_CPU, &dd->dflags);
367+
368+ omap4_sham_write_ctrl(dd, final, 0);
369+ /*
370+ * Setting the length field will also trigger start of
371+ * processing.
372+ */
373+ omap4_sham_write(dd, SHA_REG_LENGTH, length);
374+
375+ /* short-circuit zero length */
376+ if (likely(length)) {
377+ ctx->digcnt += length;
378+
379+ if (omap4_sham_wait(dd, SHA_REG_IRQSTATUS, SHA_REG_IRQSTATUS_INPUT_RDY))
380+ return -ETIMEDOUT;
381+
382+ len32 = DIV_ROUND_UP(length, sizeof(u32));
383+
384+ for (count = 0; count < len32; count++)
385+ omap4_sham_write(dd, SHA_REG_DATA_N(count), buffer[count]);
386+ }
387+
388+ return -EINPROGRESS;
389+}
390+
391+static int omap4_sham_xmit_dma(struct omap4_sham_dev *dd, dma_addr_t dma_addr,
392+ size_t length, int final)
393+{
394+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(dd->req);
395+ int nblocks;
396+ struct edmacc_param p_ram;
397+
398+ dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n",
399+ ctx->digcnt, length, final);
400+
401+ nblocks = DIV_ROUND_UP(length, SHA2_MD5_BLOCK_SIZE);
402+
403+ /* EDMA IN */
404+ p_ram.opt = TCINTEN |
405+ EDMA_TCC(EDMA_CHAN_SLOT(dd->dma_lch));
406+ p_ram.src = dma_addr;
407+ p_ram.a_b_cnt = SHA2_MD5_BLOCK_SIZE | nblocks << 16;
408+ p_ram.dst = dd->phys_base + SHA_REG_DATA;
409+ p_ram.src_dst_bidx = SHA2_MD5_BLOCK_SIZE;
410+ p_ram.link_bcntrld = 1 << 16 | 0xFFFF;
411+ p_ram.src_dst_cidx = 0;
412+ p_ram.ccnt = 1;
413+ edma_write_slot(dd->dma_lch, &p_ram);
414+
415+ omap4_sham_write_ctrl(dd, final, 1);
416+
417+ ctx->digcnt += length;
418+
419+ if (final)
420+ set_bit(FLAGS_FINAL, &dd->dflags); /* catch last interrupt */
421+
422+ set_bit(FLAGS_DMA_ACTIVE, &dd->dflags);
423+
424+ edma_start(dd->dma_lch);
425+
426+ /*
427+ * Setting the length field will also trigger start of
428+ * processing.
429+ */
430+ omap4_sham_write(dd, SHA_REG_LENGTH, length);
431+
432+ return -EINPROGRESS;
433+}
434+
435+static size_t omap4_sham_append_buffer(struct omap4_sham_reqctx *ctx,
436+ const u8 *data, size_t length)
437+{
438+ size_t count = min(length, ctx->buflen - ctx->bufcnt);
439+
440+ count = min(count, ctx->total);
441+ if (count <= 0)
442+ return 0;
443+ memcpy(ctx->buffer + ctx->bufcnt, data, count);
444+ ctx->bufcnt += count;
445+
446+ return count;
447+}
448+
449+static size_t omap4_sham_append_sg(struct omap4_sham_reqctx *ctx)
450+{
451+ size_t count;
452+
453+ while (ctx->sg) {
454+ if (ctx->sg->length) {
455+ count = omap4_sham_append_buffer(ctx,
456+ sg_virt(ctx->sg) + ctx->offset,
457+ ctx->sg->length - ctx->offset);
458+ if (!count)
459+ break;
460+ ctx->offset += count;
461+ ctx->total -= count;
462+ }
463+ if (ctx->offset == ctx->sg->length) {
464+ ctx->sg = sg_next(ctx->sg);
465+ if (ctx->sg)
466+ ctx->offset = 0;
467+ else
468+ ctx->total = 0;
469+ }
470+ }
471+
472+ return 0;
473+}
474+
475+static int omap4_sham_xmit_dma_map(struct omap4_sham_dev *dd,
476+ struct omap4_sham_reqctx *ctx,
477+ size_t length, int final)
478+{
479+ ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, ctx->buflen,
480+ DMA_TO_DEVICE);
481+ if (dma_mapping_error(dd->dev, ctx->dma_addr)) {
482+ dev_err(dd->dev, "dma %u bytes error\n", ctx->buflen);
483+ return -EINVAL;
484+ }
485+
486+ ctx->rflags &= ~BIT(FLAGS_SG);
487+
488+ /* next call does not fail... so no unmap in the case of error */
489+ return omap4_sham_xmit_dma(dd, ctx->dma_addr, length, final);
490+}
491+
492+static int omap4_sham_update_dma_slow(struct omap4_sham_dev *dd)
493+{
494+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(dd->req);
495+ unsigned int final;
496+ size_t count;
497+
498+ omap4_sham_append_sg(ctx);
499+
500+ final = (ctx->rflags & BIT(FLAGS_FINUP)) && !ctx->total;
501+
502+ dev_dbg(dd->dev, "slow: bufcnt: %u, digcnt: %d, final: %d\n",
503+ ctx->bufcnt, ctx->digcnt, final);
504+
505+ if (final || (ctx->bufcnt == ctx->buflen && ctx->total)) {
506+ count = ctx->bufcnt;
507+ ctx->bufcnt = 0;
508+ return omap4_sham_xmit_dma_map(dd, ctx, count, final);
509+ }
510+
511+ return 0;
512+}
513+
514+/* Start address alignment */
515+#define SG_AA(sg) (IS_ALIGNED(sg->offset, sizeof(u32)))
516+/* SHA1 block size alignment */
517+#define SG_SA(sg) (IS_ALIGNED(sg->length, SHA2_MD5_BLOCK_SIZE))
518+
519+static int omap4_sham_update_dma_start(struct omap4_sham_dev *dd)
520+{
521+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(dd->req);
522+ unsigned int length, final, tail;
523+ struct scatterlist *sg;
524+
525+ if (!ctx->total)
526+ return 0;
527+
528+ if (ctx->bufcnt || ctx->offset)
529+ return omap4_sham_update_dma_slow(dd);
530+
531+ dev_dbg(dd->dev, "fast: digcnt: %d, bufcnt: %u, total: %u\n",
532+ ctx->digcnt, ctx->bufcnt, ctx->total);
533+
534+ sg = ctx->sg;
535+
536+ if (!SG_AA(sg))
537+ return omap4_sham_update_dma_slow(dd);
538+
539+ if (!sg_is_last(sg) && !SG_SA(sg))
540+ /* size is not SHA1_BLOCK_SIZE aligned */
541+ return omap4_sham_update_dma_slow(dd);
542+
543+ length = min(ctx->total, sg->length);
544+
545+ if (sg_is_last(sg)) {
546+ if (!(ctx->rflags & BIT(FLAGS_FINUP))) {
547+ /* not last sg must be SHA2_MD5_BLOCK_SIZE aligned */
548+ tail = length & (SHA2_MD5_BLOCK_SIZE - 1);
549+ /* without finup() we need one block to close hash */
550+ if (!tail)
551+ tail = SHA2_MD5_BLOCK_SIZE;
552+ length -= tail;
553+ }
554+ }
555+
556+ if (!dma_map_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE)) {
557+ dev_err(dd->dev, "dma_map_sg error\n");
558+ return -EINVAL;
559+ }
560+
561+ ctx->rflags |= BIT(FLAGS_SG);
562+
563+ ctx->total -= length;
564+ ctx->offset = length; /* offset where to start slow */
565+
566+ final = (ctx->rflags & BIT(FLAGS_FINUP)) && !ctx->total;
567+
568+ /* next call does not fail... so no unmap in the case of error */
569+ return omap4_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, final);
570+}
571+
572+static int omap4_sham_update_cpu(struct omap4_sham_dev *dd)
573+{
574+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(dd->req);
575+ int bufcnt;
576+
577+ omap4_sham_append_sg(ctx);
578+ bufcnt = ctx->bufcnt;
579+ ctx->bufcnt = 0;
580+
581+ return omap4_sham_xmit_cpu(dd, ctx->buffer, bufcnt, 1);
582+}
583+
584+static int omap4_sham_update_dma_stop(struct omap4_sham_dev *dd)
585+{
586+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(dd->req);
587+
588+ edma_stop(dd->dma_lch);
589+ if (ctx->rflags & BIT(FLAGS_SG)) {
590+ dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
591+ if (ctx->sg->length == ctx->offset) {
592+ ctx->sg = sg_next(ctx->sg);
593+ if (ctx->sg)
594+ ctx->offset = 0;
595+ }
596+ } else {
597+ dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen,
598+ DMA_TO_DEVICE);
599+ }
600+
601+ return 0;
602+}
603+
604+static int omap4_sham_init(struct ahash_request *req)
605+{
606+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
607+ struct omap4_sham_ctx *tctx = crypto_ahash_ctx(tfm);
608+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(req);
609+ struct omap4_sham_dev *dd = NULL, *tmp;
610+
611+ spin_lock_bh(&sham.lock);
612+ if (!tctx->dd) {
613+ list_for_each_entry(tmp, &sham.dev_list, list) {
614+ dd = tmp;
615+ break;
616+ }
617+ tctx->dd = dd;
618+ } else {
619+ dd = tctx->dd;
620+ }
621+ spin_unlock_bh(&sham.lock);
622+
623+ ctx->dd = dd;
624+
625+ ctx->rflags = 0;
626+
627+ dev_dbg(dd->dev, "init: digest size: %d (@0x%08lx)\n",
628+ crypto_ahash_digestsize(tfm), dd->phys_base);
629+
630+ switch (crypto_ahash_digestsize(tfm)) {
631+ case MD5_DIGEST_SIZE:
632+ ctx->rflags |= FLAGS_MD5;
633+ break;
634+ case SHA1_DIGEST_SIZE:
635+ ctx->rflags |= FLAGS_SHA1;
636+ break;
637+ case SHA224_DIGEST_SIZE:
638+ ctx->rflags |= FLAGS_SHA224;
639+ break;
640+ case SHA256_DIGEST_SIZE:
641+ ctx->rflags |= FLAGS_SHA256;
642+ break;
643+ }
644+
645+ ctx->bufcnt = 0;
646+ ctx->digcnt = 0;
647+ ctx->buflen = BUFLEN;
648+
649+ if (tctx->cflags & BIT(FLAGS_HMAC)) {
650+ ctx->rflags |= BIT(FLAGS_HMAC);
651+ }
652+
653+ return 0;
654+}
655+
656+static int omap4_sham_update_req(struct omap4_sham_dev *dd)
657+{
658+ struct ahash_request *req = dd->req;
659+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(req);
660+ int err;
661+
662+ dev_dbg(dd->dev, "update_req: total: %u, digcnt: %d, finup: %d\n",
663+ ctx->total, ctx->digcnt, (ctx->rflags & BIT(FLAGS_FINUP)) != 0);
664+
665+ if (ctx->rflags & BIT(FLAGS_CPU))
666+ err = omap4_sham_update_cpu(dd);
667+ else
668+ err = omap4_sham_update_dma_start(dd);
669+
670+ /* wait for dma completion before can take more data */
671+ dev_dbg(dd->dev, "update: err: %d, digcnt: %d\n", err, ctx->digcnt);
672+
673+ return err;
674+}
675+
676+static int omap4_sham_final_req(struct omap4_sham_dev *dd)
677+{
678+ struct ahash_request *req = dd->req;
679+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(req);
680+ int err = 0;
681+
682+ if (ctx->bufcnt <= SHA2_MD5_BLOCK_SIZE) /* faster to handle single block with CPU */
683+ err = omap4_sham_xmit_cpu(dd, ctx->buffer, ctx->bufcnt, 1);
684+ else
685+ err = omap4_sham_xmit_dma_map(dd, ctx, ctx->bufcnt, 1);
686+
687+ ctx->bufcnt = 0;
688+
689+ dev_dbg(dd->dev, "final_req: err: %d\n", err);
690+
691+ return err;
692+}
693+
694+static int omap4_sham_finish(struct ahash_request *req)
695+{
696+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(req);
697+ struct omap4_sham_dev *dd = ctx->dd;
698+
699+ omap4_sham_copy_ready_hash(req);
700+ dev_dbg(dd->dev, "digcnt: %d, bufcnt: %d\n", ctx->digcnt, ctx->bufcnt);
701+
702+ return 0;
703+}
704+
705+static void omap4_sham_finish_req(struct ahash_request *req, int err)
706+{
707+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(req);
708+ struct omap4_sham_dev *dd = ctx->dd;
709+
710+ if (!err) {
711+ omap4_sham_copy_hash(req, 1);
712+ if (test_bit(FLAGS_FINAL, &dd->dflags)) {
713+ err = omap4_sham_finish(req);
714+ }
715+ } else {
716+ ctx->rflags |= BIT(FLAGS_ERROR);
717+ }
718+
719+ /* atomic operation is not needed here */
720+ dd->dflags &= ~(BIT(FLAGS_BUSY) | BIT(FLAGS_FINAL) | BIT(FLAGS_CPU) |
721+ BIT(FLAGS_DMA_READY) | BIT(FLAGS_OUTPUT_READY));
722+ clk_disable(dd->iclk);
723+
724+ if (req->base.complete)
725+ req->base.complete(&req->base, err);
726+
727+ /* handle new request */
728+ tasklet_schedule(&dd->done_task);
729+}
730+
731+static int omap4_sham_handle_queue(struct omap4_sham_dev *dd,
732+ struct ahash_request *req)
733+{
734+ struct crypto_async_request *async_req, *backlog;
735+ struct omap4_sham_reqctx *ctx;
736+ unsigned long flags;
737+ int err = 0, ret = 0;
738+
739+ spin_lock_irqsave(&dd->lock, flags);
740+ if (req)
741+ ret = ahash_enqueue_request(&dd->queue, req);
742+ if (test_bit(FLAGS_BUSY, &dd->dflags)) {
743+ spin_unlock_irqrestore(&dd->lock, flags);
744+ return ret;
745+ }
746+ backlog = crypto_get_backlog(&dd->queue);
747+ async_req = crypto_dequeue_request(&dd->queue);
748+ if (async_req)
749+ set_bit(FLAGS_BUSY, &dd->dflags);
750+ spin_unlock_irqrestore(&dd->lock, flags);
751+
752+ if (!async_req)
753+ return ret;
754+
755+ if (backlog)
756+ backlog->complete(backlog, -EINPROGRESS);
757+
758+ req = ahash_request_cast(async_req);
759+ dd->req = req;
760+ ctx = ahash_request_ctx(req);
761+
762+ dev_dbg(dd->dev, "handling new req, op: %lu, nbytes: %d\n",
763+ ctx->op, req->nbytes);
764+
765+ clk_enable(dd->iclk);
766+ if (!test_bit(FLAGS_INIT, &dd->dflags)) {
767+ set_bit(FLAGS_INIT, &dd->dflags);
768+ dd->err = 0;
769+ }
770+
771+ if (ctx->digcnt) /* not initial request - restore hash */
772+ omap4_sham_copy_hash(req, 0);
773+
774+ if (ctx->op == OP_UPDATE) {
775+ err = omap4_sham_update_req(dd);
776+ if (err != -EINPROGRESS && (ctx->rflags & BIT(FLAGS_FINUP)))
777+ /* no final() after finup() */
778+ err = omap4_sham_final_req(dd);
779+ } else if (ctx->op == OP_FINAL) {
780+ err = omap4_sham_final_req(dd);
781+ }
782+
783+ if (err != -EINPROGRESS)
784+ /* done_task will not finish it, so do it here */
785+ omap4_sham_finish_req(req, err);
786+
787+ dev_dbg(dd->dev, "exit, err: %d\n", err);
788+
789+ return ret;
790+}
791+
792+static int omap4_sham_enqueue(struct ahash_request *req, unsigned int op)
793+{
794+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(req);
795+ struct omap4_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
796+ struct omap4_sham_dev *dd = tctx->dd;
797+
798+ ctx->op = op;
799+
800+ return omap4_sham_handle_queue(dd, req);
801+}
802+
803+static int omap4_sham_update(struct ahash_request *req)
804+{
805+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(req);
806+
807+ if (!(ctx->rflags & BIT(FLAGS_FINUP)))
808+ if (!req->nbytes)
809+ return 0;
810+
811+ ctx->total = req->nbytes;
812+ ctx->sg = req->src;
813+ ctx->offset = 0;
814+
815+ if (ctx->rflags & BIT(FLAGS_FINUP)) {
816+ if (ctx->bufcnt + ctx->total <= SHA2_MD5_BLOCK_SIZE) {
817+ /*
818+ * faster to use CPU for short transfers
819+ */
820+ ctx->rflags |= BIT(FLAGS_CPU);
821+ }
822+ } else if (ctx->bufcnt + ctx->total < ctx->buflen) {
823+ omap4_sham_append_sg(ctx);
824+ return 0;
825+ }
826+
827+ return omap4_sham_enqueue(req, OP_UPDATE);
828+}
829+
830+static int omap4_sham_shash_digest(struct crypto_shash *shash, u32 flags,
831+ const u8 *data, unsigned int len, u8 *out)
832+{
833+ struct {
834+ struct shash_desc shash;
835+ char ctx[crypto_shash_descsize(shash)];
836+ } desc;
837+
838+ desc.shash.tfm = shash;
839+ desc.shash.flags = flags & CRYPTO_TFM_REQ_MAY_SLEEP;
840+
841+ return crypto_shash_digest(&desc.shash, data, len, out);
842+}
843+
844+static int omap4_sham_final(struct ahash_request *req)
845+{
846+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(req);
847+
848+ ctx->rflags |= BIT(FLAGS_FINUP);
849+
850+ if (ctx->rflags & BIT(FLAGS_ERROR))
851+ return 0; /* uncompleted hash is not needed */
852+
853+ return omap4_sham_enqueue(req, OP_FINAL);
854+}
855+
856+static int omap4_sham_finup(struct ahash_request *req)
857+{
858+ struct omap4_sham_reqctx *ctx = ahash_request_ctx(req);
859+ int err1, err2;
860+
861+ ctx->rflags |= BIT(FLAGS_FINUP);
862+
863+ err1 = omap4_sham_update(req);
864+ if (err1 == -EINPROGRESS || err1 == -EBUSY)
865+ return err1;
866+ /*
867+ * final() has to be always called to cleanup resources
868+ * even if update() failed, except EINPROGRESS
869+ */
870+ err2 = omap4_sham_final(req);
871+
872+ return err1 ?: err2;
873+}
874+
875+static int omap4_sham_digest(struct ahash_request *req)
876+{
877+ return omap4_sham_init(req) ?: omap4_sham_finup(req);
878+}
879+
880+static int omap4_sham_setkey(struct crypto_ahash *tfm, const u8 *key,
881+ unsigned int keylen)
882+{
883+ struct omap4_sham_ctx *tctx = crypto_ahash_ctx(tfm);
884+ struct omap4_sham_hmac_ctx *bctx = tctx->base;
885+ int bs = crypto_shash_blocksize(bctx->shash);
886+ int ds = crypto_shash_digestsize(bctx->shash);
887+ int err;
888+
889+ /* If key is longer than block size, use hash of original key */
890+ if (keylen > bs) {
891+ err = crypto_shash_setkey(tctx->fallback, key, keylen) ?:
892+ omap4_sham_shash_digest(bctx->shash,
893+ crypto_shash_get_flags(bctx->shash),
894+ key, keylen, bctx->keypad);
895+ if (err)
896+ return err;
897+ keylen = ds;
898+ } else {
899+ memcpy(bctx->keypad, key, keylen);
900+ }
901+
902+ /* zero-pad the key (or its digest) */
903+ if (keylen < bs)
904+ memset(bctx->keypad + keylen, 0, bs - keylen);
905+
906+ return 0;
907+}
908+
909+static int omap4_sham_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base)
910+{
911+ struct omap4_sham_ctx *tctx = crypto_tfm_ctx(tfm);
912+ const char *alg_name = crypto_tfm_alg_name(tfm);
913+
914+ /* Allocate a fallback and abort if it failed. */
915+ tctx->fallback = crypto_alloc_shash(alg_name, 0,
916+ CRYPTO_ALG_NEED_FALLBACK);
917+ if (IS_ERR(tctx->fallback)) {
918+ pr_err("omap4-sham: fallback driver '%s' "
919+ "could not be loaded.\n", alg_name);
920+ return PTR_ERR(tctx->fallback);
921+ }
922+
923+ crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
924+ sizeof(struct omap4_sham_reqctx) + BUFLEN);
925+
926+ if (alg_base) {
927+ struct omap4_sham_hmac_ctx *bctx = tctx->base;
928+ tctx->cflags |= BIT(FLAGS_HMAC);
929+ bctx->shash = crypto_alloc_shash(alg_base, 0,
930+ CRYPTO_ALG_NEED_FALLBACK);
931+ if (IS_ERR(bctx->shash)) {
932+ pr_err("omap4-sham: base driver '%s' "
933+ "could not be loaded.\n", alg_base);
934+ crypto_free_shash(tctx->fallback);
935+ return PTR_ERR(bctx->shash);
936+ }
937+
938+ }
939+
940+ return 0;
941+}
942+
943+static int omap4_sham_cra_init(struct crypto_tfm *tfm)
944+{
945+ return omap4_sham_cra_init_alg(tfm, NULL);
946+}
947+
948+static int omap4_sham_cra_sha1_init(struct crypto_tfm *tfm)
949+{
950+ return omap4_sham_cra_init_alg(tfm, "sha1");
951+}
952+
953+static int omap4_sham_cra_sha224_init(struct crypto_tfm *tfm)
954+{
955+ return omap4_sham_cra_init_alg(tfm, "sha224");
956+}
957+
958+static int omap4_sham_cra_sha256_init(struct crypto_tfm *tfm)
959+{
960+ return omap4_sham_cra_init_alg(tfm, "sha256");
961+}
962+
963+static int omap4_sham_cra_md5_init(struct crypto_tfm *tfm)
964+{
965+ return omap4_sham_cra_init_alg(tfm, "md5");
966+}
967+
968+static void omap4_sham_cra_exit(struct crypto_tfm *tfm)
969+{
970+ struct omap4_sham_ctx *tctx = crypto_tfm_ctx(tfm);
971+
972+ crypto_free_shash(tctx->fallback);
973+ tctx->fallback = NULL;
974+
975+ if (tctx->cflags & BIT(FLAGS_HMAC)) {
976+ struct omap4_sham_hmac_ctx *bctx = tctx->base;
977+ crypto_free_shash(bctx->shash);
978+ }
979+}
980+
981+static struct ahash_alg algs[] = {
982+{
983+ .init = omap4_sham_init,
984+ .update = omap4_sham_update,
985+ .final = omap4_sham_final,
986+ .finup = omap4_sham_finup,
987+ .digest = omap4_sham_digest,
988+ .halg.digestsize = SHA1_DIGEST_SIZE,
989+ .halg.base = {
990+ .cra_name = "sha1",
991+ .cra_driver_name = "omap4-sha1",
992+ .cra_priority = 300,
993+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
994+ CRYPTO_ALG_ASYNC |
995+ CRYPTO_ALG_NEED_FALLBACK,
996+ .cra_blocksize = SHA1_BLOCK_SIZE,
997+ .cra_ctxsize = sizeof(struct omap4_sham_ctx),
998+ .cra_alignmask = 0,
999+ .cra_module = THIS_MODULE,
1000+ .cra_init = omap4_sham_cra_init,
1001+ .cra_exit = omap4_sham_cra_exit,
1002+ }
1003+},
1004+{
1005+ .init = omap4_sham_init,
1006+ .update = omap4_sham_update,
1007+ .final = omap4_sham_final,
1008+ .finup = omap4_sham_finup,
1009+ .digest = omap4_sham_digest,
1010+ .halg.digestsize = SHA224_DIGEST_SIZE,
1011+ .halg.base = {
1012+ .cra_name = "sha224",
1013+ .cra_driver_name = "omap4-sha224",
1014+ .cra_priority = 300,
1015+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
1016+ CRYPTO_ALG_ASYNC |
1017+ CRYPTO_ALG_NEED_FALLBACK,
1018+ .cra_blocksize = SHA224_BLOCK_SIZE,
1019+ .cra_ctxsize = sizeof(struct omap4_sham_ctx),
1020+ .cra_alignmask = 0,
1021+ .cra_module = THIS_MODULE,
1022+ .cra_init = omap4_sham_cra_init,
1023+ .cra_exit = omap4_sham_cra_exit,
1024+ }
1025+},
1026+{
1027+ .init = omap4_sham_init,
1028+ .update = omap4_sham_update,
1029+ .final = omap4_sham_final,
1030+ .finup = omap4_sham_finup,
1031+ .digest = omap4_sham_digest,
1032+ .halg.digestsize = SHA256_DIGEST_SIZE,
1033+ .halg.base = {
1034+ .cra_name = "sha256",
1035+ .cra_driver_name = "omap4-sha256",
1036+ .cra_priority = 300,
1037+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
1038+ CRYPTO_ALG_ASYNC |
1039+ CRYPTO_ALG_NEED_FALLBACK,
1040+ .cra_blocksize = SHA256_BLOCK_SIZE,
1041+ .cra_ctxsize = sizeof(struct omap4_sham_ctx),
1042+ .cra_alignmask = 0,
1043+ .cra_module = THIS_MODULE,
1044+ .cra_init = omap4_sham_cra_init,
1045+ .cra_exit = omap4_sham_cra_exit,
1046+ }
1047+},
1048+{
1049+ .init = omap4_sham_init,
1050+ .update = omap4_sham_update,
1051+ .final = omap4_sham_final,
1052+ .finup = omap4_sham_finup,
1053+ .digest = omap4_sham_digest,
1054+ .halg.digestsize = MD5_DIGEST_SIZE,
1055+ .halg.base = {
1056+ .cra_name = "md5",
1057+ .cra_driver_name = "omap4-md5",
1058+ .cra_priority = 300,
1059+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
1060+ CRYPTO_ALG_ASYNC |
1061+ CRYPTO_ALG_NEED_FALLBACK,
1062+ .cra_blocksize = SHA1_BLOCK_SIZE,
1063+ .cra_ctxsize = sizeof(struct omap4_sham_ctx),
1064+ .cra_alignmask = AM33X_ALIGN_MASK,
1065+ .cra_module = THIS_MODULE,
1066+ .cra_init = omap4_sham_cra_init,
1067+ .cra_exit = omap4_sham_cra_exit,
1068+ }
1069+},
1070+{
1071+ .init = omap4_sham_init,
1072+ .update = omap4_sham_update,
1073+ .final = omap4_sham_final,
1074+ .finup = omap4_sham_finup,
1075+ .digest = omap4_sham_digest,
1076+ .setkey = omap4_sham_setkey,
1077+ .halg.digestsize = SHA1_DIGEST_SIZE,
1078+ .halg.base = {
1079+ .cra_name = "hmac(sha1)",
1080+ .cra_driver_name = "omap4-hmac-sha1",
1081+ .cra_priority = 300,
1082+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
1083+ CRYPTO_ALG_ASYNC |
1084+ CRYPTO_ALG_NEED_FALLBACK,
1085+ .cra_blocksize = SHA1_BLOCK_SIZE,
1086+ .cra_ctxsize = sizeof(struct omap4_sham_ctx) +
1087+ sizeof(struct omap4_sham_hmac_ctx),
1088+ .cra_alignmask = AM33X_ALIGN_MASK,
1089+ .cra_module = THIS_MODULE,
1090+ .cra_init = omap4_sham_cra_sha1_init,
1091+ .cra_exit = omap4_sham_cra_exit,
1092+ }
1093+},
1094+{
1095+ .init = omap4_sham_init,
1096+ .update = omap4_sham_update,
1097+ .final = omap4_sham_final,
1098+ .finup = omap4_sham_finup,
1099+ .digest = omap4_sham_digest,
1100+ .setkey = omap4_sham_setkey,
1101+ .halg.digestsize = SHA224_DIGEST_SIZE,
1102+ .halg.base = {
1103+ .cra_name = "hmac(sha224)",
1104+ .cra_driver_name = "omap4-hmac-sha224",
1105+ .cra_priority = 300,
1106+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
1107+ CRYPTO_ALG_ASYNC |
1108+ CRYPTO_ALG_NEED_FALLBACK,
1109+ .cra_blocksize = SHA224_BLOCK_SIZE,
1110+ .cra_ctxsize = sizeof(struct omap4_sham_ctx) +
1111+ sizeof(struct omap4_sham_hmac_ctx),
1112+ .cra_alignmask = AM33X_ALIGN_MASK,
1113+ .cra_module = THIS_MODULE,
1114+ .cra_init = omap4_sham_cra_sha224_init,
1115+ .cra_exit = omap4_sham_cra_exit,
1116+ }
1117+},
1118+{
1119+ .init = omap4_sham_init,
1120+ .update = omap4_sham_update,
1121+ .final = omap4_sham_final,
1122+ .finup = omap4_sham_finup,
1123+ .digest = omap4_sham_digest,
1124+ .setkey = omap4_sham_setkey,
1125+ .halg.digestsize = SHA256_DIGEST_SIZE,
1126+ .halg.base = {
1127+ .cra_name = "hmac(sha256)",
1128+ .cra_driver_name = "omap4-hmac-sha256",
1129+ .cra_priority = 300,
1130+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
1131+ CRYPTO_ALG_ASYNC |
1132+ CRYPTO_ALG_NEED_FALLBACK,
1133+ .cra_blocksize = SHA256_BLOCK_SIZE,
1134+ .cra_ctxsize = sizeof(struct omap4_sham_ctx) +
1135+ sizeof(struct omap4_sham_hmac_ctx),
1136+ .cra_alignmask = AM33X_ALIGN_MASK,
1137+ .cra_module = THIS_MODULE,
1138+ .cra_init = omap4_sham_cra_sha256_init,
1139+ .cra_exit = omap4_sham_cra_exit,
1140+ }
1141+},
1142+{
1143+ .init = omap4_sham_init,
1144+ .update = omap4_sham_update,
1145+ .final = omap4_sham_final,
1146+ .finup = omap4_sham_finup,
1147+ .digest = omap4_sham_digest,
1148+ .setkey = omap4_sham_setkey,
1149+ .halg.digestsize = MD5_DIGEST_SIZE,
1150+ .halg.base = {
1151+ .cra_name = "hmac(md5)",
1152+ .cra_driver_name = "omap4-hmac-md5",
1153+ .cra_priority = 300,
1154+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
1155+ CRYPTO_ALG_ASYNC |
1156+ CRYPTO_ALG_NEED_FALLBACK,
1157+ .cra_blocksize = SHA1_BLOCK_SIZE,
1158+ .cra_ctxsize = sizeof(struct omap4_sham_ctx) +
1159+ sizeof(struct omap4_sham_hmac_ctx),
1160+ .cra_alignmask = AM33X_ALIGN_MASK,
1161+ .cra_module = THIS_MODULE,
1162+ .cra_init = omap4_sham_cra_md5_init,
1163+ .cra_exit = omap4_sham_cra_exit,
1164+ }
1165+}
1166+};
1167+
1168+static void omap4_sham_done_task(unsigned long data)
1169+{
1170+ struct omap4_sham_dev *dd = (struct omap4_sham_dev *)data;
1171+ int err = 0;
1172+
1173+ if (!test_bit(FLAGS_BUSY, &dd->dflags)) {
1174+ omap4_sham_handle_queue(dd, NULL);
1175+ return;
1176+ }
1177+
1178+ if (test_bit(FLAGS_CPU, &dd->dflags)) {
1179+ if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->dflags))
1180+ goto finish;
1181+ } else if (test_bit(FLAGS_OUTPUT_READY, &dd->dflags)) {
1182+ if (test_and_clear_bit(FLAGS_DMA_ACTIVE, &dd->dflags)) {
1183+ omap4_sham_update_dma_stop(dd);
1184+ if (dd->err) {
1185+ err = dd->err;
1186+ goto finish;
1187+ }
1188+ }
1189+ if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->dflags)) {
1190+ /* hash or semi-hash ready */
1191+ clear_bit(FLAGS_DMA_READY, &dd->dflags);
1192+ err = omap4_sham_update_dma_start(dd);
1193+ if (err != -EINPROGRESS)
1194+ goto finish;
1195+ }
1196+ }
1197+
1198+ return;
1199+
1200+finish:
1201+ dev_dbg(dd->dev, "update done: err: %d\n", err);
1202+ /* finish current request */
1203+ omap4_sham_finish_req(dd->req, err);
1204+}
1205+
1206+static irqreturn_t omap4_sham_irq(int irq, void *dev_id)
1207+{
1208+ struct omap4_sham_dev *dd = dev_id;
1209+
1210+#if 0
1211+ if (unlikely(test_bit(FLAGS_FINAL, &dd->flags)))
1212+ /* final -> allow device to go to power-saving mode */
1213+ omap4_sham_write_mask(dd, SHA_REG_CTRL, 0, SHA_REG_CTRL_LENGTH);
1214+#endif
1215+
1216+ /* TODO check whether the result needs to be read out here,
1217+ or if we just disable the interrupt */
1218+ omap4_sham_write_mask(dd, SHA_REG_SYSCFG, 0, SHA_REG_SYSCFG_SIT_EN);
1219+
1220+ if (!test_bit(FLAGS_BUSY, &dd->dflags)) {
1221+ dev_warn(dd->dev, "Interrupt when no active requests.\n");
1222+ } else {
1223+ set_bit(FLAGS_OUTPUT_READY, &dd->dflags);
1224+ tasklet_schedule(&dd->done_task);
1225+ }
1226+
1227+ return IRQ_HANDLED;
1228+}
1229+
1230+static void omap4_sham_dma_callback(unsigned int lch, u16 ch_status, void *data)
1231+{
1232+ struct omap4_sham_dev *dd = data;
1233+
1234+ edma_stop(lch);
1235+
1236+ if (ch_status != DMA_COMPLETE) {
1237+ pr_err("omap4-sham DMA error status: 0x%hx\n", ch_status);
1238+ dd->err = -EIO;
1239+ clear_bit(FLAGS_INIT, &dd->dflags); /* request to re-initialize */
1240+ }
1241+
1242+ set_bit(FLAGS_DMA_READY, &dd->dflags);
1243+ tasklet_schedule(&dd->done_task);
1244+}
1245+
1246+static int omap4_sham_dma_init(struct omap4_sham_dev *dd)
1247+{
1248+ int err;
1249+
1250+ dd->dma_lch = -1;
1251+
1252+ dd->dma_lch = edma_alloc_channel(dd->dma, omap4_sham_dma_callback, dd, EVENTQ_2);
1253+ if (dd->dma_lch < 0) {
1254+ dev_err(dd->dev, "Unable to request EDMA channel\n");
1255+ return -1;
1256+ }
1257+
1258+ return 0;
1259+}
1260+
1261+static void omap4_sham_dma_cleanup(struct omap4_sham_dev *dd)
1262+{
1263+ if (dd->dma_lch >= 0) {
1264+ edma_free_channel(dd->dma_lch);
1265+ dd->dma_lch = -1;
1266+ }
1267+}
1268+
1269+static int __devinit omap4_sham_probe(struct platform_device *pdev)
1270+{
1271+ struct omap4_sham_dev *dd;
1272+ struct device *dev = &pdev->dev;
1273+ struct resource *res;
1274+ int err, i, j;
1275+ u32 reg;
1276+
1277+ dd = kzalloc(sizeof(struct omap4_sham_dev), GFP_KERNEL);
1278+ if (dd == NULL) {
1279+ dev_err(dev, "unable to alloc data struct.\n");
1280+ err = -ENOMEM;
1281+ goto data_err;
1282+ }
1283+ dd->dev = dev;
1284+ platform_set_drvdata(pdev, dd);
1285+
1286+ INIT_LIST_HEAD(&dd->list);
1287+ spin_lock_init(&dd->lock);
1288+ tasklet_init(&dd->done_task, omap4_sham_done_task, (unsigned long)dd);
1289+ crypto_init_queue(&dd->queue, AM33X_SHAM_QUEUE_LENGTH);
1290+
1291+ dd->irq = -1;
1292+
1293+ /* Get the base address */
1294+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1295+ if (!res) {
1296+ dev_err(dev, "no MEM resource info\n");
1297+ err = -ENODEV;
1298+ goto res_err;
1299+ }
1300+ dd->phys_base = res->start;
1301+
1302+ /* Get the DMA */
1303+ res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1304+ if (!res) {
1305+ dev_err(dev, "no DMA resource info\n");
1306+ err = -ENODEV;
1307+ goto res_err;
1308+ }
1309+ dd->dma = res->start;
1310+
1311+ /* Get the IRQ */
1312+ dd->irq = platform_get_irq(pdev, 0);
1313+ if (dd->irq < 0) {
1314+ dev_err(dev, "no IRQ resource info\n");
1315+ err = dd->irq;
1316+ goto res_err;
1317+ }
1318+
1319+ err = request_irq(dd->irq, omap4_sham_irq,
1320+ IRQF_TRIGGER_LOW, dev_name(dev), dd);
1321+ if (err) {
1322+ dev_err(dev, "unable to request irq.\n");
1323+ goto res_err;
1324+ }
1325+
1326+ err = omap4_sham_dma_init(dd);
1327+ if (err)
1328+ goto dma_err;
1329+
1330+ /* Initializing the clock */
1331+ dd->iclk = clk_get(dev, "sha0_fck");
1332+ if (IS_ERR(dd->iclk)) {
1333+ dev_err(dev, "clock initialization failed.\n");
1334+ err = PTR_ERR(dd->iclk);
1335+ goto clk_err;
1336+ }
1337+
1338+ dd->io_base = ioremap(dd->phys_base, SZ_4K);
1339+ if (!dd->io_base) {
1340+ dev_err(dev, "can't ioremap\n");
1341+ err = -ENOMEM;
1342+ goto io_err;
1343+ }
1344+
1345+ clk_enable(dd->iclk);
1346+ reg = omap4_sham_read(dd, SHA_REG_REV);
1347+ clk_disable(dd->iclk);
1348+
1349+ dev_info(dev, "AM33X SHA/MD5 hw accel rev: %u.%02u\n",
1350+ (reg & SHA_REG_REV_X_MAJOR_MASK) >> 8, reg & SHA_REG_REV_Y_MINOR_MASK);
1351+
1352+ spin_lock(&sham.lock);
1353+ list_add_tail(&dd->list, &sham.dev_list);
1354+ spin_unlock(&sham.lock);
1355+
1356+ for (i = 0; i < ARRAY_SIZE(algs); i++) {
1357+ err = crypto_register_ahash(&algs[i]);
1358+ if (err)
1359+ goto err_algs;
1360+ }
1361+
1362+ pr_info("probe() done\n");
1363+
1364+ return 0;
1365+
1366+err_algs:
1367+ for (j = 0; j < i; j++)
1368+ crypto_unregister_ahash(&algs[j]);
1369+ iounmap(dd->io_base);
1370+io_err:
1371+ clk_put(dd->iclk);
1372+clk_err:
1373+ omap4_sham_dma_cleanup(dd);
1374+dma_err:
1375+ if (dd->irq >= 0)
1376+ free_irq(dd->irq, dd);
1377+res_err:
1378+ kfree(dd);
1379+ dd = NULL;
1380+data_err:
1381+ dev_err(dev, "initialization failed.\n");
1382+
1383+ return err;
1384+}
1385+
1386+static int __devexit omap4_sham_remove(struct platform_device *pdev)
1387+{
1388+ static struct omap4_sham_dev *dd;
1389+ int i;
1390+
1391+ dd = platform_get_drvdata(pdev);
1392+ if (!dd)
1393+ return -ENODEV;
1394+ spin_lock(&sham.lock);
1395+ list_del(&dd->list);
1396+ spin_unlock(&sham.lock);
1397+ for (i = 0; i < ARRAY_SIZE(algs); i++)
1398+ crypto_unregister_ahash(&algs[i]);
1399+ tasklet_kill(&dd->done_task);
1400+ iounmap(dd->io_base);
1401+ clk_put(dd->iclk);
1402+ omap4_sham_dma_cleanup(dd);
1403+ if (dd->irq >= 0)
1404+ free_irq(dd->irq, dd);
1405+ kfree(dd);
1406+ dd = NULL;
1407+
1408+ return 0;
1409+}
1410+
1411+static struct platform_driver omap4_sham_driver = {
1412+ .probe = omap4_sham_probe,
1413+ .remove = omap4_sham_remove,
1414+ .driver = {
1415+ .name = "omap4-sham",
1416+ .owner = THIS_MODULE,
1417+ },
1418+};
1419+
1420+static int __init omap4_sham_mod_init(void)
1421+{
1422+ pr_info("loading AM33X SHA/MD5 driver\n");
1423+
1424+ if (!cpu_is_am33xx() || omap_type() != OMAP2_DEVICE_TYPE_GP) {
1425+ pr_err("Unsupported cpu\n");
1426+ return -ENODEV;
1427+ }
1428+
1429+ return platform_driver_register(&omap4_sham_driver);
1430+}
1431+
1432+static void __exit omap4_sham_mod_exit(void)
1433+{
1434+ platform_driver_unregister(&omap4_sham_driver);
1435+}
1436+
1437+module_init(omap4_sham_mod_init);
1438+module_exit(omap4_sham_mod_exit);
1439+
1440+MODULE_DESCRIPTION("AM33x SHA/MD5 hw acceleration support.");
1441+MODULE_LICENSE("GPL v2");
1442+MODULE_AUTHOR("Herman Schuurman");
1443--
14441.7.0.4
diff --git a/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/defconfig b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/defconfig
new file mode 100644
index 00000000..30223ae0
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x-3.2.0-psp04.06.00.08/defconfig
@@ -0,0 +1,2656 @@
1#
2# Automatically generated file; DO NOT EDIT.
3# Linux/arm 3.2.0 Kernel Configuration
4#
5CONFIG_ARM=y
6CONFIG_HAVE_PWM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_HAVE_SCHED_CLOCK=y
9CONFIG_GENERIC_GPIO=y
10# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
11CONFIG_GENERIC_CLOCKEVENTS=y
12CONFIG_KTIME_SCALAR=y
13CONFIG_HAVE_PROC_CPU=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_HAVE_LATENCYTOP_SUPPORT=y
16CONFIG_LOCKDEP_SUPPORT=y
17CONFIG_TRACE_IRQFLAGS_SUPPORT=y
18CONFIG_HARDIRQS_SW_RESEND=y
19CONFIG_GENERIC_IRQ_PROBE=y
20CONFIG_RWSEM_GENERIC_SPINLOCK=y
21CONFIG_ARCH_HAS_CPUFREQ=y
22CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
23CONFIG_GENERIC_HWEIGHT=y
24CONFIG_GENERIC_CALIBRATE_DELAY=y
25CONFIG_NEED_DMA_MAP_STATE=y
26CONFIG_VECTORS_BASE=0xffff0000
27CONFIG_ARM_PATCH_PHYS_VIRT=y
28CONFIG_GENERIC_BUG=y
29CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
30CONFIG_HAVE_IRQ_WORK=y
31
32#
33# General setup
34#
35CONFIG_EXPERIMENTAL=y
36CONFIG_BROKEN_ON_SMP=y
37CONFIG_INIT_ENV_ARG_LIMIT=32
38CONFIG_CROSS_COMPILE=""
39CONFIG_LOCALVERSION=""
40CONFIG_LOCALVERSION_AUTO=y
41CONFIG_HAVE_KERNEL_GZIP=y
42CONFIG_HAVE_KERNEL_LZMA=y
43CONFIG_HAVE_KERNEL_LZO=y
44CONFIG_KERNEL_GZIP=y
45# CONFIG_KERNEL_LZMA is not set
46# CONFIG_KERNEL_LZO is not set
47CONFIG_DEFAULT_HOSTNAME="(none)"
48CONFIG_SWAP=y
49CONFIG_SYSVIPC=y
50CONFIG_SYSVIPC_SYSCTL=y
51CONFIG_POSIX_MQUEUE=y
52CONFIG_POSIX_MQUEUE_SYSCTL=y
53CONFIG_BSD_PROCESS_ACCT=y
54# CONFIG_BSD_PROCESS_ACCT_V3 is not set
55# CONFIG_FHANDLE is not set
56# CONFIG_TASKSTATS is not set
57# CONFIG_AUDIT is not set
58CONFIG_HAVE_GENERIC_HARDIRQS=y
59
60#
61# IRQ subsystem
62#
63CONFIG_GENERIC_HARDIRQS=y
64CONFIG_HAVE_SPARSE_IRQ=y
65CONFIG_GENERIC_IRQ_SHOW=y
66CONFIG_GENERIC_IRQ_CHIP=y
67CONFIG_IRQ_DOMAIN=y
68# CONFIG_SPARSE_IRQ is not set
69
70#
71# RCU Subsystem
72#
73CONFIG_TINY_RCU=y
74# CONFIG_PREEMPT_RCU is not set
75# CONFIG_RCU_TRACE is not set
76# CONFIG_TREE_RCU_TRACE is not set
77CONFIG_IKCONFIG=y
78CONFIG_IKCONFIG_PROC=y
79CONFIG_LOG_BUF_SHIFT=16
80# CONFIG_CGROUPS is not set
81CONFIG_NAMESPACES=y
82CONFIG_UTS_NS=y
83CONFIG_IPC_NS=y
84CONFIG_USER_NS=y
85CONFIG_PID_NS=y
86CONFIG_NET_NS=y
87# CONFIG_SCHED_AUTOGROUP is not set
88# CONFIG_SYSFS_DEPRECATED is not set
89# CONFIG_RELAY is not set
90CONFIG_BLK_DEV_INITRD=y
91CONFIG_INITRAMFS_SOURCE=""
92CONFIG_RD_GZIP=y
93CONFIG_RD_BZIP2=y
94CONFIG_RD_LZMA=y
95CONFIG_RD_XZ=y
96CONFIG_RD_LZO=y
97# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
98CONFIG_SYSCTL=y
99CONFIG_ANON_INODES=y
100# CONFIG_EXPERT is not set
101CONFIG_UID16=y
102# CONFIG_SYSCTL_SYSCALL is not set
103CONFIG_KALLSYMS=y
104CONFIG_HOTPLUG=y
105CONFIG_PRINTK=y
106CONFIG_BUG=y
107CONFIG_ELF_CORE=y
108CONFIG_BASE_FULL=y
109CONFIG_FUTEX=y
110CONFIG_EPOLL=y
111CONFIG_SIGNALFD=y
112CONFIG_TIMERFD=y
113CONFIG_EVENTFD=y
114CONFIG_SHMEM=y
115CONFIG_AIO=y
116# CONFIG_EMBEDDED is not set
117CONFIG_HAVE_PERF_EVENTS=y
118CONFIG_PERF_USE_VMALLOC=y
119
120#
121# Kernel Performance Events And Counters
122#
123# CONFIG_PERF_EVENTS is not set
124# CONFIG_PERF_COUNTERS is not set
125CONFIG_VM_EVENT_COUNTERS=y
126CONFIG_COMPAT_BRK=y
127CONFIG_SLAB=y
128# CONFIG_SLUB is not set
129CONFIG_PROFILING=y
130CONFIG_OPROFILE=y
131CONFIG_HAVE_OPROFILE=y
132# CONFIG_KPROBES is not set
133CONFIG_HAVE_KPROBES=y
134CONFIG_HAVE_KRETPROBES=y
135CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
136CONFIG_HAVE_CLK=y
137CONFIG_HAVE_DMA_API_DEBUG=y
138
139#
140# GCOV-based kernel profiling
141#
142# CONFIG_GCOV_KERNEL is not set
143CONFIG_HAVE_GENERIC_DMA_COHERENT=y
144CONFIG_SLABINFO=y
145CONFIG_RT_MUTEXES=y
146CONFIG_BASE_SMALL=0
147CONFIG_MODULES=y
148CONFIG_MODULE_FORCE_LOAD=y
149CONFIG_MODULE_UNLOAD=y
150CONFIG_MODULE_FORCE_UNLOAD=y
151CONFIG_MODVERSIONS=y
152CONFIG_MODULE_SRCVERSION_ALL=y
153CONFIG_BLOCK=y
154CONFIG_LBDAF=y
155# CONFIG_BLK_DEV_BSG is not set
156# CONFIG_BLK_DEV_BSGLIB is not set
157# CONFIG_BLK_DEV_INTEGRITY is not set
158
159#
160# IO Schedulers
161#
162CONFIG_IOSCHED_NOOP=y
163CONFIG_IOSCHED_DEADLINE=y
164CONFIG_IOSCHED_CFQ=y
165# CONFIG_DEFAULT_DEADLINE is not set
166CONFIG_DEFAULT_CFQ=y
167# CONFIG_DEFAULT_NOOP is not set
168CONFIG_DEFAULT_IOSCHED="cfq"
169# CONFIG_INLINE_SPIN_TRYLOCK is not set
170# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
171# CONFIG_INLINE_SPIN_LOCK is not set
172# CONFIG_INLINE_SPIN_LOCK_BH is not set
173# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
174# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
175CONFIG_INLINE_SPIN_UNLOCK=y
176# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
177CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
178# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
179# CONFIG_INLINE_READ_TRYLOCK is not set
180# CONFIG_INLINE_READ_LOCK is not set
181# CONFIG_INLINE_READ_LOCK_BH is not set
182# CONFIG_INLINE_READ_LOCK_IRQ is not set
183# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
184CONFIG_INLINE_READ_UNLOCK=y
185# CONFIG_INLINE_READ_UNLOCK_BH is not set
186CONFIG_INLINE_READ_UNLOCK_IRQ=y
187# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
188# CONFIG_INLINE_WRITE_TRYLOCK is not set
189# CONFIG_INLINE_WRITE_LOCK is not set
190# CONFIG_INLINE_WRITE_LOCK_BH is not set
191# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
192# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
193CONFIG_INLINE_WRITE_UNLOCK=y
194# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
195CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
196# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
197# CONFIG_MUTEX_SPIN_ON_OWNER is not set
198CONFIG_FREEZER=y
199
200#
201# System Type
202#
203CONFIG_MMU=y
204# CONFIG_ARCH_INTEGRATOR is not set
205# CONFIG_ARCH_REALVIEW is not set
206# CONFIG_ARCH_VERSATILE is not set
207# CONFIG_ARCH_VEXPRESS is not set
208# CONFIG_ARCH_AT91 is not set
209# CONFIG_ARCH_BCMRING is not set
210# CONFIG_ARCH_HIGHBANK is not set
211# CONFIG_ARCH_CLPS711X is not set
212# CONFIG_ARCH_CNS3XXX is not set
213# CONFIG_ARCH_GEMINI is not set
214# CONFIG_ARCH_PRIMA2 is not set
215# CONFIG_ARCH_EBSA110 is not set
216# CONFIG_ARCH_EP93XX is not set
217# CONFIG_ARCH_FOOTBRIDGE is not set
218# CONFIG_ARCH_MXC is not set
219# CONFIG_ARCH_MXS is not set
220# CONFIG_ARCH_NETX is not set
221# CONFIG_ARCH_H720X is not set
222# CONFIG_ARCH_IOP13XX is not set
223# CONFIG_ARCH_IOP32X is not set
224# CONFIG_ARCH_IOP33X is not set
225# CONFIG_ARCH_IXP23XX is not set
226# CONFIG_ARCH_IXP2000 is not set
227# CONFIG_ARCH_IXP4XX is not set
228# CONFIG_ARCH_DOVE is not set
229# CONFIG_ARCH_KIRKWOOD is not set
230# CONFIG_ARCH_LPC32XX is not set
231# CONFIG_ARCH_MV78XX0 is not set
232# CONFIG_ARCH_ORION5X is not set
233# CONFIG_ARCH_MMP is not set
234# CONFIG_ARCH_KS8695 is not set
235# CONFIG_ARCH_W90X900 is not set
236# CONFIG_ARCH_TEGRA is not set
237# CONFIG_ARCH_PICOXCELL is not set
238# CONFIG_ARCH_PNX4008 is not set
239# CONFIG_ARCH_PXA is not set
240# CONFIG_ARCH_MSM is not set
241# CONFIG_ARCH_SHMOBILE is not set
242# CONFIG_ARCH_RPC is not set
243# CONFIG_ARCH_SA1100 is not set
244# CONFIG_ARCH_S3C2410 is not set
245# CONFIG_ARCH_S3C64XX is not set
246# CONFIG_ARCH_S5P64X0 is not set
247# CONFIG_ARCH_S5PC100 is not set
248# CONFIG_ARCH_S5PV210 is not set
249# CONFIG_ARCH_EXYNOS is not set
250# CONFIG_ARCH_SHARK is not set
251# CONFIG_ARCH_TCC_926 is not set
252# CONFIG_ARCH_U300 is not set
253# CONFIG_ARCH_U8500 is not set
254# CONFIG_ARCH_NOMADIK is not set
255# CONFIG_ARCH_DAVINCI is not set
256CONFIG_ARCH_OMAP=y
257# CONFIG_PLAT_SPEAR is not set
258# CONFIG_ARCH_VT8500 is not set
259# CONFIG_ARCH_ZYNQ is not set
260# CONFIG_GPIO_PCA953X is not set
261# CONFIG_KEYBOARD_GPIO_POLLED is not set
262
263#
264# TI OMAP Common Features
265#
266# CONFIG_ARCH_OMAP1 is not set
267CONFIG_ARCH_OMAP2PLUS=y
268
269#
270# OMAP Feature Selections
271#
272CONFIG_AM33XX_SMARTREFLEX=y
273# CONFIG_OMAP_SMARTREFLEX is not set
274CONFIG_OMAP_RESET_CLOCKS=y
275CONFIG_OMAP_MUX=y
276CONFIG_OMAP_MUX_DEBUG=y
277CONFIG_OMAP_MUX_WARNINGS=y
278# CONFIG_OMAP_MCBSP is not set
279CONFIG_OMAP_MBOX_FWK=y
280CONFIG_OMAP_MBOX_KFIFO_SIZE=256
281# CONFIG_OMAP_32K_TIMER is not set
282# CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE is not set
283CONFIG_OMAP_DM_TIMER=y
284CONFIG_OMAP_PM_NOOP=y
285CONFIG_MACH_OMAP_GENERIC=y
286
287#
288# TI OMAP2/3/4 Specific Features
289#
290CONFIG_ARCH_OMAP2PLUS_TYPICAL=y
291# CONFIG_ARCH_OMAP2 is not set
292CONFIG_ARCH_OMAP3=y
293# CONFIG_ARCH_OMAP4 is not set
294# CONFIG_SOC_OMAP3430 is not set
295CONFIG_SOC_OMAPTI81XX=y
296CONFIG_SOC_OMAPAM33XX=y
297CONFIG_OMAP_PACKAGE_CBB=y
298
299#
300# OMAP Board Type
301#
302CONFIG_MACH_OMAP3_BEAGLE=y
303# CONFIG_MACH_DEVKIT8000 is not set
304# CONFIG_MACH_OMAP_LDP is not set
305# CONFIG_MACH_OMAP3530_LV_SOM is not set
306# CONFIG_MACH_OMAP3_TORPEDO is not set
307# CONFIG_MACH_ENCORE is not set
308# CONFIG_MACH_OVERO is not set
309# CONFIG_MACH_OMAP3EVM is not set
310# CONFIG_MACH_OMAP3517EVM is not set
311# CONFIG_MACH_CRANEBOARD is not set
312# CONFIG_MACH_OMAP3_PANDORA is not set
313# CONFIG_MACH_OMAP3_TOUCHBOOK is not set
314# CONFIG_MACH_OMAP_3430SDP is not set
315# CONFIG_MACH_NOKIA_RM680 is not set
316# CONFIG_MACH_NOKIA_RX51 is not set
317# CONFIG_MACH_OMAP_ZOOM2 is not set
318# CONFIG_MACH_OMAP_ZOOM3 is not set
319# CONFIG_MACH_CM_T35 is not set
320# CONFIG_MACH_CM_T3517 is not set
321# CONFIG_MACH_IGEP0020 is not set
322# CONFIG_MACH_IGEP0030 is not set
323# CONFIG_MACH_SBC3530 is not set
324# CONFIG_MACH_OMAP_3630SDP is not set
325CONFIG_MACH_TI8168EVM=y
326CONFIG_MACH_TI8148EVM=y
327CONFIG_MACH_AM335XEVM=y
328CONFIG_MACH_AM335XIAEVM=y
329# CONFIG_OMAP3_EMU is not set
330CONFIG_TI_PM_DISABLE_VT_SWITCH=y
331# CONFIG_OMAP3_SDRC_AC_TIMING is not set
332CONFIG_OMAP3_EDMA=y
333
334#
335# System MMU
336#
337
338#
339# Processor Type
340#
341CONFIG_CPU_V7=y
342CONFIG_CPU_32v6K=y
343CONFIG_CPU_32v7=y
344CONFIG_CPU_ABRT_EV7=y
345CONFIG_CPU_PABRT_V7=y
346CONFIG_CPU_CACHE_V7=y
347CONFIG_CPU_CACHE_VIPT=y
348CONFIG_CPU_COPY_V6=y
349CONFIG_CPU_TLB_V7=y
350CONFIG_CPU_HAS_ASID=y
351CONFIG_CPU_CP15=y
352CONFIG_CPU_CP15_MMU=y
353
354#
355# Processor Features
356#
357CONFIG_ARM_THUMB=y
358CONFIG_ARM_THUMBEE=y
359# CONFIG_SWP_EMULATE is not set
360# CONFIG_CPU_ICACHE_DISABLE is not set
361# CONFIG_CPU_DCACHE_DISABLE is not set
362# CONFIG_CPU_BPREDICT_DISABLE is not set
363CONFIG_ARM_L1_CACHE_SHIFT_6=y
364CONFIG_ARM_L1_CACHE_SHIFT=6
365CONFIG_ARM_DMA_MEM_BUFFERABLE=y
366CONFIG_MULTI_IRQ_HANDLER=y
367# CONFIG_ARM_ERRATA_430973 is not set
368# CONFIG_ARM_ERRATA_458693 is not set
369# CONFIG_ARM_ERRATA_460075 is not set
370# CONFIG_ARM_ERRATA_720789 is not set
371# CONFIG_ARM_ERRATA_743622 is not set
372# CONFIG_ARM_ERRATA_751472 is not set
373# CONFIG_ARM_ERRATA_754322 is not set
374
375#
376# Bus support
377#
378# CONFIG_PCI_SYSCALL is not set
379# CONFIG_ARCH_SUPPORTS_MSI is not set
380# CONFIG_PCCARD is not set
381
382#
383# Kernel Features
384#
385CONFIG_TICK_ONESHOT=y
386CONFIG_NO_HZ=y
387CONFIG_HIGH_RES_TIMERS=y
388CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
389CONFIG_VMSPLIT_3G=y
390# CONFIG_VMSPLIT_2G is not set
391# CONFIG_VMSPLIT_1G is not set
392CONFIG_PAGE_OFFSET=0xC0000000
393CONFIG_PREEMPT_NONE=y
394# CONFIG_PREEMPT_VOLUNTARY is not set
395# CONFIG_PREEMPT is not set
396CONFIG_HZ=100
397# CONFIG_THUMB2_KERNEL is not set
398CONFIG_AEABI=y
399CONFIG_OABI_COMPAT=y
400CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
401# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
402# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
403CONFIG_HAVE_ARCH_PFN_VALID=y
404# CONFIG_HIGHMEM is not set
405CONFIG_SELECT_MEMORY_MODEL=y
406CONFIG_FLATMEM_MANUAL=y
407CONFIG_FLATMEM=y
408CONFIG_FLAT_NODE_MEM_MAP=y
409CONFIG_HAVE_MEMBLOCK=y
410CONFIG_PAGEFLAGS_EXTENDED=y
411CONFIG_SPLIT_PTLOCK_CPUS=4
412# CONFIG_COMPACTION is not set
413# CONFIG_PHYS_ADDR_T_64BIT is not set
414CONFIG_ZONE_DMA_FLAG=0
415CONFIG_VIRT_TO_BUS=y
416# CONFIG_KSM is not set
417CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
418CONFIG_NEED_PER_CPU_KM=y
419# CONFIG_CLEANCACHE is not set
420CONFIG_FORCE_MAX_ZONEORDER=11
421# CONFIG_LEDS is not set
422CONFIG_ALIGNMENT_TRAP=y
423# CONFIG_UACCESS_WITH_MEMCPY is not set
424# CONFIG_SECCOMP is not set
425# CONFIG_CC_STACKPROTECTOR is not set
426# CONFIG_DEPRECATED_PARAM_STRUCT is not set
427
428#
429# Boot options
430#
431CONFIG_USE_OF=y
432CONFIG_ZBOOT_ROM_TEXT=0x0
433CONFIG_ZBOOT_ROM_BSS=0x0
434# CONFIG_ARM_APPENDED_DTB is not set
435CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO0,115200"
436CONFIG_CMDLINE_FROM_BOOTLOADER=y
437# CONFIG_CMDLINE_EXTEND is not set
438# CONFIG_CMDLINE_FORCE is not set
439# CONFIG_XIP_KERNEL is not set
440# CONFIG_KEXEC is not set
441# CONFIG_CRASH_DUMP is not set
442# CONFIG_AUTO_ZRELADDR is not set
443
444#
445# CPU Power Management
446#
447
448#
449# CPU Frequency scaling
450#
451CONFIG_CPU_FREQ=y
452CONFIG_CPU_FREQ_TABLE=y
453CONFIG_CPU_FREQ_STAT=y
454CONFIG_CPU_FREQ_STAT_DETAILS=y
455# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
456CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
457# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
458# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
459CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
460CONFIG_CPU_FREQ_GOV_POWERSAVE=y
461CONFIG_CPU_FREQ_GOV_USERSPACE=y
462CONFIG_CPU_FREQ_GOV_ONDEMAND=y
463CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
464
465#
466# ARM CPU frequency scaling drivers
467#
468CONFIG_CPU_IDLE=y
469CONFIG_CPU_IDLE_GOV_LADDER=y
470CONFIG_CPU_IDLE_GOV_MENU=y
471
472#
473# Floating point emulation
474#
475
476#
477# At least one emulation must be selected
478#
479CONFIG_FPE_NWFPE=y
480# CONFIG_FPE_NWFPE_XP is not set
481# CONFIG_FPE_FASTFPE is not set
482CONFIG_VFP=y
483CONFIG_VFPv3=y
484CONFIG_NEON=y
485
486#
487# Userspace binary formats
488#
489CONFIG_BINFMT_ELF=y
490CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
491CONFIG_HAVE_AOUT=y
492# CONFIG_BINFMT_AOUT is not set
493CONFIG_BINFMT_MISC=y
494
495#
496# Power management options
497#
498CONFIG_SUSPEND=y
499CONFIG_SUSPEND_FREEZER=y
500CONFIG_PM_SLEEP=y
501CONFIG_PM_RUNTIME=y
502CONFIG_PM=y
503CONFIG_PM_DEBUG=y
504CONFIG_PM_ADVANCED_DEBUG=y
505# CONFIG_PM_TEST_SUSPEND is not set
506CONFIG_CAN_PM_TRACE=y
507# CONFIG_APM_EMULATION is not set
508CONFIG_ARCH_HAS_OPP=y
509CONFIG_PM_OPP=y
510CONFIG_PM_CLK=y
511CONFIG_CPU_PM=y
512CONFIG_ARCH_SUSPEND_POSSIBLE=y
513CONFIG_ARM_CPU_SUSPEND=y
514CONFIG_NET=y
515
516#
517# Networking options
518#
519CONFIG_PACKET=y
520CONFIG_UNIX=y
521# CONFIG_NET_KEY is not set
522CONFIG_INET=y
523CONFIG_IP_MULTICAST=y
524# CONFIG_IP_ADVANCED_ROUTER is not set
525CONFIG_IP_PNP=y
526CONFIG_IP_PNP_DHCP=y
527CONFIG_IP_PNP_BOOTP=y
528CONFIG_IP_PNP_RARP=y
529# CONFIG_NET_IPIP is not set
530# CONFIG_NET_IPGRE_DEMUX is not set
531# CONFIG_IP_MROUTE is not set
532# CONFIG_ARPD is not set
533# CONFIG_SYN_COOKIES is not set
534# CONFIG_INET_AH is not set
535# CONFIG_INET_ESP is not set
536# CONFIG_INET_IPCOMP is not set
537# CONFIG_INET_XFRM_TUNNEL is not set
538# CONFIG_INET_TUNNEL is not set
539# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
540# CONFIG_INET_XFRM_MODE_TUNNEL is not set
541# CONFIG_INET_XFRM_MODE_BEET is not set
542# CONFIG_INET_LRO is not set
543# CONFIG_INET_DIAG is not set
544# CONFIG_TCP_CONG_ADVANCED is not set
545CONFIG_TCP_CONG_CUBIC=y
546CONFIG_DEFAULT_TCP_CONG="cubic"
547# CONFIG_TCP_MD5SIG is not set
548# CONFIG_IPV6 is not set
549# CONFIG_NETLABEL is not set
550# CONFIG_NETWORK_SECMARK is not set
551# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
552CONFIG_NETFILTER=y
553# CONFIG_NETFILTER_DEBUG is not set
554CONFIG_NETFILTER_ADVANCED=y
555
556#
557# Core Netfilter Configuration
558#
559# CONFIG_NETFILTER_NETLINK_QUEUE is not set
560# CONFIG_NETFILTER_NETLINK_LOG is not set
561CONFIG_NF_CONNTRACK=y
562# CONFIG_NF_CONNTRACK_MARK is not set
563# CONFIG_NF_CONNTRACK_EVENTS is not set
564# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
565# CONFIG_NF_CT_PROTO_DCCP is not set
566# CONFIG_NF_CT_PROTO_SCTP is not set
567# CONFIG_NF_CT_PROTO_UDPLITE is not set
568# CONFIG_NF_CONNTRACK_AMANDA is not set
569# CONFIG_NF_CONNTRACK_FTP is not set
570# CONFIG_NF_CONNTRACK_H323 is not set
571# CONFIG_NF_CONNTRACK_IRC is not set
572# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
573# CONFIG_NF_CONNTRACK_SNMP is not set
574# CONFIG_NF_CONNTRACK_PPTP is not set
575# CONFIG_NF_CONNTRACK_SANE is not set
576# CONFIG_NF_CONNTRACK_SIP is not set
577# CONFIG_NF_CONNTRACK_TFTP is not set
578# CONFIG_NF_CT_NETLINK is not set
579CONFIG_NETFILTER_XTABLES=y
580
581#
582# Xtables combined modules
583#
584# CONFIG_NETFILTER_XT_MARK is not set
585# CONFIG_NETFILTER_XT_CONNMARK is not set
586
587#
588# Xtables targets
589#
590# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
591# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
592# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
593# CONFIG_NETFILTER_XT_TARGET_LED is not set
594# CONFIG_NETFILTER_XT_TARGET_MARK is not set
595# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
596# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
597# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
598# CONFIG_NETFILTER_XT_TARGET_TEE is not set
599# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
600
601#
602# Xtables matches
603#
604# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
605# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
606# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
607# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
608# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
609# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
610# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
611# CONFIG_NETFILTER_XT_MATCH_CPU is not set
612# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
613# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
614# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
615# CONFIG_NETFILTER_XT_MATCH_ESP is not set
616# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
617# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
618# CONFIG_NETFILTER_XT_MATCH_HL is not set
619# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
620# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
621# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
622# CONFIG_NETFILTER_XT_MATCH_MAC is not set
623# CONFIG_NETFILTER_XT_MATCH_MARK is not set
624# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
625# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
626# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
627# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
628# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
629# CONFIG_NETFILTER_XT_MATCH_REALM is not set
630# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
631# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
632# CONFIG_NETFILTER_XT_MATCH_STATE is not set
633# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
634# CONFIG_NETFILTER_XT_MATCH_STRING is not set
635# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
636# CONFIG_NETFILTER_XT_MATCH_TIME is not set
637# CONFIG_NETFILTER_XT_MATCH_U32 is not set
638# CONFIG_IP_VS is not set
639
640#
641# IP: Netfilter Configuration
642#
643CONFIG_NF_DEFRAG_IPV4=y
644CONFIG_NF_CONNTRACK_IPV4=y
645CONFIG_NF_CONNTRACK_PROC_COMPAT=y
646# CONFIG_IP_NF_QUEUE is not set
647CONFIG_IP_NF_IPTABLES=y
648# CONFIG_IP_NF_MATCH_AH is not set
649# CONFIG_IP_NF_MATCH_ECN is not set
650# CONFIG_IP_NF_MATCH_TTL is not set
651CONFIG_IP_NF_FILTER=y
652# CONFIG_IP_NF_TARGET_REJECT is not set
653CONFIG_IP_NF_TARGET_LOG=y
654# CONFIG_IP_NF_TARGET_ULOG is not set
655CONFIG_NF_NAT=y
656CONFIG_NF_NAT_NEEDED=y
657CONFIG_IP_NF_TARGET_MASQUERADE=y
658# CONFIG_IP_NF_TARGET_NETMAP is not set
659# CONFIG_IP_NF_TARGET_REDIRECT is not set
660# CONFIG_NF_NAT_FTP is not set
661# CONFIG_NF_NAT_IRC is not set
662# CONFIG_NF_NAT_TFTP is not set
663# CONFIG_NF_NAT_AMANDA is not set
664# CONFIG_NF_NAT_PPTP is not set
665# CONFIG_NF_NAT_H323 is not set
666# CONFIG_NF_NAT_SIP is not set
667# CONFIG_IP_NF_MANGLE is not set
668# CONFIG_IP_NF_RAW is not set
669# CONFIG_IP_NF_SECURITY is not set
670# CONFIG_IP_NF_ARPTABLES is not set
671# CONFIG_IP_DCCP is not set
672# CONFIG_IP_SCTP is not set
673# CONFIG_RDS is not set
674# CONFIG_TIPC is not set
675# CONFIG_ATM is not set
676# CONFIG_L2TP is not set
677# CONFIG_BRIDGE is not set
678# CONFIG_NET_DSA is not set
679# CONFIG_VLAN_8021Q is not set
680# CONFIG_DECNET is not set
681# CONFIG_LLC2 is not set
682# CONFIG_IPX is not set
683# CONFIG_ATALK is not set
684# CONFIG_X25 is not set
685# CONFIG_LAPB is not set
686# CONFIG_ECONET is not set
687# CONFIG_WAN_ROUTER is not set
688# CONFIG_PHONET is not set
689# CONFIG_IEEE802154 is not set
690# CONFIG_NET_SCHED is not set
691# CONFIG_DCB is not set
692CONFIG_DNS_RESOLVER=y
693# CONFIG_BATMAN_ADV is not set
694
695#
696# Network testing
697#
698# CONFIG_NET_PKTGEN is not set
699# CONFIG_HAMRADIO is not set
700CONFIG_CAN=y
701CONFIG_CAN_RAW=y
702CONFIG_CAN_BCM=y
703# CONFIG_CAN_GW is not set
704
705#
706# CAN Device Drivers
707#
708# CONFIG_CAN_VCAN is not set
709# CONFIG_CAN_SLCAN is not set
710CONFIG_CAN_DEV=y
711CONFIG_CAN_CALC_BITTIMING=y
712# CONFIG_CAN_TI_HECC is not set
713# CONFIG_CAN_MCP251X is not set
714# CONFIG_CAN_SJA1000 is not set
715# CONFIG_CAN_C_CAN is not set
716CONFIG_CAN_D_CAN=y
717CONFIG_CAN_D_CAN_PLATFORM=y
718
719#
720# CAN USB interfaces
721#
722# CONFIG_CAN_EMS_USB is not set
723# CONFIG_CAN_ESD_USB2 is not set
724# CONFIG_CAN_SOFTING is not set
725# CONFIG_CAN_DEBUG_DEVICES is not set
726# CONFIG_IRDA is not set
727# CONFIG_BT is not set
728# CONFIG_AF_RXRPC is not set
729CONFIG_WIRELESS=y
730CONFIG_WIRELESS_EXT=y
731CONFIG_WEXT_CORE=y
732CONFIG_WEXT_PROC=y
733CONFIG_WEXT_PRIV=y
734# CONFIG_CFG80211 is not set
735CONFIG_WIRELESS_EXT_SYSFS=y
736# CONFIG_LIB80211 is not set
737
738#
739# CFG80211 needs to be enabled for MAC80211
740#
741# CONFIG_WIMAX is not set
742CONFIG_RFKILL=y
743CONFIG_RFKILL_LEDS=y
744CONFIG_RFKILL_INPUT=y
745# CONFIG_RFKILL_REGULATOR is not set
746# CONFIG_RFKILL_GPIO is not set
747# CONFIG_NET_9P is not set
748# CONFIG_CAIF is not set
749# CONFIG_CEPH_LIB is not set
750# CONFIG_NFC is not set
751
752#
753# Device Drivers
754#
755
756#
757# Generic Driver Options
758#
759CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
760# CONFIG_DEVTMPFS is not set
761CONFIG_STANDALONE=y
762CONFIG_PREVENT_FIRMWARE_BUILD=y
763CONFIG_FW_LOADER=y
764CONFIG_FIRMWARE_IN_KERNEL=y
765CONFIG_EXTRA_FIRMWARE="am335x-pm-firmware.bin"
766CONFIG_EXTRA_FIRMWARE_DIR="firmware"
767# CONFIG_SYS_HYPERVISOR is not set
768CONFIG_REGMAP=y
769CONFIG_REGMAP_I2C=y
770CONFIG_REGMAP_SPI=y
771
772#
773# CBUS support
774#
775# CONFIG_CBUS is not set
776# CONFIG_CONNECTOR is not set
777CONFIG_MTD=y
778# CONFIG_MTD_TESTS is not set
779# CONFIG_MTD_REDBOOT_PARTS is not set
780CONFIG_MTD_CMDLINE_PARTS=y
781# CONFIG_MTD_AFS_PARTS is not set
782# CONFIG_MTD_OF_PARTS is not set
783# CONFIG_MTD_AR7_PARTS is not set
784
785#
786# User Modules And Translation Layers
787#
788CONFIG_MTD_CHAR=y
789CONFIG_MTD_BLKDEVS=y
790CONFIG_MTD_BLOCK=y
791# CONFIG_FTL is not set
792# CONFIG_NFTL is not set
793# CONFIG_INFTL is not set
794# CONFIG_RFD_FTL is not set
795# CONFIG_SSFDC is not set
796# CONFIG_SM_FTL is not set
797CONFIG_MTD_OOPS=y
798# CONFIG_MTD_SWAP is not set
799
800#
801# RAM/ROM/Flash chip drivers
802#
803CONFIG_MTD_CFI=y
804# CONFIG_MTD_JEDECPROBE is not set
805CONFIG_MTD_GEN_PROBE=y
806# CONFIG_MTD_CFI_ADV_OPTIONS is not set
807CONFIG_MTD_MAP_BANK_WIDTH_1=y
808CONFIG_MTD_MAP_BANK_WIDTH_2=y
809CONFIG_MTD_MAP_BANK_WIDTH_4=y
810# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
811# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
812# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
813CONFIG_MTD_CFI_I1=y
814CONFIG_MTD_CFI_I2=y
815# CONFIG_MTD_CFI_I4 is not set
816# CONFIG_MTD_CFI_I8 is not set
817# CONFIG_MTD_CFI_INTELEXT is not set
818# CONFIG_MTD_CFI_AMDSTD is not set
819# CONFIG_MTD_CFI_STAA is not set
820CONFIG_MTD_CFI_UTIL=y
821# CONFIG_MTD_RAM is not set
822# CONFIG_MTD_ROM is not set
823# CONFIG_MTD_ABSENT is not set
824
825#
826# Mapping drivers for chip access
827#
828# CONFIG_MTD_COMPLEX_MAPPINGS is not set
829# CONFIG_MTD_PHYSMAP is not set
830# CONFIG_MTD_PHYSMAP_OF is not set
831# CONFIG_MTD_PLATRAM is not set
832
833#
834# Self-contained MTD device drivers
835#
836# CONFIG_MTD_DATAFLASH is not set
837CONFIG_MTD_M25P80=y
838CONFIG_M25PXX_USE_FAST_READ=y
839# CONFIG_MTD_SST25L is not set
840# CONFIG_MTD_SLRAM is not set
841# CONFIG_MTD_PHRAM is not set
842# CONFIG_MTD_MTDRAM is not set
843# CONFIG_MTD_BLOCK2MTD is not set
844
845#
846# Disk-On-Chip Device Drivers
847#
848# CONFIG_MTD_DOC2000 is not set
849# CONFIG_MTD_DOC2001 is not set
850# CONFIG_MTD_DOC2001PLUS is not set
851# CONFIG_MTD_DOCG3 is not set
852CONFIG_MTD_NAND_ECC=y
853# CONFIG_MTD_NAND_ECC_SMC is not set
854CONFIG_MTD_NAND=y
855# CONFIG_MTD_NAND_VERIFY_WRITE is not set
856# CONFIG_MTD_NAND_ECC_BCH is not set
857# CONFIG_MTD_SM_COMMON is not set
858# CONFIG_MTD_NAND_MUSEUM_IDS is not set
859# CONFIG_MTD_NAND_GPIO is not set
860CONFIG_MTD_NAND_OMAP2=y
861CONFIG_MTD_NAND_IDS=y
862# CONFIG_MTD_NAND_DISKONCHIP is not set
863# CONFIG_MTD_NAND_NANDSIM is not set
864# CONFIG_MTD_NAND_PLATFORM is not set
865# CONFIG_MTD_ALAUDA is not set
866CONFIG_MTD_ONENAND=y
867# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
868# CONFIG_MTD_ONENAND_GENERIC is not set
869CONFIG_MTD_ONENAND_OMAP2=y
870# CONFIG_MTD_ONENAND_OTP is not set
871# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
872# CONFIG_MTD_ONENAND_SIM is not set
873
874#
875# LPDDR flash memory drivers
876#
877# CONFIG_MTD_LPDDR is not set
878CONFIG_MTD_UBI=y
879CONFIG_MTD_UBI_WL_THRESHOLD=4096
880CONFIG_MTD_UBI_BEB_RESERVE=1
881# CONFIG_MTD_UBI_GLUEBI is not set
882# CONFIG_MTD_UBI_DEBUG is not set
883CONFIG_DTC=y
884CONFIG_OF=y
885
886#
887# Device Tree and Open Firmware support
888#
889CONFIG_PROC_DEVICETREE=y
890CONFIG_OF_FLATTREE=y
891CONFIG_OF_EARLY_FLATTREE=y
892CONFIG_OF_ADDRESS=y
893CONFIG_OF_IRQ=y
894CONFIG_OF_DEVICE=y
895CONFIG_OF_GPIO=y
896CONFIG_OF_I2C=y
897CONFIG_OF_NET=y
898CONFIG_OF_SPI=y
899CONFIG_OF_MDIO=y
900# CONFIG_PARPORT is not set
901CONFIG_BLK_DEV=y
902# CONFIG_BLK_DEV_COW_COMMON is not set
903CONFIG_BLK_DEV_LOOP=y
904CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
905# CONFIG_BLK_DEV_CRYPTOLOOP is not set
906
907#
908# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
909#
910# CONFIG_BLK_DEV_NBD is not set
911# CONFIG_BLK_DEV_UB is not set
912CONFIG_BLK_DEV_RAM=y
913CONFIG_BLK_DEV_RAM_COUNT=16
914CONFIG_BLK_DEV_RAM_SIZE=16384
915# CONFIG_BLK_DEV_XIP is not set
916# CONFIG_CDROM_PKTCDVD is not set
917# CONFIG_ATA_OVER_ETH is not set
918# CONFIG_MG_DISK is not set
919# CONFIG_BLK_DEV_RBD is not set
920CONFIG_SENSORS_LIS3LV02D=y
921CONFIG_MISC_DEVICES=y
922# CONFIG_AD525X_DPOT is not set
923# CONFIG_ATMEL_PWM is not set
924# CONFIG_ICS932S401 is not set
925# CONFIG_ENCLOSURE_SERVICES is not set
926# CONFIG_APDS9802ALS is not set
927# CONFIG_ISL29003 is not set
928# CONFIG_ISL29020 is not set
929CONFIG_SENSORS_TSL2550=y
930# CONFIG_SENSORS_BH1780 is not set
931# CONFIG_SENSORS_BH1770 is not set
932# CONFIG_SENSORS_APDS990X is not set
933# CONFIG_HMC6352 is not set
934# CONFIG_DS1682 is not set
935# CONFIG_TI_DAC7512 is not set
936# CONFIG_BMP085 is not set
937# CONFIG_USB_SWITCH_FSA9480 is not set
938# CONFIG_C2PORT is not set
939
940#
941# EEPROM support
942#
943CONFIG_EEPROM_AT24=y
944# CONFIG_EEPROM_AT25 is not set
945# CONFIG_EEPROM_LEGACY is not set
946# CONFIG_EEPROM_MAX6875 is not set
947# CONFIG_EEPROM_93CX6 is not set
948# CONFIG_EEPROM_93XX46 is not set
949# CONFIG_IWMC3200TOP is not set
950
951#
952# Texas Instruments shared transport line discipline
953#
954# CONFIG_TI_ST is not set
955# CONFIG_SENSORS_LIS3_SPI is not set
956CONFIG_SENSORS_LIS3_I2C=y
957
958#
959# Altera FPGA firmware download module
960#
961# CONFIG_ALTERA_STAPL is not set
962
963#
964# SCSI device support
965#
966CONFIG_SCSI_MOD=y
967# CONFIG_RAID_ATTRS is not set
968CONFIG_SCSI=y
969CONFIG_SCSI_DMA=y
970# CONFIG_SCSI_TGT is not set
971# CONFIG_SCSI_NETLINK is not set
972CONFIG_SCSI_PROC_FS=y
973
974#
975# SCSI support type (disk, tape, CD-ROM)
976#
977CONFIG_BLK_DEV_SD=y
978# CONFIG_CHR_DEV_ST is not set
979# CONFIG_CHR_DEV_OSST is not set
980# CONFIG_BLK_DEV_SR is not set
981# CONFIG_CHR_DEV_SG is not set
982# CONFIG_CHR_DEV_SCH is not set
983CONFIG_SCSI_MULTI_LUN=y
984# CONFIG_SCSI_CONSTANTS is not set
985# CONFIG_SCSI_LOGGING is not set
986CONFIG_SCSI_SCAN_ASYNC=y
987CONFIG_SCSI_WAIT_SCAN=m
988
989#
990# SCSI Transports
991#
992# CONFIG_SCSI_SPI_ATTRS is not set
993# CONFIG_SCSI_FC_ATTRS is not set
994# CONFIG_SCSI_ISCSI_ATTRS is not set
995# CONFIG_SCSI_SAS_ATTRS is not set
996# CONFIG_SCSI_SAS_LIBSAS is not set
997# CONFIG_SCSI_SRP_ATTRS is not set
998CONFIG_SCSI_LOWLEVEL=y
999# CONFIG_ISCSI_TCP is not set
1000# CONFIG_ISCSI_BOOT_SYSFS is not set
1001# CONFIG_LIBFC is not set
1002# CONFIG_LIBFCOE is not set
1003# CONFIG_SCSI_DEBUG is not set
1004# CONFIG_SCSI_DH is not set
1005# CONFIG_SCSI_OSD_INITIATOR is not set
1006# CONFIG_ATA is not set
1007# CONFIG_MD is not set
1008# CONFIG_TARGET_CORE is not set
1009CONFIG_NETDEVICES=y
1010CONFIG_NET_CORE=y
1011# CONFIG_BONDING is not set
1012# CONFIG_DUMMY is not set
1013# CONFIG_EQUALIZER is not set
1014CONFIG_MII=y
1015# CONFIG_MACVLAN is not set
1016# CONFIG_NETCONSOLE is not set
1017# CONFIG_NETPOLL is not set
1018# CONFIG_NET_POLL_CONTROLLER is not set
1019# CONFIG_TUN is not set
1020# CONFIG_VETH is not set
1021
1022#
1023# CAIF transport drivers
1024#
1025CONFIG_ETHERNET=y
1026CONFIG_NET_VENDOR_BROADCOM=y
1027# CONFIG_B44 is not set
1028CONFIG_NET_VENDOR_CHELSIO=y
1029# CONFIG_DM9000 is not set
1030# CONFIG_DNET is not set
1031CONFIG_NET_VENDOR_FARADAY=y
1032# CONFIG_FTMAC100 is not set
1033# CONFIG_FTGMAC100 is not set
1034CONFIG_NET_VENDOR_INTEL=y
1035CONFIG_NET_VENDOR_I825XX=y
1036CONFIG_NET_VENDOR_MARVELL=y
1037CONFIG_NET_VENDOR_MICREL=y
1038# CONFIG_KS8851 is not set
1039# CONFIG_KS8851_MLL is not set
1040CONFIG_NET_VENDOR_MICROCHIP=y
1041# CONFIG_ENC28J60 is not set
1042CONFIG_NET_VENDOR_NATSEMI=y
1043CONFIG_NET_VENDOR_8390=y
1044# CONFIG_AX88796 is not set
1045# CONFIG_ETHOC is not set
1046CONFIG_NET_VENDOR_SEEQ=y
1047# CONFIG_SEEQ8005 is not set
1048CONFIG_NET_VENDOR_SMSC=y
1049CONFIG_SMC91X=y
1050# CONFIG_SMC911X is not set
1051CONFIG_SMSC911X=y
1052# CONFIG_SMSC911X_ARCH_HOOKS is not set
1053CONFIG_NET_VENDOR_STMICRO=y
1054# CONFIG_STMMAC_ETH is not set
1055CONFIG_NET_VENDOR_TI=y
1056# CONFIG_TI_DAVINCI_EMAC is not set
1057CONFIG_TI_DAVINCI_MDIO=y
1058CONFIG_TI_DAVINCI_CPDMA=y
1059CONFIG_TI_CPSW=y
1060CONFIG_TI_CPSW_DUAL_EMAC=y
1061CONFIG_PHYLIB=y
1062
1063#
1064# MII PHY device drivers
1065#
1066# CONFIG_MARVELL_PHY is not set
1067# CONFIG_DAVICOM_PHY is not set
1068# CONFIG_QSEMI_PHY is not set
1069# CONFIG_LXT_PHY is not set
1070# CONFIG_CICADA_PHY is not set
1071# CONFIG_VITESSE_PHY is not set
1072CONFIG_SMSC_PHY=y
1073# CONFIG_BROADCOM_PHY is not set
1074# CONFIG_ICPLUS_PHY is not set
1075# CONFIG_REALTEK_PHY is not set
1076# CONFIG_NATIONAL_PHY is not set
1077# CONFIG_STE10XP is not set
1078# CONFIG_LSI_ET1011C_PHY is not set
1079# CONFIG_MICREL_PHY is not set
1080# CONFIG_FIXED_PHY is not set
1081# CONFIG_MDIO_BITBANG is not set
1082# CONFIG_PPP is not set
1083# CONFIG_SLIP is not set
1084
1085#
1086# USB Network Adapters
1087#
1088# CONFIG_USB_CATC is not set
1089# CONFIG_USB_KAWETH is not set
1090# CONFIG_USB_PEGASUS is not set
1091# CONFIG_USB_RTL8150 is not set
1092CONFIG_USB_USBNET=y
1093# CONFIG_USB_NET_AX8817X is not set
1094CONFIG_USB_NET_CDCETHER=y
1095CONFIG_USB_NET_CDC_EEM=y
1096CONFIG_USB_NET_CDC_NCM=y
1097CONFIG_USB_NET_DM9601=y
1098# CONFIG_USB_NET_SMSC75XX is not set
1099# CONFIG_USB_NET_SMSC95XX is not set
1100# CONFIG_USB_NET_GL620A is not set
1101# CONFIG_USB_NET_NET1080 is not set
1102# CONFIG_USB_NET_PLUSB is not set
1103# CONFIG_USB_NET_MCS7830 is not set
1104# CONFIG_USB_NET_RNDIS_HOST is not set
1105# CONFIG_USB_NET_CDC_SUBSET is not set
1106# CONFIG_USB_NET_ZAURUS is not set
1107# CONFIG_USB_NET_CX82310_ETH is not set
1108# CONFIG_USB_NET_KALMIA is not set
1109# CONFIG_USB_HSO is not set
1110# CONFIG_USB_NET_INT51X1 is not set
1111# CONFIG_USB_IPHETH is not set
1112# CONFIG_USB_SIERRA_NET is not set
1113# CONFIG_USB_VL600 is not set
1114CONFIG_WLAN=y
1115CONFIG_USB_ZD1201=y
1116# CONFIG_HOSTAP is not set
1117CONFIG_WL12XX_PLATFORM_DATA=y
1118
1119#
1120# Enable WiMAX (Networking options) to see the WiMAX drivers
1121#
1122# CONFIG_WAN is not set
1123# CONFIG_ISDN is not set
1124# CONFIG_PHONE is not set
1125
1126#
1127# Input device support
1128#
1129CONFIG_INPUT=y
1130# CONFIG_INPUT_FF_MEMLESS is not set
1131CONFIG_INPUT_POLLDEV=y
1132# CONFIG_INPUT_SPARSEKMAP is not set
1133
1134#
1135# Userland interfaces
1136#
1137CONFIG_INPUT_MOUSEDEV=y
1138CONFIG_INPUT_MOUSEDEV_PSAUX=y
1139CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
1140CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
1141# CONFIG_INPUT_JOYDEV is not set
1142CONFIG_INPUT_EVDEV=y
1143# CONFIG_INPUT_EVBUG is not set
1144
1145#
1146# Input Device Drivers
1147#
1148CONFIG_INPUT_KEYBOARD=y
1149# CONFIG_KEYBOARD_ADP5588 is not set
1150# CONFIG_KEYBOARD_ADP5589 is not set
1151# CONFIG_KEYBOARD_ATKBD is not set
1152# CONFIG_KEYBOARD_QT1070 is not set
1153# CONFIG_KEYBOARD_QT2160 is not set
1154# CONFIG_KEYBOARD_LKKBD is not set
1155CONFIG_KEYBOARD_GPIO=y
1156# CONFIG_KEYBOARD_TCA6416 is not set
1157CONFIG_KEYBOARD_MATRIX=y
1158# CONFIG_KEYBOARD_LM8323 is not set
1159# CONFIG_KEYBOARD_MAX7359 is not set
1160# CONFIG_KEYBOARD_MCS is not set
1161# CONFIG_KEYBOARD_MPR121 is not set
1162# CONFIG_KEYBOARD_NEWTON is not set
1163# CONFIG_KEYBOARD_OPENCORES is not set
1164# CONFIG_KEYBOARD_STOWAWAY is not set
1165# CONFIG_KEYBOARD_SUNKBD is not set
1166# CONFIG_KEYBOARD_TWL4030 is not set
1167# CONFIG_KEYBOARD_XTKBD is not set
1168CONFIG_INPUT_MOUSE=y
1169CONFIG_MOUSE_PS2=y
1170CONFIG_MOUSE_PS2_ALPS=y
1171CONFIG_MOUSE_PS2_LOGIPS2PP=y
1172CONFIG_MOUSE_PS2_SYNAPTICS=y
1173CONFIG_MOUSE_PS2_TRACKPOINT=y
1174# CONFIG_MOUSE_PS2_ELANTECH is not set
1175# CONFIG_MOUSE_PS2_SENTELIC is not set
1176# CONFIG_MOUSE_PS2_TOUCHKIT is not set
1177# CONFIG_MOUSE_SERIAL is not set
1178# CONFIG_MOUSE_APPLETOUCH is not set
1179# CONFIG_MOUSE_BCM5974 is not set
1180# CONFIG_MOUSE_VSXXXAA is not set
1181# CONFIG_MOUSE_GPIO is not set
1182# CONFIG_MOUSE_SYNAPTICS_I2C is not set
1183# CONFIG_INPUT_JOYSTICK is not set
1184# CONFIG_INPUT_TABLET is not set
1185CONFIG_INPUT_TOUCHSCREEN=y
1186# CONFIG_TOUCHSCREEN_ADS7846 is not set
1187# CONFIG_TOUCHSCREEN_AD7877 is not set
1188# CONFIG_TOUCHSCREEN_AD7879 is not set
1189# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
1190# CONFIG_TOUCHSCREEN_BU21013 is not set
1191# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
1192# CONFIG_TOUCHSCREEN_DYNAPRO is not set
1193# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
1194# CONFIG_TOUCHSCREEN_EETI is not set
1195# CONFIG_TOUCHSCREEN_FUJITSU is not set
1196# CONFIG_TOUCHSCREEN_GUNZE is not set
1197# CONFIG_TOUCHSCREEN_ELO is not set
1198# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
1199# CONFIG_TOUCHSCREEN_MAX11801 is not set
1200# CONFIG_TOUCHSCREEN_MCS5000 is not set
1201# CONFIG_TOUCHSCREEN_MTOUCH is not set
1202# CONFIG_TOUCHSCREEN_INEXIO is not set
1203# CONFIG_TOUCHSCREEN_MK712 is not set
1204# CONFIG_TOUCHSCREEN_PENMOUNT is not set
1205# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
1206# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
1207CONFIG_TOUCHSCREEN_TI_TSCADC=y
1208# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
1209# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
1210# CONFIG_TOUCHSCREEN_TSC_SERIO is not set
1211# CONFIG_TOUCHSCREEN_TSC2005 is not set
1212# CONFIG_TOUCHSCREEN_TSC2007 is not set
1213# CONFIG_TOUCHSCREEN_W90X900 is not set
1214# CONFIG_TOUCHSCREEN_ST1232 is not set
1215# CONFIG_TOUCHSCREEN_TPS6507X is not set
1216CONFIG_INPUT_MISC=y
1217# CONFIG_INPUT_AD714X is not set
1218# CONFIG_INPUT_BMA150 is not set
1219# CONFIG_INPUT_MMA8450 is not set
1220# CONFIG_INPUT_MPU3050 is not set
1221# CONFIG_INPUT_ATI_REMOTE2 is not set
1222# CONFIG_INPUT_KEYSPAN_REMOTE is not set
1223# CONFIG_INPUT_KXTJ9 is not set
1224# CONFIG_INPUT_POWERMATE is not set
1225# CONFIG_INPUT_YEALINK is not set
1226# CONFIG_INPUT_CM109 is not set
1227# CONFIG_INPUT_TWL4030_PWRBUTTON is not set
1228# CONFIG_INPUT_TWL4030_VIBRA is not set
1229# CONFIG_INPUT_TWL6040_VIBRA is not set
1230# CONFIG_INPUT_UINPUT is not set
1231# CONFIG_INPUT_PCF8574 is not set
1232# CONFIG_INPUT_PWM_BEEPER is not set
1233# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
1234# CONFIG_INPUT_ADXL34X is not set
1235# CONFIG_INPUT_CMA3000 is not set
1236
1237#
1238# Hardware I/O ports
1239#
1240CONFIG_SERIO=y
1241# CONFIG_SERIO_SERPORT is not set
1242CONFIG_SERIO_LIBPS2=y
1243# CONFIG_SERIO_RAW is not set
1244# CONFIG_SERIO_ALTERA_PS2 is not set
1245# CONFIG_SERIO_PS2MULT is not set
1246# CONFIG_GAMEPORT is not set
1247
1248#
1249# Character devices
1250#
1251CONFIG_VT=y
1252CONFIG_CONSOLE_TRANSLATIONS=y
1253CONFIG_VT_CONSOLE=y
1254CONFIG_VT_CONSOLE_SLEEP=y
1255CONFIG_HW_CONSOLE=y
1256CONFIG_VT_HW_CONSOLE_BINDING=y
1257CONFIG_UNIX98_PTYS=y
1258# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
1259# CONFIG_LEGACY_PTYS is not set
1260# CONFIG_SERIAL_NONSTANDARD is not set
1261# CONFIG_N_GSM is not set
1262# CONFIG_TRACE_SINK is not set
1263CONFIG_DEVKMEM=y
1264
1265#
1266# Serial drivers
1267#
1268# CONFIG_SERIAL_8250 is not set
1269
1270#
1271# Non-8250 serial port support
1272#
1273# CONFIG_SERIAL_MAX3100 is not set
1274# CONFIG_SERIAL_MAX3107 is not set
1275CONFIG_SERIAL_CORE=y
1276CONFIG_SERIAL_CORE_CONSOLE=y
1277CONFIG_SERIAL_OMAP=y
1278CONFIG_SERIAL_OMAP_CONSOLE=y
1279# CONFIG_SERIAL_TIMBERDALE is not set
1280# CONFIG_SERIAL_ALTERA_JTAGUART is not set
1281# CONFIG_SERIAL_ALTERA_UART is not set
1282# CONFIG_SERIAL_IFX6X60 is not set
1283# CONFIG_SERIAL_XILINX_PS_UART is not set
1284# CONFIG_HVC_DCC is not set
1285# CONFIG_IPMI_HANDLER is not set
1286# CONFIG_HW_RANDOM is not set
1287# CONFIG_R3964 is not set
1288# CONFIG_RAW_DRIVER is not set
1289# CONFIG_TCG_TPM is not set
1290# CONFIG_RAMOOPS is not set
1291CONFIG_I2C=y
1292CONFIG_I2C_BOARDINFO=y
1293CONFIG_I2C_COMPAT=y
1294CONFIG_I2C_CHARDEV=y
1295# CONFIG_I2C_MUX is not set
1296CONFIG_I2C_HELPER_AUTO=y
1297
1298#
1299# I2C Hardware Bus support
1300#
1301
1302#
1303# I2C system bus drivers (mostly embedded / system-on-chip)
1304#
1305# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
1306# CONFIG_I2C_GPIO is not set
1307# CONFIG_I2C_OCORES is not set
1308CONFIG_I2C_OMAP=y
1309# CONFIG_I2C_PCA_PLATFORM is not set
1310# CONFIG_I2C_PXA_PCI is not set
1311# CONFIG_I2C_SIMTEC is not set
1312# CONFIG_I2C_XILINX is not set
1313
1314#
1315# External I2C/SMBus adapter drivers
1316#
1317# CONFIG_I2C_DIOLAN_U2C is not set
1318# CONFIG_I2C_PARPORT_LIGHT is not set
1319# CONFIG_I2C_TAOS_EVM is not set
1320# CONFIG_I2C_TINY_USB is not set
1321
1322#
1323# Other I2C/SMBus bus drivers
1324#
1325# CONFIG_I2C_STUB is not set
1326# CONFIG_I2C_DEBUG_CORE is not set
1327# CONFIG_I2C_DEBUG_ALGO is not set
1328# CONFIG_I2C_DEBUG_BUS is not set
1329CONFIG_SPI=y
1330CONFIG_SPI_MASTER=y
1331
1332#
1333# SPI Master Controller Drivers
1334#
1335# CONFIG_SPI_ALTERA is not set
1336# CONFIG_SPI_BITBANG is not set
1337# CONFIG_SPI_GPIO is not set
1338# CONFIG_SPI_OC_TINY is not set
1339CONFIG_SPI_OMAP24XX=y
1340# CONFIG_SPI_PXA2XX_PCI is not set
1341# CONFIG_SPI_XILINX is not set
1342# CONFIG_SPI_DESIGNWARE is not set
1343
1344#
1345# SPI Protocol Masters
1346#
1347# CONFIG_SPI_SPIDEV is not set
1348# CONFIG_SPI_TLE62X0 is not set
1349
1350#
1351# PPS support
1352#
1353# CONFIG_PPS is not set
1354
1355#
1356# PPS generators support
1357#
1358
1359#
1360# PTP clock support
1361#
1362
1363#
1364# Enable Device Drivers -> PPS to see the PTP clock options.
1365#
1366CONFIG_ARCH_REQUIRE_GPIOLIB=y
1367CONFIG_GPIOLIB=y
1368CONFIG_GPIO_SYSFS=y
1369
1370#
1371# Memory mapped GPIO drivers:
1372#
1373# CONFIG_GPIO_GENERIC_PLATFORM is not set
1374# CONFIG_GPIO_IT8761E is not set
1375
1376#
1377# I2C GPIO expanders:
1378#
1379# CONFIG_GPIO_MAX7300 is not set
1380# CONFIG_GPIO_MAX732X is not set
1381# CONFIG_GPIO_PCF857X is not set
1382# CONFIG_GPIO_SX150X is not set
1383# CONFIG_GPIO_TWL4030 is not set
1384# CONFIG_GPIO_ADP5588 is not set
1385
1386#
1387# PCI GPIO expanders:
1388#
1389
1390#
1391# SPI GPIO expanders:
1392#
1393# CONFIG_GPIO_MAX7301 is not set
1394# CONFIG_GPIO_MCP23S08 is not set
1395# CONFIG_GPIO_MC33880 is not set
1396# CONFIG_GPIO_74X164 is not set
1397
1398#
1399# AC97 GPIO expanders:
1400#
1401
1402#
1403# MODULbus GPIO expanders:
1404#
1405CONFIG_GPIO_TPS65910=y
1406CONFIG_GENERIC_PWM=y
1407CONFIG_DAVINCI_EHRPWM=y
1408CONFIG_ECAP_PWM=y
1409# CONFIG_W1 is not set
1410# CONFIG_POWER_SUPPLY is not set
1411CONFIG_HWMON=y
1412# CONFIG_HWMON_VID is not set
1413# CONFIG_HWMON_DEBUG_CHIP is not set
1414
1415#
1416# Native drivers
1417#
1418# CONFIG_SENSORS_AD7314 is not set
1419# CONFIG_SENSORS_AD7414 is not set
1420# CONFIG_SENSORS_AD7418 is not set
1421# CONFIG_SENSORS_ADCXX is not set
1422# CONFIG_SENSORS_ADM1021 is not set
1423# CONFIG_SENSORS_ADM1025 is not set
1424# CONFIG_SENSORS_ADM1026 is not set
1425# CONFIG_SENSORS_ADM1029 is not set
1426# CONFIG_SENSORS_ADM1031 is not set
1427# CONFIG_SENSORS_ADM9240 is not set
1428# CONFIG_SENSORS_ADT7411 is not set
1429# CONFIG_SENSORS_ADT7462 is not set
1430# CONFIG_SENSORS_ADT7470 is not set
1431# CONFIG_SENSORS_ADT7475 is not set
1432# CONFIG_SENSORS_ASC7621 is not set
1433# CONFIG_SENSORS_ATXP1 is not set
1434# CONFIG_SENSORS_DS620 is not set
1435# CONFIG_SENSORS_DS1621 is not set
1436# CONFIG_SENSORS_F71805F is not set
1437# CONFIG_SENSORS_F71882FG is not set
1438# CONFIG_SENSORS_F75375S is not set
1439# CONFIG_SENSORS_G760A is not set
1440# CONFIG_SENSORS_GL518SM is not set
1441# CONFIG_SENSORS_GL520SM is not set
1442# CONFIG_SENSORS_GPIO_FAN is not set
1443# CONFIG_SENSORS_IT87 is not set
1444# CONFIG_SENSORS_JC42 is not set
1445# CONFIG_SENSORS_LINEAGE is not set
1446# CONFIG_SENSORS_LM63 is not set
1447# CONFIG_SENSORS_LM70 is not set
1448# CONFIG_SENSORS_LM73 is not set
1449CONFIG_SENSORS_LM75=y
1450# CONFIG_SENSORS_LM77 is not set
1451# CONFIG_SENSORS_LM78 is not set
1452# CONFIG_SENSORS_LM80 is not set
1453# CONFIG_SENSORS_LM83 is not set
1454# CONFIG_SENSORS_LM85 is not set
1455# CONFIG_SENSORS_LM87 is not set
1456# CONFIG_SENSORS_LM90 is not set
1457# CONFIG_SENSORS_LM92 is not set
1458# CONFIG_SENSORS_LM93 is not set
1459# CONFIG_SENSORS_LTC4151 is not set
1460# CONFIG_SENSORS_LTC4215 is not set
1461# CONFIG_SENSORS_LTC4245 is not set
1462# CONFIG_SENSORS_LTC4261 is not set
1463# CONFIG_SENSORS_LM95241 is not set
1464# CONFIG_SENSORS_LM95245 is not set
1465# CONFIG_SENSORS_MAX1111 is not set
1466# CONFIG_SENSORS_MAX16065 is not set
1467# CONFIG_SENSORS_MAX1619 is not set
1468# CONFIG_SENSORS_MAX1668 is not set
1469# CONFIG_SENSORS_MAX6639 is not set
1470# CONFIG_SENSORS_MAX6642 is not set
1471# CONFIG_SENSORS_MAX6650 is not set
1472# CONFIG_SENSORS_NTC_THERMISTOR is not set
1473# CONFIG_SENSORS_PC87360 is not set
1474# CONFIG_SENSORS_PC87427 is not set
1475# CONFIG_SENSORS_PCF8591 is not set
1476# CONFIG_PMBUS is not set
1477# CONFIG_SENSORS_SHT15 is not set
1478# CONFIG_SENSORS_SHT21 is not set
1479# CONFIG_SENSORS_SMM665 is not set
1480# CONFIG_SENSORS_DME1737 is not set
1481# CONFIG_SENSORS_EMC1403 is not set
1482# CONFIG_SENSORS_EMC2103 is not set
1483# CONFIG_SENSORS_EMC6W201 is not set
1484# CONFIG_SENSORS_SMSC47M1 is not set
1485# CONFIG_SENSORS_SMSC47M192 is not set
1486# CONFIG_SENSORS_SMSC47B397 is not set
1487# CONFIG_SENSORS_SCH56XX_COMMON is not set
1488# CONFIG_SENSORS_SCH5627 is not set
1489# CONFIG_SENSORS_SCH5636 is not set
1490# CONFIG_SENSORS_ADS1015 is not set
1491# CONFIG_SENSORS_ADS7828 is not set
1492# CONFIG_SENSORS_ADS7871 is not set
1493# CONFIG_SENSORS_AMC6821 is not set
1494# CONFIG_SENSORS_THMC50 is not set
1495# CONFIG_SENSORS_TMP102 is not set
1496# CONFIG_SENSORS_TMP401 is not set
1497# CONFIG_SENSORS_TMP421 is not set
1498# CONFIG_SENSORS_VT1211 is not set
1499# CONFIG_SENSORS_W83781D is not set
1500# CONFIG_SENSORS_W83791D is not set
1501# CONFIG_SENSORS_W83792D is not set
1502# CONFIG_SENSORS_W83793 is not set
1503# CONFIG_SENSORS_W83795 is not set
1504# CONFIG_SENSORS_W83L785TS is not set
1505# CONFIG_SENSORS_W83L786NG is not set
1506# CONFIG_SENSORS_W83627HF is not set
1507# CONFIG_SENSORS_W83627EHF is not set
1508# CONFIG_THERMAL is not set
1509CONFIG_WATCHDOG=y
1510# CONFIG_WATCHDOG_CORE is not set
1511# CONFIG_WATCHDOG_NOWAYOUT is not set
1512
1513#
1514# Watchdog Device Drivers
1515#
1516# CONFIG_SOFT_WATCHDOG is not set
1517# CONFIG_DW_WATCHDOG is not set
1518CONFIG_OMAP_WATCHDOG=y
1519# CONFIG_TWL4030_WATCHDOG is not set
1520# CONFIG_MAX63XX_WATCHDOG is not set
1521
1522#
1523# USB-based Watchdog Cards
1524#
1525# CONFIG_USBPCWATCHDOG is not set
1526CONFIG_SSB_POSSIBLE=y
1527
1528#
1529# Sonics Silicon Backplane
1530#
1531# CONFIG_SSB is not set
1532CONFIG_BCMA_POSSIBLE=y
1533
1534#
1535# Broadcom specific AMBA
1536#
1537# CONFIG_BCMA is not set
1538
1539#
1540# Multifunction device drivers
1541#
1542CONFIG_MFD_CORE=y
1543# CONFIG_MFD_88PM860X is not set
1544# CONFIG_MFD_SM501 is not set
1545# CONFIG_MFD_ASIC3 is not set
1546# CONFIG_HTC_EGPIO is not set
1547# CONFIG_HTC_PASIC3 is not set
1548# CONFIG_HTC_I2CPLD is not set
1549# CONFIG_TPS6105X is not set
1550# CONFIG_TPS65010 is not set
1551# CONFIG_TPS6507X is not set
1552CONFIG_MFD_TPS65217=y
1553# CONFIG_MFD_TPS6586X is not set
1554CONFIG_MFD_TPS65910=y
1555# CONFIG_MFD_TPS65912_I2C is not set
1556# CONFIG_MFD_TPS65912_SPI is not set
1557CONFIG_TWL4030_CORE=y
1558# CONFIG_TWL4030_MADC is not set
1559CONFIG_TWL4030_POWER=y
1560# CONFIG_MFD_TWL4030_AUDIO is not set
1561# CONFIG_TWL6030_PWM is not set
1562# CONFIG_TWL6040_CORE is not set
1563# CONFIG_MFD_STMPE is not set
1564# CONFIG_MFD_TC3589X is not set
1565# CONFIG_MFD_TMIO is not set
1566# CONFIG_MFD_T7L66XB is not set
1567# CONFIG_MFD_TC6387XB is not set
1568# CONFIG_MFD_TC6393XB is not set
1569# CONFIG_PMIC_DA903X is not set
1570# CONFIG_PMIC_ADP5520 is not set
1571# CONFIG_MFD_MAX8925 is not set
1572# CONFIG_MFD_MAX8997 is not set
1573# CONFIG_MFD_MAX8998 is not set
1574# CONFIG_MFD_WM8400 is not set
1575# CONFIG_MFD_WM831X_I2C is not set
1576# CONFIG_MFD_WM831X_SPI is not set
1577# CONFIG_MFD_WM8350_I2C is not set
1578# CONFIG_MFD_WM8994 is not set
1579# CONFIG_MFD_PCF50633 is not set
1580# CONFIG_MFD_MC13XXX is not set
1581# CONFIG_ABX500_CORE is not set
1582# CONFIG_EZX_PCAP is not set
1583# CONFIG_MFD_WL1273_CORE is not set
1584# CONFIG_MFD_AAT2870_CORE is not set
1585CONFIG_REGULATOR=y
1586# CONFIG_REGULATOR_DEBUG is not set
1587CONFIG_REGULATOR_DUMMY=y
1588CONFIG_REGULATOR_FIXED_VOLTAGE=y
1589# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
1590# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
1591# CONFIG_REGULATOR_GPIO is not set
1592# CONFIG_REGULATOR_BQ24022 is not set
1593# CONFIG_REGULATOR_MAX1586 is not set
1594# CONFIG_REGULATOR_MAX8649 is not set
1595# CONFIG_REGULATOR_MAX8660 is not set
1596# CONFIG_REGULATOR_MAX8952 is not set
1597# CONFIG_REGULATOR_TWL4030 is not set
1598# CONFIG_REGULATOR_LP3971 is not set
1599# CONFIG_REGULATOR_LP3972 is not set
1600# CONFIG_REGULATOR_TPS65023 is not set
1601# CONFIG_REGULATOR_TPS6507X is not set
1602CONFIG_REGULATOR_TPS65217=y
1603# CONFIG_REGULATOR_ISL6271A is not set
1604# CONFIG_REGULATOR_AD5398 is not set
1605# CONFIG_REGULATOR_TPS6524X is not set
1606CONFIG_REGULATOR_TPS65910=y
1607CONFIG_MEDIA_SUPPORT=y
1608
1609#
1610# Multimedia core support
1611#
1612# CONFIG_MEDIA_CONTROLLER is not set
1613CONFIG_VIDEO_DEV=y
1614CONFIG_VIDEO_V4L2_COMMON=y
1615# CONFIG_DVB_CORE is not set
1616CONFIG_VIDEO_MEDIA=y
1617
1618#
1619# Multimedia drivers
1620#
1621# CONFIG_RC_CORE is not set
1622# CONFIG_MEDIA_ATTACH is not set
1623CONFIG_MEDIA_TUNER=y
1624# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
1625CONFIG_MEDIA_TUNER_SIMPLE=y
1626CONFIG_MEDIA_TUNER_TDA8290=y
1627CONFIG_MEDIA_TUNER_TDA827X=y
1628CONFIG_MEDIA_TUNER_TDA18271=y
1629CONFIG_MEDIA_TUNER_TDA9887=y
1630CONFIG_MEDIA_TUNER_TEA5761=y
1631CONFIG_MEDIA_TUNER_TEA5767=y
1632CONFIG_MEDIA_TUNER_MT20XX=y
1633CONFIG_MEDIA_TUNER_XC2028=y
1634CONFIG_MEDIA_TUNER_XC5000=y
1635CONFIG_MEDIA_TUNER_XC4000=y
1636CONFIG_MEDIA_TUNER_MC44S803=y
1637CONFIG_VIDEO_V4L2=y
1638CONFIG_VIDEO_CAPTURE_DRIVERS=y
1639# CONFIG_VIDEO_ADV_DEBUG is not set
1640# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
1641# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
1642
1643#
1644# Encoders, decoders, sensors and other helper chips
1645#
1646
1647#
1648# Audio decoders, processors and mixers
1649#
1650# CONFIG_VIDEO_TVAUDIO is not set
1651# CONFIG_VIDEO_TDA7432 is not set
1652# CONFIG_VIDEO_TDA9840 is not set
1653# CONFIG_VIDEO_TEA6415C is not set
1654# CONFIG_VIDEO_TEA6420 is not set
1655# CONFIG_VIDEO_MSP3400 is not set
1656# CONFIG_VIDEO_CS5345 is not set
1657# CONFIG_VIDEO_CS53L32A is not set
1658# CONFIG_VIDEO_TLV320AIC23B is not set
1659# CONFIG_VIDEO_WM8775 is not set
1660# CONFIG_VIDEO_WM8739 is not set
1661# CONFIG_VIDEO_VP27SMPX is not set
1662
1663#
1664# RDS decoders
1665#
1666# CONFIG_VIDEO_SAA6588 is not set
1667
1668#
1669# Video decoders
1670#
1671# CONFIG_VIDEO_ADV7180 is not set
1672# CONFIG_VIDEO_BT819 is not set
1673# CONFIG_VIDEO_BT856 is not set
1674# CONFIG_VIDEO_BT866 is not set
1675# CONFIG_VIDEO_KS0127 is not set
1676# CONFIG_VIDEO_SAA7110 is not set
1677# CONFIG_VIDEO_SAA711X is not set
1678# CONFIG_VIDEO_SAA7191 is not set
1679# CONFIG_VIDEO_TVP514X is not set
1680# CONFIG_VIDEO_TVP5150 is not set
1681# CONFIG_VIDEO_TVP7002 is not set
1682# CONFIG_VIDEO_VPX3220 is not set
1683
1684#
1685# Video and audio decoders
1686#
1687# CONFIG_VIDEO_SAA717X is not set
1688# CONFIG_VIDEO_CX25840 is not set
1689
1690#
1691# MPEG video encoders
1692#
1693# CONFIG_VIDEO_CX2341X is not set
1694
1695#
1696# Video encoders
1697#
1698# CONFIG_VIDEO_SAA7127 is not set
1699# CONFIG_VIDEO_SAA7185 is not set
1700# CONFIG_VIDEO_ADV7170 is not set
1701# CONFIG_VIDEO_ADV7175 is not set
1702# CONFIG_VIDEO_ADV7343 is not set
1703# CONFIG_VIDEO_AK881X is not set
1704
1705#
1706# Camera sensor devices
1707#
1708# CONFIG_VIDEO_OV7670 is not set
1709# CONFIG_VIDEO_MT9V011 is not set
1710# CONFIG_VIDEO_TCM825X is not set
1711# CONFIG_VIDEO_SR030PC30 is not set
1712
1713#
1714# Flash devices
1715#
1716
1717#
1718# Video improvement chips
1719#
1720# CONFIG_VIDEO_UPD64031A is not set
1721# CONFIG_VIDEO_UPD64083 is not set
1722
1723#
1724# Miscelaneous helper chips
1725#
1726# CONFIG_VIDEO_THS7303 is not set
1727# CONFIG_VIDEO_M52790 is not set
1728# CONFIG_VIDEO_VIVI is not set
1729# CONFIG_VIDEO_VPFE_CAPTURE is not set
1730# CONFIG_VIDEO_OMAP2_VOUT is not set
1731# CONFIG_VIDEO_CPIA2 is not set
1732# CONFIG_SOC_CAMERA is not set
1733CONFIG_V4L_USB_DRIVERS=y
1734CONFIG_USB_VIDEO_CLASS=y
1735CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
1736# CONFIG_USB_GSPCA is not set
1737# CONFIG_VIDEO_PVRUSB2 is not set
1738# CONFIG_VIDEO_HDPVR is not set
1739# CONFIG_VIDEO_EM28XX is not set
1740# CONFIG_VIDEO_USBVISION is not set
1741# CONFIG_USB_ET61X251 is not set
1742# CONFIG_USB_SN9C102 is not set
1743# CONFIG_USB_PWC is not set
1744# CONFIG_USB_ZR364XX is not set
1745# CONFIG_USB_STKWEBCAM is not set
1746# CONFIG_USB_S2255 is not set
1747# CONFIG_V4L_MEM2MEM_DRIVERS is not set
1748# CONFIG_RADIO_ADAPTERS is not set
1749
1750#
1751# Graphics support
1752#
1753# CONFIG_DRM is not set
1754# CONFIG_VGASTATE is not set
1755# CONFIG_VIDEO_OUTPUT_CONTROL is not set
1756CONFIG_FB=y
1757# CONFIG_FIRMWARE_EDID is not set
1758# CONFIG_FB_DDC is not set
1759# CONFIG_FB_BOOT_VESA_SUPPORT is not set
1760CONFIG_FB_CFB_FILLRECT=y
1761CONFIG_FB_CFB_COPYAREA=y
1762CONFIG_FB_CFB_IMAGEBLIT=y
1763# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
1764# CONFIG_FB_SYS_FILLRECT is not set
1765# CONFIG_FB_SYS_COPYAREA is not set
1766# CONFIG_FB_SYS_IMAGEBLIT is not set
1767# CONFIG_FB_FOREIGN_ENDIAN is not set
1768# CONFIG_FB_SYS_FOPS is not set
1769# CONFIG_FB_WMT_GE_ROPS is not set
1770# CONFIG_FB_SVGALIB is not set
1771# CONFIG_FB_MACMODES is not set
1772# CONFIG_FB_BACKLIGHT is not set
1773# CONFIG_FB_MODE_HELPERS is not set
1774# CONFIG_FB_TILEBLITTING is not set
1775
1776#
1777# Frame buffer hardware drivers
1778#
1779# CONFIG_FB_S1D13XXX is not set
1780# CONFIG_FB_TMIO is not set
1781# CONFIG_FB_SMSCUFX is not set
1782# CONFIG_FB_UDL is not set
1783CONFIG_FB_DA8XX=y
1784CONFIG_FB_DA8XX_CONSISTENT_DMA_SIZE=5
1785# CONFIG_FB_VIRTUAL is not set
1786# CONFIG_FB_METRONOME is not set
1787# CONFIG_FB_BROADSHEET is not set
1788# CONFIG_FB_OMAP is not set
1789# CONFIG_OMAP2_DSS is not set
1790CONFIG_BACKLIGHT_LCD_SUPPORT=y
1791CONFIG_LCD_CLASS_DEVICE=y
1792# CONFIG_LCD_L4F00242T03 is not set
1793# CONFIG_LCD_LMS283GF05 is not set
1794# CONFIG_LCD_LTV350QV is not set
1795# CONFIG_LCD_TDO24M is not set
1796# CONFIG_LCD_VGG2432A4 is not set
1797# CONFIG_LCD_PLATFORM is not set
1798# CONFIG_LCD_S6E63M0 is not set
1799# CONFIG_LCD_LD9040 is not set
1800# CONFIG_LCD_AMS369FG06 is not set
1801CONFIG_BACKLIGHT_CLASS_DEVICE=y
1802# CONFIG_BACKLIGHT_GENERIC is not set
1803CONFIG_BACKLIGHT_PWM=y
1804# CONFIG_BACKLIGHT_ADP8860 is not set
1805# CONFIG_BACKLIGHT_ADP8870 is not set
1806CONFIG_BACKLIGHT_TLC59108=y
1807
1808#
1809# Display device support
1810#
1811CONFIG_DISPLAY_SUPPORT=y
1812
1813#
1814# Display hardware drivers
1815#
1816
1817#
1818# Console display driver support
1819#
1820CONFIG_DUMMY_CONSOLE=y
1821CONFIG_FRAMEBUFFER_CONSOLE=y
1822# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1823# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1824# CONFIG_FONTS is not set
1825CONFIG_FONT_8x8=y
1826CONFIG_FONT_8x16=y
1827CONFIG_LOGO=y
1828CONFIG_LOGO_LINUX_MONO=y
1829CONFIG_LOGO_LINUX_VGA16=y
1830CONFIG_LOGO_LINUX_CLUT224=y
1831CONFIG_SOUND=y
1832# CONFIG_SOUND_OSS_CORE is not set
1833CONFIG_SND=y
1834CONFIG_SND_TIMER=y
1835CONFIG_SND_PCM=y
1836CONFIG_SND_HWDEP=y
1837CONFIG_SND_RAWMIDI=y
1838CONFIG_SND_JACK=y
1839# CONFIG_SND_SEQUENCER is not set
1840# CONFIG_SND_MIXER_OSS is not set
1841# CONFIG_SND_PCM_OSS is not set
1842# CONFIG_SND_HRTIMER is not set
1843# CONFIG_SND_DYNAMIC_MINORS is not set
1844CONFIG_SND_SUPPORT_OLD_API=y
1845CONFIG_SND_VERBOSE_PROCFS=y
1846# CONFIG_SND_VERBOSE_PRINTK is not set
1847# CONFIG_SND_DEBUG is not set
1848# CONFIG_SND_RAWMIDI_SEQ is not set
1849# CONFIG_SND_OPL3_LIB_SEQ is not set
1850# CONFIG_SND_OPL4_LIB_SEQ is not set
1851# CONFIG_SND_SBAWE_SEQ is not set
1852# CONFIG_SND_EMU10K1_SEQ is not set
1853CONFIG_SND_DRIVERS=y
1854# CONFIG_SND_DUMMY is not set
1855# CONFIG_SND_ALOOP is not set
1856# CONFIG_SND_MTPAV is not set
1857# CONFIG_SND_SERIAL_U16550 is not set
1858# CONFIG_SND_MPU401 is not set
1859CONFIG_SND_ARM=y
1860CONFIG_SND_SPI=y
1861CONFIG_SND_USB=y
1862CONFIG_SND_USB_AUDIO=y
1863# CONFIG_SND_USB_UA101 is not set
1864# CONFIG_SND_USB_CAIAQ is not set
1865# CONFIG_SND_USB_6FIRE is not set
1866CONFIG_SND_SOC=y
1867# CONFIG_SND_SOC_CACHE_LZO is not set
1868CONFIG_SND_AM33XX_SOC=y
1869CONFIG_SND_DAVINCI_SOC_MCASP=y
1870CONFIG_SND_AM335X_SOC_EVM=y
1871# CONFIG_SND_OMAP_SOC is not set
1872CONFIG_SND_SOC_I2C_AND_SPI=y
1873# CONFIG_SND_SOC_ALL_CODECS is not set
1874CONFIG_SND_SOC_TLV320AIC3X=y
1875# CONFIG_SOUND_PRIME is not set
1876CONFIG_HID_SUPPORT=y
1877CONFIG_HID=y
1878# CONFIG_HIDRAW is not set
1879
1880#
1881# USB Input Devices
1882#
1883CONFIG_USB_HID=y
1884# CONFIG_HID_PID is not set
1885# CONFIG_USB_HIDDEV is not set
1886
1887#
1888# Special HID drivers
1889#
1890CONFIG_HID_A4TECH=y
1891# CONFIG_HID_ACRUX is not set
1892CONFIG_HID_APPLE=y
1893CONFIG_HID_BELKIN=y
1894CONFIG_HID_CHERRY=y
1895CONFIG_HID_CHICONY=y
1896# CONFIG_HID_PRODIKEYS is not set
1897CONFIG_HID_CYPRESS=y
1898# CONFIG_HID_DRAGONRISE is not set
1899# CONFIG_HID_EMS_FF is not set
1900CONFIG_HID_EZKEY=y
1901# CONFIG_HID_HOLTEK is not set
1902# CONFIG_HID_KEYTOUCH is not set
1903CONFIG_HID_KYE=y
1904# CONFIG_HID_UCLOGIC is not set
1905# CONFIG_HID_WALTOP is not set
1906# CONFIG_HID_GYRATION is not set
1907# CONFIG_HID_TWINHAN is not set
1908CONFIG_HID_KENSINGTON=y
1909# CONFIG_HID_LCPOWER is not set
1910CONFIG_HID_LOGITECH=y
1911CONFIG_HID_LOGITECH_DJ=m
1912# CONFIG_LOGITECH_FF is not set
1913# CONFIG_LOGIRUMBLEPAD2_FF is not set
1914# CONFIG_LOGIG940_FF is not set
1915# CONFIG_LOGIWHEELS_FF is not set
1916CONFIG_HID_MICROSOFT=y
1917CONFIG_HID_MONTEREY=y
1918# CONFIG_HID_MULTITOUCH is not set
1919# CONFIG_HID_NTRIG is not set
1920# CONFIG_HID_ORTEK is not set
1921# CONFIG_HID_PANTHERLORD is not set
1922# CONFIG_HID_PETALYNX is not set
1923# CONFIG_HID_PICOLCD is not set
1924# CONFIG_HID_PRIMAX is not set
1925# CONFIG_HID_QUANTA is not set
1926# CONFIG_HID_ROCCAT is not set
1927# CONFIG_HID_SAMSUNG is not set
1928# CONFIG_HID_SONY is not set
1929# CONFIG_HID_SPEEDLINK is not set
1930# CONFIG_HID_SUNPLUS is not set
1931# CONFIG_HID_GREENASIA is not set
1932# CONFIG_HID_SMARTJOYPLUS is not set
1933# CONFIG_HID_TOPSEED is not set
1934# CONFIG_HID_THRUSTMASTER is not set
1935# CONFIG_HID_ZEROPLUS is not set
1936# CONFIG_HID_ZYDACRON is not set
1937CONFIG_USB_SUPPORT=y
1938CONFIG_USB_COMMON=y
1939CONFIG_USB_ARCH_HAS_HCD=y
1940CONFIG_USB_ARCH_HAS_OHCI=y
1941CONFIG_USB_ARCH_HAS_EHCI=y
1942# CONFIG_USB_ARCH_HAS_XHCI is not set
1943CONFIG_USB=y
1944# CONFIG_USB_DEBUG is not set
1945CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
1946
1947#
1948# Miscellaneous USB options
1949#
1950CONFIG_USB_DEVICEFS=y
1951CONFIG_USB_DEVICE_CLASS=y
1952# CONFIG_USB_DYNAMIC_MINORS is not set
1953CONFIG_USB_SUSPEND=y
1954CONFIG_USB_OTG=y
1955# CONFIG_USB_OTG_WHITELIST is not set
1956# CONFIG_USB_OTG_BLACKLIST_HUB is not set
1957# CONFIG_USB_DWC3 is not set
1958# CONFIG_USB_MON is not set
1959# CONFIG_USB_WUSB is not set
1960# CONFIG_USB_WUSB_CBAF is not set
1961
1962#
1963# USB Host Controller Drivers
1964#
1965# CONFIG_USB_C67X00_HCD is not set
1966# CONFIG_USB_EHCI_HCD is not set
1967# CONFIG_USB_OXU210HP_HCD is not set
1968# CONFIG_USB_ISP116X_HCD is not set
1969# CONFIG_USB_ISP1760_HCD is not set
1970# CONFIG_USB_ISP1362_HCD is not set
1971# CONFIG_USB_OHCI_HCD is not set
1972# CONFIG_USB_SL811_HCD is not set
1973# CONFIG_USB_R8A66597_HCD is not set
1974# CONFIG_USB_HWA_HCD is not set
1975CONFIG_USB_MUSB_HDRC=y
1976
1977#
1978# Platform Glue Layer
1979#
1980# CONFIG_USB_MUSB_TUSB6010_GLUE is not set
1981# CONFIG_USB_MUSB_OMAP2PLUS_GLUE is not set
1982# CONFIG_USB_MUSB_AM35X_GLUE is not set
1983CONFIG_USB_MUSB_TI81XX_GLUE=y
1984# CONFIG_USB_MUSB_DAVINCI is not set
1985# CONFIG_USB_MUSB_DA8XX is not set
1986# CONFIG_USB_MUSB_TUSB6010 is not set
1987# CONFIG_USB_MUSB_OMAP2PLUS is not set
1988# CONFIG_USB_MUSB_AM35X is not set
1989CONFIG_USB_MUSB_TI81XX=y
1990# CONFIG_USB_MUSB_BLACKFIN is not set
1991# CONFIG_USB_MUSB_UX500 is not set
1992CONFIG_MUSB_PIO_ONLY=y
1993# CONFIG_USB_INVENTRA_DMA is not set
1994# CONFIG_USB_TI_CPPI_DMA is not set
1995# CONFIG_USB_TI_CPPI41_DMA is not set
1996# CONFIG_USB_TUSB_OMAP_DMA is not set
1997# CONFIG_USB_UX500_DMA is not set
1998# CONFIG_USB_RENESAS_USBHS is not set
1999
2000#
2001# USB Device Class drivers
2002#
2003# CONFIG_USB_ACM is not set
2004# CONFIG_USB_PRINTER is not set
2005# CONFIG_USB_WDM is not set
2006# CONFIG_USB_TMC is not set
2007
2008#
2009# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
2010#
2011
2012#
2013# also be needed; see USB_STORAGE Help for more info
2014#
2015CONFIG_USB_STORAGE=y
2016# CONFIG_USB_STORAGE_DEBUG is not set
2017# CONFIG_USB_STORAGE_REALTEK is not set
2018# CONFIG_USB_STORAGE_DATAFAB is not set
2019# CONFIG_USB_STORAGE_FREECOM is not set
2020# CONFIG_USB_STORAGE_ISD200 is not set
2021# CONFIG_USB_STORAGE_USBAT is not set
2022# CONFIG_USB_STORAGE_SDDR09 is not set
2023# CONFIG_USB_STORAGE_SDDR55 is not set
2024# CONFIG_USB_STORAGE_JUMPSHOT is not set
2025# CONFIG_USB_STORAGE_ALAUDA is not set
2026# CONFIG_USB_STORAGE_ONETOUCH is not set
2027# CONFIG_USB_STORAGE_KARMA is not set
2028# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
2029# CONFIG_USB_STORAGE_ENE_UB6250 is not set
2030# CONFIG_USB_UAS is not set
2031# CONFIG_USB_LIBUSUAL is not set
2032
2033#
2034# USB Imaging devices
2035#
2036# CONFIG_USB_MDC800 is not set
2037# CONFIG_USB_MICROTEK is not set
2038
2039#
2040# USB port drivers
2041#
2042# CONFIG_USB_SERIAL is not set
2043
2044#
2045# USB Miscellaneous drivers
2046#
2047# CONFIG_USB_EMI62 is not set
2048# CONFIG_USB_EMI26 is not set
2049# CONFIG_USB_ADUTUX is not set
2050# CONFIG_USB_SEVSEG is not set
2051# CONFIG_USB_RIO500 is not set
2052# CONFIG_USB_LEGOTOWER is not set
2053# CONFIG_USB_LCD is not set
2054# CONFIG_USB_LED is not set
2055# CONFIG_USB_CYPRESS_CY7C63 is not set
2056# CONFIG_USB_CYTHERM is not set
2057# CONFIG_USB_IDMOUSE is not set
2058# CONFIG_USB_FTDI_ELAN is not set
2059# CONFIG_USB_APPLEDISPLAY is not set
2060# CONFIG_USB_SISUSBVGA is not set
2061# CONFIG_USB_LD is not set
2062# CONFIG_USB_TRANCEVIBRATOR is not set
2063# CONFIG_USB_IOWARRIOR is not set
2064# CONFIG_USB_TEST is not set
2065# CONFIG_USB_ISIGHTFW is not set
2066# CONFIG_USB_YUREX is not set
2067CONFIG_USB_GADGET=y
2068# CONFIG_USB_GADGET_DEBUG_FILES is not set
2069# CONFIG_USB_GADGET_DEBUG_FS is not set
2070CONFIG_USB_GADGET_VBUS_DRAW=2
2071CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
2072# CONFIG_USB_FUSB300 is not set
2073# CONFIG_USB_OMAP is not set
2074# CONFIG_USB_R8A66597 is not set
2075CONFIG_USB_GADGET_MUSB_HDRC=y
2076# CONFIG_USB_M66592 is not set
2077# CONFIG_USB_NET2272 is not set
2078# CONFIG_USB_DUMMY_HCD is not set
2079CONFIG_USB_GADGET_DUALSPEED=y
2080# CONFIG_USB_ZERO is not set
2081# CONFIG_USB_AUDIO is not set
2082CONFIG_USB_ETH=m
2083CONFIG_USB_ETH_RNDIS=y
2084# CONFIG_USB_ETH_EEM is not set
2085# CONFIG_USB_G_NCM is not set
2086# CONFIG_USB_GADGETFS is not set
2087# CONFIG_USB_FUNCTIONFS is not set
2088CONFIG_USB_FILE_STORAGE=m
2089# CONFIG_USB_FILE_STORAGE_TEST is not set
2090CONFIG_USB_MASS_STORAGE=m
2091# CONFIG_USB_G_SERIAL is not set
2092# CONFIG_USB_MIDI_GADGET is not set
2093# CONFIG_USB_G_PRINTER is not set
2094# CONFIG_USB_CDC_COMPOSITE is not set
2095# CONFIG_USB_G_ACM_MS is not set
2096# CONFIG_USB_G_MULTI is not set
2097# CONFIG_USB_G_HID is not set
2098# CONFIG_USB_G_DBGP is not set
2099# CONFIG_USB_G_WEBCAM is not set
2100
2101#
2102# OTG and related infrastructure
2103#
2104CONFIG_USB_OTG_UTILS=y
2105# CONFIG_USB_GPIO_VBUS is not set
2106# CONFIG_USB_ULPI is not set
2107# CONFIG_TWL6030_USB is not set
2108CONFIG_NOP_USB_XCEIV=y
2109CONFIG_MMC=y
2110# CONFIG_MMC_DEBUG is not set
2111CONFIG_MMC_UNSAFE_RESUME=y
2112# CONFIG_MMC_CLKGATE is not set
2113
2114#
2115# MMC/SD/SDIO Card Drivers
2116#
2117CONFIG_MMC_BLOCK=y
2118CONFIG_MMC_BLOCK_MINORS=8
2119CONFIG_MMC_BLOCK_BOUNCE=y
2120# CONFIG_SDIO_UART is not set
2121# CONFIG_MMC_TEST is not set
2122
2123#
2124# MMC/SD/SDIO Host Controller Drivers
2125#
2126# CONFIG_MMC_SDHCI is not set
2127# CONFIG_MMC_SDHCI_PXAV3 is not set
2128# CONFIG_MMC_SDHCI_PXAV2 is not set
2129# CONFIG_MMC_OMAP is not set
2130CONFIG_MMC_OMAP_HS=y
2131# CONFIG_MMC_SPI is not set
2132# CONFIG_MMC_DW is not set
2133# CONFIG_MMC_VUB300 is not set
2134# CONFIG_MMC_USHC is not set
2135# CONFIG_MEMSTICK is not set
2136CONFIG_NEW_LEDS=y
2137CONFIG_LEDS_CLASS=y
2138
2139#
2140# LED drivers
2141#
2142# CONFIG_LEDS_LM3530 is not set
2143# CONFIG_LEDS_PCA9532 is not set
2144CONFIG_LEDS_GPIO=y
2145# CONFIG_LEDS_LP3944 is not set
2146# CONFIG_LEDS_LP5521 is not set
2147# CONFIG_LEDS_LP5523 is not set
2148# CONFIG_LEDS_PCA955X is not set
2149# CONFIG_LEDS_DAC124S085 is not set
2150# CONFIG_LEDS_PWM is not set
2151# CONFIG_LEDS_REGULATOR is not set
2152# CONFIG_LEDS_BD2802 is not set
2153# CONFIG_LEDS_LT3593 is not set
2154# CONFIG_LEDS_RENESAS_TPU is not set
2155CONFIG_LEDS_TRIGGERS=y
2156
2157#
2158# LED Triggers
2159#
2160CONFIG_LEDS_TRIGGER_TIMER=y
2161CONFIG_LEDS_TRIGGER_HEARTBEAT=y
2162# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
2163# CONFIG_LEDS_TRIGGER_GPIO is not set
2164# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
2165
2166#
2167# iptables trigger is under Netfilter config (LED target)
2168#
2169# CONFIG_ACCESSIBILITY is not set
2170CONFIG_RTC_LIB=y
2171CONFIG_RTC_CLASS=y
2172CONFIG_RTC_HCTOSYS=y
2173CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
2174# CONFIG_RTC_DEBUG is not set
2175
2176#
2177# RTC interfaces
2178#
2179CONFIG_RTC_INTF_SYSFS=y
2180CONFIG_RTC_INTF_PROC=y
2181CONFIG_RTC_INTF_DEV=y
2182# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
2183# CONFIG_RTC_DRV_TEST is not set
2184
2185#
2186# I2C RTC drivers
2187#
2188# CONFIG_RTC_DRV_DS1307 is not set
2189# CONFIG_RTC_DRV_DS1374 is not set
2190# CONFIG_RTC_DRV_DS1672 is not set
2191# CONFIG_RTC_DRV_DS3232 is not set
2192# CONFIG_RTC_DRV_MAX6900 is not set
2193# CONFIG_RTC_DRV_RS5C372 is not set
2194# CONFIG_RTC_DRV_ISL1208 is not set
2195# CONFIG_RTC_DRV_ISL12022 is not set
2196# CONFIG_RTC_DRV_X1205 is not set
2197# CONFIG_RTC_DRV_PCF8563 is not set
2198# CONFIG_RTC_DRV_PCF8583 is not set
2199# CONFIG_RTC_DRV_M41T80 is not set
2200# CONFIG_RTC_DRV_BQ32K is not set
2201# CONFIG_RTC_DRV_TWL4030 is not set
2202# CONFIG_RTC_DRV_S35390A is not set
2203# CONFIG_RTC_DRV_FM3130 is not set
2204# CONFIG_RTC_DRV_RX8581 is not set
2205# CONFIG_RTC_DRV_RX8025 is not set
2206# CONFIG_RTC_DRV_EM3027 is not set
2207# CONFIG_RTC_DRV_RV3029C2 is not set
2208
2209#
2210# SPI RTC drivers
2211#
2212# CONFIG_RTC_DRV_M41T93 is not set
2213# CONFIG_RTC_DRV_M41T94 is not set
2214# CONFIG_RTC_DRV_DS1305 is not set
2215# CONFIG_RTC_DRV_DS1390 is not set
2216# CONFIG_RTC_DRV_MAX6902 is not set
2217# CONFIG_RTC_DRV_R9701 is not set
2218# CONFIG_RTC_DRV_RS5C348 is not set
2219# CONFIG_RTC_DRV_DS3234 is not set
2220# CONFIG_RTC_DRV_PCF2123 is not set
2221
2222#
2223# Platform RTC drivers
2224#
2225# CONFIG_RTC_DRV_CMOS is not set
2226# CONFIG_RTC_DRV_DS1286 is not set
2227# CONFIG_RTC_DRV_DS1511 is not set
2228# CONFIG_RTC_DRV_DS1553 is not set
2229# CONFIG_RTC_DRV_DS1742 is not set
2230# CONFIG_RTC_DRV_STK17TA8 is not set
2231# CONFIG_RTC_DRV_M48T86 is not set
2232# CONFIG_RTC_DRV_M48T35 is not set
2233# CONFIG_RTC_DRV_M48T59 is not set
2234# CONFIG_RTC_DRV_MSM6242 is not set
2235# CONFIG_RTC_DRV_BQ4802 is not set
2236# CONFIG_RTC_DRV_RP5C01 is not set
2237# CONFIG_RTC_DRV_V3020 is not set
2238
2239#
2240# on-CPU RTC drivers
2241#
2242CONFIG_RTC_DRV_OMAP=y
2243# CONFIG_DMADEVICES is not set
2244# CONFIG_AUXDISPLAY is not set
2245# CONFIG_UIO is not set
2246
2247#
2248# Virtio drivers
2249#
2250# CONFIG_VIRTIO_BALLOON is not set
2251# CONFIG_VIRTIO_MMIO is not set
2252# CONFIG_STAGING is not set
2253CONFIG_CLKDEV_LOOKUP=y
2254
2255#
2256# Hardware Spinlock drivers
2257#
2258CONFIG_CLKSRC_MMIO=y
2259# CONFIG_IOMMU_SUPPORT is not set
2260# CONFIG_VIRT_DRIVERS is not set
2261# CONFIG_PM_DEVFREQ is not set
2262
2263#
2264# File systems
2265#
2266CONFIG_EXT2_FS=y
2267# CONFIG_EXT2_FS_XATTR is not set
2268# CONFIG_EXT2_FS_XIP is not set
2269CONFIG_EXT3_FS=y
2270CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
2271# CONFIG_EXT3_FS_XATTR is not set
2272# CONFIG_EXT4_FS is not set
2273CONFIG_JBD=y
2274# CONFIG_JBD_DEBUG is not set
2275# CONFIG_REISERFS_FS is not set
2276# CONFIG_JFS_FS is not set
2277# CONFIG_XFS_FS is not set
2278# CONFIG_GFS2_FS is not set
2279# CONFIG_BTRFS_FS is not set
2280# CONFIG_NILFS2_FS is not set
2281CONFIG_FS_POSIX_ACL=y
2282CONFIG_FILE_LOCKING=y
2283CONFIG_FSNOTIFY=y
2284CONFIG_DNOTIFY=y
2285CONFIG_INOTIFY_USER=y
2286# CONFIG_FANOTIFY is not set
2287CONFIG_QUOTA=y
2288# CONFIG_QUOTA_NETLINK_INTERFACE is not set
2289CONFIG_PRINT_QUOTA_WARNING=y
2290# CONFIG_QUOTA_DEBUG is not set
2291CONFIG_QUOTA_TREE=y
2292# CONFIG_QFMT_V1 is not set
2293CONFIG_QFMT_V2=y
2294CONFIG_QUOTACTL=y
2295# CONFIG_AUTOFS4_FS is not set
2296# CONFIG_FUSE_FS is not set
2297
2298#
2299# Caches
2300#
2301# CONFIG_FSCACHE is not set
2302
2303#
2304# CD-ROM/DVD Filesystems
2305#
2306# CONFIG_ISO9660_FS is not set
2307# CONFIG_UDF_FS is not set
2308
2309#
2310# DOS/FAT/NT Filesystems
2311#
2312CONFIG_FAT_FS=y
2313CONFIG_MSDOS_FS=y
2314CONFIG_VFAT_FS=y
2315CONFIG_FAT_DEFAULT_CODEPAGE=437
2316CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
2317# CONFIG_NTFS_FS is not set
2318
2319#
2320# Pseudo filesystems
2321#
2322CONFIG_PROC_FS=y
2323CONFIG_PROC_SYSCTL=y
2324CONFIG_PROC_PAGE_MONITOR=y
2325CONFIG_SYSFS=y
2326CONFIG_TMPFS=y
2327# CONFIG_TMPFS_POSIX_ACL is not set
2328# CONFIG_TMPFS_XATTR is not set
2329# CONFIG_HUGETLB_PAGE is not set
2330# CONFIG_CONFIGFS_FS is not set
2331CONFIG_MISC_FILESYSTEMS=y
2332# CONFIG_ADFS_FS is not set
2333# CONFIG_AFFS_FS is not set
2334# CONFIG_ECRYPT_FS is not set
2335# CONFIG_HFS_FS is not set
2336# CONFIG_HFSPLUS_FS is not set
2337# CONFIG_BEFS_FS is not set
2338# CONFIG_BFS_FS is not set
2339# CONFIG_EFS_FS is not set
2340# CONFIG_JFFS2_FS is not set
2341CONFIG_UBIFS_FS=y
2342# CONFIG_UBIFS_FS_XATTR is not set
2343# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
2344CONFIG_UBIFS_FS_LZO=y
2345CONFIG_UBIFS_FS_ZLIB=y
2346# CONFIG_UBIFS_FS_DEBUG is not set
2347# CONFIG_LOGFS is not set
2348CONFIG_CRAMFS=y
2349# CONFIG_SQUASHFS is not set
2350# CONFIG_VXFS_FS is not set
2351# CONFIG_MINIX_FS is not set
2352# CONFIG_OMFS_FS is not set
2353# CONFIG_HPFS_FS is not set
2354# CONFIG_QNX4FS_FS is not set
2355# CONFIG_ROMFS_FS is not set
2356# CONFIG_PSTORE is not set
2357# CONFIG_SYSV_FS is not set
2358# CONFIG_UFS_FS is not set
2359CONFIG_NETWORK_FILESYSTEMS=y
2360CONFIG_NFS_FS=y
2361CONFIG_NFS_V3=y
2362CONFIG_NFS_V3_ACL=y
2363CONFIG_NFS_V4=y
2364# CONFIG_NFS_V4_1 is not set
2365CONFIG_ROOT_NFS=y
2366# CONFIG_NFS_USE_LEGACY_DNS is not set
2367CONFIG_NFS_USE_KERNEL_DNS=y
2368# CONFIG_NFS_USE_NEW_IDMAPPER is not set
2369# CONFIG_NFSD is not set
2370CONFIG_LOCKD=y
2371CONFIG_LOCKD_V4=y
2372CONFIG_NFS_ACL_SUPPORT=y
2373CONFIG_NFS_COMMON=y
2374CONFIG_SUNRPC=y
2375CONFIG_SUNRPC_GSS=y
2376# CONFIG_CEPH_FS is not set
2377# CONFIG_CIFS is not set
2378# CONFIG_NCP_FS is not set
2379# CONFIG_CODA_FS is not set
2380# CONFIG_AFS_FS is not set
2381
2382#
2383# Partition Types
2384#
2385CONFIG_PARTITION_ADVANCED=y
2386# CONFIG_ACORN_PARTITION is not set
2387# CONFIG_OSF_PARTITION is not set
2388# CONFIG_AMIGA_PARTITION is not set
2389# CONFIG_ATARI_PARTITION is not set
2390# CONFIG_MAC_PARTITION is not set
2391CONFIG_MSDOS_PARTITION=y
2392# CONFIG_BSD_DISKLABEL is not set
2393# CONFIG_MINIX_SUBPARTITION is not set
2394# CONFIG_SOLARIS_X86_PARTITION is not set
2395# CONFIG_UNIXWARE_DISKLABEL is not set
2396# CONFIG_LDM_PARTITION is not set
2397# CONFIG_SGI_PARTITION is not set
2398# CONFIG_ULTRIX_PARTITION is not set
2399# CONFIG_SUN_PARTITION is not set
2400# CONFIG_KARMA_PARTITION is not set
2401# CONFIG_EFI_PARTITION is not set
2402# CONFIG_SYSV68_PARTITION is not set
2403CONFIG_NLS=y
2404CONFIG_NLS_DEFAULT="iso8859-1"
2405CONFIG_NLS_CODEPAGE_437=y
2406# CONFIG_NLS_CODEPAGE_737 is not set
2407# CONFIG_NLS_CODEPAGE_775 is not set
2408# CONFIG_NLS_CODEPAGE_850 is not set
2409# CONFIG_NLS_CODEPAGE_852 is not set
2410# CONFIG_NLS_CODEPAGE_855 is not set
2411# CONFIG_NLS_CODEPAGE_857 is not set
2412# CONFIG_NLS_CODEPAGE_860 is not set
2413# CONFIG_NLS_CODEPAGE_861 is not set
2414# CONFIG_NLS_CODEPAGE_862 is not set
2415# CONFIG_NLS_CODEPAGE_863 is not set
2416# CONFIG_NLS_CODEPAGE_864 is not set
2417# CONFIG_NLS_CODEPAGE_865 is not set
2418# CONFIG_NLS_CODEPAGE_866 is not set
2419# CONFIG_NLS_CODEPAGE_869 is not set
2420# CONFIG_NLS_CODEPAGE_936 is not set
2421# CONFIG_NLS_CODEPAGE_950 is not set
2422# CONFIG_NLS_CODEPAGE_932 is not set
2423# CONFIG_NLS_CODEPAGE_949 is not set
2424# CONFIG_NLS_CODEPAGE_874 is not set
2425# CONFIG_NLS_ISO8859_8 is not set
2426# CONFIG_NLS_CODEPAGE_1250 is not set
2427# CONFIG_NLS_CODEPAGE_1251 is not set
2428# CONFIG_NLS_ASCII is not set
2429CONFIG_NLS_ISO8859_1=y
2430# CONFIG_NLS_ISO8859_2 is not set
2431# CONFIG_NLS_ISO8859_3 is not set
2432# CONFIG_NLS_ISO8859_4 is not set
2433# CONFIG_NLS_ISO8859_5 is not set
2434# CONFIG_NLS_ISO8859_6 is not set
2435# CONFIG_NLS_ISO8859_7 is not set
2436# CONFIG_NLS_ISO8859_9 is not set
2437# CONFIG_NLS_ISO8859_13 is not set
2438# CONFIG_NLS_ISO8859_14 is not set
2439# CONFIG_NLS_ISO8859_15 is not set
2440# CONFIG_NLS_KOI8_R is not set
2441# CONFIG_NLS_KOI8_U is not set
2442# CONFIG_NLS_UTF8 is not set
2443
2444#
2445# Kernel hacking
2446#
2447CONFIG_PRINTK_TIME=y
2448CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
2449CONFIG_ENABLE_WARN_DEPRECATED=y
2450CONFIG_ENABLE_MUST_CHECK=y
2451CONFIG_FRAME_WARN=1024
2452CONFIG_MAGIC_SYSRQ=y
2453# CONFIG_STRIP_ASM_SYMS is not set
2454# CONFIG_UNUSED_SYMBOLS is not set
2455CONFIG_DEBUG_FS=y
2456# CONFIG_HEADERS_CHECK is not set
2457# CONFIG_DEBUG_SECTION_MISMATCH is not set
2458# CONFIG_DEBUG_KERNEL is not set
2459# CONFIG_HARDLOCKUP_DETECTOR is not set
2460# CONFIG_SPARSE_RCU_POINTER is not set
2461CONFIG_DEBUG_BUGVERBOSE=y
2462CONFIG_DEBUG_MEMORY_INIT=y
2463CONFIG_FRAME_POINTER=y
2464# CONFIG_LKDTM is not set
2465# CONFIG_SYSCTL_SYSCALL_CHECK is not set
2466CONFIG_HAVE_FUNCTION_TRACER=y
2467CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
2468CONFIG_HAVE_DYNAMIC_FTRACE=y
2469CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
2470CONFIG_HAVE_C_RECORDMCOUNT=y
2471CONFIG_RING_BUFFER=y
2472CONFIG_RING_BUFFER_ALLOW_SWAP=y
2473CONFIG_TRACING_SUPPORT=y
2474# CONFIG_FTRACE is not set
2475CONFIG_DYNAMIC_DEBUG=y
2476# CONFIG_DMA_API_DEBUG is not set
2477# CONFIG_ATOMIC64_SELFTEST is not set
2478# CONFIG_SAMPLES is not set
2479CONFIG_HAVE_ARCH_KGDB=y
2480# CONFIG_TEST_KSTRTOX is not set
2481# CONFIG_STRICT_DEVMEM is not set
2482# CONFIG_ARM_UNWIND is not set
2483# CONFIG_DEBUG_USER is not set
2484CONFIG_DEBUG_JTAG_ENABLE=y
2485
2486#
2487# Security options
2488#
2489CONFIG_KEYS=y
2490# CONFIG_ENCRYPTED_KEYS is not set
2491# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
2492# CONFIG_SECURITY_DMESG_RESTRICT is not set
2493CONFIG_SECURITY=y
2494# CONFIG_SECURITYFS is not set
2495# CONFIG_SECURITY_NETWORK is not set
2496# CONFIG_SECURITY_PATH is not set
2497# CONFIG_SECURITY_TOMOYO is not set
2498# CONFIG_SECURITY_APPARMOR is not set
2499# CONFIG_IMA is not set
2500# CONFIG_EVM is not set
2501CONFIG_DEFAULT_SECURITY_DAC=y
2502CONFIG_DEFAULT_SECURITY=""
2503CONFIG_CRYPTO=y
2504
2505#
2506# Crypto core or helper
2507#
2508CONFIG_CRYPTO_ALGAPI=y
2509CONFIG_CRYPTO_ALGAPI2=y
2510CONFIG_CRYPTO_AEAD=y
2511CONFIG_CRYPTO_AEAD2=y
2512CONFIG_CRYPTO_BLKCIPHER=y
2513CONFIG_CRYPTO_BLKCIPHER2=y
2514CONFIG_CRYPTO_HASH=y
2515CONFIG_CRYPTO_HASH2=y
2516CONFIG_CRYPTO_RNG=y
2517CONFIG_CRYPTO_RNG2=y
2518CONFIG_CRYPTO_PCOMP2=y
2519CONFIG_CRYPTO_MANAGER=y
2520CONFIG_CRYPTO_MANAGER2=y
2521# CONFIG_CRYPTO_USER is not set
2522# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
2523# CONFIG_CRYPTO_GF128MUL is not set
2524# CONFIG_CRYPTO_NULL is not set
2525CONFIG_CRYPTO_WORKQUEUE=y
2526# CONFIG_CRYPTO_CRYPTD is not set
2527# CONFIG_CRYPTO_AUTHENC is not set
2528CONFIG_CRYPTO_TEST=m
2529
2530#
2531# Authenticated Encryption with Associated Data
2532#
2533# CONFIG_CRYPTO_CCM is not set
2534# CONFIG_CRYPTO_GCM is not set
2535CONFIG_CRYPTO_SEQIV=y
2536
2537#
2538# Block modes
2539#
2540CONFIG_CRYPTO_CBC=y
2541CONFIG_CRYPTO_CTR=y
2542# CONFIG_CRYPTO_CTS is not set
2543CONFIG_CRYPTO_ECB=y
2544# CONFIG_CRYPTO_LRW is not set
2545# CONFIG_CRYPTO_PCBC is not set
2546# CONFIG_CRYPTO_XTS is not set
2547
2548#
2549# Hash modes
2550#
2551CONFIG_CRYPTO_HMAC=y
2552# CONFIG_CRYPTO_XCBC is not set
2553# CONFIG_CRYPTO_VMAC is not set
2554
2555#
2556# Digest
2557#
2558CONFIG_CRYPTO_CRC32C=y
2559# CONFIG_CRYPTO_GHASH is not set
2560# CONFIG_CRYPTO_MD4 is not set
2561CONFIG_CRYPTO_MD5=y
2562CONFIG_CRYPTO_MICHAEL_MIC=y
2563# CONFIG_CRYPTO_RMD128 is not set
2564# CONFIG_CRYPTO_RMD160 is not set
2565# CONFIG_CRYPTO_RMD256 is not set
2566# CONFIG_CRYPTO_RMD320 is not set
2567CONFIG_CRYPTO_SHA1=y
2568CONFIG_CRYPTO_SHA256=y
2569# CONFIG_CRYPTO_SHA512 is not set
2570# CONFIG_CRYPTO_TGR192 is not set
2571# CONFIG_CRYPTO_WP512 is not set
2572
2573#
2574# Ciphers
2575#
2576CONFIG_CRYPTO_AES=y
2577# CONFIG_CRYPTO_ANUBIS is not set
2578CONFIG_CRYPTO_ARC4=y
2579# CONFIG_CRYPTO_BLOWFISH is not set
2580# CONFIG_CRYPTO_CAMELLIA is not set
2581# CONFIG_CRYPTO_CAST5 is not set
2582# CONFIG_CRYPTO_CAST6 is not set
2583CONFIG_CRYPTO_DES=y
2584# CONFIG_CRYPTO_FCRYPT is not set
2585# CONFIG_CRYPTO_KHAZAD is not set
2586# CONFIG_CRYPTO_SALSA20 is not set
2587# CONFIG_CRYPTO_SEED is not set
2588# CONFIG_CRYPTO_SERPENT is not set
2589# CONFIG_CRYPTO_TEA is not set
2590# CONFIG_CRYPTO_TWOFISH is not set
2591
2592#
2593# Compression
2594#
2595CONFIG_CRYPTO_DEFLATE=y
2596# CONFIG_CRYPTO_ZLIB is not set
2597CONFIG_CRYPTO_LZO=y
2598
2599#
2600# Random Number Generation
2601#
2602# CONFIG_CRYPTO_ANSI_CPRNG is not set
2603# CONFIG_CRYPTO_USER_API_HASH is not set
2604# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
2605CONFIG_CRYPTO_HW=y
2606CONFIG_CRYPTO_DEV_OMAP4_AES=y
2607CONFIG_CRYPTO_DEV_OMAP4_SHAM=y
2608
2609#
2610# OCF Configuration
2611#
2612CONFIG_OCF_OCF=y
2613# CONFIG_OCF_RANDOMHARVEST is not set
2614CONFIG_OCF_CRYPTODEV=y
2615CONFIG_OCF_CRYPTOSOFT=y
2616# CONFIG_OCF_OCFNULL is not set
2617# CONFIG_OCF_BENCH is not set
2618# CONFIG_BINARY_PRINTF is not set
2619
2620#
2621# Library routines
2622#
2623CONFIG_BITREVERSE=y
2624CONFIG_CRC_CCITT=y
2625CONFIG_CRC16=y
2626CONFIG_CRC_T10DIF=y
2627CONFIG_CRC_ITU_T=y
2628CONFIG_CRC32=y
2629CONFIG_CRC7=y
2630CONFIG_LIBCRC32C=y
2631# CONFIG_CRC8 is not set
2632CONFIG_ZLIB_INFLATE=y
2633CONFIG_ZLIB_DEFLATE=y
2634CONFIG_LZO_COMPRESS=y
2635CONFIG_LZO_DECOMPRESS=y
2636CONFIG_XZ_DEC=y
2637CONFIG_XZ_DEC_X86=y
2638CONFIG_XZ_DEC_POWERPC=y
2639CONFIG_XZ_DEC_IA64=y
2640CONFIG_XZ_DEC_ARM=y
2641CONFIG_XZ_DEC_ARMTHUMB=y
2642CONFIG_XZ_DEC_SPARC=y
2643CONFIG_XZ_DEC_BCJ=y
2644# CONFIG_XZ_DEC_TEST is not set
2645CONFIG_DECOMPRESS_GZIP=y
2646CONFIG_DECOMPRESS_BZIP2=y
2647CONFIG_DECOMPRESS_LZMA=y
2648CONFIG_DECOMPRESS_XZ=y
2649CONFIG_DECOMPRESS_LZO=y
2650CONFIG_GENERIC_ALLOCATOR=y
2651CONFIG_HAS_IOMEM=y
2652CONFIG_HAS_IOPORT=y
2653CONFIG_HAS_DMA=y
2654CONFIG_NLATTR=y
2655CONFIG_AVERAGE=y
2656# CONFIG_CORDIC is not set
diff --git a/recipes-kernel/linux/linux-am335x_3.2.0-psp04.06.00.08.bb b/recipes-kernel/linux/linux-am335x_3.2.0-psp04.06.00.08.bb
new file mode 100644
index 00000000..49d67342
--- /dev/null
+++ b/recipes-kernel/linux/linux-am335x_3.2.0-psp04.06.00.08.bb
@@ -0,0 +1,81 @@
1SECTION = "kernel"
2DESCRIPTION = "Linux kernel for TI33x devices from PSP"
3LICENSE = "GPLv2"
4LIC_FILES_CHKSUM = "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7"
5COMPATIBLE_MACHINE = "ti33x"
6
7DEFAULT_PREFERENCE = "-1"
8
9inherit kernel
10
11# Stage the power management firmware before building the kernel
12DEPENDS += "am33x-cm3"
13
14KERNEL_IMAGETYPE = "uImage"
15
16# The main PR is now using MACHINE_KERNEL_PR, for ti33x see conf/machine/include/ti33x.inc
17MACHINE_KERNEL_PR_append = "a+gitr${SRCREV}"
18
19BRANCH = "v3.2-staging"
20
21# This SRCREV corresponds to tag v3.2_AM335xPSP_04.06.00.08
22SRCREV = "d7e124e8074cccf9958290e773c88a4b2b36412b"
23
24SRC_URI = "git://arago-project.org/git/projects/linux-am33x.git;protocol=git;branch=${BRANCH} \
25 file://defconfig \
26 ${KERNEL_PATCHES} \
27"
28
29S = "${WORKDIR}/git"
30
31# Allow a layer to easily add to the list of patches or completely override them.
32KERNEL_PATCHES ?= "${PATCHES}"
33
34# Add a set of patches that enabled features, fixed bugs or disabled buggy features
35# that weren't part of the official PSP release
36PATCHES = "file://0001-musb-update-PIO-mode-help-information-in-Kconfig.patch \
37 file://0001-am335x_evm_defconfig-turn-off-MUSB-DMA.patch \
38 file://0001-mach-omap2-pm33xx-Disable-VT-switch.patch"
39
40# Add Cryptography support early driver patches while working to get the driver
41# upstream.
42PATCHES += "file://0001-am33x-Add-memory-addresses-for-crypto-modules.patch \
43 file://0002-am33x-Add-crypto-device-and-resource-structures.patch \
44 file://0003-am33x-Add-crypto-device-and-resource-structure-for-T.patch \
45 file://0004-am33x-Add-crypto-drivers-to-Kconfig-and-Makefiles.patch \
46 file://0005-am33x-Create-header-file-for-OMAP4-crypto-modules.patch \
47 file://0006-am33x-Create-driver-for-TRNG-crypto-module.patch \
48 file://0007-am33x-Create-driver-for-AES-crypto-module.patch \
49 file://0008-am33x-Create-driver-for-SHA-MD5-crypto-module.patch \
50 file://0002-AM335x-OCF-Driver-for-Linux-3.patch \
51 file://0001-am335x-Add-crypto-driver-settings-to-defconfig.patch \
52 file://0001-am335x-Add-pm_runtime-API-to-crypto-driver.patch \
53 file://0002-am335x-Add-suspend-resume-routines-to-crypto-driver.patch \
54 "
55
56# Add SmartReflex support early driver patches while working to get the driver
57# upstream.
58PATCHES += "file://0001-am33xx-Add-SmartReflex-support.patch \
59 file://0002-am33xx-Enable-CONFIG_AM33XX_SMARTREFLEX.patch \
60 "
61
62# Add a patch to the omap-serial driver to allow suspend/resume during
63# Bluetooth traffic
64PATCHES += "file://0001-omap-serial-add-delay-before-suspending.patch"
65
66# Add patch to allow wireless to work properly on EVM-SK 1.2.
67PATCHES += "file://0001-am3358-sk-modified-WLAN-enable-and-irq-to-match-boar.patch"
68
69# Add CPU utilization patch for WLAN
70PATCHES += "file://0001-am335xevm-using-edge-triggered-interrupts-for-WLAN.patch"
71
72# Add patch to enable pullup on WLAN enable
73PATCHES += "file://0001-am335x-enable-pullup-on-the-WLAN-enable-pin-fo.patch"
74
75# Copy the am33x-cm3 firmware if it is available
76do_compile_prepend() {
77 if [ -e "${STAGING_DIR_HOST}/${base_libdir}/firmware/am335x-pm-firmware.bin" ]
78 then
79 cp "${STAGING_DIR_HOST}/${base_libdir}/firmware/am335x-pm-firmware.bin" "${S}/firmware"
80 fi
81}