mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-13 22:25:03 +00:00
nfp: bpf: separate I/O from checks for legacy data load
Move data load into a separate function and separate it from packet length checks of legacy I/O. This makes the code more readable and easier to reuse. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Simon Horman <simon.horman@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
943c57b97c
commit
0a7939775f
1 changed files with 40 additions and 37 deletions
|
@ -515,63 +515,66 @@ static void wrp_reg_mov(struct nfp_prog *nfp_prog, u16 dst, u16 src)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
construct_data_ind_ld(struct nfp_prog *nfp_prog, u16 offset,
|
data_ld(struct nfp_prog *nfp_prog, swreg offset, u8 dst_gpr, int size)
|
||||||
u16 src, bool src_valid, u8 size)
|
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
u16 shift, sz;
|
u16 shift, sz;
|
||||||
swreg tmp_reg;
|
|
||||||
|
|
||||||
/* We load the value from the address indicated in @offset and then
|
/* We load the value from the address indicated in @offset and then
|
||||||
* shift out the data we don't need. Note: this is big endian!
|
* shift out the data we don't need. Note: this is big endian!
|
||||||
*/
|
*/
|
||||||
sz = size < 4 ? 4 : size;
|
sz = max(size, 4);
|
||||||
shift = size < 4 ? 4 - size : 0;
|
shift = size < 4 ? 4 - size : 0;
|
||||||
|
|
||||||
if (src_valid) {
|
emit_cmd(nfp_prog, CMD_TGT_READ8, CMD_MODE_32b, 0,
|
||||||
/* Calculate the true offset (src_reg + imm) */
|
pptr_reg(nfp_prog), offset, sz - 1, true);
|
||||||
tmp_reg = ur_load_imm_any(nfp_prog, offset, imm_b(nfp_prog));
|
|
||||||
emit_alu(nfp_prog, imm_both(nfp_prog),
|
|
||||||
reg_a(src), ALU_OP_ADD, tmp_reg);
|
|
||||||
/* Check packet length (size guaranteed to fit b/c it's u8) */
|
|
||||||
emit_alu(nfp_prog, imm_a(nfp_prog),
|
|
||||||
imm_a(nfp_prog), ALU_OP_ADD, reg_imm(size));
|
|
||||||
emit_alu(nfp_prog, reg_none(),
|
|
||||||
plen_reg(nfp_prog), ALU_OP_SUB, imm_a(nfp_prog));
|
|
||||||
wrp_br_special(nfp_prog, BR_BLO, OP_BR_GO_ABORT);
|
|
||||||
/* Load data */
|
|
||||||
emit_cmd(nfp_prog, CMD_TGT_READ8, CMD_MODE_32b, 0,
|
|
||||||
pptr_reg(nfp_prog), imm_b(nfp_prog), sz - 1, true);
|
|
||||||
} else {
|
|
||||||
/* Check packet length */
|
|
||||||
tmp_reg = ur_load_imm_any(nfp_prog, offset + size,
|
|
||||||
imm_a(nfp_prog));
|
|
||||||
emit_alu(nfp_prog, reg_none(),
|
|
||||||
plen_reg(nfp_prog), ALU_OP_SUB, tmp_reg);
|
|
||||||
wrp_br_special(nfp_prog, BR_BLO, OP_BR_GO_ABORT);
|
|
||||||
/* Load data */
|
|
||||||
tmp_reg = re_load_imm_any(nfp_prog, offset, imm_b(nfp_prog));
|
|
||||||
emit_cmd(nfp_prog, CMD_TGT_READ8, CMD_MODE_32b, 0,
|
|
||||||
pptr_reg(nfp_prog), tmp_reg, sz - 1, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
if (shift)
|
if (shift)
|
||||||
emit_shf(nfp_prog, reg_both(0), reg_none(), SHF_OP_NONE,
|
emit_shf(nfp_prog, reg_both(dst_gpr), reg_none(), SHF_OP_NONE,
|
||||||
reg_xfer(0), SHF_SC_R_SHF, shift * 8);
|
reg_xfer(0), SHF_SC_R_SHF, shift * 8);
|
||||||
else
|
else
|
||||||
for (; i * 4 < size; i++)
|
for (; i * 4 < size; i++)
|
||||||
wrp_mov(nfp_prog, reg_both(i), reg_xfer(i));
|
wrp_mov(nfp_prog, reg_both(dst_gpr + i), reg_xfer(i));
|
||||||
|
|
||||||
if (i < 2)
|
if (i < 2)
|
||||||
wrp_immed(nfp_prog, reg_both(1), 0);
|
wrp_immed(nfp_prog, reg_both(dst_gpr + 1), 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
construct_data_ind_ld(struct nfp_prog *nfp_prog, u16 offset, u16 src, u8 size)
|
||||||
|
{
|
||||||
|
swreg tmp_reg;
|
||||||
|
|
||||||
|
/* Calculate the true offset (src_reg + imm) */
|
||||||
|
tmp_reg = ur_load_imm_any(nfp_prog, offset, imm_b(nfp_prog));
|
||||||
|
emit_alu(nfp_prog, imm_both(nfp_prog), reg_a(src), ALU_OP_ADD, tmp_reg);
|
||||||
|
|
||||||
|
/* Check packet length (size guaranteed to fit b/c it's u8) */
|
||||||
|
emit_alu(nfp_prog, imm_a(nfp_prog),
|
||||||
|
imm_a(nfp_prog), ALU_OP_ADD, reg_imm(size));
|
||||||
|
emit_alu(nfp_prog, reg_none(),
|
||||||
|
plen_reg(nfp_prog), ALU_OP_SUB, imm_a(nfp_prog));
|
||||||
|
wrp_br_special(nfp_prog, BR_BLO, OP_BR_GO_ABORT);
|
||||||
|
|
||||||
|
/* Load data */
|
||||||
|
return data_ld(nfp_prog, imm_b(nfp_prog), 0, size);
|
||||||
|
}
|
||||||
|
|
||||||
static int construct_data_ld(struct nfp_prog *nfp_prog, u16 offset, u8 size)
|
static int construct_data_ld(struct nfp_prog *nfp_prog, u16 offset, u8 size)
|
||||||
{
|
{
|
||||||
return construct_data_ind_ld(nfp_prog, offset, 0, false, size);
|
swreg tmp_reg;
|
||||||
|
|
||||||
|
/* Check packet length */
|
||||||
|
tmp_reg = ur_load_imm_any(nfp_prog, offset + size, imm_a(nfp_prog));
|
||||||
|
emit_alu(nfp_prog, reg_none(), plen_reg(nfp_prog), ALU_OP_SUB, tmp_reg);
|
||||||
|
wrp_br_special(nfp_prog, BR_BLO, OP_BR_GO_ABORT);
|
||||||
|
|
||||||
|
/* Load data */
|
||||||
|
tmp_reg = re_load_imm_any(nfp_prog, offset, imm_b(nfp_prog));
|
||||||
|
return data_ld(nfp_prog, tmp_reg, 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1055,19 +1058,19 @@ static int data_ld4(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
|
||||||
static int data_ind_ld1(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
|
static int data_ind_ld1(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
|
||||||
{
|
{
|
||||||
return construct_data_ind_ld(nfp_prog, meta->insn.imm,
|
return construct_data_ind_ld(nfp_prog, meta->insn.imm,
|
||||||
meta->insn.src_reg * 2, true, 1);
|
meta->insn.src_reg * 2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int data_ind_ld2(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
|
static int data_ind_ld2(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
|
||||||
{
|
{
|
||||||
return construct_data_ind_ld(nfp_prog, meta->insn.imm,
|
return construct_data_ind_ld(nfp_prog, meta->insn.imm,
|
||||||
meta->insn.src_reg * 2, true, 2);
|
meta->insn.src_reg * 2, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int data_ind_ld4(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
|
static int data_ind_ld4(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
|
||||||
{
|
{
|
||||||
return construct_data_ind_ld(nfp_prog, meta->insn.imm,
|
return construct_data_ind_ld(nfp_prog, meta->insn.imm,
|
||||||
meta->insn.src_reg * 2, true, 4);
|
meta->insn.src_reg * 2, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mem_ldx_skb(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
|
static int mem_ldx_skb(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
|
||||||
|
|
Loading…
Reference in a new issue