diff -urN -X /home/jgarzik/dontdiff /home/jgarzik/tmp/linux-2.4.11-pre6/drivers/net/sis900.c linux_2_4/drivers/net/sis900.c --- /home/jgarzik/tmp/linux-2.4.11-pre6/drivers/net/sis900.c Tue Oct 9 00:03:54 2001 +++ linux_2_4/drivers/net/sis900.c Tue Oct 9 03:06:00 2001 @@ -1,6 +1,6 @@ /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux. Copyright 1999 Silicon Integrated System Corporation - Revision: 1.08.00 Jun. 11 2001 + Revision: 1.08.01 Aug. 25 2001 Modified from the driver which is originally written by Donald Becker. @@ -18,8 +18,9 @@ preliminary Rev. 1.0 Jan. 18, 1998 http://www.sis.com.tw/support/databook.htm + Rev 1.08.01 Aug. 25 2001 Hui-Fen Hsu update for 630ET & workaround for ICS1893 PHY Rev 1.08.00 Jun. 11 2001 Hui-Fen Hsu workaround for RTL8201 PHY and some bug fix - Rev 1.07.11 Apr. 2 2001 Hui-Fen Hsu updates PCI drivers to use the new pci_set_dma_mask for kernel 2.4.3 + Rev 1.07.11 Apr. 2 2001 Hui-Fen Hsu updates PCI drivers to use the new pci_set_dma_mask for kernel 2.4.3 Rev 1.07.10 Mar. 1 2001 Hui-Fen Hsu some bug fix & 635M/B support Rev 1.07.09 Feb. 9 2001 Dave Jones PCI enable cleanup Rev 1.07.08 Jan. 8 2001 Lei-Chun Chang added RTL8201 PHY support @@ -65,7 +66,7 @@ #include "sis900.h" static char version[] __devinitdata = -KERN_INFO "sis900.c: v1.08.00 6/11/2001\n"; +KERN_INFO "sis900.c: v1.08.01 9/25/2001\n"; static int max_interrupt_work = 40; static int multicast_filter_limit = 128; @@ -406,8 +407,12 @@ ret = -ENODEV; goto err_out_unregister; } + + /* 630ET : set the mii access mode as software-mode */ + if (revision == SIS630ET_900_REV) + outl(ACCESSMODE | inl(ioaddr + cr), ioaddr + cr); - /* probe for mii transciver */ + /* probe for mii transceiver */ if (sis900_mii_probe(net_dev) == 0) { ret = -ENODEV; goto err_out_unregister; @@ -515,6 +520,11 @@ if ((sis_priv->mii->phy_id0 == 0x001D) && ((sis_priv->mii->phy_id1&0xFFF0) == 0x8000)) status = sis900_reset_phy(net_dev, sis_priv->cur_phy); + + /* workaround for ICS1893 PHY */ + if ((sis_priv->mii->phy_id0 == 0x0015) && + ((sis_priv->mii->phy_id1&0xFFF0) == 0xF440)) + mdio_write(net_dev, sis_priv->cur_phy, 0x0018, 0xD200); if(status & MII_STAT_LINK){ while (poll_bit) { @@ -862,7 +872,7 @@ /* Enable all known interrupts by setting the interrupt mask. */ outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr); - outl(RxENA, ioaddr + cr); + outl(RxENA | inl(ioaddr + cr), ioaddr + cr); outl(IE, ioaddr + ier); sis900_check_mode(net_dev, sis_priv->mii); @@ -1039,7 +1049,7 @@ struct pci_dev *dev=NULL; if ( !(revision == SIS630E_900_REV || revision == SIS630EA1_900_REV || - revision == SIS630A_900_REV) ) + revision == SIS630A_900_REV || revision == SIS630ET_900_REV) ) return; dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, dev); @@ -1057,7 +1067,8 @@ min_value=(eq_value < min_value) ? eq_value : min_value; } /* 630E rule to determine the equalizer value */ - if (revision == SIS630E_900_REV || revision == SIS630EA1_900_REV) { + if (revision == SIS630E_900_REV || revision == SIS630EA1_900_REV || + revision == SIS630ET_900_REV) { if (max_value < 5) eq_value=max_value; else if (max_value >= 5 && max_value < 15) @@ -1373,7 +1384,7 @@ net_dev->trans_start = jiffies; /* FIXME: Should we restart the transmission thread here ?? */ - outl(TxENA, ioaddr + cr); + outl(TxENA | inl(ioaddr + cr), ioaddr + cr); /* Enable all known interrupts by setting the interrupt mask. */ outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr); @@ -1408,7 +1419,7 @@ sis_priv->tx_ring[entry].bufptr = pci_map_single(sis_priv->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE); sis_priv->tx_ring[entry].cmdsts = (OWN | skb->len); - outl(TxENA, ioaddr + cr); + outl(TxENA | inl(ioaddr + cr), ioaddr + cr); if (++sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC) { /* Typical path, tell upper layer that more transmission is possible */ @@ -1624,7 +1635,7 @@ } } /* re-enable the potentially idle receive state matchine */ - outl(RxENA , ioaddr + cr ); + outl(RxENA | inl(ioaddr + cr), ioaddr + cr ); return 0; } @@ -1722,7 +1733,7 @@ outl(0x0000, ioaddr + ier); /* Stop the chip's Tx and Rx Status Machine */ - outl(RxDIS | TxDIS, ioaddr + cr); + outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr); del_timer(&sis_priv->timer); @@ -2038,7 +2049,7 @@ outl(0, ioaddr + imr); outl(0, ioaddr + rfcr); - outl(RxRESET | TxRESET | RESET, ioaddr + cr); + outl(RxRESET | TxRESET | RESET | inl(ioaddr + cr), ioaddr + cr); /* Check that the chip has finished the reset. */ while (status && (i++ < 1000)) { diff -urN -X /home/jgarzik/dontdiff /home/jgarzik/tmp/linux-2.4.11-pre6/drivers/net/sis900.h linux_2_4/drivers/net/sis900.h --- /home/jgarzik/tmp/linux-2.4.11-pre6/drivers/net/sis900.h Tue Jul 17 21:53:55 2001 +++ linux_2_4/drivers/net/sis900.h Tue Oct 9 03:06:00 2001 @@ -41,7 +41,7 @@ /* Symbolic names for bits in various registers */ enum sis900_command_register_bits { - RELOAD = 0x00000400, + RELOAD = 0x00000400, ACCESSMODE = 0x00000200,/* ET */ RESET = 0x00000100, SWI = 0x00000080, RxRESET = 0x00000020, TxRESET = 0x00000010, RxDIS = 0x00000008, RxENA = 0x00000004, TxDIS = 0x00000002, TxENA = 0x00000001 @@ -239,7 +239,8 @@ enum sis900_revision_id { SIS630A_900_REV = 0x80, SIS630E_900_REV = 0x81, SIS630S_900_REV = 0x82, SIS630EA1_900_REV = 0x83, - SIS635A_900_REV = 0x90, SIS900B_900_REV = 0x03 + SIS630ET_900_REV = 0x84, SIS635A_900_REV = 0x90, + SIS900B_900_REV = 0x03 }; enum sis630_revision_id {