[ofw] [VNIC] Added suppot for ipv6 checksum offload

Alex Estrin alex.estrin at qlogic.com
Mon Feb 11 05:52:53 PST 2008


> >Also included
> >fix for potential netpath null dereference,
> >fix for control path potential flaw,
> >fix for LBFO primary adapter failover.
> >For complete list of changes please see repository log.
> 
> Can you please resend the patch inline as text, and include the proper
> change
> logs?
> 
> - Sean

Added support for ipv6 checksum offload.
- fixed potential netpath null dereference
- fixed control path initialization potential flaw,
- simplified LBFO a bit and removed NdisMRemoveMiniport since 
  it breaks adapter reset-reinitialization.
- removed cmd reset request (doesn't make sense when path is broken).
- hung flag set change
- debug messages, replace some macros with inline funcs, some code
cleanup and formatting.
INF changes
 - fixed service name.
 - mtu payload size can be modified in 100 bytes increments( was 500).

Please review

Index: ulp/qlc_vnic/kernel/netvnic.inf
===================================================================
--- ulp/qlc_vnic/kernel/netvnic.inf	(revision 932)
+++ ulp/qlc_vnic/kernel/netvnic.inf	(working copy)
@@ -80,7 +80,7 @@
 qlc_vnic.sys,,,2
 
 [vnic.AddReg]
-HKR, Ndi,                       Service,    0, "qlc_vnic"
+HKR, Ndi,                       Service,    0, "vnic"
 HKR, Ndi\Interfaces,            UpperRange, 0, "ndis5"
 HKR, Ndi\Interfaces,            LowerRange, 0, "ethernet"
 
@@ -106,7 +106,7 @@
 HKR, Ndi\Params\PayloadMtu,       Default,        0, "1500"
 HKR, Ndi\Params\PayloadMtu,       Min,            0, "1500"
 HKR, Ndi\Params\PayloadMtu,       Max,            0, "9500"
-HKR, Ndi\Params\PayloadMtu,       Step,           0, "500"
+HKR, Ndi\Params\PayloadMtu,       Step,           0, "100"
 HKR, Ndi\Params\PayloadMtu,       Base,           0, "10"
 
 HKR, Ndi\Params\UseTxCsum,        ParamDesc,      0, "Send Chksum
Offload"
Index: ulp/qlc_vnic/kernel/SOURCES
===================================================================
--- ulp/qlc_vnic/kernel/SOURCES	(revision 932)
+++ ulp/qlc_vnic/kernel/SOURCES	(working copy)
@@ -51,8 +51,13 @@
 INCLUDES=..;..\..\..\inc;..\..\..\inc\kernel;
 
 C_DEFINES=$(C_DEFINES) -DNDIS_MINIPORT_DRIVER -DNDIS_WDM=1 \
-	-DDEPRECATE_DDK_FUNCTIONS -DNDIS51_MINIPORT
-DBINARY_COMPATIBLE=0 -DLBFO_ENABLED
+	-DDEPRECATE_DDK_FUNCTIONS -DNDIS51_MINIPORT
-DBINARY_COMPATIBLE=0 -DLBFO_ENABLED=1
 
+#!if $(FREEBUILD)
+#  Free build will printout error messages
+#C_DEFINES=$(C_DEFINES) -DFREE_BUILD_DBG=1
+#!endif
+
 TARGETLIBS= \
 	$(DDK_LIB_PATH)\ntoskrnl.lib \
 	$(DDK_LIB_PATH)\hal.lib		\
Index: ulp/qlc_vnic/kernel/vnic_adapter.c
===================================================================
--- ulp/qlc_vnic/kernel/vnic_adapter.c	(revision 932)
+++ ulp/qlc_vnic/kernel/vnic_adapter.c	(working copy)
@@ -121,7 +121,7 @@
 __adapter_cleanup(
 	IN	vnic_adapter_t		*p_adapter );
 
-#if defined( LBFO_ENABLED )
+#if ( LBFO_ENABLED )
 
 static NDIS_STATUS
 __adapter_set_failover_primary(
@@ -221,7 +221,7 @@
 	/* set adapter level params here */
 	p_adapter->vlan_info = p_adapter->params.VlanInfo;
 
-#if defined (LBFO_ENABLED)
+#if ( LBFO_ENABLED )
 
 	p_adapter->failover.bundle_id = p_adapter->params.bundle_id;
 	p_adapter->failover.fo_state = _ADAPTER_NOT_BUNDLED;
@@ -264,7 +264,7 @@
 
 	_adapter_close_ca( p_adapter );
 
-#if defined( LBFO_ENABLED )
+#if ( LBFO_ENABLED )
 
 	__adapter_remove_from_failover_list( p_adapter );
 
@@ -567,7 +567,7 @@
 	p_params->ViportHbInterval = ( status != NDIS_STATUS_SUCCESS ) ?
 		VIPORT_HEARTBEAT_INTERVAL :
p_reg_prm->ParameterData.IntegerData;
 
-#if defined(LBFO_ENABLED)
+#if ( LBFO_ENABLED )
 	/* read Failover group Name/Number */
 
 	RtlInitUnicodeString( &keyword, L"BundleId" );
@@ -657,8 +657,8 @@
 	NdisZeroMemory( p_viport, sizeof(viport_t) );
 	NdisAllocateSpinLock( &p_viport->lock );
 	InitializeListHead( &p_viport->listPtrs );
-	KeInitializeEvent( &p_viport->sync_event, SynchronizationEvent,
FALSE );
-
+	cl_event_init( &p_viport->sync_event, FALSE );
+	
 	p_viport->p_adapter = p_adapter;
 	viport_config_defaults ( p_viport );
 
@@ -975,7 +975,7 @@
 	vnic_path_record_t		*p_path_record;
 	Netpath_t*				p_netpath = NULL;
 
-#if defined( LBFO_ENABLED )
+#if ( LBFO_ENABLED )
 	vnic_adapter_t			*p_primary_adapter;	
 #endif
 
@@ -1050,15 +1050,6 @@
 					netpath_linkDown(
p_adapter->p_currentPath );
 					__pending_queue_cleanup(
p_adapter );
 				}
-				/*
-				if( p_adapter->p_currentPath ==
&p_adapter->primaryPath )
-					p_netpath =
&p_adapter->secondaryPath;
-				else
-					p_netpath =
&p_adapter->primaryPath;
-
-				netpath_free( p_adapter->p_currentPath
);
-				netpath_free( p_netpath );
-				*/
 			}
 			break;
 
@@ -1112,14 +1103,12 @@
 				break;
 			}
 
-			if( ( InterlockedCompareExchange( (volatile LONG
*)&p_adapter->state,	
-						INIC_REGISTERED,
INIC_UNINITIALIZED ) == INIC_UNINITIALIZED )
-#if defined( LBFO_ENABLED )
-						|| (
p_adapter->failover.fo_state == _ADAPTER_NOT_BUNDLED )
-#endif
-				)
+			InterlockedCompareExchange( (volatile LONG
*)&p_adapter->state,	
+
INIC_REGISTERED, INIC_UNINITIALIZED );
+#if ( LBFO_ENABLED )
+
+			if( p_adapter->failover.fo_state ==
_ADAPTER_NOT_BUNDLED )
 			{
-#if defined( LBFO_ENABLED )
 				/* we don't look for zero id, since it
meant to be primary by default */
 				if( p_adapter->failover.bundle_id != 0
&& 
 					( p_primary_adapter =
__adapter_find_on_failover_list( _ADAPTER_PRIMARY,
@@ -1134,8 +1123,10 @@
 					/* bundle_id '0' , all go to
primary */
 					__adapter_set_failover_primary(
p_adapter, FALSE );
 				}
-#endif // LBFO_ENABLED
 			}
+
+#endif // LBFO_ENABLED
+
 			break;
 
 		case IB_PNP_IOC_PATH_REMOVE:
@@ -1323,7 +1314,7 @@
 	
 	if( p_adapter->pnp_state != IB_PNP_IOC_REMOVE )
 	{
-
+		p_adapter->pnp_state = IB_PNP_IOC_ADD;
 		/* Register for IOC events */
 		pnp_req.pfn_pnp_cb = __vnic_pnp_cb;
 		pnp_req.pnp_class = IB_PNP_IOC | IB_PNP_FLAG_REG_SYNC;
@@ -1368,25 +1359,26 @@
 		return IB_INVALID_STATE;
 
 	p_adapter->reset = TRUE;
+	p_adapter->hung = 0;
 
+#if ( LBFO_ENABLED )
 	__adapter_remove_from_failover_list( p_adapter );
 
+#endif // LBFO_ENABLED
+
 	if( p_adapter->h_pnp )
 	{
 		h_pnp = p_adapter->h_pnp;
 		p_adapter->h_pnp  = NULL;
-
-		p_adapter->hung = 0;
 		status = p_adapter->ifc.dereg_pnp( h_pnp,
__vnic_pnp_dereg_cb );
+		if( status == IB_SUCCESS )
+			status = IB_NOT_DONE;
 	}
 	else
 	{
 		status = IB_NOT_FOUND;
 	}
-
-	if( status == IB_SUCCESS )
-		status = IB_NOT_DONE;
-
+	
 	VNIC_EXIT( VNIC_DBG_INIT );
 	return status;
 }
@@ -1623,7 +1615,10 @@
 			p_viport->p_netpath->instance,
 			netpath_to_string( p_viport->p_netpath ) ));
 
-	p_adapter->num_paths++;
+	if( p_viport->state == VIPORT_CONNECTED )
+	{
+		p_adapter->num_paths++;
+	}
 
 	if( p_adapter->num_paths > 1 &&
 		p_viport->p_netpath != p_adapter->p_currentPath )
@@ -1651,7 +1646,7 @@
 	return ib_status;
 }
 
-#if defined( LBFO_ENABLED )
+#if ( LBFO_ENABLED )
 
 static void
 __adapter_add_to_failover_list(
@@ -1692,8 +1687,7 @@
 	if( lbfo_state == _ADAPTER_PRIMARY )
 	{
 		cl_qlist_remove_item( &g_vnic.primary_list,
&p_adapter->list_item );
-		NdisMRemoveMiniport( p_adapter->h_handle );
-
+	
 		/* search for secondary adapter with same id && (id != 0
) */
 		if( bundle_id != 0 )
 		{
@@ -1702,8 +1696,8 @@
 		
 			if( p_adapter_to_promote &&
 				p_adapter_to_promote->pnp_state !=
IB_PNP_IOC_REMOVE &&
-				( p_adapter_to_promote->reset == FALSE
|| 
-				p_adapter_to_promote->hung  <
p_adapter_to_promote->num_paths ) )
+				p_adapter_to_promote->state ==
INIC_REGISTERED &&
+				p_adapter_to_promote->reset == FALSE )
 			{
 				/* a small recursion */
 				__adapter_set_failover_primary(
p_adapter_to_promote, TRUE );
@@ -1717,9 +1711,11 @@
 				("IOC[%d]  LBFO bundle %d Secondary
Adapter Removed\n", 
 				p_adapter->ioc_num,
p_adapter->failover.bundle_id ));
 	}
-	else
-		VNIC_TRACE( VNIC_DBG_ERROR,
+	else if( lbfo_state == _ADAPTER_NOT_BUNDLED )
+	{
+		VNIC_TRACE( VNIC_DBG_INFO,
 		("IOC[%d] Adapter not bundled\n", p_adapter->ioc_num ));
+	}
 
 	return;
 }
Index: ulp/qlc_vnic/kernel/vnic_adapter.h
===================================================================
--- ulp/qlc_vnic/kernel/vnic_adapter.h	(revision 932)
+++ ulp/qlc_vnic/kernel/vnic_adapter.h	(working copy)
@@ -139,7 +139,7 @@
 	struct Netpath			secondaryPath;
 	struct Netpath			*p_currentPath;
 	vnic_params_t			params;
-	int						num_paths;
+	uint32_t				num_paths;
 	int						macSet;
 	int						mc_count;
 	mac_addr_t				mcast_array[MAX_MCAST];
@@ -149,7 +149,7 @@
 	uint32_t				link_speed;
 	uint32_t				packet_filter;
 	uint32_t				vlan_info;
-	int						hung;
+	uint32_t				hung;
 	BOOLEAN					reset;
 	BOOLEAN					pending_set;
 	BOOLEAN					pending_query;
@@ -157,7 +157,7 @@
 	pending_oid_t			set_oid;
 	ib_svc_entry_t			svc_entries[2];
 
-#if defined( LBFO_ENABLED )
+#if ( LBFO_ENABLED )
 	lbfo_failover_t			failover;
 #endif
 #ifdef VNIC_STATISTIC
Index: ulp/qlc_vnic/kernel/vnic_config.h
===================================================================
--- ulp/qlc_vnic/kernel/vnic_config.h	(revision 932)
+++ ulp/qlc_vnic/kernel/vnic_config.h	(working copy)
@@ -191,7 +191,7 @@
 typedef struct _vnic_globals {
 	NDIS_HANDLE			ndis_handle; // ndis wrapper
handle
 	NDIS_SPIN_LOCK		lock;
-#if defined (LBFO_ENABLED)
+#if ( LBFO_ENABLED )
 	cl_qlist_t			primary_list;
 	cl_qlist_t			secondary_list;
 #endif
Index: ulp/qlc_vnic/kernel/vnic_control.c
===================================================================
--- ulp/qlc_vnic/kernel/vnic_control.c	(revision 932)
+++ ulp/qlc_vnic/kernel/vnic_control.c	(working copy)
@@ -1236,9 +1236,10 @@
 			return;
 	}
 
-	if( (pCHdr->pktSeqNum != pControl->seqNum) ||
-		!InterlockedExchange( (volatile
LONG*)&pControl->rspExpected, FALSE ) )
+	if( !InterlockedExchange( (volatile
LONG*)&pControl->rspExpected, FALSE ) )
 	{
+		VNIC_TRACE_EXIT( VNIC_DBG_ERROR,
+			("UNEXPECTED RSP Packet CMD: %d\n",
pCHdr->pktCmd ) );
 		return;
 	}
 
@@ -1410,12 +1411,10 @@
 control_send(
 	IN		Control_t		*pControl )
 {
-	ib_api_status_t	ib_status;
 	Inic_ControlPacket_t *pPkt = control_packet(&pControl->sendIo);
 
 	VNIC_ENTER ( VNIC_DBG_CTRL );
 
-	//ASSERT( !pControl->reqOutstanding );
 	if ( InterlockedCompareExchange( (volatile
LONG*)&pControl->reqOutstanding,
 
TRUE, FALSE ) == TRUE )
 	{
@@ -1425,14 +1424,12 @@
 		 */
 		VNIC_TRACE_EXIT( VNIC_DBG_ERROR,
 			("IB Send never completed\n" ) );
-		viport_failure( pControl->p_viport );
-		return IB_ERROR;
+		goto failure;
 	}
 
 #ifdef _DEBUG_
 	//__control_logControlPacket( pPkt );
 #endif
-
 	InterlockedExchange( (volatile LONG*)&pControl->rspExpected,
 
(LONG)pPkt->hdr.pktCmd );
 
@@ -1442,18 +1439,23 @@
 	pControl->statistics.requestTime = cl_get_time_stamp();
 #endif /* VNIC_STATISTIC */
 
-	ib_status = ibqp_postSend( &pControl->qp, &pControl->sendIo.io
);
-	if( ib_status != IB_SUCCESS )
+	if( ( ibqp_postSend( &pControl->qp, &pControl->sendIo.io )) !=
IB_SUCCESS )
 	{
 		InterlockedExchange((volatile
LONG*)&pControl->reqOutstanding, FALSE );
 
 		VNIC_TRACE( VNIC_DBG_ERROR,
 			("IOC %d: Failed to post send\n",
pControl->p_viport->ioc_num ) );
-		viport_failure( pControl->p_viport );
+		goto failure;
 	}
+	
+	VNIC_EXIT( VNIC_DBG_CTRL );
+	return IB_SUCCESS;
 
+failure:
+	pControl->p_viport->p_adapter->hung++;
+	viport_failure( pControl->p_viport );
 	VNIC_EXIT( VNIC_DBG_CTRL );
-	return ib_status;
+	return IB_ERROR;
 }
 
 
@@ -1583,7 +1585,6 @@
 			VNIC_TRACE( VNIC_DBG_ERROR,
 				("IOC %d: Control packet retry
exceeded\n",
 
pControl->p_viport->ioc_num ) );
-			viport_failure(pControl->p_viport );
 		}
 		else
 		{
Index: ulp/qlc_vnic/kernel/vnic_data.c
===================================================================
--- ulp/qlc_vnic/kernel/vnic_data.c	(revision 932)
+++ ulp/qlc_vnic/kernel/vnic_data.c	(working copy)
@@ -609,7 +609,7 @@
 	{
 		pRdmaIo->p_trailer->txChksumFlags = 0;
 	}
-	pRdmaIo->p_trailer->connectionHashAndValid |= CHV_VALID;
+	pRdmaIo->p_trailer->connectionHashAndValid = CHV_VALID;
 
 	if( last )
 		pRdmaIo->p_trailer->pktFlags |= PF_KICK;
@@ -664,18 +664,27 @@
 		packet_info = PtrToUlong(
NDIS_PER_PACKET_INFO_FROM_PACKET( p_packet, TcpIpChecksumPacketInfo));
 		p_packet_info = ( NDIS_TCP_IP_CHECKSUM_PACKET_INFO
*)&packet_info;
 
-		if( p_packet_info &&
-			p_packet_info->Transmit.NdisPacketChecksumV4 )
+		if( p_packet_info )
 		{
-			txChksumFlags = TX_CHKSUM_FLAGS_CHECKSUM_V4
-			| ( p_packet_info->Transmit.NdisPacketIpChecksum
? TX_CHKSUM_FLAGS_IP_CHECKSUM: 0 )
-			| (
p_packet_info->Transmit.NdisPacketTcpChecksum ?
TX_CHKSUM_FLAGS_TCP_CHECKSUM: 0 )
-			| (
p_packet_info->Transmit.NdisPacketUdpChecksum ?
TX_CHKSUM_FLAGS_UDP_CHECKSUM: 0 );
+			if( p_packet_info->Transmit.NdisPacketChecksumV4
)
+			{
+				txChksumFlags =
TX_CHKSUM_FLAGS_CHECKSUM_V4
+				| (
p_packet_info->Transmit.NdisPacketIpChecksum ?
TX_CHKSUM_FLAGS_IP_CHECKSUM: 0 )
+				| (
p_packet_info->Transmit.NdisPacketTcpChecksum ?
TX_CHKSUM_FLAGS_TCP_CHECKSUM: 0 )
+				| (
p_packet_info->Transmit.NdisPacketUdpChecksum ?
TX_CHKSUM_FLAGS_UDP_CHECKSUM: 0 );
+			}
+			else if(
p_packet_info->Transmit.NdisPacketChecksumV6 )
+			{
+				txChksumFlags =
TX_CHKSUM_FLAGS_CHECKSUM_V6
+				| (
p_packet_info->Transmit.NdisPacketIpChecksum ?
TX_CHKSUM_FLAGS_IP_CHECKSUM: 0 )
+				| (
p_packet_info->Transmit.NdisPacketTcpChecksum ?
TX_CHKSUM_FLAGS_TCP_CHECKSUM: 0 )
+				| (
p_packet_info->Transmit.NdisPacketUdpChecksum ?
TX_CHKSUM_FLAGS_UDP_CHECKSUM: 0 );
+			}
 		}
 	}
 	
 	VNIC_TRACE( VNIC_DBG_DATA ,
-				("txChksumFlags = %d: V4 %c, V6 %c, IP
%c, TCP %c, UDP %c\n",
+		("txChksumFlags = %#x: V4 %c, V6 %c, IP %c, TCP %c, UDP
%c\n",
 				txChksumFlags,
 				((txChksumFlags &
TX_CHKSUM_FLAGS_CHECKSUM_V4 )? '+': '-'),
 				((txChksumFlags &
TX_CHKSUM_FLAGS_CHECKSUM_V6 )? '+': '-'),
@@ -1073,7 +1082,7 @@
 		rxChksumFlags = pTrailer->rxChksumFlags;
 
 		VNIC_TRACE( VNIC_DBG_DATA,
-			("rxChksumFlags = %d, LOOP = %c, IP = %c, TCP =
%c, UDP = %c\n",
+			("rxChksumFlags = %#x, LOOP = %c, IP = %c, TCP =
%c, UDP = %c\n",
 			rxChksumFlags,
 			(rxChksumFlags & RX_CHKSUM_FLAGS_LOOPBACK)? 'Y':
'N',
 			(rxChksumFlags &
RX_CHKSUM_FLAGS_IP_CHECKSUM_SUCCEEDED)? 'Y':
Index: ulp/qlc_vnic/kernel/vnic_driver.c
===================================================================
--- ulp/qlc_vnic/kernel/vnic_driver.c	(revision 932)
+++ ulp/qlc_vnic/kernel/vnic_driver.c	(working copy)
@@ -181,7 +181,7 @@
 		__vnic_read_machine_name();
 		__vnic_read_service_registry( p_registry_path );
 
-#if defined (LBFO_ENABLED)
+#if ( LBFO_ENABLED )
 		cl_qlist_init( &g_vnic.primary_list );
 		cl_qlist_init( &g_vnic.secondary_list );
 #endif
@@ -291,16 +291,24 @@
 	{
 		VNIC_TRACE( VNIC_DBG_ERROR,
 			("ib_reg_pnp returned %s\n",
p_adapter->ifc.get_err_str( ib_status )) );
+		NdisWriteErrorLogEntry( h_handle,
+			NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);
 		status = NDIS_STATUS_FAILURE;
-		goto failure;
 	}
+	else if( p_adapter->state != INIC_REGISTERED )
+	{
+		status = NDIS_STATUS_OPEN_FAILED;
+		*p_open_status = NDIS_STATUS_DEVICE_FAILED;
 
-	if( p_adapter->state != INIC_REGISTERED )
+		VNIC_TRACE( VNIC_DBG_ERROR,
+			("IOC[%d] ADAPTER Initialization Failed\n",
p_adapter->ioc_num ) );
+		NdisWriteErrorLogEntry( h_handle, 
+			NDIS_ERROR_CODE_HARDWARE_FAILURE, 1,
p_adapter->ioc_num );
+	}
+
+	if( status != NDIS_STATUS_SUCCESS )
 	{
-		status = NDIS_STATUS_FAILURE;
-failure:
 		vnic_destroy_adapter( p_adapter );
-		return status;
 	}
 
 	VNIC_EXIT( VNIC_DBG_INIT );
@@ -352,8 +360,9 @@
 	if( p_adapter->hung != 0 && 
 		p_adapter->hung >= p_adapter->num_paths )
 	{
-			VNIC_TRACE( VNIC_DBG_WARN, 
-				("IOC[%d] Adapter Hung\n",
p_adapter->ioc_num ));
+		VNIC_TRACE( VNIC_DBG_ERROR, 
+			("IOC[%d] Adapter Hung: %d NumPath: %d\n",
+			p_adapter->ioc_num,	p_adapter->hung,
p_adapter->num_paths ) );
 			return TRUE;
 	}
 
@@ -1088,7 +1097,6 @@
 	ULONG						buf_len;
 	uint32_t					enabled_TxCsum;
 	uint32_t					enabled_RxCsum;
-	viport_t					*p_viport;
 
 	buf_len = sizeof(NDIS_TASK_OFFLOAD_HEADER) +
 		sizeof(NDIS_TASK_OFFLOAD) +
@@ -1108,20 +1116,18 @@
 	{
 		return NDIS_STATUS_INVALID_DATA;
 	}
-	p_viport = p_adapter->p_currentPath->pViport;
-
 	/* too early, we didn't get response on CMD_INIT_INIC yet */
-	if( !p_viport || !viport_features( p_viport ) )
+	if( !netpath_is_connected( p_adapter->p_currentPath ) )
 	{
 		return NDIS_STATUS_NOT_ACCEPTED;
 	}
-
 	enabled_RxCsum = 
 		(uint32_t)( p_adapter->params.UseRxCsum && 
-					viport_canRxCsum(
p_adapter->p_currentPath->pViport ) );
+		netpath_canRxCsum( p_adapter->p_currentPath ) );
+
 	enabled_TxCsum = 
-		(uint32_t)( p_adapter->params.UseTxCsum && 
-					viport_canTxCsum(
p_adapter->p_currentPath->pViport ) );
+		(uint32_t)( p_adapter->params.UseTxCsum &&
+		netpath_canTxCsum( p_adapter->p_currentPath ) );
 
 	p_offload_hdr->OffsetFirstTask =
sizeof(NDIS_TASK_OFFLOAD_HEADER);
 	p_offload_task = (NDIS_TASK_OFFLOAD*)(p_offload_hdr + 1);
@@ -1145,15 +1151,15 @@
 	p_offload_chksum->V4Receive.UdpChecksum = enabled_RxCsum;
 	p_offload_chksum->V4Receive.IpChecksum = enabled_RxCsum;
 
-	p_offload_chksum->V6Transmit.IpOptionsSupported = FALSE;
-	p_offload_chksum->V6Transmit.TcpOptionsSupported = FALSE;
-	p_offload_chksum->V6Transmit.TcpChecksum = FALSE;
-	p_offload_chksum->V6Transmit.UdpChecksum = FALSE;
+	p_offload_chksum->V6Transmit.IpOptionsSupported =
enabled_TxCsum;
+	p_offload_chksum->V6Transmit.TcpOptionsSupported =
enabled_TxCsum;
+	p_offload_chksum->V6Transmit.TcpChecksum = enabled_TxCsum;
+	p_offload_chksum->V6Transmit.UdpChecksum = enabled_TxCsum;
 
-	p_offload_chksum->V6Receive.IpOptionsSupported = FALSE;
-	p_offload_chksum->V6Receive.TcpOptionsSupported = FALSE;
-	p_offload_chksum->V6Receive.TcpChecksum = FALSE;
-	p_offload_chksum->V6Receive.UdpChecksum = FALSE;
+	p_offload_chksum->V6Receive.IpOptionsSupported = enabled_RxCsum;
+	p_offload_chksum->V6Receive.TcpOptionsSupported =
enabled_RxCsum;
+	p_offload_chksum->V6Receive.TcpChecksum = enabled_RxCsum;
+	p_offload_chksum->V6Receive.UdpChecksum = enabled_RxCsum;
 
 	*(p_oid_info->p_bytes_used) = buf_len;
 
@@ -1175,6 +1181,11 @@
 
 	VNIC_ENTER( VNIC_DBG_OID );
 
+	if( !netpath_is_connected( p_adapter->p_currentPath ) )
+	{
+		return NDIS_STATUS_NOT_ACCEPTED;
+	}
+
 	p_offload_hdr = (NDIS_TASK_OFFLOAD_HEADER*)p_info_buf;
 
 	if( *p_info_len < sizeof(NDIS_TASK_OFFLOAD_HEADER) )
@@ -1211,16 +1222,22 @@
 		(NDIS_TASK_TCP_IP_CHECKSUM*)p_offload_task->TaskBuffer;
 
 	enabled_TxCsum = 
-		( p_adapter->params.UseTxCsum && viport_canTxCsum(
p_adapter->p_currentPath->pViport ) );
+		( p_adapter->params.UseTxCsum && 
+			netpath_canTxCsum( p_adapter->p_currentPath ) );
 	enabled_RxCsum = 
-		( p_adapter->params.UseRxCsum && viport_canRxCsum(
p_adapter->p_currentPath->pViport ) );
+		( p_adapter->params.UseRxCsum && 
+			netpath_canRxCsum( p_adapter->p_currentPath ) );
 	
 	if( !enabled_TxCsum &&
 		(p_offload_chksum->V4Transmit.IpOptionsSupported ||
 		p_offload_chksum->V4Transmit.TcpOptionsSupported ||
 		p_offload_chksum->V4Transmit.TcpChecksum ||
 		p_offload_chksum->V4Transmit.UdpChecksum ||
-		p_offload_chksum->V4Transmit.IpChecksum) )
+		p_offload_chksum->V4Transmit.IpChecksum ||
+		p_offload_chksum->V6Transmit.IpOptionsSupported ||
+		p_offload_chksum->V6Transmit.TcpOptionsSupported ||
+		p_offload_chksum->V6Transmit.TcpChecksum ||
+		p_offload_chksum->V6Transmit.UdpChecksum ) )
 	{
 		return NDIS_STATUS_NOT_SUPPORTED;
 	}
@@ -1230,22 +1247,15 @@
 		p_offload_chksum->V4Receive.TcpOptionsSupported ||
 		p_offload_chksum->V4Receive.TcpChecksum ||
 		p_offload_chksum->V4Receive.UdpChecksum ||
-		p_offload_chksum->V4Receive.IpChecksum) )
-	{
-		return NDIS_STATUS_NOT_SUPPORTED;
-	}
-
-	if( p_offload_chksum->V6Receive.IpOptionsSupported ||
+		p_offload_chksum->V4Receive.IpChecksum ||
+		p_offload_chksum->V6Receive.IpOptionsSupported ||
 		p_offload_chksum->V6Receive.TcpOptionsSupported ||
 		p_offload_chksum->V6Receive.TcpChecksum ||
-		p_offload_chksum->V6Receive.UdpChecksum  ||
-		p_offload_chksum->V6Transmit.IpOptionsSupported ||
-		p_offload_chksum->V6Transmit.TcpOptionsSupported ||
-		p_offload_chksum->V6Transmit.TcpChecksum ||
-		p_offload_chksum->V6Transmit.UdpChecksum )
+		p_offload_chksum->V6Receive.UdpChecksum ) )
 	{
 		return NDIS_STATUS_NOT_SUPPORTED;
 	}
+
 	VNIC_EXIT( VNIC_DBG_OID );
 
 	return NDIS_STATUS_SUCCESS;
@@ -1830,7 +1840,7 @@
 							&query_oid,
 							status,
 
p_netpath->p_adapter->mcast_array,
-							( sizeof(
p_netpath->p_adapter->mcast_array ) * sizeof( mac_addr_t ) ) );
+
p_adapter->mc_count * sizeof( mac_addr_t ) );
 			 break;
 		case OID_GEN_TRANSMIT_BUFFER_SPACE:
 			if( status == NDIS_STATUS_SUCCESS )
@@ -2020,7 +2030,8 @@
 		if( !( p_viport->flags & INIC_FLAG_ENABLE_NIC ) )
 		{
 			p_viport->newFlags &= ~INIC_FLAG_DISABLE_NIC;
-			p_viport->newFlags |= INIC_FLAG_ENABLE_NIC;
+			p_viport->newFlags |= INIC_FLAG_ENABLE_NIC |
INIC_FLAG_SET_MTU;
+			p_viport->newMtu =
(uint16_t)p_adapter->params.MinMtu;
 			InterlockedOr( (volatile LONG*)&need_updates,
NEED_LINK_CONFIG );
 		}
 
Index: ulp/qlc_vnic/kernel/vnic_ib.c
===================================================================
--- ulp/qlc_vnic/kernel/vnic_ib.c	(revision 932)
+++ ulp/qlc_vnic/kernel/vnic_ib.c	(working copy)
@@ -450,7 +450,8 @@
 				("Conn req reject status %d\n",
 						cl_ntoh16(
p_rej_rec->rej_status )) );
 	}
-	viport_failure( pQp->pViport );
+
+	pQp->pViport->p_adapter->hung++;
 	cl_event_signal( &pQp->pViport->sync_event );
 }
 
@@ -729,10 +730,10 @@
 	if ( ib_status != IB_SUCCESS )
 	{
 		VNIC_TRACE_EXIT( VNIC_DBG_ERROR,
-					("Send RTU failed\n") );
+			("Send RTU failed: status %#x\n", ib_status ) );
 err:
 		InterlockedExchange( &pQp->qpState, IB_DETACHED );
-		viport_failure( p_viport );
+		pQp->pViport->p_adapter->hung++;
 	}
 	else
 	{
Index: ulp/qlc_vnic/kernel/vnic_ib.h
===================================================================
--- ulp/qlc_vnic/kernel/vnic_ib.h	(revision 932)
+++ ulp/qlc_vnic/kernel/vnic_ib.h	(working copy)
@@ -181,30 +181,56 @@
 ibqp_construct(
 	IN	OUT		IbQp_t			*pQp,
 	IN			struct _viport	*pViport );
-ib_api_status_t ibqp_init(IbQp_t *pQp, uint64_t guid, struct IbConfig
*p_conf);
-ib_api_status_t ibqp_connect(IbQp_t *pQp);
-void    ibqp_detach(IbQp_t *pQp);
-void    ibqp_cleanup(IbQp_t *pQp);
-ib_api_status_t ibqp_postSend(IbQp_t *pQp, Io_t *pIo);
-ib_api_status_t ibqp_postRecv(IbQp_t *pQp, Io_t *pIo);
 
-uint8_t  ibca_findPortNum( struct _viport *p_viport, uint64_t guid );
+ib_api_status_t 
+ibqp_init(
+	IN		IbQp_t				*pQp, 
+	IN		uint64_t			guid,
+	IN	OUT	struct IbConfig		*p_conf);
 
+ib_api_status_t 
+ibqp_connect(
+	IN		IbQp_t				*pQp);
+
+void
+ibqp_detach(
+	IN		IbQp_t				*pQp);
+
+void
+ibqp_cleanup(
+	IN		IbQp_t				*pQp);
+
 ib_api_status_t
+ibqp_postSend(
+	IN		IbQp_t		*pQp,
+	IN		Io_t		*pIo);
+
+ib_api_status_t
+ibqp_postRecv(
+	IN		IbQp_t		*pQp,
+	IN		Io_t		*pIo);
+uint8_t
+ibca_findPortNum( 
+	IN		struct _viport	*p_viport,
+	IN		uint64_t		guid );
+
+ib_api_status_t
 ibregion_init(
-		IN		struct _viport		*p_viport,
-		OUT		IbRegion_t
*pRegion,
-		IN		ib_pd_handle_t		hPd,
-		IN		void* __ptr64		vaddr,
-		IN		uint64_t			len,
-		IN		ib_access_t
access_ctrl );
+	IN		struct _viport		*p_viport,
+	OUT		IbRegion_t			*pRegion,
+	IN		ib_pd_handle_t		hPd,
+	IN		void* __ptr64		vaddr,
+	IN		uint64_t			len,
+	IN		ib_access_t			access_ctrl );
 
 void
 ibregion_cleanup(
-				 struct _viport *p_viport,
-				 IbRegion_t *pRegion );
+	IN		struct _viport		*p_viport,
+	IN		IbRegion_t			*pRegion );
 
-void ib_asyncEvent( ib_async_event_rec_t	*pEventRecord );
+void 
+ib_asyncEvent( 
+	IN		ib_async_event_rec_t	*pEventRecord );
 
 #define ibpd_fromCa(pCa) (&(pCa)->pd)
 
Index: ulp/qlc_vnic/kernel/vnic_netpath.c
===================================================================
--- ulp/qlc_vnic/kernel/vnic_netpath.c	(revision 932)
+++ ulp/qlc_vnic/kernel/vnic_netpath.c	(working copy)
@@ -269,29 +269,26 @@
 void netpath_restartXmit(
 		IN		Netpath_t		*pNetpath )
 {
-		VNIC_ENTER( VNIC_DBG_NETPATH );
+	VNIC_ENTER( VNIC_DBG_NETPATH );
 
-	if (pNetpath == pNetpath->p_adapter->p_currentPath )
+	if( ( netpath_is_connected( pNetpath ) ) &&
+		pNetpath == pNetpath->p_adapter->p_currentPath )
 	{
-		if( !pNetpath->pViport->errored &&
-			pNetpath->pViport->state == VIPORT_CONNECTED )
-		{
-			InterlockedCompareExchange(
&pNetpath->p_adapter->xmitStarted, 1, 0 );
-			VNIC_TRACE( VNIC_DBG_NETPATH,
-					("IOC[%d] instance %d Restart
TRANSMIT\n", 
-
pNetpath->pViport->ioc_num, 
-
pNetpath->instance ));
-	
-		}
+		InterlockedCompareExchange(
&pNetpath->p_adapter->xmitStarted, 1, 0 );
+		VNIC_TRACE( VNIC_DBG_NETPATH,
+			("IOC[%d] instance %d Restart TRANSMIT\n", 
+			pNetpath->pViport->ioc_num, 
+			pNetpath->instance ));
+
 	}
 #ifdef INIC_STATISTICS
-		if (pNetpath->p_adapter->statistics.xmitRef != 0)
-		{
-			pNetpath->p_adapter->statistics.xmitOffTime +=
-				get_time_stamp_ms() -
pNetpath->p_adapter->statistics.xmitRef;
-			pNetpath->p_adapter->statistics.xmitOffNum++;
-			pNetpath->p_adapter->statistics.xmitRef = 0;
-		}
+	if (pNetpath->p_adapter->statistics.xmitRef != 0)
+	{
+		pNetpath->p_adapter->statistics.xmitOffTime +=
+			get_time_stamp_ms() -
pNetpath->p_adapter->statistics.xmitRef;
+		pNetpath->p_adapter->statistics.xmitOffNum++;
+		pNetpath->p_adapter->statistics.xmitRef = 0;
+	}
 #endif /* INIC_STATISTICS */
 	return;
 }
Index: ulp/qlc_vnic/kernel/vnic_viport.c
===================================================================
--- ulp/qlc_vnic/kernel/vnic_viport.c	(revision 932)
+++ ulp/qlc_vnic/kernel/vnic_viport.c	(working copy)
@@ -273,7 +273,11 @@
 	InterlockedExchange( &p_viport->p_netpath->carrier, FALSE );
 	p_viport->p_netpath->pViport = NULL;
 	p_viport->p_netpath = NULL;
-	p_viport->p_adapter->num_paths--;
+	
+	if( p_viport->state == VIPORT_CONNECTED )
+	{
+		p_viport->p_adapter->num_paths--;
+	}
 	return TRUE;
 }
 
@@ -286,7 +290,7 @@
 		IN		BOOLEAN			sync )
 {
 
-	NDIS_STATUS	status;
+	NDIS_STATUS	status = NDIS_STATUS_SUCCESS;
 
 	VNIC_ENTER( VNIC_DBG_VIPORT );
 
@@ -300,16 +304,20 @@
 
 	NdisAcquireSpinLock( &p_viport->lock );
 	
-	if( ( (p_viport->flags & flags ) != flags ) || (p_viport->mtu !=
mtu ))
+	if( ( (p_viport->newFlags & flags ) != flags ) || 
+		( p_viport->newMtu != mtu ) )
 	{
 		p_viport->newFlags = flags;
 		p_viport->newMtu = mtu;
 		InterlockedOr( &p_viport->updates, NEED_LINK_CONFIG );
+	
+		NdisReleaseSpinLock( &p_viport->lock );
+	
+		status = _viport_process_query( p_viport, sync );
 	}
-	NdisReleaseSpinLock( &p_viport->lock );
+	else
+		NdisReleaseSpinLock( &p_viport->lock );
 
-	status = _viport_process_query( p_viport, sync );
-	
 	VNIC_EXIT( VNIC_DBG_VIPORT );
 	return status;
 }
@@ -845,6 +853,7 @@
 	IN		viport_t*	const	p_viport )
 {
 	ib_api_status_t	ib_status;
+	cl_status_t		cl_status;
 
 	VNIC_ENTER( VNIC_DBG_INIT );
 
@@ -873,19 +882,20 @@
 	{
 		VNIC_TRACE_EXIT( VNIC_DBG_ERROR, 
 			("CMD_INIT_INIC  REQ failed\n") );
-		control_resetReq( &p_viport->control );
+
 		control_cleanup( &p_viport->control );
 		return ib_status;
 	}
-	cl_event_wait_on( &p_viport->sync_event,
-
(p_viport->control.p_conf->rspTimeout << 11), TRUE );
+	cl_status = cl_event_wait_on( &p_viport->sync_event,
+
(p_viport->control.p_conf->rspTimeout << 11), FALSE );
 
 	if( p_viport->linkState != LINK_INITINICRSP )
 	{
 		VNIC_TRACE_EXIT( VNIC_DBG_ERROR,
-					("CMD_INIT_INIC RSP failed\n"));
+			("CMD_INIT_INIC RSP failed: return linkstate:
%d, cl_status: %d\n",
+			p_viport->linkState, cl_status ));
+
 		ib_status = IB_INSUFFICIENT_RESOURCES;
-		control_resetReq( &p_viport->control );
 		control_cleanup( &p_viport->control );
 		return ib_status;
 	}
@@ -897,8 +907,6 @@
 	{
 		VNIC_TRACE( VNIC_DBG_ERROR,
 				("Init MAC Addresses failed\n"));
-		
-		control_resetReq( &p_viport->control );
 		control_cleanup( &p_viport->control );
 	}
 
@@ -1183,3 +1191,42 @@
 	return status;
 }
 
+BOOLEAN
+viport_canTxCsum(
+	IN		viport_t*	p_viport ) 
+{
+	if( !p_viport )
+		return FALSE;
+
+	return( BOOLEAN )( ( p_viport->featuresSupported &  
+			( INIC_FEAT_IPV4_HEADERS | 
+			  INIC_FEAT_IPV6_HEADERS |
+			  INIC_FEAT_IPV4_CSUM_TX |
+			  INIC_FEAT_TCP_CSUM_TX  | 
+			  INIC_FEAT_UDP_CSUM_TX ) ) == 
+			( INIC_FEAT_IPV4_HEADERS | 
+			  INIC_FEAT_IPV6_HEADERS | 
+			  INIC_FEAT_IPV4_CSUM_TX | 
+			  INIC_FEAT_TCP_CSUM_TX  |
+			  INIC_FEAT_UDP_CSUM_TX ) );
+}
+
+BOOLEAN
+viport_canRxCsum(
+	IN	viport_t*		p_viport )
+{
+	if( !p_viport )
+		return FALSE;
+
+	return( BOOLEAN )( ( p_viport->featuresSupported &  
+			( INIC_FEAT_IPV4_HEADERS | 
+			  INIC_FEAT_IPV6_HEADERS |
+			  INIC_FEAT_IPV4_CSUM_RX |
+			  INIC_FEAT_TCP_CSUM_RX  | 
+			  INIC_FEAT_UDP_CSUM_RX ) ) == 
+			( INIC_FEAT_IPV4_HEADERS | 
+			  INIC_FEAT_IPV6_HEADERS | 
+			  INIC_FEAT_IPV4_CSUM_RX | 
+			  INIC_FEAT_TCP_CSUM_RX  |
+			  INIC_FEAT_UDP_CSUM_RX ) );
+}
Index: ulp/qlc_vnic/kernel/vnic_viport.h
===================================================================
--- ulp/qlc_vnic/kernel/vnic_viport.h	(revision 932)
+++ ulp/qlc_vnic/kernel/vnic_viport.h	(working copy)
@@ -143,7 +143,7 @@
 	// connected/disconnected state of control and data QPs.
 	viport_state_t					state;
 
-	// State machine state?
+	// Control Path cmd state Query/Rsp
 	LinkState_t
linkState;
 	LinkState_t
link_hb_state;
 	Inic_CmdReportStatisticsRsp_t	stats;
@@ -157,11 +157,9 @@
 
 	// Indicates actions (to the VEx) that need to be taken.
 	volatile LONG					updates;
-	// ???
+
 	uint8_t							flags;
-	// TODO: Can we eliminate newFlags?
 	uint8_t
newFlags;
-
 	uint16_t						mtu;
 	uint16_t						newMtu;
 	uint32_t						errored;
@@ -367,9 +365,17 @@
 
 BOOLEAN
 netpath_setUnicast(
-		IN		Netpath_t*		p_netpath,
-		IN		uint8_t*		p_address );
+	IN		Netpath_t*		p_netpath,
+	IN		uint8_t*		p_address );
 
+BOOLEAN
+viport_canTxCsum(
+	IN		viport_t*		p_viport );
+
+BOOLEAN
+viport_canRxCsum(
+	IN		viport_t*		p_viport );
+
 #define  viport_portGuid(pViport) ((pViport)->portGuid)
 #define  viport_maxMtu(pViport) data_maxMtu(&(pViport)->data)
 
@@ -378,20 +384,13 @@
 
 #define  viport_features(pViport) ( (pViport)->featuresSupported )
 
-#define  viport_canTxCsum(pViport) \
-		( (pViport) && ((pViport)->featuresSupported & \
-
(INIC_FEAT_IPV4_CSUM_TX|INIC_FEAT_TCP_CSUM_TX|INIC_FEAT_UDP_CSUM_TX)) \
-		==
(INIC_FEAT_IPV4_CSUM_TX|INIC_FEAT_TCP_CSUM_TX|INIC_FEAT_UDP_CSUM_TX))
-
-#define  viport_canRxCsum(pViport) \
-			( (pViport) && ((pViport)->featuresSupported & \
-
(INIC_FEAT_IPV4_CSUM_RX|INIC_FEAT_TCP_CSUM_RX|INIC_FEAT_UDP_CSUM_RX)) \
-			==
(INIC_FEAT_IPV4_CSUM_RX|INIC_FEAT_TCP_CSUM_RX|INIC_FEAT_UDP_CSUM_RX))
-
 #define netpath_getHwAddr(pNetpath, pAddress) \
 			viport_getHwAddr((pNetpath)->pViport, pAddress)
 
 #define netpath_canTxCsum(pNetpath) \
 			viport_canTxCsum( (pNetpath)->pViport )
 
+#define netpath_canRxCsum(pNetpath) \
+			viport_canRxCsum( (pNetpath)->pViport )
+
 #endif /* _VNIC_VIPORT_H_ */



More information about the ofw mailing list