From 6574c55e27f352336252c663376a7b3b6a6dae23 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 15 Sep 2010 05:00:44 +0100 Subject: [PATCH] [fcoe] Disambiguate the various error cases and add a CRC failure message It seems as though several drivers neglect to strip the Ethernet CRC, which will cause the FCoE footer to be misplaced and result (coincidentally) in an "invalid CRC" error from FCoE. Add a human-visible message indicating this, to aid in diagnosis. Signed-off-by: Michael Brown --- src/net/fcoe.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/net/fcoe.c b/src/net/fcoe.c index a5bed373..64dd2639 100644 --- a/src/net/fcoe.c +++ b/src/net/fcoe.c @@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include #include #include @@ -41,6 +42,20 @@ FILE_LICENCE ( GPL2_OR_LATER ); FEATURE ( FEATURE_PROTOCOL, "FCoE", DHCP_EB_FEATURE_FCOE, 1 ); +/* Disambiguate the various error causes */ +#define EINVAL_UNDERLENGTH __einfo_error ( EINFO_EINVAL_UNDERLENGTH ) +#define EINFO_EINVAL_UNDERLENGTH \ + __einfo_uniqify ( EINFO_EINVAL, 0x01, "Underlength packet" ) +#define EINVAL_SOF __einfo_error ( EINFO_EINVAL_SOF ) +#define EINFO_EINVAL_SOF \ + __einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid SoF delimiter" ) +#define EINVAL_CRC __einfo_error ( EINFO_EINVAL_CRC ) +#define EINFO_EINVAL_CRC \ + __einfo_uniqify ( EINFO_EINVAL, 0x03, "Invalid CRC (not stripped?)" ) +#define EINVAL_EOF __einfo_error ( EINFO_EINVAL_EOF ) +#define EINFO_EINVAL_EOF \ + __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid EoF delimiter" ) + /** An FCoE port */ struct fcoe_port { /** Reference count */ @@ -171,7 +186,7 @@ static int fcoe_rx ( struct io_buffer *iobuf, if ( iob_len ( iobuf ) < ( sizeof ( *fcoehdr ) + sizeof ( *fcoeftr ) )){ DBGC ( fcoe, "FCoE %s received under-length frame (%zd " "bytes)\n", fcoe->netdev->name, iob_len ( iobuf ) ); - rc = -EINVAL; + rc = -EINVAL_UNDERLENGTH; goto done; } @@ -192,21 +207,21 @@ static int fcoe_rx ( struct io_buffer *iobuf, ( fcoehdr->sof == FCOE_SOF_N3 ) ) ) { DBGC ( fcoe, "FCoE %s received unsupported start-of-frame " "delimiter %02x\n", fcoe->netdev->name, fcoehdr->sof ); - rc = -EINVAL; + rc = -EINVAL_SOF; goto done; } if ( ( le32_to_cpu ( fcoeftr->crc ) ^ ~((uint32_t)0) ) != crc32_le ( ~((uint32_t)0), iobuf->data, iob_len ( iobuf ) ) ) { DBGC ( fcoe, "FCoE %s received invalid CRC\n", fcoe->netdev->name ); - rc = -EINVAL; + rc = -EINVAL_CRC; goto done; } if ( ! ( ( fcoeftr->eof == FCOE_EOF_N ) || ( fcoeftr->eof == FCOE_EOF_T ) ) ) { DBGC ( fcoe, "FCoE %s received unsupported end-of-frame " "delimiter %02x\n", fcoe->netdev->name, fcoeftr->eof ); - rc = -EINVAL; + rc = -EINVAL_EOF; goto done; } @@ -381,3 +396,13 @@ struct net_protocol fcoe_protocol __net_protocol = { .net_proto = htons ( ETH_P_FCOE ), .rx = fcoe_rx, }; + +/** Human-readable message for CRC errors + * + * It seems as though several drivers neglect to strip the Ethernet + * CRC, which will cause the FCoE footer to be misplaced and result + * (coincidentally) in an "invalid CRC" error from FCoE. + */ +struct errortab fcoe_errors[] __errortab = { + __einfo_errortab ( EINFO_EINVAL_CRC ), +};