Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next v2 2/7] r8169: modify the flow of the hw reset
From: Hayes Wang @ 2011-07-06  7:58 UTC (permalink / raw)
  To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
In-Reply-To: <1309939088-31994-1-git-send-email-hayeswang@realtek.com>

-Disable tx and rx by resetting hw, so replace rtl8169_asic_down with
 rtl8169_hw_reset.
-RxConfig bits 0 ~ 5 have to be clear before hw reset to avoid the
 coming of rx data.
-Certain chips need to do some checking before reset.
-Remove hw reset which is done before hw_start, because it would be
 done in close or down functions.
-Move rtl8169_init_ring_indexes function into rtl_hw_reset function.
 The indexes of tx and rx need to be zero only when the hw reset
 occures.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/r8169.c |   53 ++++++++++++++++++++++++++------------------------
 1 files changed, 28 insertions(+), 25 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index a8de449..a579da0 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1071,13 +1071,6 @@ static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
 	RTL_W16(IntrStatus, 0xffff);
 }
 
-static void rtl8169_asic_down(void __iomem *ioaddr)
-{
-	RTL_W8(ChipCmd, 0x00);
-	rtl8169_irq_mask_and_ack(ioaddr);
-	RTL_R16(CPlusCmd);
-}
-
 static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
@@ -3337,6 +3330,11 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
 	}
 }
 
+static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)
+{
+	tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
+}
+
 static void rtl_hw_reset(struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
@@ -3349,8 +3347,10 @@ static void rtl_hw_reset(struct rtl8169_private *tp)
 	for (i = 0; i < 100; i++) {
 		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
 			break;
-		msleep_interruptible(1);
+		udelay(100);
 	}
+
+	rtl8169_init_ring_indexes(tp);
 }
 
 static int __devinit
@@ -3732,6 +3732,16 @@ err_pm_runtime_put:
 	goto out;
 }
 
+static void rtl_rx_close(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+	u32 rxcfg = RTL_R32(RxConfig);
+
+	rxcfg &= ~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast |
+		   AcceptMyPhys | AcceptAllPhys);
+	RTL_W32(RxConfig, rxcfg);
+}
+
 static void rtl8169_hw_reset(struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
@@ -3739,19 +3749,19 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
 	/* Disable interrupts */
 	rtl8169_irq_mask_and_ack(ioaddr);
 
+	rtl_rx_close(tp);
+
 	if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
 	    tp->mac_version == RTL_GIGA_MAC_VER_28 ||
 	    tp->mac_version == RTL_GIGA_MAC_VER_31) {
 		while (RTL_R8(TxPoll) & NPQ)
 			udelay(20);
-
+	} else {
+		RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq);
+		udelay(100);
 	}
 
-	/* Reset the chipset */
-	RTL_W8(ChipCmd, CmdReset);
-
-	/* PCI commit */
-	RTL_R8(ChipCmd);
+	rtl_hw_reset(tp);
 }
 
 static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp)
@@ -3771,8 +3781,6 @@ static void rtl_hw_start(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 
-	rtl_hw_reset(tp);
-
 	tp->hw_start(dev);
 
 	netif_start_queue(dev);
@@ -4581,11 +4589,6 @@ err_out:
 	return -ENOMEM;
 }
 
-static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)
-{
-	tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
-}
-
 static int rtl8169_init_ring(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -4713,7 +4716,7 @@ static void rtl8169_reset_task(struct work_struct *work)
 
 	rtl8169_tx_clear(tp);
 
-	rtl8169_init_ring_indexes(tp);
+	rtl8169_hw_reset(tp);
 	rtl_hw_start(dev);
 	netif_wake_queue(dev);
 	rtl8169_check_link_status(dev, tp, tp->mmio_addr);
@@ -5127,7 +5130,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
 		 * the chip, so just exit the loop.
 		 */
 		if (unlikely(!netif_running(dev))) {
-			rtl8169_asic_down(ioaddr);
+			rtl8169_hw_reset(tp);
 			break;
 		}
 
@@ -5250,7 +5253,7 @@ static void rtl8169_down(struct net_device *dev)
 
 	spin_lock_irq(&tp->lock);
 
-	rtl8169_asic_down(ioaddr);
+	rtl8169_hw_reset(tp);
 	/*
 	 * At this point device interrupts can not be enabled in any function,
 	 * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task,
@@ -5504,7 +5507,7 @@ static void rtl_shutdown(struct pci_dev *pdev)
 
 	spin_lock_irq(&tp->lock);
 
-	rtl8169_asic_down(ioaddr);
+	rtl8169_hw_reset(tp);
 
 	spin_unlock_irq(&tp->lock);
 
-- 
1.7.3.2

^ permalink raw reply related

* [PATCH net-next v2 3/7] r8169: adjust the settings about RxConfig
From: Hayes Wang @ 2011-07-06  7:58 UTC (permalink / raw)
  To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
In-Reply-To: <1309939088-31994-1-git-send-email-hayeswang@realtek.com>

Set the init value before reset in probe function. And then just
modify the relative bits and keep the init settings.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/r8169.c |   54 +++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index a579da0..50bf897 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -282,7 +282,6 @@ enum rtl_registers {
 #define	RXCFG_DMA_SHIFT			8
 					/* Unlimited maximum PCI burst. */
 #define	RX_DMA_BURST			(7 << RXCFG_DMA_SHIFT)
-#define RTL_RX_CONFIG_MASK		0xff7e1880u
 
 	RxMissed	= 0x4c,
 	Cfg9346		= 0x50,
@@ -724,8 +723,6 @@ static void rtl8169_down(struct net_device *dev);
 static void rtl8169_rx_clear(struct rtl8169_private *tp);
 static int rtl8169_poll(struct napi_struct *napi, int budget);
 
-static const unsigned int rtl8169_rx_config = RX_FIFO_THRESH | RX_DMA_BURST;
-
 static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
@@ -3330,6 +3327,42 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
 	}
 }
 
+static void rtl_init_rxcfg(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	switch (tp->mac_version) {
+	case RTL_GIGA_MAC_VER_01:
+	case RTL_GIGA_MAC_VER_02:
+	case RTL_GIGA_MAC_VER_03:
+	case RTL_GIGA_MAC_VER_04:
+	case RTL_GIGA_MAC_VER_05:
+	case RTL_GIGA_MAC_VER_06:
+	case RTL_GIGA_MAC_VER_10:
+	case RTL_GIGA_MAC_VER_11:
+	case RTL_GIGA_MAC_VER_12:
+	case RTL_GIGA_MAC_VER_13:
+	case RTL_GIGA_MAC_VER_14:
+	case RTL_GIGA_MAC_VER_15:
+	case RTL_GIGA_MAC_VER_16:
+	case RTL_GIGA_MAC_VER_17:
+		RTL_W32(RxConfig, RX_FIFO_THRESH | RX_DMA_BURST);
+		break;
+	case RTL_GIGA_MAC_VER_18:
+	case RTL_GIGA_MAC_VER_19:
+	case RTL_GIGA_MAC_VER_20:
+	case RTL_GIGA_MAC_VER_21:
+	case RTL_GIGA_MAC_VER_22:
+	case RTL_GIGA_MAC_VER_23:
+	case RTL_GIGA_MAC_VER_24:
+		RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
+		break;
+	default:
+		RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST);
+		break;
+	}
+}
+
 static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)
 {
 	tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
@@ -3457,6 +3490,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (!pci_is_pcie(pdev))
 		netif_info(tp, probe, dev, "not PCI Express\n");
 
+	/* Identify chip attached to board */
+	rtl8169_get_mac_version(tp, dev, cfg->default_ver);
+
+	rtl_init_rxcfg(tp);
+
 	RTL_W16(IntrMask, 0x0000);
 
 	rtl_hw_reset(tp);
@@ -3465,9 +3503,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	pci_set_master(pdev);
 
-	/* Identify chip attached to board */
-	rtl8169_get_mac_version(tp, dev, cfg->default_ver);
-
 	/*
 	 * Pretend we are using VLANs; This bypasses a nasty bug where
 	 * Interrupts stop flowing on high load on 8110SCd controllers.
@@ -3767,10 +3802,6 @@ static void rtl8169_hw_reset(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;
-
-	cfg |= (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK);
-	RTL_W32(RxConfig, cfg);
 
 	/* Set DMA burst size and Interframe Gap Time */
 	RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
@@ -5336,8 +5367,7 @@ static void rtl_set_rx_mode(struct net_device *dev)
 
 	spin_lock_irqsave(&tp->lock, flags);
 
-	tmp = rtl8169_rx_config | rx_mode |
-	      (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK);
+	tmp = RTL_R32(RxConfig) | rx_mode;
 
 	if (tp->mac_version > RTL_GIGA_MAC_VER_06) {
 		u32 data = mc_filter[0];
-- 
1.7.3.2

^ permalink raw reply related

* [PATCH net-next v2 5/7] r8169: support RTL8111E-VL
From: Hayes Wang @ 2011-07-06  7:58 UTC (permalink / raw)
  To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
In-Reply-To: <1309939088-31994-1-git-send-email-hayeswang@realtek.com>

Support RTL8111E-VL

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/r8169.c |  187 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 180 insertions(+), 7 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index f83e9fa..6bfabe2 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -41,6 +41,7 @@
 #define FIRMWARE_8168D_2	"rtl_nic/rtl8168d-2.fw"
 #define FIRMWARE_8168E_1	"rtl_nic/rtl8168e-1.fw"
 #define FIRMWARE_8168E_2	"rtl_nic/rtl8168e-2.fw"
+#define FIRMWARE_8168E_3	"rtl_nic/rtl8168e-3.fw"
 #define FIRMWARE_8105E_1	"rtl_nic/rtl8105e-1.fw"
 
 #ifdef RTL8169_DEBUG
@@ -131,6 +132,7 @@ enum mac_version {
 	RTL_GIGA_MAC_VER_31,
 	RTL_GIGA_MAC_VER_32,
 	RTL_GIGA_MAC_VER_33,
+	RTL_GIGA_MAC_VER_34,
 	RTL_GIGA_MAC_NONE   = 0xff,
 };
 
@@ -214,7 +216,9 @@ static const struct {
 	[RTL_GIGA_MAC_VER_32] =
 		_R("RTL8168e/8111e",	RTL_TD_1, FIRMWARE_8168E_1),
 	[RTL_GIGA_MAC_VER_33] =
-		_R("RTL8168e/8111e",	RTL_TD_1, FIRMWARE_8168E_2)
+		_R("RTL8168e/8111e",	RTL_TD_1, FIRMWARE_8168E_2),
+	[RTL_GIGA_MAC_VER_34] =
+		_R("RTL8168evl/8111evl",RTL_TD_1, FIRMWARE_8168E_3)
 };
 #undef _R
 
@@ -1148,6 +1152,39 @@ static void rtl8169_xmii_reset_enable(struct rtl8169_private *tp)
 	rtl_writephy(tp, MII_BMCR, val & 0xffff);
 }
 
+static void rtl_link_chg_patch(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+	struct net_device *dev = tp->dev;
+
+	if (!netif_running(dev))
+		return;
+
+	if (tp->mac_version == RTL_GIGA_MAC_VER_34) {
+		if (RTL_R8(PHYstatus) & _1000bpsF) {
+			rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111,
+				      0x00000011, ERIAR_EXGMAC);
+			rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111,
+				      0x00000005, ERIAR_EXGMAC);
+		} else if (RTL_R8(PHYstatus) & _100bps) {
+			rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111,
+				      0x0000001f, ERIAR_EXGMAC);
+			rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111,
+				      0x00000005, ERIAR_EXGMAC);
+		} else {
+			rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111,
+				      0x0000001f, ERIAR_EXGMAC);
+			rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111,
+				      0x0000003f, ERIAR_EXGMAC);
+		}
+		/* Reset packet filter */
+		rtl_eri_write_w0w1(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01,
+				   0x00, ERIAR_EXGMAC);
+		rtl_eri_write_w0w1(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00,
+				   0x01, ERIAR_EXGMAC);
+	}
+}
+
 static void __rtl8169_check_link_status(struct net_device *dev,
 					struct rtl8169_private *tp,
 					void __iomem *ioaddr, bool pm)
@@ -1156,6 +1193,7 @@ static void __rtl8169_check_link_status(struct net_device *dev,
 
 	spin_lock_irqsave(&tp->lock, flags);
 	if (tp->link_ok(ioaddr)) {
+		rtl_link_chg_patch(tp);
 		/* This is to cancel a scheduled suspend if there's one. */
 		if (pm)
 			pm_request_resume(&tp->pci_dev->dev);
@@ -1684,6 +1722,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
 		int mac_version;
 	} mac_info[] = {
 		/* 8168E family. */
+		{ 0x7c800000, 0x2c800000,	RTL_GIGA_MAC_VER_34 },
 		{ 0x7cf00000, 0x2c200000,	RTL_GIGA_MAC_VER_33 },
 		{ 0x7cf00000, 0x2c100000,	RTL_GIGA_MAC_VER_32 },
 		{ 0x7c800000, 0x2c000000,	RTL_GIGA_MAC_VER_33 },
@@ -2661,7 +2700,7 @@ static void rtl8168d_4_hw_phy_config(struct rtl8169_private *tp)
 	rtl_patchphy(tp, 0x0d, 1 << 5);
 }
 
-static void rtl8168e_hw_phy_config(struct rtl8169_private *tp)
+static void rtl8168e_1_hw_phy_config(struct rtl8169_private *tp)
 {
 	static const struct phy_reg phy_reg_init[] = {
 		/* Enable Delay cap */
@@ -2734,6 +2773,91 @@ static void rtl8168e_hw_phy_config(struct rtl8169_private *tp)
 	rtl_writephy(tp, 0x0d, 0x0000);
 }
 
+static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp)
+{
+	static const struct phy_reg phy_reg_init[] = {
+		/* Enable Delay cap */
+		{ 0x1f, 0x0004 },
+		{ 0x1f, 0x0007 },
+		{ 0x1e, 0x00ac },
+		{ 0x18, 0x0006 },
+		{ 0x1f, 0x0002 },
+		{ 0x1f, 0x0000 },
+		{ 0x1f, 0x0000 },
+
+		/* Channel estimation fine tune */
+		{ 0x1f, 0x0003 },
+		{ 0x09, 0xa20f },
+		{ 0x1f, 0x0000 },
+		{ 0x1f, 0x0000 },
+
+		/* Green Setting */
+		{ 0x1f, 0x0005 },
+		{ 0x05, 0x8b5b },
+		{ 0x06, 0x9222 },
+		{ 0x05, 0x8b6d },
+		{ 0x06, 0x8000 },
+		{ 0x05, 0x8b76 },
+		{ 0x06, 0x8000 },
+		{ 0x1f, 0x0000 }
+	};
+
+	rtl_apply_firmware(tp);
+
+	rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+
+	/* For 4-corner performance improve */
+	rtl_writephy(tp, 0x1f, 0x0005);
+	rtl_writephy(tp, 0x05, 0x8b80);
+	rtl_w1w0_phy(tp, 0x17, 0x0006, 0x0000);
+	rtl_writephy(tp, 0x1f, 0x0000);
+
+	/* PHY auto speed down */
+	rtl_writephy(tp, 0x1f, 0x0004);
+	rtl_writephy(tp, 0x1f, 0x0007);
+	rtl_writephy(tp, 0x1e, 0x002d);
+	rtl_w1w0_phy(tp, 0x18, 0x0010, 0x0000);
+	rtl_writephy(tp, 0x1f, 0x0002);
+	rtl_writephy(tp, 0x1f, 0x0000);
+	rtl_w1w0_phy(tp, 0x14, 0x8000, 0x0000);
+
+	/* improve 10M EEE waveform */
+	rtl_writephy(tp, 0x1f, 0x0005);
+	rtl_writephy(tp, 0x05, 0x8b86);
+	rtl_w1w0_phy(tp, 0x06, 0x0001, 0x0000);
+	rtl_writephy(tp, 0x1f, 0x0000);
+
+	/* Improve 2-pair detection performance */
+	rtl_writephy(tp, 0x1f, 0x0005);
+	rtl_writephy(tp, 0x05, 0x8b85);
+	rtl_w1w0_phy(tp, 0x06, 0x4000, 0x0000);
+	rtl_writephy(tp, 0x1f, 0x0000);
+
+	/* EEE setting */
+	rtl_eri_write_w0w1(tp->mmio_addr, 0x1b0, ERIAR_MASK_1111, 0x0003,
+			   0x0000, ERIAR_EXGMAC);
+	rtl_writephy(tp, 0x1f, 0x0005);
+	rtl_writephy(tp, 0x05, 0x8b85);
+	rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000);
+	rtl_writephy(tp, 0x1f, 0x0004);
+	rtl_writephy(tp, 0x1f, 0x0007);
+	rtl_writephy(tp, 0x1e, 0x0020);
+	rtl_w1w0_phy(tp, 0x06, 0x0000, 0x0100);
+	rtl_writephy(tp, 0x1f, 0x0002);
+	rtl_writephy(tp, 0x1f, 0x0000);
+	rtl_writephy(tp, 0x0d, 0x0007);
+	rtl_writephy(tp, 0x0e, 0x003c);
+	rtl_writephy(tp, 0x0d, 0x4007);
+	rtl_writephy(tp, 0x0e, 0x0000);
+	rtl_writephy(tp, 0x0d, 0x0000);
+
+	/* Green feature */
+	rtl_writephy(tp, 0x1f, 0x0003);
+	rtl_w1w0_phy(tp, 0x19, 0x0000, 0x0001);
+	rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0400);
+	rtl_writephy(tp, 0x1f, 0x0000);
+}
+
 static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
 {
 	static const struct phy_reg phy_reg_init[] = {
@@ -2853,7 +2977,10 @@ static void rtl_hw_phy_config(struct net_device *dev)
 		break;
 	case RTL_GIGA_MAC_VER_32:
 	case RTL_GIGA_MAC_VER_33:
-		rtl8168e_hw_phy_config(tp);
+		rtl8168e_1_hw_phy_config(tp);
+		break;
+	case RTL_GIGA_MAC_VER_34:
+		rtl8168e_2_hw_phy_config(tp);
 		break;
 
 	default:
@@ -3359,6 +3486,7 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
 	case RTL_GIGA_MAC_VER_31:
 	case RTL_GIGA_MAC_VER_32:
 	case RTL_GIGA_MAC_VER_33:
+	case RTL_GIGA_MAC_VER_34:
 		ops->down	= r8168_pll_power_down;
 		ops->up		= r8168_pll_power_up;
 		break;
@@ -3834,6 +3962,9 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
 	    tp->mac_version == RTL_GIGA_MAC_VER_31) {
 		while (RTL_R8(TxPoll) & NPQ)
 			udelay(20);
+	} else if (tp->mac_version == RTL_GIGA_MAC_VER_34) {
+		while (!(RTL_R32(TxConfig) & TXCFG_EMPTY))
+			udelay(100);
 	} else {
 		RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq);
 		udelay(100);
@@ -4241,9 +4372,9 @@ static void rtl_hw_start_8168d_4(void __iomem *ioaddr, struct pci_dev *pdev)
 	rtl_enable_clock_request(pdev);
 }
 
-static void rtl_hw_start_8168e(void __iomem *ioaddr, struct pci_dev *pdev)
+static void rtl_hw_start_8168e_1(void __iomem *ioaddr, struct pci_dev *pdev)
 {
-	static const struct ephy_info e_info_8168e[] = {
+	static const struct ephy_info e_info_8168e_1[] = {
 		{ 0x00, 0x0200,	0x0100 },
 		{ 0x00, 0x0000,	0x0004 },
 		{ 0x06, 0x0002,	0x0001 },
@@ -4261,7 +4392,7 @@ static void rtl_hw_start_8168e(void __iomem *ioaddr, struct pci_dev *pdev)
 
 	rtl_csi_access_enable_2(ioaddr);
 
-	rtl_ephy_init(ioaddr, e_info_8168e, ARRAY_SIZE(e_info_8168e));
+	rtl_ephy_init(ioaddr, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1));
 
 	rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
@@ -4276,6 +4407,45 @@ static void rtl_hw_start_8168e(void __iomem *ioaddr, struct pci_dev *pdev)
 	RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en);
 }
 
+static void rtl_hw_start_8168e_2(void __iomem *ioaddr, struct pci_dev *pdev)
+{
+	static const struct ephy_info e_info_8168e_2[] = {
+		{ 0x09, 0x0000,	0x0080 },
+		{ 0x19, 0x0000,	0x0224 }
+	};
+
+	rtl_csi_access_enable_1(ioaddr);
+
+	rtl_ephy_init(ioaddr, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2));
+
+	rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+
+	rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+	rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+	rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC);
+	rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC);
+	rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC);
+	rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_1111, 0x07ff0060, ERIAR_EXGMAC);
+	rtl_eri_write_w0w1(ioaddr, 0x1b0, ERIAR_MASK_0001, 0x00, 0x10,
+			   ERIAR_EXGMAC);
+	rtl_eri_write_w0w1(ioaddr, 0xd4, ERIAR_MASK_0011, 0xff00, 0x0c00,
+			   ERIAR_EXGMAC);
+
+	RTL_W8(MaxTxPacketSize, 0x27);
+
+	rtl_disable_clock_request(pdev);
+
+	RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO);
+	RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB);
+
+	/* Adjust EEE LED frequency */
+	RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07);
+
+	RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN);
+	RTL_W32(MISC, RTL_R32(MISC) | PWM_EN);
+	RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en);
+}
+
 static void rtl_hw_start_8168(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -4364,7 +4534,10 @@ static void rtl_hw_start_8168(struct net_device *dev)
 
 	case RTL_GIGA_MAC_VER_32:
 	case RTL_GIGA_MAC_VER_33:
-		rtl_hw_start_8168e(ioaddr, pdev);
+		rtl_hw_start_8168e_1(ioaddr, pdev);
+		break;
+	case RTL_GIGA_MAC_VER_34:
+		rtl_hw_start_8168e_2(ioaddr, pdev);
 		break;
 
 	default:
-- 
1.7.3.2

^ permalink raw reply related

* [PATCH net-next v2 6/7] r8169: fix wake on lan setting for non-8111E
From: Hayes Wang @ 2011-07-06  7:58 UTC (permalink / raw)
  To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
In-Reply-To: <1309939088-31994-1-git-send-email-hayeswang@realtek.com>

Only 8111E needs enable RxConfig bit 0 ~ 3 when suspending or
shutdowning when supporting wake on lan.

Signed-off-by: Hayes Wang <hayeswang@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 6bfabe2..8551848 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -3390,8 +3390,10 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
 		rtl_writephy(tp, 0x1f, 0x0000);
 		rtl_writephy(tp, MII_BMCR, 0x0000);
 
-		RTL_W32(RxConfig, RTL_R32(RxConfig) |
-			AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
+		if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
+		    tp->mac_version == RTL_GIGA_MAC_VER_33)
+			RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast |
+				AcceptMulticast | AcceptMyPhys);
 		return;
 	}
 
-- 
1.7.3.2

^ permalink raw reply related

* [PATCH net-next v2 7/7] r8169: don't enable rx when shutdown
From: Hayes Wang @ 2011-07-06  7:58 UTC (permalink / raw)
  To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
In-Reply-To: <1309939088-31994-1-git-send-email-hayeswang@realtek.com>

Only 8111b needs to enable rx when shutdown for supporting WOL.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/r8169.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 8551848..99a2f30 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -5760,8 +5760,11 @@ static void rtl_shutdown(struct pci_dev *pdev)
 	spin_unlock_irq(&tp->lock);
 
 	if (system_state == SYSTEM_POWER_OFF) {
-		/* WoL fails with some 8168 when the receiver is disabled. */
-		if (tp->features & RTL_FEATURE_WOL) {
+		/* WoL fails with 8168b when the receiver is disabled. */
+		if ((tp->mac_version == RTL_GIGA_MAC_VER_11 ||
+		     tp->mac_version == RTL_GIGA_MAC_VER_12 ||
+		     tp->mac_version == RTL_GIGA_MAC_VER_17) &&
+		    (tp->features & RTL_FEATURE_WOL)) {
 			pci_clear_master(pdev);
 
 			RTL_W8(ChipCmd, CmdRxEnb);
-- 
1.7.3.2

^ permalink raw reply related

* [PATCH net-next v2 4/7] r8169: add ERI functions
From: Hayes Wang @ 2011-07-06  7:58 UTC (permalink / raw)
  To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
In-Reply-To: <1309939088-31994-1-git-send-email-hayeswang@realtek.com>

Add the ERI functions which would be used by the new chips.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/r8169.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 50bf897..f83e9fa 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1043,6 +1043,49 @@ static u32 rtl_csi_read(void __iomem *ioaddr, int addr)
 	return value;
 }
 
+static
+void rtl_eri_write(void __iomem *ioaddr, int addr, u32 mask, u32 val, int type)
+{
+	unsigned int i;
+
+	BUG_ON((addr & 3) || (mask == 0));
+	RTL_W32(ERIDR, val);
+	RTL_W32(ERIAR, ERIAR_WRITE_CMD | type | mask | addr);
+
+	for (i = 0; i < 100; i++) {
+		if (!(RTL_R32(ERIAR) & ERIAR_FLAG))
+			break;
+		udelay(100);
+	}
+}
+
+static  u32 rtl_eri_read(void __iomem *ioaddr, int addr, int type)
+{
+	unsigned int i;
+	u32 value = ~0x00;
+
+	RTL_W32(ERIAR, ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr);
+
+	for (i = 0; i < 100; i++) {
+		if (RTL_R32(ERIAR) & ERIAR_FLAG) {
+			value = RTL_R32(ERIDR);
+			break;
+		}
+		udelay(100);
+	}
+
+	return value;
+}
+
+static void
+rtl_eri_write_w0w1(void __iomem *ioaddr, int addr, u32 mask, u32 m, u32 p, int type)
+{
+	u32 val;
+
+	val = rtl_eri_read(ioaddr, addr, type);
+	rtl_eri_write(ioaddr, addr, mask, (val & ~m) | p, type);
+}
+
 static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr)
 {
 	u8 value = 0xff;
-- 
1.7.3.2


^ permalink raw reply related

* Re: [PATCH] veth: Kill unused code label and code block.
From: WANG Cong @ 2011-07-06  8:16 UTC (permalink / raw)
  To: netdev
In-Reply-To: <20110705.234930.2282002049899864045.davem@davemloft.net>

On Tue, 05 Jul 2011 23:49:30 -0700, David Miller wrote:

>  
> -tx_drop:
> -	kfree_skb(skb);
> -	u64_stats_update_begin(&stats->syncp); -	stats->tx_dropped++;
> -	u64_stats_update_end(&stats->syncp); -	return NETDEV_TX_OK;
> -

Ahh, yeah, we have removed the goto tx_drop...

Reviewed-by: WANG Cong <xiyou.wangcong@gmail.com>


^ permalink raw reply

* [PATCH net-next-2.6] veth: Kill unused tx_dropped
From: Eric Dumazet @ 2011-07-06  8:17 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20110705.234930.2282002049899864045.davem@davemloft.net>

Le mardi 05 juillet 2011 à 23:49 -0700, David Miller a écrit :

> -tx_drop:
> -	kfree_skb(skb);
> -	u64_stats_update_begin(&stats->syncp);
> -	stats->tx_dropped++;
> -	u64_stats_update_end(&stats->syncp);
> -	return NETDEV_TX_OK;
> -
>  rx_drop:
>  	u64_stats_update_begin(&rcv_stats->syncp);
>  	rcv_stats->rx_dropped++;


Then we should also kill tx_dropped from percpu stats ?

Here is a patch on top of yours

[PATCH] veth: Kill unused tx_dropped

Followup to commit f82528bc13a (Exclude duplicated checking for
iface-up) : We no longer need percpu tx_dropped field.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 drivers/net/veth.c |    5 +----
 1 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 19e0b0c..7f78db7 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -30,7 +30,6 @@ struct veth_net_stats {
 	u64			rx_bytes;
 	u64			tx_bytes;
 	u64			rx_dropped;
-	u64			tx_dropped;
 	struct u64_stats_sync	syncp;
 };
 
@@ -168,7 +167,7 @@ static struct rtnl_link_stats64 *veth_get_stats64(struct net_device *dev,
 	for_each_possible_cpu(cpu) {
 		struct veth_net_stats *stats = per_cpu_ptr(priv->stats, cpu);
 		u64 rx_packets, rx_bytes, rx_dropped;
-		u64 tx_packets, tx_bytes, tx_dropped;
+		u64 tx_packets, tx_bytes;
 		unsigned int start;
 
 		do {
@@ -178,14 +177,12 @@ static struct rtnl_link_stats64 *veth_get_stats64(struct net_device *dev,
 			rx_bytes = stats->rx_bytes;
 			tx_bytes = stats->tx_bytes;
 			rx_dropped = stats->rx_dropped;
-			tx_dropped = stats->tx_dropped;
 		} while (u64_stats_fetch_retry_bh(&stats->syncp, start));
 		tot->rx_packets += rx_packets;
 		tot->tx_packets += tx_packets;
 		tot->rx_bytes   += rx_bytes;
 		tot->tx_bytes   += tx_bytes;
 		tot->rx_dropped += rx_dropped;
-		tot->tx_dropped += tx_dropped;
 	}
 
 	return tot;



^ permalink raw reply related

* Re: [PATCH net-next-2.6] veth: Kill unused tx_dropped
From: David Miller @ 2011-07-06  8:51 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev
In-Reply-To: <1309940240.2292.7.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 06 Jul 2011 10:17:20 +0200

> Then we should also kill tx_dropped from percpu stats ?
> 
> Here is a patch on top of yours
> 
> [PATCH] veth: Kill unused tx_dropped
> 
> Followup to commit f82528bc13a (Exclude duplicated checking for
> iface-up) : We no longer need percpu tx_dropped field.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Looks good to me, applied, thanks!

^ permalink raw reply

* Re: [E1000-devel] [PATCH] fix WOL on 2nd port on i350
From: Jeff Kirsher @ 2011-07-06  8:53 UTC (permalink / raw)
  To: Martin Wilck; +Cc: carolyn.wyborny, netdev, e1000-devel, Uhe, Rudolf
In-Reply-To: <4E11CB87.5040806@ts.fujitsu.com>

On Mon, Jul 4, 2011 at 07:17, Martin Wilck <martin.wilck@ts.fujitsu.com> wrote:
> WOL fails on second port of a i350 network adapter with the latest
> upstream kernel driver. It works with the sf.net driver 3.0.19. The
> following patch seems to be missing upstream.
>
> Regards,
> Martin
>
> --
> Dr. Martin Wilck
> PRIMERGY System Software Engineer
> x86 Server Engineering
>
> FUJITSU
> Fujitsu Technology Solutions GmbH
> Heinz-Nixdorf-Ring 1
> 33106 Paderborn, Germany
> Phone:                  ++49 5251 525 2796
> Fax:                    ++49 5251 525 2820
> Email:                  martin.wilck@ts.fujitsu.com
> Internet:               http://ts.fujitsu.com
> Company Details:        http://ts.fujitsu.com/imprint
>
>

Thanks, we should have a patch to sync up the upstream driver in
net-next (3.1) here soon.

-- 
Cheers,
Jeff

^ permalink raw reply

* [PATCH v2] Disable router anycast address for /127 prefixes
From: Bjørn Mork @ 2011-07-06  9:04 UTC (permalink / raw)
  To: netdev; +Cc: Stephen Hemminger, Herbert Xu, Brian Haley, Bjørn Mork
In-Reply-To: <87r569rpis.fsf@nemi.mork.no>

RFC 6164 requires that routers MUST disable Subnet-Router anycast
for the prefix when /127 prefixes are used.

No need for matching code in addrconf_leave_anycast() as it
will silently ignore any attempt to leave an unknown anycast
address.

Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
Changes since v1:
 * removed unneeded change based on review comments from Brian Haley

Thought a bit more about this and found that adding less code
makes more sense, given that the meaning is clear enough. But I
really don't have any strong meanings about this. Please apply either 
version 1 or version 2 depending on your preferences.


Bjørn


 net/ipv6/addrconf.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 498b927..fef2e2e 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1470,6 +1470,8 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
 static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
 {
 	struct in6_addr addr;
+	if (ifp->prefix_len == 127) /* RFC 6164 */
+		return;
 	ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
 	if (ipv6_addr_any(&addr))
 		return;
-- 
1.7.2.5


^ permalink raw reply related

* Confirm Your Winning Prize!!
From: British Canadian Lotto @ 2011-07-05 18:33 UTC (permalink / raw)


Dear  Winner!!!

This is to inform you that your email address has been emerged as the winner of (£1,263,584.00 GBP) in the British  Canadian Lotto.For details of claims,Send us your full name and home address asap.Contact E-mail:britshcanadialc101@yahoo.com.hk  

Regards
Mrs.Elizabeth Williams


^ permalink raw reply

* Re: [PATCH v2] net: sched: constify tcf_proto and tc_action
From: Eric Dumazet @ 2011-07-06  9:25 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20110705.225921.2065481038863776818.davem@davemloft.net>

Le mardi 05 juillet 2011 à 22:59 -0700, David Miller a écrit :

> BTW, is is really so hard for people to do "allmodconfig"
> builds?
> 
> You can take your chances the first time, but if you need to respin
> because of warnings and breakage, the onus is on you to actually do a
> real complete build regression test on your changes.
> 
> I shouldn't be the one hitting this stuff, you folks should.

Yes my bad, sorry David, I hope this one is OK.

[PATCH v3] net: sched: constify tcf_proto and tc_action

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 include/net/act_api.h     |    6 +++---
 include/net/pkt_sched.h   |    4 ++--
 include/net/sch_generic.h |   12 +++++++-----
 net/sched/act_api.c       |    4 ++--
 net/sched/act_csum.c      |    2 +-
 net/sched/act_gact.c      |    3 ++-
 net/sched/act_ipt.c       |    2 +-
 net/sched/act_mirred.c    |    2 +-
 net/sched/act_nat.c       |    2 +-
 net/sched/act_pedit.c     |    2 +-
 net/sched/act_police.c    |    2 +-
 net/sched/act_simple.c    |    3 ++-
 net/sched/act_skbedit.c   |    2 +-
 net/sched/cls_api.c       |    6 +++---
 net/sched/cls_basic.c     |    2 +-
 net/sched/cls_cgroup.c    |    2 +-
 net/sched/cls_flow.c      |    2 +-
 net/sched/cls_fw.c        |    2 +-
 net/sched/cls_route.c     |    2 +-
 net/sched/cls_rsvp.h      |    2 +-
 net/sched/cls_tcindex.c   |    2 +-
 net/sched/cls_u32.c       |    2 +-
 net/sched/sch_api.c       |    6 +++---
 23 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/include/net/act_api.h b/include/net/act_api.h
index bab385f..c739531 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -72,7 +72,7 @@ struct tcf_act_hdr {
 
 struct tc_action {
 	void			*priv;
-	struct tc_action_ops	*ops;
+	const struct tc_action_ops	*ops;
 	__u32			type; /* for backward compat(TCA_OLD_COMPAT) */
 	__u32			order;
 	struct tc_action	*next;
@@ -86,7 +86,7 @@ struct tc_action_ops {
 	__u32   type; /* TBD to match kind */
 	__u32 	capab;  /* capabilities includes 4 bit version */
 	struct module		*owner;
-	int     (*act)(struct sk_buff *, struct tc_action *, struct tcf_result *);
+	int     (*act)(struct sk_buff *, const struct tc_action *, struct tcf_result *);
 	int     (*get_stats)(struct sk_buff *, struct tc_action *);
 	int     (*dump)(struct sk_buff *, struct tc_action *, int, int);
 	int     (*cleanup)(struct tc_action *, int bind);
@@ -115,7 +115,7 @@ extern void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo);
 extern int tcf_register_action(struct tc_action_ops *a);
 extern int tcf_unregister_action(struct tc_action_ops *a);
 extern void tcf_action_destroy(struct tc_action *a, int bind);
-extern int tcf_action_exec(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res);
+extern int tcf_action_exec(struct sk_buff *skb, const struct tc_action *a, struct tcf_result *res);
 extern struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind);
 extern struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind);
 extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int);
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 65afc49..fffdc60 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -99,9 +99,9 @@ static inline void qdisc_run(struct Qdisc *q)
 		__qdisc_run(q);
 }
 
-extern int tc_classify_compat(struct sk_buff *skb, struct tcf_proto *tp,
+extern int tc_classify_compat(struct sk_buff *skb, const struct tcf_proto *tp,
 			      struct tcf_result *res);
-extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
+extern int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 		       struct tcf_result *res);
 
 /* Calculate maximal size of packet seen by hard_start_xmit
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index b931f02..626177b 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -181,8 +181,9 @@ struct tcf_proto_ops {
 	struct tcf_proto_ops	*next;
 	char			kind[IFNAMSIZ];
 
-	int			(*classify)(struct sk_buff*, struct tcf_proto*,
-					struct tcf_result *);
+	int			(*classify)(struct sk_buff *,
+					    const struct tcf_proto *,
+					    struct tcf_result *);
 	int			(*init)(struct tcf_proto*);
 	void			(*destroy)(struct tcf_proto*);
 
@@ -205,8 +206,9 @@ struct tcf_proto {
 	/* Fast access part */
 	struct tcf_proto	*next;
 	void			*root;
-	int			(*classify)(struct sk_buff*, struct tcf_proto*,
-					struct tcf_result *);
+	int			(*classify)(struct sk_buff *,
+					    const struct tcf_proto *,
+					    struct tcf_result *);
 	__be16			protocol;
 
 	/* All the rest */
@@ -214,7 +216,7 @@ struct tcf_proto {
 	u32			classid;
 	struct Qdisc		*q;
 	void			*data;
-	struct tcf_proto_ops	*ops;
+	const struct tcf_proto_ops	*ops;
 };
 
 struct qdisc_skb_cb {
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 2f64262..f2fb67e 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -365,10 +365,10 @@ static struct tc_action_ops *tc_lookup_action_id(u32 type)
 }
 #endif
 
-int tcf_action_exec(struct sk_buff *skb, struct tc_action *act,
+int tcf_action_exec(struct sk_buff *skb, const struct tc_action *act,
 		    struct tcf_result *res)
 {
-	struct tc_action *a;
+	const struct tc_action *a;
 	int ret = -1;
 
 	if (skb->tc_verd & TC_NCLS) {
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
index 6cdf9ab..453a734 100644
--- a/net/sched/act_csum.c
+++ b/net/sched/act_csum.c
@@ -500,7 +500,7 @@ fail:
 }
 
 static int tcf_csum(struct sk_buff *skb,
-		    struct tc_action *a, struct tcf_result *res)
+		    const struct tc_action *a, struct tcf_result *res)
 {
 	struct tcf_csum *p = a->priv;
 	int action;
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index 2b4ab4b..b77f5a0 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -125,7 +125,8 @@ static int tcf_gact_cleanup(struct tc_action *a, int bind)
 	return 0;
 }
 
-static int tcf_gact(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
+static int tcf_gact(struct sk_buff *skb, const struct tc_action *a,
+		    struct tcf_result *res)
 {
 	struct tcf_gact *gact = a->priv;
 	int action = TC_ACT_SHOT;
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 9fc211a..60f8f61 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -195,7 +195,7 @@ static int tcf_ipt_cleanup(struct tc_action *a, int bind)
 	return tcf_ipt_release(ipt, bind);
 }
 
-static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
+static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a,
 		   struct tcf_result *res)
 {
 	int ret = 0, result = 0;
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index 961386e..102fc21 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -154,7 +154,7 @@ static int tcf_mirred_cleanup(struct tc_action *a, int bind)
 	return 0;
 }
 
-static int tcf_mirred(struct sk_buff *skb, struct tc_action *a,
+static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
 		      struct tcf_result *res)
 {
 	struct tcf_mirred *m = a->priv;
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
index 762b027..001d1b3 100644
--- a/net/sched/act_nat.c
+++ b/net/sched/act_nat.c
@@ -102,7 +102,7 @@ static int tcf_nat_cleanup(struct tc_action *a, int bind)
 	return tcf_hash_release(&p->common, bind, &nat_hash_info);
 }
 
-static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
+static int tcf_nat(struct sk_buff *skb, const struct tc_action *a,
 		   struct tcf_result *res)
 {
 	struct tcf_nat *p = a->priv;
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 7affe9a..10d3aed 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -120,7 +120,7 @@ static int tcf_pedit_cleanup(struct tc_action *a, int bind)
 	return 0;
 }
 
-static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
+static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
 		     struct tcf_result *res)
 {
 	struct tcf_pedit *p = a->priv;
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index b3b9b32..6fb3f5a 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -282,7 +282,7 @@ static int tcf_act_police_cleanup(struct tc_action *a, int bind)
 	return ret;
 }
 
-static int tcf_act_police(struct sk_buff *skb, struct tc_action *a,
+static int tcf_act_police(struct sk_buff *skb, const struct tc_action *a,
 			  struct tcf_result *res)
 {
 	struct tcf_police *police = a->priv;
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index a34a22d..73e0a3a 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -36,7 +36,8 @@ static struct tcf_hashinfo simp_hash_info = {
 };
 
 #define SIMP_MAX_DATA	32
-static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
+static int tcf_simp(struct sk_buff *skb, const struct tc_action *a,
+		    struct tcf_result *res)
 {
 	struct tcf_defact *d = a->priv;
 
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
index 5f6f0c7..35dbbe9 100644
--- a/net/sched/act_skbedit.c
+++ b/net/sched/act_skbedit.c
@@ -39,7 +39,7 @@ static struct tcf_hashinfo skbedit_hash_info = {
 	.lock	=	&skbedit_lock,
 };
 
-static int tcf_skbedit(struct sk_buff *skb, struct tc_action *a,
+static int tcf_skbedit(struct sk_buff *skb, const struct tc_action *a,
 		       struct tcf_result *res)
 {
 	struct tcf_skbedit *d = a->priv;
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 9563887..a69d44f 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -40,9 +40,9 @@ static DEFINE_RWLOCK(cls_mod_lock);
 
 /* Find classifier type by string name */
 
-static struct tcf_proto_ops *tcf_proto_lookup_ops(struct nlattr *kind)
+static const struct tcf_proto_ops *tcf_proto_lookup_ops(struct nlattr *kind)
 {
-	struct tcf_proto_ops *t = NULL;
+	const struct tcf_proto_ops *t = NULL;
 
 	if (kind) {
 		read_lock(&cls_mod_lock);
@@ -132,7 +132,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 	struct Qdisc  *q;
 	struct tcf_proto **back, **chain;
 	struct tcf_proto *tp;
-	struct tcf_proto_ops *tp_ops;
+	const struct tcf_proto_ops *tp_ops;
 	const struct Qdisc_class_ops *cops;
 	unsigned long cl;
 	unsigned long fh;
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 8be8872..ea1f70b 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -39,7 +39,7 @@ static const struct tcf_ext_map basic_ext_map = {
 	.police = TCA_BASIC_POLICE
 };
 
-static int basic_classify(struct sk_buff *skb, struct tcf_proto *tp,
+static int basic_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 			  struct tcf_result *res)
 {
 	int r;
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 32a3351..f84fdc3 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -101,7 +101,7 @@ struct cls_cgroup_head {
 	struct tcf_ematch_tree	ematches;
 };
 
-static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp,
+static int cls_cgroup_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 			       struct tcf_result *res)
 {
 	struct cls_cgroup_head *head = tp->root;
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 34533a5..6994214 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -356,7 +356,7 @@ static u32 flow_key_get(struct sk_buff *skb, int key)
 	}
 }
 
-static int flow_classify(struct sk_buff *skb, struct tcf_proto *tp,
+static int flow_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 			 struct tcf_result *res)
 {
 	struct flow_head *head = tp->root;
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 26e7bc4..389af15 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -77,7 +77,7 @@ static inline int fw_hash(u32 handle)
 		return handle & (HTSIZE - 1);
 }
 
-static int fw_classify(struct sk_buff *skb, struct tcf_proto *tp,
+static int fw_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 			  struct tcf_result *res)
 {
 	struct fw_head *head = (struct fw_head *)tp->root;
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index a9079053..13ab66e 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -125,7 +125,7 @@ static inline int route4_hash_wild(void)
 	return 0;						\
 }
 
-static int route4_classify(struct sk_buff *skb, struct tcf_proto *tp,
+static int route4_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 			   struct tcf_result *res)
 {
 	struct route4_head *head = (struct route4_head *)tp->root;
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index ed691b1..be4505e 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -130,7 +130,7 @@ static struct tcf_ext_map rsvp_ext_map = {
 		return r;				\
 }
 
-static int rsvp_classify(struct sk_buff *skb, struct tcf_proto *tp,
+static int rsvp_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 			 struct tcf_result *res)
 {
 	struct rsvp_session **sht = ((struct rsvp_head *)tp->root)->ht;
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 36667fa..dbe1992 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -79,7 +79,7 @@ tcindex_lookup(struct tcindex_data *p, u16 key)
 }
 
 
-static int tcindex_classify(struct sk_buff *skb, struct tcf_proto *tp,
+static int tcindex_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 			    struct tcf_result *res)
 {
 	struct tcindex_data *p = PRIV(tp);
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 3b93fc0..939b627 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -93,7 +93,7 @@ static inline unsigned int u32_hash_fold(__be32 key,
 	return h;
 }
 
-static int u32_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_result *res)
+static int u32_classify(struct sk_buff *skb, const struct tcf_proto *tp, struct tcf_result *res)
 {
 	struct {
 		struct tc_u_knode *knode;
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 8182aef..dca6c1a 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1644,7 +1644,7 @@ done:
  * to this qdisc, (optionally) tests for protocol and asks
  * specific classifiers.
  */
-int tc_classify_compat(struct sk_buff *skb, struct tcf_proto *tp,
+int tc_classify_compat(struct sk_buff *skb, const struct tcf_proto *tp,
 		       struct tcf_result *res)
 {
 	__be16 protocol = skb->protocol;
@@ -1668,12 +1668,12 @@ int tc_classify_compat(struct sk_buff *skb, struct tcf_proto *tp,
 }
 EXPORT_SYMBOL(tc_classify_compat);
 
-int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
+int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 		struct tcf_result *res)
 {
 	int err = 0;
 #ifdef CONFIG_NET_CLS_ACT
-	struct tcf_proto *otp = tp;
+	const struct tcf_proto *otp = tp;
 reclassify:
 #endif
 



^ permalink raw reply related

* Re: [PATCH v2] net: sched: constify tcf_proto and tc_action
From: David Miller @ 2011-07-06 10:05 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev
In-Reply-To: <1309944342.2292.15.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 06 Jul 2011 11:25:42 +0200

> Le mardi 05 juillet 2011 à 22:59 -0700, David Miller a écrit :
> 
>> BTW, is is really so hard for people to do "allmodconfig"
>> builds?
>> 
>> You can take your chances the first time, but if you need to respin
>> because of warnings and breakage, the onus is on you to actually do a
>> real complete build regression test on your changes.
>> 
>> I shouldn't be the one hitting this stuff, you folks should.
> 
> Yes my bad, sorry David, I hope this one is OK.
> 
> [PATCH v3] net: sched: constify tcf_proto and tc_action
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Yep, this one passed :-)  Applied, thanks.

^ permalink raw reply

* instant oops with AF_ROSE
From: David Miller @ 2011-07-06 10:57 UTC (permalink / raw)
  To: netdev; +Cc: ralf, linux-hams


The support for ipv4 over rose devices has been broken for as long as
the code has existed (I went back to 2.0.x just to make sure).  Try
this:

modprobe rose
ip link set rose0 up
ip addr add 11.0.0.3/8 dev rose0
ping -b 11.255.255.255

That should crash your box pretty well.

The immediate reason is that rose_rebuild_header() calls
rose_route_frame() with second arg NULL.

The first thing rose_route_frame() does is take that second arg and
dereference it in order to find the appropriate rose neighbour to use.

Again, it has "worked" this way since day one.  Ie. it never worked.

Since this has never worked, I think the thing to do is to simply
remove all of the rose device code.  It's only used to provide support
for ipv4 over ROSE and it simply never worked.

If someone wants to resurrect this, that's fine, but they'll have
to implement proper header_ops and a real transmit function instead
of the hacky thing it does now where it does the transmit in the
header building routines :-/


^ permalink raw reply

* Re: linux-next: manual merge of the net tree with the wireless-current tree
From: Gustavo Padovan @ 2011-07-06 11:07 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: David Miller, netdev, linux-next, linux-kernel
In-Reply-To: <20110706125329.6e5bdd1a.sfr@canb.auug.org.au>

* Stephen Rothwell <sfr@canb.auug.org.au> [2011-07-06 12:53:29 +1000]:

> Hi all,
> 
> Today's linux-next merge of the net tree got a conflict in
> net/bluetooth/l2cap_core.c between commit 9fa7e4f76f36 ("Bluetooth: Fix
> regression with incoming L2CAP connections") from the wireless-current
> tree and commit 89bc500e41fc ("Bluetooth: Add state tracking to struct
> l2cap_chan") from the net tree.
> 
> I fixed it up (I think - see below) and can carry the fix as necessary.
> -- 
> Cheers,
> Stephen Rothwell                    sfr@canb.auug.org.au
> 
> diff --cc net/bluetooth/l2cap_core.c
> index ebff14c,9ec9c8c..0000000
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@@ -2323,8 -2530,7 +2530,8 @@@ static inline int l2cap_config_req(stru
>   
>   	sk = chan->sk;
>   
> - 	if ((bt_sk(sk)->defer_setup && sk->sk_state != BT_CONNECT2) ||
> - 		 (!bt_sk(sk)->defer_setup && sk->sk_state != BT_CONFIG)) {
>  -	if (chan->state != BT_CONFIG) {
> ++	if ((bt_sk(sk)->defer_setup && chan->state != BT_CONNECT2) ||
> ++		 (!bt_sk(sk)->defer_setup && chan->state != BT_CONFIG)) {

Seems I need to merge my own trees. I'll do that. Thanks, Stephen.
And the fix is right ;)

	Gustavo

^ permalink raw reply

* 3.0.0rc6: ethtool not working without a cable
From: Arkadiusz Miskiewicz @ 2011-07-06 11:38 UTC (permalink / raw)
  To: netdev


3.0.0rc6, thinkpad t400 notebook.

If there is no cable then ethtool reports no device. It wasn't that before 
AFAIK.

ethtool version 2.6.36


cable disconnected:

[root@t400 ~]# ethtool eth0
Settings for eth0:
Cannot get device settings: No such device
Cannot get wake-on-lan settings: No such device
Cannot get message level: No such device
Cannot get link status: No such device
No data available
zsh: exit 75    ethtool eth0
[root@t400 ~]# ethtool -i eth0
Cannot get driver information: No such device
zsh: exit 71    ethtool -i eth0

cable connected:

[root@t400 ~]# ethtool -i eth0
driver: e1000e
version: 1.3.10-k2
firmware-version: 1.8-3
bus-info: 0000:00:19.0
[root@t400 ~]# ethtool eth0
Settings for eth0:
        Supported ports: [ TP ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Advertised pause frame use: No
        Advertised auto-negotiation: Yes
        Speed: 100Mb/s
        Duplex: Full
        Port: Twisted Pair
        PHYAD: 2
        Transceiver: internal
        Auto-negotiation: on
        MDI-X: off
        Supports Wake-on: pumbg
        Wake-on: d
        Current message level: 0x00000001 (1)
                               drv
        Link detected: yes


-- 
Arkadiusz Miśkiewicz        PLD/Linux Team
arekm / maven.pl            http://ftp.pld-linux.org/

^ permalink raw reply

* Re: instant oops with AF_ROSE
From: Chuck Hast @ 2011-07-06 11:42 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, ralf, linux-hams
In-Reply-To: <20110706.035735.1271031398642349034.davem@davemloft.net>

On Wed, Jul 6, 2011 at 06:57, David Miller <davem@davemloft.net> wrote:
>
> The support for ipv4 over rose devices has been broken for as long as
> the code has existed (I went back to 2.0.x just to make sure).  Try
> this:
>
> modprobe rose
> ip link set rose0 up
> ip addr add 11.0.0.3/8 dev rose0
> ping -b 11.255.255.255
>
> That should crash your box pretty well.
>
----- Text cut for bandwidth reduction-----------

It has been a while, and we were (still are I just am not active)  using FPAC
we have run a lot of IP through it, and never seemed to have a issue, but
perhaps this is not quite in that area.

I  am sure Bernard will see this and pitch in with more info. I am
just trying to
figure out if we are taking two different pieces here.

Here in FL I have ran both NetRom and IP over ROSE through FPAC boxes
with no issues that I can remember. FPAC is a wrapper around the rose piece.
We probably have people still doing IP inside ROSE through FPAC boxes around
the state, not sure who or where, but it would not be a surprise to me because
some use SMTP between their BBS devices.


Bernard, any comments?
-- 

Chuck Hast  -- KP4DJT --
To paraphrase my flight instructor;
"the only dumb question is the one you DID NOT ask resulting in my going
out and having to identify your bits and pieces in the midst of torn
and twisted metal."
---
Home web site:
www.wchast.com

ZoneMinder Demo and test site
www.wchast.com/zm
Login = guest
pwd   = guest
--
To unsubscribe from this list: send the line "unsubscribe linux-hams" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 0/3] Add device tree probe support for imx fec driver
From: Shawn Guo @ 2011-07-06 11:59 UTC (permalink / raw)
  To: Grant Likely
  Cc: David Miller, netdev, devicetree-discuss, linux-arm-kernel,
	patches
In-Reply-To: <20110706062901.GJ9978@ponder.secretlab.ca>

On Wed, Jul 06, 2011 at 12:29:01AM -0600, Grant Likely wrote:
> On Tue, Jul 05, 2011 at 11:22:52PM -0700, David Miller wrote:
> > From: Grant Likely <grant.likely@secretlab.ca>
> > Date: Wed, 6 Jul 2011 00:19:01 -0600
> > 
> > > Sorry about that, I missed the reference to that function which is
> > > currently in my devicetree/next branch.  I can either take the series
> > > via devicetree/next, or I can provide you with a topic branch
> > > containing the needed commit that you can merge.  Whichever you prefer.
> > 
> > Please just take the series, thanks.
> 
> Will do.
> 
Grant, please hold for a while.  I will send an update to use
of_get_named_gpio for phy-reset-gpios.

-- 
Regards,
Shawn


^ permalink raw reply

* Re: [PATCHv2] sctp: Enforce retransmission limit during shutdown
From: Neil Horman @ 2011-07-06 12:15 UTC (permalink / raw)
  To: Vladislav Yasevich, netdev, davem, Wei Yongjun, Sridhar Samudrala,
	linux-sctp
In-Reply-To: <20110704135019.GA801@canuck.infradead.org>

On Mon, Jul 04, 2011 at 09:50:19AM -0400, Thomas Graf wrote:
> When initiating a graceful shutdown while having data chunks
> on the retransmission queue with a peer which is in zero
> window mode the shutdown is never completed because the
> retransmission error count is reset periodically by the
> following two rules:
> 
>  - Do not timeout association while doing zero window probe.
>  - Reset overall error count when a heartbeat request has
>    been acknowledged.
> 
> The graceful shutdown will wait for all outstanding TSN to
> be acknowledged before sending the SHUTDOWN request. This
> never happens due to the peer's zero window not acknowledging
> the continuously retransmitted data chunks. Although the
> error counter is incremented for each failed retransmission,
> the receiving of the SACK announcing the zero window clears
> the error count again immediately. Also heartbeat requests
> continue to be sent periodically. The peer acknowledges these
> requests causing the error counter to be reset as well.
> 
> This patch changes behaviour to only reset the overall error
> counter for the above rules while not in shutdown. After
> reaching the maximum number of retransmission attempts, the
> T5 shutdown guard timer is scheduled to give the receiver
> some additional time to recover. The timer is stopped as soon
> as the receiver acknowledges any data.
> 
> The issue can be easily reproduced by establishing a sctp
> association over the loopback device, constantly queueing
> data at the sender while not reading any at the receiver.
> Wait for the window to reach zero, then initiate a shutdown
> by killing both processes simultaneously. The association
> will never be freed and the chunks on the retransmission
> queue will be retransmitted indefinitely.
> 
> Signed-off-by: Thomas Graf <tgraf@infradead.org>
<snip>
> --- a/net/sctp/sm_statefuns.c
> +++ b/net/sctp/sm_statefuns.c
> @@ -5154,7 +5154,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
>  	 * The sender of the SHUTDOWN MAY also start an overall guard timer
>  	 * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
>  	 */
> -	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
> +	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
>  			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
>  
How come you're modifying this chunk to use TIMER_RESTART rather than
TIMER_START? start shutdown is where the t5 timer is actually started, isn't it?


The rest, I think looks ok to me.
Neil

^ permalink raw reply

* Re: [PATCHv2] sctp: Enforce retransmission limit during shutdown
From: Thomas Graf @ 2011-07-06 13:16 UTC (permalink / raw)
  To: Neil Horman
  Cc: Vladislav Yasevich, netdev, davem, Wei Yongjun, Sridhar Samudrala,
	linux-sctp
In-Reply-To: <20110706121508.GA19518@hmsreliant.think-freely.org>

On Wed, 2011-07-06 at 08:15 -0400, Neil Horman wrote: 
> On Mon, Jul 04, 2011 at 09:50:19AM -0400, Thomas Graf wrote:

> > --- a/net/sctp/sm_statefuns.c
> > +++ b/net/sctp/sm_statefuns.c
> > @@ -5154,7 +5154,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
> >  	 * The sender of the SHUTDOWN MAY also start an overall guard timer
> >  	 * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
> >  	 */
> > -	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
> > +	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
> >  			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
> >  
> How come you're modifying this chunk to use TIMER_RESTART rather than
> TIMER_START? start shutdown is where the t5 timer is actually started, isn't it?

Since we also start the timer in SHUTDOWN_PENDING now if we hit
the retransmission limit the timer may be running already and
needs to be restarted (at least in theory).

In reality the timer should be stopped though, we can only go
from SHUTDOWN_PENDING into SHUTDOWN by actually SACKing bytes which
will delete the timer. This may change though and I did not want
this to bite us later on.



^ permalink raw reply

* Re: [PATCHv2] sctp: Enforce retransmission limit during shutdown
From: Vladislav Yasevich @ 2011-07-06 13:42 UTC (permalink / raw)
  To: netdev, davem, Wei Yongjun, Sridhar Samudrala, linux-sctp
In-Reply-To: <20110704135019.GA801@canuck.infradead.org>

Hi Tomas

Some minor nits and one substantial issue.  See below.

On a related note, were you going to re-submit the receiver patch as well?

On 07/04/2011 09:50 AM, Thomas Graf wrote:
> 
> diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
> index 1c88c89..0ae911f 100644
> --- a/net/sctp/outqueue.c
> +++ b/net/sctp/outqueue.c
> @@ -1582,6 +1582,9 @@ static void sctp_check_transmitted(struct sctp_outq *q,
>  #endif /* SCTP_DEBUG */
>  	if (transport) {
>  		if (bytes_acked) {
> +			struct sctp_association *asoc = transport->asoc;
> +			struct timer_list *t;
> +
>  			/* We may have counted DATA that was migrated
>  			 * to this transport due to DEL-IP operation.
>  			 * Subtract those bytes, since the were never
> @@ -1600,6 +1603,17 @@ static void sctp_check_transmitted(struct sctp_outq *q,
>  			transport->error_count = 0;
>  			transport->asoc->overall_error_count = 0;
>  
> +			/*
> +			 * While in SHUTDOWN PENDING, we may have started
> +			 * the T5 shutdown guard timer after reaching the
> +			 * retransmission limit. Stop that timer as soon
> +			 * as the receiver acknowledged any data.
> +			 */
> +			t = &asoc->timers[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD];
> +			if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING &&
> +			    timer_pending(t) && del_timer(t))
> +				sctp_association_put(asoc);
> +

I believe 'state' and 'timers' are in different cache lines, so might be able to optimize it
a little by checking the state prior to referencing timers array.

>  			/* Mark the destination transport address as
>  			 * active if it is not so marked.
>  			 */
> @@ -1629,10 +1643,15 @@ static void sctp_check_transmitted(struct sctp_outq *q,
>  			 * A sender is doing zero window probing when the
>  			 * receiver's advertised window is zero, and there is
>  			 * only one data chunk in flight to the receiver.
> +			 *
> +			 * Allow the association to timeout if SHUTDOWN is
> +			 * pending in case the receiver stays in zero window
> +			 * mode forever.
>  			 */
>  			if (!q->asoc->peer.rwnd &&
>  			    !list_empty(&tlist) &&
> -			    (sack_ctsn+2 == q->asoc->next_tsn)) {
> +			    (sack_ctsn+2 == q->asoc->next_tsn) &&
> +			    !(q->asoc->state >= SCTP_STATE_SHUTDOWN_PENDING)) {

Would a test for (q->asoc->state != SCTP_STATE_SHUTDOWN_PENDING) be clearer?  We only
care about the PENDING state here.

>  				SCTP_DEBUG_PRINTK("%s: SACK received for zero "
>  						  "window probe: %u\n",
>  						  __func__, sack_ctsn);
> diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
> index 534c2e5..fa92f4d6 100644
> --- a/net/sctp/sm_sideeffect.c
> +++ b/net/sctp/sm_sideeffect.c
> @@ -670,10 +670,21 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
>  	/* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of the
>  	 * HEARTBEAT should clear the error counter of the destination
>  	 * transport address to which the HEARTBEAT was sent.
> -	 * The association's overall error count is also cleared.
>  	 */
>  	t->error_count = 0;
> -	t->asoc->overall_error_count = 0;
> +
> +	/*
> +	 * Although RFC2960 and RFC4460 specify that the overall error
> +	 * count must be cleared when a HEARTBEAT ACK is received this
> +	 * behaviour may prevent the maximum retransmission count from
> +	 * being reached while in SHUTDOWN. If the peer keeps its window
> +	 * closed not acknowledging any outstanding TSN we may rely on
> +	 * reaching the max_retrans limit via the T3-rtx timer to close
> +	 * the association which will never happen if the error count is
> +	 * reset every heartbeat interval.
> +	 */
> +	if (!(t->asoc->state >= SCTP_STATE_SHUTDOWN_PENDING))
> +		t->asoc->overall_error_count = 0;

Same here.  We only care about the PENDING state. Also, please fix the comment to reflect
the code.

>  
>  	/* Clear the hb_sent flag to signal that we had a good
>  	 * acknowledgement.
> diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
> index a297283..e6a0c35 100644
> --- a/net/sctp/sm_statefuns.c
> +++ b/net/sctp/sm_statefuns.c
> @@ -5154,7 +5154,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
>  	 * The sender of the SHUTDOWN MAY also start an overall guard timer
>  	 * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
>  	 */
> -	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
> +	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
>  			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
>  
>  	if (asoc->autoclose)
> @@ -5299,14 +5299,28 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep,
>  	SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS);
>  
>  	if (asoc->overall_error_count >= asoc->max_retrans) {
> -		sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
> -				SCTP_ERROR(ETIMEDOUT));
> -		/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
> -		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
> -				SCTP_PERR(SCTP_ERROR_NO_ERROR));
> -		SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
> -		SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
> -		return SCTP_DISPOSITION_DELETE_TCB;
> +		if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) {
> +			/*
> +			 * We are here likely because the receiver had its rwnd
> +			 * closed for a while and we have not been able to
> +			 * transmit the locally queued data within the maximum
> +			 * retransmission attempts limit.  Start the T5
> +			 * shutdown guard timer to give the receiver one last
> +			 * chance and some additional time to recover before
> +			 * aborting.
> +			 */
> +			sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
> +				SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));

This is bug.  You don't want to restart the timer every time you hit a T3-timeout.  Remember, since you fall
through here, you do another retransmission and schedule another timeout.  So next time the timeout happens,
you'll restart the SHUTDOWN_GUARD, which is not what you want.

We want to start it once if it isn't pending, and leave it running without restart if it is already pending.

-vlad

> +		} else {
> +			sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
> +					SCTP_ERROR(ETIMEDOUT));
> +			/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
> +			sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
> +					SCTP_PERR(SCTP_ERROR_NO_ERROR));
> +			SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
> +			SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
> +			return SCTP_DISPOSITION_DELETE_TCB;
> +		}
>  	}
>  
>  	/* E1) For the destination address for which the timer
> diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
> index 0338dc6..7c211a7 100644
> --- a/net/sctp/sm_statetable.c
> +++ b/net/sctp/sm_statetable.c
> @@ -827,7 +827,7 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
>  	/* SCTP_STATE_ESTABLISHED */ \
>  	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
>  	/* SCTP_STATE_SHUTDOWN_PENDING */ \
> -	TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
> +	TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \
>  	/* SCTP_STATE_SHUTDOWN_SENT */ \
>  	TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \
>  	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
> 


^ permalink raw reply

* FW: Re: [PATCH v3 4/4] packet: Add pre-defragmentation support for ipv4
From: Penttilä Mika @ 2011-07-06 14:06 UTC (permalink / raw)
  To: netdev@vger.kernel.org; +Cc: davem@davemloft.net



> +static struct sk_buff *fanout_check_defrag(struct sk_buff *skb)
> +{
> +	const struct iphdr *iph;
> +	u32 len;
> +
> +	if (skb->protocol != htons(ETH_P_IP))
> +		return skb;
> +
> +	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
> +		return skb;
> +
> +	iph = ip_hdr(skb);
> +	if (iph->ihl < 5 || iph->version != 4)
> +		return skb;
> +	if (!pskb_may_pull(skb, iph->ihl*4))
> +		return skb;
> +	iph = ip_hdr(skb);
> +	len = ntohs(iph->tot_len);
> +	if (skb->len < len || len < (iph->ihl * 4))
> +		return skb;
> +
> +	if (ip_is_fragment(ip_hdr(skb))) {
> +		skb = skb_clone(skb, GFP_ATOMIC);

Isn't this leaking the original skb?

> +		if (skb) {
> +			if (pskb_trim_rcsum(skb, len))
> +				return skb;
> +			memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
> +			if (ip_defrag(skb, IP_DEFRAG_AF_PACKET))
> +				return NULL;
> +			skb->rxhash = 0;
> +		}
> +	}
> +	return skb;
> +}

-Mika



^ permalink raw reply

* Re: [PATCHv2] sctp: Enforce retransmission limit during shutdown
From: Thomas Graf @ 2011-07-06 14:18 UTC (permalink / raw)
  To: Vladislav Yasevich
  Cc: netdev, davem, Wei Yongjun, Sridhar Samudrala, linux-sctp
In-Reply-To: <4E146652.7010205@hp.com>

On Wed, Jul 06, 2011 at 09:42:42AM -0400, Vladislav Yasevich wrote:
> On a related note, were you going to re-submit the receiver patch as well?

Yes

> On 07/04/2011 09:50 AM, Thomas Graf wrote:
> > +			 * retransmission limit. Stop that timer as soon
> > +			 * as the receiver acknowledged any data.
> > +			 */
> > +			t = &asoc->timers[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD];
> > +			if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING &&
> > +			    timer_pending(t) && del_timer(t))
> > +				sctp_association_put(asoc);
> > +
> 
> I believe 'state' and 'timers' are in different cache lines, so might be able to optimize it
> a little by checking the state prior to referencing timers array.

gcc should do that but I'm fine with changing it.

> > +			 *
> > +			 * Allow the association to timeout if SHUTDOWN is
> > +			 * pending in case the receiver stays in zero window
> > +			 * mode forever.
> >  			 */
> >  			if (!q->asoc->peer.rwnd &&
> >  			    !list_empty(&tlist) &&
> > -			    (sack_ctsn+2 == q->asoc->next_tsn)) {
> > +			    (sack_ctsn+2 == q->asoc->next_tsn) &&
> > +			    !(q->asoc->state >= SCTP_STATE_SHUTDOWN_PENDING)) {
> 
> Would a test for (q->asoc->state != SCTP_STATE_SHUTDOWN_PENDING) be clearer?  We only
> care about the PENDING state here.

I think SHUTDOWN_RECEIVED should also be included. We continue to transmit and
process SACKs after receiving a SHUTDOWN.

> > +	 * Although RFC2960 and RFC4460 specify that the overall error
> > +	 * count must be cleared when a HEARTBEAT ACK is received this
> > +	 * behaviour may prevent the maximum retransmission count from
> > +	 * being reached while in SHUTDOWN. If the peer keeps its window
> > +	 * closed not acknowledging any outstanding TSN we may rely on
> > +	 * reaching the max_retrans limit via the T3-rtx timer to close
> > +	 * the association which will never happen if the error count is
> > +	 * reset every heartbeat interval.
> > +	 */
> > +	if (!(t->asoc->state >= SCTP_STATE_SHUTDOWN_PENDING))
> > +		t->asoc->overall_error_count = 0;
> 
> Same here.  We only care about the PENDING state. Also, please fix the comment to reflect
> the code.

Agreed.

> > +		if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) {
> > +			/*
> > +			 * We are here likely because the receiver had its rwnd
> > +			 * closed for a while and we have not been able to
> > +			 * transmit the locally queued data within the maximum
> > +			 * retransmission attempts limit.  Start the T5
> > +			 * shutdown guard timer to give the receiver one last
> > +			 * chance and some additional time to recover before
> > +			 * aborting.
> > +			 */
> > +			sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
> > +				SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
> 
> This is bug.  You don't want to restart the timer every time you hit a T3-timeout.  Remember, since you fall
> through here, you do another retransmission and schedule another timeout.  So next time the timeout happens,
> you'll restart the SHUTDOWN_GUARD, which is not what you want.
> 
> We want to start it once if it isn't pending, and leave it running without restart if it is already pending.

Doh, absolutely. The timer_pending() check got lost between testing and submission.


^ permalink raw reply

* Re: [PATCHv2] sctp: Enforce retransmission limit during shutdown
From: Neil Horman @ 2011-07-06 14:19 UTC (permalink / raw)
  To: Thomas Graf
  Cc: Vladislav Yasevich, netdev, davem, Wei Yongjun, Sridhar Samudrala,
	linux-sctp
In-Reply-To: <1309958184.12098.111.camel@lsx>

On Wed, Jul 06, 2011 at 03:16:24PM +0200, Thomas Graf wrote:
> On Wed, 2011-07-06 at 08:15 -0400, Neil Horman wrote: 
> > On Mon, Jul 04, 2011 at 09:50:19AM -0400, Thomas Graf wrote:
> 
> > > --- a/net/sctp/sm_statefuns.c
> > > +++ b/net/sctp/sm_statefuns.c
> > > @@ -5154,7 +5154,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
> > >  	 * The sender of the SHUTDOWN MAY also start an overall guard timer
> > >  	 * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
> > >  	 */
> > > -	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
> > > +	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
> > >  			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
> > >  
> > How come you're modifying this chunk to use TIMER_RESTART rather than
> > TIMER_START? start shutdown is where the t5 timer is actually started, isn't it?
> 
> Since we also start the timer in SHUTDOWN_PENDING now if we hit
> the retransmission limit the timer may be running already and
> needs to be restarted (at least in theory).
> 
> In reality the timer should be stopped though, we can only go
> from SHUTDOWN_PENDING into SHUTDOWN by actually SACKing bytes which
> will delete the timer. This may change though and I did not want
> this to bite us later on.
> 
> 
> 
Ok, makes sense
Acked-by: Neil Horman <nhorman@tuxdriver.com>


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox