summaryrefslogtreecommitdiffstats
path: root/src/net/fcoe.c
diff options
context:
space:
mode:
authorMichael Brown2010-09-15 06:00:44 +0200
committerMichael Brown2010-09-15 06:11:28 +0200
commit6574c55e27f352336252c663376a7b3b6a6dae23 (patch)
tree948215c5f22a8b029165363abcc70ca5f5581aad /src/net/fcoe.c
parent[netdevice] Report network-layer errors via network device statistics (diff)
downloadipxe-6574c55e27f352336252c663376a7b3b6a6dae23.tar.gz
ipxe-6574c55e27f352336252c663376a7b3b6a6dae23.tar.xz
ipxe-6574c55e27f352336252c663376a7b3b6a6dae23.zip
[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>
Diffstat (limited to 'src/net/fcoe.c')
-rw-r--r--src/net/fcoe.c33
1 files 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 <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 ),
+};