in bcm-sba-raid.c [1086:1312]
static void sba_fillup_pq_single_msg(struct sba_request *req,
bool pq_continue,
struct brcm_sba_command *cmds,
struct brcm_message *msg,
dma_addr_t msg_offset, size_t msg_len,
dma_addr_t *dst_p, dma_addr_t *dst_q,
dma_addr_t src, u8 scf)
{
u64 cmd;
u32 c_mdata;
u8 pos, dpos = raid6_gflog[scf];
dma_addr_t resp_dma = req->tx.phys;
struct brcm_sba_command *cmdsp = cmds;
if (!dst_p)
goto skip_p;
if (pq_continue) {
/* Type-B command to load old P into buf0 */
cmd = sba_cmd_enc(0x0, SBA_TYPE_B,
SBA_TYPE_SHIFT, SBA_TYPE_MASK);
cmd = sba_cmd_enc(cmd, msg_len,
SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK);
c_mdata = sba_cmd_load_c_mdata(0);
cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata),
SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK);
cmd = sba_cmd_enc(cmd, SBA_CMD_LOAD_BUFFER,
SBA_CMD_SHIFT, SBA_CMD_MASK);
cmdsp->cmd = cmd;
*cmdsp->cmd_dma = cpu_to_le64(cmd);
cmdsp->flags = BRCM_SBA_CMD_TYPE_B;
cmdsp->data = *dst_p + msg_offset;
cmdsp->data_len = msg_len;
cmdsp++;
/*
* Type-B commands to xor data with buf0 and put it
* back in buf0
*/
cmd = sba_cmd_enc(0x0, SBA_TYPE_B,
SBA_TYPE_SHIFT, SBA_TYPE_MASK);
cmd = sba_cmd_enc(cmd, msg_len,
SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK);
c_mdata = sba_cmd_xor_c_mdata(0, 0);
cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata),
SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK);
cmd = sba_cmd_enc(cmd, SBA_CMD_XOR,
SBA_CMD_SHIFT, SBA_CMD_MASK);
cmdsp->cmd = cmd;
*cmdsp->cmd_dma = cpu_to_le64(cmd);
cmdsp->flags = BRCM_SBA_CMD_TYPE_B;
cmdsp->data = src + msg_offset;
cmdsp->data_len = msg_len;
cmdsp++;
} else {
/* Type-B command to load old P into buf0 */
cmd = sba_cmd_enc(0x0, SBA_TYPE_B,
SBA_TYPE_SHIFT, SBA_TYPE_MASK);
cmd = sba_cmd_enc(cmd, msg_len,
SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK);
c_mdata = sba_cmd_load_c_mdata(0);
cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata),
SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK);
cmd = sba_cmd_enc(cmd, SBA_CMD_LOAD_BUFFER,
SBA_CMD_SHIFT, SBA_CMD_MASK);
cmdsp->cmd = cmd;
*cmdsp->cmd_dma = cpu_to_le64(cmd);
cmdsp->flags = BRCM_SBA_CMD_TYPE_B;
cmdsp->data = src + msg_offset;
cmdsp->data_len = msg_len;
cmdsp++;
}
/* Type-A command to write buf0 */
cmd = sba_cmd_enc(0x0, SBA_TYPE_A,
SBA_TYPE_SHIFT, SBA_TYPE_MASK);
cmd = sba_cmd_enc(cmd, msg_len,
SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK);
cmd = sba_cmd_enc(cmd, 0x1,
SBA_RESP_SHIFT, SBA_RESP_MASK);
c_mdata = sba_cmd_write_c_mdata(0);
cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata),
SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK);
cmd = sba_cmd_enc(cmd, SBA_CMD_WRITE_BUFFER,
SBA_CMD_SHIFT, SBA_CMD_MASK);
cmdsp->cmd = cmd;
*cmdsp->cmd_dma = cpu_to_le64(cmd);
cmdsp->flags = BRCM_SBA_CMD_TYPE_A;
if (req->sba->hw_resp_size) {
cmdsp->flags |= BRCM_SBA_CMD_HAS_RESP;
cmdsp->resp = resp_dma;
cmdsp->resp_len = req->sba->hw_resp_size;
}
cmdsp->flags |= BRCM_SBA_CMD_HAS_OUTPUT;
cmdsp->data = *dst_p + msg_offset;
cmdsp->data_len = msg_len;
cmdsp++;
skip_p:
if (!dst_q)
goto skip_q;
/* Type-A command to zero all buffers */
cmd = sba_cmd_enc(0x0, SBA_TYPE_A,
SBA_TYPE_SHIFT, SBA_TYPE_MASK);
cmd = sba_cmd_enc(cmd, msg_len,
SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK);
cmd = sba_cmd_enc(cmd, SBA_CMD_ZERO_ALL_BUFFERS,
SBA_CMD_SHIFT, SBA_CMD_MASK);
cmdsp->cmd = cmd;
*cmdsp->cmd_dma = cpu_to_le64(cmd);
cmdsp->flags = BRCM_SBA_CMD_TYPE_A;
cmdsp++;
if (dpos == 255)
goto skip_q_computation;
pos = (dpos < req->sba->max_pq_coefs) ?
dpos : (req->sba->max_pq_coefs - 1);
/*
* Type-B command to generate initial Q from data
* and store output into buf0
*/
cmd = sba_cmd_enc(0x0, SBA_TYPE_B,
SBA_TYPE_SHIFT, SBA_TYPE_MASK);
cmd = sba_cmd_enc(cmd, msg_len,
SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK);
c_mdata = sba_cmd_pq_c_mdata(pos, 0, 0);
cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata),
SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK);
cmd = sba_cmd_enc(cmd, SBA_C_MDATA_MS(c_mdata),
SBA_C_MDATA_MS_SHIFT, SBA_C_MDATA_MS_MASK);
cmd = sba_cmd_enc(cmd, SBA_CMD_GALOIS,
SBA_CMD_SHIFT, SBA_CMD_MASK);
cmdsp->cmd = cmd;
*cmdsp->cmd_dma = cpu_to_le64(cmd);
cmdsp->flags = BRCM_SBA_CMD_TYPE_B;
cmdsp->data = src + msg_offset;
cmdsp->data_len = msg_len;
cmdsp++;
dpos -= pos;
/* Multiple Type-A command to generate final Q */
while (dpos) {
pos = (dpos < req->sba->max_pq_coefs) ?
dpos : (req->sba->max_pq_coefs - 1);
/*
* Type-A command to generate Q with buf0 and
* buf1 store result in buf0
*/
cmd = sba_cmd_enc(0x0, SBA_TYPE_A,
SBA_TYPE_SHIFT, SBA_TYPE_MASK);
cmd = sba_cmd_enc(cmd, msg_len,
SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK);
c_mdata = sba_cmd_pq_c_mdata(pos, 0, 1);
cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata),
SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK);
cmd = sba_cmd_enc(cmd, SBA_C_MDATA_MS(c_mdata),
SBA_C_MDATA_MS_SHIFT, SBA_C_MDATA_MS_MASK);
cmd = sba_cmd_enc(cmd, SBA_CMD_GALOIS,
SBA_CMD_SHIFT, SBA_CMD_MASK);
cmdsp->cmd = cmd;
*cmdsp->cmd_dma = cpu_to_le64(cmd);
cmdsp->flags = BRCM_SBA_CMD_TYPE_A;
cmdsp++;
dpos -= pos;
}
skip_q_computation:
if (pq_continue) {
/*
* Type-B command to XOR previous output with
* buf0 and write it into buf0
*/
cmd = sba_cmd_enc(0x0, SBA_TYPE_B,
SBA_TYPE_SHIFT, SBA_TYPE_MASK);
cmd = sba_cmd_enc(cmd, msg_len,
SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK);
c_mdata = sba_cmd_xor_c_mdata(0, 0);
cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata),
SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK);
cmd = sba_cmd_enc(cmd, SBA_CMD_XOR,
SBA_CMD_SHIFT, SBA_CMD_MASK);
cmdsp->cmd = cmd;
*cmdsp->cmd_dma = cpu_to_le64(cmd);
cmdsp->flags = BRCM_SBA_CMD_TYPE_B;
cmdsp->data = *dst_q + msg_offset;
cmdsp->data_len = msg_len;
cmdsp++;
}
/* Type-A command to write buf0 */
cmd = sba_cmd_enc(0x0, SBA_TYPE_A,
SBA_TYPE_SHIFT, SBA_TYPE_MASK);
cmd = sba_cmd_enc(cmd, msg_len,
SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK);
cmd = sba_cmd_enc(cmd, 0x1,
SBA_RESP_SHIFT, SBA_RESP_MASK);
c_mdata = sba_cmd_write_c_mdata(0);
cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata),
SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK);
cmd = sba_cmd_enc(cmd, SBA_CMD_WRITE_BUFFER,
SBA_CMD_SHIFT, SBA_CMD_MASK);
cmdsp->cmd = cmd;
*cmdsp->cmd_dma = cpu_to_le64(cmd);
cmdsp->flags = BRCM_SBA_CMD_TYPE_A;
if (req->sba->hw_resp_size) {
cmdsp->flags |= BRCM_SBA_CMD_HAS_RESP;
cmdsp->resp = resp_dma;
cmdsp->resp_len = req->sba->hw_resp_size;
}
cmdsp->flags |= BRCM_SBA_CMD_HAS_OUTPUT;
cmdsp->data = *dst_q + msg_offset;
cmdsp->data_len = msg_len;
cmdsp++;
skip_q:
/* Fillup brcm_message */
msg->type = BRCM_MESSAGE_SBA;
msg->sba.cmds = cmds;
msg->sba.cmds_count = cmdsp - cmds;
msg->ctx = req;
msg->error = 0;
}