aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-05-18 14:16:21 -0400
committerJeff Garzik <jeff@garzik.org>2006-05-20 00:15:39 -0400
commitee7abb04df92b444069be8fe47d66d809de23782 (patch)
treeb96478a17f08aed0955ea6fba06cc9dde8f517fe
parent38bb6b288bf4fb954a3793e57c7339774c842a54 (diff)
[PATCH] sky2: allow dual port usage
If both ports are receiving on the SysKonnect dual port cards, then it appears the bus interface unit can give an interrupt status for frame before DMA has completed. This leads to bogus frames and general confusion. This is why receive checksumming is also messed up on dual port cards. A workaround for the out of order receive problem is to eliminating split transactions on PCI-X. This version is based of the current linux-2.6.git including earlier patch to disable dual ports. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/sky2.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 62be6d99d05..277c57b3df9 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1020,19 +1020,26 @@ static int sky2_up(struct net_device *dev)
1020 struct sky2_hw *hw = sky2->hw; 1020 struct sky2_hw *hw = sky2->hw;
1021 unsigned port = sky2->port; 1021 unsigned port = sky2->port;
1022 u32 ramsize, rxspace, imask; 1022 u32 ramsize, rxspace, imask;
1023 int err; 1023 int cap, err = -ENOMEM;
1024 struct net_device *otherdev = hw->dev[sky2->port^1]; 1024 struct net_device *otherdev = hw->dev[sky2->port^1];
1025 1025
1026 /* Block bringing up both ports at the same time on a dual port card. 1026 /*
1027 * There is an unfixed bug where receiver gets confused and picks up 1027 * On dual port PCI-X card, there is an problem where status
1028 * packets out of order. Until this is fixed, prevent data corruption. 1028 * can be received out of order due to split transactions
1029 */ 1029 */
1030 if (otherdev && netif_running(otherdev)) { 1030 if (otherdev && netif_running(otherdev) &&
1031 printk(KERN_INFO PFX "dual port support is disabled.\n"); 1031 (cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) {
1032 return -EBUSY; 1032 struct sky2_port *osky2 = netdev_priv(otherdev);
1033 } 1033 u16 cmd;
1034
1035 cmd = sky2_pci_read16(hw, cap + PCI_X_CMD);
1036 cmd &= ~PCI_X_CMD_MAX_SPLIT;
1037 sky2_pci_write16(hw, cap + PCI_X_CMD, cmd);
1038
1039 sky2->rx_csum = 0;
1040 osky2->rx_csum = 0;
1041 }
1034 1042
1035 err = -ENOMEM;
1036 if (netif_msg_ifup(sky2)) 1043 if (netif_msg_ifup(sky2))
1037 printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); 1044 printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
1038 1045
@@ -3078,12 +3085,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
3078 sky2->duplex = -1; 3085 sky2->duplex = -1;
3079 sky2->speed = -1; 3086 sky2->speed = -1;
3080 sky2->advertising = sky2_supported_modes(hw); 3087 sky2->advertising = sky2_supported_modes(hw);
3081 3088 sky2->rx_csum = 1;
3082 /* Receive checksum disabled for Yukon XL
3083 * because of observed problems with incorrect
3084 * values when multiple packets are received in one interrupt
3085 */
3086 sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
3087 3089
3088 spin_lock_init(&sky2->phy_lock); 3090 spin_lock_init(&sky2->phy_lock);
3089 sky2->tx_pending = TX_DEF_PENDING; 3091 sky2->tx_pending = TX_DEF_PENDING;