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

net: ethernet: pcnet32: Setup the SRAM and NOUFLO on Am79C97{3, 5}

On a MIPS Malta board, tons of fifo underflow errors have been observed
when using u-boot as bootloader instead of YAMON. The reason for that
is that YAMON used to set the pcnet device to SRAM mode but u-boot does
not. As a result, the default Tx threshold (64 bytes) is now too small to
keep the fifo relatively used and it can result to Tx fifo underflow errors.
As a result of which, it's best to setup the SRAM on supported controllers
so we can always use the NOUFLO bit.

Cc: <netdev@vger.kernel.org>
Cc: <stable@vger.kernel.org>
Cc: <linux-kernel@vger.kernel.org>
Cc: Don Fry <pcnet32@frontier.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Markos Chandras and committed by
David S. Miller
87f966d9 8e199dfd

+29 -2
+29 -2
drivers/net/ethernet/amd/pcnet32.c
··· 1543 1543 { 1544 1544 struct pcnet32_private *lp; 1545 1545 int i, media; 1546 - int fdx, mii, fset, dxsuflo; 1546 + int fdx, mii, fset, dxsuflo, sram; 1547 1547 int chip_version; 1548 1548 char *chipname; 1549 1549 struct net_device *dev; ··· 1580 1580 } 1581 1581 1582 1582 /* initialize variables */ 1583 - fdx = mii = fset = dxsuflo = 0; 1583 + fdx = mii = fset = dxsuflo = sram = 0; 1584 1584 chip_version = (chip_version >> 12) & 0xffff; 1585 1585 1586 1586 switch (chip_version) { ··· 1613 1613 chipname = "PCnet/FAST III 79C973"; /* PCI */ 1614 1614 fdx = 1; 1615 1615 mii = 1; 1616 + sram = 1; 1616 1617 break; 1617 1618 case 0x2626: 1618 1619 chipname = "PCnet/Home 79C978"; /* PCI */ ··· 1637 1636 chipname = "PCnet/FAST III 79C975"; /* PCI */ 1638 1637 fdx = 1; 1639 1638 mii = 1; 1639 + sram = 1; 1640 1640 break; 1641 1641 case 0x2628: 1642 1642 chipname = "PCnet/PRO 79C976"; ··· 1664 1662 a->write_csr(ioaddr, 80, 1665 1663 (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00); 1666 1664 dxsuflo = 1; 1665 + } 1666 + 1667 + /* 1668 + * The Am79C973/Am79C975 controllers come with 12K of SRAM 1669 + * which we can use for the Tx/Rx buffers but most importantly, 1670 + * the use of SRAM allow us to use the BCR18:NOUFLO bit to avoid 1671 + * Tx fifo underflows. 1672 + */ 1673 + if (sram) { 1674 + /* 1675 + * The SRAM is being configured in two steps. First we 1676 + * set the SRAM size in the BCR25:SRAM_SIZE bits. According 1677 + * to the datasheet, each bit corresponds to a 512-byte 1678 + * page so we can have at most 24 pages. The SRAM_SIZE 1679 + * holds the value of the upper 8 bits of the 16-bit SRAM size. 1680 + * The low 8-bits start at 0x00 and end at 0xff. So the 1681 + * address range is from 0x0000 up to 0x17ff. Therefore, 1682 + * the SRAM_SIZE is set to 0x17. The next step is to set 1683 + * the BCR26:SRAM_BND midway through so the Tx and Rx 1684 + * buffers can share the SRAM equally. 1685 + */ 1686 + a->write_bcr(ioaddr, 25, 0x17); 1687 + a->write_bcr(ioaddr, 26, 0xc); 1688 + /* And finally enable the NOUFLO bit */ 1689 + a->write_bcr(ioaddr, 18, a->read_bcr(ioaddr, 18) | (1 << 11)); 1667 1690 } 1668 1691 1669 1692 dev = alloc_etherdev(sizeof(*lp));