Netdev List
 help / color / mirror / Atom feed
* [PATCH 8/13] tg3: Limit 5784 / 5764 to MAC LED mode
From: Matt Carlson @ 2007-11-10  0:38 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

Most 5784 / 5764 LED modes do not work as expected because of a hardware
bug.  This patch forces the LED mode to be in MAC LED mode.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index b5c4799..bb3b734 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -10610,6 +10610,9 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
 		    tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL)
 			tp->led_ctrl = LED_CTRL_MODE_PHY_2;
 
+		if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0)
+			tp->led_ctrl = LED_CTRL_MODE_MAC;
+
 		if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) {
 			tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
 			if ((tp->pdev->subsystem_vendor ==



^ permalink raw reply related

* [PATCH 12/13] tg3: MII => TP
From: Matt Carlson @ 2007-11-10  0:39 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

This patch changes the PHY type reported through ethtool for copper
devices from MII to TP.  The latter is more accurate.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8e76092..8d518cc 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -8329,7 +8329,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 				  SUPPORTED_100baseT_Full |
 				  SUPPORTED_10baseT_Half |
 				  SUPPORTED_10baseT_Full |
-				  SUPPORTED_MII);
+				  SUPPORTED_TP);
 		cmd->port = PORT_TP;
 	} else {
 		cmd->supported |= SUPPORTED_FIBRE;



^ permalink raw reply related

* [PATCH 11/13] tg3: Add A1 revs
From: Matt Carlson @ 2007-11-10  0:39 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

This patch adds the A1 revision of 5784, 5764, and 5761, and applies all
previous bugfixes.  In places where the list of devices gets too long,
the patch uses a new TG3_FLG3_5761_5784_AX_FIXES flag instead.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 72db78b..8e76092 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -1106,8 +1106,7 @@ static int tg3_phy_reset(struct tg3 *tp)
 	if (err)
 		return err;
 
-	if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
-	    tp->pci_chip_rev_id == CHIPREV_ID_5761_A0) {
+	if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
 		u32 val;
 
 		val = tr32(TG3_CPMU_LSPD_1000MB_CLK);
@@ -1352,8 +1351,7 @@ static void tg3_power_down_phy(struct tg3 *tp)
 	     (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
 		return;
 
-	if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
-	    tp->pci_chip_rev_id == CHIPREV_ID_5761_A0) {
+	if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
 		val = tr32(TG3_CPMU_LSPD_1000MB_CLK);
 		val &= ~CPMU_LSPD_1000MB_MACCLK_MASK;
 		val |= CPMU_LSPD_1000MB_MACCLK_12_5;
@@ -3154,7 +3152,8 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
 		err = tg3_setup_copper_phy(tp, force_reset);
 	}
 
-	if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0) {
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5784_A1) {
 		u32 val, scale;
 
 		val = tr32(TG3_CPMU_CLCK_STAT) & CPMU_CLCK_STAT_MAC_CLCK_MASK;
@@ -6390,7 +6389,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 
 	tg3_write_sig_legacy(tp, RESET_KIND_INIT);
 
-	if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0) {
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5784_A1) {
 		val = tr32(TG3_CPMU_CTRL);
 		val &= ~(CPMU_CTRL_LINK_AWARE_MODE | CPMU_CTRL_LINK_IDLE_MODE);
 		tw32(TG3_CPMU_CTRL, val);
@@ -9379,8 +9379,7 @@ static int tg3_test_loopback(struct tg3 *tp)
 	if (err)
 		return TG3_LOOPBACK_FAILED;
 
-	if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
-	    tp->pci_chip_rev_id == CHIPREV_ID_5761_A0) {
+	if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
 		int i;
 		u32 status;
 
@@ -9407,8 +9406,7 @@ static int tg3_test_loopback(struct tg3 *tp)
 	if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK))
 		err |= TG3_MAC_LOOPBACK_FAILED;
 
-	if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
-	    tp->pci_chip_rev_id == CHIPREV_ID_5761_A0) {
+	if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
 		tw32(TG3_CPMU_CTRL, cpmuctrl);
 
 		/* Release the mutex */
@@ -10629,7 +10627,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
 		    tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL)
 			tp->led_ctrl = LED_CTRL_MODE_PHY_2;
 
-		if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0)
+		if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
+		    tp->pci_chip_rev_id == CHIPREV_ID_5784_A1)
 			tp->led_ctrl = LED_CTRL_MODE_MAC;
 
 		if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) {
@@ -11401,9 +11400,16 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	}
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
 		tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
 
+		if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
+		    tp->pci_chip_rev_id == CHIPREV_ID_5784_A1 ||
+		    tp->pci_chip_rev_id == CHIPREV_ID_5761_A0 ||
+		    tp->pci_chip_rev_id == CHIPREV_ID_5761_A1)
+			tp->tg3_flags3 |= TG3_FLG3_5761_5784_AX_FIXES;
+	}
+
 	/* Set up tp->grc_local_ctrl before calling tg3_set_power_state().
 	 * GPIO1 driven high will bring 5700's external PHY out of reset.
 	 * It is also used as eeprom write protect on LOMs.
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index d325ab5..da18fb2 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -109,7 +109,9 @@
 #define  CHIPREV_ID_5714_A2		 0x9002
 #define  CHIPREV_ID_5906_A1		 0xc001
 #define  CHIPREV_ID_5784_A0		 0x5784000
+#define  CHIPREV_ID_5784_A1		 0x5784001
 #define  CHIPREV_ID_5761_A0		 0x5761000
+#define  CHIPREV_ID_5761_A1		 0x5761001
 #define  GET_ASIC_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700			 0x07
 #define   ASIC_REV_5701			 0x00
@@ -2391,6 +2393,7 @@ struct tg3 {
 	u32				tg3_flags3;
 #define TG3_FLG3_NO_NVRAM_ADDR_TRANS	0x00000001
 #define TG3_FLG3_ENABLE_APE		0x00000002
+#define TG3_FLG3_5761_5784_AX_FIXES	0x00000004
 
 	struct timer_list		timer;
 	u16				timer_counter;



^ permalink raw reply related

* [PATCH 3/13] tg3: APE flag fix
From: Matt Carlson @ 2007-11-10  0:38 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

This patch corrects a bug where the ENABLE_APE flag was tested against
the wrong flag variable.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 82b1cf0..833cb9b 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -10881,7 +10881,7 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
 	}
 
 	if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
-	     (tp->tg3_flags & TG3_FLG3_ENABLE_APE))
+	     (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
 		return;
 
 	for (offset = TG3_NVM_DIR_START;



^ permalink raw reply related

* [PATCH 7/13] tg3: Disable GPHY autopowerdown
From: Matt Carlson @ 2007-11-10  0:38 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

New CPMU devices contend with the GPHY for power management.  The GPHY
autopowerdown feature is enabled by default in the PHY and thus needs to
be disabled after every PHY reset.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 25e57d8..b5c4799 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -1117,6 +1117,12 @@ static int tg3_phy_reset(struct tg3 *tp)
 			udelay(40);
 			tw32_f(TG3_CPMU_LSPD_1000MB_CLK, val);
 		}
+
+		/* Disable GPHY autopowerdown. */
+		tg3_writephy(tp, MII_TG3_MISC_SHDW,
+			     MII_TG3_MISC_SHDW_WREN |
+			     MII_TG3_MISC_SHDW_APD_SEL |
+			     MII_TG3_MISC_SHDW_APD_WKTM_84MS);
 	}
 
 out:
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index f715b35..5b799ff 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1715,6 +1715,12 @@
 #define MII_TG3_ISTAT			0x1a /* IRQ status register */
 #define MII_TG3_IMASK			0x1b /* IRQ mask register */
 
+#define MII_TG3_MISC_SHDW		0x1c
+#define MII_TG3_MISC_SHDW_WREN		0x8000
+#define MII_TG3_MISC_SHDW_APD_SEL	0x2800
+
+#define MII_TG3_MISC_SHDW_APD_WKTM_84MS	0x0001
+
 /* ISTAT/IMASK event bits */
 #define MII_TG3_INT_LINKCHG		0x0002
 #define MII_TG3_INT_SPEEDCHG		0x0004



^ permalink raw reply related

* [PATCH 4/13] tg3: 5784 / 5764 DMA engine lockup fix
From: Matt Carlson @ 2007-11-10  0:38 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

5784 and 5764 devices lock up when the link speed is 10Mbps, the CPMU
link speed mode is enabled, and the MAC clock is running at 1.5Mhz.  The
fix is to run the MAC clock at faster speeds.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 833cb9b..b865c5d 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -6369,6 +6369,21 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 		val = tr32(TG3_CPMU_CTRL);
 		val &= ~(CPMU_CTRL_LINK_AWARE_MODE | CPMU_CTRL_LINK_IDLE_MODE);
 		tw32(TG3_CPMU_CTRL, val);
+
+		val = tr32(TG3_CPMU_LSPD_10MB_CLK);
+		val &= ~CPMU_LSPD_10MB_MACCLK_MASK;
+		val |= CPMU_LSPD_10MB_MACCLK_6_25;
+		tw32(TG3_CPMU_LSPD_10MB_CLK, val);
+
+		val = tr32(TG3_CPMU_LNK_AWARE_PWRMD);
+		val &= ~CPMU_LNK_AWARE_MACCLK_MASK;
+		val |= CPMU_LNK_AWARE_MACCLK_6_25;
+		tw32(TG3_CPMU_LNK_AWARE_PWRMD, val);
+
+		val = tr32(TG3_CPMU_HST_ACC);
+		val &= ~CPMU_HST_ACC_MACCLK_MASK;
+		val |= CPMU_HST_ACC_MACCLK_6_25;
+		tw32(TG3_CPMU_HST_ACC, val);
 	}
 
 	/* This works around an issue with Athlon chipsets on
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 4659697..c6aad49 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -857,13 +857,24 @@
 #define  CPMU_CTRL_LINK_IDLE_MODE	 0x00000200
 #define  CPMU_CTRL_LINK_AWARE_MODE	 0x00000400
 #define  CPMU_CTRL_LINK_SPEED_MODE	 0x00004000
-/* 0x3604 --> 0x360c unused */
+#define TG3_CPMU_LSPD_10MB_CLK		0x00003604
+#define  CPMU_LSPD_10MB_MACCLK_MASK	 0x001f0000
+#define  CPMU_LSPD_10MB_MACCLK_6_25	 0x00130000
+/* 0x3608 --> 0x360c unused */
 
 #define TG3_CPMU_LSPD_1000MB_CLK	0x0000360c
 #define  CPMU_LSPD_1000MB_MACCLK_62_5	 0x00000000
 #define  CPMU_LSPD_1000MB_MACCLK_12_5	 0x00110000
 #define  CPMU_LSPD_1000MB_MACCLK_MASK	 0x001f0000
-/* 0x3610 --> 0x365c unused */
+#define TG3_CPMU_LNK_AWARE_PWRMD	0x00003610
+#define  CPMU_LNK_AWARE_MACCLK_MASK	 0x001f0000
+#define  CPMU_LNK_AWARE_MACCLK_6_25	 0x00130000
+/* 0x3614 --> 0x361c unused */
+
+#define TG3_CPMU_HST_ACC		0x0000361c
+#define  CPMU_HST_ACC_MACCLK_MASK	 0x001f0000
+#define  CPMU_HST_ACC_MACCLK_6_25	 0x00130000
+/* 0x3620 --> 0x365c unused */
 
 #define TG3_CPMU_MUTEX_REQ		0x0000365c
 #define  CPMU_MUTEX_REQ_DRIVER		 0x00001000



^ permalink raw reply related

* [PATCH 6/13] tg3: CPMU adjustments for loopback tests
From: Matt Carlson @ 2007-11-10  0:38 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

This patch adds the LINK_SPEED mode to the list of CPMU modes that can
cause the loopback tests to fail.  These bugs are planned to be fixed in
future revisions of the chip, so the patch qualifies the fixes as such.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index ef849b1..25e57d8 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -9354,7 +9354,8 @@ static int tg3_test_loopback(struct tg3 *tp)
 	if (err)
 		return TG3_LOOPBACK_FAILED;
 
-	if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) {
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5761_A0) {
 		int i;
 		u32 status;
 
@@ -9371,17 +9372,18 @@ static int tg3_test_loopback(struct tg3 *tp)
 		if (status != CPMU_MUTEX_GNT_DRIVER)
 			return TG3_LOOPBACK_FAILED;
 
-		cpmuctrl = tr32(TG3_CPMU_CTRL);
-
 		/* Turn off power management based on link speed. */
+		cpmuctrl = tr32(TG3_CPMU_CTRL);
 		tw32(TG3_CPMU_CTRL,
-		     cpmuctrl & ~CPMU_CTRL_LINK_SPEED_MODE);
+		     cpmuctrl & ~(CPMU_CTRL_LINK_SPEED_MODE |
+				  CPMU_CTRL_LINK_AWARE_MODE));
 	}
 
 	if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK))
 		err |= TG3_MAC_LOOPBACK_FAILED;
 
-	if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) {
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5761_A0) {
 		tw32(TG3_CPMU_CTRL, cpmuctrl);
 
 		/* Release the mutex */



^ permalink raw reply related

* [PATCH 1/13] tg3: Fix 5761 PXEboot crash
From: Matt Carlson @ 2007-11-10  0:38 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

When 5761 devices boot the machine using PXEboot, PXE leaves the device
active when it terminates.  The tg3 driver has code to detect this
condition and resets the device during initialization.  On 5761 devices,
device resets involve sending a driver state update message to the APE
on the 5761.  However, during this initialization stage, communications
to the APE registers have not yet been set up.  The driver then
dereferences a NULL pointer and crashes the machine.  The fix is to move
the APE register access setup earlier in the initialization code to
cover this condition.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index cad5199..ddeaa0c 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -12464,6 +12464,28 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 		goto err_out_iounmap;
 	}
 
+	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+		if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
+			printk(KERN_ERR PFX "Cannot find proper PCI device "
+			       "base address for APE, aborting.\n");
+			err = -ENODEV;
+			goto err_out_iounmap;
+		}
+
+		tg3reg_base = pci_resource_start(pdev, 2);
+		tg3reg_len = pci_resource_len(pdev, 2);
+
+		tp->aperegs = ioremap_nocache(tg3reg_base, tg3reg_len);
+		if (tp->aperegs == 0UL) {
+			printk(KERN_ERR PFX "Cannot map APE registers, "
+			       "aborting.\n");
+			err = -ENOMEM;
+			goto err_out_iounmap;
+		}
+
+		tg3_ape_lock_init(tp);
+	}
+
 	/*
 	 * Reset chip in case UNDI or EFI driver did not shutdown
 	 * DMA self test will enable WDMAC and we'll see (spurious)
@@ -12478,7 +12500,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 	err = tg3_test_dma(tp);
 	if (err) {
 		printk(KERN_ERR PFX "DMA engine test failed, aborting.\n");
-		goto err_out_iounmap;
+		goto err_out_apeunmap;
 	}
 
 	/* Tigon3 can do ipv4 only... and some chips have buggy
@@ -12501,28 +12523,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
 	tg3_init_coal(tp);
 
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
-		if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
-			printk(KERN_ERR PFX "Cannot find proper PCI device "
-			       "base address for APE, aborting.\n");
-			err = -ENODEV;
-			goto err_out_iounmap;
-		}
-
-		tg3reg_base = pci_resource_start(pdev, 2);
-		tg3reg_len = pci_resource_len(pdev, 2);
-
-		tp->aperegs = ioremap_nocache(tg3reg_base, tg3reg_len);
-		if (tp->aperegs == 0UL) {
-			printk(KERN_ERR PFX "Cannot map APE registers, "
-			       "aborting.\n");
-			err = -ENOMEM;
-			goto err_out_iounmap;
-		}
-
-		tg3_ape_lock_init(tp);
-	}
-
 	pci_set_drvdata(pdev, dev);
 
 	err = register_netdev(dev);



^ permalink raw reply related

* [PATCH 13/13] tg3: Update version to 3.86
From: Matt Carlson @ 2007-11-10  0:39 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

This patch updates the version number to 3.86

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8d518cc..4942f7d 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -64,8 +64,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.85"
-#define DRV_MODULE_RELDATE	"October 18, 2007"
+#define DRV_MODULE_VERSION	"3.86"
+#define DRV_MODULE_RELDATE	"November 9, 2007"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0



^ permalink raw reply related

* [PATCH 10/13] tg3: Increase the PCI MRRS
From: Matt Carlson @ 2007-11-10  0:39 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

Previous devices hardcoded the PCI Maximum Read Request Size to 4K.  To
better comply with the PCI spec, the hardware now defaults the MRRS to
512 bytes.  This will yield poor driver performance if left untouched.
This patch increases the MRRS to 4K on driver initialization.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index ecd64a2..72db78b 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -5098,12 +5098,15 @@ static void tg3_restore_pci_state(struct tg3 *tp)
 
 	pci_write_config_word(tp->pdev, PCI_COMMAND, tp->pci_cmd);
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) {
+	if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
+		pcie_set_readrq(tp->pdev, 4096);
+	else {
 		pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
 				      tp->pci_cacheline_sz);
 		pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER,
 				      tp->pci_lat_timer);
 	}
+
 	/* Make sure PCI-X relaxed ordering bit is clear. */
 	if (tp->pcix_cap) {
 		u16 pcix_cmd;
@@ -11215,6 +11218,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP);
 	if (pcie_cap != 0) {
 		tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
+
+		pcie_set_readrq(tp->pdev, 4096);
+
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
 			u16 lnkctl;
 



^ permalink raw reply related

* [PATCH 2/13] tg3: 5784 / 5764 GPHY power down fix
From: Matt Carlson @ 2007-11-10  0:38 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

5784 and 5764 devices fail to link / pass traffic after one load /
unload cycle.  This happens because of a hardware bug in the new CPMU.
During normal operation, the MAC depends on the PHY clock being
available.  When the PHY is powered down, the clock the MAC depends on
is disabled.  The fix is to switch the MAC clock to an alternate source
before powering down the PHY, and to restore the MAC clock to the PHY
source upon device resume.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index ddeaa0c..82b1cf0 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -1106,6 +1106,19 @@ static int tg3_phy_reset(struct tg3 *tp)
 	if (err)
 		return err;
 
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5761_A0) {
+		u32 val;
+
+		val = tr32(TG3_CPMU_LSPD_1000MB_CLK);
+		if ((val & CPMU_LSPD_1000MB_MACCLK_MASK) ==
+		    CPMU_LSPD_1000MB_MACCLK_12_5) {
+			val &= ~CPMU_LSPD_1000MB_MACCLK_MASK;
+			udelay(40);
+			tw32_f(TG3_CPMU_LSPD_1000MB_CLK, val);
+		}
+	}
+
 out:
 	if (tp->tg3_flags2 & TG3_FLG2_PHY_ADC_BUG) {
 		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
@@ -1297,6 +1310,8 @@ static void tg3_nvram_unlock(struct tg3 *);
 
 static void tg3_power_down_phy(struct tg3 *tp)
 {
+	u32 val;
+
 	if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
 			u32 sg_dig_ctrl = tr32(SG_DIG_CTRL);
@@ -1311,8 +1326,6 @@ static void tg3_power_down_phy(struct tg3 *tp)
 	}
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-		u32 val;
-
 		tg3_bmcr_reset(tp);
 		val = tr32(GRC_MISC_CFG);
 		tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
@@ -1332,6 +1345,15 @@ static void tg3_power_down_phy(struct tg3 *tp)
 	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 &&
 	     (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
 		return;
+
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5761_A0) {
+		val = tr32(TG3_CPMU_LSPD_1000MB_CLK);
+		val &= ~CPMU_LSPD_1000MB_MACCLK_MASK;
+		val |= CPMU_LSPD_1000MB_MACCLK_12_5;
+		tw32_f(TG3_CPMU_LSPD_1000MB_CLK, val);
+	}
+
 	tg3_writephy(tp, MII_BMCR, BMCR_PDOWN);
 }
 
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 1d5b2a3..4659697 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -109,6 +109,7 @@
 #define  CHIPREV_ID_5714_A2		 0x9002
 #define  CHIPREV_ID_5906_A1		 0xc001
 #define  CHIPREV_ID_5784_A0		 0x5784000
+#define  CHIPREV_ID_5761_A0		 0x5761000
 #define  GET_ASIC_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700			 0x07
 #define   ASIC_REV_5701			 0x00
@@ -856,7 +857,13 @@
 #define  CPMU_CTRL_LINK_IDLE_MODE	 0x00000200
 #define  CPMU_CTRL_LINK_AWARE_MODE	 0x00000400
 #define  CPMU_CTRL_LINK_SPEED_MODE	 0x00004000
-/* 0x3604 --> 0x365c unused */
+/* 0x3604 --> 0x360c unused */
+
+#define TG3_CPMU_LSPD_1000MB_CLK	0x0000360c
+#define  CPMU_LSPD_1000MB_MACCLK_62_5	 0x00000000
+#define  CPMU_LSPD_1000MB_MACCLK_12_5	 0x00110000
+#define  CPMU_LSPD_1000MB_MACCLK_MASK	 0x001f0000
+/* 0x3610 --> 0x365c unused */
 
 #define TG3_CPMU_MUTEX_REQ		0x0000365c
 #define  CPMU_MUTEX_REQ_DRIVER		 0x00001000



^ permalink raw reply related

* [PATCH 5/13] tg3: Fix nvram selftest failures
From: Matt Carlson @ 2007-11-10  0:38 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

Newer devices contain bootcode in the chip's private ROM area.  This
bootcode is called selfboot.  Selfboot can be patched in the device's
NVRAM and the patches can have several formats.  In one particular
format, the checksum calculation needs to be slightly modified.  This
patch adjusts the NVRAM test code for that case, and add support for the
missing formats.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index b865c5d..ef849b1 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -8701,7 +8701,9 @@ static void tg3_get_ethtool_stats (struct net_device *dev,
 }
 
 #define NVRAM_TEST_SIZE 0x100
-#define NVRAM_SELFBOOT_FORMAT1_SIZE 0x14
+#define NVRAM_SELFBOOT_FORMAT1_0_SIZE	0x14
+#define NVRAM_SELFBOOT_FORMAT1_2_SIZE	0x18
+#define NVRAM_SELFBOOT_FORMAT1_3_SIZE	0x1c
 #define NVRAM_SELFBOOT_HW_SIZE 0x20
 #define NVRAM_SELFBOOT_DATA_SIZE 0x1c
 
@@ -8716,9 +8718,22 @@ static int tg3_test_nvram(struct tg3 *tp)
 	if (magic == TG3_EEPROM_MAGIC)
 		size = NVRAM_TEST_SIZE;
 	else if ((magic & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW) {
-		if ((magic & 0xe00000) == 0x200000)
-			size = NVRAM_SELFBOOT_FORMAT1_SIZE;
-		else
+		if ((magic & TG3_EEPROM_SB_FORMAT_MASK) ==
+		    TG3_EEPROM_SB_FORMAT_1) {
+			switch (magic & TG3_EEPROM_SB_REVISION_MASK) {
+			case TG3_EEPROM_SB_REVISION_0:
+				size = NVRAM_SELFBOOT_FORMAT1_0_SIZE;
+				break;
+			case TG3_EEPROM_SB_REVISION_2:
+				size = NVRAM_SELFBOOT_FORMAT1_2_SIZE;
+				break;
+			case TG3_EEPROM_SB_REVISION_3:
+				size = NVRAM_SELFBOOT_FORMAT1_3_SIZE;
+				break;
+			default:
+				return 0;
+			}
+		} else
 			return 0;
 	} else if ((magic & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW)
 		size = NVRAM_SELFBOOT_HW_SIZE;
@@ -8745,8 +8760,17 @@ static int tg3_test_nvram(struct tg3 *tp)
 	    TG3_EEPROM_MAGIC_FW) {
 		u8 *buf8 = (u8 *) buf, csum8 = 0;
 
-		for (i = 0; i < size; i++)
-			csum8 += buf8[i];
+		if ((cpu_to_be32(buf[0]) & TG3_EEPROM_SB_REVISION_MASK) ==
+		    TG3_EEPROM_SB_REVISION_2) {
+			/* For rev 2, the csum doesn't include the MBA. */
+			for (i = 0; i < TG3_EEPROM_SB_F1R2_MBA_OFF; i++)
+				csum8 += buf8[i];
+			for (i = TG3_EEPROM_SB_F1R2_MBA_OFF + 4; i < size; i++)
+				csum8 += buf8[i];
+		} else {
+			for (i = 0; i < size; i++)
+				csum8 += buf8[i];
+		}
 
 		if (csum8 == 0) {
 			err = 0;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index c6aad49..f715b35 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1555,6 +1555,12 @@
 #define TG3_EEPROM_MAGIC		0x669955aa
 #define TG3_EEPROM_MAGIC_FW		0xa5000000
 #define TG3_EEPROM_MAGIC_FW_MSK		0xff000000
+#define TG3_EEPROM_SB_FORMAT_MASK	0x00e00000
+#define TG3_EEPROM_SB_FORMAT_1		0x00200000
+#define TG3_EEPROM_SB_REVISION_MASK	0x001f0000
+#define TG3_EEPROM_SB_REVISION_0	0x00000000
+#define TG3_EEPROM_SB_REVISION_2	0x00020000
+#define TG3_EEPROM_SB_REVISION_3	0x00030000
 #define TG3_EEPROM_MAGIC_HW		0xabcd
 #define TG3_EEPROM_MAGIC_HW_MSK		0xffff
 
@@ -1765,6 +1771,8 @@
 /* APE convenience enumerations. */
 #define TG3_APE_LOCK_MEM                4
 
+#define TG3_EEPROM_SB_F1R2_MBA_OFF	0x10
+
 
 /* There are two ways to manage the TX descriptors on the tigon3.
  * Either the descriptors are in host DMA'able memory, or they



^ permalink raw reply related

* [PATCH 9/13] tg3: Prescaler fix
From: Matt Carlson @ 2007-11-10  0:38 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

Internal hardware timers become inaccurate after link events.  Clock
frequency switches performed by the CPMU fail to adjust timer
prescalers.  The fix is to detect core clock frequency changes during
link events and adjust the timer prescalers accordingly.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index bb3b734..ecd64a2 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -3154,6 +3154,22 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
 		err = tg3_setup_copper_phy(tp, force_reset);
 	}
 
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0) {
+		u32 val, scale;
+
+		val = tr32(TG3_CPMU_CLCK_STAT) & CPMU_CLCK_STAT_MAC_CLCK_MASK;
+		if (val == CPMU_CLCK_STAT_MAC_CLCK_62_5)
+			scale = 65;
+		else if (val == CPMU_CLCK_STAT_MAC_CLCK_6_25)
+			scale = 6;
+		else
+			scale = 12;
+
+		val = tr32(GRC_MISC_CFG) & ~GRC_MISC_CFG_PRESCALAR_MASK;
+		val |= (scale << GRC_MISC_CFG_PRESCALAR_SHIFT);
+		tw32(GRC_MISC_CFG, val);
+	}
+
 	if (tp->link_config.active_speed == SPEED_1000 &&
 	    tp->link_config.active_duplex == DUPLEX_HALF)
 		tw32(MAC_TX_LENGTHS,
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 5b799ff..d325ab5 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -874,7 +874,14 @@
 #define TG3_CPMU_HST_ACC		0x0000361c
 #define  CPMU_HST_ACC_MACCLK_MASK	 0x001f0000
 #define  CPMU_HST_ACC_MACCLK_6_25	 0x00130000
-/* 0x3620 --> 0x365c unused */
+/* 0x3620 --> 0x3630 unused */
+
+#define TG3_CPMU_CLCK_STAT		0x00003630
+#define  CPMU_CLCK_STAT_MAC_CLCK_MASK	 0x001f0000
+#define  CPMU_CLCK_STAT_MAC_CLCK_62_5	 0x00000000
+#define  CPMU_CLCK_STAT_MAC_CLCK_12_5	 0x00110000
+#define  CPMU_CLCK_STAT_MAC_CLCK_6_25	 0x00130000
+/* 0x3634 --> 0x365c unused */
 
 #define TG3_CPMU_MUTEX_REQ		0x0000365c
 #define  CPMU_MUTEX_REQ_DRIVER		 0x00001000





^ permalink raw reply related

* [PATCH 0/13] tg3: 5761, 5784, and 5764 support fixes
From: Matt Carlson @ 2007-11-10  0:38 UTC (permalink / raw)
  To: davem; +Cc: netdev, andy, Michael Chan

The following patches round out support for 5784, 5764, and 5761
devices, fixing bugs in the process.


^ permalink raw reply

* [PATCH 01/05] ipv6: RFC4214 Support (3)
From: osprey67 @ 2007-11-10  0:34 UTC (permalink / raw)
  To: netdev; +Cc: osprey67
In-Reply-To: <473371B3.5030908@yahoo.com>

From: Fred L. Templin <fred.l.templin@boeing.com>

This is experimental support for the Intra-Site Automatic
Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
the SIT module, and is configured using the unmodified
"ip" utility with device names beginning with: "isatap".

The following diffs are specific to the Linux 2.6.24-rc2
kernel distribution.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

----- linux-2.6.24-rc2/include/linux/if.h.orig    2007-11-08 12:05:47.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if.h 2007-11-08 08:26:44.000000000 -0800
@@ -61,6 +61,7 @@
  #define IFF_MASTER_ALB 0x10            /* bonding master, balance-alb. */
  #define IFF_BONDING    0x20            /* bonding master or slave      */
  #define IFF_SLAVE_NEEDARP 0x40         /* need ARPs for validation     */
+#define IFF_ISATAP     0x80            /* ISATAP interface (RFC4214)   */

  #define IF_GET_IFACE   0x0001          /* for querying only */
  #define IF_GET_PROTO   0x0002
--- linux-2.6.24-rc2/include/linux/if_tunnel.h.orig     2007-11-09 09:06:16.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if_tunnel.h  2007-11-09 15:49:54.000000000 -0800
@@ -25,6 +25,8 @@ struct ip_tunnel_parm
         __be16                  o_flags;
         __be32                  i_key;
         __be32                  o_key;
+       __be32                  router;
+       __be32                  lifetime;
         struct iphdr            iph;
  };

--- linux-2.6.24-rc2/include/linux/in.h.orig    2007-11-09 08:00:32.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/in.h 2007-11-09 08:56:09.000000000 -0800
@@ -252,7 +252,15 @@ struct sockaddr_in {
  #define BADCLASS(x)    (((x) & htonl(0xf0000000)) == htonl(0xf0000000))
  #define ZERONET(x)     (((x) & htonl(0xff000000)) == htonl(0x00000000))
  #define LOCAL_MCAST(x) (((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
-
+
+/* Special-Use IPv4 Addresses (RFC3330) */
+#define PRIVATE_10(x)  (((x) & htonl(0xff000000)) == htonl(0x0A000000))
+#define LINK_169(x)    (((x) & htonl(0xffff0000)) == htonl(0xA9FE0000))
+#define PRIVATE_172(x) (((x) & htonl(0xfff00000)) == htonl(0xAC100000))
+#define TEST_192(x)    (((x) & htonl(0xffffff00)) == htonl(0xC0000200))
+#define ANYCAST_6TO4(x)        (((x) & htonl(0xffffff00)) == htonl(0xC0586300))
+#define PRIVATE_192(x) (((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
+#define TEST_198(x)    (((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
  #endif

  #endif /* _LINUX_IN_H */
--- linux-2.6.24-rc2/include/net/addrconf.h.orig        2007-11-08 12:06:17.000000000 -0800
+++ linux-2.6.24-rc2/include/net/addrconf.h     2007-11-09 08:12:29.000000000 -0800
@@ -241,6 +241,14 @@ static inline int ipv6_addr_is_ll_all_ro
                 addr->s6_addr32[3] == htonl(0x00000002));
  }

+#if defined(CONFIG_IPV6_ISATAP)
+/* only for IFF_ISATAP interfaces */
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+       return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+}
+#endif
+
  #ifdef CONFIG_PROC_FS
  extern int if6_proc_init(void);
  extern void if6_proc_exit(void);-



^ permalink raw reply

* [PATCH 02/05] ipv6: RFC4214 Support (3)
From: osprey67 @ 2007-11-10  0:35 UTC (permalink / raw)
  To: netdev; +Cc: osprey67
In-Reply-To: <473371B3.5030908@yahoo.com>

From: Fred L. Templin <fred.l.templin@boeing.com>

This is experimental support for the Intra-Site Automatic
Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
the SIT module, and is configured using the unmodified
"ip" utility with device names beginning with: "isatap".

The following diffs are specific to the Linux 2.6.24-rc2
kernel distribution.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- linux-2.6.24-rc2/net/ipv6/Kconfig.orig      2007-11-08 12:07:17.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/Kconfig   2007-11-08 08:27:48.000000000 -0800
@@ -57,6 +57,17 @@ config IPV6_ROUTE_INFO

           If unsure, say N.

+config IPV6_ISATAP
+       bool "IPv6: ISATAP (RFC 4214) support (EXPERIMENTAL)"
+       depends on IPV6 && EXPERIMENTAL
+       ---help---
+         This is experimental support for the Intra-Site Automatic
+         Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
+         the SIT module, and is configured using the "ip" utility
+         with device names beginning with: "isatap".
+
+         If unsure, say N.
+
  config IPV6_OPTIMISTIC_DAD
         bool "IPv6: Enable RFC 4429 Optimistic DAD (EXPERIMENTAL)"
         depends on IPV6 && EXPERIMENTAL



^ permalink raw reply

* [PATCH 03/05] ipv6: RFC4214 Support (3)
From: osprey67 @ 2007-11-10  0:35 UTC (permalink / raw)
  To: netdev; +Cc: osprey67
In-Reply-To: <473371B3.5030908@yahoo.com>

From: Fred L. Templin <fred.l.templin@boeing.com>

This is experimental support for the Intra-Site Automatic
Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
the SIT module, and is configured using the unmodified
"ip" utility with device names beginning with: "isatap".

The following diffs are specific to the Linux 2.6.24-rc2
kernel distribution.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig   2007-11-08 11:59:35.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/addrconf.c        2007-11-09 14:19:19.000000000 -0800
@@ -75,7 +75,7 @@
  #include <net/ip.h>
  #include <net/netlink.h>
  #include <net/pkt_sched.h>
-#include <linux/if_tunnel.h>
+#include <net/ipip.h>
  #include <linux/rtnetlink.h>

  #ifdef CONFIG_IPV6_PRIVACY
@@ -1424,6 +1424,24 @@ static int addrconf_ifid_infiniband(u8 *
         return 0;
  }

+#if defined(CONFIG_IPV6_ISATAP)
+static int addrconf_ifid_isatap(u8 *eui, __be32 addr)
+{
+
+       eui[0] = 0x02; eui[1] = 0; eui[2] = 0x5E; eui[3] = 0xFE;
+       memcpy (eui+4, &addr, 4);
+
+       /* Special-Use IPv4 Addresses (RFC3330)
+       if (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
+           LINK_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
+           ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
+           MULTICAST(addr) || BADCLASS(addr)) eui[0] &= ~0x02;
+*/ eui[0] = 0;
+
+       return 0;
+}
+#endif
+
  static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
  {
         switch (dev->type) {
@@ -1435,6 +1453,11 @@ static int ipv6_generate_eui64(u8 *eui,
                 return addrconf_ifid_arcnet(eui, dev);
         case ARPHRD_INFINIBAND:
                 return addrconf_ifid_infiniband(eui, dev);
+#if defined(CONFIG_IPV6_ISATAP)
+       case ARPHRD_SIT:
+               if (dev->priv_flags & IFF_ISATAP)
+                       return addrconf_ifid_isatap(eui, *(__be32 *)dev->dev_addr);
+#endif
         }
         return -1;
  }
@@ -1470,8 +1493,7 @@ regen:
          *
          *  - Reserved subnet anycast (RFC 2526)
          *      11111101 11....11 1xxxxxxx
-        *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
-        *      00-00-5E-FE-xx-xx-xx-xx
+        *  - ISATAP (RFC4214) 00-00-5E-FE-xx-xx-xx-xx - remove??
          *  - value 0
          *  - XXX: already assigned to an address on the device
          */
@@ -2201,6 +2223,31 @@ static void addrconf_sit_config(struct n
                 return;
         }

+#if defined(CONFIG_IPV6_ISATAP)
+       /* ISATAP (RFC4214) - NBMA link */
+       if (dev->priv_flags & IFF_ISATAP) {
+               struct in6_addr addr;
+
+               addrconf_add_lroute(dev);
+
+               ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
+
+               if (ipv6_generate_eui64(addr.s6_addr + 8, dev) == 0) {
+                       struct inet6_ifaddr *ifp;
+
+                       ifp = ipv6_add_addr(idev, &addr, 64,
+                                       IFA_LINK, IFA_F_PERMANENT);
+                       if (!IS_ERR(ifp)) {
+                               addrconf_prefix_route(&ifp->addr,
+                                       ifp->prefix_len, idev->dev, 0, 0);
+                               addrconf_dad_start(ifp, 0);
+                               in6_ifa_put(ifp);
+                       }
+               }
+               return;
+       }
+#endif
+
         sit_add_v4_addrs(idev);

         if (dev->flags&IFF_POINTOPOINT) {
@@ -2531,6 +2578,19 @@ static void addrconf_rs_timer(unsigned l
                  *      Announcement received after solicitation
                  *      was sent
                  */
+#if defined(CONFIG_IPV6_ISATAP)
+               /* ISATAP (RFC4214) - Re-DAD to trigger new RS/RA */
+               if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+                       struct ip_tunnel *t  = netdev_priv(ifp->idev->dev);
+                       if (t->parms.router != INADDR_NONE) {
+                               spin_lock(&ifp->lock);
+                               ifp->probes = 0;
+                               ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+                               addrconf_mod_timer(ifp, AC_DAD, t->parms.lifetime*HZ);
+                               spin_unlock(&ifp->lock);
+                       }
+               }
+#endif
                 goto out;
         }

@@ -2545,10 +2605,32 @@ static void addrconf_rs_timer(unsigned l
                                    ifp->idev->cnf.rtr_solicit_interval);
                 spin_unlock(&ifp->lock);

+#if defined(CONFIG_IPV6_ISATAP)
+               /* ISATAP (RFC4214) - unicast RS */
+               if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+                       struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+                       if (t->parms.router == INADDR_NONE) goto out;
+
+                       ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+                       addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.router);
+               } else
+#endif
                 ipv6_addr_all_routers(&all_routers);

                 ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
         } else {
+#if defined(CONFIG_IPV6_ISATAP)
+               /* ISATAP (RFC4214) - Re-DAD to trigger new RS/RA */
+               if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+                       struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+                       if (t->parms.router != INADDR_NONE) {
+                               ifp->probes = 0;
+                               ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+                               addrconf_mod_timer(ifp, AC_DAD, t->parms.lifetime*HZ);
+                       }
+               }
+#endif
                 spin_unlock(&ifp->lock);
                 /*
                  * Note: we do not support deprecated "all on-link"
@@ -2594,6 +2676,9 @@ static void addrconf_dad_start(struct in
         spin_lock_bh(&ifp->lock);

         if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
+#if defined(CONFIG_IPV6_ISATAP)
+           dev->priv_flags&IFF_ISATAP ||
+#endif
             !(ifp->flags&IFA_F_TENTATIVE) ||
             ifp->flags & IFA_F_NODAD) {
                 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
@@ -2690,6 +2775,17 @@ static void addrconf_dad_completed(struc
             (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
                 struct in6_addr all_routers;

+#if defined(CONFIG_IPV6_ISATAP)
+               /* ISATAP (RFC4214) - unicast RS */
+               if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+                       struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+                       if (t->parms.router == INADDR_NONE) return;
+
+                       ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+                       addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.router);
+               } else
+#endif
                 ipv6_addr_all_routers(&all_routers);

                 /*

^ permalink raw reply

* [PATCH 04/05] ipv6: RFC4214 Support (3)
From: osprey67 @ 2007-11-10  0:35 UTC (permalink / raw)
  To: netdev; +Cc: osprey67
In-Reply-To: <473371B3.5030908@yahoo.com>

From: Fred L. Templin <fred.l.templin@boeing.com>

This is experimental support for the Intra-Site Automatic
Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
the SIT module, and is configured using the unmodified
"ip" utility with device names beginning with: "isatap".

The following diffs are specific to the Linux 2.6.24-rc2
kernel distribution.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- linux-2.6.24-rc2/net/ipv6/sit.c.orig        2007-11-08 12:03:41.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/sit.c     2007-11-09 15:50:41.000000000 -0800
@@ -16,6 +16,7 @@
   *     Changes:
   * Roger Venning <r.venning@telstra.com>:      6to4 support
   * Nate Thompson <nate@thebog.net>:            6to4 support
+ * Fred L. Templin <fltemplin@acm.org>:                isatap support
   */

  #include <linux/module.h>
@@ -182,6 +183,14 @@ static struct ip_tunnel * ipip6_tunnel_l
         dev->init = ipip6_tunnel_init;
         nt->parms = *parms;

+#if defined(CONFIG_IPV6_ISATAP)
+       if (parms->router) {
+               dev->priv_flags |= IFF_ISATAP;
+               if (!nt->parms.lifetime)
+                       nt->parms.lifetime = 120; /* RFC4214 Default */
+       }
+#endif
+
         if (register_netdevice(dev) < 0) {
                 free_netdev(dev);
                 goto failed;
@@ -382,6 +391,48 @@ static int ipip6_rcv(struct sk_buff *skb
                 IPCB(skb)->flags = 0;
                 skb->protocol = htons(ETH_P_IPV6);
                 skb->pkt_type = PACKET_HOST;
+#if defined(CONFIG_IPV6_ISATAP)
+               /* ISATAP (RFC4214) - check source address */
+               if (tunnel->dev->priv_flags & IFF_ISATAP) {
+                       struct neighbour *neigh;
+                       struct dst_entry *dst;
+                       struct flowi fl;
+                       struct in6_addr *addr6;
+                       struct ipv6hdr *iph6;
+
+                       /* from ISATAP router */
+                       if ((tunnel->parms.router != INADDR_NONE) &&
+                           (iph->saddr == tunnel->parms.router)) goto accept;
+
+                       iph6 = ipv6_hdr(skb);
+                       addr6 = &iph6->saddr;
+
+                       /* from legitimate previous hop */
+                       memset(&fl, 0, sizeof(fl));
+                       fl.proto = iph6->nexthdr;
+                       ipv6_addr_copy(&fl.fl6_dst, addr6);
+                       fl.oif = tunnel->dev->ifindex;
+                       security_skb_classify_flow(skb, &fl);
+
+                       if (!(dst = ip6_route_output(NULL, &fl)) ||
+                            (dst->dev != tunnel->dev) ||
+                            ((neigh = dst->neighbour) == NULL)) goto drop;
+
+                       addr6 = (struct in6_addr*)&neigh->primary_key;
+
+                       if (!(ipv6_addr_is_isatap(addr6)) ||
+                            (addr6->s6_addr32[3] != iph->saddr)) {
+drop:
+                               tunnel->stat.rx_errors++;
+                               read_unlock(&ipip6_lock);
+                               dst_release(dst);
+                               kfree_skb(skb);
+                               return 0;
+                       }
+                       dst_release(dst);
+               }
+accept:
+#endif
                 tunnel->stat.rx_packets++;
                 tunnel->stat.rx_bytes += skb->len;
                 skb->dev = tunnel->dev;
@@ -444,6 +495,31 @@ static int ipip6_tunnel_xmit(struct sk_b
         if (skb->protocol != htons(ETH_P_IPV6))
                 goto tx_error;

+#if defined(CONFIG_IPV6_ISATAP)
+       /* ISATAP (RFC4214) - must come before 6to4 */
+       if (dev->priv_flags & IFF_ISATAP) {
+               struct neighbour *neigh = NULL;
+
+               if (skb->dst)
+                       neigh = skb->dst->neighbour;
+
+               if (neigh == NULL) {
+                       if (net_ratelimit())
+                               printk(KERN_DEBUG "sit: nexthop == NULL\n");
+                       goto tx_error;
+               }
+
+               addr6 = (struct in6_addr*)&neigh->primary_key;
+               addr_type = ipv6_addr_type(addr6);
+
+               if ((addr_type & IPV6_ADDR_UNICAST) &&
+                    ipv6_addr_is_isatap(addr6))
+                       dst = addr6->s6_addr32[3];
+               else
+                       goto tx_error;
+       }
+#endif /* CONFIG_IPV6_ISATAP */
+
         if (!dst)
                 dst = try_6to4(&iph6->daddr);

@@ -651,6 +727,10 @@ ipip6_tunnel_ioctl (struct net_device *d
                                 ipip6_tunnel_unlink(t);
                                 t->parms.iph.saddr = p.iph.saddr;
                                 t->parms.iph.daddr = p.iph.daddr;
+#if defined(CONFIG_IPV6_ISATAP)
+                               if (p.router) t->parms.router = p.router;
+                               if (p.lifetime) t->parms.lifetime = p.lifetime;
+#endif
                                 memcpy(dev->dev_addr, &p.iph.saddr, 4);
                                 memcpy(dev->broadcast, &p.iph.daddr, 4);
                                 ipip6_tunnel_link(t);
@@ -663,6 +743,10 @@ ipip6_tunnel_ioctl (struct net_device *d
                         if (cmd == SIOCCHGTUNNEL) {
                                 t->parms.iph.ttl = p.iph.ttl;
                                 t->parms.iph.tos = p.iph.tos;
+#if defined(CONFIG_IPV6_ISATAP)
+                               if (p.router) t->parms.router = p.router;
+                               if (p.lifetime) t->parms.lifetime = p.lifetime;
+#endif
                         }
                         if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
                                 err = -EFAULT;


^ permalink raw reply

* [PATCH 05/05] ipv6: RFC4214 Support (3)
From: osprey67 @ 2007-11-10  0:35 UTC (permalink / raw)
  To: osprey67, netdev
In-Reply-To: <473371B3.5030908@yahoo.com>

[-- Attachment #1: Type: text/plain, Size: 249 bytes --]

From: Fred L. Templin <fred.l.templin@boeing.com>

This message attaches the combined diffs from
messages 01/05 through 04/05. This file should be
suitable for use with the patch utility.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>


[-- Attachment #2: isatap_linux.txt --]
[-- Type: text/plain, Size: 12025 bytes --]

--- linux-2.6.24-rc2/include/linux/if.h.orig	2007-11-08 12:05:47.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if.h	2007-11-08 08:26:44.000000000 -0800
@@ -61,6 +61,7 @@
 #define IFF_MASTER_ALB	0x10		/* bonding master, balance-alb.	*/
 #define IFF_BONDING	0x20		/* bonding master or slave	*/
 #define IFF_SLAVE_NEEDARP 0x40		/* need ARPs for validation	*/
+#define IFF_ISATAP	0x80		/* ISATAP interface (RFC4214)	*/
 
 #define IF_GET_IFACE	0x0001		/* for querying only */
 #define IF_GET_PROTO	0x0002
--- linux-2.6.24-rc2/include/linux/if_tunnel.h.orig	2007-11-09 09:06:16.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if_tunnel.h	2007-11-09 15:49:54.000000000 -0800
@@ -25,6 +25,8 @@ struct ip_tunnel_parm
 	__be16			o_flags;
 	__be32			i_key;
 	__be32			o_key;
+	__be32			router;
+	__be32			lifetime;
 	struct iphdr		iph;
 };
 
--- linux-2.6.24-rc2/include/linux/in.h.orig	2007-11-09 08:00:32.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/in.h	2007-11-09 08:56:09.000000000 -0800
@@ -252,7 +252,15 @@ struct sockaddr_in {
 #define BADCLASS(x)	(((x) & htonl(0xf0000000)) == htonl(0xf0000000))
 #define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
 #define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
-
+ 
+/* Special-Use IPv4 Addresses (RFC3330) */
+#define PRIVATE_10(x)	(((x) & htonl(0xff000000)) == htonl(0x0A000000))
+#define LINK_169(x) 	(((x) & htonl(0xffff0000)) == htonl(0xA9FE0000))
+#define PRIVATE_172(x)	(((x) & htonl(0xfff00000)) == htonl(0xAC100000))
+#define TEST_192(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0000200))
+#define ANYCAST_6TO4(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0586300))
+#define PRIVATE_192(x)	(((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
+#define TEST_198(x)	(((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
 #endif
 
 #endif	/* _LINUX_IN_H */
--- linux-2.6.24-rc2/include/net/addrconf.h.orig	2007-11-08 12:06:17.000000000 -0800
+++ linux-2.6.24-rc2/include/net/addrconf.h	2007-11-09 08:12:29.000000000 -0800
@@ -241,6 +241,14 @@ static inline int ipv6_addr_is_ll_all_ro
 		addr->s6_addr32[3] == htonl(0x00000002));
 }
 
+#if defined(CONFIG_IPV6_ISATAP)
+/* only for IFF_ISATAP interfaces */
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+	return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+}
+#endif
+
 #ifdef CONFIG_PROC_FS
 extern int if6_proc_init(void);
 extern void if6_proc_exit(void);
--- linux-2.6.24-rc2/net/ipv6/Kconfig.orig	2007-11-08 12:07:17.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/Kconfig	2007-11-08 08:27:48.000000000 -0800
@@ -57,6 +57,17 @@ config IPV6_ROUTE_INFO
 
 	  If unsure, say N.
 
+config IPV6_ISATAP
+	bool "IPv6: ISATAP (RFC 4214) support (EXPERIMENTAL)"
+	depends on IPV6 && EXPERIMENTAL
+	---help---
+	  This is experimental support for the Intra-Site Automatic
+	  Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
+	  the SIT module, and is configured using the "ip" utility
+	  with device names beginning with: "isatap".
+
+	  If unsure, say N.
+
 config IPV6_OPTIMISTIC_DAD
 	bool "IPv6: Enable RFC 4429 Optimistic DAD (EXPERIMENTAL)"
 	depends on IPV6 && EXPERIMENTAL
--- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	2007-11-08 11:59:35.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-09 14:19:19.000000000 -0800
@@ -75,7 +75,7 @@
 #include <net/ip.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
-#include <linux/if_tunnel.h>
+#include <net/ipip.h>
 #include <linux/rtnetlink.h>
 
 #ifdef CONFIG_IPV6_PRIVACY
@@ -1424,6 +1424,24 @@ static int addrconf_ifid_infiniband(u8 *
 	return 0;
 }
 
+#if defined(CONFIG_IPV6_ISATAP)
+static int addrconf_ifid_isatap(u8 *eui, __be32 addr)
+{
+
+	eui[0] = 0x02; eui[1] = 0; eui[2] = 0x5E; eui[3] = 0xFE;
+	memcpy (eui+4, &addr, 4);
+
+	/* Special-Use IPv4 Addresses (RFC3330)
+	if (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
+	    LINK_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
+	    ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
+	    MULTICAST(addr) || BADCLASS(addr)) eui[0] &= ~0x02;
+*/ eui[0] = 0;
+
+	return 0;
+}
+#endif
+
 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
 {
 	switch (dev->type) {
@@ -1435,6 +1453,11 @@ static int ipv6_generate_eui64(u8 *eui, 
 		return addrconf_ifid_arcnet(eui, dev);
 	case ARPHRD_INFINIBAND:
 		return addrconf_ifid_infiniband(eui, dev);
+#if defined(CONFIG_IPV6_ISATAP)
+	case ARPHRD_SIT:
+		if (dev->priv_flags & IFF_ISATAP)
+			return addrconf_ifid_isatap(eui, *(__be32 *)dev->dev_addr);
+#endif
 	}
 	return -1;
 }
@@ -1470,8 +1493,7 @@ regen:
 	 *
 	 *  - Reserved subnet anycast (RFC 2526)
 	 *	11111101 11....11 1xxxxxxx
-	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
-	 *	00-00-5E-FE-xx-xx-xx-xx
+	 *  - ISATAP (RFC4214) 00-00-5E-FE-xx-xx-xx-xx - remove??
 	 *  - value 0
 	 *  - XXX: already assigned to an address on the device
 	 */
@@ -2201,6 +2223,31 @@ static void addrconf_sit_config(struct n
 		return;
 	}
 
+#if defined(CONFIG_IPV6_ISATAP)
+	/* ISATAP (RFC4214) - NBMA link */
+	if (dev->priv_flags & IFF_ISATAP) {
+		struct in6_addr addr;
+
+		addrconf_add_lroute(dev);
+
+		ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
+
+		if (ipv6_generate_eui64(addr.s6_addr + 8, dev) == 0) {
+			struct inet6_ifaddr *ifp;
+
+			ifp = ipv6_add_addr(idev, &addr, 64,
+					IFA_LINK, IFA_F_PERMANENT);
+			if (!IS_ERR(ifp)) {
+				addrconf_prefix_route(&ifp->addr,
+					ifp->prefix_len, idev->dev, 0, 0);
+				addrconf_dad_start(ifp, 0);
+				in6_ifa_put(ifp);
+			}
+		}
+		return;
+	}
+#endif
+
 	sit_add_v4_addrs(idev);
 
 	if (dev->flags&IFF_POINTOPOINT) {
@@ -2531,6 +2578,19 @@ static void addrconf_rs_timer(unsigned l
 		 *	Announcement received after solicitation
 		 *	was sent
 		 */
+#if defined(CONFIG_IPV6_ISATAP)
+		/* ISATAP (RFC4214) - Re-DAD to trigger new RS/RA */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t  = netdev_priv(ifp->idev->dev);
+			if (t->parms.router != INADDR_NONE) {
+				spin_lock(&ifp->lock);
+				ifp->probes = 0;
+				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+				addrconf_mod_timer(ifp, AC_DAD, t->parms.lifetime*HZ);
+				spin_unlock(&ifp->lock);
+			}
+		}
+#endif
 		goto out;
 	}
 
@@ -2545,10 +2605,32 @@ static void addrconf_rs_timer(unsigned l
 				   ifp->idev->cnf.rtr_solicit_interval);
 		spin_unlock(&ifp->lock);
 
+#if defined(CONFIG_IPV6_ISATAP)
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+			if (t->parms.router == INADDR_NONE) goto out;
+
+			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.router);
+		} else
+#endif
 		ipv6_addr_all_routers(&all_routers);
 
 		ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
 	} else {
+#if defined(CONFIG_IPV6_ISATAP)
+		/* ISATAP (RFC4214) - Re-DAD to trigger new RS/RA */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+			if (t->parms.router != INADDR_NONE) {
+				ifp->probes = 0;
+				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+				addrconf_mod_timer(ifp, AC_DAD, t->parms.lifetime*HZ);
+			}
+		}
+#endif
 		spin_unlock(&ifp->lock);
 		/*
 		 * Note: we do not support deprecated "all on-link"
@@ -2594,6 +2676,9 @@ static void addrconf_dad_start(struct in
 	spin_lock_bh(&ifp->lock);
 
 	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
+#if defined(CONFIG_IPV6_ISATAP)
+	    dev->priv_flags&IFF_ISATAP ||
+#endif
 	    !(ifp->flags&IFA_F_TENTATIVE) ||
 	    ifp->flags & IFA_F_NODAD) {
 		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
@@ -2690,6 +2775,17 @@ static void addrconf_dad_completed(struc
 	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
 		struct in6_addr all_routers;
 
+#if defined(CONFIG_IPV6_ISATAP)
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+			if (t->parms.router == INADDR_NONE) return;
+
+			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.router);
+		} else
+#endif
 		ipv6_addr_all_routers(&all_routers);
 
 		/*
--- linux-2.6.24-rc2/net/ipv6/sit.c.orig	2007-11-08 12:03:41.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/sit.c	2007-11-09 15:50:41.000000000 -0800
@@ -16,6 +16,7 @@
  *	Changes:
  * Roger Venning <r.venning@telstra.com>:	6to4 support
  * Nate Thompson <nate@thebog.net>:		6to4 support
+ * Fred L. Templin <fltemplin@acm.org>:		isatap support
  */
 
 #include <linux/module.h>
@@ -182,6 +183,14 @@ static struct ip_tunnel * ipip6_tunnel_l
 	dev->init = ipip6_tunnel_init;
 	nt->parms = *parms;
 
+#if defined(CONFIG_IPV6_ISATAP)
+	if (parms->router) {
+		dev->priv_flags |= IFF_ISATAP;
+		if (!nt->parms.lifetime)
+			nt->parms.lifetime = 120; /* RFC4214 Default */
+	}
+#endif
+
 	if (register_netdevice(dev) < 0) {
 		free_netdev(dev);
 		goto failed;
@@ -382,6 +391,48 @@ static int ipip6_rcv(struct sk_buff *skb
 		IPCB(skb)->flags = 0;
 		skb->protocol = htons(ETH_P_IPV6);
 		skb->pkt_type = PACKET_HOST;
+#if defined(CONFIG_IPV6_ISATAP)
+		/* ISATAP (RFC4214) - check source address */
+		if (tunnel->dev->priv_flags & IFF_ISATAP) {
+			struct neighbour *neigh;
+			struct dst_entry *dst;
+			struct flowi fl;
+			struct in6_addr *addr6;
+			struct ipv6hdr *iph6;
+
+			/* from ISATAP router */
+			if ((tunnel->parms.router != INADDR_NONE) &&
+			    (iph->saddr == tunnel->parms.router)) goto accept;
+
+			iph6 = ipv6_hdr(skb);
+			addr6 = &iph6->saddr;
+
+			/* from legitimate previous hop */
+			memset(&fl, 0, sizeof(fl));
+			fl.proto = iph6->nexthdr;
+			ipv6_addr_copy(&fl.fl6_dst, addr6);
+			fl.oif = tunnel->dev->ifindex;
+			security_skb_classify_flow(skb, &fl);
+
+			if (!(dst = ip6_route_output(NULL, &fl)) ||
+			     (dst->dev != tunnel->dev) ||
+			     ((neigh = dst->neighbour) == NULL)) goto drop;
+
+			addr6 = (struct in6_addr*)&neigh->primary_key;
+
+			if (!(ipv6_addr_is_isatap(addr6)) ||
+			     (addr6->s6_addr32[3] != iph->saddr)) {
+drop:
+				tunnel->stat.rx_errors++;
+				read_unlock(&ipip6_lock);
+				dst_release(dst);
+				kfree_skb(skb);
+				return 0;
+		    	}
+			dst_release(dst);
+		}
+accept:
+#endif
 		tunnel->stat.rx_packets++;
 		tunnel->stat.rx_bytes += skb->len;
 		skb->dev = tunnel->dev;
@@ -444,6 +495,31 @@ static int ipip6_tunnel_xmit(struct sk_b
 	if (skb->protocol != htons(ETH_P_IPV6))
 		goto tx_error;
 
+#if defined(CONFIG_IPV6_ISATAP)
+	/* ISATAP (RFC4214) - must come before 6to4 */
+	if (dev->priv_flags & IFF_ISATAP) {
+		struct neighbour *neigh = NULL;
+
+		if (skb->dst)
+			neigh = skb->dst->neighbour;
+
+		if (neigh == NULL) {
+			if (net_ratelimit())
+		    		printk(KERN_DEBUG "sit: nexthop == NULL\n");
+			goto tx_error;
+	    	}
+
+		addr6 = (struct in6_addr*)&neigh->primary_key;
+		addr_type = ipv6_addr_type(addr6);
+
+		if ((addr_type & IPV6_ADDR_UNICAST) &&
+		     ipv6_addr_is_isatap(addr6))
+			dst = addr6->s6_addr32[3];
+		else
+			goto tx_error;
+	}
+#endif	/* CONFIG_IPV6_ISATAP */
+
 	if (!dst)
 		dst = try_6to4(&iph6->daddr);
 
@@ -651,6 +727,10 @@ ipip6_tunnel_ioctl (struct net_device *d
 				ipip6_tunnel_unlink(t);
 				t->parms.iph.saddr = p.iph.saddr;
 				t->parms.iph.daddr = p.iph.daddr;
+#if defined(CONFIG_IPV6_ISATAP)
+				if (p.router) t->parms.router = p.router;
+				if (p.lifetime) t->parms.lifetime = p.lifetime;
+#endif
 				memcpy(dev->dev_addr, &p.iph.saddr, 4);
 				memcpy(dev->broadcast, &p.iph.daddr, 4);
 				ipip6_tunnel_link(t);
@@ -663,6 +743,10 @@ ipip6_tunnel_ioctl (struct net_device *d
 			if (cmd == SIOCCHGTUNNEL) {
 				t->parms.iph.ttl = p.iph.ttl;
 				t->parms.iph.tos = p.iph.tos;
+#if defined(CONFIG_IPV6_ISATAP)
+				if (p.router) t->parms.router = p.router;
+				if (p.lifetime) t->parms.lifetime = p.lifetime;
+#endif
 			}
 			if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
 				err = -EFAULT;

^ permalink raw reply

* [PATCH 01/01] iproute2-2.6.23: RFC4214 Support (3)
From: osprey67 @ 2007-11-10  0:42 UTC (permalink / raw)
  To: netdev; +Cc: osprey67
In-Reply-To: <4734FCEF.3080301@yahoo.com>

[-- Attachment #1: Type: text/plain, Size: 4831 bytes --]

From: Fred L. Templin <fred.l.templin@boeing.com>

This is experimental support for the Intra-Site Automatic
Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
the SIT module, and is configured using the unmodified
"ip" utility with device names beginning with: "isatap".

The following diffs are specific to the iproute2-2.6.23
software distribution. The diff text file itself is also
attached and should be suitable for use with the patch
utility.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- iproute2-2.6.23/ip/iptunnel.c.orig  2007-11-08 16:27:24.000000000 -0800
+++ iproute2-2.6.23/ip/iptunnel.c       2007-11-09 15:47:06.000000000 -0800
@@ -1,3 +1,5 @@
+#define ISATAP
+
  /*
   * iptunnel.c         "ip tunnel"
   *
@@ -39,7 +41,12 @@ static void usage(void) __attribute__((n
  static void usage(void)
  {
         fprintf(stderr, "Usage: ip tunnel { add | change | del | show } [ NAME ]\n");
+#if defined(ISATAP)
+       fprintf(stderr, "          [ mode { ipip | gre | sit | isatap } ]\n");
+       fprintf(stderr, "          [ remote ADDR ] [ local ADDR ] [ router ADDR ] [ lifetime NUMBER ]\n");
+#else
         fprintf(stderr, "          [ mode { ipip | gre | sit } ] [ remote ADDR ] [ local ADDR ]\n");
+#endif
         fprintf(stderr, "          [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n");
         fprintf(stderr, "          [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
         fprintf(stderr, "\n");
@@ -55,6 +62,9 @@ static int parse_args(int argc, char **a
  {
         int count = 0;
         char medium[IFNAMSIZ];
+#if defined(ISATAP)
+       int isatap = 0;
+#endif

         memset(p, 0, sizeof(*p));
         memset(&medium, 0, sizeof(medium));
@@ -90,6 +100,15 @@ static int parse_args(int argc, char **a
                                         exit(-1);
                                 }
                                 p->iph.protocol = IPPROTO_IPV6;
+#if defined(ISATAP)
+                       } else if (strcmp(*argv, "isatap") == 0) {
+                               if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) {
+                                       fprintf(stderr,"You managed to ask for more than one tunnel mode.\n");
+                                       exit(-1);
+                               }
+                               p->iph.protocol = IPPROTO_IPV6;
+                               isatap++;
+#endif
                         } else {
                                 fprintf(stderr,"Cannot guess tunnel mode.\n");
                                 exit(-1);
@@ -160,6 +179,20 @@ static int parse_args(int argc, char **a
                         NEXT_ARG();
                         if (strcmp(*argv, "any"))
                                 p->iph.saddr = get_addr32(*argv);
+#if defined(ISATAP)
+               } else if (strcmp(*argv, "router") == 0) {
+                       NEXT_ARG();
+                       if (strcmp(*argv, "any"))
+                               p->router = get_addr32(*argv);
+               } else if (strcmp(*argv, "lifetime") == 0) {
+                       unsigned uval;
+                       NEXT_ARG();
+                       if (get_unsigned(&uval, *argv, 0)) {
+                               invarg("invalid lifetime\n", *argv);
+                               exit(-1);
+                       }
+                       p->lifetime = uval;
+#endif
                 } else if (strcmp(*argv, "dev") == 0) {
                         NEXT_ARG();
                         strncpy(medium, *argv, IFNAMSIZ-1);
@@ -212,6 +245,12 @@ static int parse_args(int argc, char **a
                         p->iph.protocol = IPPROTO_IPIP;
                 else if (memcmp(p->name, "sit", 3) == 0)
                         p->iph.protocol = IPPROTO_IPV6;
+#if defined(ISATAP)
+               else if (memcmp(p->name, "isatap", 6) == 0) {
+                       p->iph.protocol = IPPROTO_IPV6;
+                       isatap++;
+               }
+#endif
         }

         if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) {
@@ -239,6 +278,22 @@ static int parse_args(int argc, char **a
                 fprintf(stderr, "Broadcast tunnel requires a source address.\n");
                 return -1;
         }
+#if defined(ISATAP)
+       if (isatap) {
+               if (p->iph.daddr) {
+                       fprintf(stderr, "no remote with isatap.\n");
+                       return -1;
+               }
+               if (!p->router) p->router = INADDR_NONE;
+               if (!p->lifetime) p->lifetime = 120;
+       } else {
+               if (p->router || p->lifetime) {
+                       fprintf(stderr, "router/lifetime only for isatap.\n");
+                       return -1;
+               }
+       }
+#endif
+
         return 0;
  }


[-- Attachment #2: isatap_iproute2.txt --]
[-- Type: text/plain, Size: 3125 bytes --]

--- iproute2-2.6.23/ip/iptunnel.c.orig	2007-11-08 16:27:24.000000000 -0800
+++ iproute2-2.6.23/ip/iptunnel.c	2007-11-09 15:47:06.000000000 -0800
@@ -1,3 +1,5 @@
+#define ISATAP
+
 /*
  * iptunnel.c	       "ip tunnel"
  *
@@ -39,7 +41,12 @@ static void usage(void) __attribute__((n
 static void usage(void)
 {
 	fprintf(stderr, "Usage: ip tunnel { add | change | del | show } [ NAME ]\n");
+#if defined(ISATAP)
+	fprintf(stderr, "          [ mode { ipip | gre | sit | isatap } ]\n");
+	fprintf(stderr, "          [ remote ADDR ] [ local ADDR ] [ router ADDR ] [ lifetime NUMBER ]\n");
+#else
 	fprintf(stderr, "          [ mode { ipip | gre | sit } ] [ remote ADDR ] [ local ADDR ]\n");
+#endif
 	fprintf(stderr, "          [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n");
 	fprintf(stderr, "          [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
 	fprintf(stderr, "\n");
@@ -55,6 +62,9 @@ static int parse_args(int argc, char **a
 {
 	int count = 0;
 	char medium[IFNAMSIZ];
+#if defined(ISATAP)
+	int isatap = 0;
+#endif
 
 	memset(p, 0, sizeof(*p));
 	memset(&medium, 0, sizeof(medium));
@@ -90,6 +100,15 @@ static int parse_args(int argc, char **a
 					exit(-1);
 				}
 				p->iph.protocol = IPPROTO_IPV6;
+#if defined(ISATAP)
+			} else if (strcmp(*argv, "isatap") == 0) {
+				if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) {
+					fprintf(stderr,"You managed to ask for more than one tunnel mode.\n");
+					exit(-1);
+				}
+				p->iph.protocol = IPPROTO_IPV6;
+				isatap++;
+#endif
 			} else {
 				fprintf(stderr,"Cannot guess tunnel mode.\n");
 				exit(-1);
@@ -160,6 +179,20 @@ static int parse_args(int argc, char **a
 			NEXT_ARG();
 			if (strcmp(*argv, "any"))
 				p->iph.saddr = get_addr32(*argv);
+#if defined(ISATAP)
+		} else if (strcmp(*argv, "router") == 0) {
+			NEXT_ARG();
+			if (strcmp(*argv, "any"))
+				p->router = get_addr32(*argv);
+		} else if (strcmp(*argv, "lifetime") == 0) {
+			unsigned uval;
+			NEXT_ARG();
+			if (get_unsigned(&uval, *argv, 0)) {
+				invarg("invalid lifetime\n", *argv);
+				exit(-1);
+			}
+			p->lifetime = uval;
+#endif
 		} else if (strcmp(*argv, "dev") == 0) {
 			NEXT_ARG();
 			strncpy(medium, *argv, IFNAMSIZ-1);
@@ -212,6 +245,12 @@ static int parse_args(int argc, char **a
 			p->iph.protocol = IPPROTO_IPIP;
 		else if (memcmp(p->name, "sit", 3) == 0)
 			p->iph.protocol = IPPROTO_IPV6;
+#if defined(ISATAP)
+		else if (memcmp(p->name, "isatap", 6) == 0) {
+			p->iph.protocol = IPPROTO_IPV6;
+			isatap++;
+		}
+#endif
 	}
 
 	if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) {
@@ -239,6 +278,22 @@ static int parse_args(int argc, char **a
 		fprintf(stderr, "Broadcast tunnel requires a source address.\n");
 		return -1;
 	}
+#if defined(ISATAP)
+	if (isatap) {
+		if (p->iph.daddr) {
+			fprintf(stderr, "no remote with isatap.\n");
+			return -1;
+		}
+		if (!p->router) p->router = INADDR_NONE;
+		if (!p->lifetime) p->lifetime = 120;
+	} else {
+		if (p->router || p->lifetime) {
+			fprintf(stderr, "router/lifetime only for isatap.\n");
+			return -1;
+		}
+	}
+#endif
+
 	return 0;
 }
 

^ permalink raw reply

* Re: [PATCH 01/01] iproute2-2.6.23: RFC4214 Support (3)
From: Patrick McHardy @ 2007-11-10  1:04 UTC (permalink / raw)
  To: osprey67; +Cc: netdev
In-Reply-To: <4734FE8D.5070107@yahoo.com>

osprey67 wrote:
>
> --- iproute2-2.6.23/ip/iptunnel.c.orig  2007-11-08 16:27:24.000000000 
> -0800
> +++ iproute2-2.6.23/ip/iptunnel.c       2007-11-09 15:47:06.000000000 
> -0800
> @@ -1,3 +1,5 @@
> +#define ISATAP
> +
>  /*
>   * iptunnel.c         "ip tunnel"
>   *
> @@ -39,7 +41,12 @@ static void usage(void) __attribute__((n
>  static void usage(void)
>  {
>         fprintf(stderr, "Usage: ip tunnel { add | change | del | show 
> } [ NAME ]\n");
> +#if defined(ISATAP)
> +       fprintf(stderr, "          [ mode { ipip | gre | sit | isatap 
> } ]\n");
> +       fprintf(stderr, "          [ remote ADDR ] [ local ADDR ] [ 
> router ADDR ] [ lifetime NUMBER ]\n");
> +#else
>         fprintf(stderr, "          [ mode { ipip | gre | sit } ] [ 
> remote ADDR ] [ local ADDR ]\n");
> +#endif 


Why all the #ifdefs if you define it in the same file anyway?


^ permalink raw reply

* Re: [PATCH 05/05] ipv6: RFC4214 Support (3)
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2007-11-10  1:44 UTC (permalink / raw)
  To: osprey67; +Cc: netdev, yoshfuji
In-Reply-To: <4734FCEF.3080301@yahoo.com>

In article <4734FCEF.3080301@yahoo.com> (at Fri, 09 Nov 2007 16:35:59 -0800), osprey67 <osprey67@yahoo.com> says:

> --- linux-2.6.24-rc2/include/linux/if_tunnel.h.orig	2007-11-09 09:06:16.000000000 -0800
> +++ linux-2.6.24-rc2/include/linux/if_tunnel.h	2007-11-09 15:49:54.000000000 -0800
> @@ -25,6 +25,8 @@ struct ip_tunnel_parm
>  	__be16			o_flags;
>  	__be32			i_key;
>  	__be32			o_key;
> +	__be32			router;
> +	__be32			lifetime;
>  	struct iphdr		iph;
>  };
>  

No, you cannot simply change this.
If you change ioctl structure, you need to change
constants for SIOC{GET,ADD,CHG,DEL}TUNNEL.
Rename ole ones to OSIOxxx and assign new values.

If possible, new iproute2 should work with old kernels, and
old iproute2 should work with new kernels (without new features).

--yoshfuji

^ permalink raw reply

* Re: [RFC] dependencies for platform drivers (was Re: ax88796: add superh to kconfig dependencies)
From: Jeff Garzik @ 2007-11-10  3:12 UTC (permalink / raw)
  To: Ben Dooks
  Cc: Al Viro, Magnus Damm, netdev, lethal, ben-linux, akpm, linux-arch
In-Reply-To: <20071109120648.GA31353@fluff.org.uk>

Ben Dooks wrote:
> in submission process, or awaiting for an resolution. In the case
> of simtec-ide, I would like to replace it with platform-ata, but
> the libata maintainers seem wholy un-interested in
> PLAT_HAS_PLATFORM_ATA or similar.


I've either missed or forgotten your patch/proposal, want to repost to 
linux-ide?

I want to spread libata to the far corner of the globe, and am quite 
interested in supporting all architectures.

	Jeff



^ permalink raw reply

* Re: [PATCH 00/05] pull request for 'upstream-jeff' branch
From: Jeff Garzik @ 2007-11-10  5:33 UTC (permalink / raw)
  To: Francois Romieu
  Cc: netdev, Andrew Morton, Mark Lord, Ciaran McCreesh, Josh Logan,
	cecco, Hans-Jurgen Koch, David Gundersen, Will Trives,
	Alexander Y. Fomichev, Rolf Eike Beer, Daniel Drake,
	Lennert Buytenhek, Philip Craig, Edward Hsu
In-Reply-To: <20071108230734.GA15968@electric-eye.fr.zoreil.com>

Francois Romieu wrote:
> Please pull from branch 'upstream-jeff' in repository
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/romieu/netdev-2.6.git upstream-jeff
> 
> to get the changes below.
> 
> They should make things better for people who have experienced the 8168b
> regression since 2.6.24-rc1.
> 
> Distance from 'master' (f2511f13daaf00fdd206bee7b108f75923a613c6)
> -----------------------------------------------------------------
> 
> 407b35429151dd1d7a64cbef9f4bc59dac2efe5d
> d981c1de3b81edf50fe59f0e1298668919117b14
> 9d891d0bb0a14bc8184eee45323cb010db4d0db4
> 69b4d070ea49bd7f589776ea471a6988345eeee5
> db1470271c581050dcacc6ed681b9166d30bdba0
> 
> Diffstat
> --------
> 
>  drivers/net/r8169.c |   26 +++++++-------------------
>  1 files changed, 7 insertions(+), 19 deletions(-)
> 
> Shortlog
> --------
> 
> Ciaran McCreesh (1):
>       r8169: add PCI ID for the 8168 in the Abit Fatal1ty F-190HD motherboard
> 
> Francois Romieu (2):
>       r8169: do not enable the TBI for the 8168 and the 81x0
>       r8169: prevent bit sign expansion error in mdio_write
> 
> Mark Lord (2):
>       r8169: revert 7da97ec96a0934319c7fbedd3d38baf533e20640 (partly)
>       r8169: revert 7da97ec96a0934319c7fbedd3d38baf533e20640 (bis repetita)
> 

pulled



^ permalink raw reply

* Re: 2.6.24-rc2: Network commit causes SLUB performance regression with tbench
From: Nick Piggin @ 2007-11-10  3:28 UTC (permalink / raw)
  To: Christoph Lameter, netdev; +Cc: David S. Miller, Herbert Xu, linux-kernel
In-Reply-To: <200711101229.35822.nickpiggin@yahoo.com.au>

On Saturday 10 November 2007 12:29, Nick Piggin wrote:
> cc'ed linux-netdev

Err, make that 'netdev' :P

> On Saturday 10 November 2007 10:46, Christoph Lameter wrote:
> > commit deea84b0ae3d26b41502ae0a39fe7fe134e703d0 seems to cause a drop
> > in SLUB tbench performance:
> >
> > 8p x86_64 system:
> >
> > 2.6.24-rc2:
> > 	1260.80 MB/sec
> >
> > After reverting the patch:
> > 	2350.04 MB/sec
> >
> > SLAB performance (which is at 2435.58 MB/sec, ~3% better than SLUB) is
> > not affected by the patch.
>
> Ah, I didn't realise this was a regression. Thanks for bisecting it.
>
> > Since this is an alignment change it seems that tbench performance is
> > sensitive to the data layout? SLUB packs data more tightly than SLAB. So
> > 8 byte allocations could result in cacheline contention if adjacent
> > objects are allocated from different cpus. SLABs minimum size is 32
> > bytes so the cacheline contention is likely more limited.
> >
> > Maybe we need to allocate a mininum of one cacheline to the skb head? Or
> > padd it out to a full cacheline?
>
> The data should already be cacheline aligned. It is kmalloced, and
> with a minimum size of somewhere around 200 bytes on a 64-bit machine.
> So it will hit a cacheline aligned kmalloc slab AFAIKS  -- cacheline
> interference is probably not the problem. (To verify, I built slub with
> minimum kmalloc size set to 32 like slab and it's no real difference)
>
> But I can't see why restricting the allocation to PAGE_SIZE would help
> either. Maybe the macros are used in some other areas.
>
> BTW. your size-2048 kmalloc cache is order-1 in the default setup,
> wheras kmalloc(1024) or kmalloc(4096) will be order-0 allocations. And
> SLAB also uses order-0 for size-2048. It would be nice if SLUB did the
> same...
>
> > commit deea84b0ae3d26b41502ae0a39fe7fe134e703d0
> > Author: Herbert Xu <herbert@gondor.apana.org.au>
> > Date:   Sun Oct 21 16:27:46 2007 -0700
> >
> >     [NET]: Fix SKB_WITH_OVERHEAD calculation
> >
> >     The calculation in SKB_WITH_OVERHEAD is incorrect in that it can
> > cause an overflow across a page boundary which is what it's meant to
> > prevent. In particular, the header length (X) should not be lumped
> > together with skb_shared_info.  The latter needs to be aligned properly
> > while the header has no choice but to sit in front of wherever the
> > payload is.
> >
> >     Therefore the correct calculation is to take away the aligned size of
> >     skb_shared_info, and then subtract the header length.  The resulting
> >     quantity L satisfies the following inequality:
> >
> >         SKB_DATA_ALIGN(L + X) + sizeof(struct skb_shared_info) <=
> > PAGE_SIZE
> >
> >     This is the quantity used by alloc_skb to do the actual allocation.
> >     Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
> >     Signed-off-by: David S. Miller <davem@davemloft.net>
> >
> > diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> > index f93f22b..369f60a 100644
> > --- a/include/linux/skbuff.h
> > +++ b/include/linux/skbuff.h
> > @@ -41,8 +41,7 @@
> >  #define SKB_DATA_ALIGN(X)      (((X) + (SMP_CACHE_BYTES - 1)) & \
> >                                  ~(SMP_CACHE_BYTES - 1))
> >  #define SKB_WITH_OVERHEAD(X)   \
> > -       (((X) - sizeof(struct skb_shared_info)) & \
> > -        ~(SMP_CACHE_BYTES - 1))
> > +       ((X) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
> >  #define SKB_MAX_ORDER(X, ORDER) \
> >         SKB_WITH_OVERHEAD((PAGE_SIZE << (ORDER)) - (X))
> >  #define SKB_MAX_HEAD(X)                (SKB_MAX_ORDER((X), 0))

^ 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