netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/12] r8169: add per-device hw_start handler (1/2)
       [not found] <20070426205714.GA12701@electric-eye.fr.zoreil.com>
@ 2007-04-26 21:47 ` Francois Romieu
  2007-04-26 21:48 ` [PATCH 02/12] r8169: add per-device hw_start handler (2/2) Francois Romieu
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Francois Romieu @ 2007-04-26 21:47 UTC (permalink / raw)
  To: jeff; +Cc: netdev, Edward Hsu

rtl8169_hw_start will not help maintaining an unified driver for
different chipsets but people at Realtek are probably too polite
to say it distinctly.

Part 1: add the hook and keep hw_start handler unchanged.

As can be seen from the content of rtl8169_pci_tbl, the RTL_CFG_1
entry in rtl_cfg_info was unused. I recycled it for the 0x8168.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Edward Hsu <edward_hsu@realtek.com>
---
 drivers/net/r8169.c |   68 +++++++++++++++++++++++++++++++++++---------------
 1 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 6a77b8a..ba8e04c 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -199,20 +199,25 @@ enum cfg_version {
 	RTL_CFG_2
 };
 
+static void rtl_hw_start_8169(struct net_device *);
+static void rtl_hw_start_8168(struct net_device *);
+static void rtl_hw_start_8101(struct net_device *);
+
 static const struct {
+	void (*hw_start)(struct net_device *);
 	unsigned int region;
 	unsigned int align;
 } rtl_cfg_info[] = {
-	[RTL_CFG_0] = { 1, NET_IP_ALIGN },
-	[RTL_CFG_1] = { 2, NET_IP_ALIGN },
-	[RTL_CFG_2] = { 2, 8 }
+	[RTL_CFG_0] = { rtl_hw_start_8169, 1, NET_IP_ALIGN },
+	[RTL_CFG_1] = { rtl_hw_start_8168, 2, 8 },
+	[RTL_CFG_2] = { rtl_hw_start_8101, 2, 8 }
 };
 
 static struct pci_device_id rtl8169_pci_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8129), 0, 0, RTL_CFG_0 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8136), 0, 0, RTL_CFG_2 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8167), 0, 0, RTL_CFG_0 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8168), 0, 0, RTL_CFG_2 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8168), 0, 0, RTL_CFG_1 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), 0, 0, RTL_CFG_0 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), 0, 0, RTL_CFG_0 },
 	{ PCI_DEVICE(0x1259,			0xc107), 0, 0, RTL_CFG_0 },
@@ -455,6 +460,7 @@ struct rtl8169_private {
 	int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
 	void (*get_settings)(struct net_device *, struct ethtool_cmd *);
 	void (*phy_reset_enable)(void __iomem *);
+	void (*hw_start)(struct net_device *);
 	unsigned int (*phy_reset_pending)(void __iomem *);
 	unsigned int (*link_ok)(void __iomem *);
 	struct delayed_work task;
@@ -478,9 +484,9 @@ static int rtl8169_open(struct net_device *dev);
 static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance);
 static int rtl8169_init_ring(struct net_device *dev);
-static void rtl8169_hw_start(struct net_device *dev);
+static void rtl_hw_start(struct net_device *dev);
 static int rtl8169_close(struct net_device *dev);
-static void rtl8169_set_rx_mode(struct net_device *dev);
+static void rtl_set_rx_mode(struct net_device *dev);
 static void rtl8169_tx_timeout(struct net_device *dev);
 static struct net_device_stats *rtl8169_get_stats(struct net_device *dev);
 static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
@@ -1657,7 +1663,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
 	dev->stop = rtl8169_close;
 	dev->tx_timeout = rtl8169_tx_timeout;
-	dev->set_multicast_list = rtl8169_set_rx_mode;
+	dev->set_multicast_list = rtl_set_rx_mode;
 	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
 	dev->irq = pdev->irq;
 	dev->base_addr = (unsigned long) ioaddr;
@@ -1687,6 +1693,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	tp->timer.data = (unsigned long) dev;
 	tp->timer.function = rtl8169_phy_timer;
 
+	tp->hw_start = rtl_cfg_info[ent->driver_data].hw_start;
+
 	spin_lock_init(&tp->lock);
 
 	rc = register_netdev(dev);
@@ -1785,7 +1793,7 @@ static int rtl8169_open(struct net_device *dev)
 	if (retval < 0)
 		goto err_release_ring_2;
 
-	rtl8169_hw_start(dev);
+	rtl_hw_start(dev);
 
 	rtl8169_request_timer(dev);
 
@@ -1829,24 +1837,38 @@ static void rtl8169_set_rx_tx_config_registers(struct rtl8169_private *tp)
 		(InterFrameGap << TxInterFrameGapShift));
 }
 
-static void rtl8169_hw_start(struct net_device *dev)
+static void rtl_hw_start(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
-	struct pci_dev *pdev = tp->pci_dev;
-	u16 cmd;
-	u32 i;
+	unsigned int i;
 
 	/* Soft reset the chip. */
 	RTL_W8(ChipCmd, CmdReset);
 
 	/* Check that the chip has finished the reset. */
-	for (i = 100; i > 0; i--) {
+	for (i = 0; i < 100; i++) {
 		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
 			break;
 		msleep_interruptible(1);
 	}
 
+	tp->hw_start(dev);
+
+	/* Enable all known interrupts by setting the interrupt mask. */
+	RTL_W16(IntrMask, rtl8169_intr_mask);
+
+	netif_start_queue(dev);
+}
+
+
+static void rtl_hw_start_8169(struct net_device *dev)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void __iomem *ioaddr = tp->mmio_addr;
+	struct pci_dev *pdev = tp->pci_dev;
+	u16 cmd;
+
 	if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
 		RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW);
 		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08);
@@ -1933,15 +1955,20 @@ static void rtl8169_hw_start(struct net_device *dev)
 
 	RTL_W32(RxMissed, 0);
 
-	rtl8169_set_rx_mode(dev);
+	rtl_set_rx_mode(dev);
 
 	/* no early-rx interrupts */
 	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
+}
 
-	/* Enable all known interrupts by setting the interrupt mask. */
-	RTL_W16(IntrMask, rtl8169_intr_mask);
+static void rtl_hw_start_8168(struct net_device *dev)
+{
+	rtl_hw_start_8169(dev);
+}
 
-	netif_start_queue(dev);
+static void rtl_hw_start_8101(struct net_device *dev)
+{
+	rtl_hw_start_8169(dev);
 }
 
 static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
@@ -1967,7 +1994,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
 
 	netif_poll_enable(dev);
 
-	rtl8169_hw_start(dev);
+	rtl_hw_start(dev);
 
 	rtl8169_request_timer(dev);
 
@@ -2209,7 +2236,7 @@ static void rtl8169_reset_task(struct work_struct *work)
 
 	if (tp->dirty_rx == tp->cur_rx) {
 		rtl8169_init_ring_indexes(tp);
-		rtl8169_hw_start(dev);
+		rtl_hw_start(dev);
 		netif_wake_queue(dev);
 	} else {
 		if (net_ratelimit()) {
@@ -2801,8 +2828,7 @@ static int rtl8169_close(struct net_device *dev)
 	return 0;
 }
 
-static void
-rtl8169_set_rx_mode(struct net_device *dev)
+static void rtl_set_rx_mode(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
-- 
1.4.4.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 02/12] r8169: add per-device hw_start handler (2/2)
       [not found] <20070426205714.GA12701@electric-eye.fr.zoreil.com>
  2007-04-26 21:47 ` [PATCH 01/12] r8169: add per-device hw_start handler (1/2) Francois Romieu
@ 2007-04-26 21:48 ` Francois Romieu
  2007-04-26 21:48 ` [PATCH 03/12] r8169: merge with version 6.001.00 of Realtek's r8169 driver Francois Romieu
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Francois Romieu @ 2007-04-26 21:48 UTC (permalink / raw)
  To: jeff; +Cc: netdev, Edward Hsu

Part 2: populate the hw_start handlers for the 8168 and the 8101.

- annotate mac_version
- factor out the initialization of the receive and transmit ring
  descriptor registers (rtl_set_rx_tx_desc_registers)
- access to the CPlusCmd and setting of the maximum receive size are
  idiomatic too (rtl_rw_cpluscmd and rtl_set_rx_max_size)

Each chipset should run through the same code as before in its
dedicated hw_start handler.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Edward Hsu <edward_hsu@realtek.com>
---
 drivers/net/r8169.c |  154 +++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 114 insertions(+), 40 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index ba8e04c..05408f3 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -151,16 +151,16 @@ 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_11 = 0x0b,
-	RTL_GIGA_MAC_VER_12 = 0x0c,
-	RTL_GIGA_MAC_VER_13 = 0x0d,
-	RTL_GIGA_MAC_VER_14 = 0x0e,
-	RTL_GIGA_MAC_VER_15 = 0x0f
+	RTL_GIGA_MAC_VER_01 = 0x01, // 8169
+	RTL_GIGA_MAC_VER_02 = 0x02, // 8169S
+	RTL_GIGA_MAC_VER_03 = 0x03, // 8110S
+	RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
+	RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
+	RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
+	RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be 8168Bf
+	RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb 8101Ec
+	RTL_GIGA_MAC_VER_14 = 0x0e, // 8101
+	RTL_GIGA_MAC_VER_15 = 0x0f  // 8101
 };
 
 enum phy_version {
@@ -180,11 +180,11 @@ 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("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("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_05, 0xff7e1880),
+	_R("RTL8169",		RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169
+	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S
+	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S
+	_R("RTL8169sb/8110sb",	RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
+	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
 	_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
@@ -1824,7 +1824,7 @@ static void rtl8169_hw_reset(void __iomem *ioaddr)
 	RTL_R8(ChipCmd);
 }
 
-static void rtl8169_set_rx_tx_config_registers(struct rtl8169_private *tp)
+static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
 	u32 cfg = rtl8169_rx_config;
@@ -1862,6 +1862,35 @@ static void rtl_hw_start(struct net_device *dev)
 }
 
 
+static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp,
+					 void __iomem *ioaddr)
+{
+	/*
+	 * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh
+	 * register to be written before TxDescAddrLow to work.
+	 * Switching from MMIO to I/O access fixes the issue as well.
+	 */
+	RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32);
+	RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_32BIT_MASK);
+	RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32);
+	RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_32BIT_MASK);
+}
+
+static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
+{
+	u16 cmd;
+
+	cmd = RTL_R16(CPlusCmd);
+	RTL_W16(CPlusCmd, cmd);
+	return cmd;
+}
+
+static void rtl_set_rx_max_size(void __iomem *ioaddr)
+{
+	/* Low hurts. Let's disable the filtering. */
+	RTL_W16(RxMaxSize, 16383);
+}
+
 static void rtl_hw_start_8169(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -1874,11 +1903,6 @@ static void rtl_hw_start_8169(struct net_device *dev)
 		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);
-		pci_write_config_word(pdev, 0x69, 0x08);
-	}
-
 	/* Undocumented stuff. */
 	if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
 		/* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */
@@ -1901,19 +1925,15 @@ static void rtl_hw_start_8169(struct net_device *dev)
 
 	RTL_W8(EarlyTxThres, EarlyTxThld);
 
-	/* Low hurts. Let's disable the filtering. */
-	RTL_W16(RxMaxSize, 16383);
+	rtl_set_rx_max_size(ioaddr);
 
 	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))
-		rtl8169_set_rx_tx_config_registers(tp);
+		rtl_set_rx_tx_config_registers(tp);
 
-	cmd = RTL_R16(CPlusCmd);
-	RTL_W16(CPlusCmd, cmd);
-
-	tp->cp_cmd |= cmd | PCIMulRW;
+	tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
 
 	if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
 	    (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
@@ -1930,22 +1950,14 @@ static void rtl_hw_start_8169(struct net_device *dev)
 	 */
 	RTL_W16(IntrMitigate, 0x0000);
 
-	/*
-	 * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh
-	 * register to be written before TxDescAddrLow to work.
-	 * Switching from MMIO to I/O access fixes the issue as well.
-	 */
-	RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32));
-	RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK));
-	RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32));
-	RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK));
+	rtl_set_rx_tx_desc_registers(tp, ioaddr);
 
 	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)) {
 		RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
-		rtl8169_set_rx_tx_config_registers(tp);
+		rtl_set_rx_tx_config_registers(tp);
 	}
 
 	RTL_W8(Cfg9346, Cfg9346_Lock);
@@ -1963,12 +1975,74 @@ static void rtl_hw_start_8169(struct net_device *dev)
 
 static void rtl_hw_start_8168(struct net_device *dev)
 {
-	rtl_hw_start_8169(dev);
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	RTL_W8(Cfg9346, Cfg9346_Unlock);
+
+	RTL_W8(EarlyTxThres, EarlyTxThld);
+
+	rtl_set_rx_max_size(ioaddr);
+
+	tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
+
+	RTL_W16(CPlusCmd, tp->cp_cmd);
+
+	RTL_W16(IntrMitigate, 0x0000);
+
+	rtl_set_rx_tx_desc_registers(tp, ioaddr);
+
+	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+	rtl_set_rx_tx_config_registers(tp);
+
+	RTL_W8(Cfg9346, Cfg9346_Lock);
+
+	RTL_R8(IntrMask);
+
+	RTL_W32(RxMissed, 0);
+
+	rtl_set_rx_mode(dev);
+
+	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
 }
 
 static void rtl_hw_start_8101(struct net_device *dev)
 {
-	rtl_hw_start_8169(dev);
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void __iomem *ioaddr = tp->mmio_addr;
+	struct pci_dev *pdev = tp->pci_dev;
+
+	if (tp->mac_version == RTL_GIGA_MAC_VER_13) {
+		pci_write_config_word(pdev, 0x68, 0x00);
+		pci_write_config_word(pdev, 0x69, 0x08);
+	}
+
+	RTL_W8(Cfg9346, Cfg9346_Unlock);
+
+	RTL_W8(EarlyTxThres, EarlyTxThld);
+
+	rtl_set_rx_max_size(ioaddr);
+
+	tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
+
+	RTL_W16(CPlusCmd, tp->cp_cmd);
+
+	RTL_W16(IntrMitigate, 0x0000);
+
+	rtl_set_rx_tx_desc_registers(tp, ioaddr);
+
+	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+	rtl_set_rx_tx_config_registers(tp);
+
+	RTL_W8(Cfg9346, Cfg9346_Lock);
+
+	RTL_R8(IntrMask);
+
+	RTL_W32(RxMissed, 0);
+
+	rtl_set_rx_mode(dev);
+
+	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
 }
 
 static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
-- 
1.4.4.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 03/12] r8169: merge with version 6.001.00 of Realtek's r8169 driver
       [not found] <20070426205714.GA12701@electric-eye.fr.zoreil.com>
  2007-04-26 21:47 ` [PATCH 01/12] r8169: add per-device hw_start handler (1/2) Francois Romieu
  2007-04-26 21:48 ` [PATCH 02/12] r8169: add per-device hw_start handler (2/2) Francois Romieu
@ 2007-04-26 21:48 ` Francois Romieu
  2007-04-26 21:48 ` [PATCH 04/12] r8169: merge with version 8.001.00 of Realtek's r8168 driver Francois Romieu
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Francois Romieu @ 2007-04-26 21:48 UTC (permalink / raw)
  To: jeff; +Cc: netdev, Edward Hsu

- new identifier for the 8110SCe

- the PCI latency timer is set unconditionally. This part is identical
  in Realtek's r8168 (8.001.00) and r8101 (1.001.00)

- initialization of the cache line size register is for the 8169s only

- more magic in rtl_hw_start_8169

- it is not possible to factor out the setting of the the irq event mask
  with the 8168 and the 8101 any more. Pushed it into the hw_start handler.

- rtl_set_rx_tx_config_registers() and write to the ChipCmd register are
  issued identically for the whole 8169/8110 family: the 8110SCd/8110SCe
  are handled the same way

- work around for AMD platform.

Some registers definitions are let aside for later.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Edward Hsu <edward_hsu@realtek.com>
---
 drivers/net/r8169.c |   90 +++++++++++++++++++++++++++++++--------------------
 1 files changed, 55 insertions(+), 35 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 05408f3..74973ef 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -156,6 +156,7 @@ enum mac_version {
 	RTL_GIGA_MAC_VER_03 = 0x03, // 8110S
 	RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
 	RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
+	RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
 	RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
 	RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be 8168Bf
 	RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb 8101Ec
@@ -185,6 +186,7 @@ static const struct {
 	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S
 	_R("RTL8169sb/8110sb",	RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
 	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
+	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
 	_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
@@ -328,6 +330,10 @@ 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 */
@@ -1179,6 +1185,7 @@ 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_06 },
 		{ 0x18000000,	RTL_GIGA_MAC_VER_05 },
 		{ 0x10000000,	RTL_GIGA_MAC_VER_04 },
 		{ 0x04000000,	RTL_GIGA_MAC_VER_03 },
@@ -1187,7 +1194,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *io
 	}, *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;
@@ -1435,10 +1442,10 @@ 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) {
-		dprintk("Set PCI Latency=0x40\n");
-		pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
-	}
+	pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
+
+	if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
+		pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08);
 
 	if (tp->mac_version == RTL_GIGA_MAC_VER_02) {
 		dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
@@ -1855,9 +1862,6 @@ static void rtl_hw_start(struct net_device *dev)
 
 	tp->hw_start(dev);
 
-	/* Enable all known interrupts by setting the interrupt mask. */
-	RTL_W16(IntrMask, rtl8169_intr_mask);
-
 	netif_start_queue(dev);
 }
 
@@ -1891,31 +1895,41 @@ static void rtl_set_rx_max_size(void __iomem *ioaddr)
 	RTL_W16(RxMaxSize, 16383);
 }
 
+static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
+{
+	struct {
+		u32 mac_version;
+		u32 clk;
+		u32 val;
+	} cfg2_info [] = {
+		{ RTL_GIGA_MAC_VER_05, PCI_Clock_33MHz, 0x000fff00 }, // 8110SCd
+		{ RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff },
+		{ RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe
+		{ RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff }
+	}, *p = cfg2_info;
+	unsigned int i;
+	u32 clk;
+
+	clk = RTL_R8(Config2) & PCI_Clock_66MHz;
+	for (i = 0; i < ARRAY_SIZE(cfg2_info); i++) {
+		if ((p->mac_version == mac_version) && (p->clk == clk)) {
+			RTL_W32(0x7c, p->val);
+			break;
+		}
+	}
+}
+
 static void rtl_hw_start_8169(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
 	struct pci_dev *pdev = tp->pci_dev;
-	u16 cmd;
 
 	if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
 		RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW);
 		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08);
 	}
 
-	/* Undocumented stuff. */
-	if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
-		/* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */
-		if ((RTL_R8(Config2) & 0x07) & 0x01)
-			RTL_W32(0x7c, 0x0007ffff);
-
-		RTL_W32(0x7c, 0x0007ff00);
-
-		pci_read_config_word(pdev, PCI_COMMAND, &cmd);
-		cmd = cmd & 0xef;
-		pci_write_config_word(pdev, PCI_COMMAND, cmd);
-	}
-
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
 	if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
 	    (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
@@ -1927,11 +1941,7 @@ static void rtl_hw_start_8169(struct net_device *dev)
 
 	rtl_set_rx_max_size(ioaddr);
 
-	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))
-		rtl_set_rx_tx_config_registers(tp);
+	rtl_set_rx_tx_config_registers(tp);
 
 	tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
 
@@ -1944,6 +1954,8 @@ static void rtl_hw_start_8169(struct net_device *dev)
 
 	RTL_W16(CPlusCmd, tp->cp_cmd);
 
+	rtl8169_set_magic_reg(ioaddr, tp->mac_version);
+
 	/*
 	 * Undocumented corner. Supposedly:
 	 * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
@@ -1952,14 +1964,6 @@ static void rtl_hw_start_8169(struct net_device *dev)
 
 	rtl_set_rx_tx_desc_registers(tp, ioaddr);
 
-	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)) {
-		RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
-		rtl_set_rx_tx_config_registers(tp);
-	}
-
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 
 	/* Initially a 10 us delay. Turned it into a PCI commit. - FR */
@@ -1971,6 +1975,11 @@ static void rtl_hw_start_8169(struct net_device *dev)
 
 	/* no early-rx interrupts */
 	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
+
+	/* Enable all known interrupts by setting the interrupt mask. */
+	RTL_W16(IntrMask, rtl8169_intr_mask);
+
+	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
 }
 
 static void rtl_hw_start_8168(struct net_device *dev)
@@ -2004,6 +2013,8 @@ static void rtl_hw_start_8168(struct net_device *dev)
 	rtl_set_rx_mode(dev);
 
 	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
+
+	RTL_W16(IntrMask, rtl8169_intr_mask);
 }
 
 static void rtl_hw_start_8101(struct net_device *dev)
@@ -2043,6 +2054,8 @@ static void rtl_hw_start_8101(struct net_device *dev)
 	rtl_set_rx_mode(dev);
 
 	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
+
+	RTL_W16(IntrMask, rtl8169_intr_mask);
 }
 
 static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
@@ -2698,6 +2711,13 @@ 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.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 04/12] r8169: merge with version 8.001.00 of Realtek's r8168 driver
       [not found] <20070426205714.GA12701@electric-eye.fr.zoreil.com>
                   ` (2 preceding siblings ...)
  2007-04-26 21:48 ` [PATCH 03/12] r8169: merge with version 6.001.00 of Realtek's r8169 driver Francois Romieu
@ 2007-04-26 21:48 ` Francois Romieu
  2007-04-26 21:48 ` [PATCH 05/12] r8169: confusion between hardware and IP header alignment Francois Romieu
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Francois Romieu @ 2007-04-26 21:48 UTC (permalink / raw)
  To: jeff; +Cc: netdev, Edward Hsu

This one includes:

- more tweaks to rtl_hw_start_8168

- a work around for a Rx FiFO overflow issue on the 8168Bb
  - rtl8169_{intr_mask/napi_event} are replaced with per-device fields,
    namely tp->{intr/napi}_event
  - rtl_cfg_info is converted to C99 for readability but the values are
    not changed for the 8169/8110 and the 8101

Includes ChipCmd fix from Bernhard Walle <bwalle@suse.de> (2007/02/24).

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Edward Hsu <edward_hsu@realtek.com>
---
 drivers/net/r8169.c |  119 ++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 89 insertions(+), 30 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 74973ef..241e204 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -205,16 +205,6 @@ static void rtl_hw_start_8169(struct net_device *);
 static void rtl_hw_start_8168(struct net_device *);
 static void rtl_hw_start_8101(struct net_device *);
 
-static const struct {
-	void (*hw_start)(struct net_device *);
-	unsigned int region;
-	unsigned int align;
-} rtl_cfg_info[] = {
-	[RTL_CFG_0] = { rtl_hw_start_8169, 1, NET_IP_ALIGN },
-	[RTL_CFG_1] = { rtl_hw_start_8168, 2, 8 },
-	[RTL_CFG_2] = { rtl_hw_start_8101, 2, 8 }
-};
-
 static struct pci_device_id rtl8169_pci_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8129), 0, 0, RTL_CFG_0 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8136), 0, 0, RTL_CFG_2 },
@@ -354,10 +344,15 @@ enum RTL8169_register_content {
 	TBINwComplete	= 0x01000000,
 
 	/* CPlusCmd p.31 */
+	PktCntrDisable	= (1 << 7),	// 8168
 	RxVlan		= (1 << 6),
 	RxChkSum	= (1 << 5),
 	PCIDAC		= (1 << 4),
 	PCIMulRW	= (1 << 3),
+	INTT_0		= 0x0000,	// 8168
+	INTT_1		= 0x0001,	// 8168
+	INTT_2		= 0x0002,	// 8168
+	INTT_3		= 0x0003,	// 8168
 
 	/* rtl8169_PHYstatus */
 	TBI_Enable = 0x80,
@@ -457,6 +452,8 @@ struct rtl8169_private {
 	unsigned rx_buf_sz;
 	struct timer_list timer;
 	u16 cp_cmd;
+	u16 intr_event;
+	u16 napi_event;
 	u16 intr_mask;
 	int phy_auto_nego_reg;
 	int phy_1000_ctrl_reg;
@@ -505,10 +502,6 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp);
 static int rtl8169_poll(struct net_device *dev, int *budget);
 #endif
 
-static const u16 rtl8169_intr_mask =
-	SYSErr | LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK;
-static const u16 rtl8169_napi_event =
-	RxOK | RxOverflow | RxFIFOOver | TxOK | TxErr;
 static const unsigned int rtl8169_rx_config =
 	(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
 
@@ -1176,6 +1169,13 @@ static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum
 
 static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *ioaddr)
 {
+	/*
+	 * The driver currently handles the 8168Bf and the 8168Be identically
+	 * but they can be identified more specifically through the test below
+	 * if needed:
+	 *
+	 * (RTL_R32(TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be
+	 */
 	const struct {
 		u32 mask;
 		int mac_version;
@@ -1490,10 +1490,44 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	return -EOPNOTSUPP;
 }
 
+static const struct rtl_cfg_info {
+	void (*hw_start)(struct net_device *);
+	unsigned int region;
+	unsigned int align;
+	u16 intr_event;
+	u16 napi_event;
+} rtl_cfg_infos [] = {
+	[RTL_CFG_0] = {
+		.hw_start	= rtl_hw_start_8169,
+		.region		= 1,
+		.align		= NET_IP_ALIGN,
+		.intr_event	= SYSErr | LinkChg | RxOverflow |
+				  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
+		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow
+	},
+	[RTL_CFG_1] = {
+		.hw_start	= rtl_hw_start_8168,
+		.region		= 2,
+		.align		= 8,
+		.intr_event	= SYSErr | LinkChg | RxOverflow |
+				  TxErr | TxOK | RxOK | RxErr,
+		.napi_event	= TxErr | TxOK | RxOK | RxOverflow
+	},
+	[RTL_CFG_2] = {
+		.hw_start	= rtl_hw_start_8101,
+		.region		= 2,
+		.align		= 8,
+		.intr_event	= SYSErr | LinkChg | RxOverflow | PCSTimeout |
+				  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
+		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow
+	}
+};
+
 static int __devinit
 rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	const unsigned int region = rtl_cfg_info[ent->driver_data].region;
+	const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
+	const unsigned int region = cfg->region;
 	struct rtl8169_private *tp;
 	struct net_device *dev;
 	void __iomem *ioaddr;
@@ -1694,14 +1728,15 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	tp->intr_mask = 0xffff;
 	tp->pci_dev = pdev;
 	tp->mmio_addr = ioaddr;
-	tp->align = rtl_cfg_info[ent->driver_data].align;
+	tp->align = cfg->align;
+	tp->hw_start = cfg->hw_start;
+	tp->intr_event = cfg->intr_event;
+	tp->napi_event = cfg->napi_event;
 
 	init_timer(&tp->timer);
 	tp->timer.data = (unsigned long) dev;
 	tp->timer.function = rtl8169_phy_timer;
 
-	tp->hw_start = rtl_cfg_info[ent->driver_data].hw_start;
-
 	spin_lock_init(&tp->lock);
 
 	rc = register_netdev(dev);
@@ -1977,7 +2012,7 @@ static void rtl_hw_start_8169(struct net_device *dev)
 	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
 
 	/* Enable all known interrupts by setting the interrupt mask. */
-	RTL_W16(IntrMask, rtl8169_intr_mask);
+	RTL_W16(IntrMask, tp->intr_event);
 
 	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
 }
@@ -1986,6 +2021,8 @@ static void rtl_hw_start_8168(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
+	struct pci_dev *pdev = tp->pci_dev;
+	u8 ctl;
 
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
 
@@ -1993,16 +2030,26 @@ static void rtl_hw_start_8168(struct net_device *dev)
 
 	rtl_set_rx_max_size(ioaddr);
 
-	tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
+	rtl_set_rx_tx_config_registers(tp);
+
+	tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1;
 
 	RTL_W16(CPlusCmd, tp->cp_cmd);
 
-	RTL_W16(IntrMitigate, 0x0000);
+	/* Tx performance tweak. */
+	pci_read_config_byte(pdev, 0x69, &ctl);
+	ctl = (ctl & ~0x70) | 0x50;
+	pci_write_config_byte(pdev, 0x69, ctl);
 
-	rtl_set_rx_tx_desc_registers(tp, ioaddr);
+	RTL_W16(IntrMitigate, 0x5151);
 
-	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
-	rtl_set_rx_tx_config_registers(tp);
+	/* Work around for RxFIFO overflow. */
+	if (tp->mac_version == RTL_GIGA_MAC_VER_11) {
+		tp->intr_event |= RxFIFOOver | PCSTimeout;
+		tp->intr_event &= ~RxOverflow;
+	}
+
+	rtl_set_rx_tx_desc_registers(tp, ioaddr);
 
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 
@@ -2012,9 +2059,11 @@ static void rtl_hw_start_8168(struct net_device *dev)
 
 	rtl_set_rx_mode(dev);
 
+	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+
 	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
 
-	RTL_W16(IntrMask, rtl8169_intr_mask);
+	RTL_W16(IntrMask, tp->intr_event);
 }
 
 static void rtl_hw_start_8101(struct net_device *dev)
@@ -2053,9 +2102,11 @@ static void rtl_hw_start_8101(struct net_device *dev)
 
 	rtl_set_rx_mode(dev);
 
+	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+
 	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
 
-	RTL_W16(IntrMask, rtl8169_intr_mask);
+	RTL_W16(IntrMask, tp->intr_event);
 }
 
 static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
@@ -2770,8 +2821,16 @@ rtl8169_interrupt(int irq, void *dev_instance)
 		RTL_W16(IntrStatus,
 			(status & RxFIFOOver) ? (status | RxOverflow) : status);
 
-		if (!(status & rtl8169_intr_mask))
+		if (!(status & tp->intr_event))
+			break;
+
+                /* Work around for rx fifo overflow */
+                if (unlikely(status & RxFIFOOver) &&
+		    (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
+			netif_stop_queue(dev);
+			rtl8169_tx_timeout(dev);
 			break;
+		}
 
 		if (unlikely(status & SYSErr)) {
 			rtl8169_pcierr_interrupt(dev);
@@ -2782,8 +2841,8 @@ rtl8169_interrupt(int irq, void *dev_instance)
 			rtl8169_check_link_status(dev, tp, ioaddr);
 
 #ifdef CONFIG_R8169_NAPI
-		RTL_W16(IntrMask, rtl8169_intr_mask & ~rtl8169_napi_event);
-		tp->intr_mask = ~rtl8169_napi_event;
+		RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
+		tp->intr_mask = ~tp->napi_event;
 
 		if (likely(netif_rx_schedule_prep(dev)))
 			__netif_rx_schedule(dev);
@@ -2840,7 +2899,7 @@ static int rtl8169_poll(struct net_device *dev, int *budget)
 		 * write is safe - FR
 		 */
 		smp_wmb();
-		RTL_W16(IntrMask, rtl8169_intr_mask);
+		RTL_W16(IntrMask, tp->intr_event);
 	}
 
 	return (work_done >= work_to_do);
-- 
1.4.4.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 05/12] r8169: confusion between hardware and IP header alignment
       [not found] <20070426205714.GA12701@electric-eye.fr.zoreil.com>
                   ` (3 preceding siblings ...)
  2007-04-26 21:48 ` [PATCH 04/12] r8169: merge with version 8.001.00 of Realtek's r8168 driver Francois Romieu
@ 2007-04-26 21:48 ` Francois Romieu
  2007-04-26 21:48 ` [PATCH 06/12] r8169: small 8101 comment Francois Romieu
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Francois Romieu @ 2007-04-26 21:48 UTC (permalink / raw)
  To: jeff; +Cc: netdev, Edward Hsu

The rx copybreak part is straightforward.

The align field in struct rtl_cfg_info is related to the alignment
requirements of the DMA operation. Its value is set at 2 to limit the
scale of possible regression but my old v1.21 8169 datasheet claims a
8 bytes requirements (that was never followed by the driver of course)
and the 8101/8168 go with a plain 8 bytes alignments. Yuck, yuck...

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Edward Hsu <edward_hsu@realtek.com>
---
 drivers/net/r8169.c |   11 +++++------
 1 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 241e204..1111ca4 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1500,7 +1500,7 @@ static const struct rtl_cfg_info {
 	[RTL_CFG_0] = {
 		.hw_start	= rtl_hw_start_8169,
 		.region		= 1,
-		.align		= NET_IP_ALIGN,
+		.align		= 2,
 		.intr_event	= SYSErr | LinkChg | RxOverflow |
 				  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
 		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow
@@ -2657,17 +2657,16 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
 }
 
 static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
-				      struct RxDesc *desc, int rx_buf_sz,
-				      unsigned int align)
+				      struct RxDesc *desc, int rx_buf_sz)
 {
 	int ret = -1;
 
 	if (pkt_size < rx_copybreak) {
 		struct sk_buff *skb;
 
-		skb = dev_alloc_skb(pkt_size + align);
+		skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
 		if (skb) {
-			skb_reserve(skb, (align - 1) & (unsigned long)skb->data);
+			skb_reserve(skb, NET_IP_ALIGN);
 			eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
 			*sk_buff = skb;
 			rtl8169_mark_to_asic(desc, rx_buf_sz);
@@ -2743,7 +2742,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
 				PCI_DMA_FROMDEVICE);
 
 			if (rtl8169_try_rx_copy(&skb, pkt_size, desc,
-						tp->rx_buf_sz, tp->align)) {
+						tp->rx_buf_sz)) {
 				pci_action = pci_unmap_single;
 				tp->Rx_skbuff[entry] = NULL;
 			}
-- 
1.4.4.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 06/12] r8169: small 8101 comment
       [not found] <20070426205714.GA12701@electric-eye.fr.zoreil.com>
                   ` (4 preceding siblings ...)
  2007-04-26 21:48 ` [PATCH 05/12] r8169: confusion between hardware and IP header alignment Francois Romieu
@ 2007-04-26 21:48 ` Francois Romieu
  2007-04-26 21:48 ` [PATCH 07/12] r8169: remove the media option Francois Romieu
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Francois Romieu @ 2007-04-26 21:48 UTC (permalink / raw)
  To: jeff; +Cc: netdev, Edward Hsu

Extracted from version 1.001.00 of Realtek's r8101.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Edward Hsu <edward_hsu@realtek.com>
---
 drivers/net/r8169.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 1111ca4..adc4d3d 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1175,6 +1175,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *io
 	 * if needed:
 	 *
 	 * (RTL_R32(TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be
+	 *
+	 * Same thing for the 8101Eb and the 8101Ec:
+	 *
+	 * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec
 	 */
 	const struct {
 		u32 mask;
-- 
1.4.4.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 07/12] r8169: remove the media option
       [not found] <20070426205714.GA12701@electric-eye.fr.zoreil.com>
                   ` (5 preceding siblings ...)
  2007-04-26 21:48 ` [PATCH 06/12] r8169: small 8101 comment Francois Romieu
@ 2007-04-26 21:48 ` Francois Romieu
  2007-04-26 21:48 ` [PATCH 08/12] r8169: cleanup Francois Romieu
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Francois Romieu @ 2007-04-26 21:48 UTC (permalink / raw)
  To: jeff; +Cc: netdev, Edward Hsu

It has been documented as deprecated:
- in MODULE_PARM_DESC since may 2005 ;
- at the top of the source file and in printk since june 2004.

Good bye.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Edward Hsu <edward_hsu@realtek.com>
---
 drivers/net/r8169.c |   72 +++-----------------------------------------------
 1 files changed, 5 insertions(+), 67 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index adc4d3d..7a44de2 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -8,19 +8,6 @@
  May 20 2002	- Add link status force-mode and TBI mode support.
 	2004	- Massive updates. See kernel SCM system for details.
 =========================================================================
-  1. [DEPRECATED: use ethtool instead] The media can be forced in 5 modes.
-	 Command: 'insmod r8169 media = SET_MEDIA'
-	 Ex:	  'insmod r8169 media = 0x04' will force PHY to operate in 100Mpbs Half-duplex.
-
-	 SET_MEDIA can be:
- 		_10_Half	= 0x01
- 		_10_Full	= 0x02
- 		_100_Half	= 0x04
- 		_100_Full	= 0x08
- 		_1000_Full	= 0x10
-
-  2. Support TBI mode.
-=========================================================================
 VERSION 1.1	<2002/10/4>
 
 	The bit4:0 of MII register 4 is called "selector field", and have to be
@@ -108,11 +95,6 @@ VERSION 2.2LK	<2005/01/25>
 #define rtl8169_rx_quota(count, quota)	count
 #endif
 
-/* media options */
-#define MAX_UNITS 8
-static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
-static int num_media = 0;
-
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static const int max_interrupt_work = 20;
 
@@ -364,13 +346,6 @@ enum RTL8169_register_content {
 	LinkStatus = 0x02,
 	FullDup = 0x01,
 
-	/* _MediaType */
-	_10_Half = 0x01,
-	_10_Full = 0x02,
-	_100_Half = 0x04,
-	_100_Full = 0x08,
-	_1000_Full = 0x10,
-
 	/* _TBICSRBit */
 	TBILinkOK = 0x02000000,
 
@@ -472,8 +447,6 @@ struct rtl8169_private {
 
 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
 MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
-module_param_array(media, int, &num_media, 0);
-MODULE_PARM_DESC(media, "force phy operation. Deprecated by ethtool (8).");
 module_param(rx_copybreak, int, 0);
 MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
 module_param(use_dac, int, 0);
@@ -601,38 +574,6 @@ static void rtl8169_check_link_status(struct net_device *dev,
 	spin_unlock_irqrestore(&tp->lock, flags);
 }
 
-static void rtl8169_link_option(int idx, u8 *autoneg, u16 *speed, u8 *duplex)
-{
-	struct {
-		u16 speed;
-		u8 duplex;
-		u8 autoneg;
-		u8 media;
-	} link_settings[] = {
-		{ SPEED_10,	DUPLEX_HALF, AUTONEG_DISABLE,	_10_Half },
-		{ SPEED_10,	DUPLEX_FULL, AUTONEG_DISABLE,	_10_Full },
-		{ SPEED_100,	DUPLEX_HALF, AUTONEG_DISABLE,	_100_Half },
-		{ SPEED_100,	DUPLEX_FULL, AUTONEG_DISABLE,	_100_Full },
-		{ SPEED_1000,	DUPLEX_FULL, AUTONEG_DISABLE,	_1000_Full },
-		/* Make TBI happy */
-		{ SPEED_1000,	DUPLEX_FULL, AUTONEG_ENABLE,	0xff }
-	}, *p;
-	unsigned char option;
-
-	option = ((idx < MAX_UNITS) && (idx >= 0)) ? media[idx] : 0xff;
-
-	if ((option != 0xff) && !idx && netif_msg_drv(&debug))
-		printk(KERN_WARNING PFX "media option is deprecated.\n");
-
-	for (p = link_settings; p->media != 0xff; p++) {
-		if (p->media == option)
-			break;
-	}
-	*autoneg = p->autoneg;
-	*speed = p->speed;
-	*duplex = p->duplex;
-}
-
 static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -1435,11 +1376,6 @@ static void rtl8169_phy_reset(struct net_device *dev,
 static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
-	static int board_idx = -1;
-	u8 autoneg, duplex;
-	u16 speed;
-
-	board_idx++;
 
 	rtl8169_hw_phy_config(dev);
 
@@ -1458,11 +1394,13 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
 		mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
 	}
 
-	rtl8169_link_option(board_idx, &autoneg, &speed, &duplex);
-
 	rtl8169_phy_reset(dev, tp);
 
-	rtl8169_set_speed(dev, autoneg, speed, duplex);
+	/*
+	 * rtl8169_set_speed_xmii takes good care of the Fast Ethernet
+	 * only 8101. Don't panic.
+	 */
+	rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL);
 
 	if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
 		printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
-- 
1.4.4.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 08/12] r8169: cleanup
       [not found] <20070426205714.GA12701@electric-eye.fr.zoreil.com>
                   ` (6 preceding siblings ...)
  2007-04-26 21:48 ` [PATCH 07/12] r8169: remove the media option Francois Romieu
@ 2007-04-26 21:48 ` Francois Romieu
  2007-05-08  4:52   ` Jeff Garzik
  2007-04-26 21:49 ` [PATCH 09/12] r8169: MSI support Francois Romieu
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2007-04-26 21:48 UTC (permalink / raw)
  To: jeff; +Cc: netdev, Edward Hsu

No functionnal change:
- trim the old history log
- whitespace/indent/case police
- unsigned int where signedness does not matte
- removal of obsolete assert
- needless cast from void * (dev_instance)

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Edward Hsu <edward_hsu@realtek.com>
---
 drivers/net/r8169.c |  311 ++++++++++++++++++++++-----------------------------
 1 files changed, 133 insertions(+), 178 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 7a44de2..7a0c5e7 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1,40 +1,11 @@
 /*
-=========================================================================
- r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver for Linux kernel 2.4.x.
- --------------------------------------------------------------------
-
- History:
- Feb  4 2002	- created initially by ShuChen <shuchen@realtek.com.tw>.
- May 20 2002	- Add link status force-mode and TBI mode support.
-	2004	- Massive updates. See kernel SCM system for details.
-=========================================================================
-VERSION 1.1	<2002/10/4>
-
-	The bit4:0 of MII register 4 is called "selector field", and have to be
-	00001b to indicate support of IEEE std 802.3 during NWay process of
-	exchanging Link Code Word (FLP).
-
-VERSION 1.2	<2002/11/30>
-
-	- Large style cleanup
-	- Use ether_crc in stock kernel (linux/crc32.h)
-	- Copy mc_filter setup code from 8139cp
-	  (includes an optimization, and avoids set_bit use)
-
-VERSION 1.6LK	<2004/04/14>
-
-	- Merge of Realtek's version 1.6
-	- Conversion to DMA API
-	- Suspend/resume
-	- Endianness
-	- Misc Rx/Tx bugs
-
-VERSION 2.2LK	<2005/01/25>
-
-	- RX csum, TX csum/SG, TSO
-	- VLAN
-	- baby (< 7200) Jumbo frames support
-	- Merge of Realtek's version 2.2 (new phy)
+ * r8169.c: RealTek 8169/8168/8101 ethernet driver.
+ *
+ * Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
+ * Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
+ * Copyright (c) a lot of people too. Please respect their work.
+ *
+ * See MAINTAINERS file fro support contact information.
  */
 
 #include <linux/module.h>
@@ -108,7 +79,7 @@ static const int multicast_filter_limit = 32;
 #define RX_FIFO_THRESH	7	/* 7 means NO threshold, Rx buffer level before first PCI xfer. */
 #define RX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
 #define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
-#define EarlyTxThld 	0x3F	/* 0x3F means NO early transmit */
+#define EarlyTxThld	0x3F	/* 0x3F means NO early transmit */
 #define RxPacketMaxSize	0x3FE8	/* 16K - 1 - ETH_HLEN - VLAN - CRC... */
 #define SafeMtu		0x1c20	/* ... actually life sucks beyond ~7k */
 #define InterFrameGap	0x03	/* 3 means InterFrameGap = the shortest one */
@@ -209,62 +180,62 @@ static struct {
 	u32 msg_enable;
 } debug = { -1 };
 
-enum RTL8169_registers {
-	MAC0 = 0,		/* Ethernet hardware address. */
-	MAR0 = 8,		/* Multicast filter. */
-	CounterAddrLow = 0x10,
-	CounterAddrHigh = 0x14,
-	TxDescStartAddrLow = 0x20,
-	TxDescStartAddrHigh = 0x24,
-	TxHDescStartAddrLow = 0x28,
-	TxHDescStartAddrHigh = 0x2c,
-	FLASH = 0x30,
-	ERSR = 0x36,
-	ChipCmd = 0x37,
-	TxPoll = 0x38,
-	IntrMask = 0x3C,
-	IntrStatus = 0x3E,
-	TxConfig = 0x40,
-	RxConfig = 0x44,
-	RxMissed = 0x4C,
-	Cfg9346 = 0x50,
-	Config0 = 0x51,
-	Config1 = 0x52,
-	Config2 = 0x53,
-	Config3 = 0x54,
-	Config4 = 0x55,
-	Config5 = 0x56,
-	MultiIntr = 0x5C,
-	PHYAR = 0x60,
-	TBICSR = 0x64,
-	TBI_ANAR = 0x68,
-	TBI_LPAR = 0x6A,
-	PHYstatus = 0x6C,
-	RxMaxSize = 0xDA,
-	CPlusCmd = 0xE0,
-	IntrMitigate = 0xE2,
-	RxDescAddrLow = 0xE4,
-	RxDescAddrHigh = 0xE8,
-	EarlyTxThres = 0xEC,
-	FuncEvent = 0xF0,
-	FuncEventMask = 0xF4,
-	FuncPresetState = 0xF8,
-	FuncForceEvent = 0xFC,
+enum rtl_registers {
+	MAC0		= 0,	/* Ethernet hardware address. */
+	MAR0		= 8,	/* Multicast filter. */
+	CounterAddrLow		= 0x10,
+	CounterAddrHigh		= 0x14,
+	TxDescStartAddrLow	= 0x20,
+	TxDescStartAddrHigh	= 0x24,
+	TxHDescStartAddrLow	= 0x28,
+	TxHDescStartAddrHigh	= 0x2c,
+	FLASH		= 0x30,
+	ERSR		= 0x36,
+	ChipCmd		= 0x37,
+	TxPoll		= 0x38,
+	IntrMask	= 0x3c,
+	IntrStatus	= 0x3e,
+	TxConfig	= 0x40,
+	RxConfig	= 0x44,
+	RxMissed	= 0x4c,
+	Cfg9346		= 0x50,
+	Config0		= 0x51,
+	Config1		= 0x52,
+	Config2		= 0x53,
+	Config3		= 0x54,
+	Config4		= 0x55,
+	Config5		= 0x56,
+	MultiIntr	= 0x5c,
+	PHYAR		= 0x60,
+	TBICSR		= 0x64,
+	TBI_ANAR	= 0x68,
+	TBI_LPAR	= 0x6a,
+	PHYstatus	= 0x6c,
+	RxMaxSize	= 0xda,
+	CPlusCmd	= 0xe0,
+	IntrMitigate	= 0xe2,
+	RxDescAddrLow	= 0xe4,
+	RxDescAddrHigh	= 0xe8,
+	EarlyTxThres	= 0xec,
+	FuncEvent	= 0xf0,
+	FuncEventMask	= 0xf4,
+	FuncPresetState	= 0xf8,
+	FuncForceEvent	= 0xfc,
 };
 
-enum RTL8169_register_content {
+enum rtl_register_content {
 	/* InterruptStatusBits */
-	SYSErr = 0x8000,
-	PCSTimeout = 0x4000,
-	SWInt = 0x0100,
-	TxDescUnavail = 0x80,
-	RxFIFOOver = 0x40,
-	LinkChg = 0x20,
-	RxOverflow = 0x10,
-	TxErr = 0x08,
-	TxOK = 0x04,
-	RxErr = 0x02,
-	RxOK = 0x01,
+	SYSErr		= 0x8000,
+	PCSTimeout	= 0x4000,
+	SWInt		= 0x0100,
+	TxDescUnavail	= 0x0080,
+	RxFIFOOver	= 0x0040,
+	LinkChg		= 0x0020,
+	RxOverflow	= 0x0010,
+	TxErr		= 0x0008,
+	TxOK		= 0x0004,
+	RxErr		= 0x0002,
+	RxOK		= 0x0001,
 
 	/* RxStatusDesc */
 	RxFOVF	= (1 << 23),
@@ -274,26 +245,26 @@ enum RTL8169_register_content {
 	RxCRC	= (1 << 19),
 
 	/* ChipCmdBits */
-	CmdReset = 0x10,
-	CmdRxEnb = 0x08,
-	CmdTxEnb = 0x04,
-	RxBufEmpty = 0x01,
+	CmdReset	= 0x10,
+	CmdRxEnb	= 0x08,
+	CmdTxEnb	= 0x04,
+	RxBufEmpty	= 0x01,
 
 	/* Cfg9346Bits */
-	Cfg9346_Lock = 0x00,
-	Cfg9346_Unlock = 0xC0,
+	Cfg9346_Lock	= 0x00,
+	Cfg9346_Unlock	= 0xc0,
 
 	/* rx_mode_bits */
-	AcceptErr = 0x20,
-	AcceptRunt = 0x10,
-	AcceptBroadcast = 0x08,
-	AcceptMulticast = 0x04,
-	AcceptMyPhys = 0x02,
-	AcceptAllPhys = 0x01,
+	AcceptErr	= 0x20,
+	AcceptRunt	= 0x10,
+	AcceptBroadcast	= 0x08,
+	AcceptMulticast	= 0x04,
+	AcceptMyPhys	= 0x02,
+	AcceptAllPhys	= 0x01,
 
 	/* RxConfigBits */
-	RxCfgFIFOShift = 13,
-	RxCfgDMAShift = 8,
+	RxCfgFIFOShift	= 13,
+	RxCfgDMAShift	=  8,
 
 	/* TxConfigBits */
 	TxInterFrameGapShift = 24,
@@ -337,23 +308,23 @@ enum RTL8169_register_content {
 	INTT_3		= 0x0003,	// 8168
 
 	/* rtl8169_PHYstatus */
-	TBI_Enable = 0x80,
-	TxFlowCtrl = 0x40,
-	RxFlowCtrl = 0x20,
-	_1000bpsF = 0x10,
-	_100bps = 0x08,
-	_10bps = 0x04,
-	LinkStatus = 0x02,
-	FullDup = 0x01,
+	TBI_Enable	= 0x80,
+	TxFlowCtrl	= 0x40,
+	RxFlowCtrl	= 0x20,
+	_1000bpsF	= 0x10,
+	_100bps		= 0x08,
+	_10bps		= 0x04,
+	LinkStatus	= 0x02,
+	FullDup		= 0x01,
 
 	/* _TBICSRBit */
-	TBILinkOK = 0x02000000,
+	TBILinkOK	= 0x02000000,
 
 	/* DumpCounterCommand */
-	CounterDump = 0x8,
+	CounterDump	= 0x8,
 };
 
-enum _DescStatusBit {
+enum desc_status_bit {
 	DescOwn		= (1 << 31), /* Descriptor is owned by NIC */
 	RingEnd		= (1 << 30), /* End of descriptor ring */
 	FirstFrag	= (1 << 29), /* First segment of a packet */
@@ -478,28 +449,34 @@ static int rtl8169_poll(struct net_device *dev, int *budget);
 static const unsigned int rtl8169_rx_config =
 	(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
 
-static void mdio_write(void __iomem *ioaddr, int RegAddr, int value)
+static void mdio_write(void __iomem *ioaddr, int reg_addr, int value)
 {
 	int i;
 
-	RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
+	RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0xFF) << 16 | value);
 
 	for (i = 20; i > 0; i--) {
-		/* Check if the RTL8169 has completed writing to the specified MII register */
+		/*
+		 * Check if the RTL8169 has completed writing to the specified
+		 * MII register.
+		 */
 		if (!(RTL_R32(PHYAR) & 0x80000000))
 			break;
 		udelay(25);
 	}
 }
 
-static int mdio_read(void __iomem *ioaddr, int RegAddr)
+static int mdio_read(void __iomem *ioaddr, int reg_addr)
 {
 	int i, value = -1;
 
-	RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
+	RTL_W32(PHYAR, 0x0 | (reg_addr & 0xFF) << 16);
 
 	for (i = 20; i > 0; i--) {
-		/* Check if the RTL8169 has completed retrieving data from the specified MII register */
+		/*
+		 * Check if the RTL8169 has completed retrieving data from
+		 * the specified MII register.
+		 */
 		if (RTL_R32(PHYAR) & 0x80000000) {
 			value = (int) (RTL_R32(PHYAR) & 0xFFFF);
 			break;
@@ -557,7 +534,8 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr)
 }
 
 static void rtl8169_check_link_status(struct net_device *dev,
-				      struct rtl8169_private *tp, void __iomem *ioaddr)
+				      struct rtl8169_private *tp,
+				      void __iomem *ioaddr)
 {
 	unsigned long flags;
 
@@ -613,7 +591,7 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
-	int i;
+	unsigned int i;
 	static struct {
 		u32 opt;
 		u16 reg;
@@ -849,8 +827,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
 	int ret;
 
 	if (tp->vlgrp && (opts2 & RxVlanTag)) {
-		rtl8169_rx_hwaccel_skb(skb, tp->vlgrp,
-				       swab16(opts2 & 0xffff));
+		rtl8169_rx_hwaccel_skb(skb, tp->vlgrp, swab16(opts2 & 0xffff));
 		ret = 0;
 	} else
 		ret = -1;
@@ -1071,7 +1048,6 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
 	}
 }
 
-
 static const struct ethtool_ops rtl8169_ethtool_ops = {
 	.get_drvinfo		= rtl8169_get_drvinfo,
 	.get_regs_len		= rtl8169_get_regs_len,
@@ -1097,8 +1073,8 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
 	.get_perm_addr		= ethtool_op_get_perm_addr,
 };
 
-static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum,
-				       int bitval)
+static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg,
+				       int bitnum, int bitval)
 {
 	int val;
 
@@ -1108,7 +1084,8 @@ static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum
 	mdio_write(ioaddr, reg, val & 0xffff);
 }
 
-static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *ioaddr)
+static void rtl8169_get_mac_version(struct rtl8169_private *tp,
+				    void __iomem *ioaddr)
 {
 	/*
 	 * The driver currently handles the 8168Bf and the 8168Be identically
@@ -1150,7 +1127,8 @@ static void rtl8169_print_mac_version(struct rtl8169_private *tp)
 	dprintk("mac_version = 0x%02x\n", tp->mac_version);
 }
 
-static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr)
+static void rtl8169_get_phy_version(struct rtl8169_private *tp,
+				    void __iomem *ioaddr)
 {
 	const struct {
 		u16 mask;
@@ -1227,7 +1205,7 @@ static void rtl8169_hw_phy_config(struct net_device *dev)
 		  0xbf00 }	//w 0 15 0 bf00
 		}
 	}, *p = phy_magic;
-	int i;
+	unsigned int i;
 
 	rtl8169_print_mac_version(tp);
 	rtl8169_print_phy_version(tp);
@@ -1361,7 +1339,7 @@ static void rtl8169_phy_reset(struct net_device *dev,
 			      struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
-	int i;
+	unsigned int i;
 
 	tp->phy_reset_enable(ioaddr);
 	for (i = 0; i < 100; i++) {
@@ -1717,15 +1695,11 @@ err_out_free_dev_1:
 	goto out;
 }
 
-static void __devexit
-rtl8169_remove_one(struct pci_dev *pdev)
+static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct rtl8169_private *tp = netdev_priv(dev);
 
-	assert(dev != NULL);
-	assert(tp != NULL);
-
 	flush_scheduled_work();
 
 	unregister_netdev(dev);
@@ -2146,7 +2120,7 @@ err_out:
 
 static void rtl8169_rx_clear(struct rtl8169_private *tp)
 {
-	int i;
+	unsigned int i;
 
 	for (i = 0; i < NUM_RX_DESC; i++) {
 		if (tp->Rx_skbuff[i]) {
@@ -2282,14 +2256,9 @@ static void rtl8169_reinit_task(struct work_struct *work)
 
 	ret = rtl8169_open(dev);
 	if (unlikely(ret < 0)) {
-		if (net_ratelimit()) {
-			struct rtl8169_private *tp = netdev_priv(dev);
-
-			if (netif_msg_drv(tp)) {
-				printk(PFX KERN_ERR
-				       "%s: reinit failure (status = %d)."
-				       " Rescheduling.\n", dev->name, ret);
-			}
+		if (net_ratelimit() && netif_msg_drv(tp)) {
+			printk(PFX KERN_ERR "%s: reinit failure (status = %d)."
+			       " Rescheduling.\n", dev->name, ret);
 		}
 		rtl8169_schedule_work(dev, rtl8169_reinit_task);
 	}
@@ -2319,13 +2288,9 @@ static void rtl8169_reset_task(struct work_struct *work)
 		rtl_hw_start(dev);
 		netif_wake_queue(dev);
 	} else {
-		if (net_ratelimit()) {
-			struct rtl8169_private *tp = netdev_priv(dev);
-
-			if (netif_msg_intr(tp)) {
-				printk(PFX KERN_EMERG
-				       "%s: Rx buffers shortage\n", dev->name);
-			}
+		if (net_ratelimit() && netif_msg_intr(tp)) {
+			printk(PFX KERN_EMERG "%s: Rx buffers shortage\n",
+			       dev->name);
 		}
 		rtl8169_schedule_work(dev, rtl8169_reset_task);
 	}
@@ -2532,16 +2497,12 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
 	rtl8169_schedule_work(dev, rtl8169_reinit_task);
 }
 
-static void
-rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
-		     void __iomem *ioaddr)
+static void rtl8169_tx_interrupt(struct net_device *dev,
+				 struct rtl8169_private *tp,
+				 void __iomem *ioaddr)
 {
 	unsigned int dirty_tx, tx_left;
 
-	assert(dev != NULL);
-	assert(tp != NULL);
-	assert(ioaddr != NULL);
-
 	dirty_tx = tp->dirty_tx;
 	smp_rmb();
 	tx_left = tp->cur_tx - dirty_tx;
@@ -2618,17 +2579,13 @@ static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
 	return ret;
 }
 
-static int
-rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
-		     void __iomem *ioaddr)
+static int rtl8169_rx_interrupt(struct net_device *dev,
+				struct rtl8169_private *tp,
+				void __iomem *ioaddr)
 {
 	unsigned int cur_rx, rx_left;
 	unsigned int delta, count;
 
-	assert(dev != NULL);
-	assert(tp != NULL);
-	assert(ioaddr != NULL);
-
 	cur_rx = tp->cur_rx;
 	rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
 	rx_left = rtl8169_rx_quota(rx_left, (u32) dev->quota);
@@ -2733,11 +2690,9 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
 	return count;
 }
 
-/* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */
-static irqreturn_t
-rtl8169_interrupt(int irq, void *dev_instance)
+static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
 {
-	struct net_device *dev = (struct net_device *) dev_instance;
+	struct net_device *dev = dev_instance;
 	struct rtl8169_private *tp = netdev_priv(dev);
 	int boguscnt = max_interrupt_work;
 	void __iomem *ioaddr = tp->mmio_addr;
@@ -2794,9 +2749,9 @@ rtl8169_interrupt(int irq, void *dev_instance)
 		break;
 #else
 		/* Rx interrupt */
-		if (status & (RxOK | RxOverflow | RxFIFOOver)) {
+		if (status & (RxOK | RxOverflow | RxFIFOOver))
 			rtl8169_rx_interrupt(dev, tp, ioaddr);
-		}
+
 		/* Tx interrupt */
 		if (status & (TxOK | TxErr))
 			rtl8169_tx_interrupt(dev, tp, ioaddr);
@@ -2928,7 +2883,7 @@ static void rtl_set_rx_mode(struct net_device *dev)
 	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 	u32 mc_filter[2];	/* Multicast hash filter */
-	int i, rx_mode;
+	int rx_mode;
 	u32 tmp = 0;
 
 	if (dev->flags & IFF_PROMISC) {
@@ -2948,6 +2903,8 @@ static void rtl_set_rx_mode(struct net_device *dev)
 		mc_filter[1] = mc_filter[0] = 0xffffffff;
 	} else {
 		struct dev_mc_list *mclist;
+		unsigned int i;
+
 		rx_mode = AcceptBroadcast | AcceptMyPhys;
 		mc_filter[1] = mc_filter[0] = 0;
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
@@ -3063,14 +3020,12 @@ static struct pci_driver rtl8169_pci_driver = {
 #endif
 };
 
-static int __init
-rtl8169_init_module(void)
+static int __init rtl8169_init_module(void)
 {
 	return pci_register_driver(&rtl8169_pci_driver);
 }
 
-static void __exit
-rtl8169_cleanup_module(void)
+static void __exit rtl8169_cleanup_module(void)
 {
 	pci_unregister_driver(&rtl8169_pci_driver);
 }
-- 
1.4.4.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 09/12] r8169: MSI support
       [not found] <20070426205714.GA12701@electric-eye.fr.zoreil.com>
                   ` (7 preceding siblings ...)
  2007-04-26 21:48 ` [PATCH 08/12] r8169: cleanup Francois Romieu
@ 2007-04-26 21:49 ` Francois Romieu
  2007-05-08  4:53   ` Jeff Garzik
  2007-04-26 21:49 ` [PATCH 10/12] r8169: add bit description for the TxPoll register Francois Romieu
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2007-04-26 21:49 UTC (permalink / raw)
  To: jeff; +Cc: netdev, Bernhard Walle, Edward Hsu

It is currently limited to 0x8136 and 0x8168. 8169sb/8110sb ought to
handle it as well where they support MSI.

Includes unregister_netdev() fix from Bernhard Walle <bwalle@suse.de>
against BUG_ON(irq_has_action(dev->first_msi_irq)) (2007/02/24).

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Fixed-by: Bernhard Walle <bernhard.walle@gmx.de>
Cc: Edward Hsu <edward_hsu@realtek.com>
---
 drivers/net/r8169.c |  102 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 97 insertions(+), 5 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 7a0c5e7..e6dbfc9 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -250,6 +250,9 @@ enum rtl_register_content {
 	CmdTxEnb	= 0x04,
 	RxBufEmpty	= 0x01,
 
+	/* TXPoll register p.5 */
+	FSWInt		= 1,		/* Forced software interrupt */
+
 	/* Cfg9346Bits */
 	Cfg9346_Lock	= 0x00,
 	Cfg9346_Unlock	= 0xc0,
@@ -271,6 +274,7 @@ enum rtl_register_content {
 	TxDMAShift = 8,	/* DMA burst value (0-7) is shift this many bits */
 
 	/* Config1 register p.24 */
+	MSIEnable	= (1 << 5),	/* Enable Message Signaled Interrupt */
 	PMEnable	= (1 << 0),	/* Power Management Enable */
 
 	/* Config2 register p. 25 */
@@ -414,6 +418,7 @@ struct rtl8169_private {
 	unsigned int (*link_ok)(void __iomem *);
 	struct delayed_work task;
 	unsigned wol_enabled : 1;
+	unsigned msi : 1;
 };
 
 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -1410,12 +1415,85 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	return -EOPNOTSUPP;
 }
 
+static irqreturn_t __devinit rtl_test_intr(int irq, void *dev_instance)
+{
+	struct rtl8169_private *tp = dev_instance;
+	void __iomem *ioaddr = tp->mmio_addr;
+	u32 status;
+
+	status = RTL_R16(IntrStatus);
+	if ((status == 0xffff) || !status)
+		return IRQ_NONE;
+
+	if (status & SWInt) {
+		tp->msi = 1;
+		smp_wmb();
+		RTL_W16(IntrStatus, SWInt);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit rtl_try_msi(struct rtl8169_private *tp)
+{
+	struct pci_dev *pdev = tp->pci_dev;
+	void __iomem *ioaddr = tp->mmio_addr;
+	unsigned int i;
+	int rc;
+
+	rc = pci_enable_msi(pdev);
+	if (rc < 0)
+		return 0;
+
+	RTL_W8(Config2, RTL_R8(Config2) | MSIEnable);
+
+	rc = request_irq(pdev->irq, rtl_test_intr, 0, pci_name(pdev), tp);
+	if (rc < 0)
+		goto err_disable_msi_0;
+
+	RTL_W16(IntrMask, SWInt);
+	RTL_W8(TxPoll, FSWInt);
+	/* Commit */
+	RTL_R8(IntrMask);
+
+	for (i = 0; i < 100; i++) {
+		smp_rmb();
+		if (tp->msi)
+			break;
+		msleep(10);
+	}
+
+	RTL_W16(IntrStatus, SWInt);
+	RTL_W16(IntrMask, 0);
+	RTL_R8(IntrMask);
+
+	free_irq(pdev->irq, tp);
+
+	smp_rmb();
+
+	if (!tp->msi && netif_msg_drv(tp))
+		goto err_status_ok_1;
+
+	tp->dev->irq = pdev->irq;
+out:
+	return rc;
+
+err_status_ok_1:
+	printk(KERN_INFO "%s: no MSI. Back to INTx.\n", pci_name(pdev));
+	rc = 0;
+err_disable_msi_0:
+	RTL_W8(Config2, RTL_R8(Config2) & ~MSIEnable);
+	pci_disable_msi(pdev);
+	goto out;
+}
+
 static const struct rtl_cfg_info {
 	void (*hw_start)(struct net_device *);
 	unsigned int region;
 	unsigned int align;
 	u16 intr_event;
 	u16 napi_event;
+	unsigned msi : 1;
 } rtl_cfg_infos [] = {
 	[RTL_CFG_0] = {
 		.hw_start	= rtl_hw_start_8169,
@@ -1423,7 +1501,8 @@ static const struct rtl_cfg_info {
 		.align		= 2,
 		.intr_event	= SYSErr | LinkChg | RxOverflow |
 				  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
-		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow
+		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
+		.msi		= 0
 	},
 	[RTL_CFG_1] = {
 		.hw_start	= rtl_hw_start_8168,
@@ -1431,7 +1510,8 @@ static const struct rtl_cfg_info {
 		.align		= 8,
 		.intr_event	= SYSErr | LinkChg | RxOverflow |
 				  TxErr | TxOK | RxOK | RxErr,
-		.napi_event	= TxErr | TxOK | RxOK | RxOverflow
+		.napi_event	= TxErr | TxOK | RxOK | RxOverflow,
+		.msi		= 1
 	},
 	[RTL_CFG_2] = {
 		.hw_start	= rtl_hw_start_8101,
@@ -1439,7 +1519,8 @@ static const struct rtl_cfg_info {
 		.align		= 8,
 		.intr_event	= SYSErr | LinkChg | RxOverflow | PCSTimeout |
 				  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
-		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow
+		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
+		.msi		= 1
 	}
 };
 
@@ -1663,6 +1744,12 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (rc < 0)
 		goto err_out_unmap_5;
 
+	if (cfg->msi) {
+		rc = rtl_try_msi(tp);
+		if (rc < 0)
+			goto err_out_unregister_netdev_6;
+	}
+
 	pci_set_drvdata(pdev, dev);
 
 	if (netif_msg_probe(tp)) {
@@ -1682,6 +1769,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 out:
 	return rc;
 
+err_out_unregister_netdev_6:
+	unregister_netdev(dev);
 err_out_unmap_5:
 	iounmap(ioaddr);
 err_out_free_res_4:
@@ -1703,6 +1792,9 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
 	flush_scheduled_work();
 
 	unregister_netdev(dev);
+	if (tp->msi)
+		pci_disable_msi(pdev);
+	tp->msi = 0;
 	rtl8169_release_board(pdev, dev, tp->mmio_addr);
 	pci_set_drvdata(pdev, NULL);
 }
@@ -1746,8 +1838,8 @@ static int rtl8169_open(struct net_device *dev)
 
 	smp_mb();
 
-	retval = request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED,
-			     dev->name, dev);
+	retval = request_irq(dev->irq, rtl8169_interrupt,
+			     tp->msi ? 0 : IRQF_SHARED, dev->name, dev);
 	if (retval < 0)
 		goto err_release_ring_2;
 
-- 
1.4.4.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 10/12] r8169: add bit description for the TxPoll register
       [not found] <20070426205714.GA12701@electric-eye.fr.zoreil.com>
                   ` (8 preceding siblings ...)
  2007-04-26 21:49 ` [PATCH 09/12] r8169: MSI support Francois Romieu
@ 2007-04-26 21:49 ` Francois Romieu
  2007-04-26 21:49 ` [PATCH 11/12] r8169: align the IP header when there is no DMA constraint Francois Romieu
  2007-04-26 21:49 ` [PATCH 12/12] r8169: mac address change support Francois Romieu
  11 siblings, 0 replies; 17+ messages in thread
From: Francois Romieu @ 2007-04-26 21:49 UTC (permalink / raw)
  To: jeff; +Cc: netdev, Edward Hsu

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Edward Hsu <edward_hsu@realtek.com>
---
 drivers/net/r8169.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index e6dbfc9..2cbb63b 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -251,7 +251,9 @@ enum rtl_register_content {
 	RxBufEmpty	= 0x01,
 
 	/* TXPoll register p.5 */
-	FSWInt		= 1,		/* Forced software interrupt */
+	HPQ		= 0x80,		/* Poll cmd on the high prio queue */
+	NPQ		= 0x40,		/* Poll cmd on the low prio queue */
+	FSWInt		= 0x01,		/* Forced software interrupt */
 
 	/* Cfg9346Bits */
 	Cfg9346_Lock	= 0x00,
@@ -2519,7 +2521,7 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	smp_wmb();
 
-	RTL_W8(TxPoll, 0x40);	/* set polling bit */
+	RTL_W8(TxPoll, NPQ);	/* set polling bit */
 
 	if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) {
 		netif_stop_queue(dev);
-- 
1.4.4.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 11/12] r8169: align the IP header when there is no DMA constraint
       [not found] <20070426205714.GA12701@electric-eye.fr.zoreil.com>
                   ` (9 preceding siblings ...)
  2007-04-26 21:49 ` [PATCH 10/12] r8169: add bit description for the TxPoll register Francois Romieu
@ 2007-04-26 21:49 ` Francois Romieu
  2007-04-27  4:45   ` Mike Isely
  2007-05-08  4:53   ` Jeff Garzik
  2007-04-26 21:49 ` [PATCH 12/12] r8169: mac address change support Francois Romieu
  11 siblings, 2 replies; 17+ messages in thread
From: Francois Romieu @ 2007-04-26 21:49 UTC (permalink / raw)
  To: jeff; +Cc: netdev, Philip Craig, Mike Isely

Align the IP header when the chipset can DMA at any location (plain 0x8169).
Otherwise (0x8136/0x8168) obey the constraint imposed by the hardware.

This patch complements the previous alignment rework done for copybreak.

Original idea from Philip Craig <philipc@snapgear.com>

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Philip Craig <philipc@snapgear.com>
Cc: Mike Isely <isely@pobox.com>
---
 drivers/net/r8169.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 2cbb63b..2667862 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1500,7 +1500,7 @@ static const struct rtl_cfg_info {
 	[RTL_CFG_0] = {
 		.hw_start	= rtl_hw_start_8169,
 		.region		= 1,
-		.align		= 2,
+		.align		= 0,
 		.intr_event	= SYSErr | LinkChg | RxOverflow |
 				  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
 		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
@@ -2189,13 +2189,17 @@ static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
 {
 	struct sk_buff *skb;
 	dma_addr_t mapping;
+	unsigned int pad;
 	int ret = 0;
 
-	skb = dev_alloc_skb(rx_buf_sz + align);
+	pad = align ? align : NET_IP_ALIGN;
+
+	skb = dev_alloc_skb(rx_buf_sz + pad);
 	if (!skb)
 		goto err_out;
 
-	skb_reserve(skb, (align - 1) & (unsigned long)skb->data);
+
+	skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad);
 	*sk_buff = skb;
 
 	mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
-- 
1.4.4.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 12/12] r8169: mac address change support
       [not found] <20070426205714.GA12701@electric-eye.fr.zoreil.com>
                   ` (10 preceding siblings ...)
  2007-04-26 21:49 ` [PATCH 11/12] r8169: align the IP header when there is no DMA constraint Francois Romieu
@ 2007-04-26 21:49 ` Francois Romieu
  2007-05-08  4:55   ` Jeff Garzik
  11 siblings, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2007-04-26 21:49 UTC (permalink / raw)
  To: jeff; +Cc: netdev, Edward Hsu

Merged from Realtek's r8169-6.001 driver.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Edward Hsu <edward_hsu@realtek.com>
---
 drivers/net/r8169.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 2667862..5b42176 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -182,6 +182,7 @@ static struct {
 
 enum rtl_registers {
 	MAC0		= 0,	/* Ethernet hardware address. */
+	MAC4		= 4,
 	MAR0		= 8,	/* Multicast filter. */
 	CounterAddrLow		= 0x10,
 	CounterAddrHigh		= 0x14,
@@ -1391,6 +1392,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);
@@ -1712,6 +1743,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;
-- 
1.4.4.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH 11/12] r8169: align the IP header when there is no DMA constraint
  2007-04-26 21:49 ` [PATCH 11/12] r8169: align the IP header when there is no DMA constraint Francois Romieu
@ 2007-04-27  4:45   ` Mike Isely
  2007-05-08  4:53   ` Jeff Garzik
  1 sibling, 0 replies; 17+ messages in thread
From: Mike Isely @ 2007-04-27  4:45 UTC (permalink / raw)
  To: Francois Romieu; +Cc: jeff, netdev, Philip Craig, Mike Isely at pobox


On Thu, 26 Apr 2007, Francois Romieu wrote:

> Align the IP header when the chipset can DMA at any location (plain 0x8169).
> Otherwise (0x8136/0x8168) obey the constraint imposed by the hardware.
> 
> This patch complements the previous alignment rework done for copybreak.
> 
> Original idea from Philip Craig <philipc@snapgear.com>
> 
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Cc: Philip Craig <philipc@snapgear.com>
> Cc: Mike Isely <isely@pobox.com>
> ---

   [...]


Francois:

I just tried this.  It worked fine here (and a test with rsync shows 
bandwidth to be about where I'd expect).  Some more detail...

I grabbed the following:

http://www.fr.zoreil.com/linux/kernel/2.6.x/2.6.21-rc7/r8169-20070416.tar.bz2

That appears to also include the patch below (I could not successfully 
just apply the one piece).  I then applied the entire series to the 
r8169 driver from the newly minted vanilla 2.6.21 kernel, replaced that 
module and tested.  No ill effects.  Everything looks good here.  To 
refresh your memory, my system is an Intel Core2 Duo system built around 
a Gigabyte GA-945GM-S2 mainboard.  And of course it has an r8169 class 
chip.  Here's the relevant output from "lspci -vvnn":

<CUT>
02:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller [10ec:8168] (rev 01)
	Subsystem: Giga-byte Technology Unknown device [1458:e000]
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 0, Cache Line Size: 32 bytes
	Interrupt: pin A routed to IRQ 221
	Region 0: I/O ports at a000 [size=256]
	Region 2: Memory at e1000000 (64-bit, non-prefetchable) [size=4K]
	[virtual] Expansion ROM at 80000000 [disabled] [size=64K]
	Capabilities: [40] Power Management version 2
		Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA PME(D0-,D1+,D2+,D3hot+,D3cold+)
		Status: D0 PME-Enable- DSel=0 DScale=0 PME-
	Capabilities: [48] Vital Product Data
	Capabilities: [50] Message Signalled Interrupts: Mask- 64bit+ Queue=0/1 Enable+
		Address: 00000000fee0100c  Data: 41e1
	Capabilities: [60] Express Endpoint IRQ 0
		Device: Supported: MaxPayload 1024 bytes, PhantFunc 0, ExtTag+
		Device: Latency L0s unlimited, L1 unlimited
		Device: AtnBtn+ AtnInd+ PwrInd+
		Device: Errors: Correctable- Non-Fatal- Fatal- Unsupported-
		Device: RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
		Device: MaxPayload 128 bytes, MaxReadReq 4096 bytes
		Link: Supported Speed 2.5Gb/s, Width x1, ASPM L0s, Port 0
		Link: Latency L0s unlimited, L1 unlimited
		Link: ASPM Disabled RCB 64 bytes CommClk- ExtSynch-
		Link: Speed 2.5Gb/s, Width x1
	Capabilities: [84] Vendor Specific Information
	Capabilities: [100] Advanced Error Reporting
	Capabilities: [12c] Virtual Channel
	Capabilities: [148] Device Serial Number 68-81-ec-10-00-00-00-25
	Capabilities: [154] Power Budgeting
</CUT>

Everything looks good here.

  -Mike



-- 
                        |         Mike Isely          |     PGP fingerprint
     Spammers Die!!     |                             | 03 54 43 4D 75 E5 CC 92
                        |   isely @ pobox (dot) com   | 71 16 01 E2 B5 F5 C1 E8
                        |                             |

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 08/12] r8169: cleanup
  2007-04-26 21:48 ` [PATCH 08/12] r8169: cleanup Francois Romieu
@ 2007-05-08  4:52   ` Jeff Garzik
  0 siblings, 0 replies; 17+ messages in thread
From: Jeff Garzik @ 2007-05-08  4:52 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev, Edward Hsu

Francois Romieu wrote:
> No functionnal change:
> - trim the old history log
> - whitespace/indent/case police
> - unsigned int where signedness does not matte
> - removal of obsolete assert
> - needless cast from void * (dev_instance)
> 
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Cc: Edward Hsu <edward_hsu@realtek.com>
> ---
>  drivers/net/r8169.c |  311 ++++++++++++++++++++++-----------------------------
>  1 files changed, 133 insertions(+), 178 deletions(-)

ACK patches 1-8



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 09/12] r8169: MSI support
  2007-04-26 21:49 ` [PATCH 09/12] r8169: MSI support Francois Romieu
@ 2007-05-08  4:53   ` Jeff Garzik
  0 siblings, 0 replies; 17+ messages in thread
From: Jeff Garzik @ 2007-05-08  4:53 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev, Bernhard Walle, Edward Hsu

Francois Romieu wrote:
> It is currently limited to 0x8136 and 0x8168. 8169sb/8110sb ought to
> handle it as well where they support MSI.
> 
> Includes unregister_netdev() fix from Bernhard Walle <bwalle@suse.de>
> against BUG_ON(irq_has_action(dev->first_msi_irq)) (2007/02/24).
> 
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Fixed-by: Bernhard Walle <bernhard.walle@gmx.de>
> Cc: Edward Hsu <edward_hsu@realtek.com>
> ---
>  drivers/net/r8169.c |  102 ++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 files changed, 97 insertions(+), 5 deletions(-)

PCI MSI is increasingly mature upstream, so I do not wish to add more 
IRQ handling test code to each individual driver.

Just add the MSI support without the test interrupt stuff.

	Jeff




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 11/12] r8169: align the IP header when there is no DMA constraint
  2007-04-26 21:49 ` [PATCH 11/12] r8169: align the IP header when there is no DMA constraint Francois Romieu
  2007-04-27  4:45   ` Mike Isely
@ 2007-05-08  4:53   ` Jeff Garzik
  1 sibling, 0 replies; 17+ messages in thread
From: Jeff Garzik @ 2007-05-08  4:53 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev, Philip Craig, Mike Isely

Francois Romieu wrote:
> Align the IP header when the chipset can DMA at any location (plain 0x8169).
> Otherwise (0x8136/0x8168) obey the constraint imposed by the hardware.
> 
> This patch complements the previous alignment rework done for copybreak.
> 
> Original idea from Philip Craig <philipc@snapgear.com>
> 
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Cc: Philip Craig <philipc@snapgear.com>
> Cc: Mike Isely <isely@pobox.com>
> ---
>  drivers/net/r8169.c |   10 +++++++---
>  1 files changed, 7 insertions(+), 3 deletions(-)

ACK patches 10-11



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 12/12] r8169: mac address change support
  2007-04-26 21:49 ` [PATCH 12/12] r8169: mac address change support Francois Romieu
@ 2007-05-08  4:55   ` Jeff Garzik
  0 siblings, 0 replies; 17+ messages in thread
From: Jeff Garzik @ 2007-05-08  4:55 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev, Edward Hsu

Francois Romieu wrote:
> Merged from Realtek's r8169-6.001 driver.
> 
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Cc: Edward Hsu <edward_hsu@realtek.com>
> ---
>  drivers/net/r8169.c |   32 ++++++++++++++++++++++++++++++++
>  1 files changed, 32 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
> index 2667862..5b42176 100644
> --- a/drivers/net/r8169.c
> +++ b/drivers/net/r8169.c
> @@ -182,6 +182,7 @@ static struct {
>  
>  enum rtl_registers {
>  	MAC0		= 0,	/* Ethernet hardware address. */
> +	MAC4		= 4,
>  	MAR0		= 8,	/* Multicast filter. */
>  	CounterAddrLow		= 0x10,
>  	CounterAddrHigh		= 0x14,
> @@ -1391,6 +1392,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);
> @@ -1712,6 +1743,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;

Code seems OK, except the register interaction (particularly 9346 
lock/unlock) can race with other parts of the code.

	Jeff




^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2007-05-08  4:55 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20070426205714.GA12701@electric-eye.fr.zoreil.com>
2007-04-26 21:47 ` [PATCH 01/12] r8169: add per-device hw_start handler (1/2) Francois Romieu
2007-04-26 21:48 ` [PATCH 02/12] r8169: add per-device hw_start handler (2/2) Francois Romieu
2007-04-26 21:48 ` [PATCH 03/12] r8169: merge with version 6.001.00 of Realtek's r8169 driver Francois Romieu
2007-04-26 21:48 ` [PATCH 04/12] r8169: merge with version 8.001.00 of Realtek's r8168 driver Francois Romieu
2007-04-26 21:48 ` [PATCH 05/12] r8169: confusion between hardware and IP header alignment Francois Romieu
2007-04-26 21:48 ` [PATCH 06/12] r8169: small 8101 comment Francois Romieu
2007-04-26 21:48 ` [PATCH 07/12] r8169: remove the media option Francois Romieu
2007-04-26 21:48 ` [PATCH 08/12] r8169: cleanup Francois Romieu
2007-05-08  4:52   ` Jeff Garzik
2007-04-26 21:49 ` [PATCH 09/12] r8169: MSI support Francois Romieu
2007-05-08  4:53   ` Jeff Garzik
2007-04-26 21:49 ` [PATCH 10/12] r8169: add bit description for the TxPoll register Francois Romieu
2007-04-26 21:49 ` [PATCH 11/12] r8169: align the IP header when there is no DMA constraint Francois Romieu
2007-04-27  4:45   ` Mike Isely
2007-05-08  4:53   ` Jeff Garzik
2007-04-26 21:49 ` [PATCH 12/12] r8169: mac address change support Francois Romieu
2007-05-08  4:55   ` Jeff Garzik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).