Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

atl1: fix frame length bug

The driver sets up the hardware to accept a frame with max length
equal to MTU + Ethernet header + FCS + VLAN tag, but we neglect to
add the VLAN tag size to the ingress buffer. When a VLAN-tagged
frame arrives, the hardware passes it, but bad things happen
because the buffer is too small. This patch fixes that.

Thanks to David Harris for reporting the bug and testing the fix.

Tested-by: David Harris <david.harris@cpni-inc.com>
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by

Jay Cliburn and committed by
Jeff Garzik
2a49128f ce3ba139

+4 -4
+4 -4
drivers/net/atl1/atl1_main.c
··· 120 120 struct atl1_hw *hw = &adapter->hw; 121 121 struct net_device *netdev = adapter->netdev; 122 122 123 - hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; 123 + hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; 124 124 hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; 125 125 126 126 adapter->wol = 0; ··· 688 688 { 689 689 struct atl1_adapter *adapter = netdev_priv(netdev); 690 690 int old_mtu = netdev->mtu; 691 - int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; 691 + int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; 692 692 693 693 if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) || 694 694 (max_frame > MAX_JUMBO_FRAME_SIZE)) { ··· 853 853 /* set Interrupt Clear Timer */ 854 854 iowrite16(adapter->ict, hw->hw_addr + REG_CMBDISDMA_TIMER); 855 855 856 - /* set MTU, 4 : VLAN */ 857 - iowrite32(hw->max_frame_size + 4, hw->hw_addr + REG_MTU); 856 + /* set max frame size hw will accept */ 857 + iowrite32(hw->max_frame_size, hw->hw_addr + REG_MTU); 858 858 859 859 /* jumbo size & rrd retirement timer */ 860 860 value = (((u32) hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK)