Skip to contentSkip to conversation

e1000e: update netstats traffic counters realtime

PATCH Applied Auke Kok 4 participants 17 messages Nov 13, 2007 – Nov 14, 2007

Subsystems (2)
lore
Share & tools
lore

Auke Kok

author
#0 lore raw

PATCH 1/6 e1000e: update netstats traffic counters realtime

formerly e1000/e1000e only updated traffic counters once every 2 seconds with the register values of bytes/packets. With newer code however in the interrupt and polling code we can real-time fill in these values in the netstats struct for users to see.

---

 drivers/net/e1000e/netdev.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)
drivers/net/e1000e/netdev.c +6 -4
index a271112..6c99703 100644
@@ -458,6 +458,8 @@ next_desc:
 
 	adapter->total_rx_packets += total_rx_packets;
 	adapter->total_rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_packets += total_rx_packets;
+	adapter->net_stats.rx_bytes += total_rx_bytes;
 	return cleaned;
 }
 
@@ -593,6 +595,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
 	}
 	adapter->total_tx_bytes += total_tx_bytes;
 	adapter->total_tx_packets += total_tx_packets;
+	adapter->net_stats.tx_packets += total_tx_packets;
+	adapter->net_stats.tx_bytes += total_tx_bytes;
 	return cleaned;
 }
 
@@ -755,6 +759,8 @@ next_desc:
 
 	adapter->total_rx_packets += total_rx_packets;
 	adapter->total_rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_packets += total_rx_packets;
+	adapter->net_stats.rx_bytes += total_rx_bytes;
 	return cleaned;
 }
 
@@ -2537,10 +2543,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 	}
 
 	/* Fill out the OS statistics structure */
-	adapter->net_stats.rx_packets = adapter->stats.gprc;
-	adapter->net_stats.tx_packets = adapter->stats.gptc;
-	adapter->net_stats.rx_bytes = adapter->stats.gorcl;
-	adapter->net_stats.tx_bytes = adapter->stats.gotcl;
 	adapter->net_stats.multicast = adapter->stats.mprc;
 	adapter->net_stats.collisions = adapter->stats.colc;
 
author
#1 lore raw

PATCH 2/6 e1000: update netstats traffic counters realtime

formerly e1000/e1000e only updated traffic counters once every 2 seconds with the register values of bytes/packets. With newer code however in the interrupt and polling code we can real-time fill in these values in the netstats struct for users to see.

---

 drivers/net/e1000/e1000_main.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)
drivers/net/e1000/e1000_main.c +6 -4
index d1b88e4..e1ba705 100644
@@ -3652,10 +3652,6 @@ e1000_update_stats(struct e1000_adapter *adapter)
 	}
 
 	/* Fill out the OS statistics structure */
-	adapter->net_stats.rx_packets = adapter->stats.gprc;
-	adapter->net_stats.tx_packets = adapter->stats.gptc;
-	adapter->net_stats.rx_bytes = adapter->stats.gorcl;
-	adapter->net_stats.tx_bytes = adapter->stats.gotcl;
 	adapter->net_stats.multicast = adapter->stats.mprc;
 	adapter->net_stats.collisions = adapter->stats.colc;
 
@@ -4034,6 +4030,8 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
 	}
 	adapter->total_tx_bytes += total_tx_bytes;
 	adapter->total_tx_packets += total_tx_packets;
+	adapter->net_stats.tx_bytes += total_tx_bytes;
+	adapter->net_stats.tx_packets += total_tx_packets;
 	return cleaned;
 }
 
@@ -4256,6 +4254,8 @@ next_desc:
 
 	adapter->total_rx_packets += total_rx_packets;
 	adapter->total_rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_packets += total_rx_packets;
 	return cleaned;
 }
 
@@ -4443,6 +4443,8 @@ next_desc:
 
 	adapter->total_rx_packets += total_rx_packets;
 	adapter->total_rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_packets += total_rx_packets;
 	return cleaned;
 }
 
maintainer Applied
#2 lore raw

Re: [PATCH 2/6] e1000: update netstats traffic counters realtime

From: Auke Kok <[email protected]>
Date: Tue, 13 Nov 2007 15:11:17 -0800

Quoted 6 lines

formerly e1000/e1000e only updated traffic counters once every 2 seconds with the register values of bytes/packets. With newer code however in the interrupt and polling code we can real-time fill in these values in the netstats struct for users to see.

Applied to netdev-2.6, thanks.

author
#3 lore raw

PATCH 3/6 e1000: convert regtest macro's to functions

In reply to Auke Kok

Minimal macro to function conversion in e1000_ethtool.c

Adds functions reg_pattern_test and reg_set_and_check Changes REG_PATTERN_TEST and REG_SET_AND_CHECK macros to call these functions.

Saves ~2.5KB

Compiled x86, untested (no hardware)

old:

$ size drivers/net/e1000/e1000_ethtool.o
   text    data     bss     dec     hex filename
  16778       0       0   16778    418a drivers/net/e1000/e1000_ethtool.o

new:

$ size drivers/net/e1000/e1000_ethtool.o
   text    data     bss     dec     hex filename
  14128       0       0   14128    3730 drivers/net/e1000/e1000_ethtool.o

---

 drivers/net/e1000/e1000_ethtool.c |   84 ++++++++++++++++++++++++-------------
 1 files changed, 55 insertions(+), 29 deletions(-)
drivers/net/e1000/e1000_ethtool.c +55 -29
index 667f18b..ec67ea9 100644
@@ -728,39 +728,65 @@ err_setup:
 	return err;
 }
 
-#define REG_PATTERN_TEST(R, M, W)                                              \
-{                                                                              \
-	uint32_t pat, val;                                                     \
-	const uint32_t test[] = 					       \
-		{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};              \
-	for (pat = 0; pat < ARRAY_SIZE(test); pat++) {           	       \
-		E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W));             \
-		val = E1000_READ_REG(&adapter->hw, R);                         \
-		if (val != (test[pat] & W & M)) {                              \
-			DPRINTK(DRV, ERR, "pattern test reg %04X failed: got " \
-			        "0x%08X expected 0x%08X\n",                    \
-			        E1000_##R, val, (test[pat] & W & M));          \
-			*data = (adapter->hw.mac_type < e1000_82543) ?         \
-				E1000_82542_##R : E1000_##R;                   \
-			return 1;                                              \
-		}                                                              \
-	}                                                                      \
+static bool reg_pattern_test(struct e1000_adapter *adapter, uint64_t *data,
+			     int reg, uint32_t mask, uint32_t write)
+{
+	static const uint32_t test[] =
+		{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
+	uint8_t __iomem *address = adapter->hw.hw_addr + reg;
+	uint32_t read;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(test); i++) {
+		writel(write & test[i], address);
+		read = readl(address);
+		if (read != (write & test[i] & mask)) {
+			DPRINTK(DRV, ERR, "pattern test reg %04X failed: "
+				"got 0x%08X expected 0x%08X\n",
+			        reg, read, (write & test[i] & mask));
+			*data = reg;
+			return true;
+		}
+	}
+	return false;
 }
 
-#define REG_SET_AND_CHECK(R, M, W)                                             \
-{                                                                              \
-	uint32_t val;                                                          \
-	E1000_WRITE_REG(&adapter->hw, R, W & M);                               \
-	val = E1000_READ_REG(&adapter->hw, R);                                 \
-	if ((W & M) != (val & M)) {                                            \
-		DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\
-		        "expected 0x%08X\n", E1000_##R, (val & M), (W & M));   \
-		*data = (adapter->hw.mac_type < e1000_82543) ?                 \
-			E1000_82542_##R : E1000_##R;                           \
-		return 1;                                                      \
-	}                                                                      \
+static bool reg_set_and_check(struct e1000_adapter *adapter, uint64_t *data,
+			      int reg, uint32_t mask, uint32_t write)
+{
+	uint8_t __iomem *address = adapter->hw.hw_addr + reg;
+	uint32_t read;
+
+	writel(write & mask, address);
+	read = readl(address);
+	if ((read & mask) != (write & mask)) {
+		DPRINTK(DRV, ERR, "set/check reg %04X test failed: "
+			"got 0x%08X expected 0x%08X\n",
+			reg, (read & mask), (write & mask));
+		*data = reg;
+		return true;
+	}
+	return false;
 }
 
+#define REG_PATTERN_TEST(reg, mask, write)			     \
+	do {							     \
+		if (reg_pattern_test(adapter, data,		     \
+			     (adapter->hw.mac_type >= e1000_82543)   \
+			     ? E1000_##reg : E1000_82542_##reg,	     \
+			     mask, write))			     \
+			return 1;				     \
+	} while (0)
+
+#define REG_SET_AND_CHECK(reg, mask, write)			     \
+	do {							     \
+		if (reg_set_and_check(adapter, data,		     \
+			      (adapter->hw.mac_type >= e1000_82543)  \
+			      ? E1000_##reg : E1000_82542_##reg,     \
+			      mask, write))			     \
+			return 1;				     \
+	} while (0)
+
 static int
 e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
 {
maintainer Applied
#4 lore raw

Re: [PATCH 3/6] e1000: convert regtest macro's to functions

From: Auke Kok <[email protected]>
Date: Tue, 13 Nov 2007 15:11:23 -0800

Quoted 16 lines

Minimal macro to function conversion in e1000_ethtool.c

Adds functions reg_pattern_test and reg_set_and_check Changes REG_PATTERN_TEST and REG_SET_AND_CHECK macros to call these functions.

Saves ~2.5KB

Compiled x86, untested (no hardware)

old:

$ size drivers/net/e1000/e1000_ethtool.o
   text    data     bss     dec     hex filename
  16778       0       0   16778    418a drivers/net/e1000/e1000_ethtool.o
Quoted 8 lines

new:

$ size drivers/net/e1000/e1000_ethtool.o
   text    data     bss     dec     hex filename
  14128       0       0   14128    3730 drivers/net/e1000/e1000_ethtool.o

Definitely this looks nicer :-)

Applied to netdev-2.6, thanks!

author
#5 lore raw

PATCH 4/6 e1000e: convert register test macros to functions

In reply to Auke Kok

From: Joe Perches <[email protected]>

Add functions for reg_pattern_test and reg_set_and check Changed macros to use these functions

Compiled x86, untested

Size decreased ~2K

old:

$ size drivers/net/e1000e/ethtool.o
   text    data     bss     dec     hex filename
  14461       0       0   14461    387d drivers/net/e1000e/ethtool.o

new:

$ size drivers/net/e1000e/ethtool.o
   text    data     bss     dec     hex filename
  12498       0       0   12498    30d2 drivers/net/e1000e/ethtool.o

---

 drivers/net/e1000e/ethtool.c |   84 +++++++++++++++++++++++++++---------------
 1 files changed, 53 insertions(+), 31 deletions(-)
drivers/net/e1000e/ethtool.c +53 -31
index 6a39784..bc1115d 100644
@@ -691,41 +691,63 @@ err_setup:
 	return err;
 }
 
-#define REG_PATTERN_TEST(R, M, W) REG_PATTERN_TEST_ARRAY(R, 0, M, W)
-#define REG_PATTERN_TEST_ARRAY(reg, offset, mask, writeable)		      \
-{									      \
-	u32 _pat;							      \
-	u32 _value;							      \
-	u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};	      \
-	for (_pat = 0; _pat < ARRAY_SIZE(_test); _pat++) {		      \
-		E1000_WRITE_REG_ARRAY(hw, reg, offset,	      \
-				      (_test[_pat] & writeable));	      \
-		_value = E1000_READ_REG_ARRAY(hw, reg, offset);     \
-		if (_value != (_test[_pat] & writeable & mask)) {	      \
-			ndev_err(netdev, "pattern test reg %04X "             \
-				 "failed: got 0x%08X expected 0x%08X\n",      \
-				 reg + offset,  \
-				 value, (_test[_pat] & writeable & mask));    \
-			*data = reg;					      \
-			return 1;					      \
-		}							      \
-	}								      \
+bool reg_pattern_test_array(struct e1000_adapter *adapter, u64 *data, 
+			    int reg, int offset, u32 mask, u32 write)
+{
+	int i;
+	u32 read;
+	static const u32 test[] = 
+		{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
+	for (i = 0; i < ARRAY_SIZE(test); i++) {
+		E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset,
+				      (test[i] & write));
+		read = E1000_READ_REG_ARRAY(&adapter->hw, reg, offset);
+		if (read != (test[i] & write & mask)) {
+			ndev_err(adapter->netdev, "pattern test reg %04X "
+				 "failed: got 0x%08X expected 0x%08X\n",
+				 reg + offset,
+				 read, (test[i] & write & mask));
+			*data = reg;
+			return true;
+		}
+	}
+	return false;
 }
 
-#define REG_SET_AND_CHECK(R, M, W)					      \
-{									      \
-	u32 _value;							      \
-	__ew32(hw, R, W & M);						\
-	_value = __er32(hw, R);						\
-	if ((W & M) != (_value & M)) {					      \
-		ndev_err(netdev, "set/check reg %04X test failed: "           \
-			 "got 0x%08X expected 0x%08X\n", R, (_value & M),     \
-			 (W & M));					      \
-		*data = R;						      \
-		return 1;						      \
-	}								      \
+static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data,
+			      int reg, u32 mask, u32 write)
+{
+	u32 read;
+	__ew32(&adapter->hw, reg, write & mask);
+	read = __er32(&adapter->hw, reg);
+	if ((write & mask) != (read & mask)) {
+		ndev_err(adapter->netdev, "set/check reg %04X test failed: "
+			 "got 0x%08X expected 0x%08X\n", reg, (read & mask),
+			 (write & mask));
+		*data = reg;
+		return true;
+	}
+	return false;
 }
 
+#define REG_PATTERN_TEST(R, M, W) \
+	do { \
+		if (reg_pattern_test_array(adapter, data, R, 0, M, W)) \
+			return 1; \
+	} while (0)
+
+#define REG_PATTERN_TEST_ARRAY(R, offset, M, W) \
+	do { \
+		if (reg_pattern_test_array(adapter, data, R, offset, M, W)) \
+			return 1; \
+	} while (0)
+
+#define REG_SET_AND_CHECK(R, M, W) \
+	do { \
+		if (reg_set_and_check(adapter, data, R, M, W)) \
+			return 1; \
+	} while (0)
+
 static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
 {
 	struct e1000_hw *hw = &adapter->hw;
maintainer Applied
#6 lore raw

Re: [PATCH 4/6] e1000e: convert register test macros to functions

From: Auke Kok <[email protected]>
Date: Tue, 13 Nov 2007 15:11:28 -0800

Quoted 17 lines

From: Joe Perches <[email protected]>

Add functions for reg_pattern_test and reg_set_and check Changed macros to use these functions

Compiled x86, untested

Size decreased ~2K

old:

$ size drivers/net/e1000e/ethtool.o
   text    data     bss     dec     hex filename
  14461       0       0   14461    387d drivers/net/e1000e/ethtool.o

new:

Quoted 7 lines
$ size drivers/net/e1000e/ethtool.o
   text    data     bss     dec     hex filename
  12498       0       0   12498    30d2 drivers/net/e1000e/ethtool.o

Applied to netdev-2.6, but I had to fix up the following whitespace issues by hand:

Adds trailing whitespace.
diff:28:bool reg_pattern_test_array(struct e1000_adapter *adapter, u64 *data, Adds trailing whitespace.
diff:33: static const u32 test[] =
warning: 2 lines add whitespace errors.

Please correct this before submission in the future.

Thanks!

author
#7 lore raw

PATCH 5/6 e1000: Secondary unicast address support

In reply to Auke Kok

From: Patrick McHardy <[email protected]>

Add support for configuring secondary unicast addresses. Unicast addresses take precendece over multicast addresses when filling the exact address filters to avoid going to promiscous mode. When more unicast addresses are present than filter slots, unicast filtering is disabled and all slots can be used for multicast addresses.

---

 drivers/net/e1000/e1000_main.c |   47 ++++++++++++++++++++++++++--------------
 1 files changed, 31 insertions(+), 16 deletions(-)
drivers/net/e1000/e1000_main.c +31 -16
index e1ba705..dc4934d 100644
@@ -126,7 +126,7 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
                                 struct e1000_tx_ring *tx_ring);
 static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
                                 struct e1000_rx_ring *rx_ring);
-static void e1000_set_multi(struct net_device *netdev);
+static void e1000_set_rx_mode(struct net_device *netdev);
 static void e1000_update_phy_info(unsigned long data);
 static void e1000_watchdog(unsigned long data);
 static void e1000_82547_tx_fifo_stall(unsigned long data);
@@ -487,7 +487,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
 	struct net_device *netdev = adapter->netdev;
 	int i;
 
-	e1000_set_multi(netdev);
+	e1000_set_rx_mode(netdev);
 
 	e1000_restore_vlan(adapter);
 	e1000_init_manageability(adapter);
@@ -899,7 +899,7 @@ e1000_probe(struct pci_dev *pdev,
 	netdev->stop = &e1000_close;
 	netdev->hard_start_xmit = &e1000_xmit_frame;
 	netdev->get_stats = &e1000_get_stats;
-	netdev->set_multicast_list = &e1000_set_multi;
+	netdev->set_rx_mode = &e1000_set_rx_mode;
 	netdev->set_mac_address = &e1000_set_mac;
 	netdev->change_mtu = &e1000_change_mtu;
 	netdev->do_ioctl = &e1000_ioctl;
@@ -2382,21 +2382,22 @@ e1000_set_mac(struct net_device *netdev, void *p)
 }
 
 /**
- * e1000_set_multi - Multicast and Promiscuous mode set
+ * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
  * @netdev: network interface device structure
  *
- * The set_multi entry point is called whenever the multicast address
- * list or the network interface flags are updated.  This routine is
- * responsible for configuring the hardware for proper multicast,
+ * The set_rx_mode entry point is called whenever the unicast or multicast
+ * address lists or the network interface flags are updated. This routine is
+ * responsible for configuring the hardware for proper unicast, multicast,
  * promiscuous mode, and all-multi behavior.
  **/
 
 static void
-e1000_set_multi(struct net_device *netdev)
+e1000_set_rx_mode(struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-	struct dev_mc_list *mc_ptr;
+	struct dev_addr_list *uc_ptr;
+	struct dev_addr_list *mc_ptr;
 	uint32_t rctl;
 	uint32_t hash_value;
 	int i, rar_entries = E1000_RAR_ENTRIES;
@@ -2419,9 +2420,16 @@ e1000_set_multi(struct net_device *netdev)
 		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
 	} else if (netdev->flags & IFF_ALLMULTI) {
 		rctl |= E1000_RCTL_MPE;
-		rctl &= ~E1000_RCTL_UPE;
 	} else {
-		rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
+		rctl &= ~E1000_RCTL_MPE;
+	}
+
+	uc_ptr = NULL;
+	if (netdev->uc_count > rar_entries - 1) {
+		rctl |= E1000_RCTL_UPE;
+	} else if (!(netdev->flags & IFF_PROMISC)) {
+		rctl &= ~E1000_RCTL_UPE;
+		uc_ptr = netdev->uc_list;
 	}
 
 	E1000_WRITE_REG(hw, RCTL, rctl);
@@ -2431,7 +2439,10 @@ e1000_set_multi(struct net_device *netdev)
 	if (hw->mac_type == e1000_82542_rev2_0)
 		e1000_enter_82542_rst(adapter);
 
-	/* load the first 14 multicast address into the exact filters 1-14
+	/* load the first 14 addresses into the exact filters 1-14. Unicast
+	 * addresses take precedence to avoid disabling unicast filtering
+	 * when possible.
+	 *
 	 * RAR 0 is used for the station MAC adddress
 	 * if there are not 14 addresses, go ahead and clear the filters
 	 * -- with 82571 controllers only 0-13 entries are filled here
@@ -2439,8 +2450,11 @@ e1000_set_multi(struct net_device *netdev)
 	mc_ptr = netdev->mc_list;
 
 	for (i = 1; i < rar_entries; i++) {
-		if (mc_ptr) {
-			e1000_rar_set(hw, mc_ptr->dmi_addr, i);
+		if (uc_ptr) {
+			e1000_rar_set(hw, uc_ptr->da_addr, i);
+			uc_ptr = uc_ptr->next;
+		} else if (mc_ptr) {
+			e1000_rar_set(hw, mc_ptr->da_addr, i);
 			mc_ptr = mc_ptr->next;
 		} else {
 			E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
@@ -2449,6 +2463,7 @@ e1000_set_multi(struct net_device *netdev)
 			E1000_WRITE_FLUSH(hw);
 		}
 	}
+	WARN_ON(uc_ptr != NULL);
 
 	/* clear the old settings from the multicast hash table */
 
@@ -2460,7 +2475,7 @@ e1000_set_multi(struct net_device *netdev)
 	/* load any remaining addresses into the hash table */
 
 	for (; mc_ptr; mc_ptr = mc_ptr->next) {
-		hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr);
+		hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
 		e1000_mta_set(hw, hash_value);
 	}
 
@@ -5079,7 +5094,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 
 	if (wufc) {
 		e1000_setup_rctl(adapter);
-		e1000_set_multi(netdev);
+		e1000_set_rx_mode(netdev);
 
 		/* turn on all-multi mode if wake on multicast is enabled */
 		if (wufc & E1000_WUFC_MC) {
#8 lore raw

Re: [PATCH 5/6] e1000: Secondary unicast address support

Quoted 8 lines · Auke Kok

From: Patrick McHardy <[email protected]>

Add support for configuring secondary unicast addresses. Unicast addresses take precendece over multicast addresses when filling the exact address filters to avoid going to promiscous mode. When more unicast addresses are present than filter slots, unicast filtering is disabled and all slots can be used for multicast addresses.

Is there any easy way to use it for VRRP? It would be really great to have two IP addresses on the same interface, each with a different hw address.

Best regards,

Krzysztof Olędzki

#9 lore raw

Re: [PATCH 5/6] e1000: Secondary unicast address support

Quoted 6 lines · Krzysztof Oledzki
Quoted 2 lines · Auke Kok

From: Patrick McHardy <[email protected]>

Quoted 8 lines
Quoted 6 lines

Add support for configuring secondary unicast addresses. Unicast addresses take precendece over multicast addresses when filling the exact address filters to avoid going to promiscous mode. When more unicast addresses are present than filter slots, unicast filtering is disabled and all slots can be used for multicast addresses.

Is there any easy way to use it for VRRP? It would be really great to have two IP addresses on the same interface, each with a different hw address.

mac-vlans should do this for you..with our without the driver patch.

Ben

Quoted 4 lines

Best regards,

Krzysztof Olędzki

Signature · 2 lines
Ben Greear <[email protected]>
Candela Technologies Inc  http://www.candelatech.com
#10 lore raw

Re: [PATCH 5/6] e1000: Secondary unicast address support

Quoted 14 lines · Ben Greear
Quoted 13 lines · Krzysztof Oledzki
Quoted 8 lines · Auke Kok

From: Patrick McHardy <[email protected]>

Add support for configuring secondary unicast addresses. Unicast addresses take precendece over multicast addresses when filling the exact address filters to avoid going to promiscous mode. When more unicast addresses are present than filter slots, unicast filtering is disabled and all slots can be used for multicast addresses.

Quoted 3 lines
Quoted 1 line

Is there any easy way to use it for VRRP? It would be really great to have two IP addresses on the same interface, each with a different hw address.

mac-vlans should do this for you..with our without the driver patch.

I'm afraid mac-vlans is not a solution here. Having 2x more interfaces (ex. 2000 instead of 1000) makes everything (especially routing, firewalling and QoS) much more complicated. It would be nice to have something like "ip addr add a.b.c.d/24 dev vlan32 hwaddress aa:bb:cc:dd:ee:ff".

BTW: is it possible to stack mac-vlans ontop of .1Q vlans?

Best regards,

Krzysztof Olędzki

#11 lore raw

Re: [PATCH 5/6] e1000: Secondary unicast address support

Quoted 1 line · Krzysztof Oledzki

I'm afraid mac-vlans is not a solution here. Having 2x more interfaces (ex. 2000 instead of 1000) makes everything (especially routing, firewalling and QoS) much more complicated. It would be nice to have something like "ip addr add a.b.c.d/24 dev vlan32 hwaddress aa:bb:cc:dd:ee:ff".

I'll take your word for it, though I have had good luck using mac-vlans in my own app. They are nice because the are full-fledged interfaces, so you can treat them basically as .1q vlans or ethernet devices, including all the routing and firewalling tricks.

Quoted 1 line

BTW: is it possible to stack mac-vlans ontop of .1Q vlans?

I believe it will work fine. You could probably also stack .1q VLANs on top of mac-vlans so long as you use the same MAC for the VLANs as for the mac-vlan dev.

Thanks,
Ben

Signature · 2 lines
Ben Greear <[email protected]>
Candela Technologies Inc  http://www.candelatech.com
#12 lore raw

Re: [PATCH 5/6] e1000: Secondary unicast address support

Quoted 8 lines · Ben Greear
Quoted 1 line · Krzysztof Oledzki

I'm afraid mac-vlans is not a solution here. Having 2x more interfaces (ex. 2000 instead of 1000) makes everything (especially routing, firewalling and QoS) much more complicated. It would be nice to have something like "ip addr add a.b.c.d/24 dev vlan32 hwaddress aa:bb:cc:dd:ee:ff".

I'll take your word for it, though I have had good luck using mac-vlans in my own app. They are nice because the are full-fledged interfaces, so you can treat them basically as .1q vlans or ethernet devices, including all the routing and firewalling tricks.

OK. But in my situation it is going to be:

vlan1 (.1q) - real MAC
vlan1a (mac-vlan) - VRRP MAC
(...)
vlan999 (.1q) - real MAC
vlan999 (mac-vlan) - VRRP MAC

... with packets for the same destination coming in and out over both interfaces depending on a src ip address.

Quoted 5 lines
Quoted 1 line

BTW: is it possible to stack mac-vlans ontop of .1Q vlans?

I believe it will work fine. You could probably also stack .1q VLANs on top of mac-vlans so long as you use the same MAC for the VLANs as for the mac-vlan dev.

So, this is something exactly I don't want to do as I need two different MAC addresses. ;)

Best regards,

Krzysztof Olędzki

maintainer Applied
#13 lore raw

Re: [PATCH 5/6] e1000: Secondary unicast address support

In reply to Auke Kok

From: Auke Kok <[email protected]>
Date: Tue, 13 Nov 2007 15:11:33 -0800

Quoted 11 lines

From: Patrick McHardy <[email protected]>

Add support for configuring secondary unicast addresses. Unicast addresses take precendece over multicast addresses when filling the exact address filters to avoid going to promiscous mode. When more unicast addresses are present than filter slots, unicast filtering is disabled and all slots can be used for multicast addresses.

Applied to netdev-2.6, thanks!

author
#14 lore raw

PATCH 6/6 e1000: fix schedule while atomic when called from mii-tool

In reply to Auke Kok

From: Jesse Brandeburg <[email protected]>

mii-tool can cause the driver to call msleep during nway reset, bugzilla.kernel.org bug 8430. Fix by simply calling reinit_locked outside of the spinlock, which is safe from ethtool, so it should be safe from here.

---

 drivers/net/e1000/e1000_main.c |   13 +++----------
 1 files changed, 3 insertions(+), 10 deletions(-)
drivers/net/e1000/e1000_main.c +3 -10
index dc4934d..b7c3070 100644
@@ -4794,6 +4794,7 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 			spin_unlock_irqrestore(&adapter->stats_lock, flags);
 			return -EIO;
 		}
+		spin_unlock_irqrestore(&adapter->stats_lock, flags);
 		if (adapter->hw.media_type == e1000_media_type_copper) {
 			switch (data->reg_num) {
 			case PHY_CTRL:
@@ -4814,12 +4815,8 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 						   DUPLEX_HALF;
 					retval = e1000_set_spd_dplx(adapter,
 								    spddplx);
-					if (retval) {
-						spin_unlock_irqrestore(
-							&adapter->stats_lock,
-							flags);
+					if (retval)
 						return retval;
-					}
 				}
 				if (netif_running(adapter->netdev))
 					e1000_reinit_locked(adapter);
@@ -4828,11 +4825,8 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 				break;
 			case M88E1000_PHY_SPEC_CTRL:
 			case M88E1000_EXT_PHY_SPEC_CTRL:
-				if (e1000_phy_reset(&adapter->hw)) {
-					spin_unlock_irqrestore(
-						&adapter->stats_lock, flags);
+				if (e1000_phy_reset(&adapter->hw))
 					return -EIO;
-				}
 				break;
 			}
 		} else {
@@ -4847,7 +4841,6 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 				break;
 			}
 		}
-		spin_unlock_irqrestore(&adapter->stats_lock, flags);
 		break;
 	default:
 		return -EOPNOTSUPP;
maintainer
#15 lore raw

Re: [PATCH 6/6] e1000: fix schedule while atomic when called from mii-tool

From: Auke Kok <[email protected]>
Date: Tue, 13 Nov 2007 15:11:38 -0800

Quoted 9 lines

From: Jesse Brandeburg <[email protected]>

mii-tool can cause the driver to call msleep during nway reset, bugzilla.kernel.org bug 8430. Fix by simply calling reinit_locked outside of the spinlock, which is safe from ethtool, so it should be safe from here.

Looks good.

A bug fix, so queued to net-2.6, thanks.

maintainer Applied
#16 lore raw
In reply to Auke Kok

From: Auke Kok <[email protected]>
Date: Tue, 13 Nov 2007 15:11:10 -0800

Quoted 6 lines

formerly e1000/e1000e only updated traffic counters once every 2 seconds with the register values of bytes/packets. With newer code however in the interrupt and polling code we can real-time fill in these values in the netstats struct for users to see.

Applied to netdev-2.6