Untested, straight from the "release early" dept. You have been warned.

Realtek's driver restricts itself to 0x8169 and 0x8167.
It won't be surprising if it breaks on anything else until
I merge the new 0x8168 and 0x8136 bits.

Signed-off-by: Francois Romieu <[EMAIL PROTECTED]>
---
 drivers/net/r8169.c |  159 ++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 121 insertions(+), 38 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 577babd..2f320de 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -150,11 +150,13 @@ static const int multicast_filter_limit = 32;
 #define RTL_R32(reg)           ((unsigned long) readl (ioaddr + (reg)))
 
 enum mac_version {
-       RTL_GIGA_MAC_VER_01 = 0x00,
-       RTL_GIGA_MAC_VER_02 = 0x01,
-       RTL_GIGA_MAC_VER_03 = 0x02,
-       RTL_GIGA_MAC_VER_04 = 0x03,
-       RTL_GIGA_MAC_VER_05 = 0x04,
+       RTL_GIGA_MAC_VER_00 = 0x00,     // 8169
+       RTL_GIGA_MAC_VER_01 = 0x01,     // 8169S
+       RTL_GIGA_MAC_VER_02 = 0x02,     // 8110S
+       RTL_GIGA_MAC_VER_03 = 0x03,
+       RTL_GIGA_MAC_VER_04 = 0x04,     // 8169SB
+       RTL_GIGA_MAC_VER_05 = 0x05,     // 8169SCd
+       RTL_GIGA_MAC_VER_06 = 0x06,     // 8169SCe
        RTL_GIGA_MAC_VER_11 = 0x0b,
        RTL_GIGA_MAC_VER_12 = 0x0c,
        RTL_GIGA_MAC_VER_13 = 0x0d,
@@ -179,11 +181,13 @@ static const struct {
        u8 mac_version;
        u32 RxConfigMask;       /* Clears the bits supported by this chip */
 } rtl_chip_info[] = {
-       _R("RTL8169",           RTL_GIGA_MAC_VER_01, 0xff7e1880),
+       _R("RTL8169",           RTL_GIGA_MAC_VER_00, 0xff7e1880),
+       _R("RTL8169s/8110s",    RTL_GIGA_MAC_VER_01, 0xff7e1880),
        _R("RTL8169s/8110s",    RTL_GIGA_MAC_VER_02, 0xff7e1880),
-       _R("RTL8169s/8110s",    RTL_GIGA_MAC_VER_03, 0xff7e1880),
-       _R("RTL8169sb/8110sb",  RTL_GIGA_MAC_VER_04, 0xff7e1880),
+       _R("RTL8169sb/8110sb",  RTL_GIGA_MAC_VER_03, 0xff7e1880),
+       _R("RTL8169sc/8110sc",  RTL_GIGA_MAC_VER_04, 0xff7e1880),
        _R("RTL8169sc/8110sc",  RTL_GIGA_MAC_VER_05, 0xff7e1880),
+       _R("RTL8169sc/8110sc",  RTL_GIGA_MAC_VER_06, 0xff7e1880),
        _R("RTL8168b/8111b",    RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
        _R("RTL8168b/8111b",    RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
        _R("RTL8101e",          RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
@@ -231,6 +235,7 @@ static struct {
 
 enum RTL8169_registers {
        MAC0 = 0,               /* Ethernet hardware address. */
+       MAC4 = 4,
        MAR0 = 8,               /* Multicast filter. */
        CounterAddrLow = 0x10,
        CounterAddrHigh = 0x14,
@@ -322,6 +327,11 @@ enum RTL8169_register_content {
        /* Config1 register p.24 */
        PMEnable        = (1 << 0),     /* Power Management Enable */
 
+       /* Config2 register p. 25 */
+       PCI_Clock_66MHz = 0x01,
+       PCI_Clock_33MHz = 0x00,
+
+
        /* Config3 register p.25 */
        MagicPacket     = (1 << 5),     /* Wake up when receives a Magic Packet 
*/
        LinkUp          = (1 << 4),     /* Wake up when the cable connection is 
re-established */
@@ -1172,15 +1182,17 @@ static void rtl8169_get_mac_version(struct 
rtl8169_private *tp, void __iomem *io
                { 0x34000000,   RTL_GIGA_MAC_VER_13 },
                { 0x30800000,   RTL_GIGA_MAC_VER_14 },
                { 0x30000000,   RTL_GIGA_MAC_VER_11 },
+               { 0x98000000,   RTL_GIGA_MAC_VER_05 },
                { 0x18000000,   RTL_GIGA_MAC_VER_05 },
-               { 0x10000000,   RTL_GIGA_MAC_VER_04 },
-               { 0x04000000,   RTL_GIGA_MAC_VER_03 },
-               { 0x00800000,   RTL_GIGA_MAC_VER_02 },
-               { 0x00000000,   RTL_GIGA_MAC_VER_01 }   /* Catch-all */
+               { 0x18000000,   RTL_GIGA_MAC_VER_04 },
+               { 0x10000000,   RTL_GIGA_MAC_VER_03 },
+               { 0x04000000,   RTL_GIGA_MAC_VER_02 },
+               { 0x00800000,   RTL_GIGA_MAC_VER_01 },
+               { 0x00000000,   RTL_GIGA_MAC_VER_00 }   /* Catch-all */
        }, *p = mac_info;
        u32 reg;
 
-       reg = RTL_R32(TxConfig) & 0x7c800000;
+       reg = RTL_R32(TxConfig) & 0xfc800000;
        while ((reg & p->mask) != p->mask)
                p++;
        tp->mac_version = p->mac_version;
@@ -1273,7 +1285,7 @@ static void rtl8169_hw_phy_config(struct net_device *dev)
        rtl8169_print_mac_version(tp);
        rtl8169_print_phy_version(tp);
 
-       if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
+       if (tp->mac_version <= RTL_GIGA_MAC_VER_00)
                return;
        if (tp->phy_version >= RTL_GIGA_PHY_VER_H)
                return;
@@ -1283,7 +1295,7 @@ static void rtl8169_hw_phy_config(struct net_device *dev)
 
        /* Shazam ! */
 
-       if (tp->mac_version == RTL_GIGA_MAC_VER_04) {
+       if (tp->mac_version == RTL_GIGA_MAC_VER_03) {
                mdio_write(ioaddr, 31, 0x0002);
                mdio_write(ioaddr,  1, 0x90d0);
                mdio_write(ioaddr, 31, 0x0000);
@@ -1317,7 +1329,7 @@ static void rtl8169_phy_timer(unsigned long __opaque)
        void __iomem *ioaddr = tp->mmio_addr;
        unsigned long timeout = RTL8169_PHY_TIMEOUT;
 
-       assert(tp->mac_version > RTL_GIGA_MAC_VER_01);
+       assert(tp->mac_version > RTL_GIGA_MAC_VER_00);
        assert(tp->phy_version < RTL_GIGA_PHY_VER_H);
 
        if (!(tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL))
@@ -1353,7 +1365,7 @@ static inline void rtl8169_delete_timer(struct net_device 
*dev)
        struct rtl8169_private *tp = netdev_priv(dev);
        struct timer_list *timer = &tp->timer;
 
-       if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) ||
+       if ((tp->mac_version <= RTL_GIGA_MAC_VER_00) ||
            (tp->phy_version >= RTL_GIGA_PHY_VER_H))
                return;
 
@@ -1365,7 +1377,7 @@ static inline void rtl8169_request_timer(struct 
net_device *dev)
        struct rtl8169_private *tp = netdev_priv(dev);
        struct timer_list *timer = &tp->timer;
 
-       if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) ||
+       if ((tp->mac_version <= RTL_GIGA_MAC_VER_00) ||
            (tp->phy_version >= RTL_GIGA_PHY_VER_H))
                return;
 
@@ -1432,12 +1444,14 @@ static void rtl8169_init_phy(struct net_device *dev, 
struct rtl8169_private *tp)
        dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
        RTL_W8(0x82, 0x01);
 
-       if (tp->mac_version < RTL_GIGA_MAC_VER_03) {
+       if (tp->mac_version < RTL_GIGA_MAC_VER_02) {
                dprintk("Set PCI Latency=0x40\n");
                pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
        }
 
-       if (tp->mac_version == RTL_GIGA_MAC_VER_02) {
+       pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+       if (tp->mac_version == RTL_GIGA_MAC_VER_01) {
                dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
                RTL_W8(0x82, 0x01);
                dprintk("Set PHY Reg 0x0bh = 0x00h\n");
@@ -1454,6 +1468,36 @@ static void rtl8169_init_phy(struct net_device *dev, 
struct rtl8169_private *tp)
                printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
 }
 
+static void rtl8169_rar_set(struct rtl8169_private *tp, u8 *addr)
+{
+       void __iomem *ioaddr = tp->mmio_addr;
+       u32 low;
+       u32 high;
+
+       low  = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
+       high = addr[4] | (addr[5] << 8);
+
+       RTL_W8(Cfg9346, Cfg9346_Unlock);
+       RTL_W32(MAC0, low);
+       RTL_W32(MAC4, high);
+       RTL_W8(Cfg9346, Cfg9346_Lock);
+}
+
+static int rtl8169_set_mac_address(struct net_device *dev, void *p)
+{
+       struct rtl8169_private *tp = netdev_priv(dev);
+       struct sockaddr *addr = p;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+       rtl8169_rar_set(tp, dev->dev_addr);
+
+       return 0;
+}
+
 static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
@@ -1665,6 +1709,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct 
pci_device_id *ent)
        dev->irq = pdev->irq;
        dev->base_addr = (unsigned long) ioaddr;
        dev->change_mtu = rtl8169_change_mtu;
+       dev->set_mac_address = rtl8169_set_mac_address;
 
 #ifdef CONFIG_R8169_NAPI
        dev->poll = rtl8169_poll;
@@ -1825,6 +1870,41 @@ static void rtl8169_set_rx_tx_config_registers(struct 
rtl8169_private *tp)
                (InterFrameGap << TxInterFrameGapShift));
 }
 
+static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
+{
+       struct {
+               u32 mac_version;
+               u32 clk66;
+               u32 val;
+       } cfg2_info [] = {
+               { RTL_GIGA_MAC_VER_05, 0, 0x000fff00 },
+               { RTL_GIGA_MAC_VER_05, 1, 0x000fffff },
+               { RTL_GIGA_MAC_VER_06, 0, 0x00ffffff },
+               { RTL_GIGA_MAC_VER_06, 1, 0x00ffff00 }
+       }, *p = cfg2_info;
+       unsigned int i;
+       u32 clk66;
+
+       clk66 = RTL_R8(Config2) & PCI_Clock_66MHz;
+       for (i = 0; i < ARRAY_SIZE(cfg2_info); i++) {
+               if ((p->mac_version == mac_version) && (p->clk66 == clk66)) {
+                       RTL_W32(0x7c, p->val);
+                       break;
+               }
+       }
+}
+
+static bool rtl8169_plain_old_8169(unsigned int mac_version)
+{
+       return ((mac_version == RTL_GIGA_MAC_VER_00) ||
+               (mac_version == RTL_GIGA_MAC_VER_01) ||
+               (mac_version == RTL_GIGA_MAC_VER_02) ||
+               (mac_version == RTL_GIGA_MAC_VER_03) || // FIXME: remove ?
+               (mac_version == RTL_GIGA_MAC_VER_04) ||
+               (mac_version == RTL_GIGA_MAC_VER_05) ||
+               (mac_version == RTL_GIGA_MAC_VER_06)) ? true : false;
+}
+
 static void rtl8169_hw_start(struct net_device *dev)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
@@ -1843,10 +1923,8 @@ static void rtl8169_hw_start(struct net_device *dev)
                msleep_interruptible(1);
        }
 
-       if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
+       if (tp->mac_version == RTL_GIGA_MAC_VER_04)
                RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW);
-               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08);
-       }
 
        if (tp->mac_version == RTL_GIGA_MAC_VER_13) {
                pci_write_config_word(pdev, 0x68, 0x00);
@@ -1854,7 +1932,7 @@ static void rtl8169_hw_start(struct net_device *dev)
        }
 
        /* Undocumented stuff. */
-       if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
+       if (tp->mac_version == RTL_GIGA_MAC_VER_04) {
                /* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */
                if ((RTL_R8(Config2) & 0x07) & 0x01)
                        RTL_W32(0x7c, 0x0007ffff);
@@ -1867,10 +1945,8 @@ static void rtl8169_hw_start(struct net_device *dev)
        }
 
        RTL_W8(Cfg9346, Cfg9346_Unlock);
-       if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_04))
+
+       if (rtl8169_plain_old_8169(tp->mac_version))
                RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
 
        RTL_W8(EarlyTxThres, EarlyTxThld);
@@ -1878,10 +1954,7 @@ static void rtl8169_hw_start(struct net_device *dev)
        /* Low hurts. Let's disable the filtering. */
        RTL_W16(RxMaxSize, 16383);
 
-       if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_04))
+       if (rtl8169_plain_old_8169(tp->mac_version))
                rtl8169_set_rx_tx_config_registers(tp);
 
        cmd = RTL_R16(CPlusCmd);
@@ -1889,8 +1962,10 @@ static void rtl8169_hw_start(struct net_device *dev)
 
        tp->cp_cmd |= cmd | PCIMulRW;
 
-       if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
+       rtl8169_set_magic_reg(ioaddr, tp->mac_version);
+
+       if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
+           (tp->mac_version == RTL_GIGA_MAC_VER_02)) {
                dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0. "
                        "Bit-3 and bit-14 MUST be 1\n");
                tp->cp_cmd |= (1 << 14);
@@ -1914,10 +1989,7 @@ static void rtl8169_hw_start(struct net_device *dev)
        RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32));
        RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK));
 
-       if ((tp->mac_version != RTL_GIGA_MAC_VER_01) &&
-           (tp->mac_version != RTL_GIGA_MAC_VER_02) &&
-           (tp->mac_version != RTL_GIGA_MAC_VER_03) &&
-           (tp->mac_version != RTL_GIGA_MAC_VER_04)) {
+       if (!rtl8169_plain_old_8169(tp->mac_version)) {
                RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
                rtl8169_set_rx_tx_config_registers(tp);
        }
@@ -1937,6 +2009,9 @@ static void rtl8169_hw_start(struct net_device *dev)
        /* Enable all known interrupts by setting the interrupt mask. */
        RTL_W16(IntrMask, rtl8169_intr_mask);
 
+       if (rtl8169_plain_old_8169(tp->mac_version))
+               RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+
        netif_start_queue(dev);
 }
 
@@ -2582,6 +2657,14 @@ rtl8169_rx_interrupt(struct net_device *dev, struct 
rtl8169_private *tp,
                        tp->stats.rx_bytes += pkt_size;
                        tp->stats.rx_packets++;
                }
+
+               /* Work around for AMD plateform. */
+               if ((desc->opts2 & 0xfffe000) &&
+                   (tp->mac_version == RTL_GIGA_MAC_VER_05)) {
+                       desc->opts2 = 0;
+                       cur_rx++;
+               }
+
        }
 
        count = cur_rx - tp->cur_rx;
-- 
1.4.4.4

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to