diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index b8e192374a32..ab3ee5c3fd02 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -439,8 +439,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports) ocelot->vcap_is2_actions= felix->info->vcap_is2_actions; ocelot->vcap = felix->info->vcap; ocelot->ops = felix->info->ops; - ocelot->inj_prefix = OCELOT_TAG_PREFIX_NONE; - ocelot->xtr_prefix = OCELOT_TAG_PREFIX_LONG; + ocelot->inj_prefix = OCELOT_TAG_PREFIX_SHORT; + ocelot->xtr_prefix = OCELOT_TAG_PREFIX_SHORT; port_phy_modes = kcalloc(num_phys_ports, sizeof(phy_interface_t), GFP_KERNEL); @@ -511,7 +511,7 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports) return PTR_ERR(target); } - template = devm_kzalloc(ocelot->dev, OCELOT_TAG_LEN, + template = devm_kzalloc(ocelot->dev, OCELOT_TOTAL_TAG_LEN, GFP_KERNEL); if (!template) { dev_err(ocelot->dev, diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 3ab6d6847c5b..2e9270c00096 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -1155,6 +1155,8 @@ static void vsc9959_xmit_template_populate(struct ocelot *ocelot, int port) struct ocelot_port *ocelot_port = ocelot->ports[port]; u8 *template = ocelot_port->xmit_template; u64 bypass, dest, src; + __be32 *prefix; + u8 *injection; /* Set the source port as the CPU port module and not the * NPI port @@ -1163,9 +1165,14 @@ static void vsc9959_xmit_template_populate(struct ocelot *ocelot, int port) dest = BIT(port); bypass = true; - packing(template, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0); - packing(template, &dest, 68, 56, OCELOT_TAG_LEN, PACK, 0); - packing(template, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0); + injection = template + OCELOT_SHORT_PREFIX_LEN; + prefix = (__be32 *)template; + + packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0); + packing(injection, &dest, 68, 56, OCELOT_TAG_LEN, PACK, 0); + packing(injection, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0); + + *prefix = cpu_to_be32(0x8880000a); } static const struct felix_info felix_info_vsc9959 = { diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c index b0ff90c0ae16..e28dd600f464 100644 --- a/drivers/net/dsa/ocelot/seville_vsc9953.c +++ b/drivers/net/dsa/ocelot/seville_vsc9953.c @@ -1003,6 +1003,8 @@ static void vsc9953_xmit_template_populate(struct ocelot *ocelot, int port) struct ocelot_port *ocelot_port = ocelot->ports[port]; u8 *template = ocelot_port->xmit_template; u64 bypass, dest, src; + __be32 *prefix; + u8 *injection; /* Set the source port as the CPU port module and not the * NPI port @@ -1011,9 +1013,14 @@ static void vsc9953_xmit_template_populate(struct ocelot *ocelot, int port) dest = BIT(port); bypass = true; - packing(template, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0); - packing(template, &dest, 67, 57, OCELOT_TAG_LEN, PACK, 0); - packing(template, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0); + injection = template + OCELOT_SHORT_PREFIX_LEN; + prefix = (__be32 *)template; + + packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0); + packing(injection, &dest, 67, 57, OCELOT_TAG_LEN, PACK, 0); + packing(injection, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0); + + *prefix = cpu_to_be32(0x88800005); } static const struct felix_info seville_info_vsc9953 = { diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index 349e839c4c18..3093385f6147 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -101,6 +101,7 @@ #define OCELOT_TAG_LEN 16 #define OCELOT_SHORT_PREFIX_LEN 4 #define OCELOT_LONG_PREFIX_LEN 16 +#define OCELOT_TOTAL_TAG_LEN (OCELOT_SHORT_PREFIX_LEN + OCELOT_TAG_LEN) #define OCELOT_SPEED_2500 0 #define OCELOT_SPEED_1000 1 diff --git a/net/dsa/tag_ocelot.c b/net/dsa/tag_ocelot.c index d1a7e224adff..ec16badb7812 100644 --- a/net/dsa/tag_ocelot.c +++ b/net/dsa/tag_ocelot.c @@ -141,10 +141,12 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb, struct dsa_switch *ds = dp->ds; struct ocelot *ocelot = ds->priv; struct ocelot_port *ocelot_port; + u8 *prefix, *injection; u64 qos_class, rew_op; - u8 *injection; + int err; - if (unlikely(skb_cow_head(skb, OCELOT_TAG_LEN) < 0)) { + err = skb_cow_head(skb, OCELOT_TOTAL_TAG_LEN); + if (unlikely(err < 0)) { netdev_err(netdev, "Cannot make room for tag.\n"); return NULL; } @@ -153,7 +155,10 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb, injection = skb_push(skb, OCELOT_TAG_LEN); - memcpy(injection, ocelot_port->xmit_template, OCELOT_TAG_LEN); + prefix = skb_push(skb, OCELOT_SHORT_PREFIX_LEN); + + memcpy(prefix, ocelot_port->xmit_template, OCELOT_TOTAL_TAG_LEN); + /* Fix up the fields which are not statically determined * in the template */ @@ -187,11 +192,11 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb, * so it points to the beginning of the frame. */ skb_push(skb, ETH_HLEN); - /* We don't care about the long prefix, it is just for easy entrance + /* We don't care about the short prefix, it is just for easy entrance * into the DSA master's RX filter. Discard it now by moving it into * the headroom. */ - skb_pull(skb, OCELOT_LONG_PREFIX_LEN); + skb_pull(skb, OCELOT_SHORT_PREFIX_LEN); /* And skb->data now points to the extraction frame header. * Keep a pointer to it. */ @@ -205,7 +210,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb, skb_pull(skb, ETH_HLEN); /* Remove from inet csum the extraction header */ - skb_postpull_rcsum(skb, start, OCELOT_LONG_PREFIX_LEN + OCELOT_TAG_LEN); + skb_postpull_rcsum(skb, start, OCELOT_TOTAL_TAG_LEN); packing(extraction, &src_port, 46, 43, OCELOT_TAG_LEN, UNPACK, 0); packing(extraction, &qos_class, 19, 17, OCELOT_TAG_LEN, UNPACK, 0); @@ -231,7 +236,8 @@ static const struct dsa_device_ops ocelot_netdev_ops = { .proto = DSA_TAG_PROTO_OCELOT, .xmit = ocelot_xmit, .rcv = ocelot_rcv, - .overhead = OCELOT_TAG_LEN + OCELOT_LONG_PREFIX_LEN, + .overhead = OCELOT_TOTAL_TAG_LEN, + .promisc_on_master = true, }; MODULE_LICENSE("GPL v2");