david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[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 <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2010-09-15 05:00:44 +01:00
parent 85a3169967
commit 6574c55e27
1 changed files with 29 additions and 4 deletions

View File

@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/xfer.h>
#include <ipxe/netdevice.h>
#include <ipxe/features.h>
#include <ipxe/errortab.h>
#include <ipxe/crc32.h>
#include <ipxe/fc.h>
#include <ipxe/fcoe.h>
@ -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 ),
};