diff options
author | Vladimir Oltean <olteanv@gmail.com> | 2019-06-03 00:15:33 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-06-04 21:49:20 +0300 |
commit | 2a7e7409298d5e0a51e7ff23dc0befc6fdef69d1 (patch) | |
tree | 7a066867a3624d53e8870f24d7e229902cd33376 /drivers/net/dsa/sja1105/sja1105_dynamic_config.c | |
parent | def846042f13cb0feabb86375e824c648543700a (diff) | |
download | linux-2a7e7409298d5e0a51e7ff23dc0befc6fdef69d1.tar.xz |
net: dsa: sja1105: Add P/Q/R/S management route support via dynamic interface
Management routes are one-shot FDB rules installed on the CPU port for
sending link-local traffic. They are a prerequisite for STP, PTP etc to
work.
Also make a note that removing a management route was not supported on
the previous generation of switches.
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/sja1105/sja1105_dynamic_config.c')
-rw-r--r-- | drivers/net/dsa/sja1105/sja1105_dynamic_config.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c index 02a67df4437e..352bb6e89297 100644 --- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c +++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c @@ -161,6 +161,36 @@ static size_t sja1105et_mgmt_route_entry_packing(void *buf, void *entry_ptr, return size; } +static void +sja1105pqrs_mgmt_route_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) +{ + u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY; + u64 mgmtroute = 1; + + sja1105pqrs_l2_lookup_cmd_packing(buf, cmd, op); + if (op == PACK) + sja1105_pack(p, &mgmtroute, 26, 26, SJA1105_SIZE_DYN_CMD); +} + +static size_t sja1105pqrs_mgmt_route_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + const size_t size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY; + struct sja1105_mgmt_entry *entry = entry_ptr; + + /* In P/Q/R/S, enfport got renamed to mgmtvalid, but its purpose + * is the same (driver uses it to confirm that frame was sent). + * So just keep the name from E/T. + */ + sja1105_packing(buf, &entry->tsreg, 71, 71, size, op); + sja1105_packing(buf, &entry->takets, 70, 70, size, op); + sja1105_packing(buf, &entry->macaddr, 69, 22, size, op); + sja1105_packing(buf, &entry->destports, 21, 17, size, op); + sja1105_packing(buf, &entry->enfport, 16, 16, size, op); + return size; +} + /* In E/T, entry is at addresses 0x27-0x28. There is a 4 byte gap at 0x29, * and command is at 0x2a. Similarly in P/Q/R/S there is a 1 register gap * between entry (0x2d, 0x2e) and command (0x30). @@ -359,7 +389,7 @@ struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = { [BLK_IDX_XMII_PARAMS] = {0}, }; -/* SJA1105P/Q/R/S: Second generation: TODO */ +/* SJA1105P/Q/R/S: Second generation */ struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = { [BLK_IDX_L2_LOOKUP] = { .entry_packing = sja1105pqrs_l2_lookup_entry_packing, @@ -369,6 +399,14 @@ struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = { .packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD, .addr = 0x24, }, + [BLK_IDX_MGMT_ROUTE] = { + .entry_packing = sja1105pqrs_mgmt_route_entry_packing, + .cmd_packing = sja1105pqrs_mgmt_route_cmd_packing, + .access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH), + .max_entry_count = SJA1105_NUM_PORTS, + .packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD, + .addr = 0x24, + }, [BLK_IDX_L2_POLICING] = {0}, [BLK_IDX_VLAN_LOOKUP] = { .entry_packing = sja1105_vlan_lookup_entry_packing, |