diff options
author | Vladimir Oltean | 2021-05-24 12:25:22 +0300 |
---|---|---|
committer | David S. Miller | 2021-05-24 13:20:24 -0700 |
commit | ba61cf167cb77e54c1ec5adb7aa49a22ab3c9b28 (patch) | |
tree | c6affbecd561407a3f50ac487ca9f0f6cd0b2151 /drivers/net/dsa | |
parent | 1a6e9a9c68c1f183872e4bcc947382111c2e04eb (diff) |
net: dsa: sja1105: fix VL lookup command packing for P/Q/R/S
At the beginning of the sja1105_dynamic_config.c file there is a diagram
of the dynamic config interface layout:
packed_buf
|
V
+-----------------------------------------+------------------+
| ENTRY BUFFER | COMMAND BUFFER |
+-----------------------------------------+------------------+
<----------------------- packed_size ------------------------>
So in order to pack/unpack the command bits into the buffer,
sja1105_vl_lookup_cmd_packing must first advance the buffer pointer by
the length of the entry. This is similar to what the other *cmd_packing
functions do.
This bug exists because the command packing function for P/Q/R/S was
copied from the E/T generation, and on E/T, the command was actually
embedded within the entry buffer itself.
Fixes: 94f94d4acfb2 ("net: dsa: sja1105: add static tables for virtual links")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r-- | drivers/net/dsa/sja1105/sja1105_dynamic_config.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c index b777d3f37573..12cd04b56803 100644 --- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c +++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c @@ -167,9 +167,10 @@ enum sja1105_hostcmd { SJA1105_HOSTCMD_INVALIDATE = 4, }; +/* Command and entry overlap */ static void -sja1105_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, - enum packing_op op) +sja1105et_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) { const int size = SJA1105_SIZE_DYN_CMD; @@ -179,6 +180,20 @@ sja1105_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, sja1105_packing(buf, &cmd->index, 9, 0, size, op); } +/* Command and entry are separate */ +static void +sja1105pqrs_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) +{ + u8 *p = buf + SJA1105_SIZE_VL_LOOKUP_ENTRY; + const int size = SJA1105_SIZE_DYN_CMD; + + sja1105_packing(p, &cmd->valid, 31, 31, size, op); + sja1105_packing(p, &cmd->errors, 30, 30, size, op); + sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op); + sja1105_packing(p, &cmd->index, 9, 0, size, op); +} + static size_t sja1105et_vl_lookup_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -641,7 +656,7 @@ static size_t sja1105pqrs_cbs_entry_packing(void *buf, void *entry_ptr, const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = { [BLK_IDX_VL_LOOKUP] = { .entry_packing = sja1105et_vl_lookup_entry_packing, - .cmd_packing = sja1105_vl_lookup_cmd_packing, + .cmd_packing = sja1105et_vl_lookup_cmd_packing, .access = OP_WRITE, .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT, .packed_size = SJA1105ET_SIZE_VL_LOOKUP_DYN_CMD, @@ -725,7 +740,7 @@ const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = { const struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = { [BLK_IDX_VL_LOOKUP] = { .entry_packing = sja1105_vl_lookup_entry_packing, - .cmd_packing = sja1105_vl_lookup_cmd_packing, + .cmd_packing = sja1105pqrs_vl_lookup_cmd_packing, .access = (OP_READ | OP_WRITE), .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT, .packed_size = SJA1105PQRS_SIZE_VL_LOOKUP_DYN_CMD, |