aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntoine Tenart <antoine.tenart@bootlin.com>2018-06-20 04:50:46 -0400
committerDavid S. Miller <davem@davemloft.net>2018-06-20 21:29:46 -0400
commit08d02364b12faa54d76dbfea2090321fd27996f2 (patch)
treea40b3a5e1608afe22717b80d4a92c4ff950326c1
parentea0820bb771175c7d4192fc6f5b5c56b3c6d5239 (diff)
net: mscc: fix the injection header
When injecting frames in the Ocelot switch driver an injection header (IFH) should be used to configure various parameters related to a given frame, such as the port onto which the frame should be departed or its vlan id. Other parameters in the switch configuration can led to an injected frame being sent without an IFH but this led to various issues as the per-frame parameters are then not used. This is especially true when using multiple ports for injection. The IFH was injected with the wrong endianness which led to the switch not taking it into account as the IFH_INJ_BYPASS bit was then unset. (The bit tells the switch to use the IFH over its internal configuration). This patch fixes it. In addition to the endianness fix, the IFH is also fixed. As it was (unwillingly) unused, some of its fields were not configured the right way. Fixes: a556c76adc05 ("net: mscc: Add initial Ocelot switch support") Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com> Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mscc/ocelot.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index fb2c8f8071e6..52c57e0ff617 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -344,10 +344,9 @@ static int ocelot_port_stop(struct net_device *dev)
344static int ocelot_gen_ifh(u32 *ifh, struct frame_info *info) 344static int ocelot_gen_ifh(u32 *ifh, struct frame_info *info)
345{ 345{
346 ifh[0] = IFH_INJ_BYPASS; 346 ifh[0] = IFH_INJ_BYPASS;
347 ifh[1] = (0xff00 & info->port) >> 8; 347 ifh[1] = (0xf00 & info->port) >> 8;
348 ifh[2] = (0xff & info->port) << 24; 348 ifh[2] = (0xff & info->port) << 24;
349 ifh[3] = IFH_INJ_POP_CNT_DISABLE | (info->cpuq << 20) | 349 ifh[3] = (info->tag_type << 16) | info->vid;
350 (info->tag_type << 16) | info->vid;
351 350
352 return 0; 351 return 0;
353} 352}
@@ -370,11 +369,12 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
370 QS_INJ_CTRL_SOF, QS_INJ_CTRL, grp); 369 QS_INJ_CTRL_SOF, QS_INJ_CTRL, grp);
371 370
372 info.port = BIT(port->chip_port); 371 info.port = BIT(port->chip_port);
373 info.cpuq = 0xff; 372 info.tag_type = IFH_TAG_TYPE_C;
373 info.vid = skb_vlan_tag_get(skb);
374 ocelot_gen_ifh(ifh, &info); 374 ocelot_gen_ifh(ifh, &info);
375 375
376 for (i = 0; i < IFH_LEN; i++) 376 for (i = 0; i < IFH_LEN; i++)
377 ocelot_write_rix(ocelot, ifh[i], QS_INJ_WR, grp); 377 ocelot_write_rix(ocelot, cpu_to_be32(ifh[i]), QS_INJ_WR, grp);
378 378
379 count = (skb->len + 3) / 4; 379 count = (skb->len + 3) / 4;
380 last = skb->len % 4; 380 last = skb->len % 4;