diff options
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 @@ | |||
1 | From 69c82f68876d24e798388fc053c8d6766236ac65 Mon Sep 17 00:00:00 2001 | ||
2 | From: Vita Preskovsky <vitap@ti.com> | ||
3 | Date: Thu, 28 Jun 2012 14:53:12 +0300 | ||
4 | Subject: [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 | |||
8 | Upstream-Status: Pending | ||
9 | |||
10 | Signed-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 | |||
15 | diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c | ||
16 | index 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 | -- | ||
62 | 1.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 @@ | |||
1 | From 1edc97015f69fac420c32df514e1d1d546041d42 Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Turner <gregturner@ti.com> | ||
3 | Date: Fri, 8 Jun 2012 13:54:13 -0500 | ||
4 | Subject: [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 | |||
12 | diff --git a/arch/arm/configs/am335x_evm_defconfig b/arch/arm/configs/am335x_evm_defconfig | ||
13 | old mode 100644 | ||
14 | new mode 100755 | ||
15 | index 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 | -- | ||
130 | 1.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 @@ | |||
1 | From 7cb6dbae57e2bb5d237bb88f6eb40971cf8fc3b5 Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Turner <gregturner@ti.com> | ||
3 | Date: Wed, 18 Jul 2012 09:15:18 -0500 | ||
4 | Subject: [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 | |||
22 | diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c | ||
23 | old mode 100644 | ||
24 | new mode 100755 | ||
25 | index 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) { } | ||
121 | diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c | ||
122 | old mode 100644 | ||
123 | new mode 100755 | ||
124 | index 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 = { | ||
169 | diff --git a/drivers/crypto/omap4-aes.c b/drivers/crypto/omap4-aes.c | ||
170 | old mode 100644 | ||
171 | new mode 100755 | ||
172 | index 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 | |||
289 | diff --git a/drivers/crypto/omap4-sham.c b/drivers/crypto/omap4-sham.c | ||
290 | old mode 100644 | ||
291 | new mode 100755 | ||
292 | index 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 | -- | ||
405 | 1.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 @@ | |||
1 | From f69ffbef6793b7238a8518481735fd53326e0cdf Mon Sep 17 00:00:00 2001 | ||
2 | From: Vita Preskovsky <vitap@ti.com> | ||
3 | Date: Tue, 24 Jul 2012 20:02:28 +0300 | ||
4 | Subject: [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 | |||
11 | Signed-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 | |||
16 | diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c | ||
17 | index 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 | -- | ||
57 | 1.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 @@ | |||
1 | From 95eca5a896c96d0af7188c97825a3b3ef5313ed3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Chase Maupin <Chase.Maupin@ti.com> | ||
3 | Date: Thu, 2 Feb 2012 16:38:51 -0600 | ||
4 | Subject: [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 | |||
10 | Signed-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 | |||
15 | diff --git a/arch/arm/configs/am335x_evm_defconfig b/arch/arm/configs/am335x_evm_defconfig | ||
16 | index 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 | -- | ||
35 | 1.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 @@ | |||
1 | From be52bac69dfe6a56276b16ccd234970c4f7b1255 Mon Sep 17 00:00:00 2001 | ||
2 | From: Vita Preskovsky <vitap@ti.com> | ||
3 | Date: Wed, 18 Jul 2012 16:20:36 +0300 | ||
4 | Subject: [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 | |||
11 | Signed-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 | |||
16 | diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c | ||
17 | index 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 | -- | ||
35 | 1.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 @@ | |||
1 | From 5f2f17a488aba4319b537aed040ea13607af128b Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Turner <gregturner@ti.com> | ||
3 | Date: Thu, 17 May 2012 14:25:40 -0500 | ||
4 | Subject: [PATCH 1/8] am33x: Add memory addresses for crypto modules | ||
5 | |||
6 | * Add base memory addresses to the am33xx.h header file | ||
7 | |||
8 | These addresses are for the HW crypto modules including TRNG, AES, and SHA/MD5 | ||
9 | |||
10 | Signed-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 | |||
16 | diff --git a/arch/arm/plat-omap/include/plat/am33xx.h b/arch/arm/plat-omap/include/plat/am33xx.h | ||
17 | old mode 100644 | ||
18 | new mode 100755 | ||
19 | index 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 | -- | ||
41 | 1.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 @@ | |||
1 | From 35ae6b61d349e5b4efd1c6337a0d1e23b6e86899 Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Guyotte <gguyotte@ti.com> | ||
3 | Date: Thu, 7 Jun 2012 18:05:31 -0500 | ||
4 | Subject: [PATCH] am33xx: Add SmartReflex support. | ||
5 | |||
6 | This patch introduces SmartReflex support to AM33XX devices. The | ||
7 | purpose of SmartReflex is to optimize (lower) voltage based upon | ||
8 | silicon process and temperature. | ||
9 | |||
10 | The SmartReflex driver requires the silicon to be programmed with | ||
11 | "nTarget" EFUSE values. If the values are not present (as with | ||
12 | pre-RTP samples), the driver will simply fail to load and kernel | ||
13 | boot will continue normally. | ||
14 | |||
15 | The SR driver logs several items in the debugfs at /debug/smartreflex. | ||
16 | To disable SmartReflex, use the command 'echo 0 > /debug/smartreflex/autocomp'. | ||
17 | The node /debug/smartreflex/smartreflex0 gives information about | ||
18 | the CORE voltage domain, and /smartreflex1 is related to the MPU voltage | ||
19 | domain. | ||
20 | |||
21 | To determine the effectiveness of SmartReflex, you can compare the | ||
22 | initial voltage with the current voltage for a given OPP. For example, | ||
23 | 'cat /debug/smartreflex/smartreflex1/current_voltage' gives the current | ||
24 | MPU voltage. Comparing that with 'cat /debug/smartreflex/smartreflex1/ | ||
25 | initial_voltage' will show you the voltage drop associated with SR | ||
26 | operation. | ||
27 | |||
28 | Signed-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 | |||
45 | diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile | ||
46 | index 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) | ||
57 | diff --git a/arch/arm/mach-omap2/am33xx-smartreflex-class2.c b/arch/arm/mach-omap2/am33xx-smartreflex-class2.c | ||
58 | new file mode 100644 | ||
59 | index 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"); | ||
1118 | diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c | ||
1119 | index 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 = { | ||
1164 | diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c | ||
1165 | index 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) | ||
1462 | diff --git a/arch/arm/mach-omap2/include/mach/board-am335xevm.h b/arch/arm/mach-omap2/include/mach/board-am335xevm.h | ||
1463 | index 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 | ||
1474 | diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig | ||
1475 | index 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 | ||
1506 | diff --git a/arch/arm/plat-omap/include/plat/am33xx.h b/arch/arm/plat-omap/include/plat/am33xx.h | ||
1507 | index 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 | |||
1520 | diff --git a/arch/arm/plat-omap/include/plat/smartreflex.h b/arch/arm/plat-omap/include/plat/smartreflex.h | ||
1521 | new file mode 100644 | ||
1522 | index 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 | ||
1957 | diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c | ||
1958 | index 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); | ||
1979 | diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h | ||
1980 | index 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 | ||
1992 | diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h | ||
1993 | index 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 | -- | ||
2014 | 1.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 @@ | |||
1 | From 31ec2850e89414efb30accb9d8b5228257e507b1 Mon Sep 17 00:00:00 2001 | ||
2 | From: Chase Maupin <Chase.Maupin@ti.com> | ||
3 | Date: Wed, 21 Mar 2012 10:18:03 -0500 | ||
4 | Subject: [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 | |||
15 | Signed-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 | |||
22 | diff --git a/arch/arm/configs/am335x_evm_defconfig b/arch/arm/configs/am335x_evm_defconfig | ||
23 | index 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 | |||
34 | diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig | ||
35 | index 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 | ||
54 | diff --git a/arch/arm/mach-omap2/pm33xx.c b/arch/arm/mach-omap2/pm33xx.c | ||
55 | index 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 | -- | ||
71 | 1.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 @@ | |||
1 | From 214f6b2fee005dba5e01b3b434f184adf4386a25 Mon Sep 17 00:00:00 2001 | ||
2 | From: Chase Maupin <Chase.Maupin@ti.com> | ||
3 | Date: Thu, 2 Feb 2012 15:52:10 -0600 | ||
4 | Subject: [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 | |||
12 | Upstream-Status: Submitted | ||
13 | * Submitted to the PSP team using the lpr list | ||
14 | |||
15 | Signed-off-by: Matt Porter <mporter@ti.com> | ||
16 | Signed-off-by: Chase Maupin <Chase.Maupin@ti.com> | ||
17 | --- | ||
18 | drivers/usb/musb/Kconfig | 12 ++++++++---- | ||
19 | 1 files changed, 8 insertions(+), 4 deletions(-) | ||
20 | |||
21 | diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig | ||
22 | index 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 | -- | ||
45 | 1.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 @@ | |||
1 | From 0f62d1f4d4543a315815b8eb15ea9cdad25d16c8 Mon Sep 17 00:00:00 2001 | ||
2 | From: Eyal Reizer <eyalr@ti.com> | ||
3 | Date: Wed, 27 Jun 2012 16:08:53 +0300 | ||
4 | Subject: [PATCH] omap-serial: add delay before suspending | ||
5 | |||
6 | In case suspending during Bluetooth traffic, after resume the bluetooth is | ||
7 | stuck. | ||
8 | It was identified that suspend is happening before the UART buffer was | ||
9 | fully drained which caused this hang after resume. | ||
10 | The folliwng delay is a temporary workaround until the issue is resolved | ||
11 | properly. | ||
12 | |||
13 | Upstream Status: Pending | ||
14 | |||
15 | Signed-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 | |||
20 | diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c | ||
21 | index 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 | -- | ||
42 | 1.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 @@ | |||
1 | From a97aac248717d62bdbf322c1d6d422ddfde87de0 Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Turner <gregturner@ti.com> | ||
3 | Date: Thu, 3 May 2012 10:33:13 -0500 | ||
4 | Subject: [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 | |||
48 | diff --git a/crypto/Kconfig b/crypto/Kconfig | ||
49 | index 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 | + | ||
59 | diff --git a/crypto/Makefile b/crypto/Makefile | ||
60 | index 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 | # | ||
72 | diff --git a/crypto/ocf/Config.in b/crypto/ocf/Config.in | ||
73 | new file mode 100755 | ||
74 | index 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 | +############################################################################# | ||
98 | diff --git a/crypto/ocf/Kconfig b/crypto/ocf/Kconfig | ||
99 | new file mode 100755 | ||
100 | index 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 | ||
152 | diff --git a/crypto/ocf/Makefile b/crypto/ocf/Makefile | ||
153 | new file mode 100755 | ||
154 | index 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 | + | ||
296 | diff --git a/crypto/ocf/criov.c b/crypto/ocf/criov.c | ||
297 | new file mode 100644 | ||
298 | index 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 | + | ||
517 | diff --git a/crypto/ocf/crypto.c b/crypto/ocf/crypto.c | ||
518 | new file mode 100644 | ||
519 | index 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(¤t->sigmask_lock); | ||
1959 | +#endif | ||
1960 | + flush_signals(current); | ||
1961 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) | ||
1962 | + spin_unlock_irq(¤t->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(¤t->sigmask_lock); | ||
2039 | +#endif | ||
2040 | + flush_signals(current); | ||
2041 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) | ||
2042 | + spin_unlock_irq(¤t->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)"); | ||
2289 | diff --git a/crypto/ocf/cryptodev.c b/crypto/ocf/cryptodev.c | ||
2290 | new file mode 100644 | ||
2291 | index 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)"); | ||
3364 | diff --git a/crypto/ocf/cryptodev.h b/crypto/ocf/cryptodev.h | ||
3365 | new file mode 100644 | ||
3366 | index 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_ */ | ||
3850 | diff --git a/crypto/ocf/cryptosoft.c b/crypto/ocf/cryptosoft.c | ||
3851 | new file mode 100644 | ||
3852 | index 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)"); | ||
5178 | diff --git a/crypto/ocf/ocf-bench.c b/crypto/ocf/ocf-bench.c | ||
5179 | new file mode 100644 | ||
5180 | index 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"); | ||
5698 | diff --git a/crypto/ocf/ocf-compat.h b/crypto/ocf/ocf-compat.h | ||
5699 | new file mode 100644 | ||
5700 | index 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(¤t->sigmask_lock); \ | ||
5864 | + sigemptyset(¤t->blocked); \ | ||
5865 | + recalc_sigpending(current); \ | ||
5866 | + spin_unlock_irq(¤t->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(¤t->sigmask_lock); | ||
6029 | + sigemptyset(¤t->blocked); | ||
6030 | + recalc_sigpending(current); | ||
6031 | + spin_unlock_irq(¤t->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_ */ | ||
6076 | diff --git a/crypto/ocf/ocfnull/Makefile b/crypto/ocf/ocfnull/Makefile | ||
6077 | new file mode 100644 | ||
6078 | index 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 | + | ||
6094 | diff --git a/crypto/ocf/ocfnull/ocfnull.c b/crypto/ocf/ocfnull/ocfnull.c | ||
6095 | new file mode 100644 | ||
6096 | index 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"); | ||
6304 | diff --git a/crypto/ocf/random.c b/crypto/ocf/random.c | ||
6305 | new file mode 100644 | ||
6306 | index 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(¤t->sigmask_lock); | ||
6506 | + sigemptyset(¤t->blocked); | ||
6507 | + recalc_sigpending(current); | ||
6508 | + spin_unlock_irq(¤t->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(¤t->sigmask_lock); | ||
6608 | +#endif | ||
6609 | + flush_signals(current); | ||
6610 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) | ||
6611 | + spin_unlock_irq(¤t->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 | + | ||
6627 | diff --git a/crypto/ocf/rndtest.c b/crypto/ocf/rndtest.c | ||
6628 | new file mode 100644 | ||
6629 | index 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 | + | ||
6933 | diff --git a/crypto/ocf/rndtest.h b/crypto/ocf/rndtest.h | ||
6934 | new file mode 100644 | ||
6935 | index 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); | ||
6993 | diff --git a/crypto/ocf/uio.h b/crypto/ocf/uio.h | ||
6994 | new file mode 100644 | ||
6995 | index 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 | ||
7053 | diff --git a/drivers/char/random.c b/drivers/char/random.c | ||
7054 | index 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 | ||
7145 | diff --git a/fs/fcntl.c b/fs/fcntl.c | ||
7146 | index 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 | |||
7157 | diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h | ||
7158 | index 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 | ||
7169 | diff --git a/include/linux/random.h b/include/linux/random.h | ||
7170 | index 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 | |||
7215 | diff --git a/kernel/pid.c b/kernel/pid.c | ||
7216 | index 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 | -- | ||
7228 | 1.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 @@ | |||
1 | From 0fb328ec0a5ba8a1440336c8dc7a029cfffa4529 Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Turner <gregturner@ti.com> | ||
3 | Date: Thu, 19 Jul 2012 15:27:59 -0500 | ||
4 | Subject: [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 | |||
14 | diff --git a/drivers/crypto/omap4-aes.c b/drivers/crypto/omap4-aes.c | ||
15 | index 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 | |||
76 | diff --git a/drivers/crypto/omap4-sham.c b/drivers/crypto/omap4-sham.c | ||
77 | index 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 | -- | ||
147 | 1.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 @@ | |||
1 | From 8c0f7553e75774849463f90b0135874754650386 Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Turner <gregturner@ti.com> | ||
3 | Date: Thu, 17 May 2012 14:45:05 -0500 | ||
4 | Subject: [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 | |||
10 | Signed-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 | |||
16 | diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c | ||
17 | old mode 100644 | ||
18 | new mode 100755 | ||
19 | index 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 | -- | ||
111 | 1.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 @@ | |||
1 | From e1b7a67fc82991a633f0ed615d69157c98c1c35d Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Guyotte <gguyotte@ti.com> | ||
3 | Date: Thu, 7 Jun 2012 18:15:21 -0500 | ||
4 | Subject: [PATCH 2/2] am33xx: Enable CONFIG_AM33XX_SMARTREFLEX | ||
5 | |||
6 | Simply enables the SmartReflex driver in the defconfig file. | ||
7 | |||
8 | Signed-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 | |||
13 | diff --git a/arch/arm/configs/am335x_evm_defconfig b/arch/arm/configs/am335x_evm_defconfig | ||
14 | index 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 | -- | ||
26 | 1.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 @@ | |||
1 | From b7477dd40221a91af286bffa110879075a498943 Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Turner <gregturner@ti.com> | ||
3 | Date: Thu, 17 May 2012 14:49:39 -0500 | ||
4 | Subject: [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 | |||
10 | Signed-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 | |||
16 | diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c | ||
17 | old mode 100644 | ||
18 | new mode 100755 | ||
19 | index 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 | -- | ||
60 | 1.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 @@ | |||
1 | From e49e6dcff5665cb2f132d9654a060fa43a382810 Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Turner <gregturner@ti.com> | ||
3 | Date: Thu, 17 May 2012 14:53:25 -0500 | ||
4 | Subject: [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 | |||
10 | Signed-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 | |||
22 | diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig | ||
23 | old mode 100644 | ||
24 | new mode 100755 | ||
25 | index 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 | ||
48 | diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile | ||
49 | old mode 100644 | ||
50 | new mode 100755 | ||
51 | index 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 | ||
62 | diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig | ||
63 | old mode 100644 | ||
64 | new mode 100755 | ||
65 | index 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 | ||
109 | diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile | ||
110 | old mode 100644 | ||
111 | new mode 100755 | ||
112 | index 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 | -- | ||
124 | 1.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 @@ | |||
1 | From 2dc9dec7510746b3c3f5420f4f3ab8395cc7b012 Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Turner <gregturner@ti.com> | ||
3 | Date: Thu, 17 May 2012 14:59:38 -0500 | ||
4 | Subject: [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 | |||
8 | Signed-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 | |||
14 | diff --git a/drivers/crypto/omap4.h b/drivers/crypto/omap4.h | ||
15 | new file mode 100644 | ||
16 | index 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 | -- | ||
213 | 1.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 @@ | |||
1 | From d56c0ab935577ef32ffdf23a62d2e1cecc391730 Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Turner <gregturner@ti.com> | ||
3 | Date: Thu, 17 May 2012 15:11:26 -0500 | ||
4 | Subject: [PATCH 6/8] am33x: Create driver for TRNG crypto module | ||
5 | |||
6 | This 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 | |||
8 | Signed-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 | |||
14 | diff --git a/drivers/char/hw_random/omap4-rng.c b/drivers/char/hw_random/omap4-rng.c | ||
15 | new file mode 100755 | ||
16 | index 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 | -- | ||
324 | 1.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 @@ | |||
1 | From 501def5dd499457a38e6284f9780ba169284e530 Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Turner <gregturner@ti.com> | ||
3 | Date: Thu, 17 May 2012 15:17:13 -0500 | ||
4 | Subject: [PATCH 7/8] am33x: Create driver for AES crypto module | ||
5 | |||
6 | This 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 | |||
8 | Signed-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 | |||
14 | diff --git a/drivers/crypto/omap4-aes.c b/drivers/crypto/omap4-aes.c | ||
15 | new file mode 100755 | ||
16 | index 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 | -- | ||
971 | 1.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 @@ | |||
1 | From 31e5e24a1d713b1f8306050e6b6a640ec30b1848 Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Turner <gregturner@ti.com> | ||
3 | Date: Thu, 17 May 2012 15:19:26 -0500 | ||
4 | Subject: [PATCH 8/8] am33x: Create driver for SHA/MD5 crypto module | ||
5 | |||
6 | This is the initial version of the SHA/MD5 driver for OMAP4 derivative SOC's such as AM335x. | ||
7 | |||
8 | Signed-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 | |||
14 | diff --git a/drivers/crypto/omap4-sham.c b/drivers/crypto/omap4-sham.c | ||
15 | new file mode 100755 | ||
16 | index 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 | -- | ||
1444 | 1.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 | # | ||
5 | CONFIG_ARM=y | ||
6 | CONFIG_HAVE_PWM=y | ||
7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||
8 | CONFIG_HAVE_SCHED_CLOCK=y | ||
9 | CONFIG_GENERIC_GPIO=y | ||
10 | # CONFIG_ARCH_USES_GETTIMEOFFSET is not set | ||
11 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
12 | CONFIG_KTIME_SCALAR=y | ||
13 | CONFIG_HAVE_PROC_CPU=y | ||
14 | CONFIG_STACKTRACE_SUPPORT=y | ||
15 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | ||
16 | CONFIG_LOCKDEP_SUPPORT=y | ||
17 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
18 | CONFIG_HARDIRQS_SW_RESEND=y | ||
19 | CONFIG_GENERIC_IRQ_PROBE=y | ||
20 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
21 | CONFIG_ARCH_HAS_CPUFREQ=y | ||
22 | CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y | ||
23 | CONFIG_GENERIC_HWEIGHT=y | ||
24 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
25 | CONFIG_NEED_DMA_MAP_STATE=y | ||
26 | CONFIG_VECTORS_BASE=0xffff0000 | ||
27 | CONFIG_ARM_PATCH_PHYS_VIRT=y | ||
28 | CONFIG_GENERIC_BUG=y | ||
29 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
30 | CONFIG_HAVE_IRQ_WORK=y | ||
31 | |||
32 | # | ||
33 | # General setup | ||
34 | # | ||
35 | CONFIG_EXPERIMENTAL=y | ||
36 | CONFIG_BROKEN_ON_SMP=y | ||
37 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
38 | CONFIG_CROSS_COMPILE="" | ||
39 | CONFIG_LOCALVERSION="" | ||
40 | CONFIG_LOCALVERSION_AUTO=y | ||
41 | CONFIG_HAVE_KERNEL_GZIP=y | ||
42 | CONFIG_HAVE_KERNEL_LZMA=y | ||
43 | CONFIG_HAVE_KERNEL_LZO=y | ||
44 | CONFIG_KERNEL_GZIP=y | ||
45 | # CONFIG_KERNEL_LZMA is not set | ||
46 | # CONFIG_KERNEL_LZO is not set | ||
47 | CONFIG_DEFAULT_HOSTNAME="(none)" | ||
48 | CONFIG_SWAP=y | ||
49 | CONFIG_SYSVIPC=y | ||
50 | CONFIG_SYSVIPC_SYSCTL=y | ||
51 | CONFIG_POSIX_MQUEUE=y | ||
52 | CONFIG_POSIX_MQUEUE_SYSCTL=y | ||
53 | CONFIG_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 | ||
58 | CONFIG_HAVE_GENERIC_HARDIRQS=y | ||
59 | |||
60 | # | ||
61 | # IRQ subsystem | ||
62 | # | ||
63 | CONFIG_GENERIC_HARDIRQS=y | ||
64 | CONFIG_HAVE_SPARSE_IRQ=y | ||
65 | CONFIG_GENERIC_IRQ_SHOW=y | ||
66 | CONFIG_GENERIC_IRQ_CHIP=y | ||
67 | CONFIG_IRQ_DOMAIN=y | ||
68 | # CONFIG_SPARSE_IRQ is not set | ||
69 | |||
70 | # | ||
71 | # RCU Subsystem | ||
72 | # | ||
73 | CONFIG_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 | ||
77 | CONFIG_IKCONFIG=y | ||
78 | CONFIG_IKCONFIG_PROC=y | ||
79 | CONFIG_LOG_BUF_SHIFT=16 | ||
80 | # CONFIG_CGROUPS is not set | ||
81 | CONFIG_NAMESPACES=y | ||
82 | CONFIG_UTS_NS=y | ||
83 | CONFIG_IPC_NS=y | ||
84 | CONFIG_USER_NS=y | ||
85 | CONFIG_PID_NS=y | ||
86 | CONFIG_NET_NS=y | ||
87 | # CONFIG_SCHED_AUTOGROUP is not set | ||
88 | # CONFIG_SYSFS_DEPRECATED is not set | ||
89 | # CONFIG_RELAY is not set | ||
90 | CONFIG_BLK_DEV_INITRD=y | ||
91 | CONFIG_INITRAMFS_SOURCE="" | ||
92 | CONFIG_RD_GZIP=y | ||
93 | CONFIG_RD_BZIP2=y | ||
94 | CONFIG_RD_LZMA=y | ||
95 | CONFIG_RD_XZ=y | ||
96 | CONFIG_RD_LZO=y | ||
97 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
98 | CONFIG_SYSCTL=y | ||
99 | CONFIG_ANON_INODES=y | ||
100 | # CONFIG_EXPERT is not set | ||
101 | CONFIG_UID16=y | ||
102 | # CONFIG_SYSCTL_SYSCALL is not set | ||
103 | CONFIG_KALLSYMS=y | ||
104 | CONFIG_HOTPLUG=y | ||
105 | CONFIG_PRINTK=y | ||
106 | CONFIG_BUG=y | ||
107 | CONFIG_ELF_CORE=y | ||
108 | CONFIG_BASE_FULL=y | ||
109 | CONFIG_FUTEX=y | ||
110 | CONFIG_EPOLL=y | ||
111 | CONFIG_SIGNALFD=y | ||
112 | CONFIG_TIMERFD=y | ||
113 | CONFIG_EVENTFD=y | ||
114 | CONFIG_SHMEM=y | ||
115 | CONFIG_AIO=y | ||
116 | # CONFIG_EMBEDDED is not set | ||
117 | CONFIG_HAVE_PERF_EVENTS=y | ||
118 | CONFIG_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 | ||
125 | CONFIG_VM_EVENT_COUNTERS=y | ||
126 | CONFIG_COMPAT_BRK=y | ||
127 | CONFIG_SLAB=y | ||
128 | # CONFIG_SLUB is not set | ||
129 | CONFIG_PROFILING=y | ||
130 | CONFIG_OPROFILE=y | ||
131 | CONFIG_HAVE_OPROFILE=y | ||
132 | # CONFIG_KPROBES is not set | ||
133 | CONFIG_HAVE_KPROBES=y | ||
134 | CONFIG_HAVE_KRETPROBES=y | ||
135 | CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y | ||
136 | CONFIG_HAVE_CLK=y | ||
137 | CONFIG_HAVE_DMA_API_DEBUG=y | ||
138 | |||
139 | # | ||
140 | # GCOV-based kernel profiling | ||
141 | # | ||
142 | # CONFIG_GCOV_KERNEL is not set | ||
143 | CONFIG_HAVE_GENERIC_DMA_COHERENT=y | ||
144 | CONFIG_SLABINFO=y | ||
145 | CONFIG_RT_MUTEXES=y | ||
146 | CONFIG_BASE_SMALL=0 | ||
147 | CONFIG_MODULES=y | ||
148 | CONFIG_MODULE_FORCE_LOAD=y | ||
149 | CONFIG_MODULE_UNLOAD=y | ||
150 | CONFIG_MODULE_FORCE_UNLOAD=y | ||
151 | CONFIG_MODVERSIONS=y | ||
152 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
153 | CONFIG_BLOCK=y | ||
154 | CONFIG_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 | # | ||
162 | CONFIG_IOSCHED_NOOP=y | ||
163 | CONFIG_IOSCHED_DEADLINE=y | ||
164 | CONFIG_IOSCHED_CFQ=y | ||
165 | # CONFIG_DEFAULT_DEADLINE is not set | ||
166 | CONFIG_DEFAULT_CFQ=y | ||
167 | # CONFIG_DEFAULT_NOOP is not set | ||
168 | CONFIG_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 | ||
175 | CONFIG_INLINE_SPIN_UNLOCK=y | ||
176 | # CONFIG_INLINE_SPIN_UNLOCK_BH is not set | ||
177 | CONFIG_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 | ||
184 | CONFIG_INLINE_READ_UNLOCK=y | ||
185 | # CONFIG_INLINE_READ_UNLOCK_BH is not set | ||
186 | CONFIG_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 | ||
193 | CONFIG_INLINE_WRITE_UNLOCK=y | ||
194 | # CONFIG_INLINE_WRITE_UNLOCK_BH is not set | ||
195 | CONFIG_INLINE_WRITE_UNLOCK_IRQ=y | ||
196 | # CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set | ||
197 | # CONFIG_MUTEX_SPIN_ON_OWNER is not set | ||
198 | CONFIG_FREEZER=y | ||
199 | |||
200 | # | ||
201 | # System Type | ||
202 | # | ||
203 | CONFIG_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 | ||
256 | CONFIG_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 | ||
267 | CONFIG_ARCH_OMAP2PLUS=y | ||
268 | |||
269 | # | ||
270 | # OMAP Feature Selections | ||
271 | # | ||
272 | CONFIG_AM33XX_SMARTREFLEX=y | ||
273 | # CONFIG_OMAP_SMARTREFLEX is not set | ||
274 | CONFIG_OMAP_RESET_CLOCKS=y | ||
275 | CONFIG_OMAP_MUX=y | ||
276 | CONFIG_OMAP_MUX_DEBUG=y | ||
277 | CONFIG_OMAP_MUX_WARNINGS=y | ||
278 | # CONFIG_OMAP_MCBSP is not set | ||
279 | CONFIG_OMAP_MBOX_FWK=y | ||
280 | CONFIG_OMAP_MBOX_KFIFO_SIZE=256 | ||
281 | # CONFIG_OMAP_32K_TIMER is not set | ||
282 | # CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE is not set | ||
283 | CONFIG_OMAP_DM_TIMER=y | ||
284 | CONFIG_OMAP_PM_NOOP=y | ||
285 | CONFIG_MACH_OMAP_GENERIC=y | ||
286 | |||
287 | # | ||
288 | # TI OMAP2/3/4 Specific Features | ||
289 | # | ||
290 | CONFIG_ARCH_OMAP2PLUS_TYPICAL=y | ||
291 | # CONFIG_ARCH_OMAP2 is not set | ||
292 | CONFIG_ARCH_OMAP3=y | ||
293 | # CONFIG_ARCH_OMAP4 is not set | ||
294 | # CONFIG_SOC_OMAP3430 is not set | ||
295 | CONFIG_SOC_OMAPTI81XX=y | ||
296 | CONFIG_SOC_OMAPAM33XX=y | ||
297 | CONFIG_OMAP_PACKAGE_CBB=y | ||
298 | |||
299 | # | ||
300 | # OMAP Board Type | ||
301 | # | ||
302 | CONFIG_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 | ||
325 | CONFIG_MACH_TI8168EVM=y | ||
326 | CONFIG_MACH_TI8148EVM=y | ||
327 | CONFIG_MACH_AM335XEVM=y | ||
328 | CONFIG_MACH_AM335XIAEVM=y | ||
329 | # CONFIG_OMAP3_EMU is not set | ||
330 | CONFIG_TI_PM_DISABLE_VT_SWITCH=y | ||
331 | # CONFIG_OMAP3_SDRC_AC_TIMING is not set | ||
332 | CONFIG_OMAP3_EDMA=y | ||
333 | |||
334 | # | ||
335 | # System MMU | ||
336 | # | ||
337 | |||
338 | # | ||
339 | # Processor Type | ||
340 | # | ||
341 | CONFIG_CPU_V7=y | ||
342 | CONFIG_CPU_32v6K=y | ||
343 | CONFIG_CPU_32v7=y | ||
344 | CONFIG_CPU_ABRT_EV7=y | ||
345 | CONFIG_CPU_PABRT_V7=y | ||
346 | CONFIG_CPU_CACHE_V7=y | ||
347 | CONFIG_CPU_CACHE_VIPT=y | ||
348 | CONFIG_CPU_COPY_V6=y | ||
349 | CONFIG_CPU_TLB_V7=y | ||
350 | CONFIG_CPU_HAS_ASID=y | ||
351 | CONFIG_CPU_CP15=y | ||
352 | CONFIG_CPU_CP15_MMU=y | ||
353 | |||
354 | # | ||
355 | # Processor Features | ||
356 | # | ||
357 | CONFIG_ARM_THUMB=y | ||
358 | CONFIG_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 | ||
363 | CONFIG_ARM_L1_CACHE_SHIFT_6=y | ||
364 | CONFIG_ARM_L1_CACHE_SHIFT=6 | ||
365 | CONFIG_ARM_DMA_MEM_BUFFERABLE=y | ||
366 | CONFIG_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 | # | ||
385 | CONFIG_TICK_ONESHOT=y | ||
386 | CONFIG_NO_HZ=y | ||
387 | CONFIG_HIGH_RES_TIMERS=y | ||
388 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | ||
389 | CONFIG_VMSPLIT_3G=y | ||
390 | # CONFIG_VMSPLIT_2G is not set | ||
391 | # CONFIG_VMSPLIT_1G is not set | ||
392 | CONFIG_PAGE_OFFSET=0xC0000000 | ||
393 | CONFIG_PREEMPT_NONE=y | ||
394 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
395 | # CONFIG_PREEMPT is not set | ||
396 | CONFIG_HZ=100 | ||
397 | # CONFIG_THUMB2_KERNEL is not set | ||
398 | CONFIG_AEABI=y | ||
399 | CONFIG_OABI_COMPAT=y | ||
400 | CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y | ||
401 | # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set | ||
402 | # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set | ||
403 | CONFIG_HAVE_ARCH_PFN_VALID=y | ||
404 | # CONFIG_HIGHMEM is not set | ||
405 | CONFIG_SELECT_MEMORY_MODEL=y | ||
406 | CONFIG_FLATMEM_MANUAL=y | ||
407 | CONFIG_FLATMEM=y | ||
408 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
409 | CONFIG_HAVE_MEMBLOCK=y | ||
410 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
411 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
412 | # CONFIG_COMPACTION is not set | ||
413 | # CONFIG_PHYS_ADDR_T_64BIT is not set | ||
414 | CONFIG_ZONE_DMA_FLAG=0 | ||
415 | CONFIG_VIRT_TO_BUS=y | ||
416 | # CONFIG_KSM is not set | ||
417 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
418 | CONFIG_NEED_PER_CPU_KM=y | ||
419 | # CONFIG_CLEANCACHE is not set | ||
420 | CONFIG_FORCE_MAX_ZONEORDER=11 | ||
421 | # CONFIG_LEDS is not set | ||
422 | CONFIG_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 | # | ||
431 | CONFIG_USE_OF=y | ||
432 | CONFIG_ZBOOT_ROM_TEXT=0x0 | ||
433 | CONFIG_ZBOOT_ROM_BSS=0x0 | ||
434 | # CONFIG_ARM_APPENDED_DTB is not set | ||
435 | CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO0,115200" | ||
436 | CONFIG_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 | # | ||
451 | CONFIG_CPU_FREQ=y | ||
452 | CONFIG_CPU_FREQ_TABLE=y | ||
453 | CONFIG_CPU_FREQ_STAT=y | ||
454 | CONFIG_CPU_FREQ_STAT_DETAILS=y | ||
455 | # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set | ||
456 | CONFIG_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 | ||
459 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y | ||
460 | CONFIG_CPU_FREQ_GOV_POWERSAVE=y | ||
461 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | ||
462 | CONFIG_CPU_FREQ_GOV_ONDEMAND=y | ||
463 | CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y | ||
464 | |||
465 | # | ||
466 | # ARM CPU frequency scaling drivers | ||
467 | # | ||
468 | CONFIG_CPU_IDLE=y | ||
469 | CONFIG_CPU_IDLE_GOV_LADDER=y | ||
470 | CONFIG_CPU_IDLE_GOV_MENU=y | ||
471 | |||
472 | # | ||
473 | # Floating point emulation | ||
474 | # | ||
475 | |||
476 | # | ||
477 | # At least one emulation must be selected | ||
478 | # | ||
479 | CONFIG_FPE_NWFPE=y | ||
480 | # CONFIG_FPE_NWFPE_XP is not set | ||
481 | # CONFIG_FPE_FASTFPE is not set | ||
482 | CONFIG_VFP=y | ||
483 | CONFIG_VFPv3=y | ||
484 | CONFIG_NEON=y | ||
485 | |||
486 | # | ||
487 | # Userspace binary formats | ||
488 | # | ||
489 | CONFIG_BINFMT_ELF=y | ||
490 | CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y | ||
491 | CONFIG_HAVE_AOUT=y | ||
492 | # CONFIG_BINFMT_AOUT is not set | ||
493 | CONFIG_BINFMT_MISC=y | ||
494 | |||
495 | # | ||
496 | # Power management options | ||
497 | # | ||
498 | CONFIG_SUSPEND=y | ||
499 | CONFIG_SUSPEND_FREEZER=y | ||
500 | CONFIG_PM_SLEEP=y | ||
501 | CONFIG_PM_RUNTIME=y | ||
502 | CONFIG_PM=y | ||
503 | CONFIG_PM_DEBUG=y | ||
504 | CONFIG_PM_ADVANCED_DEBUG=y | ||
505 | # CONFIG_PM_TEST_SUSPEND is not set | ||
506 | CONFIG_CAN_PM_TRACE=y | ||
507 | # CONFIG_APM_EMULATION is not set | ||
508 | CONFIG_ARCH_HAS_OPP=y | ||
509 | CONFIG_PM_OPP=y | ||
510 | CONFIG_PM_CLK=y | ||
511 | CONFIG_CPU_PM=y | ||
512 | CONFIG_ARCH_SUSPEND_POSSIBLE=y | ||
513 | CONFIG_ARM_CPU_SUSPEND=y | ||
514 | CONFIG_NET=y | ||
515 | |||
516 | # | ||
517 | # Networking options | ||
518 | # | ||
519 | CONFIG_PACKET=y | ||
520 | CONFIG_UNIX=y | ||
521 | # CONFIG_NET_KEY is not set | ||
522 | CONFIG_INET=y | ||
523 | CONFIG_IP_MULTICAST=y | ||
524 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
525 | CONFIG_IP_PNP=y | ||
526 | CONFIG_IP_PNP_DHCP=y | ||
527 | CONFIG_IP_PNP_BOOTP=y | ||
528 | CONFIG_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 | ||
545 | CONFIG_TCP_CONG_CUBIC=y | ||
546 | CONFIG_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 | ||
552 | CONFIG_NETFILTER=y | ||
553 | # CONFIG_NETFILTER_DEBUG is not set | ||
554 | CONFIG_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 | ||
561 | CONFIG_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 | ||
579 | CONFIG_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 | # | ||
643 | CONFIG_NF_DEFRAG_IPV4=y | ||
644 | CONFIG_NF_CONNTRACK_IPV4=y | ||
645 | CONFIG_NF_CONNTRACK_PROC_COMPAT=y | ||
646 | # CONFIG_IP_NF_QUEUE is not set | ||
647 | CONFIG_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 | ||
651 | CONFIG_IP_NF_FILTER=y | ||
652 | # CONFIG_IP_NF_TARGET_REJECT is not set | ||
653 | CONFIG_IP_NF_TARGET_LOG=y | ||
654 | # CONFIG_IP_NF_TARGET_ULOG is not set | ||
655 | CONFIG_NF_NAT=y | ||
656 | CONFIG_NF_NAT_NEEDED=y | ||
657 | CONFIG_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 | ||
692 | CONFIG_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 | ||
700 | CONFIG_CAN=y | ||
701 | CONFIG_CAN_RAW=y | ||
702 | CONFIG_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 | ||
710 | CONFIG_CAN_DEV=y | ||
711 | CONFIG_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 | ||
716 | CONFIG_CAN_D_CAN=y | ||
717 | CONFIG_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 | ||
729 | CONFIG_WIRELESS=y | ||
730 | CONFIG_WIRELESS_EXT=y | ||
731 | CONFIG_WEXT_CORE=y | ||
732 | CONFIG_WEXT_PROC=y | ||
733 | CONFIG_WEXT_PRIV=y | ||
734 | # CONFIG_CFG80211 is not set | ||
735 | CONFIG_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 | ||
742 | CONFIG_RFKILL=y | ||
743 | CONFIG_RFKILL_LEDS=y | ||
744 | CONFIG_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 | # | ||
759 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
760 | # CONFIG_DEVTMPFS is not set | ||
761 | CONFIG_STANDALONE=y | ||
762 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
763 | CONFIG_FW_LOADER=y | ||
764 | CONFIG_FIRMWARE_IN_KERNEL=y | ||
765 | CONFIG_EXTRA_FIRMWARE="am335x-pm-firmware.bin" | ||
766 | CONFIG_EXTRA_FIRMWARE_DIR="firmware" | ||
767 | # CONFIG_SYS_HYPERVISOR is not set | ||
768 | CONFIG_REGMAP=y | ||
769 | CONFIG_REGMAP_I2C=y | ||
770 | CONFIG_REGMAP_SPI=y | ||
771 | |||
772 | # | ||
773 | # CBUS support | ||
774 | # | ||
775 | # CONFIG_CBUS is not set | ||
776 | # CONFIG_CONNECTOR is not set | ||
777 | CONFIG_MTD=y | ||
778 | # CONFIG_MTD_TESTS is not set | ||
779 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
780 | CONFIG_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 | # | ||
788 | CONFIG_MTD_CHAR=y | ||
789 | CONFIG_MTD_BLKDEVS=y | ||
790 | CONFIG_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 | ||
797 | CONFIG_MTD_OOPS=y | ||
798 | # CONFIG_MTD_SWAP is not set | ||
799 | |||
800 | # | ||
801 | # RAM/ROM/Flash chip drivers | ||
802 | # | ||
803 | CONFIG_MTD_CFI=y | ||
804 | # CONFIG_MTD_JEDECPROBE is not set | ||
805 | CONFIG_MTD_GEN_PROBE=y | ||
806 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
807 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
808 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
809 | CONFIG_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 | ||
813 | CONFIG_MTD_CFI_I1=y | ||
814 | CONFIG_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 | ||
820 | CONFIG_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 | ||
837 | CONFIG_MTD_M25P80=y | ||
838 | CONFIG_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 | ||
852 | CONFIG_MTD_NAND_ECC=y | ||
853 | # CONFIG_MTD_NAND_ECC_SMC is not set | ||
854 | CONFIG_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 | ||
860 | CONFIG_MTD_NAND_OMAP2=y | ||
861 | CONFIG_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 | ||
866 | CONFIG_MTD_ONENAND=y | ||
867 | # CONFIG_MTD_ONENAND_VERIFY_WRITE is not set | ||
868 | # CONFIG_MTD_ONENAND_GENERIC is not set | ||
869 | CONFIG_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 | ||
878 | CONFIG_MTD_UBI=y | ||
879 | CONFIG_MTD_UBI_WL_THRESHOLD=4096 | ||
880 | CONFIG_MTD_UBI_BEB_RESERVE=1 | ||
881 | # CONFIG_MTD_UBI_GLUEBI is not set | ||
882 | # CONFIG_MTD_UBI_DEBUG is not set | ||
883 | CONFIG_DTC=y | ||
884 | CONFIG_OF=y | ||
885 | |||
886 | # | ||
887 | # Device Tree and Open Firmware support | ||
888 | # | ||
889 | CONFIG_PROC_DEVICETREE=y | ||
890 | CONFIG_OF_FLATTREE=y | ||
891 | CONFIG_OF_EARLY_FLATTREE=y | ||
892 | CONFIG_OF_ADDRESS=y | ||
893 | CONFIG_OF_IRQ=y | ||
894 | CONFIG_OF_DEVICE=y | ||
895 | CONFIG_OF_GPIO=y | ||
896 | CONFIG_OF_I2C=y | ||
897 | CONFIG_OF_NET=y | ||
898 | CONFIG_OF_SPI=y | ||
899 | CONFIG_OF_MDIO=y | ||
900 | # CONFIG_PARPORT is not set | ||
901 | CONFIG_BLK_DEV=y | ||
902 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
903 | CONFIG_BLK_DEV_LOOP=y | ||
904 | CONFIG_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 | ||
912 | CONFIG_BLK_DEV_RAM=y | ||
913 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
914 | CONFIG_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 | ||
920 | CONFIG_SENSORS_LIS3LV02D=y | ||
921 | CONFIG_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 | ||
929 | CONFIG_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 | # | ||
943 | CONFIG_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 | ||
956 | CONFIG_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 | # | ||
966 | CONFIG_SCSI_MOD=y | ||
967 | # CONFIG_RAID_ATTRS is not set | ||
968 | CONFIG_SCSI=y | ||
969 | CONFIG_SCSI_DMA=y | ||
970 | # CONFIG_SCSI_TGT is not set | ||
971 | # CONFIG_SCSI_NETLINK is not set | ||
972 | CONFIG_SCSI_PROC_FS=y | ||
973 | |||
974 | # | ||
975 | # SCSI support type (disk, tape, CD-ROM) | ||
976 | # | ||
977 | CONFIG_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 | ||
983 | CONFIG_SCSI_MULTI_LUN=y | ||
984 | # CONFIG_SCSI_CONSTANTS is not set | ||
985 | # CONFIG_SCSI_LOGGING is not set | ||
986 | CONFIG_SCSI_SCAN_ASYNC=y | ||
987 | CONFIG_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 | ||
998 | CONFIG_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 | ||
1009 | CONFIG_NETDEVICES=y | ||
1010 | CONFIG_NET_CORE=y | ||
1011 | # CONFIG_BONDING is not set | ||
1012 | # CONFIG_DUMMY is not set | ||
1013 | # CONFIG_EQUALIZER is not set | ||
1014 | CONFIG_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 | # | ||
1025 | CONFIG_ETHERNET=y | ||
1026 | CONFIG_NET_VENDOR_BROADCOM=y | ||
1027 | # CONFIG_B44 is not set | ||
1028 | CONFIG_NET_VENDOR_CHELSIO=y | ||
1029 | # CONFIG_DM9000 is not set | ||
1030 | # CONFIG_DNET is not set | ||
1031 | CONFIG_NET_VENDOR_FARADAY=y | ||
1032 | # CONFIG_FTMAC100 is not set | ||
1033 | # CONFIG_FTGMAC100 is not set | ||
1034 | CONFIG_NET_VENDOR_INTEL=y | ||
1035 | CONFIG_NET_VENDOR_I825XX=y | ||
1036 | CONFIG_NET_VENDOR_MARVELL=y | ||
1037 | CONFIG_NET_VENDOR_MICREL=y | ||
1038 | # CONFIG_KS8851 is not set | ||
1039 | # CONFIG_KS8851_MLL is not set | ||
1040 | CONFIG_NET_VENDOR_MICROCHIP=y | ||
1041 | # CONFIG_ENC28J60 is not set | ||
1042 | CONFIG_NET_VENDOR_NATSEMI=y | ||
1043 | CONFIG_NET_VENDOR_8390=y | ||
1044 | # CONFIG_AX88796 is not set | ||
1045 | # CONFIG_ETHOC is not set | ||
1046 | CONFIG_NET_VENDOR_SEEQ=y | ||
1047 | # CONFIG_SEEQ8005 is not set | ||
1048 | CONFIG_NET_VENDOR_SMSC=y | ||
1049 | CONFIG_SMC91X=y | ||
1050 | # CONFIG_SMC911X is not set | ||
1051 | CONFIG_SMSC911X=y | ||
1052 | # CONFIG_SMSC911X_ARCH_HOOKS is not set | ||
1053 | CONFIG_NET_VENDOR_STMICRO=y | ||
1054 | # CONFIG_STMMAC_ETH is not set | ||
1055 | CONFIG_NET_VENDOR_TI=y | ||
1056 | # CONFIG_TI_DAVINCI_EMAC is not set | ||
1057 | CONFIG_TI_DAVINCI_MDIO=y | ||
1058 | CONFIG_TI_DAVINCI_CPDMA=y | ||
1059 | CONFIG_TI_CPSW=y | ||
1060 | CONFIG_TI_CPSW_DUAL_EMAC=y | ||
1061 | CONFIG_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 | ||
1072 | CONFIG_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 | ||
1092 | CONFIG_USB_USBNET=y | ||
1093 | # CONFIG_USB_NET_AX8817X is not set | ||
1094 | CONFIG_USB_NET_CDCETHER=y | ||
1095 | CONFIG_USB_NET_CDC_EEM=y | ||
1096 | CONFIG_USB_NET_CDC_NCM=y | ||
1097 | CONFIG_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 | ||
1114 | CONFIG_WLAN=y | ||
1115 | CONFIG_USB_ZD1201=y | ||
1116 | # CONFIG_HOSTAP is not set | ||
1117 | CONFIG_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 | # | ||
1129 | CONFIG_INPUT=y | ||
1130 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
1131 | CONFIG_INPUT_POLLDEV=y | ||
1132 | # CONFIG_INPUT_SPARSEKMAP is not set | ||
1133 | |||
1134 | # | ||
1135 | # Userland interfaces | ||
1136 | # | ||
1137 | CONFIG_INPUT_MOUSEDEV=y | ||
1138 | CONFIG_INPUT_MOUSEDEV_PSAUX=y | ||
1139 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
1140 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
1141 | # CONFIG_INPUT_JOYDEV is not set | ||
1142 | CONFIG_INPUT_EVDEV=y | ||
1143 | # CONFIG_INPUT_EVBUG is not set | ||
1144 | |||
1145 | # | ||
1146 | # Input Device Drivers | ||
1147 | # | ||
1148 | CONFIG_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 | ||
1155 | CONFIG_KEYBOARD_GPIO=y | ||
1156 | # CONFIG_KEYBOARD_TCA6416 is not set | ||
1157 | CONFIG_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 | ||
1168 | CONFIG_INPUT_MOUSE=y | ||
1169 | CONFIG_MOUSE_PS2=y | ||
1170 | CONFIG_MOUSE_PS2_ALPS=y | ||
1171 | CONFIG_MOUSE_PS2_LOGIPS2PP=y | ||
1172 | CONFIG_MOUSE_PS2_SYNAPTICS=y | ||
1173 | CONFIG_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 | ||
1185 | CONFIG_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 | ||
1207 | CONFIG_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 | ||
1216 | CONFIG_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 | # | ||
1240 | CONFIG_SERIO=y | ||
1241 | # CONFIG_SERIO_SERPORT is not set | ||
1242 | CONFIG_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 | # | ||
1251 | CONFIG_VT=y | ||
1252 | CONFIG_CONSOLE_TRANSLATIONS=y | ||
1253 | CONFIG_VT_CONSOLE=y | ||
1254 | CONFIG_VT_CONSOLE_SLEEP=y | ||
1255 | CONFIG_HW_CONSOLE=y | ||
1256 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
1257 | CONFIG_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 | ||
1263 | CONFIG_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 | ||
1275 | CONFIG_SERIAL_CORE=y | ||
1276 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
1277 | CONFIG_SERIAL_OMAP=y | ||
1278 | CONFIG_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 | ||
1291 | CONFIG_I2C=y | ||
1292 | CONFIG_I2C_BOARDINFO=y | ||
1293 | CONFIG_I2C_COMPAT=y | ||
1294 | CONFIG_I2C_CHARDEV=y | ||
1295 | # CONFIG_I2C_MUX is not set | ||
1296 | CONFIG_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 | ||
1308 | CONFIG_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 | ||
1329 | CONFIG_SPI=y | ||
1330 | CONFIG_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 | ||
1339 | CONFIG_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 | # | ||
1366 | CONFIG_ARCH_REQUIRE_GPIOLIB=y | ||
1367 | CONFIG_GPIOLIB=y | ||
1368 | CONFIG_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 | # | ||
1405 | CONFIG_GPIO_TPS65910=y | ||
1406 | CONFIG_GENERIC_PWM=y | ||
1407 | CONFIG_DAVINCI_EHRPWM=y | ||
1408 | CONFIG_ECAP_PWM=y | ||
1409 | # CONFIG_W1 is not set | ||
1410 | # CONFIG_POWER_SUPPLY is not set | ||
1411 | CONFIG_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 | ||
1449 | CONFIG_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 | ||
1509 | CONFIG_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 | ||
1518 | CONFIG_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 | ||
1526 | CONFIG_SSB_POSSIBLE=y | ||
1527 | |||
1528 | # | ||
1529 | # Sonics Silicon Backplane | ||
1530 | # | ||
1531 | # CONFIG_SSB is not set | ||
1532 | CONFIG_BCMA_POSSIBLE=y | ||
1533 | |||
1534 | # | ||
1535 | # Broadcom specific AMBA | ||
1536 | # | ||
1537 | # CONFIG_BCMA is not set | ||
1538 | |||
1539 | # | ||
1540 | # Multifunction device drivers | ||
1541 | # | ||
1542 | CONFIG_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 | ||
1552 | CONFIG_MFD_TPS65217=y | ||
1553 | # CONFIG_MFD_TPS6586X is not set | ||
1554 | CONFIG_MFD_TPS65910=y | ||
1555 | # CONFIG_MFD_TPS65912_I2C is not set | ||
1556 | # CONFIG_MFD_TPS65912_SPI is not set | ||
1557 | CONFIG_TWL4030_CORE=y | ||
1558 | # CONFIG_TWL4030_MADC is not set | ||
1559 | CONFIG_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 | ||
1585 | CONFIG_REGULATOR=y | ||
1586 | # CONFIG_REGULATOR_DEBUG is not set | ||
1587 | CONFIG_REGULATOR_DUMMY=y | ||
1588 | CONFIG_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 | ||
1602 | CONFIG_REGULATOR_TPS65217=y | ||
1603 | # CONFIG_REGULATOR_ISL6271A is not set | ||
1604 | # CONFIG_REGULATOR_AD5398 is not set | ||
1605 | # CONFIG_REGULATOR_TPS6524X is not set | ||
1606 | CONFIG_REGULATOR_TPS65910=y | ||
1607 | CONFIG_MEDIA_SUPPORT=y | ||
1608 | |||
1609 | # | ||
1610 | # Multimedia core support | ||
1611 | # | ||
1612 | # CONFIG_MEDIA_CONTROLLER is not set | ||
1613 | CONFIG_VIDEO_DEV=y | ||
1614 | CONFIG_VIDEO_V4L2_COMMON=y | ||
1615 | # CONFIG_DVB_CORE is not set | ||
1616 | CONFIG_VIDEO_MEDIA=y | ||
1617 | |||
1618 | # | ||
1619 | # Multimedia drivers | ||
1620 | # | ||
1621 | # CONFIG_RC_CORE is not set | ||
1622 | # CONFIG_MEDIA_ATTACH is not set | ||
1623 | CONFIG_MEDIA_TUNER=y | ||
1624 | # CONFIG_MEDIA_TUNER_CUSTOMISE is not set | ||
1625 | CONFIG_MEDIA_TUNER_SIMPLE=y | ||
1626 | CONFIG_MEDIA_TUNER_TDA8290=y | ||
1627 | CONFIG_MEDIA_TUNER_TDA827X=y | ||
1628 | CONFIG_MEDIA_TUNER_TDA18271=y | ||
1629 | CONFIG_MEDIA_TUNER_TDA9887=y | ||
1630 | CONFIG_MEDIA_TUNER_TEA5761=y | ||
1631 | CONFIG_MEDIA_TUNER_TEA5767=y | ||
1632 | CONFIG_MEDIA_TUNER_MT20XX=y | ||
1633 | CONFIG_MEDIA_TUNER_XC2028=y | ||
1634 | CONFIG_MEDIA_TUNER_XC5000=y | ||
1635 | CONFIG_MEDIA_TUNER_XC4000=y | ||
1636 | CONFIG_MEDIA_TUNER_MC44S803=y | ||
1637 | CONFIG_VIDEO_V4L2=y | ||
1638 | CONFIG_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 | ||
1733 | CONFIG_V4L_USB_DRIVERS=y | ||
1734 | CONFIG_USB_VIDEO_CLASS=y | ||
1735 | CONFIG_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 | ||
1756 | CONFIG_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 | ||
1760 | CONFIG_FB_CFB_FILLRECT=y | ||
1761 | CONFIG_FB_CFB_COPYAREA=y | ||
1762 | CONFIG_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 | ||
1783 | CONFIG_FB_DA8XX=y | ||
1784 | CONFIG_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 | ||
1790 | CONFIG_BACKLIGHT_LCD_SUPPORT=y | ||
1791 | CONFIG_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 | ||
1801 | CONFIG_BACKLIGHT_CLASS_DEVICE=y | ||
1802 | # CONFIG_BACKLIGHT_GENERIC is not set | ||
1803 | CONFIG_BACKLIGHT_PWM=y | ||
1804 | # CONFIG_BACKLIGHT_ADP8860 is not set | ||
1805 | # CONFIG_BACKLIGHT_ADP8870 is not set | ||
1806 | CONFIG_BACKLIGHT_TLC59108=y | ||
1807 | |||
1808 | # | ||
1809 | # Display device support | ||
1810 | # | ||
1811 | CONFIG_DISPLAY_SUPPORT=y | ||
1812 | |||
1813 | # | ||
1814 | # Display hardware drivers | ||
1815 | # | ||
1816 | |||
1817 | # | ||
1818 | # Console display driver support | ||
1819 | # | ||
1820 | CONFIG_DUMMY_CONSOLE=y | ||
1821 | CONFIG_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 | ||
1825 | CONFIG_FONT_8x8=y | ||
1826 | CONFIG_FONT_8x16=y | ||
1827 | CONFIG_LOGO=y | ||
1828 | CONFIG_LOGO_LINUX_MONO=y | ||
1829 | CONFIG_LOGO_LINUX_VGA16=y | ||
1830 | CONFIG_LOGO_LINUX_CLUT224=y | ||
1831 | CONFIG_SOUND=y | ||
1832 | # CONFIG_SOUND_OSS_CORE is not set | ||
1833 | CONFIG_SND=y | ||
1834 | CONFIG_SND_TIMER=y | ||
1835 | CONFIG_SND_PCM=y | ||
1836 | CONFIG_SND_HWDEP=y | ||
1837 | CONFIG_SND_RAWMIDI=y | ||
1838 | CONFIG_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 | ||
1844 | CONFIG_SND_SUPPORT_OLD_API=y | ||
1845 | CONFIG_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 | ||
1853 | CONFIG_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 | ||
1859 | CONFIG_SND_ARM=y | ||
1860 | CONFIG_SND_SPI=y | ||
1861 | CONFIG_SND_USB=y | ||
1862 | CONFIG_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 | ||
1866 | CONFIG_SND_SOC=y | ||
1867 | # CONFIG_SND_SOC_CACHE_LZO is not set | ||
1868 | CONFIG_SND_AM33XX_SOC=y | ||
1869 | CONFIG_SND_DAVINCI_SOC_MCASP=y | ||
1870 | CONFIG_SND_AM335X_SOC_EVM=y | ||
1871 | # CONFIG_SND_OMAP_SOC is not set | ||
1872 | CONFIG_SND_SOC_I2C_AND_SPI=y | ||
1873 | # CONFIG_SND_SOC_ALL_CODECS is not set | ||
1874 | CONFIG_SND_SOC_TLV320AIC3X=y | ||
1875 | # CONFIG_SOUND_PRIME is not set | ||
1876 | CONFIG_HID_SUPPORT=y | ||
1877 | CONFIG_HID=y | ||
1878 | # CONFIG_HIDRAW is not set | ||
1879 | |||
1880 | # | ||
1881 | # USB Input Devices | ||
1882 | # | ||
1883 | CONFIG_USB_HID=y | ||
1884 | # CONFIG_HID_PID is not set | ||
1885 | # CONFIG_USB_HIDDEV is not set | ||
1886 | |||
1887 | # | ||
1888 | # Special HID drivers | ||
1889 | # | ||
1890 | CONFIG_HID_A4TECH=y | ||
1891 | # CONFIG_HID_ACRUX is not set | ||
1892 | CONFIG_HID_APPLE=y | ||
1893 | CONFIG_HID_BELKIN=y | ||
1894 | CONFIG_HID_CHERRY=y | ||
1895 | CONFIG_HID_CHICONY=y | ||
1896 | # CONFIG_HID_PRODIKEYS is not set | ||
1897 | CONFIG_HID_CYPRESS=y | ||
1898 | # CONFIG_HID_DRAGONRISE is not set | ||
1899 | # CONFIG_HID_EMS_FF is not set | ||
1900 | CONFIG_HID_EZKEY=y | ||
1901 | # CONFIG_HID_HOLTEK is not set | ||
1902 | # CONFIG_HID_KEYTOUCH is not set | ||
1903 | CONFIG_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 | ||
1908 | CONFIG_HID_KENSINGTON=y | ||
1909 | # CONFIG_HID_LCPOWER is not set | ||
1910 | CONFIG_HID_LOGITECH=y | ||
1911 | CONFIG_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 | ||
1916 | CONFIG_HID_MICROSOFT=y | ||
1917 | CONFIG_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 | ||
1937 | CONFIG_USB_SUPPORT=y | ||
1938 | CONFIG_USB_COMMON=y | ||
1939 | CONFIG_USB_ARCH_HAS_HCD=y | ||
1940 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
1941 | CONFIG_USB_ARCH_HAS_EHCI=y | ||
1942 | # CONFIG_USB_ARCH_HAS_XHCI is not set | ||
1943 | CONFIG_USB=y | ||
1944 | # CONFIG_USB_DEBUG is not set | ||
1945 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y | ||
1946 | |||
1947 | # | ||
1948 | # Miscellaneous USB options | ||
1949 | # | ||
1950 | CONFIG_USB_DEVICEFS=y | ||
1951 | CONFIG_USB_DEVICE_CLASS=y | ||
1952 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
1953 | CONFIG_USB_SUSPEND=y | ||
1954 | CONFIG_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 | ||
1975 | CONFIG_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 | ||
1983 | CONFIG_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 | ||
1989 | CONFIG_USB_MUSB_TI81XX=y | ||
1990 | # CONFIG_USB_MUSB_BLACKFIN is not set | ||
1991 | # CONFIG_USB_MUSB_UX500 is not set | ||
1992 | CONFIG_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 | # | ||
2015 | CONFIG_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 | ||
2067 | CONFIG_USB_GADGET=y | ||
2068 | # CONFIG_USB_GADGET_DEBUG_FILES is not set | ||
2069 | # CONFIG_USB_GADGET_DEBUG_FS is not set | ||
2070 | CONFIG_USB_GADGET_VBUS_DRAW=2 | ||
2071 | CONFIG_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 | ||
2075 | CONFIG_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 | ||
2079 | CONFIG_USB_GADGET_DUALSPEED=y | ||
2080 | # CONFIG_USB_ZERO is not set | ||
2081 | # CONFIG_USB_AUDIO is not set | ||
2082 | CONFIG_USB_ETH=m | ||
2083 | CONFIG_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 | ||
2088 | CONFIG_USB_FILE_STORAGE=m | ||
2089 | # CONFIG_USB_FILE_STORAGE_TEST is not set | ||
2090 | CONFIG_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 | # | ||
2104 | CONFIG_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 | ||
2108 | CONFIG_NOP_USB_XCEIV=y | ||
2109 | CONFIG_MMC=y | ||
2110 | # CONFIG_MMC_DEBUG is not set | ||
2111 | CONFIG_MMC_UNSAFE_RESUME=y | ||
2112 | # CONFIG_MMC_CLKGATE is not set | ||
2113 | |||
2114 | # | ||
2115 | # MMC/SD/SDIO Card Drivers | ||
2116 | # | ||
2117 | CONFIG_MMC_BLOCK=y | ||
2118 | CONFIG_MMC_BLOCK_MINORS=8 | ||
2119 | CONFIG_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 | ||
2130 | CONFIG_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 | ||
2136 | CONFIG_NEW_LEDS=y | ||
2137 | CONFIG_LEDS_CLASS=y | ||
2138 | |||
2139 | # | ||
2140 | # LED drivers | ||
2141 | # | ||
2142 | # CONFIG_LEDS_LM3530 is not set | ||
2143 | # CONFIG_LEDS_PCA9532 is not set | ||
2144 | CONFIG_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 | ||
2155 | CONFIG_LEDS_TRIGGERS=y | ||
2156 | |||
2157 | # | ||
2158 | # LED Triggers | ||
2159 | # | ||
2160 | CONFIG_LEDS_TRIGGER_TIMER=y | ||
2161 | CONFIG_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 | ||
2170 | CONFIG_RTC_LIB=y | ||
2171 | CONFIG_RTC_CLASS=y | ||
2172 | CONFIG_RTC_HCTOSYS=y | ||
2173 | CONFIG_RTC_HCTOSYS_DEVICE="rtc0" | ||
2174 | # CONFIG_RTC_DEBUG is not set | ||
2175 | |||
2176 | # | ||
2177 | # RTC interfaces | ||
2178 | # | ||
2179 | CONFIG_RTC_INTF_SYSFS=y | ||
2180 | CONFIG_RTC_INTF_PROC=y | ||
2181 | CONFIG_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 | # | ||
2242 | CONFIG_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 | ||
2253 | CONFIG_CLKDEV_LOOKUP=y | ||
2254 | |||
2255 | # | ||
2256 | # Hardware Spinlock drivers | ||
2257 | # | ||
2258 | CONFIG_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 | # | ||
2266 | CONFIG_EXT2_FS=y | ||
2267 | # CONFIG_EXT2_FS_XATTR is not set | ||
2268 | # CONFIG_EXT2_FS_XIP is not set | ||
2269 | CONFIG_EXT3_FS=y | ||
2270 | CONFIG_EXT3_DEFAULTS_TO_ORDERED=y | ||
2271 | # CONFIG_EXT3_FS_XATTR is not set | ||
2272 | # CONFIG_EXT4_FS is not set | ||
2273 | CONFIG_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 | ||
2281 | CONFIG_FS_POSIX_ACL=y | ||
2282 | CONFIG_FILE_LOCKING=y | ||
2283 | CONFIG_FSNOTIFY=y | ||
2284 | CONFIG_DNOTIFY=y | ||
2285 | CONFIG_INOTIFY_USER=y | ||
2286 | # CONFIG_FANOTIFY is not set | ||
2287 | CONFIG_QUOTA=y | ||
2288 | # CONFIG_QUOTA_NETLINK_INTERFACE is not set | ||
2289 | CONFIG_PRINT_QUOTA_WARNING=y | ||
2290 | # CONFIG_QUOTA_DEBUG is not set | ||
2291 | CONFIG_QUOTA_TREE=y | ||
2292 | # CONFIG_QFMT_V1 is not set | ||
2293 | CONFIG_QFMT_V2=y | ||
2294 | CONFIG_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 | # | ||
2312 | CONFIG_FAT_FS=y | ||
2313 | CONFIG_MSDOS_FS=y | ||
2314 | CONFIG_VFAT_FS=y | ||
2315 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
2316 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
2317 | # CONFIG_NTFS_FS is not set | ||
2318 | |||
2319 | # | ||
2320 | # Pseudo filesystems | ||
2321 | # | ||
2322 | CONFIG_PROC_FS=y | ||
2323 | CONFIG_PROC_SYSCTL=y | ||
2324 | CONFIG_PROC_PAGE_MONITOR=y | ||
2325 | CONFIG_SYSFS=y | ||
2326 | CONFIG_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 | ||
2331 | CONFIG_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 | ||
2341 | CONFIG_UBIFS_FS=y | ||
2342 | # CONFIG_UBIFS_FS_XATTR is not set | ||
2343 | # CONFIG_UBIFS_FS_ADVANCED_COMPR is not set | ||
2344 | CONFIG_UBIFS_FS_LZO=y | ||
2345 | CONFIG_UBIFS_FS_ZLIB=y | ||
2346 | # CONFIG_UBIFS_FS_DEBUG is not set | ||
2347 | # CONFIG_LOGFS is not set | ||
2348 | CONFIG_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 | ||
2359 | CONFIG_NETWORK_FILESYSTEMS=y | ||
2360 | CONFIG_NFS_FS=y | ||
2361 | CONFIG_NFS_V3=y | ||
2362 | CONFIG_NFS_V3_ACL=y | ||
2363 | CONFIG_NFS_V4=y | ||
2364 | # CONFIG_NFS_V4_1 is not set | ||
2365 | CONFIG_ROOT_NFS=y | ||
2366 | # CONFIG_NFS_USE_LEGACY_DNS is not set | ||
2367 | CONFIG_NFS_USE_KERNEL_DNS=y | ||
2368 | # CONFIG_NFS_USE_NEW_IDMAPPER is not set | ||
2369 | # CONFIG_NFSD is not set | ||
2370 | CONFIG_LOCKD=y | ||
2371 | CONFIG_LOCKD_V4=y | ||
2372 | CONFIG_NFS_ACL_SUPPORT=y | ||
2373 | CONFIG_NFS_COMMON=y | ||
2374 | CONFIG_SUNRPC=y | ||
2375 | CONFIG_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 | # | ||
2385 | CONFIG_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 | ||
2391 | CONFIG_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 | ||
2403 | CONFIG_NLS=y | ||
2404 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
2405 | CONFIG_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 | ||
2429 | CONFIG_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 | # | ||
2447 | CONFIG_PRINTK_TIME=y | ||
2448 | CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 | ||
2449 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
2450 | CONFIG_ENABLE_MUST_CHECK=y | ||
2451 | CONFIG_FRAME_WARN=1024 | ||
2452 | CONFIG_MAGIC_SYSRQ=y | ||
2453 | # CONFIG_STRIP_ASM_SYMS is not set | ||
2454 | # CONFIG_UNUSED_SYMBOLS is not set | ||
2455 | CONFIG_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 | ||
2461 | CONFIG_DEBUG_BUGVERBOSE=y | ||
2462 | CONFIG_DEBUG_MEMORY_INIT=y | ||
2463 | CONFIG_FRAME_POINTER=y | ||
2464 | # CONFIG_LKDTM is not set | ||
2465 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set | ||
2466 | CONFIG_HAVE_FUNCTION_TRACER=y | ||
2467 | CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y | ||
2468 | CONFIG_HAVE_DYNAMIC_FTRACE=y | ||
2469 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y | ||
2470 | CONFIG_HAVE_C_RECORDMCOUNT=y | ||
2471 | CONFIG_RING_BUFFER=y | ||
2472 | CONFIG_RING_BUFFER_ALLOW_SWAP=y | ||
2473 | CONFIG_TRACING_SUPPORT=y | ||
2474 | # CONFIG_FTRACE is not set | ||
2475 | CONFIG_DYNAMIC_DEBUG=y | ||
2476 | # CONFIG_DMA_API_DEBUG is not set | ||
2477 | # CONFIG_ATOMIC64_SELFTEST is not set | ||
2478 | # CONFIG_SAMPLES is not set | ||
2479 | CONFIG_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 | ||
2484 | CONFIG_DEBUG_JTAG_ENABLE=y | ||
2485 | |||
2486 | # | ||
2487 | # Security options | ||
2488 | # | ||
2489 | CONFIG_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 | ||
2493 | CONFIG_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 | ||
2501 | CONFIG_DEFAULT_SECURITY_DAC=y | ||
2502 | CONFIG_DEFAULT_SECURITY="" | ||
2503 | CONFIG_CRYPTO=y | ||
2504 | |||
2505 | # | ||
2506 | # Crypto core or helper | ||
2507 | # | ||
2508 | CONFIG_CRYPTO_ALGAPI=y | ||
2509 | CONFIG_CRYPTO_ALGAPI2=y | ||
2510 | CONFIG_CRYPTO_AEAD=y | ||
2511 | CONFIG_CRYPTO_AEAD2=y | ||
2512 | CONFIG_CRYPTO_BLKCIPHER=y | ||
2513 | CONFIG_CRYPTO_BLKCIPHER2=y | ||
2514 | CONFIG_CRYPTO_HASH=y | ||
2515 | CONFIG_CRYPTO_HASH2=y | ||
2516 | CONFIG_CRYPTO_RNG=y | ||
2517 | CONFIG_CRYPTO_RNG2=y | ||
2518 | CONFIG_CRYPTO_PCOMP2=y | ||
2519 | CONFIG_CRYPTO_MANAGER=y | ||
2520 | CONFIG_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 | ||
2525 | CONFIG_CRYPTO_WORKQUEUE=y | ||
2526 | # CONFIG_CRYPTO_CRYPTD is not set | ||
2527 | # CONFIG_CRYPTO_AUTHENC is not set | ||
2528 | CONFIG_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 | ||
2535 | CONFIG_CRYPTO_SEQIV=y | ||
2536 | |||
2537 | # | ||
2538 | # Block modes | ||
2539 | # | ||
2540 | CONFIG_CRYPTO_CBC=y | ||
2541 | CONFIG_CRYPTO_CTR=y | ||
2542 | # CONFIG_CRYPTO_CTS is not set | ||
2543 | CONFIG_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 | # | ||
2551 | CONFIG_CRYPTO_HMAC=y | ||
2552 | # CONFIG_CRYPTO_XCBC is not set | ||
2553 | # CONFIG_CRYPTO_VMAC is not set | ||
2554 | |||
2555 | # | ||
2556 | # Digest | ||
2557 | # | ||
2558 | CONFIG_CRYPTO_CRC32C=y | ||
2559 | # CONFIG_CRYPTO_GHASH is not set | ||
2560 | # CONFIG_CRYPTO_MD4 is not set | ||
2561 | CONFIG_CRYPTO_MD5=y | ||
2562 | CONFIG_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 | ||
2567 | CONFIG_CRYPTO_SHA1=y | ||
2568 | CONFIG_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 | # | ||
2576 | CONFIG_CRYPTO_AES=y | ||
2577 | # CONFIG_CRYPTO_ANUBIS is not set | ||
2578 | CONFIG_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 | ||
2583 | CONFIG_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 | # | ||
2595 | CONFIG_CRYPTO_DEFLATE=y | ||
2596 | # CONFIG_CRYPTO_ZLIB is not set | ||
2597 | CONFIG_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 | ||
2605 | CONFIG_CRYPTO_HW=y | ||
2606 | CONFIG_CRYPTO_DEV_OMAP4_AES=y | ||
2607 | CONFIG_CRYPTO_DEV_OMAP4_SHAM=y | ||
2608 | |||
2609 | # | ||
2610 | # OCF Configuration | ||
2611 | # | ||
2612 | CONFIG_OCF_OCF=y | ||
2613 | # CONFIG_OCF_RANDOMHARVEST is not set | ||
2614 | CONFIG_OCF_CRYPTODEV=y | ||
2615 | CONFIG_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 | # | ||
2623 | CONFIG_BITREVERSE=y | ||
2624 | CONFIG_CRC_CCITT=y | ||
2625 | CONFIG_CRC16=y | ||
2626 | CONFIG_CRC_T10DIF=y | ||
2627 | CONFIG_CRC_ITU_T=y | ||
2628 | CONFIG_CRC32=y | ||
2629 | CONFIG_CRC7=y | ||
2630 | CONFIG_LIBCRC32C=y | ||
2631 | # CONFIG_CRC8 is not set | ||
2632 | CONFIG_ZLIB_INFLATE=y | ||
2633 | CONFIG_ZLIB_DEFLATE=y | ||
2634 | CONFIG_LZO_COMPRESS=y | ||
2635 | CONFIG_LZO_DECOMPRESS=y | ||
2636 | CONFIG_XZ_DEC=y | ||
2637 | CONFIG_XZ_DEC_X86=y | ||
2638 | CONFIG_XZ_DEC_POWERPC=y | ||
2639 | CONFIG_XZ_DEC_IA64=y | ||
2640 | CONFIG_XZ_DEC_ARM=y | ||
2641 | CONFIG_XZ_DEC_ARMTHUMB=y | ||
2642 | CONFIG_XZ_DEC_SPARC=y | ||
2643 | CONFIG_XZ_DEC_BCJ=y | ||
2644 | # CONFIG_XZ_DEC_TEST is not set | ||
2645 | CONFIG_DECOMPRESS_GZIP=y | ||
2646 | CONFIG_DECOMPRESS_BZIP2=y | ||
2647 | CONFIG_DECOMPRESS_LZMA=y | ||
2648 | CONFIG_DECOMPRESS_XZ=y | ||
2649 | CONFIG_DECOMPRESS_LZO=y | ||
2650 | CONFIG_GENERIC_ALLOCATOR=y | ||
2651 | CONFIG_HAS_IOMEM=y | ||
2652 | CONFIG_HAS_IOPORT=y | ||
2653 | CONFIG_HAS_DMA=y | ||
2654 | CONFIG_NLATTR=y | ||
2655 | CONFIG_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 @@ | |||
1 | SECTION = "kernel" | ||
2 | DESCRIPTION = "Linux kernel for TI33x devices from PSP" | ||
3 | LICENSE = "GPLv2" | ||
4 | LIC_FILES_CHKSUM = "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7" | ||
5 | COMPATIBLE_MACHINE = "ti33x" | ||
6 | |||
7 | DEFAULT_PREFERENCE = "-1" | ||
8 | |||
9 | inherit kernel | ||
10 | |||
11 | # Stage the power management firmware before building the kernel | ||
12 | DEPENDS += "am33x-cm3" | ||
13 | |||
14 | KERNEL_IMAGETYPE = "uImage" | ||
15 | |||
16 | # The main PR is now using MACHINE_KERNEL_PR, for ti33x see conf/machine/include/ti33x.inc | ||
17 | MACHINE_KERNEL_PR_append = "a+gitr${SRCREV}" | ||
18 | |||
19 | BRANCH = "v3.2-staging" | ||
20 | |||
21 | # This SRCREV corresponds to tag v3.2_AM335xPSP_04.06.00.08 | ||
22 | SRCREV = "d7e124e8074cccf9958290e773c88a4b2b36412b" | ||
23 | |||
24 | SRC_URI = "git://arago-project.org/git/projects/linux-am33x.git;protocol=git;branch=${BRANCH} \ | ||
25 | file://defconfig \ | ||
26 | ${KERNEL_PATCHES} \ | ||
27 | " | ||
28 | |||
29 | S = "${WORKDIR}/git" | ||
30 | |||
31 | # Allow a layer to easily add to the list of patches or completely override them. | ||
32 | KERNEL_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 | ||
36 | PATCHES = "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. | ||
42 | PATCHES += "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. | ||
58 | PATCHES += "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 | ||
64 | PATCHES += "file://0001-omap-serial-add-delay-before-suspending.patch" | ||
65 | |||
66 | # Add patch to allow wireless to work properly on EVM-SK 1.2. | ||
67 | PATCHES += "file://0001-am3358-sk-modified-WLAN-enable-and-irq-to-match-boar.patch" | ||
68 | |||
69 | # Add CPU utilization patch for WLAN | ||
70 | PATCHES += "file://0001-am335xevm-using-edge-triggered-interrupts-for-WLAN.patch" | ||
71 | |||
72 | # Add patch to enable pullup on WLAN enable | ||
73 | PATCHES += "file://0001-am335x-enable-pullup-on-the-WLAN-enable-pin-fo.patch" | ||
74 | |||
75 | # Copy the am33x-cm3 firmware if it is available | ||
76 | do_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 | } | ||