From eb330af48a68a98ce7a3001ed0eb335ee8ef8847 Mon Sep 17 00:00:00 2001 From: aestrin Date: Fri, 8 Feb 2008 22:06:09 +0000 Subject: [PATCH] [VNIC] 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). git-svn-id: svn://openib.tc.cornell.edu/gen1@933 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- trunk/ulp/qlc_vnic/kernel/SOURCES | 7 +- trunk/ulp/qlc_vnic/kernel/netvnic.inf | 4 +- trunk/ulp/qlc_vnic/kernel/vnic_adapter.c | 74 +++++++++---------- trunk/ulp/qlc_vnic/kernel/vnic_adapter.h | 6 +- trunk/ulp/qlc_vnic/kernel/vnic_config.h | 2 +- trunk/ulp/qlc_vnic/kernel/vnic_control.c | 25 +++---- trunk/ulp/qlc_vnic/kernel/vnic_data.c | 27 ++++--- trunk/ulp/qlc_vnic/kernel/vnic_driver.c | 91 +++++++++++++----------- trunk/ulp/qlc_vnic/kernel/vnic_ib.c | 7 +- trunk/ulp/qlc_vnic/kernel/vnic_ib.h | 58 ++++++++++----- trunk/ulp/qlc_vnic/kernel/vnic_netpath.c | 35 +++++---- trunk/ulp/qlc_vnic/kernel/vnic_viport.c | 73 +++++++++++++++---- trunk/ulp/qlc_vnic/kernel/vnic_viport.h | 31 ++++---- 13 files changed, 266 insertions(+), 174 deletions(-) diff --git a/trunk/ulp/qlc_vnic/kernel/SOURCES b/trunk/ulp/qlc_vnic/kernel/SOURCES index 481cdaf1..a096eda7 100644 --- a/trunk/ulp/qlc_vnic/kernel/SOURCES +++ b/trunk/ulp/qlc_vnic/kernel/SOURCES @@ -51,7 +51,12 @@ SOURCES= inic.rc \ 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 \ diff --git a/trunk/ulp/qlc_vnic/kernel/netvnic.inf b/trunk/ulp/qlc_vnic/kernel/netvnic.inf index 8948bbc0..91db0ed0 100644 --- a/trunk/ulp/qlc_vnic/kernel/netvnic.inf +++ b/trunk/ulp/qlc_vnic/kernel/netvnic.inf @@ -80,7 +80,7 @@ AddService = vnic,%SPSVCINST_ASSOCSERVICE%,vnic.ServiceInstall,vnic.EventLogInst 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, Type, 0, "dword" 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" diff --git a/trunk/ulp/qlc_vnic/kernel/vnic_adapter.c b/trunk/ulp/qlc_vnic/kernel/vnic_adapter.c index 1b5c14c9..7be95023 100644 --- a/trunk/ulp/qlc_vnic/kernel/vnic_adapter.c +++ b/trunk/ulp/qlc_vnic/kernel/vnic_adapter.c @@ -121,7 +121,7 @@ static void __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 @@ vnic_create_adapter( /* 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 @@ vnic_destroy_adapter( _adapter_close_ca( p_adapter ); -#if defined( LBFO_ENABLED ) +#if ( LBFO_ENABLED ) __adapter_remove_from_failover_list( p_adapter ); @@ -567,7 +567,7 @@ vnic_get_adapter_params( 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 @@ adapter_viport_allocate( 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_pnp_cb( 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 @@ __vnic_pnp_cb( 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 @@ __vnic_pnp_cb( 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 @@ __vnic_pnp_cb( /* 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 @@ __vnic_pnp_dereg_cb( 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 @@ adapter_reset( 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 @@ adapter_netpath_update_and_connect( 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 @@ err: return ib_status; } -#if defined( LBFO_ENABLED ) +#if ( LBFO_ENABLED ) static void __adapter_add_to_failover_list( @@ -1692,8 +1687,7 @@ __adapter_remove_from_failover_list( 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 @@ __adapter_remove_from_failover_list( 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 @@ __adapter_remove_from_failover_list( ("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; } diff --git a/trunk/ulp/qlc_vnic/kernel/vnic_adapter.h b/trunk/ulp/qlc_vnic/kernel/vnic_adapter.h index 969c363e..cd143b52 100644 --- a/trunk/ulp/qlc_vnic/kernel/vnic_adapter.h +++ b/trunk/ulp/qlc_vnic/kernel/vnic_adapter.h @@ -139,7 +139,7 @@ typedef struct _vnic_adapter { 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 @@ typedef struct _vnic_adapter { 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 @@ typedef struct _vnic_adapter { 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 diff --git a/trunk/ulp/qlc_vnic/kernel/vnic_config.h b/trunk/ulp/qlc_vnic/kernel/vnic_config.h index 96dad841..9568b08f 100644 --- a/trunk/ulp/qlc_vnic/kernel/vnic_config.h +++ b/trunk/ulp/qlc_vnic/kernel/vnic_config.h @@ -191,7 +191,7 @@ typedef struct { 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 diff --git a/trunk/ulp/qlc_vnic/kernel/vnic_control.c b/trunk/ulp/qlc_vnic/kernel/vnic_control.c index f3fb07f9..c8967a86 100644 --- a/trunk/ulp/qlc_vnic/kernel/vnic_control.c +++ b/trunk/ulp/qlc_vnic/kernel/vnic_control.c @@ -1236,9 +1236,10 @@ control_recvComplete( 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 @@ static ib_api_status_t 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 @@ control_send( */ 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 @@ control_send( 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 @@ control_getRsp( VNIC_TRACE( VNIC_DBG_ERROR, ("IOC %d: Control packet retry exceeded\n", pControl->p_viport->ioc_num ) ); - viport_failure(pControl->p_viport ); } else { diff --git a/trunk/ulp/qlc_vnic/kernel/vnic_data.c b/trunk/ulp/qlc_vnic/kernel/vnic_data.c index 8f007a57..4f39a643 100644 --- a/trunk/ulp/qlc_vnic/kernel/vnic_data.c +++ b/trunk/ulp/qlc_vnic/kernel/vnic_data.c @@ -609,7 +609,7 @@ data_xmitPacket( { 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 @@ _tx_chksum_flags( 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 @@ _data_recv_to_ndis_pkt( 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': diff --git a/trunk/ulp/qlc_vnic/kernel/vnic_driver.c b/trunk/ulp/qlc_vnic/kernel/vnic_driver.c index e5ede83a..942fa571 100644 --- a/trunk/ulp/qlc_vnic/kernel/vnic_driver.c +++ b/trunk/ulp/qlc_vnic/kernel/vnic_driver.c @@ -181,7 +181,7 @@ DriverEntry( __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_initialize( { 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; + + 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( p_adapter->state != INIC_REGISTERED ) + 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 @@ vnic_check_for_hang( 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 @@ __vnic_get_tcp_task_offload( 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 @@ __vnic_get_tcp_task_offload( { 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 @@ __vnic_get_tcp_task_offload( 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_set_tcp_task_offload( 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 @@ __vnic_set_tcp_task_offload( (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 @@ __vnic_set_tcp_task_offload( 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 @@ vnic_resume_oids( &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 @@ _vnic_process_packet_filter( 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 ); } diff --git a/trunk/ulp/qlc_vnic/kernel/vnic_ib.c b/trunk/ulp/qlc_vnic/kernel/vnic_ib.c index e9c1cb36..31f2884b 100644 --- a/trunk/ulp/qlc_vnic/kernel/vnic_ib.c +++ b/trunk/ulp/qlc_vnic/kernel/vnic_ib.c @@ -450,7 +450,8 @@ _ibqp_rej_cb( ("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 @@ _ibqp_connect_cb( 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 { diff --git a/trunk/ulp/qlc_vnic/kernel/vnic_ib.h b/trunk/ulp/qlc_vnic/kernel/vnic_ib.h index 1503321e..8dde7deb 100644 --- a/trunk/ulp/qlc_vnic/kernel/vnic_ib.h +++ b/trunk/ulp/qlc_vnic/kernel/vnic_ib.h @@ -181,30 +181,56 @@ void 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) diff --git a/trunk/ulp/qlc_vnic/kernel/vnic_netpath.c b/trunk/ulp/qlc_vnic/kernel/vnic_netpath.c index b1b589a5..98ddb374 100644 --- a/trunk/ulp/qlc_vnic/kernel/vnic_netpath.c +++ b/trunk/ulp/qlc_vnic/kernel/vnic_netpath.c @@ -269,29 +269,26 @@ netpath_stopXmit( 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; } diff --git a/trunk/ulp/qlc_vnic/kernel/vnic_viport.c b/trunk/ulp/qlc_vnic/kernel/vnic_viport.c index 47fd0fbb..f34c8bf4 100644 --- a/trunk/ulp/qlc_vnic/kernel/vnic_viport.c +++ b/trunk/ulp/qlc_vnic/kernel/vnic_viport.c @@ -273,7 +273,11 @@ viport_unsetParent( 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 @@ viport_setLink( IN BOOLEAN sync ) { - NDIS_STATUS status; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; VNIC_ENTER( VNIC_DBG_VIPORT ); @@ -300,16 +304,20 @@ viport_setLink( 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 @@ viport_control_connect( 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 @@ viport_control_connect( { 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 @@ viport_control_connect( { VNIC_TRACE( VNIC_DBG_ERROR, ("Init MAC Addresses failed\n")); - - control_resetReq( &p_viport->control ); control_cleanup( &p_viport->control ); } @@ -1183,3 +1191,42 @@ _viport_process_query( 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 ) ); +} diff --git a/trunk/ulp/qlc_vnic/kernel/vnic_viport.h b/trunk/ulp/qlc_vnic/kernel/vnic_viport.h index eb0b2bd5..b881e69f 100644 --- a/trunk/ulp/qlc_vnic/kernel/vnic_viport.h +++ b/trunk/ulp/qlc_vnic/kernel/vnic_viport.h @@ -143,7 +143,7 @@ typedef struct _viport { // 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 @@ typedef struct _viport { // 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,8 +365,16 @@ netpath_to_string( 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 @@ netpath_setUnicast( #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_ */ -- 2.41.0