Message ID | 20180713153150.2414-1-alexander.sverdlin@nokia.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
Series | octeon_mgmt: Fix MIX registers configuration on MTU setup | expand |
From: Alexander Sverdlin <alexander.sverdlin@nokia.com> Date: Fri, 13 Jul 2018 17:31:50 +0200 > From: Alexander Sverdlin <alexander.sverdlin@nsn.com> > > octeon_mgmt driver doesn't drop RX frames that are 1-4 bytes bigger than > MTU set for the corresponding interface. The problem is in the > AGL_GMX_RX0/1_FRM_MAX register setting, which should not account for VLAN > tagging. > > According to Octeon HW manual: > "For tagged frames, MAX increases by four bytes for each VLAN found up to a > maximum of two VLANs, or MAX + 8 bytes." > > OCTEON_FRAME_HEADER_LEN "define" is fine for ring buffer management, but > should not be used for AGL_GMX_RX0/1_FRM_MAX. > > The problem could be easily reproduced using "ping" command. If affected > system has default MTU 1500, other host (having MTU >= 1504) can > successfully "ping" the affected system with payload size 1473-1476, > resulting in IP packets of size 1501-1504 accepted by the mgmt driver. > Fixed system still accepts IP packets of 1500 bytes even with VLAN tagging, > because the limits are lifted in HW as expected, for every VLAN tag. > > Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com> Applied, thank you.
diff --git a/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c b/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c index 3f6afb54a5eb..bb43ddb7539e 100644 --- a/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c +++ b/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c @@ -643,13 +643,21 @@ static int octeon_mgmt_set_mac_address(struct net_device *netdev, void *addr) static int octeon_mgmt_change_mtu(struct net_device *netdev, int new_mtu) { struct octeon_mgmt *p = netdev_priv(netdev); - int size_without_fcs = new_mtu + OCTEON_MGMT_RX_HEADROOM; + int max_packet = new_mtu + ETH_HLEN + ETH_FCS_LEN; netdev->mtu = new_mtu; - cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_MAX, size_without_fcs); + /* HW lifts the limit if the frame is VLAN tagged + * (+4 bytes per each tag, up to two tags) + */ + cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_MAX, max_packet); + /* Set the hardware to truncate packets larger than the MTU. The jabber + * register must be set to a multiple of 8 bytes, so round up. JABBER is + * an unconditional limit, so we need to account for two possible VLAN + * tags. + */ cvmx_write_csr(p->agl + AGL_GMX_RX_JABBER, - (size_without_fcs + 7) & 0xfff8); + (max_packet + 7 + VLAN_HLEN * 2) & 0xfff8); return 0; }