summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/phantom/phantom.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/net/phantom/phantom.c')
-rw-r--r--src/drivers/net/phantom/phantom.c43
1 files changed, 28 insertions, 15 deletions
diff --git a/src/drivers/net/phantom/phantom.c b/src/drivers/net/phantom/phantom.c
index 93675e3f..93fc0790 100644
--- a/src/drivers/net/phantom/phantom.c
+++ b/src/drivers/net/phantom/phantom.c
@@ -1445,9 +1445,20 @@ static void phantom_poll ( struct net_device *netdev ) {
/* Check received opcode */
sds_opcode = NX_GET ( sds, opcode );
- switch ( sds_opcode ) {
- case UNM_RXPKT_DESC:
- case UNM_SYN_OFFLOAD:
+ if ( ( sds_opcode == UNM_RXPKT_DESC ) ||
+ ( sds_opcode == UNM_SYN_OFFLOAD ) ) {
+
+ /* Sanity check: ensure that all of the SDS
+ * descriptor has been written.
+ */
+ if ( NX_GET ( sds, total_length ) == 0 ) {
+ DBGC ( phantom, "Phantom %p port %d SDS %d "
+ "incomplete; deferring\n", phantom,
+ phantom_port->port, sds_consumer_idx );
+ /* Leave for next poll() */
+ break;
+ }
+
/* Process received packet */
sds_handle = NX_GET ( sds, handle );
iobuf = phantom_port->rds_iobuf[sds_handle];
@@ -1459,25 +1470,27 @@ static void phantom_poll ( struct net_device *netdev ) {
phantom, phantom_port->port, sds_handle );
netdev_rx ( netdev, iobuf );
phantom_port->rds_iobuf[sds_handle] = NULL;
- break;
- default:
+
+ /* Update RDS consumer counter. This is a
+ * lower bound for the number of descriptors
+ * that have been read by the hardware, since
+ * the hardware must have read at least one
+ * descriptor for each completion that we
+ * receive.
+ */
+ rds_consumer_idx =
+ ( ( rds_consumer_idx + 1 ) % PHN_NUM_RDS );
+ phantom_port->rds_consumer_idx = rds_consumer_idx;
+
+ } else {
+
DBGC ( phantom, "Phantom %p port %d unexpected SDS "
"opcode %02x\n",
phantom, phantom_port->port, sds_opcode );
DBGC_HDA ( phantom, virt_to_bus ( sds ),
sds, sizeof ( *sds ) );
- break;
}
- /* Update RDS consumer counter. This is a lower bound
- * for the number of descriptors that have been read
- * by the hardware, since the hardware must have read
- * at least one descriptor for each completion that we
- * receive.
- */
- rds_consumer_idx = ( ( rds_consumer_idx + 1 ) % PHN_NUM_RDS );
- phantom_port->rds_consumer_idx = rds_consumer_idx;
-
/* Clear status descriptor */
memset ( sds, 0, sizeof ( *sds ) );