]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/skge.c
[PATCH] skge: support yukon lite rev 4
[karo-tx-linux.git] / drivers / net / skge.c
index 5cacc7ad9e79a9f8505b7dbb34a59604293b4601..0857be8f99f25b5d36a4c013af080e65faf2612d 100644 (file)
@@ -75,7 +75,6 @@ static const struct pci_device_id skge_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B) },
        { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) },
        { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) },
-       { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx  */
        { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */
@@ -669,14 +668,13 @@ static void skge_blink_timer(unsigned long data)
 {
        struct skge_port *skge = (struct skge_port *) data;
        struct skge_hw *hw = skge->hw;
-       unsigned long flags;
 
-       spin_lock_irqsave(&hw->phy_lock, flags);
+       spin_lock_bh(&hw->phy_lock);
        if (skge->blink_on)
                skge_led_on(hw, skge->port);
        else
                skge_led_off(hw, skge->port);
-       spin_unlock_irqrestore(&hw->phy_lock, flags);
+       spin_unlock_bh(&hw->phy_lock);
 
        skge->blink_on = !skge->blink_on;
        mod_timer(&skge->led_blink, jiffies + BLINK_HZ);
@@ -1209,7 +1207,6 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
         * namely for the 1000baseTX cards that use the XMAC's
         * GMII mode.
         */
-       spin_lock_bh(&hw->phy_lock);
        /* Take external Phy out of reset */
        r = skge_read32(hw, B2_GP_IO);
        if (port == 0)
@@ -1219,7 +1216,6 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
 
        skge_write32(hw, B2_GP_IO, r);
        skge_read32(hw, B2_GP_IO);
-       spin_unlock_bh(&hw->phy_lock);
 
        /* Enable GMII interfac */
        xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
@@ -1691,7 +1687,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
 
        /* WA code for COMA mode -- set PHY reset */
        if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-           hw->chip_rev == CHIP_REV_YU_LITE_A3)
+           hw->chip_rev >= CHIP_REV_YU_LITE_A3)
                skge_write32(hw, B2_GP_IO,
                             (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9));
 
@@ -1701,7 +1697,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
 
        /* WA code for COMA mode -- clear PHY reset */
        if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-           hw->chip_rev == CHIP_REV_YU_LITE_A3)
+           hw->chip_rev >= CHIP_REV_YU_LITE_A3)
                skge_write32(hw, B2_GP_IO,
                             (skge_read32(hw, B2_GP_IO) | GP_DIR_9)
                             & ~GP_IO_9);
@@ -1745,9 +1741,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
        gma_write16(hw, port, GM_GP_CTRL, reg);
        skge_read16(hw, GMAC_IRQ_SRC);
 
-       spin_lock_bh(&hw->phy_lock);
        yukon_init(hw, port);
-       spin_unlock_bh(&hw->phy_lock);
 
        /* MIB clear */
        reg = gma_read16(hw, port, GM_PHY_ADDR);
@@ -1796,7 +1790,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
        skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK);
        reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
        if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-           hw->chip_rev == CHIP_REV_YU_LITE_A3)
+           hw->chip_rev >= CHIP_REV_YU_LITE_A3)
                reg &= ~GMF_RX_F_FL_ON;
        skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
        skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg);
@@ -1813,14 +1807,14 @@ static void yukon_stop(struct skge_port *skge)
        int port = skge->port;
 
        if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-           hw->chip_rev == CHIP_REV_YU_LITE_A3) {
+           hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
                skge_write32(hw, B2_GP_IO,
                             skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9);
        }
 
        gma_write16(hw, port, GM_GP_CTRL,
                         gma_read16(hw, port, GM_GP_CTRL)
-                        & ~(GM_GPCR_RX_ENA|GM_GPCR_RX_ENA));
+                        & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
        gma_read16(hw, port, GM_GP_CTRL);
 
        /* set GPHY Control reset */
@@ -2097,10 +2091,12 @@ static int skge_up(struct net_device *dev)
        skge_write32(hw, B0_IMSK, hw->intr_mask);
 
        /* Initialze MAC */
+       spin_lock_bh(&hw->phy_lock);
        if (hw->chip_id == CHIP_ID_GENESIS)
                genesis_mac_init(hw, port);
        else
                yukon_mac_init(hw, port);
+       spin_unlock_bh(&hw->phy_lock);
 
        /* Configure RAMbuffers */
        chunk = hw->ram_size / ((hw->ports + 1)*2);
@@ -2633,11 +2629,17 @@ static inline void skge_tx_intr(struct net_device *dev)
        spin_unlock(&skge->tx_lock);
 }
 
+/* Parity errors seem to happen when Genesis is connected to a switch
+ * with no other ports present. Heartbeat error??
+ */
 static void skge_mac_parity(struct skge_hw *hw, int port)
 {
-       printk(KERN_ERR PFX "%s: mac data parity error\n",
-              hw->dev[port] ? hw->dev[port]->name
-              : (port == 0 ? "(port A)": "(port B"));
+       struct net_device *dev = hw->dev[port];
+
+       if (dev) {
+               struct skge_port *skge = netdev_priv(dev);
+               ++skge->net_stats.tx_heartbeat_errors;
+       }
 
        if (hw->chip_id == CHIP_ID_GENESIS)
                skge_write16(hw, SK_REG(port, TX_MFF_CTRL1),