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

Previous thread: none

Next thread: Re: 2.6.24-rc2: Network commit causes SLUB performance regression with tbench by Nick Piggin on Tuesday, November 13, 2007 - 4:41 am. (20 messages)
From: Auke Kok
Date: Tuesday, November 13, 2007 - 4:11 pm

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.

Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---

 drivers/net/e1000e/netdev.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index a271112..6c99703 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -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;
 
-

From: Auke Kok
Date: Tuesday, November 13, 2007 - 4:11 pm

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.

Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---

 drivers/net/e1000/e1000_main.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index d1b88e4..e1ba705 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -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;
 }
 
-

From: David Miller
Date: Tuesday, November 13, 2007 - 9:51 pm

From: Auke Kok <auke-jan.h.kok@intel.com>

Applied to netdev-2.6, thanks.
-

From: Auke Kok
Date: Tuesday, November 13, 2007 - 4:11 pm

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

Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---

 drivers/net/e1000/e1000_ethtool.c |   84 ++++++++++++++++++++++++-------------
 1 files changed, 55 insertions(+), 29 deletions(-)

diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 667f18b..ec67ea9 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -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 ...
From: David Miller
Date: Tuesday, November 13, 2007 - 9:52 pm

From: Auke Kok <auke-jan.h.kok@intel.com>

Definitely this looks nicer :-)

Applied to netdev-2.6, thanks!
-

From: Auke Kok
Date: Tuesday, November 13, 2007 - 4:11 pm

From: Joe Perches <joe@perches.com>

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


Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---

 drivers/net/e1000e/ethtool.c |   84 +++++++++++++++++++++++++++---------------
 1 files changed, 53 insertions(+), 31 deletions(-)

diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 6a39784..bc1115d 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -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[] = ...
From: David Miller
Date: Tuesday, November 13, 2007 - 9:54 pm

From: Auke Kok <auke-jan.h.kok@intel.com>

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!
-

From: Auke Kok
Date: Tuesday, November 13, 2007 - 4:11 pm

From: Patrick McHardy <kaber@trash.net>

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.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---

 drivers/net/e1000/e1000_main.c |   47 ++++++++++++++++++++++++++--------------
 1 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index e1ba705..dc4934d 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -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 = ...
From: Krzysztof Oledzki
Date: Tuesday, November 13, 2007 - 5:16 pm

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

Best regards,

 =09=09=09=09 Krzysztof Ol=EAdzki
From: Ben Greear
Date: Tuesday, November 13, 2007 - 5:18 pm

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



-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

-

From: Krzysztof Oledzki
Date: Tuesday, November 13, 2007 - 5:48 pm

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

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

Best regards,

 =09=09=09=09Krzysztof Ol=EAdzki
From: Ben Greear
Date: Tuesday, November 13, 2007 - 6:05 pm

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

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

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

-

From: Krzysztof Oledzki
Date: Tuesday, November 13, 2007 - 6:17 pm

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

=2E.. with packets for the same destination coming in and out over both=20

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

Best regards,

 =09=09=09=09Krzysztof Ol=EAdzki
From: David Miller
Date: Tuesday, November 13, 2007 - 9:55 pm

From: Auke Kok <auke-jan.h.kok@intel.com>

Applied to netdev-2.6, thanks!
-

From: Auke Kok
Date: Tuesday, November 13, 2007 - 4:11 pm

From: Jesse Brandeburg <jesse.brandeburg@intel.com>

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.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---

 drivers/net/e1000/e1000_main.c |   13 +++----------
 1 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index dc4934d..b7c3070 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -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;
 ...
From: David Miller
Date: Tuesday, November 13, 2007 - 10:00 pm

From: Auke Kok <auke-jan.h.kok@intel.com>

Looks good.

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

From: David Miller
Date: Tuesday, November 13, 2007 - 9:48 pm

From: Auke Kok <auke-jan.h.kok@intel.com>

Applied to netdev-2.6
-

Previous thread: none

Next thread: Re: 2.6.24-rc2: Network commit causes SLUB performance regression with tbench by Nick Piggin on Tuesday, November 13, 2007 - 4:41 am. (20 messages)