Skip to content

Commit

Permalink
Merge branch 'dsa-realtek-add-rtl8_4t-tags'
Browse files Browse the repository at this point in the history
Luiz Angelo Daros de Luca says:

====================
net: dsa: realtek: add rtl8_4t tag

This patch series adds support for rtl8_4t tag. It is a variant of
rtl8_4 tag, with identical values but placed at the end of the packet
(before CRC).

It forces checksum in software before adding the tag as those extra
bytes at the end of the packet would be summed together with the rest of
the payload. When the switch removes the tag before sending the packet
to the network, that checksum will not match.

It might be useful to diagnose or avoid checksum offload issues. With an
ethertype tag like rtl8_4, the cpu port ethernet driver must work with
cksum_start and chksum_offset to correctly calculate checksums. If not,
the checksum field will be broken (it will contain the fake ip header
sum).  In those cases, using 'rtl8_4t' might be an alternative way to
avoid checksum offload, either using runtime or device-tree property.

Regards,

Luiz

v4-v5)
- tags in alphabetical order in dsa_port.yaml
- remove ret var from rtl8365mb_change_tag_protocol
- Comment typos fixes

v3-v4)
- added rtl8_4 and rtl8_4t to dsa_port.yaml
- removed generic considerations about checksum problems with DSA tags.
  They belong to Documentation/networking/dsa/dsa.rst

v2-v3)
- updated tag documentation (file header)
- do not remove position and format from rtl8365mb_cpu
- reinstate cpu to rtl8365mb
- moved rtl8365mb_change_tag_protocol after rtl8365mb_cpu_config
- do not modify rtl8365mb_cpu_config() logic
- remove cpu arg from rtl8365mb_cpu_config(); get it from priv
- dropped tag_protocol from rtl8365mb. It is now derived from
  cpu->position.
- init cpu struct before dsa_register as default tag must be already
  defined before dsa_register()
- fix formatting issues

v1-v2)
- remove mention to tail tagger, use trailing tagger.
- use void* instead of char* for pointing to tag beginning
- use memcpy to avoid problems with unaligned tags
- calculate checksum if it still pending
- keep in-use tag protocol in memory instead of reading from switch
  register
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 5, 2022
2 parents 6dff157 + 59dc7b4 commit c409f9b
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 51 deletions.
2 changes: 2 additions & 0 deletions Documentation/devicetree/bindings/net/dsa/dsa-port.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ properties:
- edsa
- ocelot
- ocelot-8021q
- rtl8_4
- rtl8_4t
- seville

phy-handle: true
Expand Down
77 changes: 62 additions & 15 deletions drivers/net/dsa/realtek/rtl8365mb.c
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ struct rtl8365mb_port {
* @chip_ver: chip silicon revision
* @port_mask: mask of all ports
* @learn_limit_max: maximum number of L2 addresses the chip can learn
* @cpu: CPU tagging and CPU port configuration for this chip
* @mib_lock: prevent concurrent reads of MIB counters
* @ports: per-port data
* @jam_table: chip-specific initialization jam table
Expand All @@ -580,6 +581,7 @@ struct rtl8365mb {
u32 chip_ver;
u32 port_mask;
u32 learn_limit_max;
struct rtl8365mb_cpu cpu;
struct mutex mib_lock;
struct rtl8365mb_port ports[RTL8365MB_MAX_NUM_PORTS];
const struct rtl8365mb_jam_tbl_entry *jam_table;
Expand Down Expand Up @@ -782,6 +784,16 @@ static enum dsa_tag_protocol
rtl8365mb_get_tag_protocol(struct dsa_switch *ds, int port,
enum dsa_tag_protocol mp)
{
struct realtek_priv *priv = ds->priv;
struct rtl8365mb_cpu *cpu;
struct rtl8365mb *mb;

mb = priv->chip_data;
cpu = &mb->cpu;

if (cpu->position == RTL8365MB_CPU_POS_BEFORE_CRC)
return DSA_TAG_PROTO_RTL8_4T;

return DSA_TAG_PROTO_RTL8_4;
}

Expand Down Expand Up @@ -1737,8 +1749,10 @@ static void rtl8365mb_irq_teardown(struct realtek_priv *priv)
}
}

static int rtl8365mb_cpu_config(struct realtek_priv *priv, const struct rtl8365mb_cpu *cpu)
static int rtl8365mb_cpu_config(struct realtek_priv *priv)
{
struct rtl8365mb *mb = priv->chip_data;
struct rtl8365mb_cpu *cpu = &mb->cpu;
u32 val;
int ret;

Expand All @@ -1764,6 +1778,37 @@ static int rtl8365mb_cpu_config(struct realtek_priv *priv, const struct rtl8365m
return 0;
}

static int rtl8365mb_change_tag_protocol(struct dsa_switch *ds, int cpu_index,
enum dsa_tag_protocol proto)
{
struct realtek_priv *priv = ds->priv;
struct rtl8365mb_cpu *cpu;
struct rtl8365mb *mb;

mb = priv->chip_data;
cpu = &mb->cpu;

switch (proto) {
case DSA_TAG_PROTO_RTL8_4:
cpu->format = RTL8365MB_CPU_FORMAT_8BYTES;
cpu->position = RTL8365MB_CPU_POS_AFTER_SA;
break;
case DSA_TAG_PROTO_RTL8_4T:
cpu->format = RTL8365MB_CPU_FORMAT_8BYTES;
cpu->position = RTL8365MB_CPU_POS_BEFORE_CRC;
break;
/* The switch also supports a 4-byte format, similar to rtl4a but with
* the same 0x04 8-bit version and probably 8-bit port source/dest.
* There is no public doc about it. Not supported yet and it will probably
* never be.
*/
default:
return -EPROTONOSUPPORT;
}

return rtl8365mb_cpu_config(priv);
}

static int rtl8365mb_switch_init(struct realtek_priv *priv)
{
struct rtl8365mb *mb = priv->chip_data;
Expand Down Expand Up @@ -1810,13 +1855,14 @@ static int rtl8365mb_reset_chip(struct realtek_priv *priv)
static int rtl8365mb_setup(struct dsa_switch *ds)
{
struct realtek_priv *priv = ds->priv;
struct rtl8365mb_cpu cpu = {0};
struct rtl8365mb_cpu *cpu;
struct dsa_port *cpu_dp;
struct rtl8365mb *mb;
int ret;
int i;

mb = priv->chip_data;
cpu = &mb->cpu;

ret = rtl8365mb_reset_chip(priv);
if (ret) {
Expand All @@ -1839,21 +1885,14 @@ static int rtl8365mb_setup(struct dsa_switch *ds)
dev_info(priv->dev, "no interrupt support\n");

/* Configure CPU tagging */
cpu.trap_port = RTL8365MB_MAX_NUM_PORTS;
dsa_switch_for_each_cpu_port(cpu_dp, priv->ds) {
cpu.mask |= BIT(cpu_dp->index);
cpu->mask |= BIT(cpu_dp->index);

if (cpu.trap_port == RTL8365MB_MAX_NUM_PORTS)
cpu.trap_port = cpu_dp->index;
if (cpu->trap_port == RTL8365MB_MAX_NUM_PORTS)
cpu->trap_port = cpu_dp->index;
}

cpu.enable = cpu.mask > 0;
cpu.insert = RTL8365MB_CPU_INSERT_TO_ALL;
cpu.position = RTL8365MB_CPU_POS_AFTER_SA;
cpu.rx_length = RTL8365MB_CPU_RXLEN_64BYTES;
cpu.format = RTL8365MB_CPU_FORMAT_8BYTES;

ret = rtl8365mb_cpu_config(priv, &cpu);
cpu->enable = cpu->mask > 0;
ret = rtl8365mb_cpu_config(priv);
if (ret)
goto out_teardown_irq;

Expand All @@ -1865,7 +1904,7 @@ static int rtl8365mb_setup(struct dsa_switch *ds)
continue;

/* Forward only to the CPU */
ret = rtl8365mb_port_set_isolation(priv, i, cpu.mask);
ret = rtl8365mb_port_set_isolation(priv, i, cpu->mask);
if (ret)
goto out_teardown_irq;

Expand Down Expand Up @@ -1995,6 +2034,12 @@ static int rtl8365mb_detect(struct realtek_priv *priv)
mb->jam_table = rtl8365mb_init_jam_8365mb_vc;
mb->jam_size = ARRAY_SIZE(rtl8365mb_init_jam_8365mb_vc);

mb->cpu.trap_port = RTL8365MB_MAX_NUM_PORTS;
mb->cpu.insert = RTL8365MB_CPU_INSERT_TO_ALL;
mb->cpu.position = RTL8365MB_CPU_POS_AFTER_SA;
mb->cpu.rx_length = RTL8365MB_CPU_RXLEN_64BYTES;
mb->cpu.format = RTL8365MB_CPU_FORMAT_8BYTES;

break;
default:
dev_err(priv->dev,
Expand All @@ -2008,6 +2053,7 @@ static int rtl8365mb_detect(struct realtek_priv *priv)

static const struct dsa_switch_ops rtl8365mb_switch_ops_smi = {
.get_tag_protocol = rtl8365mb_get_tag_protocol,
.change_tag_protocol = rtl8365mb_change_tag_protocol,
.setup = rtl8365mb_setup,
.teardown = rtl8365mb_teardown,
.phylink_get_caps = rtl8365mb_phylink_get_caps,
Expand All @@ -2026,6 +2072,7 @@ static const struct dsa_switch_ops rtl8365mb_switch_ops_smi = {

static const struct dsa_switch_ops rtl8365mb_switch_ops_mdio = {
.get_tag_protocol = rtl8365mb_get_tag_protocol,
.change_tag_protocol = rtl8365mb_change_tag_protocol,
.setup = rtl8365mb_setup,
.teardown = rtl8365mb_teardown,
.phylink_get_caps = rtl8365mb_phylink_get_caps,
Expand Down
2 changes: 2 additions & 0 deletions include/net/dsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct phylink_link_state;
#define DSA_TAG_PROTO_BRCM_LEGACY_VALUE 22
#define DSA_TAG_PROTO_SJA1110_VALUE 23
#define DSA_TAG_PROTO_RTL8_4_VALUE 24
#define DSA_TAG_PROTO_RTL8_4T_VALUE 25

enum dsa_tag_protocol {
DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
Expand Down Expand Up @@ -79,6 +80,7 @@ enum dsa_tag_protocol {
DSA_TAG_PROTO_SEVILLE = DSA_TAG_PROTO_SEVILLE_VALUE,
DSA_TAG_PROTO_SJA1110 = DSA_TAG_PROTO_SJA1110_VALUE,
DSA_TAG_PROTO_RTL8_4 = DSA_TAG_PROTO_RTL8_4_VALUE,
DSA_TAG_PROTO_RTL8_4T = DSA_TAG_PROTO_RTL8_4T_VALUE,
};

struct dsa_switch;
Expand Down
Loading

0 comments on commit c409f9b

Please sign in to comment.