* [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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox