* sky2.c: length mismatch errors with vlan frames
@ 2007-09-10 14:35 Pierre-Yves Ritschard
2007-09-11 8:10 ` Stephen Hemminger
0 siblings, 1 reply; 4+ messages in thread
From: Pierre-Yves Ritschard @ 2007-09-10 14:35 UTC (permalink / raw)
To: netdev; +Cc: Stephen Hemminger
Hi list,
I have been running recent linux kernel on nexcom NSA 1086's equipped
with sysconnect NICs.
Like some people previously have on this list I am running into
problems with these NICs and seeing frequent errors in my dmesg:
sky2 eth4: rx error, status 0x402300 length 60
printk: 17 messages suppressed.
sky2 eth4: rx error, status 0x402300 length 60
printk: 32 messages suppressed.
sky2 eth4: rx error, status 0x602300 length 92
printk: 25 messages suppressed.
sky2 eth4: rx error, status 0x6e2300 length 106
printk: 16 messages suppressed.
sky2 eth4: rx error, status 0x402300 length 60
printk: 10 messages suppressed.
sky2 eth4: rx error, status 0x402300 length 60
printk: 17 messages suppressed.
sky2 eth4: rx error, status 0x402300 length 60
I have investigated a bit and status doesn't match any of the errors in
GMR_FS_ANY_ERR.
The block generating the error is now len_mismatch, due to the fact
that on packets having the GMR_FS_VLAN bit set, the length argument to
sky2_receive is 4 bytes shorter that the 16 bit value in status (status
``right shift'' 16).
Since both these values are read from the card I don't know how to
solve this other than by incrementing the length arg by 4 when
GMR_FS_VLAN is set in status. So here's a diff that does this, although
I'm not sure its an elegant solution:
--- sky2.c.orig 2007-09-10 15:34:15.000000000 +0200
+++ sky2.c 2007-09-10 16:20:28.000000000 +0200
@@ -2059,13 +2059,16 @@ static struct sk_buff *sky2_receive(stru
sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
prefetch(sky2->rx_ring + sky2->rx_next);
+ if (status & GMR_FS_VLAN)
+ length += 4;
+
if (status & GMR_FS_ANY_ERR)
goto error;
if (!(status & GMR_FS_RX_OK))
goto resubmit;
- if (status >> 16 != length)
+ if ((status >> 16) != length)
goto len_mismatch;
if (length < copybreak)
@@ -2081,6 +2084,8 @@ len_mismatch:
/* Truncation of overlength packets
causes PHY length to not match MAC length */
++sky2->net_stats.rx_length_errors;
+ printk(KERN_INFO PFX "%s: rx length mismatch: length %d != %d\n",
+ dev->name, length, status >> 16);
error:
++sky2->net_stats.rx_errors;
Any thoughts on how to solve this ?
Further testing shows that sometimes there are packets without the
GMR_FS_VLAN bit set which have a 4 bytes length difference, has shown
by this log excerpt:
sky2 eth4: rx length mismatch: length 243 != 247
sky2 eth4: rx error, status 0xf70300 length 243
For debugging purposes, I here is the little program with
excerpts from sky2.c I use to see what bits are set in the status field:
#include <sys/types.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
enum {
GMR_FS_LEN = 0xffff<<16, /* Bit 31..16: Rx Frame Length */
GMR_FS_VLAN = 1<<13, /* VLAN Packet */
GMR_FS_JABBER = 1<<12, /* Jabber Packet */
GMR_FS_UN_SIZE = 1<<11, /* Undersize Packet */
GMR_FS_MC = 1<<10, /* Multicast Packet */
GMR_FS_BC = 1<<9, /* Broadcast Packet */
GMR_FS_RX_OK = 1<<8, /* Receive OK (Good Packet) */
GMR_FS_GOOD_FC = 1<<7, /* Good Flow-Control Packet */
GMR_FS_BAD_FC = 1<<6, /* Bad Flow-Control Packet */
GMR_FS_MII_ERR = 1<<5, /* MII Error */
GMR_FS_LONG_ERR = 1<<4, /* Too Long Packet */
GMR_FS_FRAGMENT = 1<<3, /* Fragment */
GMR_FS_CRC_ERR = 1<<1, /* CRC Error */
GMR_FS_RX_FF_OV = 1<<0, /* Rx FIFO Overflow */
GMR_FS_ANY_ERR = GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR |
GMR_FS_FRAGMENT | GMR_FS_LONG_ERR |
GMR_FS_MII_ERR | GMR_FS_BAD_FC |
GMR_FS_UN_SIZE | GMR_FS_JABBER,
};
struct bitdesc {
const char *name;
u_int32_t field;
};
struct bitdesc bits[] = {
{ "GMR_FS_VLAN", 1 << 13 },
{ "GMR_FS_JABBER", 1 << 12 },
{ "GMR_FS_UN_SIZE", 1 << 11 },
{ "GMR_FS_MC", 1 << 10 },
{ "GMR_FS_BC", 1 << 9 },
{ "GMR_FS_RX_OK", 1 << 8 },
{ "GMR_FS_GOOD_FC", 1 << 7 },
{ "GMR_FS_BAD_FC", 1 << 6 },
{ "GMR_FS_MII_ERR", 1 << 5 },
{ "GMR_FS_LONG_ERR", 1 << 4 },
{ "GMR_FS_FRAGMENT", 1 << 3 },
{ "GMR_FS_CRC_ERR", 1 << 1 },
{ "GMR_FS_RX_FF_OV", 1 << 0 }
};
int
main(int argc, const char *argv[])
{
int status;
int i;
if (argc < 2)
return (1);
status = strtol(argv[1], NULL, 16);
printf("status: 0x%08x\n", status);
if (status & GMR_FS_ANY_ERR)
printf("packet has an error\n");
printf("length: %u\n", status >> 16);
for (i = 0; i < (sizeof(bits) / sizeof(bits[0])); i++) {
if (status & bits[i].field) {
printf("has bit %s\n", bits[i].name);
}
}
return (0);
}
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: sky2.c: length mismatch errors with vlan frames
2007-09-10 14:35 sky2.c: length mismatch errors with vlan frames Pierre-Yves Ritschard
@ 2007-09-11 8:10 ` Stephen Hemminger
2007-09-11 9:46 ` [PATCH] " Pierre-Yves Ritschard
0 siblings, 1 reply; 4+ messages in thread
From: Stephen Hemminger @ 2007-09-11 8:10 UTC (permalink / raw)
To: Pierre-Yves Ritschard; +Cc: netdev
On Mon, 10 Sep 2007 16:35:38 +0200
Pierre-Yves Ritschard <pyritschard@echo.fr> wrote:
> Hi list,
>
> I have been running recent linux kernel on nexcom NSA 1086's equipped
> with sysconnect NICs.
>
> Like some people previously have on this list I am running into
> problems with these NICs and seeing frequent errors in my dmesg:
>
> sky2 eth4: rx error, status 0x402300 length 60
> printk: 17 messages suppressed.
> sky2 eth4: rx error, status 0x402300 length 60
> printk: 32 messages suppressed.
> sky2 eth4: rx error, status 0x602300 length 92
> printk: 25 messages suppressed.
> sky2 eth4: rx error, status 0x6e2300 length 106
> printk: 16 messages suppressed.
> sky2 eth4: rx error, status 0x402300 length 60
> printk: 10 messages suppressed.
> sky2 eth4: rx error, status 0x402300 length 60
> printk: 17 messages suppressed.
> sky2 eth4: rx error, status 0x402300 length 60
>
>
> I have investigated a bit and status doesn't match any of the errors in
> GMR_FS_ANY_ERR.
> The block generating the error is now len_mismatch, due to the fact
> that on packets having the GMR_FS_VLAN bit set, the length argument to
> sky2_receive is 4 bytes shorter that the 16 bit value in status (status
> ``right shift'' 16).
>
> Since both these values are read from the card I don't know how to
> solve this other than by incrementing the length arg by 4 when
> GMR_FS_VLAN is set in status. So here's a diff that does this, although
> I'm not sure its an elegant solution:
>
My bad, I hadn't tested VLAN acceleration code in a while so must
have broken it when more error checking was added.
Your fix looks right. Could you format properly for kernel patch inclusion.
Also, instead of hard coding 4, please use VLAN_HLEN.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] sky2.c: length mismatch errors with vlan frames
2007-09-11 8:10 ` Stephen Hemminger
@ 2007-09-11 9:46 ` Pierre-Yves Ritschard
2007-09-11 9:50 ` Pierre-Yves Ritschard
0 siblings, 1 reply; 4+ messages in thread
From: Pierre-Yves Ritschard @ 2007-09-11 9:46 UTC (permalink / raw)
To: netdev
> My bad, I hadn't tested VLAN acceleration code in a while so must
> have broken it when more error checking was added.
>
I did check without vlans and the messages don't appear so it seems
to be working correctly. When vlans are enabled I do receive a few
frames that have the length difference but not the GMR_FS_VLAN bit
set, since there's high traffic on the interfaces it might be a
firmware bug that is triggered sometimes (running with my patch the
occurences are about 10/hour).
> Your fix looks right. Could you format properly for kernel patch
> inclusion. Also, instead of hard coding 4, please use VLAN_HLEN.
Since the snippet became a patch, here goes:
Signed-off-by: Pierre-Yves Ritschard <pyr@spootnik.org>
--- linux-2.6.22.6/drivers/net/sky2.c.orig 2007-09-10
15:34:15.000000000 +0200 +++ linux-2.6.22.6/drivers/net/sky2.c
2007-09-11 11:38:54.000000000 +0200 @@ -2059,6 +2059,9 @@ static struct
sk_buff *sky2_receive(stru sky2->rx_next = (sky2->rx_next + 1) %
sky2->rx_pending; prefetch(sky2->rx_ring + sky2->rx_next);
+ if (status & GMR_FS_VLAN)
+ length += VLAN_HLEN;
+
if (status & GMR_FS_ANY_ERR)
goto error;
@@ -2081,6 +2084,8 @@ len_mismatch:
/* Truncation of overlength packets
causes PHY length to not match MAC length */
++sky2->net_stats.rx_length_errors;
+ printk(KERN_INFO PFX "%s: rx length mismatch: length %d !=
%d\n",
+ dev->name, length, status >> 16);
error:
++sky2->net_stats.rx_errors;
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] sky2.c: length mismatch errors with vlan frames
2007-09-11 9:46 ` [PATCH] " Pierre-Yves Ritschard
@ 2007-09-11 9:50 ` Pierre-Yves Ritschard
0 siblings, 0 replies; 4+ messages in thread
From: Pierre-Yves Ritschard @ 2007-09-11 9:50 UTC (permalink / raw)
To: netdev
On Tue, 11 Sep 2007 11:46:44 +0200
Pierre-Yves Ritschard <pyritschard@echo.fr> wrote:
> > My bad, I hadn't tested VLAN acceleration code in a while so must
> > have broken it when more error checking was added.
> >
> I did check without vlans and the messages don't appear so it seems
> to be working correctly. When vlans are enabled I do receive a few
> frames that have the length difference but not the GMR_FS_VLAN bit
> set, since there's high traffic on the interfaces it might be a
> firmware bug that is triggered sometimes (running with my patch the
> occurences are about 10/hour).
>
> > Your fix looks right. Could you format properly for kernel patch
> > inclusion. Also, instead of hard coding 4, please use VLAN_HLEN.
>
> Since the snippet became a patch, here goes:
>
> Signed-off-by: Pierre-Yves Ritschard <pyr@spootnik.org>
>
The patch was mangled by my mailer, sorry about that:
Signed-off-by: Pierre-Yves Ritschard <pyr@spootnik.org>
--- linux-2.6.22.6/drivers/net/sky2.c.orig 2007-09-10 15:34:15.000000000 +0200
+++ linux-2.6.22.6/drivers/net/sky2.c 2007-09-11 11:38:54.000000000 +0200
@@ -2059,6 +2059,9 @@ static struct sk_buff *sky2_receive(stru
sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
prefetch(sky2->rx_ring + sky2->rx_next);
+ if (status & GMR_FS_VLAN)
+ length += VLAN_HLEN;
+
if (status & GMR_FS_ANY_ERR)
goto error;
@@ -2081,6 +2084,8 @@ len_mismatch:
/* Truncation of overlength packets
causes PHY length to not match MAC length */
++sky2->net_stats.rx_length_errors;
+ printk(KERN_INFO PFX "%s: rx length mismatch: length %d != %d\n",
+ dev->name, length, status >> 16);
error:
++sky2->net_stats.rx_errors;
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2007-09-11 9:50 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-10 14:35 sky2.c: length mismatch errors with vlan frames Pierre-Yves Ritschard
2007-09-11 8:10 ` Stephen Hemminger
2007-09-11 9:46 ` [PATCH] " Pierre-Yves Ritschard
2007-09-11 9:50 ` Pierre-Yves Ritschard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).