Netdev List
 help / color / mirror / Atom feed
* RE: Potential u32 classifier bug.
From: Waskiewicz Jr, Peter P @ 2007-08-15 18:02 UTC (permalink / raw)
  To: Thomas Graf; +Cc: netdev
In-Reply-To: <20070815175758.GC32236@postel.suug.ch>

> * Waskiewicz Jr, Peter P <peter.p.waskiewicz.jr@intel.com> 
> 2007-08-09 18:07
> > My big question is: Has anyone recently used the 802_3 
> protocol in tc 
> > with u32 and actually gotten it to work?  I can't see how the
> > u32_classify() code can look at the mac header, since it is 
> using the 
> > network header accessor to start looking.  I think this is an issue 
> > with the classification code, but I'm looking to see if I'm doing 
> > something stupid before I really start digging into this mess.
> 
> There is this very horrible way of using the u32 classifier 
> with a negative offset to look into the ethernet header.

Based on this, it sounds like u32 using protocol 802_3 is broken?

> You might want to look into the cmp ematch which can be 
> attached to almost any classifier. It allows basing offsets 
> on any layer thus making ethernet header filtering trivial.

I'll look at this.  Thanks Thomas for the response!

-PJ

^ permalink raw reply

* Re: Potential u32 classifier bug.
From: Thomas Graf @ 2007-08-15 17:57 UTC (permalink / raw)
  To: Waskiewicz Jr, Peter P; +Cc: netdev
In-Reply-To: <D5C1322C3E673F459512FB59E0DDC3290365C9A8@orsmsx414.amr.corp.intel.com>

* Waskiewicz Jr, Peter P <peter.p.waskiewicz.jr@intel.com> 2007-08-09 18:07
> My big question is: Has anyone recently used the 802_3 protocol in tc
> with u32 and actually gotten it to work?  I can't see how the
> u32_classify() code can look at the mac header, since it is using the
> network header accessor to start looking.  I think this is an issue with
> the classification code, but I'm looking to see if I'm doing something
> stupid before I really start digging into this mess.

There is this very horrible way of using the u32 classifier with a
negative offset to look into the ethernet header.

You might want to look into the cmp ematch which can be attached to
almost any classifier. It allows basing offsets on any layer thus
making ethernet header filtering trivial.

^ permalink raw reply

* Re: [PATCH 0/24] make atomic_read() behave consistently across all architectures
From: Satyam Sharma @ 2007-08-15 18:05 UTC (permalink / raw)
  To: Paul E. McKenney
  Cc: Herbert Xu, Stefan Richter, Christoph Lameter, Chris Snook,
	Linux Kernel Mailing List, linux-arch, Linus Torvalds, netdev,
	Andrew Morton, ak, heiko.carstens, davem, schwidefsky, wensong,
	horms, wjiang, cfriesen, zlynx, rpjday, jesper.juhl, segher
In-Reply-To: <20070815173326.GF9645@linux.vnet.ibm.com>



On Wed, 15 Aug 2007, Paul E. McKenney wrote:

> On Wed, Aug 15, 2007 at 10:48:28PM +0530, Satyam Sharma wrote:
> > [...]
> > Not for i386 and x86_64 -- those have atomic ops without any "volatile"
> > semantics (currently as per existing definitions).
> 
> I claim unit volumes with arm, and the majority of the architectures, but
> I cannot deny the popularity of i386 and x86_64 with many developers.  ;-)

Hmm, does arm really need that "volatile int counter;"? Hopefully RMK will
take a patch removing that "volatile" ... ;-)


> However, I am not aware of code in the kernel that would benefit
> from the compiler coalescing multiple atomic_set() and atomic_read()
> invocations, thus I don't see the downside to volatility in this case.
> Are there some performance-critical code fragments that I am missing?

I don't know, and yes, code with multiple atomic_set's and atomic_read's
getting optimized or coalesced does sound strange to start with. Anyway,
I'm not against "volatile semantics" per se. As replied elsewhere, I do
appreciate the motivation behind this series (to _avoid_ gotchas, not to
fix existing ones). Just that I'd like to avoid using "volatile", for
aforementioned reasons, especially given that there are perfectly
reasonable alternatives to achieve the same desired behaviour.


Satyam

^ permalink raw reply

* Re: [GENETLINK] some thoughts on the usage
From: Thomas Graf @ 2007-08-15 17:50 UTC (permalink / raw)
  To: Richard MUSIL; +Cc: netdev
In-Reply-To: <46BC25A6.7000703@st.com>

* Richard MUSIL <richard.musil@st.com> 2007-08-10 10:45
> I have noticed that although ops for each family are the same (each
> device is functionally same) I cannot use same genl_ops struct for
> registration, because it uses internal member to link in list. Therefore
> it is necessary to allocate new genl_ops for each device and pass it to
> registration. But I cannot "officially" use this list to track those
> genl_ops (so I can properly destroy them later), because there is no
> interface. So I need to redo the management of the structures on my own.

The intended usage of the interface in your example would be to register
only one genetlink family, say "tpm", register one set of operations
and then have an attribute in every message which specifies which TPM
device to use. This helps keeping the total number of genetlink families
down.

> The second "inconvenience" is that for each family I register, I also
> register basically same ops (basically means, the definitions, and doit,
> dumpit handlers are same, though the structures are at different
> addresses for reasons described above). When the handler receives the
> message it needs to associate the message with the actual device it is
> handling. This could be done through family lookup (using
> nlmsghdr::nlmsg_type), but I wondered if it would make sense to extend
> genl_family for user custom data pointer and then pass this custom data
> (or genl_family reference) to each handler (for example inside
> genl_info). It is already parsed by genetlink layer, so it should not
> slow things down.

That's not a bad idea, although I think we should try and keep the
generic netlink part as simple as possible. There is a family specific
header, referred to as user header in genl_info which is basically
what you're looking for with the custom header. I believe making the
generic netlink family aware of anything beyond family id and operations
id only complicates things.

^ permalink raw reply

* Re: [PATCH 0/24] make atomic_read() behave consistently across all architectures
From: Satyam Sharma @ 2007-08-15 17:55 UTC (permalink / raw)
  To: Paul E. McKenney
  Cc: Stefan Richter, Christoph Lameter, Chris Snook,
	Linux Kernel Mailing List, linux-arch, Linus Torvalds, netdev,
	Andrew Morton, ak, heiko.carstens, davem, schwidefsky, wensong,
	horms, wjiang, cfriesen, zlynx, rpjday, jesper.juhl, segher,
	Herbert Xu
In-Reply-To: <20070815142516.GB9645@linux.vnet.ibm.com>

Hi Paul,


On Wed, 15 Aug 2007, Paul E. McKenney wrote:

> On Wed, Aug 15, 2007 at 07:17:29PM +0530, Satyam Sharma wrote:
> > [...]
> > No, I'd actually prefer something like what Christoph Lameter suggested,
> > i.e. users (such as above) who want "volatile"-like behaviour from atomic
> > ops can use alternative functions. How about something like:
> > 
> > #define atomic_read_volatile(v)			\
> > 	({					\
> > 		forget(&(v)->counter);		\
> > 		((v)->counter);			\
> > 	})
> 
> Wouldn't the above "forget" the value, throw it away, then forget
> that it forgot it, giving non-volatile semantics?

Nope, I don't think so. I wrote the following trivial testcases:
[ See especially tp4.c and tp4.s (last example). ]

==============================================================================
$ cat tp1.c # Using volatile access casts

#define atomic_read(a)	(*(volatile int *)&a)

int a;

void func(void)
{
	a = 0;
	while (atomic_read(a))
		;
}
==============================================================================
$ gcc -Os -S tp1.c; cat tp1.s

func:
	pushl	%ebp
	movl	%esp, %ebp
	movl	$0, a
.L2:
	movl	a, %eax
	testl	%eax, %eax
	jne	.L2
	popl	%ebp
	ret
==============================================================================
$ cat tp2.c # Using nothing; gcc will optimize the whole loop away

#define forget(x)

#define atomic_read(a)		\
	({			\
		forget(&(a));	\
		(a);		\
	})

int a;

void func(void)
{
	a = 0;
	while (atomic_read(a))
		;
}
==============================================================================
$ gcc -Os -S tp2.c; cat tp2.s

func:
	pushl	%ebp
	movl	%esp, %ebp
	popl	%ebp
	movl	$0, a
	ret
==============================================================================
$ cat tp3.c # Using a full memory clobber barrier

#define forget(x)	asm volatile ("":::"memory")

#define atomic_read(a)		\
	({			\
		forget(&(a));	\
		(a);		\
	})

int a;

void func(void)
{
	a = 0;
	while (atomic_read(a))
		;
}
==============================================================================
$ gcc -Os -S tp3.c; cat tp3.s

func:
	pushl	%ebp
	movl	%esp, %ebp
	movl	$0, a
.L2:
	cmpl	$0, a
	jne	.L2
	popl	%ebp
	ret
==============================================================================
$ cat tp4.c # Using a forget(var) macro

#define forget(a)	__asm__ __volatile__ ("" :"=m" (a) :"m" (a))

#define atomic_read(a)		\
	({			\
		forget(a);	\
		(a);		\
	})

int a;

void func(void)
{
	a = 0;
	while (atomic_read(a))
		;
}
==============================================================================
$ gcc -Os -S tp4.c; cat tp4.s

func:
	pushl	%ebp
	movl	%esp, %ebp
	movl	$0, a
.L2:
	cmpl	$0, a
	jne	.L2
	popl	%ebp
	ret
==============================================================================


Possibly these were too trivial to expose any potential problems that you
may have been referring to, so would be helpful if you could write a more
concrete example / sample code.


> > Or possibly, implement these "volatile" atomic ops variants in inline asm
> > like the patch that Sebastian Siewior has submitted on another thread just
> > a while back.
> 
> Given that you are advocating a change (please keep in mind that
> atomic_read() and atomic_set() had volatile semantics on almost all
> platforms), care to give some example where these historical volatile
> semantics are causing a problem?
> [...]
> Can you give even one example
> where the pre-existing volatile semantics are causing enough of a problem
> to justify adding yet more atomic_*() APIs?

Will take this to the other sub-thread ...


> > Of course, if we find there are more callers in the kernel who want the
> > volatility behaviour than those who don't care, we can re-define the
> > existing ops to such variants, and re-name the existing definitions to
> > somethine else, say "atomic_read_nonvolatile" for all I care.
> 
> Do we really need another set of APIs?

Well, if there's one set of users who do care about volatile behaviour,
and another set that doesn't, it only sounds correct to provide both
those APIs, instead of forcing one behaviour on all users.


Thanks,
Satyam

^ permalink raw reply

* [PATCH 2/2] ethtool: add register dump support for intel 82598 chipsets (ixgbe driver)
From: Auke Kok @ 2007-08-15 17:44 UTC (permalink / raw)
  To: jeff; +Cc: davem, netdev, nicholas.d.nunley, auke-jan.h.kok
In-Reply-To: <20070815174401.15938.53561.stgit@localhost.localdomain>

From: Nicholas Nunley <nicholas.d.nunley@intel.com>

Signed-off-by: Nicholas Nunley <nicholas.d.nunley@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---

 Makefile.am    |    2 
 ethtool-util.h |    2 
 ethtool.c      |    1 
 ixgbe.c        | 1017 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 1021 insertions(+), 1 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 7bb58d8..43d1236 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,7 +6,7 @@ EXTRA_DIST = ethtool.8 ethtool.spec.in aclocal.m4 ChangeLog autogen.sh
 sbin_PROGRAMS = ethtool
 ethtool_SOURCES = ethtool.c ethtool-copy.h ethtool-util.h	\
 		  amd8111e.c de2104x.c e100.c e1000.c igb.c	\
-		  fec_8xx.c ibm_emac.c ixgb.c natsemi.c		\
+		  fec_8xx.c ibm_emac.c ixgb.c ixgbe.c natsemi.c	\
 		  pcnet32.c realtek.c tg3.c marvell.c vioc.c	\
 		  smsc911x.c
 
diff --git a/ethtool-util.h b/ethtool-util.h
index 1621dfe..5572771 100644
--- a/ethtool-util.h
+++ b/ethtool-util.h
@@ -56,6 +56,8 @@ int ibm_emac_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
 /* Intel(R) PRO/10GBe Gigabit Adapter Family */
 int ixgb_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
 
+int ixgbe_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
+
 /* Broadcom Tigon3 Ethernet controller */
 int tg3_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
 
diff --git a/ethtool.c b/ethtool.c
index 29562a7..651529e 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1005,6 +1005,7 @@ static struct {
 	{ "e1000", e1000_dump_regs },
 	{ "igb", igb_dump_regs },
 	{ "ixgb", ixgb_dump_regs },
+	{ "ixgbe", ixgbe_dump_regs },
 	{ "natsemi", natsemi_dump_regs },
 	{ "e100", e100_dump_regs },
 	{ "amd8111e", amd8111e_dump_regs },
diff --git a/ixgbe.c b/ixgbe.c
new file mode 100644
index 0000000..03eba6a
--- /dev/null
+++ b/ixgbe.c
@@ -0,0 +1,1017 @@
+/* Copyright (c) 2007 Intel Corporation */
+#include <stdio.h>
+#include "ethtool-util.h"
+
+/* Register Bit Masks */
+#define IXGBE_FCTRL_SBP            0x00000002
+#define IXGBE_FCTRL_MPE            0x00000100
+#define IXGBE_FCTRL_UPE            0x00000200
+#define IXGBE_FCTRL_BAM            0x00000400
+#define IXGBE_FCTRL_PMCF           0x00001000
+#define IXGBE_FCTRL_DPF            0x00002000
+#define IXGBE_FCTRL_RPFCE          0x00004000
+#define IXGBE_FCTRL_RFCE           0x00008000
+#define IXGBE_VLNCTRL_VET          0x0000FFFF
+#define IXGBE_VLNCTRL_CFI          0x10000000
+#define IXGBE_VLNCTRL_CFIEN        0x20000000
+#define IXGBE_VLNCTRL_VFE          0x40000000
+#define IXGBE_VLNCTRL_VME          0x80000000
+#define IXGBE_LINKS_UP             0x40000000
+#define IXGBE_LINKS_SPEED          0x20000000
+#define IXGBE_SRRCTL_BSIZEPKT_MASK 0x0000007F
+#define IXGBE_HLREG0_TXCRCEN       0x00000001
+#define IXGBE_HLREG0_RXCRCSTRP     0x00000002
+#define IXGBE_HLREG0_JUMBOEN       0x00000004
+#define IXGBE_HLREG0_TXPADEN       0x00000400
+#define IXGBE_HLREG0_LPBK          0x00008000
+#define IXGBE_RMCS_TFCE_802_3X     0x00000008
+#define IXGBE_RMCS_TFCE_PRIORITY   0x00000010
+
+int
+ixgbe_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
+{
+	u32 *regs_buff = (u32 *)regs->data;
+	u32 reg;
+	u8 i;
+	u8 version = (u8)(regs->version >> 24);
+
+	if (version != 1)
+		return -1;
+
+	reg = regs_buff[1065];
+	fprintf(stdout,
+	"0x042A4: LINKS (Link Status register)                 0x%08X\n"
+	"       Link Status:                                   %s\n"
+	"       Link Speed:                                    %s\n",
+	reg,
+	reg & IXGBE_LINKS_UP      ? "up"       : "down",
+	reg & IXGBE_LINKS_SPEED   ? "10G"      : "1G");
+	
+	reg = regs_buff[515];
+	fprintf(stdout,
+	"0x05080: FCTRL (Filter Control register)              0x%08X\n"
+	"       Receive Flow Control Packets:                  %s\n"
+	"       Receive Priority Flow Control Packets:         %s\n"
+	"       Discard Pause Frames:                          %s\n"
+	"       Pass MAC Control Frames:                       %s\n"
+	"       Broadcast Accept:                              %s\n"
+	"       Unicast Promiscuous:                           %s\n"
+	"       Multicast Promiscuous:                         %s\n"
+	"       Store Bad Packets:                             %s\n",
+	reg,
+	reg & IXGBE_FCTRL_RFCE    ? "enabled"  : "disabled",
+	reg & IXGBE_FCTRL_RPFCE   ? "enabled"  : "disabled",
+	reg & IXGBE_FCTRL_DPF     ? "enabled"  : "disabled",
+	reg & IXGBE_FCTRL_PMCF    ? "enabled"  : "disabled",
+	reg & IXGBE_FCTRL_BAM     ? "enabled"  : "disabled",
+	reg & IXGBE_FCTRL_UPE     ? "enabled"  : "disabled",
+	reg & IXGBE_FCTRL_MPE     ? "enabled"  : "disabled",
+	reg & IXGBE_FCTRL_SBP     ? "enabled"  : "disabled");
+	
+	reg = regs_buff[516];
+	fprintf(stdout,
+	"0x05088: VLNCTRL (VLAN Control register)              0x%08X\n"
+	"       VLAN Mode:                                     %s\n"
+	"       VLAN Filter:                                   %s\n",
+	reg,
+	reg & IXGBE_VLNCTRL_VME   ? "enabled"  : "disabled",
+	reg & IXGBE_VLNCTRL_VFE   ? "enabled"  : "disabled");
+	
+	reg = regs_buff[437];
+	fprintf(stdout,
+	"0x02100: SRRCTL0 (Split and Replic Rx Control 0)      0x%08X\n"
+	"       Receive Buffer Size:                           %uKB\n",
+	reg,
+	(reg & IXGBE_SRRCTL_BSIZEPKT_MASK) <= 0x10 ? (reg & IXGBE_SRRCTL_BSIZEPKT_MASK) : 0x10);
+	
+	reg = regs_buff[829];
+	fprintf(stdout,
+	"0x03D00: RMCS (Receive Music Control register)        0x%08X\n"
+	"       Transmit Flow Control:                         %s\n"
+	"       Priority Flow Control:                         %s\n",
+	reg,
+	reg & IXGBE_RMCS_TFCE_802_3X     ? "enabled"  : "disabled",
+	reg & IXGBE_RMCS_TFCE_PRIORITY   ? "enabled"  : "disabled");
+	
+	reg = regs_buff[1047];
+	fprintf(stdout,
+	"0x04250: HLREG0 (Highlander Control 0 register)       0x%08X\n"
+	"       Transmit CRC:                                  %s\n"
+	"       Receive CRC Strip:                             %s\n"
+	"       Jumbo Frames:                                  %s\n"
+	"       Pad Short Frames:                              %s\n"
+	"       Loopback:                                      %s\n",
+	reg,
+	reg & IXGBE_HLREG0_TXCRCEN   ? "enabled"  : "disabled",
+	reg & IXGBE_HLREG0_RXCRCSTRP ? "enabled"  : "disabled",
+	reg & IXGBE_HLREG0_JUMBOEN   ? "enabled"  : "disabled",
+	reg & IXGBE_HLREG0_TXPADEN   ? "enabled"  : "disabled",
+	reg & IXGBE_HLREG0_LPBK      ? "enabled"  : "disabled");
+	
+	/* General Registers */
+	fprintf(stdout,
+		"0x00000: CTRL        (Device Control)                 0x%08X\n",
+		regs_buff[0]);
+
+	fprintf(stdout,
+		"0x00008: STATUS      (Device Status)                  0x%08X\n",
+		regs_buff[1]);
+
+	fprintf(stdout,
+		"0x00018: CTRL_EXT    (Extended Device Control)        0x%08X\n",
+		regs_buff[2]);
+
+	fprintf(stdout,
+		"0x00020: ESDP        (Extended SDP Control)           0x%08X\n",
+		regs_buff[3]);
+
+	fprintf(stdout,
+		"0x00028: EODSDP      (Extended OD SDP Control)        0x%08X\n",
+		regs_buff[4]);
+
+	fprintf(stdout,
+		"0x00200: LEDCTL      (LED Control)                    0x%08X\n",
+		regs_buff[5]);
+
+	fprintf(stdout,
+		"0x00048: FRTIMER     (Free Running Timer)             0x%08X\n",
+		regs_buff[6]);
+
+	fprintf(stdout,
+		"0x0004C: TCPTIMER    (TCP Timer)                      0x%08X\n",
+		regs_buff[7]);
+
+	/* NVM Register */
+	fprintf(stdout,
+		"0x10010: EEC         (EEPROM/Flash Control)           0x%08X\n",
+		regs_buff[8]);
+
+	fprintf(stdout,
+		"0x10014: EERD        (EEPROM Read)                    0x%08X\n",
+		regs_buff[9]);
+
+	fprintf(stdout,
+		"0x1001C: FLA         (Flash Access)                   0x%08X\n",
+		regs_buff[10]);
+
+	fprintf(stdout,
+		"0x10110: EEMNGCTL    (Manageability EEPROM Control)   0x%08X\n",
+		regs_buff[11]);
+
+	fprintf(stdout,
+		"0x10114: EEMNGDATA   (Manageability EEPROM R/W Data)  0x%08X\n",
+		regs_buff[12]);
+
+	fprintf(stdout,
+		"0x10110: FLMNGCTL    (Manageability Flash Control)    0x%08X\n",
+		regs_buff[13]);
+
+	fprintf(stdout,
+		"0x1011C: FLMNGDATA   (Manageability Flash Read Data)  0x%08X\n",
+		regs_buff[14]);
+
+	fprintf(stdout,
+		"0x10120: FLMNGCNT    (Manageability Flash Read Count) 0x%08X\n",
+		regs_buff[15]);
+
+	fprintf(stdout,
+		"0x1013C: FLOP        (Flash Opcode)                   0x%08X\n",
+		regs_buff[16]);
+
+	fprintf(stdout,
+		"0x10200: GRC         (General Receive Control)        0x%08X\n",
+		regs_buff[17]);
+
+	/* Interrupt */
+	fprintf(stdout,
+		"0x00800: EICR        (Extended Interrupt Cause)       0x%08X\n",
+		regs_buff[18]);
+
+	fprintf(stdout,
+		"0x00808: EICS        (Extended Interrupt Cause Set)   0x%08X\n",
+		regs_buff[19]);
+
+	fprintf(stdout,
+		"0x00880: EIMS        (Extended Interr. Mask Set/Read) 0x%08X\n",
+		regs_buff[20]);
+
+	fprintf(stdout,
+		"0x00888: EIMC        (Extended Interrupt Mask Clear)  0x%08X\n",
+		regs_buff[21]);
+
+	fprintf(stdout,
+		"0x00810: EIAC        (Extended Interrupt Auto Clear)  0x%08X\n",
+		regs_buff[22]);
+
+	fprintf(stdout,
+		"0x00890: EIAM        (Extended Interr. Auto Mask EN)  0x%08X\n",
+		regs_buff[23]);
+
+	fprintf(stdout,
+		"0x00820: EITR0       (Extended Interrupt Throttle 0)  0x%08X\n",
+		regs_buff[24]);
+
+	fprintf(stdout,
+		"0x00900: IVAR0       (Interrupt Vector Allocation 0)  0x%08X\n",
+		regs_buff[25]);
+
+	fprintf(stdout,
+		"0x00000: MSIXT       (MSI-X Table)                    0x%08X\n",
+		regs_buff[26]);
+
+	fprintf(stdout,
+		"0x02000: MSIXPBA     (MSI-X Pending Bit Array)        0x%08X\n",
+		regs_buff[27]);
+
+	fprintf(stdout,
+		"0x11068: PBACL       (MSI-X PBA Clear)                0x%08X\n",
+		regs_buff[28]);
+
+	fprintf(stdout,
+		"0x00898: GPIE        (General Purpose Interrupt EN)   0x%08X\n",
+		regs_buff[29]);
+
+	/* Flow Control */
+	fprintf(stdout,
+		"0x03008: PFCTOP      (Priority Flow Ctrl Type Opcode) 0x%08X\n",
+		regs_buff[30]);
+
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x%05X: FCCTV%d      (Flow Ctrl Tx Timer Value %d)     0x%08X\n",
+		0x03200 + (4 * i), i, i, regs_buff[31 + i]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: FCRTL%d      (Flow Ctrl Rx Threshold low %d)   0x%08X\n",
+		0x3220 + (8 * i), i, i, regs_buff[35 + i]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: FCRTH%d      (Flow Ctrl Rx Threshold High %d)  0x%08X\n",
+		0x3260 + (8 * i), i, i, regs_buff[43 + i]);
+
+	fprintf(stdout,
+		"0x032A0: FCRTV       (Flow Control Refresh Threshold) 0x%08X\n",
+		regs_buff[51]);
+
+	fprintf(stdout,
+		"0x0CE00: TFCS        (Transmit Flow Control Status)   0x%08X\n",
+		regs_buff[52]);
+
+	/* Receive DMA */
+	for (i = 0; i < 64; i++)
+		fprintf(stdout,
+		"0x%05X: RDBAL%02d     (Rx Desc Base Addr Low %02d)       0x%08X\n",
+		0x01000 + (0x40 * i), i, i, regs_buff[53 + i]);
+
+	for (i = 0; i < 64; i++)
+		fprintf(stdout,
+		"0x%05X: RDBAH%02d     (Rx Desc Base Addr High %02d)      0x%08X\n",
+		0x01004 + (0x40 * i), i, i, regs_buff[117 + i]);
+
+	for (i = 0; i < 64; i++)
+		fprintf(stdout,
+		"0x%05X: RDLEN%02d     (Receive Descriptor Length %02d)   0x%08X\n",
+		0x01008 + (0x40 * i), i, i, regs_buff[181 + i]);
+
+	for (i = 0; i < 64; i++)
+		fprintf(stdout,
+		"0x%05X: RDH%02d       (Receive Descriptor Head %02d)     0x%08X\n",
+		0x01010 + (0x40 * i), i, i, regs_buff[245 + i]);
+
+	for (i = 0; i < 64; i++)
+		fprintf(stdout,
+		"0x%05X: RDT%02d       (Receive Descriptor Tail %02d)     0x%08X\n",
+		0x01018 + (0x40 * i), i, i, regs_buff[309 + i]);
+
+	for (i = 0; i < 64; i++)
+		fprintf(stdout,
+		"0x%05X: RXDCTL%02d    (Receive Descriptor Control %02d)  0x%08X\n",
+		0x01028 + (0x40 * i), i, i, regs_buff[373 + i]);
+
+	for (i = 0; i < 16; i++)
+		fprintf(stdout,
+		"0x%05X: SRRCTL%02d    (Split and Replic Rx Control %02d) 0x%08X\n",
+		0x02100 + (4 * i), i, i, regs_buff[437 + i]);
+
+	for (i = 0; i < 16; i++)
+		fprintf(stdout,
+		"0x%05X: DCA_RXCTRL%02d (Rx DCA Control %02d)             0x%08X\n",
+		0x02200 + (4 * i), i, i, regs_buff[453 + i]);
+
+	fprintf(stdout,
+		"0x02F00: RDRXCTL     (Receive DMA Control)            0x%08X\n",
+		regs_buff[469]);
+
+	for (i = 0; i < 8; i++ )
+		fprintf(stdout,
+		"0x%05X: RXPBSIZE%d   (Receive Packet Buffer Size %d)   0x%08X\n",
+		0x3C00 + (4 * i), i, i, regs_buff[470 + i]);
+
+	fprintf(stdout,
+		"0x03000: RXCTRL      (Receive Control)                0x%08X\n",
+		regs_buff[478]);
+
+	fprintf(stdout,
+		"0x03D04: DROPEN      (Drop Enable Control)            0x%08X\n",
+		regs_buff[479]);
+
+	/* Receive */
+	fprintf(stdout,
+		"0x05000: RXCSUM      (Receive Checksum Control)       0x%08X\n",
+		regs_buff[480]);
+
+	fprintf(stdout,
+		"0x05008: RFCTL       (Receive Filter Control)         0x%08X\n",
+		regs_buff[481]);
+
+	for (i = 0; i < 16; i++)
+		fprintf(stdout,
+		"0x%05X: RAL%02d       (Receive Address Low%02d)          0x%08X\n",
+		0x05400 + (8 * i), i, i, regs_buff[482 + i]);
+
+	for (i = 0; i < 16; i++)
+		fprintf(stdout,
+		"0x%05X: RAH%02d       (Receive Address High %02d)        0x%08X\n",
+		0x05404 + (8 * i), i, i, regs_buff[498 + i]);
+
+	fprintf(stdout,
+		"0x05480: PSRTYPE     (Packet Split Receive Type)      0x%08X\n",
+		regs_buff[514]);
+
+	fprintf(stdout,
+		"0x05090: MCSTCTRL    (Multicast Control)              0x%08X\n",
+		regs_buff[517]);
+
+	fprintf(stdout,
+		"0x05818: MRQC        (Multiple Rx Queues Command)     0x%08X\n",
+		regs_buff[518]);
+
+	fprintf(stdout,
+		"0x0581C: VMD_CTL     (VMDq Control)                   0x%08X\n",
+		regs_buff[519]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: IMIR%d       (Immediate Interrupt Rx %d)       0x%08X\n",
+		0x05A80 + (4 * i), i, i, regs_buff[520 + i]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: IMIREXT%d    (Immed. Interr. Rx Extended %d)   0x%08X\n",
+		0x05AA0 + (4 * i), i, i, regs_buff[528 + i]);
+
+	fprintf(stdout,
+		"0x05AC0: IMIRVP      (Immed. Interr. Rx VLAN Prior.)  0x%08X\n",
+		regs_buff[536]);
+
+	/* Transmit */
+	for (i = 0; i < 32; i++)
+		fprintf(stdout,
+		"0x%05X: TDBAL%02d     (Tx Desc Base Addr Low %02d)       0x%08X\n",
+		0x06000 + (0x40 * i), i, i, regs_buff[537 + i]);
+
+	for (i = 0; i < 32; i++)
+		fprintf(stdout,
+		"0x%05X: TDBAH%02d     (Tx Desc Base Addr High %02d)      0x%08X\n",
+		0x06004 + (0x40 * i), i, i, regs_buff[569 + i]);
+
+	for (i = 0; i < 32; i++)
+		fprintf(stdout,
+		"0x%05X: TDLEN%02d     (Tx Descriptor Length %02d)        0x%08X\n",
+		0x06008 + (0x40 * i), i, i, regs_buff[601 + i]);
+
+	for (i = 0; i < 32; i++)
+		fprintf(stdout,
+		"0x%05X: TDH%02d       (Transmit Descriptor Head %02d)    0x%08X\n",
+		0x06010 + (0x40 * i), i, i, regs_buff[633 + i]);
+
+	for (i = 0; i < 32; i++)
+		fprintf(stdout,
+		"0x%05X: TDT%02d       (Transmit Descriptor Tail %02d)    0x%08X\n",
+		0x06018 + (0x40 * i), i, i, regs_buff[665 + i]);
+
+	for (i = 0; i < 32; i++)
+		fprintf(stdout,
+		"0x%05X: TXDCTL%02d    (Tx Descriptor Control %02d)       0x%08X\n",
+		0x06028 + (0x40 * i), i, i, regs_buff[697 + i]);
+
+	for (i = 0; i < 32; i++)
+		fprintf(stdout,
+		"0x%05X: TDWBAL%02d    (Tx Desc Compl. WB Addr low %02d)  0x%08X\n",
+		0x06038 + (0x40 * i), i, i, regs_buff[729 + i]);
+
+	for (i = 0; i < 32; i++)
+		fprintf(stdout,
+		"0x%05X: TDWBAH%02d    (Tx Desc Compl. WB Addr High %02d) 0x%08X\n",
+		0x0603C + (0x40 * i), i, i, regs_buff[761 + i]);
+
+	fprintf(stdout,
+		"0x07E00: DTXCTL      (DMA Tx Control)                 0x%08X\n",
+		regs_buff[793]);
+
+	for (i = 0; i < 16; i++)
+		fprintf(stdout,
+		"0x%05X: DCA_TXCTRL%02d (Tx DCA Control %02d)             0x%08X\n",
+		0x07200 + (4 * i), i, i, regs_buff[794 + i]);
+
+	fprintf(stdout,
+		"0x0CB00: TIPG        (Transmit IPG Control)           0x%08X\n",
+		regs_buff[810]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: TXPBSIZE%d   (Transmit Packet Buffer Size %d)  0x%08X\n",
+		0x0CC00 + (4 * i), i, i, regs_buff[811 + i]);
+
+	fprintf(stdout,
+		"0x0CD10: MNGTXMAP    (Manageability Tx TC Mapping)    0x%08X\n",
+		regs_buff[819]);
+
+	/* Wake Up */
+	fprintf(stdout,
+		"0x05800: WUC         (Wake up Control)                0x%08X\n",
+		regs_buff[820]);
+
+	fprintf(stdout,
+		"0x05808: WUFC        (Wake Up Filter Control)         0x%08X\n",
+		regs_buff[821]);
+
+	fprintf(stdout,
+		"0x05810: WUS         (Wake Up Status)                 0x%08X\n",
+		regs_buff[822]);
+
+	fprintf(stdout,
+		"0x05838: IPAV        (IP Address Valid)               0x%08X\n",
+		regs_buff[823]);
+
+	fprintf(stdout,
+		"0x05840: IP4AT       (IPv4 Address Table)             0x%08X\n",
+		regs_buff[824]);
+
+	fprintf(stdout,
+		"0x05880: IP6AT       (IPv6 Address Table)             0x%08X\n",
+		regs_buff[825]);
+
+	fprintf(stdout,
+		"0x05900: WUPL        (Wake Up Packet Length)          0x%08X\n",
+		regs_buff[826]);
+
+	fprintf(stdout,
+		"0x05A00: WUPM        (Wake Up Packet Memory)          0x%08X\n",
+		regs_buff[827]);
+
+	fprintf(stdout,
+		"0x09000: FHFT        (Flexible Host Filter Table)     0x%08X\n",
+		regs_buff[828]);
+
+	/* DCE */
+	fprintf(stdout,
+		"0x07F40: DPMCS       (Desc. Plan Music Ctrl Status)   0x%08X\n",
+		regs_buff[830]);
+
+	fprintf(stdout,
+		"0x0CD00: PDPMCS      (Pkt Data Plan Music ctrl Stat)  0x%08X\n",
+		regs_buff[831]);
+
+	fprintf(stdout,
+		"0x050A0: RUPPBMR     (Rx User Prior to Pkt Buff Map)  0x%08X\n",
+		regs_buff[832]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: RT2CR%d      (Receive T2 Configure %d)         0x%08X\n",
+		0x03C20 + (4 * i), i, i, regs_buff[833 + i]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: RT2SR%d      (Recieve T2 Status %d)            0x%08X\n",
+		0x03C40 + (4 * i), i, i, regs_buff[841 + i]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: TDTQ2TCCR%d  (Tx Desc TQ2 TC Config %d)        0x%08X\n",
+		0x0602C + (0x40 * i), i, i, regs_buff[849 + i]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: TDTQ2TCSR%d  (Tx Desc TQ2 TC Status %d)        0x%08X\n",
+		0x0622C + (0x40 * i), i, i, regs_buff[857 + i]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: TDPT2TCCR%d  (Tx Data Plane T2 TC Config %d)   0x%08X\n",
+		0x0CD20 + (4 * i), i, i, regs_buff[865 + i]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: TDPT2TCSR%d  (Tx Data Plane T2 TC Status %d)   0x%08X\n",
+		0x0CD40 + (4 * i), i, i, regs_buff[873 + i]);
+
+	/* Statistics */
+	fprintf(stdout,
+		"0x04000: crcerrs     (CRC Error Count)                0x%08X\n",
+		regs_buff[881]);
+
+	fprintf(stdout,
+		"0x04004: illerrc     (Illegal Byte Error Count)       0x%08X\n",
+		regs_buff[882]);
+
+	fprintf(stdout,
+		"0x04008: errbc       (Error Byte Count)               0x%08X\n",
+		regs_buff[883]);
+
+	fprintf(stdout,
+		"0x04010: mspdc       (MAC Short Packet Discard Count) 0x%08X\n",
+		regs_buff[884]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: mpc%d        (Missed Packets Count %d)         0x%08X\n",
+		0x03FA0 + (4 * i), i, i, regs_buff[885 + i]);
+
+	fprintf(stdout,
+		"0x04034: mlfc        (MAC Local Fault Count)          0x%08X\n",
+		regs_buff[893]);
+
+	fprintf(stdout,
+		"0x04038: mrfc        (MAC Remote Fault Count)         0x%08X\n",
+		regs_buff[894]);
+
+	fprintf(stdout,
+		"0x04040: rlec        (Receive Length Error Count)     0x%08X\n",
+		regs_buff[895]);
+
+	fprintf(stdout,
+		"0x03F60: lxontxc     (Link XON Transmitted Count)     0x%08X\n",
+		regs_buff[896]);
+
+	fprintf(stdout,
+		"0x0CF60: lxonrxc     (Link XON Received Count)        0x%08X\n",
+		regs_buff[897]);
+
+	fprintf(stdout,
+		"0x03F68: lxofftxc    (Link XOFF Transmitted Count)    0x%08X\n",
+		regs_buff[898]);
+
+	fprintf(stdout,
+		"0x0CF68: lxoffrxc    (Link XOFF Received Count)       0x%08X\n",
+		regs_buff[899]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: pxontxc%d    (Priority XON Tx Count %d)        0x%08X\n",
+		0x03F00 + (4 * i), i, i, regs_buff[900 + i]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: pxonrxc%d    (Priority XON Received Count %d)  0x%08X\n",
+		0x0CF00 + (4 * i), i, i, regs_buff[908 + i]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: pxofftxc%d   (Priority XOFF Tx Count %d)       0x%08X\n",
+		0x03F20 + (4 * i), i, i, regs_buff[916 + i]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: pxoffrxc%d   (Priority XOFF Received Count %d) 0x%08X\n",
+		0x0CF20 + (4 * i), i, i, regs_buff[924 + i]);
+
+	fprintf(stdout,
+		"0x0405C: prc64       (Packets Received (64B) Count)   0x%08X\n",
+		regs_buff[932]);
+
+	fprintf(stdout,
+		"0x04060: prc127      (Packets Rx (65-127B) Count)     0x%08X\n",
+		regs_buff[933]);
+
+	fprintf(stdout,
+		"0x04064: prc255      (Packets Rx (128-255B) Count)    0x%08X\n",
+		regs_buff[934]);
+
+	fprintf(stdout,
+		"0x04068: prc511      (Packets Rx (256-511B) Count)    0x%08X\n",
+		regs_buff[935]);
+
+	fprintf(stdout,
+		"0x0406C: prc1023     (Packets Rx (512-1023B) Count)   0x%08X\n",
+		regs_buff[936]);
+
+	fprintf(stdout,
+		"0x04070: prc1522     (Packets Rx (1024-Max) Count)    0x%08X\n",
+		regs_buff[937]);
+
+	fprintf(stdout,
+		"0x04074: gprc        (Good Packets Received Count)    0x%08X\n",
+		regs_buff[938]);
+
+	fprintf(stdout,
+		"0x04078: bprc        (Broadcast Packets Rx Count)     0x%08X\n",
+		regs_buff[939]);
+
+	fprintf(stdout,
+		"0x0407C: mprc        (Multicast Packets Rx Count)     0x%08X\n",
+		regs_buff[940]);
+
+	fprintf(stdout,
+		"0x04080: gptc        (Good Packets Transmitted Count) 0x%08X\n",
+		regs_buff[941]);
+
+	fprintf(stdout,
+		"0x04088: gorcl       (Good Octets Rx Count Low)       0x%08X\n",
+		regs_buff[942]);
+
+	fprintf(stdout,
+		"0x0408C: gorch       (Good Octets Rx Count High)      0x%08X\n",
+		regs_buff[943]);
+
+	fprintf(stdout,
+		"0x04090: gotcl       (Good Octets Tx Count Low)       0x%08X\n",
+		regs_buff[944]);
+
+	fprintf(stdout,
+		"0x04094: gotch       (Good Octets Tx Count High)      0x%08X\n",
+		regs_buff[945]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: rnbc%d       (Receive No Buffers Count %d)     0x%08X\n",
+		0x03FC0 + (4 * i), i, i, regs_buff[946 + i]);
+
+	fprintf(stdout,
+		"0x040A4: ruc         (Receive Undersize count)        0x%08X\n",
+		regs_buff[954]);
+
+	fprintf(stdout,
+		"0x040A8: rfc         (Receive Fragment Count)         0x%08X\n",
+		regs_buff[955]);
+
+	fprintf(stdout,
+		"0x040AC: roc         (Receive Oversize Count)         0x%08X\n",
+		regs_buff[956]);
+
+	fprintf(stdout,
+		"0x040B0: rjc         (Receive Jabber Count)           0x%08X\n",
+		regs_buff[957]);
+
+	fprintf(stdout,
+		"0x040B4: mngprc      (Management Packets Rx Count)    0x%08X\n",
+		regs_buff[958]);
+
+	fprintf(stdout,
+		"0x040B8: mngpdc      (Management Pkts Dropped Count)  0x%08X\n",
+		regs_buff[959]);
+
+	fprintf(stdout,
+		"0x0CF90: mngptc      (Management Packets Tx Count)    0x%08X\n",
+		regs_buff[960]);
+
+	fprintf(stdout,
+		"0x040C0: torl        (Total Octets Rx Count Low)      0x%08X\n",
+		regs_buff[961]);
+
+	fprintf(stdout,
+		"0x040C4: torh        (Total Octets Rx Count High)     0x%08X\n",
+		regs_buff[962]);
+
+	fprintf(stdout,
+		"0x040D0: tpr         (Total Packets Received)         0x%08X\n",
+		regs_buff[963]);
+
+	fprintf(stdout,
+		"0x040D4: tpt         (Total Packets Transmitted)      0x%08X\n",
+		regs_buff[964]);
+
+	fprintf(stdout,
+		"0x040D8: ptc64       (Packets Tx (64B) Count)         0x%08X\n",
+		regs_buff[965]);
+
+	fprintf(stdout,
+		"0x040DC: ptc127      (Packets Tx (65-127B) Count)     0x%08X\n",
+		regs_buff[966]);
+
+	fprintf(stdout,
+		"0x040E0: ptc255      (Packets Tx (128-255B) Count)    0x%08X\n",
+		regs_buff[967]);
+
+	fprintf(stdout,
+		"0x040E4: ptc511      (Packets Tx (256-511B) Count)    0x%08X\n",
+		regs_buff[968]);
+
+	fprintf(stdout,
+		"0x040E8: ptc1023     (Packets Tx (512-1023B) Count)   0x%08X\n",
+		regs_buff[969]);
+
+	fprintf(stdout,
+		"0x040EC: ptc1522     (Packets Tx (1024-Max) Count)    0x%08X\n",
+		regs_buff[970]);
+
+	fprintf(stdout,
+		"0x040F0: mptc        (Multicast Packets Tx Count)     0x%08X\n",
+		regs_buff[971]);
+
+	fprintf(stdout,
+		"0x040F4: bptc        (Broadcast Packets Tx Count)     0x%08X\n",
+		regs_buff[972]);
+
+	fprintf(stdout,
+		"0x04120: xec         (XSUM Error Count)               0x%08X\n",
+		regs_buff[973]);
+
+	for (i = 0; i < 16; i++)
+		fprintf(stdout,
+		"0x%05X: qprc%02d      (Queue Packets Rx Count %02d)      0x%08X\n",
+		0x01030 + (0x40 * i), i, i, regs_buff[974 + i]);
+
+	for (i = 0; i < 16; i++)
+		fprintf(stdout,
+		"0x%05X: qptc%02d      (Queue Packets Tx Count %02d)      0x%08X\n",
+		0x06030 + (0x40 * i), i, i, regs_buff[990 + i]);
+
+	for (i = 0; i < 16; i++)
+		fprintf(stdout,
+		"0x%05X: qbrc%02d      (Queue Bytes Rx Count %02d)        0x%08X\n",
+		0x01034 + (0x40 * i), i, i, regs_buff[1006 + i]);
+
+	for (i = 0; i < 16; i++)
+		fprintf(stdout,
+		"0x%05X: qbtc%02d      (Queue Bytes Tx Count %02d)        0x%08X\n",
+		0x06034 + (0x40 * i), i, i, regs_buff[1022 + i]);
+
+	/* MAC */
+	fprintf(stdout,
+		"0x04200: PCS1GCFIG   (PCS_1G Gloabal Config 1)        0x%08X\n",
+		regs_buff[1038]);
+
+	fprintf(stdout,
+		"0x04208: PCS1GLCTL   (PCS_1G Link Control)            0x%08X\n",
+		regs_buff[1039]);
+
+	fprintf(stdout,
+		"0x0420C: PCS1GLSTA   (PCS_1G Link Status)             0x%08X\n",
+		regs_buff[1040]);
+
+	fprintf(stdout,
+		"0x04210: PCS1GDBG0   (PCS_1G Debug 0)                 0x%08X\n",
+		regs_buff[1041]);
+
+	fprintf(stdout,
+		"0x04214: PCS1GDBG1   (PCS_1G Debug 1)                 0x%08X\n",
+		regs_buff[1042]);
+
+	fprintf(stdout,
+		"0x04218: PCS1GANA    (PCS-1G Auto Neg. Adv.)          0x%08X\n",
+		regs_buff[1043]);
+
+	fprintf(stdout,
+		"0x0421C: PCS1GANLP   (PCS-1G AN LP Ability)           0x%08X\n",
+		regs_buff[1044]);
+
+	fprintf(stdout,
+		"0x04220: PCS1GANNP   (PCS_1G Auto Neg Next Page Tx)   0x%08X\n",
+		regs_buff[1045]);
+
+	fprintf(stdout,
+		"0x04224: PCS1GANLPNP (PCS_1G Auto Neg LPs Next Page)  0x%08X\n",
+		regs_buff[1046]);
+
+	fprintf(stdout,
+		"0x04244: HLREG1      (Highlander Status 1)            0x%08X\n",
+		regs_buff[1048]);
+
+	fprintf(stdout,
+		"0x04248: PAP         (Pause and Pace)                 0x%08X\n",
+		regs_buff[1049]);
+
+	fprintf(stdout,
+		"0x0424C: MACA        (MDI Auto-Scan Command and Addr) 0x%08X\n",
+		regs_buff[1050]);
+
+	fprintf(stdout,
+		"0x04250: APAE        (Auto-Scan PHY Address Enable)   0x%08X\n",
+		regs_buff[1051]);
+
+	fprintf(stdout,
+		"0x04254: ARD         (Auto-Scan Read Data)            0x%08X\n",
+		regs_buff[1052]);
+
+	fprintf(stdout,
+		"0x04258: AIS         (Auto-Scan Interrupt Status)     0x%08X\n",
+		regs_buff[1053]);
+
+	fprintf(stdout,
+		"0x0425C: MSCA        (MDI Single Command and Addr)    0x%08X\n",
+		regs_buff[1054]);
+
+	fprintf(stdout,
+		"0x04260: MSRWD       (MDI Single Read and Write Data) 0x%08X\n",
+		regs_buff[1055]);
+
+	fprintf(stdout,
+		"0x04264: MLADD       (MAC Address Low)                0x%08X\n",
+		regs_buff[1056]);
+
+	fprintf(stdout,
+		"0x04268: MHADD       (MAC Addr High/Max Frame size)   0x%08X\n",
+		regs_buff[1057]);
+
+	fprintf(stdout,
+		"0x0426C: TREG        (Test Register)                  0x%08X\n",
+		regs_buff[1058]);
+
+	fprintf(stdout,
+		"0x04288: PCSS1       (XGXS Status 1)                  0x%08X\n",
+		regs_buff[1059]);
+
+	fprintf(stdout,
+		"0x0428C: PCSS2       (XGXS Status 2)                  0x%08X\n",
+		regs_buff[1060]);
+
+	fprintf(stdout,
+		"0x04290: XPCSS       (10GBASE-X PCS Status)           0x%08X\n",
+		regs_buff[1061]);
+
+	fprintf(stdout,
+		"0x04298: SERDESC     (SERDES Interface Control)       0x%08X\n",
+		regs_buff[1062]);
+
+	fprintf(stdout,
+		"0x0429C: MACS        (FIFO Status/CNTL Report)        0x%08X\n",
+		regs_buff[1063]);
+
+	fprintf(stdout,
+		"0x042A0: AUTOC       (Auto Negotiation Control)       0x%08X\n",
+		regs_buff[1064]);
+
+	fprintf(stdout,
+		"0x042A8: AUTOC2      (Auto Negotiation Control 2)     0x%08X\n",
+		regs_buff[1066]);
+
+	fprintf(stdout,
+		"0x042AC: AUTOC3      (Auto Negotiation Control 3)     0x%08X\n",
+		regs_buff[1067]);
+
+	fprintf(stdout,
+		"0x042B0: ANLP1       (Auto Neg Lnk Part. Ctrl Word 1) 0x%08X\n",
+		regs_buff[1068]);
+
+	fprintf(stdout,
+		"0x042B0: ANLP2       (Auto Neg Lnk Part. Ctrl Word 2) 0x%08X\n",
+		regs_buff[1069]);
+
+	fprintf(stdout,
+		"0x04800: ATLASCTL    (Atlas Analog Configuration)     0x%08X\n",
+		regs_buff[1070]);
+
+	/* Diagnostic */
+	fprintf(stdout,
+		"0x02C20: RDSTATCTL   (Rx DMA Statistic Control)       0x%08X\n",
+		regs_buff[1071]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: RDSTAT%d     (Rx DMA Statistics %d)            0x%08X\n",
+		0x02C00 + (4 * i), i, i, regs_buff[1072 + i]);
+
+	fprintf(stdout,
+		"0x02F08: RDHMPN      (Rx Desc Handler Mem Page num)   0x%08X\n",
+		regs_buff[1080]);
+
+	fprintf(stdout,
+		"0x02F10: RIC_DW0     (Rx Desc Hand. Mem Read Data 0)  0x%08X\n",
+		regs_buff[1081]);
+
+	fprintf(stdout,
+		"0x02F14: RIC_DW1     (Rx Desc Hand. Mem Read Data 1)  0x%08X\n",
+		regs_buff[1082]);
+
+	fprintf(stdout,
+		"0x02F18: RIC_DW2     (Rx Desc Hand. Mem Read Data 2)  0x%08X\n",
+		regs_buff[1083]);
+
+	fprintf(stdout,
+		"0x02F1C: RIC_DW3     (Rx Desc Hand. Mem Read Data 3)  0x%08X\n",
+		regs_buff[1084]);
+
+	fprintf(stdout,
+		"0x02F20: RDPROBE     (Rx Probe Mode Status)           0x%08X\n",
+		regs_buff[1085]);
+
+	fprintf(stdout,
+		"0x07C20: TDSTATCTL   (Tx DMA Statistic Control)       0x%08X\n",
+		regs_buff[1086]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: TDSTAT%d     (Tx DMA Statistics %d)            0x%08X\n",
+		0x07C00 + (4 * i), i, i, regs_buff[1087 + i]);
+
+	fprintf(stdout,
+		"0x07F08: TDHMPN      (Tx Desc Handler Mem Page Num)   0x%08X\n",
+		regs_buff[1095]);
+
+	fprintf(stdout,
+		"0x07F10: TIC_DW0     (Tx Desc Hand. Mem Read Data 0)  0x%08X\n",
+		regs_buff[1096]);
+
+	fprintf(stdout,
+		"0x07F14: TIC_DW1     (Tx Desc Hand. Mem Read Data 1)  0x%08X\n",
+		regs_buff[1097]);
+
+	fprintf(stdout,
+		"0x07F18: TIC_DW2     (Tx Desc Hand. Mem Read Data 2)  0x%08X\n",
+		regs_buff[1098]);
+
+	fprintf(stdout,
+		"0x07F1C: TIC_DW3     (Tx Desc Hand. Mem Read Data 3)  0x%08X\n",
+		regs_buff[1099]);
+
+	fprintf(stdout,
+		"0x07F20: TDPROBE     (Tx Probe Mode Status)           0x%08X\n",
+		regs_buff[1100]);
+
+	fprintf(stdout,
+		"0x0C600: TXBUFCTRL   (TX Buffer Access Control)       0x%08X\n",
+		regs_buff[1101]);
+
+	fprintf(stdout,
+		"0x0C610: TXBUFDATA0  (TX Buffer DATA 0)               0x%08X\n",
+		regs_buff[1102]);
+
+	fprintf(stdout,
+		"0x0C614: TXBUFDATA1  (TX Buffer DATA 1)               0x%08X\n",
+		regs_buff[1103]);
+
+	fprintf(stdout,
+		"0x0C618: TXBUFDATA2  (TX Buffer DATA 2)               0x%08X\n",
+		regs_buff[1104]);
+
+	fprintf(stdout,
+		"0x0C61C: TXBUFDATA3  (TX Buffer DATA 3)               0x%08X\n",
+		regs_buff[1105]);
+
+	fprintf(stdout,
+		"0x03600: RXBUFCTRL   (RX Buffer Access Control)       0x%08X\n",
+		regs_buff[1106]);
+
+	fprintf(stdout,
+		"0x03610: RXBUFDATA0  (RX Buffer DATA 0)               0x%08X\n",
+		regs_buff[1107]);
+
+	fprintf(stdout,
+		"0x03614: RXBUFDATA1  (RX Buffer DATA 1)               0x%08X\n",
+		regs_buff[1108]);
+
+	fprintf(stdout,
+		"0x03618: RXBUFDATA2  (RX Buffer DATA 2)               0x%08X\n",
+		regs_buff[1109]);
+
+	fprintf(stdout,
+		"0x0361C: RXBUFDATA3  (RX Buffer DATA 3)               0x%08X\n",
+		regs_buff[1110]);
+
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x%05X: PCIE_DIAG%d  (PCIe Diagnostic %d)              0x%08X\n",
+		0x11090 + (4 * i), i, i, regs_buff[1111 + i]);
+
+	fprintf(stdout,
+		"0x050A4: RFVAL       (Receive Filter Validation)      0x%08X\n",
+		regs_buff[1119]);
+
+	fprintf(stdout,
+		"0x042B8: MDFTC1      (MAC DFT Control 1)              0x%08X\n",
+		regs_buff[1120]);
+
+	fprintf(stdout,
+		"0x042C0: MDFTC2      (MAC DFT Control 2)              0x%08X\n",
+		regs_buff[1121]);
+
+	fprintf(stdout,
+		"0x042C4: MDFTFIFO1   (MAC DFT FIFO 1)                 0x%08X\n",
+		regs_buff[1122]);
+
+	fprintf(stdout,
+		"0x042C8: MDFTFIFO2   (MAC DFT FIFO 2)                 0x%08X\n",
+		regs_buff[1123]);
+
+	fprintf(stdout,
+		"0x042CC: MDFTS       (MAC DFT Status)                 0x%08X\n",
+		regs_buff[1124]);
+
+	fprintf(stdout,
+		"0x1106C: PCIEECCCTL  (PCIe ECC Control)               0x%08X\n",
+		regs_buff[1125]);
+
+	fprintf(stdout,
+		"0x0C300: PBTXECC     (Packet Buffer Tx ECC)           0x%08X\n",
+		regs_buff[1126]);
+
+	fprintf(stdout,
+		"0x03300: PBRXECC     (Packet Buffer Rx ECC)           0x%08X\n",
+		regs_buff[1127]);
+
+	return 0;
+}

^ permalink raw reply related

* [PATCH 1/2] ethtool: add register dump support for intel 82575 chipsets (igb driver)
From: Auke Kok @ 2007-08-15 17:44 UTC (permalink / raw)
  To: jeff; +Cc: davem, netdev, nicholas.d.nunley, auke-jan.h.kok

From: Nicholas Nunley <nicholas.d.nunley@intel.com>

Signed-off-by: Nicholas Nunley <nicholas.d.nunley@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---

 Makefile.am    |    2 
 ethtool-util.h |    2 
 ethtool.c      |    1 
 igb.c          |  864 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 868 insertions(+), 1 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 9f4bbd3..7bb58d8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,7 +5,7 @@ EXTRA_DIST = ethtool.8 ethtool.spec.in aclocal.m4 ChangeLog autogen.sh
 
 sbin_PROGRAMS = ethtool
 ethtool_SOURCES = ethtool.c ethtool-copy.h ethtool-util.h	\
-		  amd8111e.c de2104x.c e100.c e1000.c		\
+		  amd8111e.c de2104x.c e100.c e1000.c igb.c	\
 		  fec_8xx.c ibm_emac.c ixgb.c natsemi.c		\
 		  pcnet32.c realtek.c tg3.c marvell.c vioc.c	\
 		  smsc911x.c
diff --git a/ethtool-util.h b/ethtool-util.h
index f429555..1621dfe 100644
--- a/ethtool-util.h
+++ b/ethtool-util.h
@@ -30,6 +30,8 @@ int de2104x_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
 /* Intel(R) PRO/1000 Gigabit Adapter Family */
 int e1000_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
 
+int igb_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
+
 /* RealTek PCI */
 int realtek_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
 
diff --git a/ethtool.c b/ethtool.c
index b04f747..29562a7 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1003,6 +1003,7 @@ static struct {
 	{ "r8169", realtek_dump_regs },
 	{ "de2104x", de2104x_dump_regs },
 	{ "e1000", e1000_dump_regs },
+	{ "igb", igb_dump_regs },
 	{ "ixgb", ixgb_dump_regs },
 	{ "natsemi", natsemi_dump_regs },
 	{ "e100", e100_dump_regs },
diff --git a/igb.c b/igb.c
new file mode 100644
index 0000000..fadc22e
--- /dev/null
+++ b/igb.c
@@ -0,0 +1,864 @@
+/* Copyright (c) 2007 Intel Corporation */
+#include <stdio.h>
+#include "ethtool-util.h"
+
+/* Register Bit Masks */
+/* Device Control */
+#define E1000_CTRL_FD         0x00000001  /* Full duplex.0=half; 1=full */
+#define E1000_CTRL_PRIOR      0x00000004  /* Priority on PCI. 0=rx,1=fair */
+#define E1000_CTRL_GIOMASTERD 0x00000008  /* GIO Master Disable*/
+#define E1000_CTRL_TME        0x00000010  /* Test mode. 0=normal,1=test */
+#define E1000_CTRL_SLE        0x00000020  /* Serial Link on 0=dis,1=en */
+#define E1000_CTRL_ASDE       0x00000020  /* Auto-speed detect enable */
+#define E1000_CTRL_SLU        0x00000040  /* Set link up (Force Link) */
+#define E1000_CTRL_ILOS       0x00000080  /* Invert Loss-Of Signal */
+#define E1000_CTRL_SPD_SEL    0x00000300  /* Speed Select Mask */
+#define E1000_CTRL_SPD_10     0x00000000  /* Force 10Mb */
+#define E1000_CTRL_SPD_100    0x00000100  /* Force 100Mb */
+#define E1000_CTRL_SPD_1000   0x00000200  /* Force 1Gb */
+#define E1000_CTRL_FRCSPD     0x00000800  /* Force Speed */
+#define E1000_CTRL_FRCDPX     0x00001000  /* Force Duplex */
+#define E1000_CTRL_SDP0_GPIEN 0x00010000  /* General Purpose Interrupt Detection Enable for SDP0 */
+#define E1000_CTRL_SDP1_GPIEN 0x00020000  /* General Purpose Interrupt Detection Enable for SDP1 */
+#define E1000_CTRL_SDP0_DATA  0x00040000  /* SDP0 Data */
+#define E1000_CTRL_SDP1_DATA  0x00080000  /* SDP1 Data */
+#define E1000_CTRL_ADVD3WUC   0x00100000  /* D3Cold WakeUp Capability Advertisement Enable */
+#define E1000_CTRL_SDP0_WDE   0x00200000  /* Watchdog Indication for SDP0 */
+#define E1000_CTRL_SDP1_IODIR 0x00400000  /* SDP1 Directionality */
+#define E1000_CTRL_RST        0x04000000  /* Global reset */
+#define E1000_CTRL_RFCE       0x08000000  /* Receive Flow Control enable */
+#define E1000_CTRL_TFCE       0x10000000  /* Transmit flow control enable */
+#define E1000_CTRL_VME        0x40000000  /* IEEE VLAN mode enable */
+#define E1000_CTRL_PHY_RST    0x80000000  /* PHY Reset */
+
+/* Device Status */
+#define E1000_STATUS_FD          0x00000001      /* Full duplex.0=half,1=full */
+#define E1000_STATUS_LU          0x00000002      /* Link up.0=no,1=link */
+#define E1000_STATUS_LANID       0x00000008      /* LAN ID */
+#define E1000_STATUS_TXOFF       0x00000010      /* transmission paused */
+#define E1000_STATUS_TBIMODE     0x00000020      /* TBI mode */
+#define E1000_STATUS_SPEED_MASK  0x000000C0      /* Speed Mask */
+#define E1000_STATUS_SPEED_10    0x00000000      /* Speed 10Mb/s */
+#define E1000_STATUS_SPEED_100   0x00000040      /* Speed 100Mb/s */
+#define E1000_STATUS_SPEED_1000  0x00000080      /* Speed 1000Mb/s */
+#define E1000_STATUS_ASDV        0x00000300      /* Auto speed detect value */
+#define E1000_STATUS_PHYRA       0x00000400      /* PHY Reset Asserted */
+#define E1000_STATUS_GIOMASTEREN 0x00080000      /* GIO Master Enable Status */
+#define E1000_STATUS_DMA_CGEN    0x80000000      /* DMA clock gating Enable */
+
+/* Receive Control */
+#define E1000_RCTL_EN           0x00000002      /* enable */
+#define E1000_RCTL_SBP          0x00000004      /* store bad packet */
+#define E1000_RCTL_UPE          0x00000008      /* unicast promiscuous enable */
+#define E1000_RCTL_MPE          0x00000010      /* multicast promiscuous enab */
+#define E1000_RCTL_LPE          0x00000020      /* long packet enable */
+#define E1000_RCTL_LBM_MASK     0x000000C0      /* Loopback mode mask */
+#define E1000_RCTL_LBM_NORM     0x00000000      /* normal loopback mode */
+#define E1000_RCTL_LBM_MAC      0x00000040      /* MAC loopback mode */
+#define E1000_RCTL_LBM_SERDES   0x000000C0      /* SERDES loopback mode */
+#define E1000_RCTL_RDMTS        0x00000300      /* rx desc min threshold size */
+#define E1000_RCTL_RDMTS_HALF   0x00000000      /* rx desc min threshold size */
+#define E1000_RCTL_RDMTS_QUAT   0x00000100      /* rx desc min threshold size */
+#define E1000_RCTL_RDMTS_EIGTH  0x00000200      /* rx desc min threshold size */
+#define E1000_RCTL_MO           0x00003000      /* multicast offset shift */
+#define E1000_RCTL_MO_0         0x00000000      /* multicast offset 47:36 */
+#define E1000_RCTL_MO_1         0x00001000      /* multicast offset 46:35 */
+#define E1000_RCTL_MO_2         0x00002000      /* multicast offset 45:34 */
+#define E1000_RCTL_MO_3         0x00003000      /* multicast offset 43:32 */
+#define E1000_RCTL_BAM          0x00008000      /* broadcast enable */
+#define E1000_RCTL_BSIZE        0x00030000      /* rx buffer size */
+#define E1000_RCTL_BSIZE_2048   0x00000000      /* rx buffer size 2048 */
+#define E1000_RCTL_BSIZE_1024   0x00010000      /* rx buffer size 1024 */
+#define E1000_RCTL_BSIZE_512    0x00020000      /* rx buffer size 512 */
+#define E1000_RCTL_BSIZE_256    0x00030000      /* rx buffer size 256 */
+#define E1000_RCTL_VFE          0x00040000      /* vlan filter enable */
+#define E1000_RCTL_CFIEN        0x00080000      /* canonical form enable */
+#define E1000_RCTL_CFI          0x00100000      /* canonical form indicator */
+#define E1000_RCTL_DPF          0x00400000      /* discard pause frames */
+#define E1000_RCTL_PMCF         0x00800000      /* pass MAC control frames */
+#define E1000_RCTL_SECRC        0x04000000      /* Strip Ethernet CRC from packet.0=No strip;1=strip */
+
+/* Transmit Control */
+#define E1000_TCTL_EN     0x00000002    /* enable tx */
+#define E1000_TCTL_PSP    0x00000008    /* pad short packets */
+#define E1000_TCTL_CT     0x00000ff0    /* collision threshold */
+#define E1000_TCTL_BST    0x003ff000    /* Backoff Slot time */
+#define E1000_TCTL_SWXOFF 0x00400000    /* SW Xoff transmission */
+#define E1000_TCTL_PBE    0x00800000    /* Packet Burst Enable */
+#define E1000_TCTL_RTLC   0x01000000    /* Re-transmit on late collision */
+#define E1000_TCTL_NRTU   0x02000000    /* No Re-transmit on underrun */
+
+int
+igb_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
+{
+	u32 *regs_buff = (u32 *)regs->data;
+	u32 reg;
+	u8 i;
+	u8 version = (u8)(regs->version >> 24);
+
+	if (version != 1)
+		return -1;
+
+	/* Device control register */
+	reg = regs_buff[0];
+	fprintf(stdout,
+		"0x00000: CTRL (Device control register)               0x%08X\n"
+		"       Invert Loss-Of-Signal:                         %s\n"
+		"       Receive flow control:                          %s\n"
+		"       Transmit flow control:                         %s\n"
+		"       VLAN mode:                                     %s\n"
+		"       Set link up:                                   %s\n"
+		"       D3COLD WakeUp capability advertisement:        %s\n",
+		reg,
+		reg & E1000_CTRL_ILOS     ? "yes"      : "no",
+		reg & E1000_CTRL_RFCE     ? "enabled"  : "disabled",
+		reg & E1000_CTRL_TFCE     ? "enabled"  : "disabled",
+		reg & E1000_CTRL_VME      ? "enabled"  : "disabled",
+		reg & E1000_CTRL_SLU      ? "1"        : "0",
+		reg & E1000_CTRL_ADVD3WUC ? "enabled"  : "disabled");
+	fprintf(stdout,
+		"       Auto speed detect:                             %s\n"
+		"       Speed select:                                  %s\n"
+		"       Force speed:                                   %s\n"
+		"       Force duplex:                                  %s\n",
+		reg & E1000_CTRL_ASDE   ? "enabled"  : "disabled",
+		(reg & E1000_CTRL_SPD_SEL) == E1000_CTRL_SPD_10   ? "10Mb/s"   :
+		(reg & E1000_CTRL_SPD_SEL) == E1000_CTRL_SPD_100  ? "100Mb/s"  :
+		(reg & E1000_CTRL_SPD_SEL) == E1000_CTRL_SPD_1000 ? "1000Mb/s" :
+		"not used",
+		reg & E1000_CTRL_FRCSPD ? "yes"      : "no",
+		reg & E1000_CTRL_FRCDPX ? "yes"      : "no");
+
+	/* Device status register */
+	reg = regs_buff[1];
+	fprintf(stdout,
+		"0x00008: STATUS (Device status register)              0x%08X\n"
+		"       Duplex:                                        %s\n"
+		"       Link up:                                       %s\n"
+		"       Transmission:                                  %s\n"
+		"       DMA clock gating:                              %s\n",
+		reg,
+		reg & E1000_STATUS_FD       ? "full"        : "half",
+		reg & E1000_STATUS_LU       ? "link config" : "no link config",
+		reg & E1000_STATUS_TXOFF    ? "paused"      : "on",
+		reg & E1000_STATUS_DMA_CGEN ? "enabled"     : "disabled");
+	fprintf(stdout,
+		"       TBI mode:                                      %s\n"
+		"       Link speed:                                    %s\n"
+		"       Bus type:                                      %s\n",
+		reg & E1000_STATUS_TBIMODE ? "enabled"     : "disabled",
+		(reg & E1000_STATUS_SPEED_MASK) == E1000_STATUS_SPEED_10   ?
+		"10Mb/s" :
+		(reg & E1000_STATUS_SPEED_MASK) == E1000_STATUS_SPEED_100  ?
+		"100Mb/s" :
+		(reg & E1000_STATUS_SPEED_MASK) == E1000_STATUS_SPEED_1000 ?
+		"1000Mb/s" : "not used",
+		"PCI Express");
+
+	/* Receive control register */
+	reg = regs_buff[32];
+	fprintf(stdout,
+		"0x00100: RCTL (Receive control register)              0x%08X\n"
+		"       Receiver:                                      %s\n"
+		"       Store bad packets:                             %s\n"
+		"       Unicast promiscuous:                           %s\n"
+		"       Multicast promiscuous:                         %s\n"
+		"       Long packet:                                   %s\n"
+		"       Descriptor minimum threshold size:             %s\n"
+		"       Broadcast accept mode:                         %s\n"
+		"       VLAN filter:                                   %s\n"
+		"       Cononical form indicator:                      %s\n"
+		"       Discard pause frames:                          %s\n"
+		"       Pass MAC control frames:                       %s\n"
+		"       Loopback mode:                                 %s\n",
+		reg,
+		reg & E1000_RCTL_EN      ? "enabled"  : "disabled",
+		reg & E1000_RCTL_SBP     ? "enabled"  : "disabled",
+		reg & E1000_RCTL_UPE     ? "enabled"  : "disabled",
+		reg & E1000_RCTL_MPE     ? "enabled"  : "disabled",
+		reg & E1000_RCTL_LPE     ? "enabled"  : "disabled",
+		(reg & E1000_RCTL_RDMTS) == E1000_RCTL_RDMTS_HALF  ? "1/2" :
+		(reg & E1000_RCTL_RDMTS) == E1000_RCTL_RDMTS_QUAT  ? "1/4" :
+		(reg & E1000_RCTL_RDMTS) == E1000_RCTL_RDMTS_EIGTH ? "1/8" :
+		"reserved",
+		reg & E1000_RCTL_BAM      ? "accept"   : "ignore",
+		reg & E1000_RCTL_VFE      ? "enabled"  : "disabled",
+		reg & E1000_RCTL_CFIEN    ? "enabled"  : "disabled",
+		reg & E1000_RCTL_DPF      ? "ignored"  : "filtered",
+		reg & E1000_RCTL_PMCF     ? "pass"     : "don't pass",
+		(reg & E1000_RCTL_LBM_MASK) == E1000_RCTL_LBM_NORM   ? "normal" :
+		(reg & E1000_RCTL_LBM_MASK) == E1000_RCTL_LBM_MAC    ? "MAC":
+		(reg & E1000_RCTL_LBM_MASK) == E1000_RCTL_LBM_SERDES ? "SERDES":
+		"undefined");
+	fprintf(stdout,
+		"       Receive buffer size:                           %s\n",
+		(reg & E1000_RCTL_BSIZE)==E1000_RCTL_BSIZE_2048  ? "2048"  :
+		(reg & E1000_RCTL_BSIZE)==E1000_RCTL_BSIZE_1024  ? "1024"  :
+		(reg & E1000_RCTL_BSIZE)==E1000_RCTL_BSIZE_512   ? "512"   :
+		"256");
+
+	/* Receive descriptor registers */
+	fprintf(stdout,
+		"0x02808: RDLEN  (Receive desc length)                 0x%08X\n",
+		regs_buff[142]);
+	fprintf(stdout,
+		"0x02810: RDH    (Receive desc head)                   0x%08X\n",
+		regs_buff[146]);
+	fprintf(stdout,
+		"0x02818: RDT    (Receive desc tail)                   0x%08X\n",
+		regs_buff[150]);
+
+	/* Transmit control register */
+	reg = regs_buff[38];
+	fprintf(stdout,
+		"0x00400: TCTL (Transmit ctrl register)                0x%08X\n"
+		"       Transmitter:                                   %s\n"
+		"       Pad short packets:                             %s\n"
+		"       Software XOFF Transmission:                    %s\n",
+		reg,
+		reg & E1000_TCTL_EN      ? "enabled"  : "disabled",
+		reg & E1000_TCTL_PSP     ? "enabled"  : "disabled",
+		reg & E1000_TCTL_SWXOFF  ? "enabled"  : "disabled");
+	fprintf(stdout,
+		"       Re-transmit on late collision:                 %s\n",
+		reg & E1000_TCTL_RTLC    ? "enabled"  : "disabled");
+
+	/* Transmit descriptor registers */
+	fprintf(stdout,
+		"0x03808: TDLEN       (Transmit desc length)           0x%08X\n",
+		regs_buff[214]);
+	fprintf(stdout,
+		"0x03810: TDH         (Transmit desc head)             0x%08X\n",
+		regs_buff[218]);
+	fprintf(stdout,
+		"0x03818: TDT         (Transmit desc tail)             0x%08X\n",
+		regs_buff[222]);
+
+
+	fprintf(stdout,
+		"0x00018: CTRL_EXT    (Extended device control)        0x%08X\n",
+		regs_buff[2]);
+
+	fprintf(stdout,
+		"0x00018: MDIC        (MDI control)                    0x%08X\n",
+		regs_buff[3]);
+
+	fprintf(stdout,
+		"0x00024: SCTL        (SERDES ANA)                     0x%08X\n",
+		regs_buff[4]);
+
+	fprintf(stdout,
+		"0x00034: CONNSW      (Copper/Fiber switch control)    0x%08X\n",
+		regs_buff[5]);
+
+	fprintf(stdout,
+		"0x00038: VET         (VLAN Ether type)                0x%08X\n",
+		regs_buff[6]);
+	
+	fprintf(stdout,
+		"0x00E00: LEDCTL      (LED control)                    0x%08X\n",
+		regs_buff[7]);
+
+	fprintf(stdout,
+		"0x01000: PBA         (Packet buffer allocation)       0x%08X\n",
+		regs_buff[8]);
+	
+	fprintf(stdout,
+		"0x01008: PBS         (Packet buffer size)             0x%08X\n",
+		regs_buff[9]);
+	
+	fprintf(stdout,
+		"0x01048: FRTIMER     (Free running timer)             0x%08X\n",
+		regs_buff[10]);
+
+	fprintf(stdout,
+		"0x0104C: TCPTIMER    (TCP timer)                      0x%08X\n",
+		regs_buff[11]);
+
+	fprintf(stdout,
+		"0x00010: EEC         (EEPROM/FLASH control)           0x%08X\n",
+		regs_buff[12]);
+
+	fprintf(stdout,
+		"0x01580: EICR        (Extended interrupt cause)       0x%08X\n",
+		regs_buff[13]);
+
+	fprintf(stdout,
+		"0x01520: EICS        (Extended interrupt cause set)   0x%08X\n",
+		regs_buff[14]);
+	
+	fprintf(stdout,
+		"0x01524: EIMS        (Extended interrup set/read)     0x%08X\n",
+		regs_buff[15]);
+	
+	fprintf(stdout,
+		"0x01528: EIMC        (Extended interrupt mask clear)  0x%08X\n",
+		regs_buff[16]);
+	
+	fprintf(stdout,
+		"0x0152C: EIAC        (Extended interrupt auto clear)  0x%08X\n",
+		regs_buff[17]);
+	
+	fprintf(stdout,
+		"0x01530: EIAM        (Extended interrupt auto mask)   0x%08X\n",
+		regs_buff[18]);
+	
+	fprintf(stdout,
+		"0x01500: ICR         (Interrupt cause read)           0x%08X\n",
+		regs_buff[19]);
+	
+	fprintf(stdout,
+		"0x01504: ICS         (Interrupt cause set)            0x%08X\n",
+		regs_buff[20]);
+	
+	fprintf(stdout,
+		"0x01508: IMS         (Interrupt mask set/read)        0x%08X\n",
+		regs_buff[21]);
+	
+	fprintf(stdout,
+		"0x0150C: IMC         (Interrupt mask clear)           0x%08X\n",
+		regs_buff[22]);
+	
+	fprintf(stdout,
+		"0x04100: IAC         (Interrupt assertion count)      0x%08X\n",
+		regs_buff[23]);
+	
+	fprintf(stdout,
+		"0x01510: IAM         (Interr acknowledge auto-mask)   0x%08X\n",
+		regs_buff[24]);
+	
+	fprintf(stdout,
+		"0x05AC0: IMIRVP      (Immed interr rx VLAN priority)  0x%08X\n",
+		regs_buff[25]);
+	
+	fprintf(stdout,
+		"0x00028: FCAL        (Flow control address low)       0x%08X\n",
+		regs_buff[26]);
+
+	fprintf(stdout,
+		"0x0002C: FCAH        (Flow control address high)      0x%08X\n",
+		regs_buff[27]);
+
+	fprintf(stdout,
+		"0x00170: FCTTV       (Flow control tx timer value)    0x%08X\n",
+		regs_buff[28]);
+
+	fprintf(stdout,
+		"0x02160: FCRTL       (Flow control rx threshold low)  0x%08X\n",
+		regs_buff[29]);
+
+	fprintf(stdout,
+		"0x02168: FCRTH       (Flow control rx threshold high) 0x%08X\n",
+		regs_buff[30]);
+
+	fprintf(stdout,
+		"0x02460: FCRTV       (Flow control refresh threshold) 0x%08X\n",
+		regs_buff[31]);
+
+	fprintf(stdout,
+		"0x05000: RXCSUM      (Receive checksum control)       0x%08X\n",
+		regs_buff[33]);
+
+	fprintf(stdout,
+		"0x05004: RLPML       (Receive long packet max length) 0x%08X\n",
+		regs_buff[34]);
+
+	fprintf(stdout,
+		"0x05008: RFCTL       (Receive filter control)         0x%08X\n",
+		regs_buff[35]);
+
+	fprintf(stdout,
+		"0x05818: MRQC        (Multiple rx queues command)     0x%08X\n",
+		regs_buff[36]);
+
+	fprintf(stdout,
+		"0x0581C: VMD_CTL     (VMDq control)                   0x%08X\n",
+		regs_buff[37]);
+
+	fprintf(stdout,
+		"0x00404: TCTL_EXT    (Transmit control extended)      0x%08X\n",
+		regs_buff[39]);
+
+	fprintf(stdout,
+		"0x00410: TIPG        (Transmit IPG)                   0x%08X\n",
+		regs_buff[40]);
+
+	fprintf(stdout,
+		"0x03590: DTXCTL      (DMA tx control)                 0x%08X\n",
+		regs_buff[41]);
+
+	fprintf(stdout,
+		"0x05800: WUC         (Wake up control)                0x%08X\n",
+		regs_buff[42]);
+
+	fprintf(stdout,
+		"0x05808: WUFC        (Wake up filter control)         0x%08X\n",
+		regs_buff[43]);
+
+	fprintf(stdout,
+		"0x05810: WUS         (Wake up status)                 0x%08X\n",
+		regs_buff[44]);
+
+	fprintf(stdout,
+		"0x05838: IPAV        (IP address valid)               0x%08X\n",
+		regs_buff[45]);
+
+	fprintf(stdout,
+		"0x05900: WUPL        (Wake up packet length)          0x%08X\n",
+		regs_buff[46]);
+
+	fprintf(stdout,
+		"0x04200: PCS_CFG     (PCS configuration 0)            0x%08X\n",
+		regs_buff[47]);
+
+	fprintf(stdout,
+		"0x04208: PCS_LCTL    (PCS link control)               0x%08X\n",
+		regs_buff[48]);
+
+	fprintf(stdout,
+		"0x0420C: PCS_LSTS    (PCS link status)                0x%08X\n",
+		regs_buff[49]);
+
+	fprintf(stdout,
+		"0x04218: PCS_ANADV   (AN advertisement)               0x%08X\n",
+		regs_buff[50]);
+
+	fprintf(stdout,
+		"0x0421C: PCS_LPAB    (Link partner ability)           0x%08X\n",
+		regs_buff[51]);
+
+	fprintf(stdout,
+		"0x04220: PCS_NPTX    (Next Page transmit)             0x%08X\n",
+		regs_buff[52]);
+
+	fprintf(stdout,
+		"0x04224: PCS_LPABNP  (Link partner ability Next Page) 0x%08X\n",
+		regs_buff[53]);
+
+	fprintf(stdout,
+		"0x04000: CRCERRS     (CRC error count)                0x%08X\n",
+		regs_buff[54]);
+
+	fprintf(stdout,
+		"0x04004: ALGNERRC    (Alignment error count)          0x%08X\n",
+		regs_buff[55]);
+
+	fprintf(stdout,
+		"0x04008: SYMERRS     (Symbol error count)             0x%08X\n",
+		regs_buff[56]);
+
+	fprintf(stdout,
+		"0x0400C: RXERRC      (RX error count)                 0x%08X\n",
+		regs_buff[57]);
+
+	fprintf(stdout,
+		"0x04010: MPC         (Missed packets count)           0x%08X\n",
+		regs_buff[58]);
+
+	fprintf(stdout,
+		"0x04014: SCC         (Single collision count)         0x%08X\n",
+		regs_buff[59]);
+
+	fprintf(stdout,
+		"0x04018: ECOL        (Excessive collisions count)     0x%08X\n",
+		regs_buff[60]);
+
+	fprintf(stdout,
+		"0x0401C: MCC         (Multiple collision count)       0x%08X\n",
+		regs_buff[61]);
+
+	fprintf(stdout,
+		"0x04020: LATECOL     (Late collisions count)          0x%08X\n",
+		regs_buff[62]);
+
+	fprintf(stdout,
+		"0x04028: COLC        (Collision count)                0x%08X\n",
+		regs_buff[63]);
+
+	fprintf(stdout,
+		"0x04030: DC          (Defer count)                    0x%08X\n",
+		regs_buff[64]);
+
+	fprintf(stdout,
+		"0x04034: TNCRS       (Transmit with no CRS)           0x%08X\n",
+		regs_buff[65]);
+
+	fprintf(stdout,
+		"0x04038: SEC         (Sequence error count)           0x%08X\n",
+		regs_buff[66]);
+
+	fprintf(stdout,
+		"0x0403C: HTDPMC      (Host tx discrd pkts MAC count)  0x%08X\n",
+		regs_buff[67]);
+
+	fprintf(stdout,
+		"0x04040: RLEC        (Receive length error count)     0x%08X\n",
+		regs_buff[68]);
+
+	fprintf(stdout,
+		"0x04048: XONRXC      (XON received count)             0x%08X\n",
+		regs_buff[69]);
+
+	fprintf(stdout,
+		"0x0404C: XONTXC      (XON transmitted count)          0x%08X\n",
+		regs_buff[70]);
+
+	fprintf(stdout,
+		"0x04050: XOFFRXC     (XOFF received count)            0x%08X\n",
+		regs_buff[71]);
+
+	fprintf(stdout,
+		"0x04054: XOFFTXC     (XOFF transmitted count)         0x%08X\n",
+		regs_buff[72]);
+
+	fprintf(stdout,
+		"0x04058: FCRUC       (FC received unsupported count)  0x%08X\n",
+		regs_buff[73]);
+
+	fprintf(stdout,
+		"0x0405C: PRC64       (Packets rx (64 B) count)        0x%08X\n",
+		regs_buff[74]);
+
+	fprintf(stdout,
+		"0x04060: PRC127      (Packets rx (65-127 B) count)    0x%08X\n",
+		regs_buff[75]);
+
+	fprintf(stdout,
+		"0x04064: PRC255      (Packets rx (128-255 B) count)   0x%08X\n",
+		regs_buff[76]);
+
+	fprintf(stdout,
+		"0x04068: PRC511      (Packets rx (256-511 B) count)   0x%08X\n",
+		regs_buff[77]);
+
+	fprintf(stdout,
+		"0x0406C: PRC1023     (Packets rx (512-1023 B) count)  0x%08X\n",
+		regs_buff[78]);
+
+	fprintf(stdout,
+		"0x04070: PRC1522     (Packets rx (1024-max B) count)  0x%08X\n",
+		regs_buff[79]);
+
+	fprintf(stdout,
+		"0x04074: GPRC        (Good packets received count)    0x%08X\n",
+		regs_buff[80]);
+
+	fprintf(stdout,
+		"0x04078: BPRC        (Broadcast packets rx count)     0x%08X\n",
+		regs_buff[81]);
+
+	fprintf(stdout,
+		"0x0407C: MPRC        (Multicast packets rx count)     0x%08X\n",
+		regs_buff[82]);
+
+	fprintf(stdout,
+		"0x04080: GPTC        (Good packets tx count)          0x%08X\n",
+		regs_buff[83]);
+
+	fprintf(stdout,
+		"0x04088: GORCL       (Good octets rx count lower)     0x%08X\n",
+		regs_buff[84]);
+
+	fprintf(stdout,
+		"0x0408C: GORCH       (Good octets rx count upper)     0x%08X\n",
+		regs_buff[85]);
+	
+	fprintf(stdout,
+		"0x04090: GOTCL       (Good octets tx count lower)     0x%08X\n",
+		regs_buff[86]);
+
+	fprintf(stdout,
+		"0x04094: GOTCH       (Good octets tx count upper)     0x%08X\n",
+		regs_buff[87]);
+
+	fprintf(stdout,
+		"0x040A0: RNBC        (Receive no buffers count)       0x%08X\n",
+		regs_buff[88]);
+
+	fprintf(stdout,
+		"0x040A4: RUC         (Receive undersize count)        0x%08X\n",
+		regs_buff[89]);
+
+	fprintf(stdout,
+		"0x040A8: RFC         (Receive fragment count)         0x%08X\n",
+		regs_buff[90]);
+
+	fprintf(stdout,
+		"0x040AC: ROC         (Receive oversize count)         0x%08X\n",
+		regs_buff[91]);
+
+	fprintf(stdout,
+		"0x040B0: RJC         (Receive jabber count)           0x%08X\n",
+		regs_buff[92]);
+
+	fprintf(stdout,
+		"0x040B4: MGPRC       (Management packets rx count)    0x%08X\n",
+		regs_buff[93]);
+
+	fprintf(stdout,
+		"0x040B8: MGPDC       (Management pkts dropped count)  0x%08X\n",
+		regs_buff[94]);
+
+	fprintf(stdout,
+		"0x040BC: MGPTC       (Management packets tx count)    0x%08X\n",
+		regs_buff[95]);
+
+	fprintf(stdout,
+		"0x040C0: TORL        (Total octets received lower)    0x%08X\n",
+		regs_buff[96]);
+
+	fprintf(stdout,
+		"0x040C4: TORH        (Total octets received upper)    0x%08X\n",
+		regs_buff[97]);
+
+	fprintf(stdout,
+		"0x040C8: TOTL        (Total octets transmitted lower) 0x%08X\n",
+		regs_buff[98]);
+
+	fprintf(stdout,
+		"0x040CC: TOTH        (Total octets transmitted upper) 0x%08X\n",
+		regs_buff[99]);
+
+	fprintf(stdout,
+		"0x040D0: TPR         (Total packets received)         0x%08X\n",
+		regs_buff[100]);
+
+	fprintf(stdout,
+		"0x040D4: TPT         (Total packets transmitted)      0x%08X\n",
+		regs_buff[101]);
+
+	fprintf(stdout,
+		"0x040D8: PTC64       (Packets tx (64 B) count)        0x%08X\n",
+		regs_buff[102]);
+
+	fprintf(stdout,
+		"0x040DC: PTC127      (Packets tx (65-127 B) count)    0x%08X\n",
+		regs_buff[103]);
+
+	fprintf(stdout,
+		"0x040E0: PTC255      (Packets tx (128-255 B) count)   0x%08X\n",
+		regs_buff[104]);
+
+	fprintf(stdout,
+		"0x040E4: PTC511      (Packets tx (256-511 B) count)   0x%08X\n",
+		regs_buff[105]);
+	
+	fprintf(stdout,
+		"0x040E8: PTC1023     (Packets tx (512-1023 B) count)  0x%08X\n",
+		regs_buff[106]);
+	
+	fprintf(stdout,
+		"0x040EC: PTC1522     (Packets tx (> 1024 B) count)    0x%08X\n",
+		regs_buff[107]);
+	
+	fprintf(stdout,
+		"0x040F0: MPTC        (Multicast packets tx count)     0x%08X\n",
+		regs_buff[108]);
+	
+	fprintf(stdout,
+		"0x040F4: BPTC        (Broadcast packets tx count)     0x%08X\n",
+		regs_buff[109]);
+	
+	fprintf(stdout,
+		"0x040F8: TSCTC       (TCP segment context tx count)   0x%08X\n",
+		regs_buff[110]);
+	
+	fprintf(stdout,
+		"0x04100: IAC         (Interrupt assertion count)      0x%08X\n",
+		regs_buff[111]);
+	
+	fprintf(stdout,
+		"0x04104: RPTHC       (Rx packets to host count)       0x%08X\n",
+		regs_buff[112]);
+	
+	fprintf(stdout,
+		"0x04118: HGPTC       (Host good packets tx count)     0x%08X\n",
+		regs_buff[113]);
+	
+	fprintf(stdout,
+		"0x04128: HGORCL      (Host good octets rx cnt lower)  0x%08X\n",
+		regs_buff[114]);
+	
+	fprintf(stdout,
+		"0x0412C: HGORCH      (Host good octets rx cnt upper)  0x%08X\n",
+		regs_buff[115]);
+	
+	fprintf(stdout,
+		"0x04130: HGOTCL      (Host good octets tx cnt lower)  0x%08X\n",
+		regs_buff[116]);
+	
+	fprintf(stdout,
+		"0x04134: HGOTCH      (Host good octets tx cnt upper)  0x%08X\n",
+		regs_buff[117]);
+	
+	fprintf(stdout,
+		"0x04138: LENNERS     (Length error count)             0x%08X\n",
+		regs_buff[118]);
+	
+	fprintf(stdout,
+		"0x04228: SCVPC       (SerDes/SGMII code viol pkt cnt) 0x%08X\n",
+		regs_buff[119]);
+	
+	fprintf(stdout,
+		"0x0A018: HRMPC       (Header redir missed pkt count)  0x%08X\n",
+		regs_buff[120]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: SRRCTL%d     (Split and replic rx ctl%d)       0x%08X\n",
+		0x0280C + (0x100 * i), i, i, regs_buff[121 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: PSRTYPE%d    (Packet split receive type%d)     0x%08X\n",
+		0x05480 + (0x4 * i), i, i, regs_buff[125 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: RDBAL%d      (Rx desc base addr low%d)         0x%08X\n",
+		0x02800 + (0x100 * i), i, i, regs_buff[129 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: RDBAH%d      (Rx desc base addr high%d)        0x%08X\n",
+		0x02804 + (0x100 * i), i, i, regs_buff[133 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: RDLEN%d      (Rx descriptor length%d)          0x%08X\n",
+		0x02808 + (0x100 * i), i, i, regs_buff[137 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: RDH%d        (Rx descriptor head%d)            0x%08X\n",
+		0x02810 + (0x100 * i), i, i, regs_buff[141 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: RDT%d        (Rx descriptor tail%d)            0x%08X\n",
+		0x02818 + (0x100 * i), i, i, regs_buff[145 + i]);
+
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: RXDCTL%d     (Rx descriptor control%d)         0x%08X\n",
+		0x02828 + (0x100 * i), i, i, regs_buff[149 + i]);
+	
+	for (i = 0; i < 10; i++)
+		fprintf(stdout,
+		"0x0%02X: EITR%d       (Interrupt throttle%d)            0x%08X\n",
+		0x01680 + (0x4 * i), i, i, regs_buff[153 + i]);
+	
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x0%02X: IMIR%d       (Immediate interrupt Rx%d)        0x%08X\n",
+		0x05A80 + (0x4 * i), i, i, regs_buff[163 + i]);
+	
+	for (i = 0; i < 8; i++)
+		fprintf(stdout,
+		"0x0%02X: IMIREXT%d    (Immediate interr Rx extended%d)  0x%08X\n",
+		0x05AA0 + (0x4 * i), i, i, regs_buff[171 + i]);
+	
+	for (i = 0; i < 16; i++)
+		fprintf(stdout,
+		"0x0%02X: RAL%02d       (Receive address low%02d)          0x%08X\n",
+		0x05400 + (0x8 * i), i,i, regs_buff[179 + i]);
+	
+	for (i = 0; i < 16; i++)
+		fprintf(stdout,
+		"0x0%02X: RAH%02d       (Receive address high%02d)         0x%08X\n",
+		0x05404 + (0x8 * i), i, i, regs_buff[195 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: TDBAL%d      (Tx desc base address low%d)      0x%08X\n",
+		0x03800 + (0x100 * i), i, i, regs_buff[211 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: TDBAH%d      (Tx desc base address high%d)     0x%08X\n",
+		0x03804 + (0x100 * i), i, i, regs_buff[215 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: TDLEN%d      (Tx descriptor length%d)          0x%08X\n",
+		0x03808 + (0x100 * i), i, i, regs_buff[219 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: TDH%d        (Transmit descriptor head%d)      0x%08X\n",
+		0x03810 + (0x100 * i), i, i, regs_buff[223 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: TDT%d        (Transmit descriptor tail%d)      0x%08X\n",
+		0x03818 + (0x100 * i), i, i, regs_buff[227 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: TXDCTL%d     (Transmit descriptor control%d)   0x%08X\n",
+		0x03828 + (0x100 * i), i, i, regs_buff[231 + i]);
+
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: TDWBAL%d     (Tx desc complete wb addr low%d)  0x%08X\n",
+		0x03838 + (0x100 * i), i, i, regs_buff[235 + i]);
+
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: TDWBAH%d     (Tx desc complete wb addr hi%d)   0x%08X\n",
+		0x0383C + (0x100 * i), i, i, regs_buff[239 + i]);
+
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: DCA_TXCTRL%d (Tx DCA control%d)                0x%08X\n",
+		0x03814 + (0x100 * i), i, i, regs_buff[243 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: IP4AT%d      (IPv4 address table%d)            0x%08X\n",
+		0x05840 + (0x8 * i), i, i, regs_buff[247 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: IP6AT%d      (IPv6 address table%d)            0x%08X\n",
+		0x05880 + (0x4 * i), i, i, regs_buff[251 + i]);
+	
+	for (i = 0; i < 32; i++)
+		fprintf(stdout,
+		"0x0%02X: WUPM%02d      (Wake up packet memory%02d)        0x%08X\n",
+		0x05A00 + (0x4 * i), i, i, regs_buff[255 + i]);
+	
+	for (i = 0; i < 128; i++)
+		fprintf(stdout,
+		"0x0%02X: FFMT%03d     (Flexible filter mask table%03d)  0x%08X\n",
+		0x09000 + (0x8 * i), i, i, regs_buff[287 + i]);
+	
+	for (i = 0; i < 128; i++)
+		fprintf(stdout,
+		"0x0%02X: FFVT%03d     (Flexible filter value table%03d) 0x%08X\n",
+		0x09800 + (0x8 * i), i, i, regs_buff[415 + i]);
+	
+	for (i = 0; i < 4; i++)
+		fprintf(stdout,
+		"0x0%02X: FFLT%d       (Flexible filter length table%d)  0x%08X\n",
+		0x05F00 + (0x8 * i), i, i, regs_buff[543 + i]);
+	
+	fprintf(stdout,
+		"0x03410: TDFH        (Tx data FIFO head)              0x%08X\n",
+		regs_buff[547]);
+	
+	fprintf(stdout,
+		"0x03418: TDFT        (Tx data FIFO tail)              0x%08X\n",
+		regs_buff[548]);
+	
+	fprintf(stdout,
+		"0x03420: TDFHS       (Tx data FIFO head saved)        0x%08X\n",
+		regs_buff[549]);
+	
+	fprintf(stdout,
+		"0x03430: TDFPC       (Tx data FIFO packet count)      0x%08X\n",
+		regs_buff[550]);
+
+	return 0;
+}
+

^ permalink raw reply related

* Re: [PATCH 0/24] make atomic_read() behave consistently across all architectures
From: Paul E. McKenney @ 2007-08-15 17:33 UTC (permalink / raw)
  To: Satyam Sharma
  Cc: Herbert Xu, Stefan Richter, Christoph Lameter, Chris Snook,
	Linux Kernel Mailing List, linux-arch, Linus Torvalds, netdev,
	Andrew Morton, ak, heiko.carstens, davem, schwidefsky, wensong,
	horms, wjiang, cfriesen, zlynx, rpjday, jesper.juhl, segher
In-Reply-To: <alpine.LFD.0.999.0708152244310.16414@enigma.security.iitk.ac.in>

On Wed, Aug 15, 2007 at 10:48:28PM +0530, Satyam Sharma wrote:
> On Wed, 15 Aug 2007, Paul E. McKenney wrote:
> > On Wed, Aug 15, 2007 at 11:33:36PM +0800, Herbert Xu wrote:
> > > On Wed, Aug 15, 2007 at 07:25:16AM -0700, Paul E. McKenney wrote:
> > > > 
> > > > Do we really need another set of APIs?  Can you give even one example
> > > > where the pre-existing volatile semantics are causing enough of a problem
> > > > to justify adding yet more atomic_*() APIs?
> > > 
> > > Let's turn this around.  Can you give a single example where
> > > the volatile semantics is needed in a legitimate way?
> > 
> > Sorry, but you are the one advocating for the change.
> 
> Not for i386 and x86_64 -- those have atomic ops without any "volatile"
> semantics (currently as per existing definitions).

I claim unit volumes with arm, and the majority of the architectures, but
I cannot deny the popularity of i386 and x86_64 with many developers.  ;-)

However, I am not aware of code in the kernel that would benefit
from the compiler coalescing multiple atomic_set() and atomic_read()
invocations, thus I don't see the downside to volatility in this case.
Are there some performance-critical code fragments that I am missing?

						Thanx, Paul

^ permalink raw reply

* Re: [PATCH 0/24] make atomic_read() behave consistently across all architectures
From: Satyam Sharma @ 2007-08-15 17:18 UTC (permalink / raw)
  To: Paul E. McKenney
  Cc: Herbert Xu, Stefan Richter, Christoph Lameter, Chris Snook,
	Linux Kernel Mailing List, linux-arch, Linus Torvalds, netdev,
	Andrew Morton, ak, heiko.carstens, davem, schwidefsky, wensong,
	horms, wjiang, cfriesen, zlynx, rpjday, jesper.juhl, segher
In-Reply-To: <20070815160830.GC9645@linux.vnet.ibm.com>



On Wed, 15 Aug 2007, Paul E. McKenney wrote:

> On Wed, Aug 15, 2007 at 11:33:36PM +0800, Herbert Xu wrote:
> > On Wed, Aug 15, 2007 at 07:25:16AM -0700, Paul E. McKenney wrote:
> > > 
> > > Do we really need another set of APIs?  Can you give even one example
> > > where the pre-existing volatile semantics are causing enough of a problem
> > > to justify adding yet more atomic_*() APIs?
> > 
> > Let's turn this around.  Can you give a single example where
> > the volatile semantics is needed in a legitimate way?
> 
> Sorry, but you are the one advocating for the change.

Not for i386 and x86_64 -- those have atomic ops without any "volatile"
semantics (currently as per existing definitions).

^ permalink raw reply

* Re: [PATCH 0/24] make atomic_read() behave consistently across all architectures
From: Satyam Sharma @ 2007-08-15 17:13 UTC (permalink / raw)
  To: Paul E. McKenney
  Cc: Stefan Richter, Herbert Xu, Heiko Carstens, Chris Snook, clameter,
	Linux Kernel Mailing List, linux-arch, Linus Torvalds, netdev,
	Andrew Morton, ak, davem, schwidefsky, wensong, horms, wjiang,
	cfriesen, zlynx, rpjday, jesper.juhl, segher
In-Reply-To: <20070815162722.GD9645@linux.vnet.ibm.com>



On Wed, 15 Aug 2007, Paul E. McKenney wrote:

> On Wed, Aug 15, 2007 at 06:09:35PM +0200, Stefan Richter wrote:
> > Herbert Xu wrote:
> > > On Wed, Aug 15, 2007 at 08:05:38PM +0530, Satyam Sharma wrote:
> > >>> I don't know if this here is affected:
> > 
> > [...something like]
> > 	b = atomic_read(a);
> > 	for (i = 0; i < 4; i++) {
> > 		msleep_interruptible(63);
> > 		c = atomic_read(a);
> > 		if (c != b) {
> > 			b = c;
> > 			i = 0;
> > 		}
> > 	}
> > 
> > > Nope, we're calling schedule which is a rather heavy-weight
> > > barrier.
> > 
> > How does the compiler know that msleep() has got barrier()s?
> 
> Because msleep_interruptible() is in a separate compilation unit,
> the compiler has to assume that it might modify any arbitrary global.
> In many cases, the compiler also has to assume that msleep_interruptible()
> might call back into a function in the current compilation unit, thus
> possibly modifying global static variables.

Yup, I've just verified this with a testcase. So a call to any function
outside of the current compilation unit acts as a compiler barrier. Cool.

^ permalink raw reply

* Re: [patch 08/18] 3c59x: check return of pci_enable_device()
From: Steffen Klassert @ 2007-08-15 16:30 UTC (permalink / raw)
  To: Mark Hindley; +Cc: Jeff Garzik, akpm, netdev
In-Reply-To: <20070814095432.GA13825@hindley.org.uk>

On Tue, Aug 14, 2007 at 10:54:32AM +0100, Mark Hindley wrote:
> On Tue, Aug 14, 2007 at 01:33:26AM -0400, Jeff Garzik wrote:
> > I would strongly prefer that vortex_up return a value, since all the 
> > important callers of this function can themselves return an error back 
> > to the system.
> > 
> > we can definitely return a meaningful return value here, if 
> > pci_enable_device() fails, and I would rather not apply a patch that 
> > fails to propagate a serious condition (pci_enable_device failure is 
> > indeed serious) when it is possible to do so
> > 
> 
> OK. Any comments on this revised version? I have only ignored the return of
> vortex_up in vortex_error. It is not immediately clear what to do if
> vortex_up still fails there after a pci reset.
> 
> Mark
> 
> 
> diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
> index 001c66d..a1dfd6b 100644
> --- a/drivers/net/3c59x.c
> +++ b/drivers/net/3c59x.c
> @@ -705,7 +705,7 @@ static struct {
>  
>  static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
>  				   int chip_idx, int card_idx);
> -static void vortex_up(struct net_device *dev);
> +static int vortex_up(struct net_device *dev);
>  static void vortex_down(struct net_device *dev, int final);
>  static int vortex_open(struct net_device *dev);
>  static void mdio_sync(void __iomem *ioaddr, int bits);
> @@ -841,8 +841,11 @@ static int vortex_resume(struct pci_dev *pdev)
>  			return -EBUSY;
>  		}
>  		if (netif_running(dev)) {
> -			vortex_up(dev);
> -			netif_device_attach(dev);
> +			err = vortex_up(dev);
> +			if (err)
> +				return err;
> +			else  
> +				netif_device_attach(dev);
>  		}
>  	}
>  	return 0;

I think we should free the requested irq if vortex_up really fails here.


Steffen

^ permalink raw reply

* Re: [PATCH 0/24] make atomic_read() behave consistently across all architectures
From: Paul E. McKenney @ 2007-08-15 16:27 UTC (permalink / raw)
  To: Stefan Richter
  Cc: Herbert Xu, Satyam Sharma, Heiko Carstens, Chris Snook, clameter,
	Linux Kernel Mailing List, linux-arch, Linus Torvalds, netdev,
	Andrew Morton, ak, davem, schwidefsky, wensong, horms, wjiang,
	cfriesen, zlynx, rpjday, jesper.juhl, segher
In-Reply-To: <46C3253F.5090707@s5r6.in-berlin.de>

On Wed, Aug 15, 2007 at 06:09:35PM +0200, Stefan Richter wrote:
> Herbert Xu wrote:
> > On Wed, Aug 15, 2007 at 08:05:38PM +0530, Satyam Sharma wrote:
> >>> I don't know if this here is affected:
> 
> [...something like]
> 	b = atomic_read(a);
> 	for (i = 0; i < 4; i++) {
> 		msleep_interruptible(63);
> 		c = atomic_read(a);
> 		if (c != b) {
> 			b = c;
> 			i = 0;
> 		}
> 	}
> 
> > Nope, we're calling schedule which is a rather heavy-weight
> > barrier.
> 
> How does the compiler know that msleep() has got barrier()s?

Because msleep_interruptible() is in a separate compilation unit,
the compiler has to assume that it might modify any arbitrary global.
In many cases, the compiler also has to assume that msleep_interruptible()
might call back into a function in the current compilation unit, thus
possibly modifying global static variables.

						Thanx, Paul

^ permalink raw reply

* Re: [PATCH] improved xfrm_audit_log() patch
From: Joy Latten @ 2007-08-15 16:16 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-audit, sgrubb

On Tue, 2007-08-07 at 18:32 -0700, David Miller wrote:
>From: Joy Latten <latten@austin.ibm.com>
>Date: Thu, 2 Aug 2007 15:56:47 -0500
>
>> @@ -426,10 +426,15 @@ struct xfrm_audit
>>  };
>>  
>>  #ifdef CONFIG_AUDITSYSCALL
>> -extern void xfrm_audit_log(uid_t auid, u32 secid, int type, int result,
>> -		    struct xfrm_policy *xp, struct xfrm_state *x);
>> +extern void xfrm_audit_log(struct xfrm_audit audit_info, int result,
>> +			   __be32 flowid, struct xfrm_policy *xp, 
>> +			   struct xfrm_state *x, char *buf);
>
>Passing audit_info as an aggregate argument puts them into
>previous argument registers, or if they are not enough it
>goes either partially of wholly onto the stack, depending
>upon architecture.
>
>In fact you've made the argument register usage worse than
>in your previous revision. :-/
>
>Perhaps you meant to pass "struct xfrm_audit *" instead?

Revised patch to pass pointer to struct xfrm_audit.
Sorry, I missed that.

Signed-off-by: Joy Latten <latten@austin.ibm.com>


diff -urpN linux-2.6.22/include/linux/audit.h linux-2.6.22.patch/include/linux/audit.h
--- linux-2.6.22/include/linux/audit.h	2007-08-14 18:13:53.000000000 -0500
+++ linux-2.6.22.patch/include/linux/audit.h	2007-08-14 19:08:42.000000000 -0500
@@ -112,6 +112,7 @@
 #define AUDIT_MAC_IPSEC_DELSA	1412	/* Delete a XFRM state */
 #define AUDIT_MAC_IPSEC_ADDSPD	1413	/* Add a XFRM policy */
 #define AUDIT_MAC_IPSEC_DELSPD	1414	/* Delete a XFRM policy */
+#define AUDIT_MAC_IPSEC_EVENT	1415	/* Audit IPSec events */
 
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG    1799
diff -urpN linux-2.6.22/include/net/xfrm.h linux-2.6.22.patch/include/net/xfrm.h
--- linux-2.6.22/include/net/xfrm.h	2007-08-14 18:13:53.000000000 -0500
+++ linux-2.6.22.patch/include/net/xfrm.h	2007-08-14 19:08:42.000000000 -0500
@@ -426,10 +426,15 @@ struct xfrm_audit
 };
 
 #ifdef CONFIG_AUDITSYSCALL
-extern void xfrm_audit_log(uid_t auid, u32 secid, int type, int result,
-		    struct xfrm_policy *xp, struct xfrm_state *x);
+extern void xfrm_audit_log(struct xfrm_audit *audit_info, int result,
+			   __be32 flowid, struct xfrm_policy *xp, 
+			   struct xfrm_state *x, char *buf);
+
+extern void xfrm_get_auditinfo(struct sk_buff *skb, 
+			       struct xfrm_audit *audit_info);
 #else
-#define xfrm_audit_log(a,s,t,r,p,x) do { ; } while (0)
+#define xfrm_audit_log(a,r,f,p,s,b) do { ; } while (0)
+#define xfrm_get_auditinfo(s, a) do { ; } while (0)
 #endif /* CONFIG_AUDITSYSCALL */
 
 static inline void xfrm_pol_hold(struct xfrm_policy *policy)
diff -urpN linux-2.6.22/net/key/af_key.c linux-2.6.22.patch/net/key/af_key.c
--- linux-2.6.22/net/key/af_key.c	2007-08-14 18:13:53.000000000 -0500
+++ linux-2.6.22.patch/net/key/af_key.c	2007-08-14 19:08:42.000000000 -0500
@@ -1450,6 +1450,7 @@ static int pfkey_add(struct sock *sk, st
 	struct xfrm_state *x;
 	int err;
 	struct km_event c;
+	struct xfrm_audit audit_info;
 
 	x = pfkey_msg2xfrm_state(hdr, ext_hdrs);
 	if (IS_ERR(x))
@@ -1461,8 +1462,8 @@ static int pfkey_add(struct sock *sk, st
 	else
 		err = xfrm_state_update(x);
 
-	xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
-		       AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x);
+	xfrm_get_auditinfo(0, &audit_info);
+	xfrm_audit_log(&audit_info, err ? 0 : 1, 0, 0, x, "SAD-add");
 
 	if (err < 0) {
 		x->km.state = XFRM_STATE_DEAD;
@@ -1487,6 +1488,7 @@ static int pfkey_delete(struct sock *sk,
 	struct xfrm_state *x;
 	struct km_event c;
 	int err;
+	struct xfrm_audit audit_info;
 
 	if (!ext_hdrs[SADB_EXT_SA-1] ||
 	    !present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
@@ -1515,8 +1517,9 @@ static int pfkey_delete(struct sock *sk,
 	c.event = XFRM_MSG_DELSA;
 	km_state_notify(x, &c);
 out:
-	xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
-		       AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
+	xfrm_get_auditinfo(0, &audit_info);
+	xfrm_audit_log(&audit_info, err ? 0 : 1, 0, 0, x, "SAD-delete");
+
 	xfrm_state_put(x);
 
 	return err;
@@ -1691,8 +1694,7 @@ static int pfkey_flush(struct sock *sk, 
 	if (proto == 0)
 		return -EINVAL;
 
-	audit_info.loginuid = audit_get_loginuid(current->audit_context);
-	audit_info.secid = 0;
+	xfrm_get_auditinfo(0, &audit_info);
 	err = xfrm_state_flush(proto, &audit_info);
 	if (err)
 		return err;
@@ -2182,6 +2184,7 @@ static int pfkey_spdadd(struct sock *sk,
 	struct xfrm_policy *xp;
 	struct km_event c;
 	struct sadb_x_sec_ctx *sec_ctx;
+	struct xfrm_audit audit_info;
 
 	if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
 				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2268,8 +2271,8 @@ static int pfkey_spdadd(struct sock *sk,
 	err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
 				 hdr->sadb_msg_type != SADB_X_SPDUPDATE);
 
-	xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
-		       AUDIT_MAC_IPSEC_ADDSPD, err ? 0 : 1, xp, NULL);
+	xfrm_get_auditinfo(0, &audit_info);
+	xfrm_audit_log(&audit_info, err ? 0 : 1, 0, xp, 0, "SPD-add");
 
 	if (err)
 		goto out;
@@ -2301,6 +2304,7 @@ static int pfkey_spddelete(struct sock *
 	struct xfrm_selector sel;
 	struct km_event c;
 	struct sadb_x_sec_ctx *sec_ctx;
+	struct xfrm_audit audit_info;
 
 	if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
 				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2352,8 +2356,8 @@ static int pfkey_spddelete(struct sock *
 	if (xp == NULL)
 		return -ENOENT;
 
-	xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
-		       AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
+	xfrm_get_auditinfo(0, &audit_info);
+	xfrm_audit_log(&audit_info, err ? 0 : 1, 0, xp, 0, "SPD-delete");
 
 	if (err)
 		goto out;
@@ -2613,8 +2617,10 @@ static int pfkey_spdget(struct sock *sk,
 		return -ENOENT;
 
 	if (delete) {
-		xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
-			       AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
+		struct xfrm_audit audit_info;
+	
+		xfrm_get_auditinfo(0, &audit_info);
+		xfrm_audit_log(&audit_info, err ? 0 : 1, 0, xp, 0, "SPD-delete");
 
 		if (err)
 			goto out;
@@ -2691,8 +2697,7 @@ static int pfkey_spdflush(struct sock *s
 	struct xfrm_audit audit_info;
 	int err;
 
-	audit_info.loginuid = audit_get_loginuid(current->audit_context);
-	audit_info.secid = 0;
+	xfrm_get_auditinfo(0, &audit_info);
 	err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
 	if (err)
 		return err;
diff -urpN linux-2.6.22/net/xfrm/xfrm_policy.c linux-2.6.22.patch/net/xfrm/xfrm_policy.c
--- linux-2.6.22/net/xfrm/xfrm_policy.c	2007-08-14 18:14:51.000000000 -0500
+++ linux-2.6.22.patch/net/xfrm/xfrm_policy.c	2007-08-14 19:08:42.000000000 -0500
@@ -850,10 +850,8 @@ xfrm_policy_flush_secctx_check(u8 type, 
 				continue;
 			err = security_xfrm_policy_delete(pol);
 			if (err) {
-				xfrm_audit_log(audit_info->loginuid,
-					       audit_info->secid,
-					       AUDIT_MAC_IPSEC_DELSPD, 0,
-					       pol, NULL);
+				xfrm_audit_log(audit_info, 0, 0,
+					       pol, 0, "SPD-delete");
 				return err;
 			}
 		}
@@ -865,10 +863,8 @@ xfrm_policy_flush_secctx_check(u8 type, 
 					continue;
 				err = security_xfrm_policy_delete(pol);
 				if (err) {
-					xfrm_audit_log(audit_info->loginuid,
-						       audit_info->secid,
-						       AUDIT_MAC_IPSEC_DELSPD,
-						       0, pol, NULL);
+					xfrm_audit_log(audit_info, 0, 0,
+						       pol, 0, "SPD-delete");
 					return err;
 				}
 			}
@@ -909,8 +905,7 @@ int xfrm_policy_flush(u8 type, struct xf
 			hlist_del(&pol->byidx);
 			write_unlock_bh(&xfrm_policy_lock);
 
-			xfrm_audit_log(audit_info->loginuid, audit_info->secid,
-				       AUDIT_MAC_IPSEC_DELSPD, 1, pol, NULL);
+			xfrm_audit_log(audit_info, 1, 0, pol, 0, "SPD-delete");
 
 			xfrm_policy_kill(pol);
 			killed++;
@@ -930,10 +925,8 @@ int xfrm_policy_flush(u8 type, struct xf
 				hlist_del(&pol->byidx);
 				write_unlock_bh(&xfrm_policy_lock);
 
-				xfrm_audit_log(audit_info->loginuid,
-					       audit_info->secid,
-					       AUDIT_MAC_IPSEC_DELSPD, 1,
-					       pol, NULL);
+				xfrm_audit_log(audit_info, 1, 0, pol, 0, 
+					       "SPD-delete");
 
 				xfrm_policy_kill(pol);
 				killed++;
@@ -2151,114 +2144,88 @@ int xfrm_bundle_ok(struct xfrm_policy *p
 EXPORT_SYMBOL(xfrm_bundle_ok);
 
 #ifdef CONFIG_AUDITSYSCALL
-/* Audit addition and deletion of SAs and ipsec policy */
+/* Audit ipsec events */
 
-void xfrm_audit_log(uid_t auid, u32 sid, int type, int result,
-		    struct xfrm_policy *xp, struct xfrm_state *x)
+void xfrm_get_auditinfo(struct sk_buff *skb, struct xfrm_audit *audit_info)
 {
+	if (skb) {
+		audit_info->secid = NETLINK_CB(skb).sid;
+		audit_info->loginuid = NETLINK_CB(skb).loginuid;
+	} else {
+		audit_info->loginuid =
+			audit_get_loginuid(current->audit_context);
+		audit_info->secid = 0;
+	}
+}
+
+EXPORT_SYMBOL(xfrm_get_auditinfo);
+
+static void do_xfrm_audit_log(struct audit_buffer *audit_buf,
+			      u16 family, xfrm_address_t saddr,
+			      xfrm_address_t daddr, struct xfrm_sec_ctx *sctx,
+			      __be32 spi)
+{
+	if (sctx)
+		audit_log_format(audit_buf,
+				" sec_alg=%u sec_doi=%u sec_obj=%s",
+				sctx->ctx_alg, sctx->ctx_doi, sctx->ctx_str);
+
+	switch(family) {
+	case AF_INET:
+		audit_log_format(audit_buf,
+				 " src=" NIPQUAD_FMT " dst=" NIPQUAD_FMT,
+				 NIPQUAD(saddr.a4), NIPQUAD(daddr.a4));
+		break;
+	case AF_INET6:
+		audit_log_format(audit_buf, " src=" NIP6_FMT " dst=" NIP6_FMT,
+				 NIP6(*((struct in6_addr *)&saddr.a6)),
+				 NIP6(*((struct in6_addr *)&daddr.a6)));
+		break;
+	}
+
+	if (spi)
+		audit_log_format(audit_buf, " spi=%lu(0x%lx)",
+				(unsigned long)ntohl(spi),
+				(unsigned long)ntohl(spi));
+}
 
+void xfrm_audit_log(struct xfrm_audit *audit_info, int result,
+		    __be32 flowlabel, struct xfrm_policy *xp,
+		    struct xfrm_state *x, char *buf)
+{
 	char *secctx;
 	u32 secctx_len;
-	struct xfrm_sec_ctx *sctx = NULL;
 	struct audit_buffer *audit_buf;
-	int family;
 	extern int audit_enabled;
 
 	if (audit_enabled == 0)
 		return;
 
-	BUG_ON((type == AUDIT_MAC_IPSEC_ADDSA ||
-		type == AUDIT_MAC_IPSEC_DELSA) && !x);
-	BUG_ON((type == AUDIT_MAC_IPSEC_ADDSPD ||
-		type == AUDIT_MAC_IPSEC_DELSPD) && !xp);
-
-	audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, type);
+	audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
+				    AUDIT_MAC_IPSEC_EVENT);
 	if (audit_buf == NULL)
 		return;
 
-	switch(type) {
-	case AUDIT_MAC_IPSEC_ADDSA:
-		audit_log_format(audit_buf, "SAD add: auid=%u", auid);
-		break;
-	case AUDIT_MAC_IPSEC_DELSA:
-		audit_log_format(audit_buf, "SAD delete: auid=%u", auid);
-		break;
-	case AUDIT_MAC_IPSEC_ADDSPD:
-		audit_log_format(audit_buf, "SPD add: auid=%u", auid);
-		break;
-	case AUDIT_MAC_IPSEC_DELSPD:
-		audit_log_format(audit_buf, "SPD delete: auid=%u", auid);
-		break;
-	default:
-		return;
-	}
+	audit_log_format(audit_buf, "op=%s auid=%u", buf, audit_info->loginuid);
 
-	if (sid != 0 &&
-	    security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) {
+	if (audit_info->secid != 0 &&
+		security_secid_to_secctx(audit_info->secid, &secctx,
+					 &secctx_len) == 0)
 		audit_log_format(audit_buf, " subj=%s", secctx);
-		security_release_secctx(secctx, secctx_len);
-	} else
+	else
 		audit_log_task_context(audit_buf);
 
-	if (xp) {
-		family = xp->selector.family;
-		if (xp->security)
-			sctx = xp->security;
-	} else {
-		family = x->props.family;
-		if (x->security)
-			sctx = x->security;
-	}
-
-	if (sctx)
-		audit_log_format(audit_buf,
-				" sec_alg=%u sec_doi=%u sec_obj=%s",
-				sctx->ctx_alg, sctx->ctx_doi, sctx->ctx_str);
-
-	switch(family) {
-	case AF_INET:
-		{
-			struct in_addr saddr, daddr;
-			if (xp) {
-				saddr.s_addr = xp->selector.saddr.a4;
-				daddr.s_addr = xp->selector.daddr.a4;
-			} else {
-				saddr.s_addr = x->props.saddr.a4;
-				daddr.s_addr = x->id.daddr.a4;
-			}
-			audit_log_format(audit_buf,
-					 " src=%u.%u.%u.%u dst=%u.%u.%u.%u",
-					 NIPQUAD(saddr), NIPQUAD(daddr));
-		}
-			break;
-	case AF_INET6:
-		{
-			struct in6_addr saddr6, daddr6;
-			if (xp) {
-				memcpy(&saddr6, xp->selector.saddr.a6,
-					sizeof(struct in6_addr));
-				memcpy(&daddr6, xp->selector.daddr.a6,
-					sizeof(struct in6_addr));
-			} else {
-				memcpy(&saddr6, x->props.saddr.a6,
-					sizeof(struct in6_addr));
-				memcpy(&daddr6, x->id.daddr.a6,
-					sizeof(struct in6_addr));
-			}
-			audit_log_format(audit_buf,
-					 " src=" NIP6_FMT " dst=" NIP6_FMT,
-					 NIP6(saddr6), NIP6(daddr6));
-		}
-		break;
-	}
+	if (xp)
+		do_xfrm_audit_log(audit_buf, xp->selector.family,
+				  xp->selector.saddr, xp->selector.daddr,
+				  xp->security, 0);
 
 	if (x)
-		audit_log_format(audit_buf, " spi=%lu(0x%lx) protocol=%s",
-				(unsigned long)ntohl(x->id.spi),
-				(unsigned long)ntohl(x->id.spi),
-				x->id.proto == IPPROTO_AH ? "AH" :
-				(x->id.proto == IPPROTO_ESP ?
-				"ESP" : "IPCOMP"));
+		do_xfrm_audit_log(audit_buf, x->props.family, x->props.saddr,
+				  x->id.daddr, x->security, x->id.spi);
+
+	if (flowlabel)
+		audit_log_format(audit_buf, " flowlabel=%u", flowlabel);
 
 	audit_log_format(audit_buf, " res=%u", result);
 	audit_log_end(audit_buf);
diff -urpN linux-2.6.22/net/xfrm/xfrm_state.c linux-2.6.22.patch/net/xfrm/xfrm_state.c
--- linux-2.6.22/net/xfrm/xfrm_state.c	2007-08-14 18:14:51.000000000 -0500
+++ linux-2.6.22.patch/net/xfrm/xfrm_state.c	2007-08-14 19:08:42.000000000 -0500
@@ -239,6 +239,7 @@ static void xfrm_timer_handler(unsigned 
 	long next = LONG_MAX;
 	int warn = 0;
 	int err = 0;
+	struct xfrm_audit audit_info;
 
 	spin_lock(&x->lock);
 	if (x->km.state == XFRM_STATE_DEAD)
@@ -301,8 +302,9 @@ expired:
 	if (!err && x->id.spi)
 		km_state_expired(x, 1, 0);
 
-	xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
-		       AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
+	
+	xfrm_get_auditinfo(0, &audit_info);
+	xfrm_audit_log(&audit_info, err ? 0 : 1, 0, 0, x, "SAD-delete");
 
 out:
 	spin_unlock(&x->lock);
@@ -403,11 +405,8 @@ xfrm_state_flush_secctx_check(u8 proto, 
 		hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
 			if (xfrm_id_proto_match(x->id.proto, proto) &&
 			   (err = security_xfrm_state_delete(x)) != 0) {
-				xfrm_audit_log(audit_info->loginuid,
-					       audit_info->secid,
-					       AUDIT_MAC_IPSEC_DELSA,
-					       0, NULL, x);
-
+				xfrm_audit_log(audit_info, 0, 0, 0, x,
+					       "SAD-delete");
 				return err;
 			}
 		}
@@ -443,10 +442,8 @@ restart:
 				spin_unlock_bh(&xfrm_state_lock);
 
 				err = xfrm_state_delete(x);
-				xfrm_audit_log(audit_info->loginuid,
-					       audit_info->secid,
-					       AUDIT_MAC_IPSEC_DELSA,
-					       err ? 0 : 1, NULL, x);
+				xfrm_audit_log(audit_info, err ? 0 : 1, 0,
+					       0, x, "SAD-delete");
 				xfrm_state_put(x);
 
 				spin_lock_bh(&xfrm_state_lock);
diff -urpN linux-2.6.22/net/xfrm/xfrm_user.c linux-2.6.22.patch/net/xfrm/xfrm_user.c
--- linux-2.6.22/net/xfrm/xfrm_user.c	2007-08-14 18:13:54.000000000 -0500
+++ linux-2.6.22.patch/net/xfrm/xfrm_user.c	2007-08-14 19:09:14.000000000 -0500
@@ -447,6 +447,7 @@ static int xfrm_add_sa(struct sk_buff *s
 	struct xfrm_state *x;
 	int err;
 	struct km_event c;
+	struct xfrm_audit audit_info;
 
 	err = verify_newsa_info(p, xfrma);
 	if (err)
@@ -462,8 +463,8 @@ static int xfrm_add_sa(struct sk_buff *s
 	else
 		err = xfrm_state_update(x);
 
-	xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
-		       AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x);
+	xfrm_get_auditinfo(skb, &audit_info);
+	xfrm_audit_log(&audit_info, err ? 0 : 1, 0, 0, x, "SAD-add");
 
 	if (err < 0) {
 		x->km.state = XFRM_STATE_DEAD;
@@ -521,6 +522,7 @@ static int xfrm_del_sa(struct sk_buff *s
 	int err = -ESRCH;
 	struct km_event c;
 	struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
+	struct xfrm_audit audit_info;
 
 	x = xfrm_user_state_lookup(p, xfrma, &err);
 	if (x == NULL)
@@ -545,8 +547,8 @@ static int xfrm_del_sa(struct sk_buff *s
 	km_state_notify(x, &c);
 
 out:
-	xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
-		       AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
+	xfrm_get_auditinfo(skb, &audit_info);
+	xfrm_audit_log(&audit_info, err ? 0 : 1, 0, 0, x, "SAD-delete");
 	xfrm_state_put(x);
 	return err;
 }
@@ -1137,6 +1139,7 @@ static int xfrm_add_policy(struct sk_buf
 	struct km_event c;
 	int err;
 	int excl;
+	struct xfrm_audit audit_info;
 
 	err = verify_newpolicy_info(p);
 	if (err)
@@ -1155,8 +1158,8 @@ static int xfrm_add_policy(struct sk_buf
 	 * a type XFRM_MSG_UPDPOLICY - JHS */
 	excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY;
 	err = xfrm_policy_insert(p->dir, xp, excl);
-	xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
-		       AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
+	xfrm_get_auditinfo(skb, &audit_info);
+	xfrm_audit_log(&audit_info, err ? 0 : 1, 0, xp, 0, "SPD-add");
 
 	if (err) {
 		security_xfrm_policy_free(xp);
@@ -1401,8 +1404,11 @@ static int xfrm_get_policy(struct sk_buf
 					      MSG_DONTWAIT);
 		}
 	} else {
-		xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
-			       AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
+		struct xfrm_audit audit_info;
+
+		xfrm_get_auditinfo(skb, &audit_info);
+		xfrm_audit_log(&audit_info, err ? 0 : 1, 0,
+			       xp, 0, "SPD-delete");
 
 		if (err != 0)
 			goto out;
@@ -1427,8 +1433,7 @@ static int xfrm_flush_sa(struct sk_buff 
 	struct xfrm_audit audit_info;
 	int err;
 
-	audit_info.loginuid = NETLINK_CB(skb).loginuid;
-	audit_info.secid = NETLINK_CB(skb).sid;
+	xfrm_get_auditinfo(skb, &audit_info);
 	err = xfrm_state_flush(p->proto, &audit_info);
 	if (err)
 		return err;
@@ -1590,8 +1595,7 @@ static int xfrm_flush_policy(struct sk_b
 	if (err)
 		return err;
 
-	audit_info.loginuid = NETLINK_CB(skb).loginuid;
-	audit_info.secid = NETLINK_CB(skb).sid;
+	xfrm_get_auditinfo(skb, &audit_info);
 	err = xfrm_policy_flush(type, &audit_info);
 	if (err)
 		return err;
@@ -1649,10 +1653,11 @@ static int xfrm_add_pol_expire(struct sk
 	read_unlock(&xp->lock);
 	err = 0;
 	if (up->hard) {
-		xfrm_policy_delete(xp, p->dir);
-		xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
-				AUDIT_MAC_IPSEC_DELSPD, 1, xp, NULL);
+		struct xfrm_audit audit_info;
 
+		xfrm_policy_delete(xp, p->dir);
+		xfrm_get_auditinfo(skb, &audit_info);
+		xfrm_audit_log(&audit_info, 1, 0, xp, 0, "SPD-delete");
 	} else {
 		// reset the timers here?
 		printk("Dont know what to do with soft policy expire\n");
@@ -1685,9 +1690,11 @@ static int xfrm_add_sa_expire(struct sk_
 	km_state_expired(x, ue->hard, current->pid);
 
 	if (ue->hard) {
+		struct xfrm_audit audit_info;
+
 		__xfrm_state_delete(x);
-		xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
-			       AUDIT_MAC_IPSEC_DELSA, 1, NULL, x);
+		xfrm_get_auditinfo(skb, &audit_info);
+		xfrm_audit_log(&audit_info, 1, 0, 0, x, "SAD-delete");
 	}
 	err = 0;
 out:

^ permalink raw reply

* Re: [PATCH 0/24] make atomic_read() behave consistently across all architectures
From: Chris Snook @ 2007-08-15 16:13 UTC (permalink / raw)
  To: Herbert Xu
  Cc: satyam, clameter, linux-kernel, linux-arch, torvalds, netdev,
	akpm, ak, heiko.carstens, davem, schwidefsky, wensong, horms,
	wjiang, cfriesen, zlynx, rpjday, jesper.juhl, segher
In-Reply-To: <E1ILCgh-00052A-00@gondolin.me.apana.org.au>

Herbert Xu wrote:
> Chris Snook <csnook@redhat.com> wrote:
>> Because atomic operations are generally used for synchronization, which requires 
>> volatile behavior.  Most such codepaths currently use an inefficient barrier(). 
>>  Some forget to and we get bugs, because people assume that atomic_read() 
>> actually reads something, and atomic_write() actually writes something.  Worse, 
>> these are architecture-specific, even compiler version-specific bugs that are 
>> often difficult to track down.
> 
> I'm yet to see a single example from the current tree where
> this patch series is the correct solution.  So far the only
> example has been a buggy piece of code which has since been
> fixed with a cpu_relax.

Part of the motivation here is to fix heisenbugs.  If I knew where they 
were, I'd be posting patches for them.  Unlike most bugs, where we want 
to expose them as obviously as possible, these can be extremely 
difficult to track down, and are often due to people assuming that the 
atomic_* operations have the same semantics they've historically had. 
Remember that until recently, all SMP architectures except s390 (which 
very few kernel developers outside of IBM, Red Hat, and SuSE do much 
work on) had volatile declarations for atomic_t.  Removing the volatile 
declarations from i386 and x86_64 may have created heisenbugs that won't 
manifest themselves until GCC 6.0 comes out and people start compiling 
kernels with -O5.  We should have consistent semantics for atomic_* 
operations.

The other motivation is to reduce the need for the barriers used to 
prevent/fix such problems which clobber all your registers, and instead 
force atomic_* operations to behave in the way they're actually used. 
After the (resubmitted) patchset is merged, we'll be able to remove a 
whole bunch of barriers, shrinking our source and our binaries, and 
improving performance.

	-- Chris

^ permalink raw reply

* Re: [PATCH 0/24] make atomic_read() behave consistently across all architectures
From: Stefan Richter @ 2007-08-15 16:09 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Satyam Sharma, Heiko Carstens, Chris Snook, clameter,
	Linux Kernel Mailing List, linux-arch, Linus Torvalds, netdev,
	Andrew Morton, ak, davem, schwidefsky, wensong, horms, wjiang,
	cfriesen, zlynx, rpjday, jesper.juhl, segher
In-Reply-To: <20070815145207.GA23106@gondor.apana.org.au>

Herbert Xu wrote:
> On Wed, Aug 15, 2007 at 08:05:38PM +0530, Satyam Sharma wrote:
>>> I don't know if this here is affected:

[...something like]
	b = atomic_read(a);
	for (i = 0; i < 4; i++) {
		msleep_interruptible(63);
		c = atomic_read(a);
		if (c != b) {
			b = c;
			i = 0;
		}
	}

> Nope, we're calling schedule which is a rather heavy-weight
> barrier.

How does the compiler know that msleep() has got barrier()s?
-- 
Stefan Richter
-=====-=-=== =--- -====
http://arcgraph.de/sr/

^ permalink raw reply

* Re: [PATCH 0/24] make atomic_read() behave consistently across all architectures
From: Paul E. McKenney @ 2007-08-15 16:08 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Satyam Sharma, Stefan Richter, Christoph Lameter, Chris Snook,
	Linux Kernel Mailing List, linux-arch, Linus Torvalds, netdev,
	Andrew Morton, ak, heiko.carstens, davem, schwidefsky, wensong,
	horms, wjiang, cfriesen, zlynx, rpjday, jesper.juhl, segher
In-Reply-To: <20070815153335.GA23593@gondor.apana.org.au>

On Wed, Aug 15, 2007 at 11:33:36PM +0800, Herbert Xu wrote:
> On Wed, Aug 15, 2007 at 07:25:16AM -0700, Paul E. McKenney wrote:
> > 
> > Do we really need another set of APIs?  Can you give even one example
> > where the pre-existing volatile semantics are causing enough of a problem
> > to justify adding yet more atomic_*() APIs?
> 
> Let's turn this around.  Can you give a single example where
> the volatile semantics is needed in a legitimate way?

Sorry, but you are the one advocating for the change.

Nice try, though!  ;-)

						Thanx, Paul

^ permalink raw reply

* Re: skb_pull_rcsum - Fatal exception in interrupt
From: Evgeniy Polyakov @ 2007-08-15 15:54 UTC (permalink / raw)
  To: Alan J. Wylie; +Cc: netdev
In-Reply-To: <18115.5803.588114.372952@wylie.me.uk>

Hi Alan.

On Wed, Aug 15, 2007 at 04:07:23PM +0100, Alan J. Wylie (alan@wylie.me.uk) wrote:
> EIP: [<c02b6fb2>] skb_pull_rcsum+0x6d/0x71 SS:ESP 09068:c03e1ea4
> Kernel panic - not syncing: Fatal exception in interrupt

At least with this patch it should not panic.
More correct solution might be to use pskb_may_pull() or check aditional
length in llc_fixup_skb().
Actually if dmesg will show that there is something in fragments, it
should use pskb_may_pull(). The same bug exist in bridge and vlan, btw,
so it might be a solution to remove bug_on from skb_pull_rcsum() and
instead call may_pull?

Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>

diff --git a/net/802/psnap.c b/net/802/psnap.c
index 04ee43e..5f410e9 100644
--- a/net/802/psnap.c
+++ b/net/802/psnap.c
@@ -60,13 +60,24 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
 	if (proto) {
 		/* Pass the frame on. */
 		skb->transport_header += 5;
+		if (skb->len < 5 || skb->len - 5 < skb->data_len) {
+			if (net_ratelimit())
+				printk(KERN_NOTICE "Short packet: len: %u, "
+						"data_len: %u.\n",
+					skb->len, skb->data_len);
+			goto err_out;
+		}
 		skb_pull_rcsum(skb, 5);
 		rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
-	} else {
-		skb->sk = NULL;
-		kfree_skb(skb);
-		rc = 1;
 	}
+	
+	rcu_read_unlock();
+	return rc;
+
+err_out:
+	skb->sk = NULL;
+	kfree_skb(skb);
+	rc = 1;
 
 	rcu_read_unlock();
 	return rc;


-- 
	Evgeniy Polyakov

^ permalink raw reply related

* Re: [PATCH 0/24] make atomic_read() behave consistently across all architectures
From: Herbert Xu @ 2007-08-15 15:33 UTC (permalink / raw)
  To: Paul E. McKenney
  Cc: Satyam Sharma, Stefan Richter, Christoph Lameter, Chris Snook,
	Linux Kernel Mailing List, linux-arch, Linus Torvalds, netdev,
	Andrew Morton, ak, heiko.carstens, davem, schwidefsky, wensong,
	horms, wjiang, cfriesen, zlynx, rpjday, jesper.juhl, segher
In-Reply-To: <20070815142516.GB9645@linux.vnet.ibm.com>

On Wed, Aug 15, 2007 at 07:25:16AM -0700, Paul E. McKenney wrote:
> 
> Do we really need another set of APIs?  Can you give even one example
> where the pre-existing volatile semantics are causing enough of a problem
> to justify adding yet more atomic_*() APIs?

Let's turn this around.  Can you give a single example where
the volatile semantics is needed in a legitimate way?

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH 6/24] make atomic_read() behave consistently on frv
From: Michael Buesch @ 2007-08-15 15:06 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: paulmck, Nick Piggin, Herbert Xu, csnook, dhowells, linux-kernel,
	linux-arch, torvalds, netdev, akpm, ak, heiko.carstens, davem,
	schwidefsky, wensong, horms, wjiang, cfriesen, zlynx, rpjday,
	jesper.juhl
In-Reply-To: <200708151529.46780.arnd@arndb.de>

On Wednesday 15 August 2007 15:29:43 Arnd Bergmann wrote:
> On Wednesday 15 August 2007, Paul E. McKenney wrote:
> 
> > ACCESS_ONCE() is indeed intended to be used when actually loading or
> > storing the variable.  That said, I must admit that it is not clear to me
> > why you would want to add an extra order() rather than ACCESS_ONCE()ing
> > one or both of the adjacent accesses to that same variable.
> > 
> > So, what am I missing?
> 
> You're probably right, the only case I can construct is something like
> 
> 	if (ACCESS_ONCE(x)) {
> 		...
> 		ACCESS_ONCE(x)++;
> 	}
> 
> which would be slightly less efficient than
> 
> 	if (x)
> 		x++;
> 	order(x);
> 
> because in the first case, you need to do two ordered accesses
> but only one in the second case. However, I can't think of a case
> where this actually makes a noticable difference in real life.

How can this example actually get used in a sane and race-free
way? This would need locking around the whole if
statement. But locking is a barrier.

-- 
Greetings Michael.

^ permalink raw reply

* skb_pull_rcsum - Fatal exception in interrupt
From: Alan J. Wylie @ 2007-08-15 15:07 UTC (permalink / raw)
  To: netdev


We have been shipping Linux based servers to customers for several
years now, with few problems. Recently, however, a single customer has
been seeing kernel panics. Unfortunately, the customer is about 200
miles away, so physical access is limited. There are two ethernet
interfaces, one should be plugged into a local RFC1918 network, the
other is connected to the internet. If eth0 is plugged into the local
network, a short time later the system panics.

Hardware: Intel S5000VSA server

Network cards: Intel e1000
   Intel Corporation 80003ES2LAN Gigabit Ethernet Controller (Copper) 

We shipped a second system, and this displayed identical symptoms.  We
have tested with several recent 2.6 kernels, including

2.6.22
2.6.17.14
2.6.20.15

all of which crash.

We have a couple of photographs showing the tail end of the messages
on the screen.

The last two lines are:

EIP: [<c02b6fb2>] skb_pull_rcsum+0x6d/0x71 SS:ESP 09068:c03e1ea4
Kernel panic - not syncing: Fatal exception in interrupt

The photos, along with the following information are available at
http://wylie.me.uk/skb_pull_rcsum/

lspci
lspci -n
lspci -v
ethtool -d
/proc/interrupts
kernel config

There are no related messages in the syslog files.

The code for skb_pull_rcsum is short, but contains two calls
to BUG_ON, checking for invalid lengths.

unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len)
{
        BUG_ON(len > skb->len);
        skb->len -= len;
        BUG_ON(skb->len < skb->data_len);
        skb_postpull_rcsum(skb, skb->data, len);
        return skb->data += len;
}

I wonder whether this problem bears any resemblance to 

http://bugzilla.kernel.org/show_bug.cgi?id=2979

| We were overreacting to invalid incoming AppleTalk frames. Better
| just drop invalid frames than crash the kernel ;)

<http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=75559c167bddc1254db5bcff032ad5eed8bd6f4a>

| [APPLETALK]: Fix a remotely triggerable crash

| When we receive an AppleTalk frame shorter than what its header
| says, we still attempt to verify its checksum, and trip on the
| BUG_ON() at the end of function atalk_sum_skb() because of the
| length mismatch.

| This has security implications because this can be triggered by
| simply sending a specially crafted ethernet frame to a target
| victim, effectively crashing that host. Thus this qualifies, I
| think, as a remote DoS.

Our system is also installed in a school. We have remote access to the
box, and can, with some inconvenience, arrange for the box to be
rebooted. We are currently arranging for two different network cards
(RealTek RTL8139) to be installed.

I am pretty certain that the problem is to do with network traffic,
rather than hardware or software configurations - this box is pretty
well identical to tens of other boxes working successfully, the only
difference being that recently the on-board ethernet changed from
8086:1079 (rev 03) to 8086:1096 (rev 01) requiring an updated e1000
driver.

What is the best way to track this bug down, remembering that we have
little more than ssh access and a remote finger to press the reboot
button?

Could we modify the code to log and drop the packet, rather than
panicking the kernel?

-- 
Alan J. Wylie                                          http://www.wylie.me.uk/
"Perfection [in design] is achieved not when there is nothing left to add,
but rather when there is nothing left to take away."
  -- Antoine de Saint-Exupery

^ permalink raw reply

* [PATCH 1/1] ipv6: corrects sended rtnetlink message
From: Milan Kocian @ 2007-08-15 14:33 UTC (permalink / raw)
  To: netdev

ipv6 sends a RTM_DELLINK netlink message on both events: NETDEV_DOWN,
NETDEV_UNREGISTER. Corrected by sending RTM_NEWLINK on NETDEV_DOWN event
and RTM_DELLINK on NETDEV_UNREGISTER event.
---

btw. I don't know why protocol sends a NL messages about iface state
changes. It comes from other sources. By contrast ipv6 doesn't send
no message on NETDEV_UP event !? IMO best possibility is deletion of
sending this message.


--- a/net/ipv6/addrconf.c	2007-08-13 11:35:23.481430029 +0200
+++ b/net/ipv6/addrconf.c	2007-08-13 12:47:01.825690662 +0200
@@ -2488,7 +2488,10 @@ static int addrconf_ifdown(struct net_de
 
 	/* Step 5: netlink notification of this interface */
 	idev->tstamp = jiffies;
-	inet6_ifinfo_notify(RTM_DELLINK, idev);
+	if (how)
+		inet6_ifinfo_notify(RTM_DELLINK, idev);
+	else 
+		inet6_ifinfo_notify(RTM_NEWLINK, idev);
 
 	/* Shot the device (if unregistered) */
 

Signed-off-by: Milan Kocian <milon@wq.cz>

^ permalink raw reply

* Re: [PATCH 0/24] make atomic_read() behave consistently across all architectures
From: Herbert Xu @ 2007-08-15 14:52 UTC (permalink / raw)
  To: Satyam Sharma
  Cc: Stefan Richter, Heiko Carstens, Chris Snook, clameter,
	Linux Kernel Mailing List, linux-arch, Linus Torvalds, netdev,
	Andrew Morton, ak, davem, schwidefsky, wensong, horms, wjiang,
	cfriesen, zlynx, rpjday, jesper.juhl, segher
In-Reply-To: <alpine.LFD.0.999.0708151941150.16414@enigma.security.iitk.ac.in>

On Wed, Aug 15, 2007 at 08:05:38PM +0530, Satyam Sharma wrote:
>
> > I don't know if this here is affected:
> 
> Yes, I think it is. You're clearly expecting the read to actually happen
> when you call get_hpsb_generation(). It's clearly not a busy-loop, so
> cpu_relax() sounds pointless / wrong solution for this case, so I'm now
> somewhat beginning to appreciate the motivation behind this series :-)

Nope, we're calling schedule which is a rather heavy-weight
barrier.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH 6/24] make atomic_read() behave consistently on frv
From: Arnd Bergmann @ 2007-08-15 13:29 UTC (permalink / raw)
  To: paulmck
  Cc: Nick Piggin, Herbert Xu, csnook, dhowells, linux-kernel,
	linux-arch, torvalds, netdev, akpm, ak, heiko.carstens, davem,
	schwidefsky, wensong, horms, wjiang, cfriesen, zlynx, rpjday,
	jesper.juhl
In-Reply-To: <20070814224354.GE8243@linux.vnet.ibm.com>

On Wednesday 15 August 2007, Paul E. McKenney wrote:

> ACCESS_ONCE() is indeed intended to be used when actually loading or
> storing the variable.  That said, I must admit that it is not clear to me
> why you would want to add an extra order() rather than ACCESS_ONCE()ing
> one or both of the adjacent accesses to that same variable.
> 
> So, what am I missing?

You're probably right, the only case I can construct is something like

	if (ACCESS_ONCE(x)) {
		...
		ACCESS_ONCE(x)++;
	}

which would be slightly less efficient than

	if (x)
		x++;
	order(x);

because in the first case, you need to do two ordered accesses
but only one in the second case. However, I can't think of a case
where this actually makes a noticable difference in real life.

	Arnd <><

^ permalink raw reply

* Re: [ofa-general] Re: [PATCH RFC] RDMA/CMA: Allocate PS_TCP ports from the host TCP port space.
From: Steve Wise @ 2007-08-15 14:42 UTC (permalink / raw)
  To: David Miller; +Cc: rdreier, linux-kernel, general, netdev
In-Reply-To: <20070809.145534.102938208.davem@davemloft.net>



David Miller wrote:
> From: Sean Hefty <mshefty@ichips.intel.com>
> Date: Thu, 09 Aug 2007 14:40:16 -0700
> 
>> Steve Wise wrote:
>>> Any more comments?
>> Does anyone have ideas on how to reserve the port space without using a 
>> struct socket?
> 
> How about we just remove the RDMA stack altogether?  I am not at all
> kidding.  If you guys can't stay in your sand box and need to cause
> problems for the normal network stack, it's unacceptable.  We were
> told all along the if RDMA went into the tree none of this kind of
> stuff would be an issue.

I think removing the RDMA stack is the wrong thing to do, and you 
shouldn't just threaten to yank entire subsystems because you don't like 
the technology.  Lets keep this constructive, can we?  RDMA should get 
the respect of any other technology in Linux.  Maybe its a niche in your 
opinion, but come on, there's more RDMA users than say, the sparc64 
port.  Eh?

> 
> These are exactly the kinds of problems for which people like myself
> were dreading.  These subsystems have no buisness using the TCP port
> space of the Linux software stack, absolutely none.
> 

Ok, although IMO its the correct solution.  But I'll propose other 
solutions below.  I ask for your feedback (and everyones!) on these 
alternate solutions.

> After TCP port reservation, what's next?  It seems an at least
> bi-monthly event that the RDMA folks need to put their fingers
> into something else in the normal networking stack.  No more.
>

The only other change requested and commited, if I recall correctly, was 
for netevents, and that enabled both Infiniband and iWARP to integrate 
with the neighbour subsystem.  I think that was a useful and needed 
change.  Prior to that, these subsystems were snooping ARP replies to 
trigger events.  That was back in 2.6.18 or 2.6.19 I think...

> I will NACK any patch that opens up sockets to eat up ports or
> anything stupid like that.

Got it.

Here are alternate solutions that avoid the need to share the port space:

Solution 1)

1) admins must setup an alias interface on the iwarp device for use with 
rdma.  This interface will have to be a separate subnet from the "TCP 
used" interface.  And with a canonical name that indicates its "for rdma 
only".  Like eth2:iw or eth2:rdma.  There can be many of these per device.

2) admins make sure their sockets/tcp services don't use the interface 
configured in #1, and their rdma service do use said interface.

3) iwarp providers must translation binds to ipaddr 0.0.0.0 to the 
associated "for rdma only" ip addresses.  They can do this by searching 
for all aliases of the canonical name that are aliases of the TCP 
interface for their nic device.  Or: somehow not handle incoming 
connections to any address but the "for rdma use" addresses and instead 
pass them up and not offload them.

This will avoid the collisions as long as the above steps are followed.


Solution 2)

Another possibility would be for the driver to create two net devices 
(and hence two interace names) like "eth2" and "iw2", and artificially 
separate the RDMA stuff that way.

These two solutions are similar in that they create a "rdma only" interface.

Pros:
- is not intrusive into the core networking code
- very minimal changes needed and in the iwarp provider's code, who are 
the ones with this problem
- makes it clear which subnets are RDMA only

Cons:
- relies on system admin to set it up correctly.
- native stack can still "use" this rdma-only interface and the same 
port space issue will exist.


For the record, here are possible port-sharing solutions Dave sez he'll NAK:

Solution NAK-1)

The rdma-cma just allocates a socket and binds it to reserve TCP ports.

Pros:
- minimal changes needed to implement (always a plus in my mind :)
- simple, clean, and it works (KISS)
- if no RDMA is in use, there is no impact on the native stack
- no need for a seperate RDMA interface

Cons:
- wastes memory
- puts a TCP socket in the "CLOSED" state in the pcb tables.
- Dave will NAK it :)

Solution NAK-2)

Create a low-level sockets-agnostic port allocation service that is 
shared by both TCP and RDMA.  This way, the rdma-cm can reserve ports in 
an efficient manor instead of doing it via kernel_bind() using a sock 
struct.

Pros:
- probably the correct solution (my opinion :) if we went down the path 
of sharing port space
- if no RDMA is in use, there is no impact on the native stack
- no need for a separate RDMA interface

Cons:

- very intrusive change because the port allocations stuff is tightly 
bound to the host stack and sock struct, etc.
- Dave will NAK it :)


Steve.

^ permalink raw reply

* Re: [PATCH 0/24] make atomic_read() behave consistently across all architectures
From: Paul E. McKenney @ 2007-08-15 14:25 UTC (permalink / raw)
  To: Satyam Sharma
  Cc: Stefan Richter, Christoph Lameter, Chris Snook,
	Linux Kernel Mailing List, linux-arch, Linus Torvalds, netdev,
	Andrew Morton, ak, heiko.carstens, davem, schwidefsky, wensong,
	horms, wjiang, cfriesen, zlynx, rpjday, jesper.juhl, segher,
	Herbert Xu
In-Reply-To: <alpine.LFD.0.999.0708151906330.16414@enigma.security.iitk.ac.in>

On Wed, Aug 15, 2007 at 07:17:29PM +0530, Satyam Sharma wrote:
> On Wed, 15 Aug 2007, Stefan Richter wrote:
> > Satyam Sharma wrote:
> > > On Wed, 15 Aug 2007, Stefan Richter wrote:
> > >> Doesn't "atomic WRT all processors" require volatility?
> > > 
> > > No, it definitely doesn't. Why should it?
> > > 
> > > "Atomic w.r.t. all processors" is just your normal, simple "atomicity"
> > > for SMP systems (ensure that that object is modified / set / replaced
> > > in main memory atomically) and has nothing to do with "volatile"
> > > behaviour.
> > > 
> > > "Volatile behaviour" itself isn't consistently defined (at least
> > > definitely not consistently implemented in various gcc versions across
> > > platforms), but it is /expected/ to mean something like: "ensure that
> > > every such access actually goes all the way to memory, and is not
> > > re-ordered w.r.t. to other accesses, as far as the compiler can take
> > > care of these". The last "as far as compiler can take care" disclaimer
> > > comes about due to CPUs doing their own re-ordering nowadays.
> > > 
> > > For example (say on i386):
> > 
> > [...]
> > 
> > > In (A) the compiler optimized "a = 10;" away, but the actual store
> > > of the final value "20" to "a" was still "atomic". (B) and (C) also
> > > exhibit "volatile" behaviour apart from the "atomicity".
> > > 
> > > But as others replied, it seems some callers out there depend upon
> > > atomic ops exhibiting "volatile" behaviour as well, so that answers
> > > my initial question, actually. I haven't looked at the code Paul
> > > pointed me at, but I wonder if that "forget(x)" macro would help
> > > those cases. I'd wish to avoid the "volatile" primitive, personally.
> > 
> > So, looking at load instead of store, understand I correctly that in
> > your opinion
> > 
> > 	int b;
> > 
> > 	b = atomic_read(&a);
> > 	if (b)
> > 		do_something_time_consuming();
> > 
> > 	b = atomic_read(&a);
> > 	if (b)
> > 		do_something_more();
> > 
> > should be changed to explicitly forget(&a) after
> > do_something_time_consuming?
> 
> No, I'd actually prefer something like what Christoph Lameter suggested,
> i.e. users (such as above) who want "volatile"-like behaviour from atomic
> ops can use alternative functions. How about something like:
> 
> #define atomic_read_volatile(v)			\
> 	({					\
> 		forget(&(v)->counter);		\
> 		((v)->counter);			\
> 	})

Wouldn't the above "forget" the value, throw it away, then forget
that it forgot it, giving non-volatile semantics?

> Or possibly, implement these "volatile" atomic ops variants in inline asm
> like the patch that Sebastian Siewior has submitted on another thread just
> a while back.

Given that you are advocating a change (please keep in mind that
atomic_read() and atomic_set() had volatile semantics on almost all
platforms), care to give some example where these historical volatile
semantics are causing a problem?

> Of course, if we find there are more callers in the kernel who want the
> volatility behaviour than those who don't care, we can re-define the
> existing ops to such variants, and re-name the existing definitions to
> somethine else, say "atomic_read_nonvolatile" for all I care.

Do we really need another set of APIs?  Can you give even one example
where the pre-existing volatile semantics are causing enough of a problem
to justify adding yet more atomic_*() APIs?

							Thanx, Paul

^ permalink raw reply


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