in bcm-sba-raid.c [911:1058]
static void sba_fillup_pq_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,
const u8 *scf, dma_addr_t *src, u32 src_cnt)
{
u64 cmd;
u32 c_mdata;
unsigned int i;
dma_addr_t resp_dma = req->tx.phys;
struct brcm_sba_command *cmdsp = cmds;
if (pq_continue) {
/* Type-B command to load old P into buf0 */
if (dst_p) {
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 command to load old Q into buf1 */
if (dst_q) {
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(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_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_q + msg_offset;
cmdsp->data_len = msg_len;
cmdsp++;
}
} else {
/* 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++;
}
/* Type-B commands for generate P onto buf0 and Q onto buf1 */
for (i = 0; i < src_cnt; i++) {
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(raid6_gflog[scf[i]], 1, 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_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[i] + msg_offset;
cmdsp->data_len = msg_len;
cmdsp++;
}
/* Type-A command to write buf0 */
if (dst_p) {
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++;
}
/* Type-A command to write buf1 */
if (dst_q) {
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(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_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++;
}
/* Fillup brcm_message */
msg->type = BRCM_MESSAGE_SBA;
msg->sba.cmds = cmds;
msg->sba.cmds_count = cmdsp - cmds;
msg->ctx = req;
msg->error = 0;
}