28
28
29
29
/* Registers values */
30
30
#define CRC_CR_RESET BIT(0)
31
- #define CRC_CR_REVERSE (BIT(7) | BIT(6) | BIT(5))
32
31
#define CRC_INIT_DEFAULT 0xFFFFFFFF
32
+ #define CRC_CR_REV_IN_WORD (BIT(6) | BIT(5))
33
+ #define CRC_CR_REV_IN_BYTE BIT(5)
34
+ #define CRC_CR_REV_OUT BIT(7)
33
35
34
36
#define CRC_AUTOSUSPEND_DELAY 50
35
37
@@ -38,8 +40,6 @@ struct stm32_crc {
38
40
struct device * dev ;
39
41
void __iomem * regs ;
40
42
struct clk * clk ;
41
- u8 pending_data [sizeof (u32 )];
42
- size_t nb_pending_bytes ;
43
43
};
44
44
45
45
struct stm32_crc_list {
@@ -59,7 +59,6 @@ struct stm32_crc_ctx {
59
59
60
60
struct stm32_crc_desc_ctx {
61
61
u32 partial ; /* crc32c: partial in first 4 bytes of that struct */
62
- struct stm32_crc * crc ;
63
62
};
64
63
65
64
static int stm32_crc32_cra_init (struct crypto_tfm * tfm )
@@ -99,25 +98,22 @@ static int stm32_crc_init(struct shash_desc *desc)
99
98
struct stm32_crc * crc ;
100
99
101
100
spin_lock_bh (& crc_list .lock );
102
- list_for_each_entry (crc , & crc_list .dev_list , list ) {
103
- ctx -> crc = crc ;
104
- break ;
105
- }
101
+ crc = list_first_entry (& crc_list .dev_list , struct stm32_crc , list );
106
102
spin_unlock_bh (& crc_list .lock );
107
103
108
- pm_runtime_get_sync (ctx -> crc -> dev );
104
+ pm_runtime_get_sync (crc -> dev );
109
105
110
106
/* Reset, set key, poly and configure in bit reverse mode */
111
- writel_relaxed (bitrev32 (mctx -> key ), ctx -> crc -> regs + CRC_INIT );
112
- writel_relaxed (bitrev32 (mctx -> poly ), ctx -> crc -> regs + CRC_POL );
113
- writel_relaxed (CRC_CR_RESET | CRC_CR_REVERSE , ctx -> crc -> regs + CRC_CR );
107
+ writel_relaxed (bitrev32 (mctx -> key ), crc -> regs + CRC_INIT );
108
+ writel_relaxed (bitrev32 (mctx -> poly ), crc -> regs + CRC_POL );
109
+ writel_relaxed (CRC_CR_RESET | CRC_CR_REV_IN_WORD | CRC_CR_REV_OUT ,
110
+ crc -> regs + CRC_CR );
114
111
115
112
/* Store partial result */
116
- ctx -> partial = readl_relaxed (ctx -> crc -> regs + CRC_DR );
117
- ctx -> crc -> nb_pending_bytes = 0 ;
113
+ ctx -> partial = readl_relaxed (crc -> regs + CRC_DR );
118
114
119
- pm_runtime_mark_last_busy (ctx -> crc -> dev );
120
- pm_runtime_put_autosuspend (ctx -> crc -> dev );
115
+ pm_runtime_mark_last_busy (crc -> dev );
116
+ pm_runtime_put_autosuspend (crc -> dev );
121
117
122
118
return 0 ;
123
119
}
@@ -126,54 +122,56 @@ static int stm32_crc_update(struct shash_desc *desc, const u8 *d8,
126
122
unsigned int length )
127
123
{
128
124
struct stm32_crc_desc_ctx * ctx = shash_desc_ctx (desc );
129
- struct stm32_crc * crc = ctx -> crc ;
130
- u32 * d32 ;
131
- unsigned int i ;
125
+ struct stm32_crc_ctx * mctx = crypto_shash_ctx (desc -> tfm );
126
+ struct stm32_crc * crc ;
127
+
128
+ spin_lock_bh (& crc_list .lock );
129
+ crc = list_first_entry (& crc_list .dev_list , struct stm32_crc , list );
130
+ spin_unlock_bh (& crc_list .lock );
132
131
133
132
pm_runtime_get_sync (crc -> dev );
134
133
135
- if (unlikely (crc -> nb_pending_bytes )) {
136
- while (crc -> nb_pending_bytes != sizeof (u32 ) && length ) {
137
- /* Fill in pending data */
138
- crc -> pending_data [crc -> nb_pending_bytes ++ ] = * (d8 ++ );
134
+ /*
135
+ * Restore previously calculated CRC for this context as init value
136
+ * Restore polynomial configuration
137
+ * Configure in register for word input data,
138
+ * Configure out register in reversed bit mode data.
139
+ */
140
+ writel_relaxed (bitrev32 (ctx -> partial ), crc -> regs + CRC_INIT );
141
+ writel_relaxed (bitrev32 (mctx -> poly ), crc -> regs + CRC_POL );
142
+ writel_relaxed (CRC_CR_RESET | CRC_CR_REV_IN_WORD | CRC_CR_REV_OUT ,
143
+ crc -> regs + CRC_CR );
144
+
145
+ if (d8 != PTR_ALIGN (d8 , sizeof (u32 ))) {
146
+ /* Configure for byte data */
147
+ writel_relaxed (CRC_CR_REV_IN_BYTE | CRC_CR_REV_OUT ,
148
+ crc -> regs + CRC_CR );
149
+ while (d8 != PTR_ALIGN (d8 , sizeof (u32 )) && length ) {
150
+ writeb_relaxed (* d8 ++ , crc -> regs + CRC_DR );
139
151
length -- ;
140
152
}
141
-
142
- if (crc -> nb_pending_bytes == sizeof (u32 )) {
143
- /* Process completed pending data */
144
- writel_relaxed (* (u32 * )crc -> pending_data ,
145
- crc -> regs + CRC_DR );
146
- crc -> nb_pending_bytes = 0 ;
147
- }
153
+ /* Configure for word data */
154
+ writel_relaxed (CRC_CR_REV_IN_WORD | CRC_CR_REV_OUT ,
155
+ crc -> regs + CRC_CR );
148
156
}
149
157
150
- d32 = (u32 * )d8 ;
151
- for (i = 0 ; i < length >> 2 ; i ++ )
152
- /* Process 32 bits data */
153
- writel_relaxed (* (d32 ++ ), crc -> regs + CRC_DR );
158
+ for (; length >= sizeof (u32 ); d8 += sizeof (u32 ), length -= sizeof (u32 ))
159
+ writel_relaxed (* ((u32 * )d8 ), crc -> regs + CRC_DR );
160
+
161
+ if (length ) {
162
+ /* Configure for byte data */
163
+ writel_relaxed (CRC_CR_REV_IN_BYTE | CRC_CR_REV_OUT ,
164
+ crc -> regs + CRC_CR );
165
+ while (length -- )
166
+ writeb_relaxed (* d8 ++ , crc -> regs + CRC_DR );
167
+ }
154
168
155
169
/* Store partial result */
156
170
ctx -> partial = readl_relaxed (crc -> regs + CRC_DR );
157
171
158
172
pm_runtime_mark_last_busy (crc -> dev );
159
173
pm_runtime_put_autosuspend (crc -> dev );
160
174
161
- /* Check for pending data (non 32 bits) */
162
- length &= 3 ;
163
- if (likely (!length ))
164
- return 0 ;
165
-
166
- if ((crc -> nb_pending_bytes + length ) >= sizeof (u32 )) {
167
- /* Shall not happen */
168
- dev_err (crc -> dev , "Pending data overflow\n" );
169
- return - EINVAL ;
170
- }
171
-
172
- d8 = (const u8 * )d32 ;
173
- for (i = 0 ; i < length ; i ++ )
174
- /* Store pending data */
175
- crc -> pending_data [crc -> nb_pending_bytes ++ ] = * (d8 ++ );
176
-
177
175
return 0 ;
178
176
}
179
177
0 commit comments