1b886d83cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
26ec4e251SArd Biesheuvel /*
36ec4e251SArd Biesheuvel * Copyright (C) 2012 Intel Corporation
46ec4e251SArd Biesheuvel * Copyright (C) 2017 Linaro Ltd. <ard.biesheuvel@linaro.org>
56ec4e251SArd Biesheuvel */
66ec4e251SArd Biesheuvel
76ec4e251SArd Biesheuvel #include <linux/raid/pq.h>
86ec4e251SArd Biesheuvel
96ec4e251SArd Biesheuvel #ifdef __KERNEL__
106ec4e251SArd Biesheuvel #include <asm/neon.h>
11*3de13550SArnd Bergmann #include "neon.h"
126ec4e251SArd Biesheuvel #else
136ec4e251SArd Biesheuvel #define kernel_neon_begin()
146ec4e251SArd Biesheuvel #define kernel_neon_end()
156ec4e251SArd Biesheuvel #define cpu_has_neon() (1)
166ec4e251SArd Biesheuvel #endif
176ec4e251SArd Biesheuvel
raid6_has_neon(void)186ec4e251SArd Biesheuvel static int raid6_has_neon(void)
196ec4e251SArd Biesheuvel {
206ec4e251SArd Biesheuvel return cpu_has_neon();
216ec4e251SArd Biesheuvel }
226ec4e251SArd Biesheuvel
raid6_2data_recov_neon(int disks,size_t bytes,int faila,int failb,void ** ptrs)236ec4e251SArd Biesheuvel static void raid6_2data_recov_neon(int disks, size_t bytes, int faila,
246ec4e251SArd Biesheuvel int failb, void **ptrs)
256ec4e251SArd Biesheuvel {
266ec4e251SArd Biesheuvel u8 *p, *q, *dp, *dq;
276ec4e251SArd Biesheuvel const u8 *pbmul; /* P multiplier table for B data */
286ec4e251SArd Biesheuvel const u8 *qmul; /* Q multiplier table (for both) */
296ec4e251SArd Biesheuvel
306ec4e251SArd Biesheuvel p = (u8 *)ptrs[disks - 2];
316ec4e251SArd Biesheuvel q = (u8 *)ptrs[disks - 1];
326ec4e251SArd Biesheuvel
336ec4e251SArd Biesheuvel /*
346ec4e251SArd Biesheuvel * Compute syndrome with zero for the missing data pages
356ec4e251SArd Biesheuvel * Use the dead data pages as temporary storage for
366ec4e251SArd Biesheuvel * delta p and delta q
376ec4e251SArd Biesheuvel */
386ec4e251SArd Biesheuvel dp = (u8 *)ptrs[faila];
396ec4e251SArd Biesheuvel ptrs[faila] = (void *)raid6_empty_zero_page;
406ec4e251SArd Biesheuvel ptrs[disks - 2] = dp;
416ec4e251SArd Biesheuvel dq = (u8 *)ptrs[failb];
426ec4e251SArd Biesheuvel ptrs[failb] = (void *)raid6_empty_zero_page;
436ec4e251SArd Biesheuvel ptrs[disks - 1] = dq;
446ec4e251SArd Biesheuvel
456ec4e251SArd Biesheuvel raid6_call.gen_syndrome(disks, bytes, ptrs);
466ec4e251SArd Biesheuvel
476ec4e251SArd Biesheuvel /* Restore pointer table */
486ec4e251SArd Biesheuvel ptrs[faila] = dp;
496ec4e251SArd Biesheuvel ptrs[failb] = dq;
506ec4e251SArd Biesheuvel ptrs[disks - 2] = p;
516ec4e251SArd Biesheuvel ptrs[disks - 1] = q;
526ec4e251SArd Biesheuvel
536ec4e251SArd Biesheuvel /* Now, pick the proper data tables */
546ec4e251SArd Biesheuvel pbmul = raid6_vgfmul[raid6_gfexi[failb-faila]];
556ec4e251SArd Biesheuvel qmul = raid6_vgfmul[raid6_gfinv[raid6_gfexp[faila] ^
566ec4e251SArd Biesheuvel raid6_gfexp[failb]]];
576ec4e251SArd Biesheuvel
586ec4e251SArd Biesheuvel kernel_neon_begin();
596ec4e251SArd Biesheuvel __raid6_2data_recov_neon(bytes, p, q, dp, dq, pbmul, qmul);
606ec4e251SArd Biesheuvel kernel_neon_end();
616ec4e251SArd Biesheuvel }
626ec4e251SArd Biesheuvel
raid6_datap_recov_neon(int disks,size_t bytes,int faila,void ** ptrs)636ec4e251SArd Biesheuvel static void raid6_datap_recov_neon(int disks, size_t bytes, int faila,
646ec4e251SArd Biesheuvel void **ptrs)
656ec4e251SArd Biesheuvel {
666ec4e251SArd Biesheuvel u8 *p, *q, *dq;
676ec4e251SArd Biesheuvel const u8 *qmul; /* Q multiplier table */
686ec4e251SArd Biesheuvel
696ec4e251SArd Biesheuvel p = (u8 *)ptrs[disks - 2];
706ec4e251SArd Biesheuvel q = (u8 *)ptrs[disks - 1];
716ec4e251SArd Biesheuvel
726ec4e251SArd Biesheuvel /*
736ec4e251SArd Biesheuvel * Compute syndrome with zero for the missing data page
746ec4e251SArd Biesheuvel * Use the dead data page as temporary storage for delta q
756ec4e251SArd Biesheuvel */
766ec4e251SArd Biesheuvel dq = (u8 *)ptrs[faila];
776ec4e251SArd Biesheuvel ptrs[faila] = (void *)raid6_empty_zero_page;
786ec4e251SArd Biesheuvel ptrs[disks - 1] = dq;
796ec4e251SArd Biesheuvel
806ec4e251SArd Biesheuvel raid6_call.gen_syndrome(disks, bytes, ptrs);
816ec4e251SArd Biesheuvel
826ec4e251SArd Biesheuvel /* Restore pointer table */
836ec4e251SArd Biesheuvel ptrs[faila] = dq;
846ec4e251SArd Biesheuvel ptrs[disks - 1] = q;
856ec4e251SArd Biesheuvel
866ec4e251SArd Biesheuvel /* Now, pick the proper data tables */
876ec4e251SArd Biesheuvel qmul = raid6_vgfmul[raid6_gfinv[raid6_gfexp[faila]]];
886ec4e251SArd Biesheuvel
896ec4e251SArd Biesheuvel kernel_neon_begin();
906ec4e251SArd Biesheuvel __raid6_datap_recov_neon(bytes, p, q, dq, qmul);
916ec4e251SArd Biesheuvel kernel_neon_end();
926ec4e251SArd Biesheuvel }
936ec4e251SArd Biesheuvel
946ec4e251SArd Biesheuvel const struct raid6_recov_calls raid6_recov_neon = {
956ec4e251SArd Biesheuvel .data2 = raid6_2data_recov_neon,
966ec4e251SArd Biesheuvel .datap = raid6_datap_recov_neon,
976ec4e251SArd Biesheuvel .valid = raid6_has_neon,
986ec4e251SArd Biesheuvel .name = "neon",
996ec4e251SArd Biesheuvel .priority = 10,
1006ec4e251SArd Biesheuvel };
101