Skip to content

Commit a8015de

Browse files
vladimirolteandavem330
authored andcommitted
net: mscc: ocelot: properly account for VLAN header length when setting MRU
What the driver writes into MAC_MAXLEN_CFG does not actually represent VLAN_ETH_FRAME_LEN but instead ETH_FRAME_LEN + ETH_FCS_LEN. Yes they are numerically equal, but the difference is important, as the switch treats VLAN-tagged traffic specially and knows to increase the maximum accepted frame size automatically. So it is always wrong to account for VLAN in the MAC_MAXLEN_CFG register. Unconditionally increase the maximum allowed frame size for double-tagged traffic. Accounting for the additional length does not mean that the other VLAN membership checks aren't performed, so there's no harm done. Also, stop abusing the MTU name for configuring the MRU. There is no support for configuring the MRU on an interface at the moment. Fixes: a556c76 ("net: mscc: Add initial Ocelot switch support") Fixes: fa914e9 ("net: mscc: ocelot: create a helper for changing the port MTU") Signed-off-by: Vladimir Oltean <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent afe207d commit a8015de

File tree

2 files changed

+18
-12
lines changed

2 files changed

+18
-12
lines changed

drivers/net/ethernet/mscc/ocelot.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2176,24 +2176,29 @@ static int ocelot_init_timestamp(struct ocelot *ocelot)
21762176
return 0;
21772177
}
21782178

2179-
static void ocelot_port_set_mtu(struct ocelot *ocelot, int port, size_t mtu)
2179+
/* Configure the maximum SDU (L2 payload) on RX to the value specified in @sdu.
2180+
* The length of VLAN tags is accounted for automatically via DEV_MAC_TAGS_CFG.
2181+
*/
2182+
static void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
21802183
{
21812184
struct ocelot_port *ocelot_port = ocelot->ports[port];
2185+
int maxlen = sdu + ETH_HLEN + ETH_FCS_LEN;
21822186
int atop_wm;
21832187

2184-
ocelot_port_writel(ocelot_port, mtu, DEV_MAC_MAXLEN_CFG);
2188+
ocelot_port_writel(ocelot_port, maxlen, DEV_MAC_MAXLEN_CFG);
21852189

21862190
/* Set Pause WM hysteresis
2187-
* 152 = 6 * mtu / OCELOT_BUFFER_CELL_SZ
2188-
* 101 = 4 * mtu / OCELOT_BUFFER_CELL_SZ
2191+
* 152 = 6 * maxlen / OCELOT_BUFFER_CELL_SZ
2192+
* 101 = 4 * maxlen / OCELOT_BUFFER_CELL_SZ
21892193
*/
21902194
ocelot_write_rix(ocelot, SYS_PAUSE_CFG_PAUSE_ENA |
21912195
SYS_PAUSE_CFG_PAUSE_STOP(101) |
21922196
SYS_PAUSE_CFG_PAUSE_START(152), SYS_PAUSE_CFG, port);
21932197

21942198
/* Tail dropping watermark */
2195-
atop_wm = (ocelot->shared_queue_sz - 9 * mtu) / OCELOT_BUFFER_CELL_SZ;
2196-
ocelot_write_rix(ocelot, ocelot_wm_enc(9 * mtu),
2199+
atop_wm = (ocelot->shared_queue_sz - 9 * maxlen) /
2200+
OCELOT_BUFFER_CELL_SZ;
2201+
ocelot_write_rix(ocelot, ocelot_wm_enc(9 * maxlen),
21972202
SYS_ATOP, port);
21982203
ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG);
21992204
}
@@ -2222,9 +2227,10 @@ void ocelot_init_port(struct ocelot *ocelot, int port)
22222227
DEV_MAC_HDX_CFG);
22232228

22242229
/* Set Max Length and maximum tags allowed */
2225-
ocelot_port_set_mtu(ocelot, port, VLAN_ETH_FRAME_LEN);
2230+
ocelot_port_set_maxlen(ocelot, port, ETH_DATA_LEN);
22262231
ocelot_port_writel(ocelot_port, DEV_MAC_TAGS_CFG_TAG_ID(ETH_P_8021AD) |
22272232
DEV_MAC_TAGS_CFG_VLAN_AWR_ENA |
2233+
DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA |
22282234
DEV_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA,
22292235
DEV_MAC_TAGS_CFG);
22302236

@@ -2310,18 +2316,18 @@ void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu,
23102316
* Only one port can be an NPI at the same time.
23112317
*/
23122318
if (cpu < ocelot->num_phys_ports) {
2313-
int mtu = VLAN_ETH_FRAME_LEN + OCELOT_TAG_LEN;
2319+
int sdu = ETH_DATA_LEN + OCELOT_TAG_LEN;
23142320

23152321
ocelot_write(ocelot, QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M |
23162322
QSYS_EXT_CPU_CFG_EXT_CPU_PORT(cpu),
23172323
QSYS_EXT_CPU_CFG);
23182324

23192325
if (injection == OCELOT_TAG_PREFIX_SHORT)
2320-
mtu += OCELOT_SHORT_PREFIX_LEN;
2326+
sdu += OCELOT_SHORT_PREFIX_LEN;
23212327
else if (injection == OCELOT_TAG_PREFIX_LONG)
2322-
mtu += OCELOT_LONG_PREFIX_LEN;
2328+
sdu += OCELOT_LONG_PREFIX_LEN;
23232329

2324-
ocelot_port_set_mtu(ocelot, cpu, mtu);
2330+
ocelot_port_set_maxlen(ocelot, cpu, sdu);
23252331
}
23262332

23272333
/* CPU port Injection/Extraction configuration */

include/soc/mscc/ocelot_dev.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
#define DEV_MAC_TAGS_CFG_TAG_ID_M GENMASK(31, 16)
7575
#define DEV_MAC_TAGS_CFG_TAG_ID_X(x) (((x) & GENMASK(31, 16)) >> 16)
7676
#define DEV_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA BIT(2)
77-
#define DEV_MAC_TAGS_CFG_PB_ENA BIT(1)
77+
#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA BIT(1)
7878
#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA BIT(0)
7979

8080
#define DEV_MAC_ADV_CHK_CFG 0x2c

0 commit comments

Comments
 (0)