net: lan966x: Fix FDMA when MTU is changed
When MTU is changed, FDMA is required to calculate what is the maximum size of the frame that it can received. So it can calculate what is the page order needed to allocate for the received frames. The first problem was that, when the max MTU was calculated it was reading the value from dev and not from HW, so in this way it was missing L2 header + the FCS. The other problem was that once the skb is created using __build_skb_around, it would reserve some space for skb_shared_info. So if we received a frame which size is at the limit of the page order then the creating will failed because it would not have space to put all the data. Fixes: 2ea1cbac267e ("net: lan966x: Update FDMA to change MTU.") Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
25f28bb1b4
commit
872ad758f9
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user