Commit 70644f72 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-lan966x-fixes-for-when-mtu-is-changed'

Horatiu Vultur says:

====================
net: lan966x: Fixes for when MTU is changed

There were multiple problems in different parts of the driver when
the MTU was changed.
The first problem was that the HW was missing to configure the correct
value, it was missing ETH_HLEN and ETH_FCS_LEN. The second problem was
when vlan filtering was enabled/disabled, the MRU was not adjusted
corretly. While the last issue was that the FDMA was calculated wrongly
the correct maximum MTU.
====================

Link: https://lore.kernel.org/r/20221030213636.1031408-1-horatiu.vultur@microchip.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 6c412da5 872ad758
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -668,12 +668,14 @@ static int lan966x_fdma_get_max_mtu(struct lan966x *lan966x)
	int i;

	for (i = 0; i < lan966x->num_phys_ports; ++i) {
		struct lan966x_port *port;
		int mtu;

		if (!lan966x->ports[i])
		port = lan966x->ports[i];
		if (!port)
			continue;

		mtu = lan966x->ports[i]->dev->mtu;
		mtu = lan_rd(lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port));
		if (mtu > max_mtu)
			max_mtu = mtu;
	}
@@ -733,6 +735,8 @@ int lan966x_fdma_change_mtu(struct lan966x *lan966x)

	max_mtu = lan966x_fdma_get_max_mtu(lan966x);
	max_mtu += IFH_LEN * sizeof(u32);
	max_mtu += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
	max_mtu += VLAN_HLEN * 2;

	if (round_up(max_mtu, PAGE_SIZE) / PAGE_SIZE - 1 ==
	    lan966x->rx.page_order)
+2 −2
Original line number Diff line number Diff line
@@ -386,7 +386,7 @@ static int lan966x_port_change_mtu(struct net_device *dev, int new_mtu)
	int old_mtu = dev->mtu;
	int err;

	lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(new_mtu),
	lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(LAN966X_HW_MTU(new_mtu)),
	       lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port));
	dev->mtu = new_mtu;

@@ -395,7 +395,7 @@ static int lan966x_port_change_mtu(struct net_device *dev, int new_mtu)

	err = lan966x_fdma_change_mtu(lan966x);
	if (err) {
		lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(old_mtu),
		lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(LAN966X_HW_MTU(old_mtu)),
		       lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port));
		dev->mtu = old_mtu;
	}
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@
#define LAN966X_BUFFER_MEMORY		(160 * 1024)
#define LAN966X_BUFFER_MIN_SZ		60

#define LAN966X_HW_MTU(mtu)		((mtu) + ETH_HLEN + ETH_FCS_LEN)

#define PGID_AGGR			64
#define PGID_SRC			80
#define PGID_ENTRIES			89
+15 −0
Original line number Diff line number Diff line
@@ -585,6 +585,21 @@ enum lan966x_target {
#define DEV_MAC_MAXLEN_CFG_MAX_LEN_GET(x)\
	FIELD_GET(DEV_MAC_MAXLEN_CFG_MAX_LEN, x)

/*      DEV:MAC_CFG_STATUS:MAC_TAGS_CFG */
#define DEV_MAC_TAGS_CFG(t)       __REG(TARGET_DEV, t, 8, 28, 0, 1, 44, 12, 0, 1, 4)

#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA        BIT(1)
#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_SET(x)\
	FIELD_PREP(DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA, x)
#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_GET(x)\
	FIELD_GET(DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA, x)

#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA            BIT(0)
#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(x)\
	FIELD_PREP(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_GET(x)\
	FIELD_GET(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA, x)

/*      DEV:MAC_CFG_STATUS:MAC_IFG_CFG */
#define DEV_MAC_IFG_CFG(t)        __REG(TARGET_DEV, t, 8, 28, 0, 1, 44, 20, 0, 1, 4)

+6 −0
Original line number Diff line number Diff line
@@ -169,6 +169,12 @@ void lan966x_vlan_port_apply(struct lan966x_port *port)
		ANA_VLAN_CFG_VLAN_POP_CNT,
		lan966x, ANA_VLAN_CFG(port->chip_port));

	lan_rmw(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(port->vlan_aware) |
		DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_SET(port->vlan_aware),
		DEV_MAC_TAGS_CFG_VLAN_AWR_ENA |
		DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA,
		lan966x, DEV_MAC_TAGS_CFG(port->chip_port));

	/* Drop frames with multicast source address */
	val = ANA_DROP_CFG_DROP_MC_SMAC_ENA_SET(1);
	if (port->vlan_aware && !pvid)