err = skcipher_walk_virt(&walk, req, false);
 
-       crypto_chacha_init(state, ctx, iv);
+       chacha_init_generic(state, ctx->key, iv);
 
        while (walk.nbytes > 0) {
                unsigned int nbytes = walk.nbytes;
                if (nbytes < walk.total)
                        nbytes = rounddown(nbytes, walk.stride);
 
-               kernel_neon_begin();
-               chacha_doneon(state, walk.dst.virt.addr, walk.src.virt.addr,
-                             nbytes, ctx->nrounds);
-               kernel_neon_end();
+               if (!crypto_simd_usable()) {
+                       chacha_crypt_generic(state, walk.dst.virt.addr,
+                                            walk.src.virt.addr, nbytes,
+                                            ctx->nrounds);
+               } else {
+                       kernel_neon_begin();
+                       chacha_doneon(state, walk.dst.virt.addr,
+                                     walk.src.virt.addr, nbytes, ctx->nrounds);
+                       kernel_neon_end();
+               }
                err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
        }
 
        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
        struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm);
 
-       if (req->cryptlen <= CHACHA_BLOCK_SIZE || !crypto_simd_usable())
-               return crypto_chacha_crypt(req);
-
        return chacha_neon_stream_xor(req, ctx, req->iv);
 }
 
        u32 state[16];
        u8 real_iv[16];
 
-       if (req->cryptlen <= CHACHA_BLOCK_SIZE || !crypto_simd_usable())
-               return crypto_xchacha_crypt(req);
+       chacha_init_generic(state, ctx->key, req->iv);
 
-       crypto_chacha_init(state, ctx, req->iv);
-
-       kernel_neon_begin();
-       hchacha_block_neon(state, subctx.key, ctx->nrounds);
-       kernel_neon_end();
+       if (crypto_simd_usable()) {
+               kernel_neon_begin();
+               hchacha_block_neon(state, subctx.key, ctx->nrounds);
+               kernel_neon_end();
+       } else {
+               hchacha_block_generic(state, subctx.key, ctx->nrounds);
+       }
        subctx.nrounds = ctx->nrounds;
 
        memcpy(&real_iv[0], req->iv + 24, 8);
                .ivsize                 = CHACHA_IV_SIZE,
                .chunksize              = CHACHA_BLOCK_SIZE,
                .walksize               = 5 * CHACHA_BLOCK_SIZE,
-               .setkey                 = crypto_chacha20_setkey,
+               .setkey                 = chacha20_setkey,
                .encrypt                = chacha_neon,
                .decrypt                = chacha_neon,
        }, {
                .ivsize                 = XCHACHA_IV_SIZE,
                .chunksize              = CHACHA_BLOCK_SIZE,
                .walksize               = 5 * CHACHA_BLOCK_SIZE,
-               .setkey                 = crypto_chacha20_setkey,
+               .setkey                 = chacha20_setkey,
                .encrypt                = xchacha_neon,
                .decrypt                = xchacha_neon,
        }, {
                .ivsize                 = XCHACHA_IV_SIZE,
                .chunksize              = CHACHA_BLOCK_SIZE,
                .walksize               = 5 * CHACHA_BLOCK_SIZE,
-               .setkey                 = crypto_chacha12_setkey,
+               .setkey                 = chacha12_setkey,
                .encrypt                = xchacha_neon,
                .decrypt                = xchacha_neon,
        }