Commit 8fa143ef authored by Roger Luethi's avatar Roger Luethi Committed by Jeff Garzik

[netdrvr via-rhine] various duplex-related fixes:

Fix the following bugs:
- after a watchdog timeout (still a common thing with the Rhine), the
  driver will fall back to half-duplex, ignoring the auto-negotiation
  results, killing performance completely until the driver is reloaded;
  fixed by clearing full_duplex in init_registers()
- driver considers only 0x200 for full-duplex option; now 0x220
- duplex code used dev->name before it's initialized; code section moved

The full_duplex and force_media related code is quite a mess, but this
minimal fix will make the most annoying problems go away. Looking at some
other code (e.g. mii.c) it seems to me the interaction between user force,
autoneg results and full_duplex/force_media is amazingly complex, so I'll
leave it at this for now.
parent 763a4ff3
...@@ -726,21 +726,6 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev, ...@@ -726,21 +726,6 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev,
if (dev->mem_start) if (dev->mem_start)
option = dev->mem_start; option = dev->mem_start;
/* The lower four bits are the media type. */
if (option > 0) {
if (option & 0x200)
np->mii_if.full_duplex = 1;
np->default_port = option & 15;
}
if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
np->mii_if.full_duplex = 1;
if (np->mii_if.full_duplex) {
printk(KERN_INFO "%s: Set to forced full duplex, autonegotiation"
" disabled.\n", dev->name);
np->mii_if.force_media = 1;
}
/* The chip-specific entries in the device structure. */ /* The chip-specific entries in the device structure. */
dev->open = via_rhine_open; dev->open = via_rhine_open;
dev->hard_start_xmit = via_rhine_start_tx; dev->hard_start_xmit = via_rhine_start_tx;
...@@ -753,10 +738,26 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev, ...@@ -753,10 +738,26 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev,
if (np->drv_flags & ReqTxAlign) if (np->drv_flags & ReqTxAlign)
dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM; dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
/* dev->name not defined before register_netdev()! */
i = register_netdev(dev); i = register_netdev(dev);
if (i) if (i)
goto err_out_unmap; goto err_out_unmap;
/* The lower four bits are the media type. */
if (option > 0) {
if (option & 0x220)
np->mii_if.full_duplex = 1;
np->default_port = option & 15;
}
if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
np->mii_if.full_duplex = 1;
if (np->mii_if.full_duplex) {
printk(KERN_INFO "%s: Set to forced full duplex, autonegotiation"
" disabled.\n", dev->name);
np->mii_if.force_media = 1;
}
printk(KERN_INFO "%s: %s at 0x%lx, ", printk(KERN_INFO "%s: %s at 0x%lx, ",
dev->name, via_rhine_chip_info[chip_id].name, dev->name, via_rhine_chip_info[chip_id].name,
(pci_flags & PCI_USES_IO) ? ioaddr : memaddr); (pci_flags & PCI_USES_IO) ? ioaddr : memaddr);
...@@ -992,6 +993,7 @@ static void init_registers(struct net_device *dev) ...@@ -992,6 +993,7 @@ static void init_registers(struct net_device *dev)
writeb(0x20, ioaddr + TxConfig); writeb(0x20, ioaddr + TxConfig);
np->tx_thresh = 0x20; np->tx_thresh = 0x20;
np->rx_thresh = 0x60; /* Written in via_rhine_set_rx_mode(). */ np->rx_thresh = 0x60; /* Written in via_rhine_set_rx_mode(). */
np->mii_if.full_duplex = 0;
if (dev->if_port == 0) if (dev->if_port == 0)
dev->if_port = np->default_port; dev->if_port = np->default_port;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment