* $Id: ipoib_driver.c 4506 2009-06-23 14:40:54Z xalex $\r
*/\r
\r
-#include "limits.h"\r
-#include "ipoib_driver.h"\r
-#include "ipoib_debug.h"\r
+#include "Precompile.h"\r
+\r
+\r
\r
#if defined(EVENT_TRACING)\r
#ifdef offsetof\r
ipoib_globals_t g_ipoib = {0};\r
NDIS_HANDLE g_IpoibMiniportDriverHandle = NULL;\r
NDIS_HANDLE g_IpoibDriverContext = NULL;\r
+ULONG g_ipoib_send = 0;\r
+ULONG g_ipoib_send_ack = 0;\r
+ULONG g_ipoib_send_SW = 0;\r
+ULONG g_ipoib_send_SG = 0;\r
+ULONG g_ipoib_send_SW_in_loop = 0;\r
+ULONG g_ipoib_send_SG_pending = 0;\r
+ULONG g_ipoib_send_SG_real = 0;\r
+ULONG g_ipoib_send_SG_failed = 0;\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
\r
\r
\r
IN PVOID cancel_id );\r
\r
\r
-static void\r
+static NDIS_STATUS\r
ipoib_complete_query(\r
IN ipoib_adapter_t* const p_adapter,\r
IN pending_oid_t* const p_oid_info,\r
\r
\r
\r
-//TODO NDIS60 set g_ prefix to global variables\r
status = NdisMRegisterMiniportDriver(\r
p_drv_obj, p_registry_path,(PNDIS_HANDLE)&g_IpoibDriverContext, &characteristics,&g_IpoibMiniportDriverHandle );\r
if( status != NDIS_STATUS_SUCCESS )\r
atr.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;\r
atr.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;\r
atr.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;\r
- //TODO NDIS60 Port or adapter\r
- atr.MiniportAdapterContext = (NDIS_HANDLE)p_adapter; //(NDIS_HANDLE)pPort->p_adapter;\r
+\r
+ atr.MiniportAdapterContext = (NDIS_HANDLE)p_adapter; \r
atr.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER;\r
atr.CheckForHangTimeInSeconds = 10;\r
atr.InterfaceType = NdisInterfacePci ; // ???? UH\r
gat.MediaConnectState = MediaConnectStateConnected; //TODO NDIS60 Check the current state\r
gat.MediaDuplexState = MediaDuplexStateFull;\r
\r
- gat.MtuSize = MAX_IB_MTU;\r
+ gat.MtuSize = DEFAULT_PAYLOAD_MTU;\r
gat.LookaheadSize = MAX_XFER_BLOCK_SIZE;\r
gat.MacOptions = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \r
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |\r
gat.ConnectionType = NET_IF_CONNECTION_DEDICATED; \r
gat.IfType = IF_TYPE_ETHERNET_CSMACD; \r
gat.IfConnectorPresent = TRUE; \r
- //TODO NDIS60 This value is absent for ETH driver\r
gat.AccessType = NET_IF_ACCESS_BROADCAST; // NET_IF_ACCESS_BROADCAST for a typical ethernet adapter\r
\r
\r
NdisZeroMemory(p_offload, NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1);\r
\r
p_offload->Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;\r
- p_offload->Header.Revision = NDIS_OFFLOAD_REVISION_1; // BUGBUG: do we need to support revision 2? UH 17-May-2008\r
+ p_offload->Header.Revision = NDIS_OFFLOAD_REVISION_1; // TODO: NDIS6.0. do we need to support revision 2? UH 17-May-2008\r
p_offload->Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;\r
\r
p_offload->Checksum.IPv4Transmit.Encapsulation = ulEncapsulation;\r
p_offload->Checksum.IPv4Receive.TcpOptionsSupported = \r
p_offload->Checksum.IPv4Receive.TcpChecksum = \r
p_offload->Checksum.IPv4Receive.UdpChecksum = \r
- p_offload->Checksum.IPv4Receive.IpChecksum = !!(p_adapter->params.recv_chksum_offload); //TODO NDIS60\r
+ p_offload->Checksum.IPv4Receive.IpChecksum = !!(p_adapter->params.recv_chksum_offload); \r
\r
\r
p_offload->Checksum.IPv6Transmit.Encapsulation = ulEncapsulation;\r
DmaDescription.Flags = NDIS_SG_DMA_64_BIT_ADDRESS;\r
//DmaDescription.MaximumPhysicalMapping = pPort->p_adapter->params.xfer_block_size;\r
\r
- DmaDescription.ProcessSGListHandler = ipoib_process_sg_list;\r
- DmaDescription.SharedMemAllocateCompleteHandler = NULL;\r
\r
status = NdisMRegisterScatterGatherDma(\r
h_adapter,\r
\r
if( status != NDIS_STATUS_SUCCESS )\r
{\r
- //TODO NDIS60\r
- //ipoib_destroy_adapter( p_adapter );\r
+ ipoib_destroy_adapter( p_adapter );\r
IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
("NdisMRegisterScatterGatherDma returned 0x%.8x.\n", status) );\r
+ //ASSERT(FALSE);\r
\r
}\r
//NDIS sets this value before it returns from NdisMRegisterScatterGatherDma. \r
- //Miniport drivers should use this size to preallocate memory for each scatter/gather list. \r
+ //Miniport drivers should use this size to preallocate memory for each scatter/gather list. \r
p_adapter->sg_list_size = DmaDescription.ScatterGatherListSize ;\r
\r
return status;\r
}\r
\r
\r
-NDIS_STATUS \r
-MPInitializeTest(\r
- IN NDIS_HANDLE MiniportAdapterHandle,\r
- IN NDIS_HANDLE MiniportDriverContext,\r
- IN PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters\r
- )\r
+\r
+\r
/*++\r
Routine Description:\r
\r
NDIS_STATUS_SUCCESS unless something goes wrong\r
\r
--*/\r
-{\r
-\r
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;\r
- //PMP_PORT pPort = NULL;\r
- ipoib_adapter_t *p_adapter;\r
-// NDIS_MINIPORT_INTERRUPT_CHARACTERISTICS Interrupt;\r
- NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES RegistrationAttributes;\r
- NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES GeneralAttributes;\r
- //NDIS_TIMER_CHARACTERISTICS Timer; \r
- NDIS_PNP_CAPABILITIES PowerManagementCapabilities; \r
- //PMP_ADAPTER Adapter = NULL;\r
- //PVOID NetworkAddress;\r
-// UINT index;\r
-// UINT uiPnpCommandValue;\r
-// ULONG ulInfoLen;\r
- //ULONG InterruptVersion;\r
-// LARGE_INTEGER liDueTime;\r
- //BOOLEAN isTimerAlreadyInQueue = FALSE;\r
-// uint8_t portId;\r
- ib_api_status_t ib_status;\r
-#if 0 \r
-#if DBG\r
- LARGE_INTEGER TS, TD, TE;\r
-#endif\r
-#endif\r
-\r
- cl_dbg_out ("====> MPInitialize\n");\r
-\r
- UNREFERENCED_PARAMETER(MiniportDriverContext);\r
- UNREFERENCED_PARAMETER(MiniportInitParameters);\r
- \r
-\r
-\r
- \r
-\r
- {\r
-\r
- ib_status = ipoib_create_adapter( MiniportAdapterHandle, &p_adapter );\r
- if( ib_status != IB_SUCCESS )\r
- {\r
- ASSERT(FALSE);\r
- IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
- ("ipoib_create_adapter returned status %d.\n", ib_status ) );\r
- return NDIS_STATUS_FAILURE;\r
- }\r
-\r
- \r
-\r
- NdisZeroMemory(&RegistrationAttributes, sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));\r
- NdisZeroMemory(&GeneralAttributes, sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));\r
-\r
- //\r
- // setting registration attributes\r
- //\r
- RegistrationAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;\r
- RegistrationAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;\r
- RegistrationAttributes.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES);\r
-\r
- RegistrationAttributes.MiniportAdapterContext = (NDIS_HANDLE)p_adapter;\r
- RegistrationAttributes.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_HARDWARE_DEVICE | \r
- NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER;\r
- \r
- RegistrationAttributes.CheckForHangTimeInSeconds = 2;\r
- RegistrationAttributes.InterfaceType = NdisInterfacePci;\r
-\r
- Status = NdisMSetMiniportAttributes(MiniportAdapterHandle,\r
- (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&RegistrationAttributes);\r
-\r
- if (Status != NDIS_STATUS_SUCCESS)\r
- {\r
- //break;\r
- return Status;\r
- }\r
-\r
-#if 0 \r
- //\r
- // Read the registry parameters\r
- //\r
- Status = NICReadRegParameters(Adapter);\r
- \r
- if (Status != NDIS_STATUS_SUCCESS) \r
- {\r
- break;\r
- }\r
-\r
- \r
- //\r
- // Find the physical adapter\r
- //\r
- Status = MpFindAdapter(Adapter, MiniportInitParameters->AllocatedResources);\r
- if (Status != NDIS_STATUS_SUCCESS)\r
- {\r
- break;\r
- }\r
-\r
- //\r
- // Map bus-relative IO range to system IO space\r
- //\r
- Status = NdisMRegisterIoPortRange(\r
- (PVOID *)&Adapter->PortOffset,\r
- Adapter->AdapterHandle,\r
- Adapter->IoBaseAddress,\r
- Adapter->IoRange);\r
- if (Status != NDIS_STATUS_SUCCESS)\r
- {\r
- DBGPRINT(MP_ERROR, ("NdisMRegisterioPortRange failed\n"));\r
- \r
- NdisWriteErrorLogEntry(\r
- Adapter->AdapterHandle,\r
- NDIS_ERROR_CODE_BAD_IO_BASE_ADDRESS,\r
- 0);\r
- \r
- break;\r
- }\r
- \r
- //\r
- // Read additional info from NIC such as MAC address\r
- //\r
- Status = NICReadAdapterInfo(Adapter);\r
- if (Status != NDIS_STATUS_SUCCESS) \r
- {\r
- break;\r
- }\r
-\r
-#endif\r
- //\r
- // set up generic attributes\r
- //\r
- \r
-\r
- GeneralAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;\r
- GeneralAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;\r
- GeneralAttributes.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);\r
-\r
- GeneralAttributes.MediaType = NdisMedium802_3;\r
-\r
- GeneralAttributes.MtuSize = DEFAULT_MTU;\r
-#define LINE_SPEED_10_GBTS 10000000000\r
- GeneralAttributes.MaxXmitLinkSpeed = LINE_SPEED_10_GBTS;\r
- GeneralAttributes.MaxRcvLinkSpeed = LINE_SPEED_10_GBTS;\r
- GeneralAttributes.XmitLinkSpeed = NDIS_LINK_SPEED_UNKNOWN;\r
- GeneralAttributes.RcvLinkSpeed = NDIS_LINK_SPEED_UNKNOWN;\r
- GeneralAttributes.MediaConnectState = MediaConnectStateUnknown;\r
- GeneralAttributes.MediaDuplexState = MediaDuplexStateUnknown;\r
- GeneralAttributes.LookaheadSize = MAX_XFER_BLOCK_SIZE;\r
-#if 0\r
- MPFillPoMgmtCaps (Adapter, \r
- &PowerManagementCapabilities, \r
- &Status,\r
- &ulInfoLen);\r
-#endif\r
- NdisZeroMemory(&PowerManagementCapabilities, sizeof(NDIS_PNP_CAPABILITIES));\r
- Status = NDIS_STATUS_NOT_SUPPORTED;\r
- // ulInfoLen = 0;\r
-\r
- if (Status == NDIS_STATUS_SUCCESS)\r
- {\r
- GeneralAttributes.PowerManagementCapabilities = &PowerManagementCapabilities;\r
- }\r
- else\r
- {\r
- GeneralAttributes.PowerManagementCapabilities = NULL;\r
- }\r
-\r
- //\r
- // do not fail the call because of failure to get PM caps\r
- //\r
- Status = NDIS_STATUS_SUCCESS;\r
-\r
- GeneralAttributes.MacOptions = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \r
- NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |\r
- NDIS_MAC_OPTION_NO_LOOPBACK;\r
-\r
- GeneralAttributes.SupportedPacketFilters = NDIS_PACKET_TYPE_DIRECTED |\r
- NDIS_PACKET_TYPE_MULTICAST |\r
- NDIS_PACKET_TYPE_ALL_MULTICAST |\r
- NDIS_PACKET_TYPE_BROADCAST;\r
- \r
- GeneralAttributes.MaxMulticastListSize = MAX_MCAST;\r
- GeneralAttributes.MacAddressLength = HW_ADDR_LEN;\r
- NdisMoveMemory(GeneralAttributes.PermanentMacAddress,\r
- p_adapter->mac.addr,\r
- HW_ADDR_LEN);\r
-\r
- NdisMoveMemory(GeneralAttributes.CurrentMacAddress,\r
- p_adapter->params.conf_mac.addr,\r
- HW_ADDR_LEN);\r
- GeneralAttributes.RecvScaleCapabilities = NULL;\r
- GeneralAttributes.AccessType = NET_IF_ACCESS_BROADCAST; // NET_IF_ACCESS_BROADCAST for a typical ethernet adapter\r
- GeneralAttributes.DirectionType = NET_IF_DIRECTION_SENDRECEIVE; // NET_IF_DIRECTION_SENDRECEIVE for a typical ethernet adapter\r
- GeneralAttributes.ConnectionType = NET_IF_CONNECTION_DEDICATED; // NET_IF_CONNECTION_DEDICATED for a typical ethernet adapter\r
- GeneralAttributes.IfType = IF_TYPE_ETHERNET_CSMACD; // IF_TYPE_ETHERNET_CSMACD for a typical ethernet adapter (regardless of speed)\r
- GeneralAttributes.IfConnectorPresent = TRUE; // RFC 2665 TRUE if physical adapter\r
-\r
- GeneralAttributes.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED |\r
- NDIS_STATISTICS_RCV_OK_SUPPORTED |\r
- NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |\r
- NDIS_STATISTICS_RCV_ERROR_SUPPORTED |\r
- NDIS_STATISTICS_RCV_CRC_ERROR_SUPPORTED |\r
- NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED |\r
- NDIS_STATISTICS_TRANSMIT_QUEUE_LENGTH_SUPPORTED |\r
- NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;\r
- \r
- GeneralAttributes.SupportedOidList = NICSupportedOidsTest;\r
- GeneralAttributes.SupportedOidListLength = sizeof(NICSupportedOidsTest);\r
-\r
- Status = NdisMSetMiniportAttributes(MiniportAdapterHandle,\r
- (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&GeneralAttributes);\r
-\r
-\r
-#if 0 \r
- //\r
- // Allocate all other memory blocks including shared memory\r
- //\r
- Status = NICAllocAdapterMemory(Adapter);\r
- if (Status != NDIS_STATUS_SUCCESS) \r
- {\r
- break;\r
- }\r
- //\r
- // Init send data structures\r
- //\r
- NICInitSend(Adapter);\r
-\r
- //\r
- // Init receive data structures\r
- //\r
- Status = NICInitRecv(Adapter);\r
- if (Status != NDIS_STATUS_SUCCESS)\r
- {\r
- break;\r
- }\r
- //\r
- // Map bus-relative registers to virtual system-space\r
- // \r
- Status = NdisMMapIoSpace(\r
- (PVOID *) &(Adapter->CSRAddress),\r
- Adapter->AdapterHandle,\r
- Adapter->MemPhysAddress,\r
- NIC_MAP_IOSPACE_LENGTH);\r
- if (Status != NDIS_STATUS_SUCCESS)\r
- {\r
- DBGPRINT(MP_ERROR, ("NdisMMapIoSpace failed\n"));\r
- \r
- NdisWriteErrorLogEntry(\r
- Adapter->AdapterHandle,\r
- NDIS_ERROR_CODE_RESOURCE_CONFLICT,\r
- 1,\r
- ERRLOG_MAP_IO_SPACE);\r
- \r
- break;\r
- }\r
-\r
- DBGPRINT(MP_INFO, ("CSRAddress="PTR_FORMAT"\n", Adapter->CSRAddress));\r
-\r
- //\r
- // Disable interrupts here which is as soon as possible\r
- //\r
- NICDisableInterrupt(Adapter);\r
-#endif\r
- \r
- //\r
- // Register the interrupt\r
- //\r
- //\r
- \r
- //\r
- // the embeded NDIS interrupt structure is already zero'ed out\r
- // as part of the adapter structure\r
- //\r
- #if 0\r
- NdisZeroMemory(&Interrupt, sizeof(NDIS_MINIPORT_INTERRUPT_CHARACTERISTICS));\r
- \r
- Interrupt.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_INTERRUPT;\r
- Interrupt.Header.Revision = NDIS_MINIPORT_INTERRUPT_REVISION_1;\r
- Interrupt.Header.Size = sizeof(NDIS_MINIPORT_INTERRUPT_CHARACTERISTICS);\r
-\r
- Interrupt.InterruptHandler = MPIsr;\r
- Interrupt.InterruptDpcHandler = MPHandleInterrupt;\r
- Interrupt.DisableInterruptHandler = NULL;\r
- Interrupt.EnableInterruptHandler = NULL;\r
-\r
-\r
-\r
- Status = NdisMRegisterInterruptEx(Adapter->AdapterHandle,\r
- Adapter,\r
- &Interrupt,\r
- &Adapter->NdisInterruptHandle\r
- );\r
- \r
- \r
- if (Status != NDIS_STATUS_SUCCESS)\r
- {\r
- DBGPRINT(MP_ERROR, ("NdisMRegisterInterrupt failed\n"));\r
- \r
- NdisWriteErrorLogEntry(\r
- Adapter->AdapterHandle,\r
- NDIS_ERROR_CODE_INTERRUPT_CONNECT,\r
- 0);\r
- \r
- break;\r
- }\r
- \r
- //\r
- // If the driver support MSI\r
- //\r
- Adapter->InterruptType = Interrupt.InterruptType;\r
-\r
- if (Adapter->InterruptType == NDIS_CONNECT_MESSAGE_BASED)\r
- {\r
- Adapter->MessageInfoTable = Interrupt.MessageInfoTable;\r
- }\r
- \r
- //\r
- // If the driver supports MSI, here it should what kind of interrupt is granted. If MSI is granted,\r
- // the driver can check Adapter->MessageInfoTable to get MSI information\r
- //\r
- \r
- \r
- MP_SET_FLAG(Adapter, fMP_ADAPTER_INTERRUPT_IN_USE);\r
-\r
- //\r
- // Test our adapter hardware\r
- //\r
- Status = NICSelfTest(Adapter);\r
- if (Status != NDIS_STATUS_SUCCESS)\r
- {\r
- break;\r
- }\r
- \r
- //\r
- // Init the hardware and set up everything\r
- //\r
- Status = NICInitializeAdapter(Adapter);\r
- if (Status != NDIS_STATUS_SUCCESS)\r
- {\r
- break;\r
- }\r
- \r
- //\r
- // initial state is paused\r
- //\r
- Adapter->AdapterState = NicPaused;\r
- \r
- //\r
- // Set the link detection flag\r
- //\r
- MP_SET_FLAG(Adapter, fMP_ADAPTER_LINK_DETECTION);\r
- \r
- //\r
- // Increment the reference count so halt handler will wait \r
- //\r
- MP_INC_REF(Adapter); \r
-\r
- //\r
- // Enable the interrupt\r
- //\r
- NICEnableInterrupt(Adapter);\r
-\r
- \r
- NdisZeroMemory(&Timer, sizeof(NDIS_TIMER_CHARACTERISTICS));\r
- \r
- Timer.Header.Type = NDIS_OBJECT_TYPE_TIMER_CHARACTERISTICS;\r
- Timer.Header.Revision = NDIS_TIMER_CHARACTERISTICS_REVISION_1;\r
- Timer.Header.Size = sizeof(NDIS_TIMER_CHARACTERISTICS);\r
-\r
- Timer.AllocationTag = NIC_TAG;\r
- Timer.TimerFunction = MpLinkDetectionDpc;\r
- Timer.FunctionContext = Adapter;\r
-\r
- //\r
- // Minimize init-time\r
- //\r
- Status = NdisAllocateTimerObject(\r
- Adapter->AdapterHandle,\r
- &Timer,\r
- &Adapter->LinkDetectionTimerHandle);\r
-\r
- if (Status != NDIS_STATUS_SUCCESS)\r
- {\r
- break;\r
- }\r
-\r
- liDueTime.QuadPart = NIC_LINK_DETECTION_DELAY;\r
- isTimerAlreadyInQueue =NdisSetTimerObject(Adapter->LinkDetectionTimerHandle, liDueTime, 0, NULL);\r
- ASSERT(!isTimerAlreadyInQueue);\r
-#endif \r
- } \r
-#if 0\r
- if (Adapter && (Status != NDIS_STATUS_SUCCESS))\r
- {\r
- //\r
- // Undo everything if it failed\r
- //\r
- MP_DEC_REF(Adapter);\r
- MpFreeAdapter(Adapter);\r
- }\r
-\r
- DBGPRINT_S(Status, ("<==== MPInitialize, Status=%x\n", Status));\r
-#endif\r
- /* Create the adapter adapter */\r
- ib_status = ipoib_start_adapter( p_adapter );\r
- if( ib_status != IB_SUCCESS )\r
- {\r
- ASSERT(FALSE);\r
-\r
- IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
- ("ipoib_start_adapter returned status %d.\n", ib_status ) );\r
- return NDIS_STATUS_FAILURE;\r
- }\r
- \r
- ipoib_ref_ibat();\r
- return NDIS_STATUS_SUCCESS;\r
-}\r
-\r
-\r
\r
NDIS_STATUS\r
ipoib_initialize_ex(\r
ipoib_adapter_t *p_adapter;\r
\r
IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+#if 0\r
+if(cl_get_time_stamp_sec() < 30) {\r
+ cl_dbg_out("Disable/Enable IPoIB adapter to continue running\n");\r
+ return NDIS_STATUS_HARD_ERRORS;\r
+}\r
+#endif\r
\r
#ifdef _DEBUG_\r
PAGED_CODE();\r
ib_status = ipoib_create_adapter( h_adapter, &p_adapter );\r
if( ib_status != IB_SUCCESS )\r
{\r
- ASSERT(FALSE);\r
+ //ASSERT(FALSE);\r
IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
("ipoib_create_adapter returned status %d.\n", ib_status ) );\r
return NDIS_STATUS_FAILURE;\r
p_adapter->ipoib_state = IPOIB_PAUSED;\r
status = SetAttributes(p_adapter, h_adapter);\r
if (status != NDIS_STATUS_SUCCESS) {\r
- ASSERT(FALSE);\r
+ //ASSERT(FALSE);\r
+ return NDIS_STATUS_FAILURE;\r
}\r
\r
+\r
#if IPOIB_USE_DMA\r
- InitNdisScatterGatherDma(p_adapter, h_adapter);\r
+ status = InitNdisScatterGatherDma(p_adapter, h_adapter);\r
+ if( status != NDIS_STATUS_SUCCESS )\r
+ { \r
+ ipoib_destroy_adapter( p_adapter );\r
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("InitNdisScatterGatherDma returned status 0x%.8x.\n", status ) );\r
+ return NDIS_STATUS_FAILURE;\r
+ }\r
+\r
#endif\r
\r
/* Create the adapter adapter */\r
ib_status = ipoib_start_adapter( p_adapter );\r
if( ib_status != IB_SUCCESS )\r
{\r
- ASSERT(FALSE);\r
+ //ASSERT(FALSE);\r
NdisWriteErrorLogEntry( h_adapter,\r
NDIS_ERROR_CODE_HARDWARE_FAILURE, 0 );\r
#if IPOIB_USE_DMA\r
IPOIB_ENTER( IPOIB_DBG_INIT );\r
\r
UNUSED_PARAM(HaltAction);\r
-//return; \r
+ \r
ipoib_deref_ibat();\r
\r
CL_ASSERT( adapter_context );\r
ipoib_adapter_t *p_adapter;\r
\r
IPOIB_ENTER( IPOIB_DBG_INIT );\r
-//return FALSE;\r
+\r
CL_ASSERT( adapter_context );\r
p_adapter = (ipoib_adapter_t*)adapter_context;\r
\r
OUT PULONG p_bytes_written,\r
OUT PULONG p_bytes_needed )\r
{\r
- ipoib_adapter_t *p_adapter;\r
+ ipoib_adapter_t *p_adapter;\r
NDIS_STATUS status;\r
USHORT version;\r
- ULONG info;\r
+ ULONG info;\r
PVOID src_buf;\r
ULONG buf_len;\r
pending_oid_t oid_info;\r
- uint8_t port_num;\r
+ uint8_t port_num;\r
+\r
\r
IPOIB_ENTER( IPOIB_DBG_OID );\r
\r
CL_ASSERT( p_bytes_needed );\r
CL_ASSERT( !p_adapter->pending_query );\r
\r
- status = NDIS_STATUS_SUCCESS;\r
- src_buf = &info;\r
+ status = NDIS_STATUS_SUCCESS;\r
+ src_buf = &info;\r
buf_len = sizeof(info);\r
\r
port_num = p_adapter->guids.port_num;\r
case OID_GEN_HARDWARE_STATUS:\r
IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
("Port %d received query for OID_GEN_HARDWARE_STATUS\n", port_num) );\r
+ \r
cl_obj_lock( &p_adapter->obj );\r
switch( p_adapter->state )\r
{\r
IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
("Port %d received query for OID_GEN_VENDOR_DRIVER_VERSION\n", port_num) );\r
src_buf = &version;\r
- buf_len = sizeof(version);\r
+ buf_len = sizeof(version);\r
//TODO: Figure out what the right version is.\r
version = 1 << 8 | 1;\r
break;\r
*/\r
if( status != NDIS_STATUS_PENDING )\r
{\r
- ipoib_complete_query(\r
+ return ipoib_complete_query(\r
p_adapter, &oid_info, status, src_buf, buf_len );\r
- return status;\r
}\r
\r
IPOIB_EXIT( IPOIB_DBG_OID );\r
}\r
\r
\r
-static void\r
+static NDIS_STATUS\r
ipoib_complete_query(\r
IN ipoib_adapter_t* const p_adapter,\r
IN pending_oid_t* const p_oid_info,\r
IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
("Insufficient buffer space. "\r
"Returning NDIS_STATUS_INVALID_LENGTH.\n") );\r
- oid_status = NDIS_STATUS_INVALID_LENGTH;\r
+ //oid_status = NDIS_STATUS_INVALID_LENGTH;\r
+ oid_status = NDIS_STATUS_BUFFER_TOO_SHORT;\r
*p_oid_info->p_bytes_needed = buf_len;\r
*p_oid_info->p_bytes_used = 0;\r
}\r
p_adapter->query_oid.p_pending_oid = NULL;\r
}\r
p_adapter->pending_query = FALSE;\r
-\r
IPOIB_EXIT( IPOIB_DBG_OID );\r
+ return oid_status;\r
+\r
+ \r
}\r
\r
\r
cl_obj_unlock( &p_adapter->obj );\r
//IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
// ("Starting NET BUFFER LIST \n") );\r
+\r
+\r
+ if (NET_BUFFER_LIST_NEXT_NBL(net_buffer_list) != NULL) {\r
+ cl_dbg_out("Recieved a list of NBLS ................\n");\r
+ }\r
+\r
+ \r
for (curr_net_buffer_list = net_buffer_list;\r
curr_net_buffer_list != NULL;\r
curr_net_buffer_list = next_net_buffer_list)\r
{\r
+\r
+ \r
next_net_buffer_list = NET_BUFFER_LIST_NEXT_NBL(curr_net_buffer_list);\r
+ KeMemoryBarrierWithoutFence();\r
+ // Important issue, break the connection between the different nbls\r
+ NET_BUFFER_LIST_NEXT_NBL(curr_net_buffer_list) = NULL;\r
+\r
+ \r
cl_perf_start( PortSend );\r
\r
ipoib_port_send( p_port, curr_net_buffer_list, send_flags);\r
\r
if (NDIS_TEST_SEND_AT_DISPATCH_LEVEL(send_flags))\r
{\r
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);\r
NDIS_SET_SEND_COMPLETE_FLAG(send_complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);\r
}\r
\r
IN NDIS_HANDLE adapter_context,\r
IN PVOID cancel_id )\r
{\r
-/* ipoib_adapter_t* const p_adapter =\r
+\r
+ ipoib_adapter_t* const p_adapter =\r
(ipoib_adapter_t* const )adapter_context;\r
\r
-\r
-if 0\r
if( p_adapter && p_adapter->p_port )\r
{\r
ipoib_port_cancel_xmit( p_adapter->p_port, cancel_id );\r
}\r
-endif\r
-*/\r
\r
- UNUSED_PARAM(adapter_context);\r
- UNUSED_PARAM(cancel_id);\r
-\r
- return; //TODO return this functionality\r
+ return;\r
\r
}\r
\r
\r
UNREFERENCED_PARAMETER(pause_parameters);\r
IPOIB_ENTER( IPOIB_DBG_INIT );\r
-//return NDIS_STATUS_SUCCESS;\r
+\r
CL_ASSERT(adapter_context);\r
p_adapter = (ipoib_adapter_t*)adapter_context;\r
CL_ASSERT(p_adapter->ipoib_state == IPOIB_RUNNING);\r
KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
p_adapter->ipoib_state = IPOIB_PAUSING;\r
KeReleaseInStackQueuedSpinLock( &hdl );\r
-\r
- //TODO: \r
- ipoib_port_resume(p_adapter->p_port,FALSE);\r
-// ASSERT(FALSE);\r
+ \r
+ if (p_adapter->p_port) {\r
+ //TODO improve this flow !\r
+ //TODO Be sure we stopped all sends and receives\r
+ cl_spinlock_acquire( &p_adapter->p_port->send_lock );\r
+ ipoib_port_resume(p_adapter->p_port,FALSE);\r
+ cl_spinlock_release( &p_adapter->p_port->send_lock );\r
+ }\r
\r
KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
p_adapter->ipoib_state = IPOIB_PAUSED;\r
* $Id: ipoib_port.c 4506 2009-06-23 14:40:54Z xalex $\r
*/\r
\r
+#include "precompile.h"\r
\r
-\r
-#include "ipoib_endpoint.h"\r
-#include "ipoib_port.h"\r
-#include "ipoib_adapter.h"\r
-#include "ipoib_debug.h"\r
#if defined(EVENT_TRACING)\r
#ifdef offsetof\r
#undef offsetof\r
#include "wdm.h"\r
#include <ntddk.h>\r
\r
+extern ULONG g_ipoib_send;\r
+extern ULONG g_ipoib_send_ack;\r
+extern ULONG g_ipoib_send_SW;\r
+extern ULONG g_ipoib_send_SG;\r
+extern ULONG g_ipoib_send_SW_in_loop;\r
+extern ULONG g_ipoib_send_SG_pending;\r
+extern ULONG g_ipoib_send_SG_real;\r
+extern ULONG g_ipoib_send_SG_failed;\r
+\r
+\r
\r
\r
ib_gid_t bcast_mgid_template = {\r
static void __recv_cb_dpc(KDPC *p_gc_dpc,void *context,void *s_arg1, void *s_arg2);\r
\r
\r
+#ifndef _IPOIB_DEBUG_NDIS6\r
+#define _IPOIB_DEBUG_NDIS6\r
+CL_INLINE void CL_API\r
+cl_qlist_check_validity(\r
+ IN cl_qlist_t* const p_list )\r
+{\r
+ cl_list_item_t *p_item;\r
+ size_t cnt = 0;\r
+\r
+ /* CL_ASSERT that a non-null pointer is provided. */\r
+ CL_ASSERT( p_list );\r
+ /* CL_ASSERT that the list was initialized. */\r
+ CL_ASSERT( p_list->state == CL_INITIALIZED );\r
+ p_item = cl_qlist_head(p_list);\r
+ while(p_item != cl_qlist_end(p_list)) {\r
+ ++cnt;\r
+ CL_ASSERT(p_item->p_list == p_list);\r
+ p_item = p_item->p_next;\r
+ CL_ASSERT (cnt <= p_list->count);\r
+ }\r
+ CL_ASSERT (cnt == p_list->count);\r
+ return;\r
+}\r
+#endif\r
+\r
/******************************************************************************\r
*\r
* Declarations\r
\r
//NDIS60\r
static inline NET_BUFFER_LIST*\r
-__buf_mgr_get_ndis_pkt(\r
+__buf_mgr_get_NBL(\r
IN ipoib_port_t* const p_port,\r
IN ipoib_recv_desc_t* const p_desc );\r
\r
IN ipoib_endpt_t* const p_dst );\r
\r
static ib_api_status_t\r
-__recv_mgr_prepare_pkt(\r
+__recv_mgr_prepare_NBL(\r
IN ipoib_port_t* const p_port,\r
IN ipoib_recv_desc_t* const p_desc,\r
OUT NET_BUFFER_LIST** const pp_net_buffer_list );\r
\r
static uint32_t\r
-__recv_mgr_build_pkt_array(\r
+__recv_mgr_build_NBL_array(\r
IN ipoib_port_t* const p_port,\r
- IN int32_t shortage,\r
- OUT cl_qlist_t* const p_done_list,\r
+ OUT cl_qlist_t* p_done_list,\r
OUT int32_t* const p_discarded );\r
\r
/******************************************************************************\r
__send_mgr_construct(\r
IN ipoib_port_t* const p_port );\r
\r
+static ib_api_status_t\r
+__send_mgr_init(\r
+ IN ipoib_port_t* const p_port );\r
+\r
+\r
static void\r
__send_mgr_destroy(\r
IN ipoib_port_t* const p_port );\r
IN ipoib_port_t* const p_port,\r
IN ipoib_send_desc_t* const p_desc,\r
IN SCATTER_GATHER_LIST *p_sgl,\r
- IN INT lso_data_index);\r
+ IN INT lso_data_index,\r
+ IN NET_BUFFER *p_netbuf);\r
\r
static NDIS_STATUS\r
__send_mgr_filter_ip(\r
IN MDL* p_mdl,\r
IN size_t buf_len,\r
IN SCATTER_GATHER_LIST *p_sgl,\r
- IN OUT ipoib_send_desc_t* const p_desc );\r
+ IN OUT ipoib_send_desc_t* const p_desc,\r
+ IN NET_BUFFER *p_netbuf);\r
\r
static NDIS_STATUS\r
__send_mgr_filter_igmp_v2(\r
IN const ip_hdr_t* const p_ip_hdr,\r
IN MDL* p_mdl,\r
IN size_t buf_len,\r
- IN SCATTER_GATHER_LIST *p_sgl,\r
IN OUT ipoib_send_desc_t* const p_desc );\r
\r
static NDIS_STATUS\r
IN MDL* const p_mdl,\r
IN const size_t mdl_len,\r
IN SCATTER_GATHER_LIST *p_sgl,\r
- IN OUT ipoib_send_desc_t* const p_desc );\r
+ IN OUT ipoib_send_desc_t* const p_desc,\r
+ IN NET_BUFFER *p_netbuf,\r
+ IN ipoib_send_NB_SG *s_buf);\r
\r
\r
static void\r
IN ULONG mss,\r
IN SCATTER_GATHER_LIST *p_sgl,\r
IN int32_t hdr_idx,\r
- IN PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO p_lso_info );\r
+ IN PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO p_lso_info,\r
+ IN NET_BUFFER *p_netbuf);\r
\r
static NDIS_STATUS\r
__send_fragments(\r
if ((p_port->obj.ref_cnt % 20)==0)\r
IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_OBJ,\r
("ref type %d ref_cnt %d\n", type, p_port->obj.ref_cnt) );\r
- //TODO remove\r
- //ASSERT (p_port->obj.ref_cnt < 100);\r
#else\r
UNREFERENCED_PARAMETER(type);\r
#endif\r
p_adapter->p_ifc->get_err_str( status )) );\r
return status;\r
}\r
+ \r
+ status =__send_mgr_init( p_port );\r
+ if( status != IB_SUCCESS )\r
+ {\r
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("__send_mgr_init returned %s\n", \r
+ p_adapter->p_ifc->get_err_str( status )) );\r
+ return status;\r
+ }\r
\r
/* Initialize the endpoint manager. */\r
status = __endpt_mgr_init( p_port );\r
cl_event_signal( &p_port->endpt_mgr.event );\r
}\r
#endif\r
- ASSERT(FALSE);\r
- //TODO NDIS6.0\r
+ cl_spinlock_acquire(&p_port->send_lock);\r
ipoib_port_resume( p_port, FALSE );\r
+ cl_spinlock_release(&p_port->send_lock);\r
\r
IPOIB_EXIT( IPOIB_DBG_INIT );\r
}\r
\r
\r
static inline NET_BUFFER_LIST*\r
-__buf_mgr_get_ndis_pkt(\r
+__buf_mgr_get_NBL(\r
IN ipoib_port_t* const p_port,\r
IN ipoib_recv_desc_t* const p_desc )\r
{\r
}\r
\r
NET_BUFFER_LIST_NEXT_NBL(p_net_buffer_list) = NULL;\r
- IPOIB_PORT_FROM_PACKET( p_net_buffer_list ) = p_port;\r
- IPOIB_RECV_FROM_PACKET( p_net_buffer_list ) = p_desc;\r
+ IPOIB_PORT_FROM_NBL( p_net_buffer_list ) = p_port;\r
+ IPOIB_RECV_FROM_NBL( p_net_buffer_list ) = p_desc;\r
p_net_buffer_list->SourceHandle = p_port->p_adapter->h_adapter;\r
\r
IPOIB_EXIT( IPOIB_DBG_RECV );\r
\r
cl_qlist_init( &p_port->recv_mgr.done_list );\r
\r
- p_port->recv_mgr.recv_pkt_array = NULL;\r
+ p_port->recv_mgr.recv_NBL_array = NULL;\r
\r
IPOIB_EXIT( IPOIB_DBG_INIT );\r
}\r
IPOIB_ENTER( IPOIB_DBG_INIT );\r
\r
/* Allocate the NDIS_PACKET pointer array for indicating receives. */\r
- p_port->recv_mgr.recv_pkt_array = (NET_BUFFER_LIST **)cl_malloc(\r
+ p_port->recv_mgr.recv_NBL_array = (NET_BUFFER_LIST **)cl_malloc(\r
sizeof(NET_BUFFER_LIST*) * p_port->p_adapter->params.rq_depth );\r
- if( !p_port->recv_mgr.recv_pkt_array )\r
+ if( !p_port->recv_mgr.recv_NBL_array )\r
{\r
NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,\r
EVENT_IPOIB_RECV_PKT_ARRAY, 0 );\r
CL_ASSERT( cl_is_qlist_empty( &p_port->recv_mgr.done_list ) );\r
CL_ASSERT( !p_port->recv_mgr.depth );\r
\r
- if( p_port->recv_mgr.recv_pkt_array )\r
- cl_free( p_port->recv_mgr.recv_pkt_array );\r
+ if( p_port->recv_mgr.recv_NBL_array )\r
+ cl_free( p_port->recv_mgr.recv_NBL_array );\r
\r
IPOIB_EXIT( IPOIB_DBG_INIT );\r
}\r
IN NET_BUFFER_LIST *p_net_buffer_lists,\r
IN ULONG return_flags)\r
{\r
-// cl_list_item_t *p_item;\r
ipoib_port_t *p_port;\r
ipoib_recv_desc_t *p_desc;\r
NET_BUFFER_LIST *cur_net_buffer_list,*next_net_buffer_list;\r
-// ib_api_status_t status = IB_NOT_DONE;\r
-// int32_t shortage;\r
-// ULONG complete_flags = 0;\r
+ int32_t shortage;\r
+ \r
PERF_DECLARE( ReturnPacket );\r
PERF_DECLARE( ReturnPutRecv );\r
PERF_DECLARE( ReturnRepostRecv );\r
{\r
next_net_buffer_list = NET_BUFFER_LIST_NEXT_NBL(cur_net_buffer_list);\r
\r
- /* Get the port and descriptor from the packet. */\r
- CL_ASSERT(p_port == IPOIB_PORT_FROM_PACKET( cur_net_buffer_list ));\r
- p_desc = IPOIB_RECV_FROM_PACKET( cur_net_buffer_list );\r
+ /* Get the port and descriptor from the NET_BUFFER_LIST. */\r
+ CL_ASSERT(p_port == IPOIB_PORT_FROM_NBL( cur_net_buffer_list ));\r
+ p_desc = IPOIB_RECV_FROM_NBL( cur_net_buffer_list );\r
\r
\r
//TODO: NDIS60, rewrite this block\r
- /* Get descriptor from the packet. */\r
-#if 0\r
+ \r
+#if 0 //TODO CM flow\r
if( p_desc->type == PKT_TYPE_CM_UCAST )\r
{\r
+ int32_t discarded;\r
+ uint32_t NBL_cnt = 0;\r
+ \r
+ ib_api_status_t status = IB_NOT_DONE;\r
+\r
+ \r
NDIS_BUFFER *p_buf;\r
\r
/* Unchain the NDIS buffer. */\r
__buf_mgr_put_recv( p_port, p_desc, cur_net_buffer_list );\r
cl_perf_stop( &p_port->p_adapter->perf, ReturnPutRecv );\r
}\r
-#if 0 \r
- /* Repost buffers. */\r
- cl_perf_start( ReturnRepostRecv );\r
- shortage = __recv_mgr_repost( p_port );\r
- cl_perf_stop( &p_port->p_adapter->perf, ReturnRepostRecv );\r
\r
- for( p_item = cl_qlist_remove_head( &p_port->recv_mgr.done_list );\r
- p_item != cl_qlist_end( &p_port->recv_mgr.done_list );\r
- p_item = cl_qlist_remove_head( &p_port->recv_mgr.done_list ) )\r
- {\r
- p_desc = (ipoib_recv_desc_t*)p_item;\r
\r
- cl_perf_start( ReturnPreparePkt );\r
- status = __recv_mgr_prepare_pkt( p_port, p_desc, &cur_net_buffer_list );\r
- cl_perf_stop( &p_port->p_adapter->perf, ReturnPreparePkt );\r
- if( status == IB_SUCCESS )\r
- {\r
- if( shortage > 0 )\r
- NET_BUFFER_LIST_STATUS( cur_net_buffer_list) = NDIS_STATUS_RESOURCES;\r
- else\r
- NET_BUFFER_LIST_STATUS( cur_net_buffer_list) = NDIS_STATUS_SUCCESS;\r
\r
- cl_spinlock_release( &p_port->recv_lock );\r
- NET_BUFFER_LIST_NEXT_NBL(cur_net_buffer_list) = NULL;\r
- cl_perf_start( ReturnNdisIndicate );\r
- NdisMRecvIndicate( p_port->p_adapter->h_adapter,\r
- cur_net_buffer_list, complete_flags );\r
- cl_perf_stop( &p_port->p_adapter->perf, ReturnNdisIndicate );\r
- cl_spinlock_acquire( &p_port->recv_lock );\r
-\r
- if( shortage > 0 )\r
- {\r
- cl_perf_start( ReturnPutRecv );\r
- __buf_mgr_put_recv( p_port, p_desc, cur_net_buffer_list );\r
- cl_perf_stop( &p_port->p_adapter->perf, ReturnPutRecv );\r
-\r
- /* Repost buffers. */\r
- cl_perf_start( ReturnRepostRecv );\r
- shortage = __recv_mgr_repost( p_port );\r
- cl_perf_stop( &p_port->p_adapter->perf, ReturnRepostRecv );\r
- }\r
- }\r
- else if( status != IB_NOT_DONE )\r
- {\r
- IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV,\r
- ("__recv_mgr_prepare_pkt returned %s\n",\r
- p_port->p_adapter->p_ifc->get_err_str( status )) );\r
- /* Return the item to the head of the list. */\r
- cl_qlist_insert_head( &p_port->recv_mgr.done_list, p_item );\r
- break;\r
- }\r
- }\r
- #endif\r
+ /* Repost buffers to HW */\r
+ cl_perf_start( ReturnRepostRecv );\r
+ shortage = __recv_mgr_repost( p_port );\r
+ cl_perf_stop( &p_port->p_adapter->perf, ReturnRepostRecv );\r
cl_spinlock_release( &p_port->recv_lock );\r
cl_perf_stop( &p_port->p_adapter->perf, ReturnPacket );\r
\r
ipoib_port_t *p_port;\r
ib_api_status_t status;\r
ib_wc_t wc[MAX_RECV_WC], *p_free, *p_wc;\r
- int32_t pkt_cnt, recv_cnt = 0, shortage, discarded;\r
+ int32_t NBL_cnt, recv_cnt = 0, shortage, discarded;\r
cl_qlist_t done_list, bad_list;\r
size_t i;\r
ULONG recv_complete_flags = 0;\r
PERF_DECLARE( PollRecv );\r
PERF_DECLARE( RepostRecv );\r
PERF_DECLARE( FilterRecv );\r
- PERF_DECLARE( BuildPktArray );\r
+ PERF_DECLARE( BuildNBLArray );\r
PERF_DECLARE( RecvNdisIndicate );\r
PERF_DECLARE( RearmRecv );\r
PERF_DECLARE( PutRecvList );\r
cl_perf_clr( RecvCompBundle );\r
\r
cl_perf_start( RecvCb );\r
-//return ;\r
+\r
UNUSED_PARAM( h_cq );\r
\r
NDIS_SET_SEND_COMPLETE_FLAG(recv_complete_flags, NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL );\r
recv_cnt += __recv_mgr_filter( p_port, p_wc, &done_list, &bad_list );\r
cl_perf_stop( &p_port->p_adapter->perf, FilterRecv );\r
\r
- } while( (!p_free) && (recv_cnt < 128));\r
+ } while( ( !p_free ) && ( recv_cnt < 16 )); //TODO restore back to 128\r
\r
/* We're done looking at the endpoint map, release the reference. */\r
cl_atomic_dec( &p_port->endpt_rdr );\r
\r
do\r
{\r
- int32_t cnt;\r
+ //int32_t cnt;\r
/* Repost ASAP so we don't starve the RQ. */\r
cl_perf_start( RepostRecv );\r
shortage = __recv_mgr_repost( p_port );\r
+ \r
+ if( shortage > 0 )\r
+ { \r
+ recv_complete_flags |= NDIS_RECEIVE_FLAGS_RESOURCES;\r
+ cl_dbg_out("Got SHORTAGE=%d\n",shortage);\r
+ }\r
+ \r
cl_perf_stop( &p_port->p_adapter->perf, RepostRecv );\r
\r
- cl_perf_start( BuildPktArray );\r
+ cl_perf_start( BuildNBLArray );\r
/* Notify NDIS of any and all possible receive buffers. */\r
- pkt_cnt = __recv_mgr_build_pkt_array(\r
- p_port, shortage, &done_list, &discarded );\r
- cl_perf_stop( &p_port->p_adapter->perf, BuildPktArray );\r
+ NBL_cnt = __recv_mgr_build_NBL_array(\r
+ p_port, &done_list, &discarded);\r
+ cl_perf_stop( &p_port->p_adapter->perf, BuildNBLArray );\r
\r
/* Only indicate receives if we actually had any. */\r
if( discarded && shortage > 0 )\r
cl_perf_stop( &p_port->p_adapter->perf, RepostRecv );\r
}\r
\r
- if( !pkt_cnt )\r
+ if( !NBL_cnt ) {\r
+ //cl_dbg_out("NBL cnt == 0 :-(\n");\r
break;\r
+ }\r
\r
cl_spinlock_release( &p_port->recv_lock );\r
- for( cnt = 0; cnt < pkt_cnt -1; cnt++)\r
- {\r
- NET_BUFFER_LIST_NEXT_NBL(p_port->recv_mgr.recv_pkt_array[cnt]) = \r
- p_port->recv_mgr.recv_pkt_array[cnt + 1];\r
- }\r
+\r
cl_perf_start( RecvNdisIndicate );\r
-#ifndef NDIS_DEFAULT_PORT_NUMBER\r
-#define NDIS_DEFAULT_PORT_NUMBER 0\r
-#endif\r
- IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
- ("Indicate NDIS with %d received NBs\n",\r
- pkt_cnt) );\r
+ \r
NdisMIndicateReceiveNetBufferLists(\r
p_port->p_adapter->h_adapter,\r
- p_port->recv_mgr.recv_pkt_array[0],\r
+ p_port->recv_mgr.recv_NBL_array[0],\r
NDIS_DEFAULT_PORT_NUMBER,\r
- pkt_cnt,\r
+ NBL_cnt,\r
recv_complete_flags);\r
\r
cl_perf_stop( &p_port->p_adapter->perf, RecvNdisIndicate );\r
*/\r
if( shortage > 0 )\r
{\r
- if( pkt_cnt < shortage )\r
- shortage = pkt_cnt;\r
\r
+ cl_dbg_out("GOT SHORTAGE <===============\n");\r
/* Return all but the last packet to the pool. */\r
cl_spinlock_acquire( &p_port->recv_lock );\r
- while( shortage-- > 1 )\r
+ //while( shortage-- > 1 )\r
+ while ( NBL_cnt-- > 0)\r
{\r
__buf_mgr_put_recv( p_port,\r
- (ipoib_recv_desc_t *)IPOIB_RECV_FROM_PACKET( p_port->recv_mgr.recv_pkt_array[shortage] ),\r
- p_port->recv_mgr.recv_pkt_array[shortage] );\r
+ (ipoib_recv_desc_t *)IPOIB_RECV_FROM_NBL( p_port->recv_mgr.recv_NBL_array[NBL_cnt] ),\r
+ p_port->recv_mgr.recv_NBL_array[NBL_cnt] );\r
}\r
+ __recv_mgr_repost( p_port );\r
cl_spinlock_release( &p_port->recv_lock );\r
\r
/*\r
* Return the last packet as if NDIS returned it, so that we repost\r
* and report any other pending receives.\r
*/\r
- ipoib_return_net_buffer_list( NULL, p_port->recv_mgr.recv_pkt_array[0],recv_complete_flags );\r
+ //ipoib_return_net_buffer_list( p_port, p_port->recv_mgr.recv_NBL_array[0],recv_complete_flags );\r
}\r
cl_spinlock_acquire( &p_port->recv_lock );\r
\r
- } while( pkt_cnt );\r
+ } while( NBL_cnt );\r
cl_spinlock_release( &p_port->recv_lock );\r
\r
if (p_free ) {\r
if( (p_ipoib->type.ip.prot.udp.hdr.dst_port == DHCP_PORT_SERVER &&\r
p_ipoib->type.ip.prot.udp.hdr.src_port == DHCP_PORT_CLIENT) ||\r
(p_ipoib->type.ip.prot.udp.hdr.dst_port == DHCP_PORT_CLIENT &&\r
- p_ipoib->type.ip.prot.udp.hdr.src_port == DHCP_PORT_SERVER) )\r
+ p_ipoib->type.ip.prot.udp.hdr.src_port == DHCP_PORT_SERVER)||\r
+ (p_ipoib->type.ip.prot.udp.hdr.dst_port == DHCP_PORT_PROXY_SERVER &&\r
+ p_ipoib->type.ip.prot.udp.hdr.src_port == DHCP_PORT_CLIENT) ||\r
+ (p_ipoib->type.ip.prot.udp.hdr.dst_port == DHCP_PORT_CLIENT &&\r
+ p_ipoib->type.ip.prot.udp.hdr.src_port == DHCP_PORT_PROXY_SERVER))\r
{\r
if( len < (sizeof(ipoib_hdr_t) + sizeof(ip_hdr_t) +\r
sizeof(udp_hdr_t) + DHCP_MIN_SIZE) )\r
dhcp_pkt_t *p_dhcp;\r
uint8_t *p_option;\r
uint8_t *p_cid = NULL;\r
- ib_gid_t gid;\r
uint8_t msg = 0;\r
\r
IPOIB_ENTER( IPOIB_DBG_RECV );\r
return IB_INVALID_PARAMETER;\r
}\r
\r
- p_option = &p_dhcp->options[4];\r
+ p_option = &p_dhcp->options[DHCP_COOKIE_SIZE];\r
while( *p_option != DHCP_OPT_END && p_option < &p_dhcp->options[312] )\r
{\r
switch( *p_option )\r
* accesses to the contents.\r
* Recover CID to standard type.\r
*/\r
- cl_memcpy( &gid, &p_cid[7], sizeof(ib_gid_t) );\r
- p_cid[1] = HW_ADDR_LEN +1;// CID length \r
- p_cid[2] = DHCP_HW_TYPE_ETH;// CID type \r
- status = ipoib_mac_from_guid( gid.unicast.interface_id, p_port->p_adapter->params.guid_mask, (mac_addr_t*)&p_cid[3] );\r
- if (status == IB_INVALID_GUID_MASK)\r
- {\r
- IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_ERROR,\r
- ("Invalid GUID mask received, rejecting it") );\r
- ipoib_create_log(p_port->p_adapter->h_adapter, GUID_MASK_LOG_INDEX, EVENT_IPOIB_WRONG_PARAMETER_WRN);\r
- status = IB_SUCCESS;\r
- }\r
- p_cid[HW_ADDR_LEN + 3] = DHCP_OPT_END; //terminate tag\r
+ p_cid[1] = sizeof (ib_net64_t) + 1;// CID length \r
+ p_cid[2] = DHCP_HW_TYPE_ETH;// CID type\r
+ RtlMoveMemory( &p_cid[3], &p_cid[15], sizeof (ib_net64_t) );\r
+ RtlFillMemory(&p_cid[11], 12, 0);\r
+\r
+ RtlCopyMemory( p_dhcp->chaddr, &p_src->mac, sizeof(p_src->mac) );\r
+ RtlFillMemory( &p_dhcp->chaddr[sizeof(p_src->mac)],\r
+ ( sizeof(p_dhcp->chaddr) - sizeof(p_src->mac) ), 0 );\r
}\r
IPOIB_EXIT( IPOIB_DBG_RECV );\r
return status;\r
\r
\r
static ib_api_status_t\r
-__recv_mgr_prepare_pkt(\r
+__recv_mgr_prepare_NBL(\r
IN ipoib_port_t* const p_port,\r
IN ipoib_recv_desc_t* const p_desc,\r
OUT NET_BUFFER_LIST** const pp_net_buffer_list )\r
{\r
type = IP_STAT_DROPPED;\r
status = NDIS_STATUS_FAILURE;\r
- IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_ERROR,\r
- ("Received UCAST PKT with ERROR !!!!\n"));\r
+ IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("Received UCAST PKT with ERROR !!!!\n"));\r
}\r
break;\r
case PKT_TYPE_BCAST:\r
/* OK to report. */\r
type = IP_STAT_BCAST_BYTES;\r
status = NDIS_STATUS_SUCCESS;\r
- IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_ERROR,\r
+ IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_RECV,\r
("Received BCAST PKT.\n"));\r
}\r
else\r
/* OK to report. */\r
type = IP_STAT_MCAST_BYTES;\r
status = NDIS_STATUS_SUCCESS;\r
- IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_ERROR,\r
+ IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_RECV,\r
("Received UCAST PKT.\n"));\r
}\r
else\r
ipoib_inc_recv_stat( p_port->p_adapter, type, 0, 0 );\r
/* Return the receive descriptor to the pool. */\r
__buf_mgr_put_recv( p_port, p_desc, NULL );\r
- IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_RECV,\r
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
("Packet filter doesn't match receive. Dropping.\n") );\r
/*\r
* Return IB_NOT_DONE since the packet has been completed,\r
}\r
\r
cl_perf_start( GetNdisPkt );\r
- *pp_net_buffer_list = __buf_mgr_get_ndis_pkt( p_port, p_desc );\r
+ *pp_net_buffer_list = __buf_mgr_get_NBL( p_port, p_desc );\r
cl_perf_stop( &p_port->p_adapter->perf, GetNdisPkt );\r
if( !*pp_net_buffer_list )\r
{\r
IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
- ("__buf_mgr_get_ndis_pkt failed\n") );\r
+ ("__buf_mgr_get_NBL failed\n") );\r
return IB_INSUFFICIENT_RESOURCES;\r
}\r
\r
chksum.Value = 0;\r
\r
-{\r
+\r
PNET_BUFFER NetBuffer = NET_BUFFER_LIST_FIRST_NB(*pp_net_buffer_list);\r
NET_BUFFER_DATA_LENGTH(NetBuffer) = p_desc->len;\r
-}\r
+\r
\r
switch( p_port->p_adapter->params.recv_chksum_offload )\r
{\r
default:\r
CL_ASSERT( FALSE );\r
case CSUM_DISABLED:\r
- //NDIS60\r
- //NDIS_PER_PACKET_INFO_FROM_PACKET( *pp_packet, TcpIpChecksumPacketInfo ) =\r
- //(void*)(uintn_t)chksum.Value;\r
NET_BUFFER_LIST_INFO(*pp_net_buffer_list, TcpIpChecksumNetBufferListInfo) = \r
(void*)(uintn_t)chksum.Value;\r
break;\r
/* Get the checksums directly from packet information. */\r
/* In this case, no one of cheksum's cat get false value */\r
/* If hardware checksum failed or wasn't calculated, NDIS will recalculate it again */\r
- //NDIS60\r
- //NDIS_PER_PACKET_INFO_FROM_PACKET( *pp_packet, TcpIpChecksumPacketInfo ) = \r
NET_BUFFER_LIST_INFO(*pp_net_buffer_list, TcpIpChecksumNetBufferListInfo) =\r
(void*)(uintn_t)(p_desc->ndis_csum.Value);\r
break;\r
\r
\r
static uint32_t\r
-__recv_mgr_build_pkt_array(\r
+__recv_mgr_build_NBL_array(\r
IN ipoib_port_t* const p_port,\r
- IN int32_t shortage,\r
- OUT cl_qlist_t* const p_done_list,\r
- OUT int32_t* const p_discarded )\r
+ OUT cl_qlist_t* p_done_list OPTIONAL,\r
+ OUT int32_t* const p_discarded)\r
{\r
cl_list_item_t *p_item;\r
ipoib_recv_desc_t *p_desc;\r
uint32_t i = 0;\r
ib_api_status_t status;\r
+ \r
PERF_DECLARE( PreparePkt );\r
\r
IPOIB_ENTER( IPOIB_DBG_RECV );\r
\r
*p_discarded = 0;\r
\r
- /* Move any existing receives to the head to preserve ordering. */\r
- cl_qlist_insert_list_head( p_done_list, &p_port->recv_mgr.done_list );\r
+ /* Move any existing receives to the head of p_done_list to preserve ordering. */\r
+ if ( p_done_list ) {\r
+ cl_qlist_insert_list_head( p_done_list, &p_port->recv_mgr.done_list );\r
+ } else {\r
+ p_done_list = &p_port->recv_mgr.done_list;\r
+ }\r
p_item = cl_qlist_remove_head( p_done_list );\r
while( p_item != cl_qlist_end( p_done_list ) )\r
{\r
p_desc = (ipoib_recv_desc_t*)p_item;\r
\r
cl_perf_start( PreparePkt );\r
- status = __recv_mgr_prepare_pkt( p_port, p_desc,\r
- &p_port->recv_mgr.recv_pkt_array[i] );\r
+ status = __recv_mgr_prepare_NBL( p_port, p_desc,\r
+ &p_port->recv_mgr.recv_NBL_array[i] );\r
cl_perf_stop( &p_port->p_adapter->perf, PreparePkt );\r
if( status == IB_SUCCESS )\r
{\r
- CL_ASSERT( p_port->recv_mgr.recv_pkt_array[i] );\r
- if( shortage-- > 0 )\r
- {\r
- NET_BUFFER_LIST_STATUS(p_port->recv_mgr.recv_pkt_array[i])= NDIS_STATUS_RESOURCES; \r
- }\r
- else\r
- {\r
- NET_BUFFER_LIST_STATUS(p_port->recv_mgr.recv_pkt_array[i])= NDIS_STATUS_SUCCESS;\r
- }\r
+ CL_ASSERT( p_port->recv_mgr.recv_NBL_array[i] );\r
+\r
+ if (i) {\r
+ // Link NBLs together\r
+ NET_BUFFER_LIST_NEXT_NBL(p_port->recv_mgr.recv_NBL_array[i-1]) = \r
+ p_port->recv_mgr.recv_NBL_array[i];\r
+ }\r
i++;\r
}\r
else if( status == IB_NOT_DONE )\r
}\r
else\r
{\r
- IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV,\r
- ("__recv_mgr_prepare_pkt returned %s\n",\r
+ IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("__recv_mgr_prepare_NBL returned %s\n",\r
p_port->p_adapter->p_ifc->get_err_str( status )) );\r
/* Put all completed receives on the port's done list. */\r
- cl_qlist_insert_tail( &p_port->recv_mgr.done_list, p_item );\r
- cl_qlist_insert_list_tail( &p_port->recv_mgr.done_list, p_done_list );\r
+ if ( p_done_list != &p_port->recv_mgr.done_list) {\r
+ cl_qlist_insert_tail( &p_port->recv_mgr.done_list, p_item );\r
+ cl_qlist_insert_list_tail( &p_port->recv_mgr.done_list, p_done_list );\r
+ } else {\r
+ cl_qlist_insert_head( &p_port->recv_mgr.done_list, p_item );\r
+ }\r
break;\r
}\r
\r
IPOIB_ENTER( IPOIB_DBG_SEND );\r
p_port->send_mgr.depth = 0;\r
cl_qlist_init( &p_port->send_mgr.pending_list );\r
+ cl_qpool_construct( &p_port->send_mgr.send_pool );\r
+ p_port->p_desc = NULL;\r
IPOIB_EXIT( IPOIB_DBG_SEND );\r
+ \r
+}\r
+\r
+static ib_api_status_t\r
+__send_mgr_init(\r
+ IN ipoib_port_t* const p_port )\r
+{\r
+ cl_status_t cl_status;\r
+ \r
+ IPOIB_ENTER(IPOIB_DBG_SEND );\r
+\r
+ CL_ASSERT( p_port );\r
+\r
+ static const size_t cPoolMaxSize(1000);\r
+ \r
+ /* Allocate the pool for async NETBUF flow (process_sg_list) */\r
+ cl_status = cl_qpool_init( &p_port->send_mgr.send_pool,\r
+ cPoolMaxSize,\r
+ 0, cPoolMaxSize, sizeof(ipoib_send_NB_SG), NULL, NULL, p_port );\r
+ \r
+ if( cl_status != CL_SUCCESS )\r
+ {\r
+ NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,\r
+ EVENT_IPOIB_RECV_POOL, 1, cl_status ); //TODO EVENT_IPOIB_SEND_POOL\r
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("cl_qpool_init for sends returned %#x\n",\r
+ cl_status) );\r
+ return IB_INSUFFICIENT_MEMORY;\r
+ }\r
+\r
+ //This send descriptor can't be allocated on the stack because of boundary violation !!!\r
+ p_port->p_desc = \r
+ (ipoib_send_desc_t *)ExAllocatePoolWithTag(NonPagedPool ,sizeof (ipoib_send_desc_t), 'XMXA');\r
+ if (!p_port->p_desc) {\r
+ NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,\r
+ EVENT_IPOIB_RECV_POOL, 1, CL_INSUFFICIENT_MEMORY); //TODO EVENT_IPOIB_SEND_POOL\r
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("Allocation of send descriptor failed\n") );\r
+ return IB_INSUFFICIENT_MEMORY;\r
+ }\r
+ return IB_SUCCESS;\r
}\r
\r
\r
__pending_list_destroy(\r
IN ipoib_port_t* const p_port )\r
{\r
- cl_list_item_t *p_item;\r
- NET_BUFFER_LIST **pp_net_buffer_list, *p_head;\r
- \r
- p_head = NULL;\r
+ cl_list_item_t *p_item;\r
+ ipoib_send_NB_SG *s_buf;\r
+ ULONG send_complete_flags = 0;\r
+\r
cl_spinlock_acquire( &p_port->send_lock );\r
/* Complete any pending packets. */\r
- pp_net_buffer_list = &p_head;\r
for( p_item = cl_qlist_remove_head( &p_port->send_mgr.pending_list );\r
p_item != cl_qlist_end( &p_port->send_mgr.pending_list );\r
p_item = cl_qlist_remove_head( &p_port->send_mgr.pending_list ) )\r
{\r
- *pp_net_buffer_list = IPOIB_PACKET_FROM_LIST_ITEM( p_item );\r
- NET_BUFFER_LIST_STATUS(*pp_net_buffer_list) = NDIS_STATUS_RESET_IN_PROGRESS;\r
- pp_net_buffer_list = &(NET_BUFFER_LIST_NEXT_NBL(*pp_net_buffer_list));\r
+ s_buf = (ipoib_send_NB_SG*) (PVOID) p_item; // TODO: Check this casting\r
+ ASSERT(s_buf->p_port == p_port);\r
+ ASSERT(s_buf->p_nbl);\r
+ IPOIB_DEC_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl);\r
+ \r
+ //Increase the send counter\r
+ ++g_ipoib_send;\r
+ \r
+ if (IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl) == 0) {\r
+ \r
+ NET_BUFFER_LIST_STATUS(s_buf->p_nbl) = NDIS_STATUS_RESET_IN_PROGRESS;\r
+ cl_spinlock_release( &p_port->send_lock );\r
+ if (NDIS_TEST_SEND_COMPLETE_AT_DISPATCH_LEVEL(send_complete_flags))\r
+ {\r
+ //TODO Tzachid: make an assert here to validate your IRQL\r
+ ASSERT (KeGetCurrentIrql() == DISPATCH_LEVEL);\r
+ NDIS_SET_SEND_COMPLETE_FLAG(send_complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);\r
+ } \r
+ NdisMSendNetBufferListsComplete(p_port->p_adapter->h_adapter,\r
+ s_buf->p_nbl,send_complete_flags);\r
+ cl_spinlock_acquire( &p_port->send_lock );\r
+ }\r
+ //Put back into the pool list structure allocated for the NB\r
+ cl_qpool_put(&p_port->send_mgr.send_pool, (cl_pool_item_t* )s_buf);\r
+\r
}\r
+\r
+\r
cl_spinlock_release( &p_port->send_lock );\r
- if(p_head)\r
- NdisMSendNetBufferListsComplete(\r
- p_port->p_adapter->h_adapter,\r
- p_head,\r
- 0); \r
+ \r
}\r
\r
static void\r
IN ipoib_port_t* const p_port )\r
{\r
IPOIB_ENTER( IPOIB_DBG_SEND );\r
+ //Destroy pending list and put all the send buffers back to pool\r
__pending_list_destroy(p_port);\r
\r
+ // Now, destroy the send pool\r
+ cl_qpool_destroy(&p_port->send_mgr.send_pool);\r
+\r
+ //Now, free port descriptor\r
+ ExFreePoolWithTag(p_port->p_desc, 'XMXA');\r
+ \r
+\r
IPOIB_EXIT( IPOIB_DBG_SEND );\r
}\r
\r
IN MDL* const p_mdl,\r
IN size_t buf_len,\r
IN SCATTER_GATHER_LIST *p_sgl,\r
- IN OUT ipoib_send_desc_t* const p_desc )\r
+ IN OUT ipoib_send_desc_t* const p_desc,\r
+ IN NET_BUFFER *p_netbuf)\r
{\r
NDIS_STATUS status;\r
\r
case ETH_PROT_TYPE_IP:\r
cl_perf_start( FilterIp );\r
status = __send_mgr_filter_ip(\r
- p_port, p_eth_hdr, p_mdl, buf_len, p_sgl, p_desc);\r
+ p_port, p_eth_hdr, p_mdl, buf_len, p_sgl, p_desc, p_netbuf);\r
cl_perf_stop( &p_port->p_adapter->perf, FilterIp );\r
break;\r
\r
\r
p_desc->send_dir = SEND_UD_QP;\r
cl_perf_start( SendGen );\r
- status = __send_gen( p_port, p_desc, p_sgl, 0 );\r
+ status = __send_gen( p_port, p_desc, p_sgl, 0, p_netbuf );\r
cl_perf_stop( &p_port->p_adapter->perf, SendGen );\r
break;\r
}\r
\r
#else\r
\r
-#if 0\r
-void \r
-ipoib_process_sg_list1(\r
- IN PDEVICE_OBJECT pDO,\r
- IN PVOID pIrp,\r
- IN PSCATTER_GATHER_LIST p_sgl,\r
- IN PVOID context\r
- )\r
-{\r
- int i;\r
- char temp[200];\r
- for (i = 0 ; i < 1;i++)\r
- temp[i] = 5;\r
-}\r
-#endif\r
\r
-void \r
-ipoib_process_sg_list(\r
+ULONG g_ipoib_send_mcast = 0;\r
+\r
+\r
+// returns true if buffer was sent\r
+bool \r
+ipoib_process_sg_list_real(\r
IN PDEVICE_OBJECT pDO,\r
IN PVOID pIrp,\r
IN PSCATTER_GATHER_LIST p_sgl,\r
MDL *p_mdl;\r
eth_hdr_t *p_eth_hdr;\r
UINT mdl_len;\r
- static ipoib_send_desc_t *p_desc = NULL;\r
+ bool ret = false;\r
+\r
ib_send_wr_t *p_wr_failed;\r
NET_BUFFER_LIST *p_net_buffer_list;\r
NET_BUFFER *p_netbuf;\r
\r
IPOIB_ENTER( IPOIB_DBG_SEND );\r
\r
+ ASSERT(p_sgl != NULL);\r
+\r
UNREFERENCED_PARAMETER(pDO);\r
UNREFERENCED_PARAMETER(pIrp);\r
\r
PERF_DECLARE( ProcessFailedSends );\r
PERF_DECLARE( GetEndpt );\r
\r
+ \r
+ ++g_ipoib_send_SG_real;\r
\r
- p_netbuf = (NET_BUFFER*)context;\r
- p_net_buffer_list = (NET_BUFFER_LIST*)IPOIB_NET_BUFFER_LIST_FROM_NETBUFFER(p_netbuf);\r
- p_port = (ipoib_port_t*)IPOIB_PORT_FROM_PACKET(p_net_buffer_list);\r
- NDIS_SET_SEND_COMPLETE_FLAG(complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);\r
+ //Read Data from the buffer passed as a context\r
+ ipoib_send_NB_SG * s_buf = (ipoib_send_NB_SG *)context;\r
+ p_net_buffer_list = s_buf->p_nbl;\r
+ p_netbuf = s_buf->p_curr_nb;\r
+ p_port = s_buf->p_port;\r
\r
+ //ASSERT(p_port->send_lock.lock == 1);\r
\r
- cl_spinlock_acquire( &p_port->send_lock );\r
- if (p_desc == NULL) {\r
- IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_SEND, ("Allocating send_desc First Time\n") );\r
- p_desc = \r
- (ipoib_send_desc_t *)ExAllocatePoolWithTag(NonPagedPool ,sizeof (ipoib_send_desc_t), 'XMXA');\r
- }\r
- ASSERT(p_desc);\r
- p_desc->p_netbuf_list = p_net_buffer_list;\r
- p_desc->p_endpt = NULL;\r
- p_desc->p_buf = NULL;\r
- p_desc->num_wrs = 1;\r
\r
- //IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SEND,\r
- // ("\n*******\nRECEIVED NB= %x with SG= %x\n********\n", p_netbuf, p_sgl) );\r
+\r
+ IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SEND,\r
+ ("Processing netbuffer list: %p \n", p_net_buffer_list) );\r
+\r
+\r
+\r
+ //TODO Define this function as void if we are not in DBG mode\r
+ cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
+ NDIS_SET_SEND_COMPLETE_FLAG(complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);\r
+\r
+ \r
+ p_port->p_desc->p_netbuf_list = p_net_buffer_list;\r
+ p_port->p_desc->p_endpt = NULL;\r
+ p_port->p_desc->p_buf = NULL;\r
+ p_port->p_desc->num_wrs = 1;\r
+\r
+ IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_SEND,\r
+ ("\nRECEIVED NB= %p with SG= %p\n********\n", p_netbuf, p_sgl) );\r
/* Get the ethernet header so we can find the endpoint. */\r
cl_perf_start( GetEthHdr );\r
status = __send_mgr_get_eth_hdr(\r
{\r
cl_perf_start( ProcessFailedSends );\r
/* fail net buffer list */\r
- __process_failed_send( p_port, p_desc, status, complete_flags);\r
+\r
+ //ASSERT(FALSE);\r
+ //TODO: Mark that we will not send it, and only if all netbuffers were completed complete it\r
+ // Check all __process_failed_send\r
+ cl_dbg_out("Failed send inside process SG list\n");\r
+ __process_failed_send( p_port, p_port->p_desc, status, complete_flags);\r
+ ++g_ipoib_send_SG_failed;\r
cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );\r
+ ret = true;\r
+ ++g_ipoib_send_SG_pending;\r
goto send_end;\r
}\r
- //from_queue = (boolean_t)(IPOIB_FROM_QUEUE(p_netbuf) == (void*)1);\r
- from_queue = (boolean_t)(IPOIB_FROM_QUEUE(p_netbuf) != NULL);\r
+ from_queue = (boolean_t)(s_buf->p_sgl != NULL);\r
if (from_queue)\r
{\r
cl_perf_start( GetEndpt );\r
- status = __endpt_mgr_ref( p_port, p_eth_hdr->dst, &p_desc->p_endpt );\r
+ status = __endpt_mgr_ref( p_port, p_eth_hdr->dst, &(p_port->p_desc->p_endpt) );\r
cl_perf_stop( &p_port->p_adapter->perf, GetEndpt );\r
if( status == NDIS_STATUS_PENDING )\r
{\r
- IPOIB_FROM_QUEUE(p_netbuf) = p_sgl;\r
+ s_buf->p_sgl = p_sgl;\r
cl_qlist_insert_head( &p_port->send_mgr.pending_list,\r
- IPOIB_LIST_ITEM_FROM_PACKET( p_desc->p_netbuf_list ) );\r
+ (cl_list_item_t*)s_buf );\r
+ //cl_dbg_out("We insert this item back to the pending list: %x \n", p_net_buffer_list);\r
+ ret = false;\r
goto send_end;\r
}\r
else if( status != NDIS_STATUS_SUCCESS )\r
\r
if( ETH_IS_MULTICAST( p_eth_hdr->dst.addr ) )\r
{\r
+ cl_dbg_out("recived a mc packet (from the queue) %p\n", p_net_buffer_list);\r
if( ipoib_port_join_mcast( p_port, p_eth_hdr->dst,\r
IB_MC_REC_STATE_FULL_MEMBER) == IB_SUCCESS )\r
{\r
IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SEND,\r
- ("Multicast Mac - trying to join.\n") );\r
- IPOIB_FROM_QUEUE(p_netbuf) = p_sgl;\r
- cl_qlist_insert_head( &p_port->send_mgr.pending_list,\r
- IPOIB_LIST_ITEM_FROM_PACKET( p_desc->p_netbuf_list ) );\r
+ ("Multicast Mac - trying to join ?????????????????.\n") );\r
+ s_buf->p_sgl = p_sgl;\r
+ cl_dbg_out("We insert this MULTICAST item back to the pending list: %x \n", p_net_buffer_list); \r
+ cl_qlist_insert_head( &p_port->send_mgr.pending_list, (cl_list_item_t*) s_buf );\r
+ ret = false;\r
+ ++g_ipoib_send_SG_pending;\r
goto send_end;\r
}\r
}\r
* Complete the send as if we sent it - WHQL tests don't like the\r
* sends to fail.\r
*/\r
+ cl_dbg_out("We got bad status and the packet had not been sent\n");\r
cl_perf_start( ProcessFailedSends );\r
- __process_failed_send( p_port, p_desc, NDIS_STATUS_SUCCESS,complete_flags );\r
+ __process_failed_send( p_port, p_port->p_desc, NDIS_STATUS_SUCCESS,complete_flags );\r
cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );\r
+ ret = true;\r
goto send_end;\r
}\r
+ s_buf->p_sgl = NULL;\r
}\r
else\r
{\r
+ ASSERT(s_buf->p_sgl ==NULL);\r
cl_perf_start( SendMgrQueue );\r
if ( ETH_IS_MULTICAST( p_eth_hdr->dst.addr ) && \r
p_eth_hdr->type == ETH_PROT_TYPE_IP &&\r
!ETH_IS_BROADCAST( p_eth_hdr->dst.addr ) ) \r
{\r
+\r
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_MCAST,\r
+ ("recived a Multicast NBL= %p\n", p_net_buffer_list) );\r
+\r
+ \r
+ \r
ip_hdr_t *p_ip_hdr;\r
uint8_t *p_tmp;\r
MDL *p_ip_hdr_mdl;\r
UINT ip_hdr_mdl_len;\r
-\r
+ \r
+ g_ipoib_send_mcast++;\r
+ \r
if(mdl_len >= sizeof(ip_hdr_t) + sizeof(eth_hdr_t))\r
{\r
p_ip_hdr = (ip_hdr_t*)(p_eth_hdr + 1);\r
goto mc_end;\r
}\r
p_ip_hdr = (ip_hdr_t*)(p_tmp + NET_BUFFER_CURRENT_MDL_OFFSET(p_netbuf));\r
- p_eth_hdr->dst.addr[1] = ((unsigned char*)&p_ip_hdr->dst_ip)[0] & 0x0f;\r
- p_eth_hdr->dst.addr[3] = ((unsigned char*)&p_ip_hdr->dst_ip)[1];\r
+ \r
}\r
+ \r
+ p_eth_hdr->dst.addr[1] = ((unsigned char*)&p_ip_hdr->dst_ip)[0] & 0x0f;\r
+ p_eth_hdr->dst.addr[3] = ((unsigned char*)&p_ip_hdr->dst_ip)[1];\r
+\r
}\r
+\r
mc_end:\r
- status = __send_mgr_queue( p_port, p_eth_hdr, &p_desc->p_endpt );\r
+ status = __send_mgr_queue( p_port, p_eth_hdr, &(p_port->p_desc->p_endpt) );\r
cl_perf_stop( &p_port->p_adapter->perf, SendMgrQueue );\r
if( status == NDIS_STATUS_PENDING )\r
{\r
/* Queue net buffer list. */\r
cl_perf_start( QueuePacket );\r
- NET_BUFFER_LIST_NEXT_NBL(p_net_buffer_list) = NULL;\r
- IPOIB_FROM_QUEUE(p_netbuf) = p_sgl;\r
- cl_qlist_insert_tail( &p_port->send_mgr.pending_list,\r
- IPOIB_LIST_ITEM_FROM_PACKET(p_net_buffer_list) );\r
+ s_buf->p_sgl = p_sgl;\r
+\r
+ cl_qlist_insert_tail( &p_port->send_mgr.pending_list, (cl_list_item_t*)s_buf );\r
+ //cl_dbg_out("Inserting %x NB first time to the pending list\n", p_netbuf);\r
+ \r
cl_perf_stop( &p_port->p_adapter->perf, QueuePacket );\r
+// cl_dbg_out("Fall into pending flow \n");\r
+ ++g_ipoib_send_SG_pending;\r
+ ret = false;\r
goto send_end;\r
}\r
if( status != NDIS_STATUS_SUCCESS )\r
* sends to fail.\r
*/\r
cl_perf_start( ProcessFailedSends );\r
- __process_failed_send( p_port, p_desc, NDIS_STATUS_SUCCESS, complete_flags );\r
+\r
+ // TODO: Need to make sure that we are not completing one part of the send\r
+ cl_dbg_out("Problem sending packet, got bad status\n");\r
+ \r
+ __process_failed_send( p_port, p_port->p_desc, NDIS_STATUS_SUCCESS, complete_flags );\r
cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );\r
+ ++g_ipoib_send_SG_failed;\r
+ ret = true;\r
goto send_end;\r
}\r
}\r
cl_perf_start( BuildSendDesc );\r
- status = __build_send_desc( p_port, p_eth_hdr, p_mdl, mdl_len, p_sgl, p_desc );\r
+ status = __build_send_desc( p_port, p_eth_hdr, p_mdl, mdl_len, p_sgl, p_port->p_desc, p_netbuf, s_buf );\r
cl_perf_stop( &p_port->p_adapter->perf, BuildSendDesc );\r
\r
if( status != NDIS_STATUS_SUCCESS )\r
{\r
+ ASSERT(FALSE);\r
cl_perf_start( ProcessFailedSends );\r
- __process_failed_send( p_port, p_desc, status, complete_flags );\r
+ __process_failed_send( p_port, p_port->p_desc, status, complete_flags );\r
cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );\r
+ ret = true;\r
goto send_end;\r
}\r
\r
/* Post the WR. */\r
cl_perf_start( PostSend );\r
- cl_msg_out("sending packet with wr-id =0x%x\n",&p_desc->send_wr[0].wr.wr_id );\r
- ib_status = p_port->p_adapter->p_ifc->post_send( p_port->ib_mgr.h_qp, &p_desc->send_wr[0].wr, &p_wr_failed );\r
+// cl_dbg_out("sending packet with wr-id =0x%x\n",p_net_buffer_list );\r
+ ++g_ipoib_send;\r
+ // IF this value is NULL, this netbuffer was already sent and when working on its NBL it will be not sent again\r
+ ASSERT(s_buf->p_sgl == NULL);\r
+ s_buf->p_sgl = p_sgl;\r
+ ib_status = p_port->p_adapter->p_ifc->post_send( p_port->ib_mgr.h_qp, &(p_port->p_desc->send_wr[0].wr), &p_wr_failed );\r
+ ret = true;\r
cl_perf_stop( &p_port->p_adapter->perf, PostSend );\r
if( ib_status != IB_SUCCESS )\r
{\r
("ib_post_send returned %s\n", \r
p_port->p_adapter->p_ifc->get_err_str( ib_status )) );\r
cl_perf_start( ProcessFailedSends );\r
- __process_failed_send( p_port, p_desc, NDIS_STATUS_FAILURE, complete_flags );\r
+ __process_failed_send( p_port, p_port->p_desc, NDIS_STATUS_FAILURE, complete_flags );\r
cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );\r
/* Flag the adapter as hung since posting is busted. */\r
p_port->p_adapter->hung = TRUE;\r
\r
send_end:\r
if (status != NDIS_STATUS_SUCCESS) {\r
+ //TODO Restore\r
// IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_SEND,\r
// ("Free S/G List: 0x%x.\n", (UINT) (PVOID) p_sgl) );\r
/*NdisMFreeNetBufferSGList(\r
}\r
\r
\r
- cl_spinlock_release( &p_port->send_lock );\r
IPOIB_EXIT( IPOIB_DBG_SEND );\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+void \r
+ipoib_process_sg_list(\r
+ IN PDEVICE_OBJECT pDO,\r
+ IN PVOID pIrp,\r
+ IN PSCATTER_GATHER_LIST p_sgl,\r
+ IN PVOID context\r
+ )\r
+{\r
+\r
+\r
+ ipoib_send_NB_SG * s_buf = (ipoib_send_NB_SG *)context;\r
+ ipoib_port_t* p_port = s_buf->p_port;\r
+\r
+\r
+ cl_spinlock_acquire( &p_port->send_lock );\r
+ ++g_ipoib_send_SG;\r
+ if (g_ipoib_send_SG > 2) {\r
+ ASSERT(g_ipoib_send_SG-2 <= g_ipoib_send + g_ipoib_send_mcast+p_port->send_mgr.pending_list.count+ g_ipoib_send_SG_failed);\r
+ }\r
+ ipoib_process_sg_list_real(pDO, pIrp, p_sgl, context);\r
+ if (g_ipoib_send_SG > 1) {\r
+ ASSERT(g_ipoib_send_SG-1 <= g_ipoib_send + g_ipoib_send_mcast+p_port->send_mgr.pending_list.count + g_ipoib_send_SG_failed);\r
+ }\r
+ cl_spinlock_release( &p_port->send_lock );\r
+\r
+ \r
}\r
\r
+\r
+\r
static NDIS_STATUS\r
__send_gen(\r
IN ipoib_port_t* const p_port,\r
IN ipoib_send_desc_t* const p_desc,\r
IN SCATTER_GATHER_LIST *p_sgl,\r
- IN INT lso_data_index\r
+ IN INT lso_data_index,\r
+ IN NET_BUFFER *p_netbuf\r
)\r
{\r
- NDIS_STATUS status;\r
- uint32_t i, j = 1;\r
- uint32_t offset = sizeof(eth_hdr_t);\r
+ NDIS_STATUS status;\r
+ uint32_t i, j = 1;\r
+ ULONG DataOffset = 0; \r
+ uint32_t offset = sizeof(eth_hdr_t);\r
+ \r
PERF_DECLARE( SendCopy );\r
\r
IPOIB_ENTER( IPOIB_DBG_SEND );\r
("Failed to get SGL from packet.\n") );\r
return NDIS_STATUS_FAILURE;\r
}\r
-\r
+ \r
/* Remember that one of the DS entries is reserved for the IPoIB header. */\r
if( ( p_sgl->NumberOfElements >= MAX_SEND_SGE ||\r
p_sgl->Elements[0].Length < sizeof(eth_hdr_t)) )\r
* or part of it.\r
*/\r
i = 0;\r
+ DataOffset= (ULONG)(NET_BUFFER_CURRENT_MDL_OFFSET(p_netbuf)); \r
+ \r
if( lso_data_index )\r
{ /* we have an LSO packet */\r
i = lso_data_index;\r
else\r
{\r
p_desc->send_wr[0].local_ds[j].vaddr =\r
- p_sgl->Elements[i].Address.QuadPart + offset;\r
+ p_sgl->Elements[i].Address.QuadPart + offset + DataOffset;\r
p_desc->send_wr[0].local_ds[j].length =\r
- p_sgl->Elements[i].Length - offset;\r
+ p_sgl->Elements[i].Length - offset - DataOffset;\r
p_desc->send_wr[0].local_ds[j].lkey = p_port->ib_mgr.lkey;\r
i++;\r
j++;\r
IN MDL* p_mdl,\r
IN size_t buf_len,\r
IN SCATTER_GATHER_LIST *p_sgl,\r
- IN OUT ipoib_send_desc_t* const p_desc )\r
+ IN OUT ipoib_send_desc_t* const p_desc,\r
+ IN NET_BUFFER *p_netbuf)\r
{\r
NDIS_STATUS status;\r
ip_hdr_t *p_ip_hdr;\r
\r
cl_perf_start( FilterUdp );\r
status = __send_mgr_filter_udp(\r
- p_port, p_ip_hdr, p_mdl, (buf_len - sizeof(ip_hdr_t)), p_sgl, p_desc );\r
+ p_port, p_ip_hdr, p_mdl, (buf_len - sizeof(ip_hdr_t)), p_desc );\r
cl_perf_stop( &p_port->p_adapter->perf, FilterUdp );\r
if( status == NDIS_STATUS_PENDING )\r
{ /* not DHCP packet, keep going */\r
\r
send_gen:\r
cl_perf_start( SendTcp );\r
- status = __send_gen( p_port, p_desc, p_sgl, 0 );\r
+ status = __send_gen( p_port, p_desc, p_sgl, 0, p_netbuf );\r
cl_perf_stop( &p_port->p_adapter->perf, SendTcp );\r
\r
IPOIB_EXIT( IPOIB_DBG_SEND );\r
IN const ip_hdr_t* const p_ip_hdr,\r
IN MDL* p_mdl,\r
IN size_t buf_len,\r
- IN SCATTER_GATHER_LIST *p_sgl,\r
IN OUT ipoib_send_desc_t* const p_desc )\r
{\r
NDIS_STATUS status;\r
PERF_DECLARE( QueryUdp );\r
PERF_DECLARE( SendUdp );\r
PERF_DECLARE( FilterDhcp );\r
- //TODO NDIS60 remove this param\r
- UNUSED_PARAM(p_sgl);\r
IPOIB_ENTER( IPOIB_DBG_SEND );\r
\r
if( !buf_len )\r
NdisFreeToNPagedLookasideList(\r
&p_port->buf_mgr.send_buf_list, p_desc->p_buf );\r
cl_qlist_insert_tail( &p_port->send_mgr.pending_list,\r
- IPOIB_LIST_ITEM_FROM_PACKET( p_desc->p_buf ) );\r
+ IPOIB_LIST_ITEM_FROM_NBL( p_desc->p_buf ) );\r
NdisInterlockedInsertTailList( &p_port->endpt_mgr.pending_conns, \r
&p_desc->p_endpt->list_item, \r
&p_port->endpt_mgr.conn_lock );\r
NdisFreeToNPagedLookasideList(\r
&p_port->buf_mgr.send_buf_list, p_desc->p_buf );\r
cl_qlist_insert_tail( &p_port->send_mgr.pending_list,\r
- IPOIB_LIST_ITEM_FROM_PACKET( p_desc->p_pkt ) );\r
+ IPOIB_LIST_ITEM_FROM_NBL( p_desc->p_pkt ) );\r
return NDIS_STATUS_PENDING;\r
default:\r
break;\r
IPOIB_ENTER( IPOIB_DBG_SEND );\r
\r
/* Check the send queue and pend the request if not empty. */\r
+ //No need in spinlock, this function is already under lock \r
if( cl_qlist_count( &p_port->send_mgr.pending_list ) )\r
{\r
IPOIB_PRINT_EXIT( TRACE_LEVEL_WARNING, IPOIB_DBG_SEND,\r
{\r
IPOIB_PRINT_EXIT( TRACE_LEVEL_WARNING, IPOIB_DBG_SEND,\r
("No available WQEs.\n") );\r
+ cl_dbg_out("HW is full\n");\r
return NDIS_STATUS_PENDING;\r
}\r
\r
IN MDL* const p_mdl,\r
IN const size_t mdl_len,\r
IN SCATTER_GATHER_LIST *p_sgl,\r
- IN OUT ipoib_send_desc_t* const p_desc )\r
+ IN OUT ipoib_send_desc_t* const p_desc,\r
+ IN NET_BUFFER *p_netbuf,\r
+ IN ipoib_send_NB_SG *s_buf)\r
{\r
NDIS_STATUS status;\r
int32_t hdr_idx;\r
uint32_t mss = 0;\r
\r
PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO p_checksum_list_info;\r
- PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO p_lso_info;\r
+ PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO p_lso_info = NULL;\r
PERF_DECLARE( SendMgrFilter );\r
\r
IPOIB_ENTER( IPOIB_DBG_SEND );\r
if (mss) { //We have LSO packet\r
ASSERT( mss == (p_lso_info->LsoV1Transmit.MSS & p_lso_info->LsoV2Transmit.MSS));\r
ASSERT ( (mss & (1<<20)) == mss);\r
- status = __build_lso_desc( p_port, p_desc, mss, p_sgl, hdr_idx, p_lso_info );\r
+ status = __build_lso_desc( p_port, p_desc, mss, p_sgl, hdr_idx, p_lso_info, p_netbuf);\r
if( status != NDIS_STATUS_SUCCESS )\r
{\r
IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
uint32_t i;\r
cl_perf_start( SendMgrFilter );\r
status = __send_mgr_filter(\r
- p_port, p_eth_hdr, p_mdl, mdl_len,p_sgl, p_desc );\r
+ p_port, p_eth_hdr, p_mdl, mdl_len,p_sgl, p_desc, p_netbuf );\r
cl_perf_stop( &p_port->p_adapter->perf, SendMgrFilter );\r
if( status != NDIS_STATUS_SUCCESS )\r
{\r
p_desc->send_wr[i].wr.dgrm.ud.rsvd = NULL;\r
p_desc->send_wr[i].wr.send_opt = 0;\r
\r
- if( p_port->p_adapter->params.send_chksum_offload && \r
+ if( p_port->p_adapter->params.send_chksum_offload &&\r
+ p_checksum_list_info &&\r
( p_checksum_list_info->Transmit.IsIPv4 || \r
p_checksum_list_info->Transmit.IsIPv6 ))\r
{\r
p_desc->send_wr[i-1].wr.p_next = &p_desc->send_wr[i].wr;\r
}\r
}\r
- //TODO p_net_buf or p_buf\r
-// p_desc->send_wr[p_desc->num_wrs - 1].wr.wr_id = (uintn_t)NET_BUFFER_LIST_FIRST_NB(p_desc->p_netbuf_list );\r
-//???? IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("WR_ID was set to NBL 0x%x \n",p_desc->p_netbuf_list ));\r
- p_desc->send_wr[p_desc->num_wrs - 1].wr.wr_id = (uintn_t)p_desc->p_netbuf_list ;\r
+ \r
+ p_desc->send_wr[p_desc->num_wrs - 1].wr.wr_id = (uintn_t)s_buf ;\r
\r
p_desc->send_wr[p_desc->num_wrs - 1].wr.send_opt |= IB_SEND_OPT_SIGNALED;\r
p_desc->send_wr[p_desc->num_wrs - 1].wr.p_next = NULL;\r
}\r
\r
/* Store context in our reserved area of the packet. */\r
- IPOIB_PORT_FROM_PACKET( p_desc->p_netbuf_list ) = p_port;\r
- IPOIB_ENDPT_FROM_PACKET( p_desc->p_netbuf_list ) = p_desc->p_endpt;\r
- IPOIB_SEND_FROM_NETBUFFER( NET_BUFFER_LIST_FIRST_NB(p_desc->p_netbuf_list ))= p_desc->p_buf;\r
\r
+ ASSERT(s_buf == (ipoib_send_NB_SG *) IPOIB_INFO_FROM_NB(p_netbuf));\r
+ s_buf->p_endpt = p_desc->p_endpt;\r
+ s_buf->p_send_buf= p_desc->p_buf;\r
+ \r
IPOIB_EXIT( IPOIB_DBG_SEND );\r
return NDIS_STATUS_SUCCESS;\r
}\r
IN ULONG mss,\r
IN SCATTER_GATHER_LIST *p_sgl,\r
IN int32_t hdr_idx, \r
- IN PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO p_lso_info)\r
+ IN PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO p_lso_info,\r
+ IN NET_BUFFER *p_netbuf)\r
{\r
NDIS_STATUS status;\r
LsoData TheLsoData;\r
p_desc->send_wr[0].wr.dgrm.ud.pkey_index = p_port->pkey_index;\r
p_desc->send_wr[0].wr.dgrm.ud.rsvd = NULL;\r
\r
- //TODO: Should be NBL or p_desc\r
+ //TODO: Should be NBL or p_desc SHOULD be s_buf\r
p_desc->send_wr[0].wr.wr_id = (uintn_t)p_desc->p_netbuf_list;\r
p_desc->send_wr[0].wr.ds_array = p_desc->send_wr[0].local_ds;\r
p_desc->send_wr[0].wr.wr_type = WR_LSO;\r
p_desc->send_wr[0].wr.p_next = NULL;\r
p_desc->send_qp = p_port->ib_mgr.h_qp;\r
p_desc->send_dir = SEND_UD_QP;\r
- status = __send_gen(p_port, p_desc, p_sgl, IndexOfData );\r
+ status = __send_gen(p_port, p_desc, p_sgl, IndexOfData, p_netbuf);\r
\r
IPOIB_EXIT( IPOIB_DBG_SEND );\r
return status;\r
IN const NDIS_STATUS status,\r
IN ULONG compl_flags)\r
{\r
+\r
+ cl_dbg_out("__process_failed_send called, chechk that things are ok\n");\r
+\r
IPOIB_ENTER( IPOIB_DBG_SEND );\r
+ PNET_BUFFER_LIST p_nbl = p_desc->p_netbuf_list;\r
\r
/* Complete the packet. */\r
NET_BUFFER_LIST_NEXT_NBL(p_desc->p_netbuf_list) = NULL;\r
NET_BUFFER_LIST_STATUS(p_desc->p_netbuf_list) = status;\r
- NdisMSendNetBufferListsComplete( p_port->p_adapter->h_adapter,\r
- p_desc->p_netbuf_list, compl_flags );\r
+ \r
+ IPOIB_DEC_NET_BUFFER_LIST_REF_COUNT(p_nbl);\r
+ if (IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(p_nbl) == 0) {\r
+ cl_spinlock_release( &p_port->send_lock );\r
+ NdisMSendNetBufferListsComplete( p_port->p_adapter->h_adapter,\r
+ p_nbl, compl_flags );\r
+ cl_spinlock_acquire( &p_port->send_lock );\r
+ }\r
+ \r
ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_ERROR, 0 );\r
/* Deref the endpoint. */\r
if( p_desc->p_endpt )\r
}\r
#endif\r
\r
-// ETH_EXIT(ETH_SND);\r
}\r
\r
\r
IN ULONG send_flags)\r
{\r
NDIS_STATUS status;\r
- PNET_BUFFER p_netbuf;\r
+ PNET_BUFFER p_netbuf, p_next_netbuf = NULL;\r
UINT buf_cnt = 0;\r
//ipoib_send_desc_t *p_desc;\r
ULONG send_complete_flags = 0;\r
+ \r
KIRQL old_irql;\r
- PVOID p_sgl;\r
\r
PERF_DECLARE( GetEthHdr );\r
PERF_DECLARE( BuildSendDesc );\r
if (NDIS_TEST_SEND_AT_DISPATCH_LEVEL(send_flags))\r
{\r
//TODO Tzachid: make an assert here to validate your IRQL\r
- //ASSERT (KeGetCurrentIRQL() == DISPATCH_LEVEL);\r
+ ASSERT (KeGetCurrentIrql() == DISPATCH_LEVEL);\r
+ old_irql = DISPATCH_LEVEL;\r
NDIS_SET_SEND_COMPLETE_FLAG(send_complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);\r
} else {\r
- //ASSERT (KeGetCurrentIRQL() == PASSIVE_LEVEL);\r
+ NDIS_RAISE_IRQL_TO_DISPATCH(&old_irql);\r
+ //ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL); // Happens\r
}\r
+ NDIS_SET_SEND_COMPLETE_FLAG(send_complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);\r
\r
cl_obj_lock( &p_port->obj );\r
if( p_port->state != IB_QPS_RTS )\r
\r
\r
NET_BUFFER_LIST_STATUS(p_net_buffer_list) = NDIS_STATUS_FAILURE;\r
- NET_BUFFER_LIST_NEXT_NBL(p_net_buffer_list) = NULL;\r
ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_DROPPED, 0 );\r
\r
NdisMSendNetBufferListsComplete(\r
return;\r
}\r
cl_obj_unlock( &p_port->obj );\r
- \r
- //IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
- // ("Processing netbuffer list: %x\n", p_net_buffer_list));\r
+\r
+ cl_spinlock_acquire( &p_port->send_lock );\r
+ // You are already here at dispatch\r
+\r
+\r
for (p_netbuf = NET_BUFFER_LIST_FIRST_NB(p_net_buffer_list);\r
p_netbuf != NULL; \r
p_netbuf = NET_BUFFER_NEXT_NB(p_netbuf))\r
{\r
- IPOIB_PORT_FROM_PACKET(p_net_buffer_list) = p_port;\r
- IPOIB_NET_BUFFER_LIST_FROM_NETBUFFER(p_netbuf) = p_net_buffer_list;\r
- IPOIB_FROM_QUEUE(p_netbuf) = NULL;\r
- /*p_desc = &p_port->send_mgr.desc;\r
- p_desc->p_buf = p_netbuf;\r
- p_desc->p_endpt = NULL;\r
- p_desc->p_buf = NULL;\r
- p_desc->send_qp = NULL;\r
- p_desc->num_wrs = 1;\r
- p_desc->send_dir = 0;*/\r
- \r
- old_irql = KeGetCurrentIrql();\r
- if (old_irql < DISPATCH_LEVEL) \r
- {\r
- KeRaiseIrqlToDpcLevel();\r
- }\r
+ ++g_ipoib_send_SW;\r
++buf_cnt;\r
- //IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
- // ("[%d] Netbuf = %x\n",buf_cnt, p_netbuf) );\r
- if (cl_is_item_in_qlist( &p_port->send_mgr.pending_list,\r
- IPOIB_LIST_ITEM_FROM_PACKET( p_net_buffer_list ))) {\r
- p_sgl = IPOIB_FROM_QUEUE(p_netbuf); \r
- //IPOIB_FROM_QUEUE(p_net_buffer) = (void*)1;\r
- ASSERT (p_sgl); \r
- //IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
- // ("[%d] FROM_QUEUE Netbuf = %x, found SGL = %x\n",buf_cnt, p_netbuf, p_sgl) );\r
- status = NDIS_STATUS_SUCCESS;\r
- } else {\r
+ }\r
+\r
+ IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_SEND,\r
+ ("Processing netbuffer list: %p buf_cnt = %d\n", p_net_buffer_list, buf_cnt));\r
+\r
+ ASSERT(buf_cnt);\r
+ // Raise reference count of the NBL to the number of its NBs\r
+ IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(p_net_buffer_list) = (PVOID)(ULONG_PTR)buf_cnt;\r
+\r
+ for (p_netbuf = NET_BUFFER_LIST_FIRST_NB(p_net_buffer_list);\r
+ p_netbuf != NULL; \r
+ p_netbuf = p_next_netbuf)\r
+ {\r
+ p_next_netbuf = NET_BUFFER_NEXT_NB(p_netbuf);\r
+\r
+ ipoib_send_NB_SG * s_buf = (ipoib_send_NB_SG*) (PVOID) (cl_qpool_get(&p_port->send_mgr.send_pool));\r
+ ASSERT(s_buf != NULL);// TODO: replace assert\r
+\r
+ //Set all the data needed for process_sg_list\r
+ s_buf->p_port = p_port;\r
+ s_buf->p_sgl = NULL;\r
+ s_buf->p_nbl = p_net_buffer_list;\r
+ s_buf->p_curr_nb = p_netbuf;\r
+\r
+ IPOIB_INFO_FROM_NB(p_netbuf) = s_buf;\r
+ \r
+ \r
+ IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_SEND,\r
+ ("Netbuf to send = %p\n", p_netbuf) );\r
\r
-//#if 0\r
+\r
+#if 0\r
CHAR *pTemp = (CHAR *) ExAllocatePoolWithTag(NonPagedPool , p_port->p_adapter->sg_list_size, 'abcd');\r
CL_ASSERT(pTemp != NULL);\r
- status = NDIS_STATUS_SUCCESS;\r
p_sgl = pTemp;\r
CreateFragList(NdisQueryNetBufferPhysicalCount(p_netbuf), p_netbuf, NET_BUFFER_DATA_LENGTH(p_netbuf), (PMP_FRAG_LIST) p_sgl);\r
IPOIB_FROM_QUEUE(p_netbuf) = NULL;\r
*/\r
ipoib_process_sg_list(NULL, NULL, (PSCATTER_GATHER_LIST)p_sgl, p_netbuf);\r
status = NDIS_STATUS_SUCCESS;\r
-//#endif\r
-#if 0 \r
+#else \r
+\r
+ //cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
+\r
+ cl_spinlock_release( &p_port->send_lock );\r
+\r
+\r
+ ++g_ipoib_send_SW_in_loop;\r
+ //TODO use preallocated SG pool\r
status = NdisMAllocateNetBufferSGList(\r
p_port->p_adapter->NdisMiniportDmaHandle,\r
p_netbuf,\r
- p_netbuf,\r
+ s_buf,\r
NDIS_SG_LIST_WRITE_TO_DEVICE,\r
NULL,\r
0);\r
+ \r
+ cl_spinlock_acquire( &p_port->send_lock );\r
+ //cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
#endif\r
- }\r
- KeLowerIrql (old_irql);\r
+// }\r
\r
if( status != NDIS_STATUS_SUCCESS )\r
{\r
+\r
+ ASSERT(FALSE);\r
+ // TODOD: There is a bug here if we have succeeded in sending some and failed\r
+ // with the otheres.\r
+\r
+ \r
/* fail net buffer list */\r
- NET_BUFFER_LIST_NEXT_NBL(p_net_buffer_list) = NULL;\r
- NET_BUFFER_LIST_STATUS(p_net_buffer_list) = NDIS_STATUS_RESOURCES;\r
+ NET_BUFFER_LIST_STATUS(p_net_buffer_list) = status;\r
NdisMSendNetBufferListsComplete(\r
p_port->p_adapter->h_adapter,\r
p_net_buffer_list,\r
send_complete_flags); \r
break;\r
}\r
- ASSERT(buf_cnt);\r
- IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(p_net_buffer_list) = (PVOID)(ULONG_PTR)buf_cnt;\r
}\r
- \r
+ \r
+ cl_spinlock_release( &p_port->send_lock );\r
+ NDIS_LOWER_IRQL(old_irql, DISPATCH_LEVEL);\r
}\r
\r
\r
IN ipoib_port_t* const p_port,\r
IN boolean_t b_pending )\r
{\r
- NDIS_STATUS status;\r
cl_list_item_t *p_item;\r
- NET_BUFFER *p_net_buffer;\r
- NET_BUFFER_LIST *p_net_buffer_list;\r
- //ipoib_send_desc_t *p_desc;\r
- KIRQL old_irql;\r
- UINT buf_cnt = 0;\r
- NET_BUFFER_LIST *p_prev_nbl = NULL;\r
- PVOID p_sgl;\r
- static PVOID p_prev_sgl = NULL;\r
+ ipoib_send_NB_SG *s_buf = NULL;\r
\r
PERF_DECLARE( GetEndpt );\r
PERF_DECLARE( BuildSendDesc );\r
cl_obj_lock( &p_port->obj );\r
if( p_port->state != IB_QPS_RTS )\r
{\r
- IPOIB_PRINT_EXIT( TRACE_LEVEL_WARNING, IPOIB_DBG_SEND,\r
+ // TODO: If there are packets that are not handeled, how will they get out of the\r
+ // queues\r
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_SEND,\r
("Invalid state - Aborting.\n") );\r
cl_obj_unlock( &p_port->obj );\r
return;\r
}\r
cl_obj_unlock( &p_port->obj );\r
\r
-//TODO NDIS60\r
-////?????????????? cl_spinlock_acquire( &p_port->send_lock );\r
\r
- for( p_item = cl_qlist_head( &p_port->send_mgr.pending_list );\r
- p_item != cl_qlist_end( &p_port->send_mgr.pending_list );\r
- p_item = cl_qlist_head( &p_port->send_mgr.pending_list ) )\r
+ if (p_port->send_mgr.pending_list.count <= 0) {\r
+ return;\r
+ };\r
+\r
+ p_item = cl_qlist_remove_head( &p_port->send_mgr.pending_list );\r
+ while (p_item != cl_qlist_end(&p_port->send_mgr.pending_list))\r
{\r
- \r
- \r
+ \r
/* Check the send queue and pend the request if not empty. */\r
if( p_port->send_mgr.depth == p_port->p_adapter->params.sq_depth )\r
{\r
+ \r
IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_SEND,\r
("No available WQEs.\n") );\r
+ cl_qlist_insert_head( &p_port->send_mgr.pending_list, p_item );\r
break;\r
}\r
- \r
- p_net_buffer_list = IPOIB_PACKET_FROM_LIST_ITEM(\r
- cl_qlist_remove_head( &p_port->send_mgr.pending_list ) );\r
- if (p_prev_nbl == p_net_buffer_list) {\r
-// IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
- // ("TRYING TO PROCESS ONCE AGAIN, EXITING: %x\n", p_net_buffer_list));\r
- break; //TODO more sophisticated mechanism to avoid starvation\r
- }\r
- old_irql = KeGetCurrentIrql();\r
- if (old_irql < DISPATCH_LEVEL) \r
- {\r
- KeRaiseIrqlToDpcLevel();\r
- }\r
-// IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
- // ("Processing netbuffer list from queue: %x\n", (UINT) (PVOID) p_net_buffer_list));\r
- \r
- for( p_net_buffer = NET_BUFFER_LIST_FIRST_NB(p_net_buffer_list);\r
- p_net_buffer != NULL;\r
- p_net_buffer = NET_BUFFER_NEXT_NB(p_net_buffer), buf_cnt++)\r
- {\r
\r
+ s_buf = (ipoib_send_NB_SG*) (PVOID) p_item; // TODO: Check this casting\r
\r
- p_sgl = IPOIB_FROM_QUEUE(p_net_buffer); \r
- //IPOIB_FROM_QUEUE(p_net_buffer) = (void*)1;\r
- ASSERT (p_sgl);\r
- IPOIB_PORT_FROM_PACKET(p_net_buffer_list) = p_port;\r
- IPOIB_NET_BUFFER_LIST_FROM_NETBUFFER(p_net_buffer) = p_net_buffer_list;\r
- /*p_desc = &p_port->send_mgr.desc;\r
- p_desc->p_buf = p_net_buffer;\r
- p_desc->p_endpt = NULL;\r
- p_desc->p_buf = NULL;\r
- p_desc->send_qp = NULL;\r
- p_desc->num_wrs = 1;\r
- p_desc->send_dir = 0;*/\r
-\r
-// IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
- // ("[%d] Netbuf = %x, p_sgl = %x\n",buf_cnt, p_net_buffer, p_sgl) );\r
- ASSERT(p_sgl);\r
- if (p_sgl != (void*) 1) {\r
- ipoib_process_sg_list(NULL, NULL, (PSCATTER_GATHER_LIST) p_sgl, p_net_buffer);\r
- status = NDIS_STATUS_SUCCESS;\r
- }\r
- else {\r
- ASSERT(FALSE);\r
- IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
- ("Getting strange flow\n") );\r
- NdisMFreeNetBufferSGList(\r
- p_port->p_adapter->NdisMiniportDmaHandle,\r
- (PSCATTER_GATHER_LIST)p_sgl,\r
- p_net_buffer );\r
- status = NdisMAllocateNetBufferSGList(\r
- p_port->p_adapter->NdisMiniportDmaHandle,\r
- p_net_buffer,\r
- p_net_buffer,\r
- NDIS_SG_LIST_WRITE_TO_DEVICE,\r
- NULL,\r
- 0 /*p_port->p_adapter->sg_list_size*/ );\r
- }\r
- p_prev_sgl = p_sgl; \r
- if( status != NDIS_STATUS_SUCCESS )\r
- {\r
- /* fail net buffer list */\r
- NET_BUFFER_LIST_NEXT_NBL(p_net_buffer_list) = NULL;\r
- NET_BUFFER_LIST_STATUS(p_net_buffer_list) = NDIS_STATUS_RESOURCES;\r
- NdisMSendNetBufferListsComplete(\r
- p_port->p_adapter->h_adapter,\r
- p_net_buffer_list,\r
- 0); \r
- break;\r
- }\r
+ bool continue_sending = ipoib_process_sg_list_real(NULL, NULL, (PSCATTER_GATHER_LIST) s_buf->p_sgl, s_buf);\r
+\r
+ cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
+\r
+ if (!continue_sending) {\r
+ ASSERT (cl_is_item_in_qlist(&p_port->send_mgr.pending_list, (cl_list_item_t*)(PVOID)s_buf));\r
+ goto Cleanup;\r
}\r
- \r
- KeLowerIrql (old_irql);\r
- \r
- \r
- p_prev_nbl = p_net_buffer_list;\r
- \r
+\r
+ \r
+ p_item = cl_qlist_remove_head( &p_port->send_mgr.pending_list );\r
}\r
+Cleanup:\r
IPOIB_EXIT( IPOIB_DBG_SEND );\r
}\r
\r
-\r
+//TODO: use s_buf-><data_member> directly, instead of useless copies\r
\r
static void\r
__send_cb(\r
ib_api_status_t status;\r
ib_wc_t wc[MAX_SEND_WC], *p_wc, *p_free;\r
cl_qlist_t done_list;\r
- NET_BUFFER_LIST *p_nbl;\r
uint32_t length;\r
ipoib_endpt_t *p_endpt;\r
send_buf_t *p_send_buf;\r
ip_stat_sel_t type;\r
size_t i;\r
NET_BUFFER *p_netbuffer = NULL;\r
+ ipoib_send_NB_SG *s_buf;\r
\r
PERF_DECLARE( SendCompBundle );\r
PERF_DECLARE( SendCb );\r
\r
IPOIB_ENTER( IPOIB_DBG_SEND );\r
\r
+\r
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);\r
+\r
cl_perf_clr( SendCompBundle );\r
\r
cl_perf_start( SendCb );\r
\r
UNUSED_PARAM( h_cq );\r
\r
+ \r
cl_qlist_init( &done_list );\r
+ \r
\r
p_port = (ipoib_port_t*)cq_context;\r
-\r
+ cl_spinlock_acquire( &p_port->send_lock );\r
+ cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
ipoib_port_ref( p_port, ref_send_cb );\r
\r
for( i = 0; i < MAX_SEND_WC; i++ )\r
{\r
cl_perf_start( SendComp );\r
CL_ASSERT( p_wc->status != IB_WCS_SUCCESS || p_wc->wc_type == IB_WC_SEND );\r
- p_nbl = (NET_BUFFER_LIST*)(uintn_t)p_wc->wr_id;\r
- //IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_SEND,\r
- //("[1]Successfull send completion for NBL=0x%x .\n", (UINT) (PVOID) p_nbl ));\r
- CL_ASSERT( p_nbl );\r
- CL_ASSERT( IPOIB_PORT_FROM_PACKET( p_nbl ) == p_port );\r
+ s_buf = (ipoib_send_NB_SG*)(uintn_t)p_wc->wr_id;\r
+ IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_SEND,\r
+ ("Successfull send completion for NBL=0x%p .\n", s_buf->p_nbl ));\r
+ CL_ASSERT( s_buf );\r
+\r
+\r
+ ++g_ipoib_send_ack;\r
length = 0;\r
- p_endpt = IPOIB_ENDPT_FROM_PACKET( p_nbl );\r
- p_send_buf = IPOIB_SEND_FROM_NETBUFFER( NET_BUFFER_LIST_FIRST_NB (p_nbl ));\r
- \r
+ p_endpt = s_buf->p_endpt;\r
+ p_send_buf = s_buf->p_send_buf;\r
+\r
+ //Free SGL element allocated by NDIS\r
+ //TODO free SGL also each time we decide not to send (before post_send)\r
+\r
+ NdisMFreeNetBufferSGList(\r
+ p_port->p_adapter->NdisMiniportDmaHandle,\r
+ s_buf->p_sgl,\r
+ s_buf->p_curr_nb);\r
+\r
+ NDIS_STATUS status = NDIS_STATUS_FAILURE;\r
switch( p_wc->status )\r
{\r
+ \r
case IB_WCS_SUCCESS:\r
if( p_endpt->h_mcast )\r
{\r
{\r
type = IP_STAT_UCAST_BYTES;\r
}\r
- for (p_netbuffer = NET_BUFFER_LIST_FIRST_NB(p_nbl);\r
- p_netbuffer != NULL;\r
- p_netbuffer = NET_BUFFER_NEXT_NB(p_netbuffer))\r
- {\r
- length += NET_BUFFER_DATA_LENGTH(p_netbuffer);\r
- } \r
- ipoib_inc_send_stat( p_port->p_adapter, type, length );\r
- // IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_SEND,\r
- //("Successfull send completion for NBL=0x%x .\n", (UINT) (PVOID) p_nbl) );\r
- NET_BUFFER_LIST_STATUS(p_nbl) = NDIS_STATUS_SUCCESS;\r
- IPOIB_DEC_NET_BUFFER_LIST_REF_COUNT(p_nbl);\r
- if (IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(p_nbl) == 0)\r
- NdisMSendNetBufferListsComplete(p_port->p_adapter->h_adapter,\r
- p_nbl,\r
- 0);\r
+\r
+ p_netbuffer = s_buf->p_curr_nb;\r
+ ipoib_inc_send_stat( p_port->p_adapter, type, NET_BUFFER_DATA_LENGTH(p_netbuffer) ); \r
+ status = NDIS_STATUS_SUCCESS;\r
break;\r
\r
case IB_WCS_WR_FLUSHED_ERR:\r
IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_SEND,\r
("Flushed send completion.\n") );\r
ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_DROPPED, 0 );\r
- NET_BUFFER_LIST_STATUS(p_nbl) = NDIS_STATUS_RESET_IN_PROGRESS;\r
- NdisMSendNetBufferListsComplete(p_port->p_adapter->h_adapter,\r
- p_nbl,\r
- 0); \r
+ status = NDIS_STATUS_RESET_IN_PROGRESS;\r
+ \r
break;\r
\r
default:\r
p_port->p_adapter->p_ifc->get_wc_status_str( p_wc->status ),\r
(int)p_wc->vendor_specific) );\r
ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_ERROR, 0 );\r
- NET_BUFFER_LIST_STATUS(p_nbl) = NDIS_STATUS_FAILURE;\r
- NdisMSendNetBufferListsComplete(p_port->p_adapter->h_adapter,\r
- p_nbl,\r
- 0); \r
+ status = NDIS_STATUS_FAILURE;\r
+ \r
break;\r
}\r
+ IPOIB_DEC_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl);\r
+ if (IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl) == 0) {\r
+ \r
+\r
+ NET_BUFFER_LIST_STATUS(s_buf->p_nbl) = status;\r
+ NdisMSendNetBufferListsComplete(p_port->p_adapter->h_adapter,\r
+ s_buf->p_nbl,\r
+ NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL); \r
+ }\r
+ \r
+ //Put back into the pool list structure allocated for the NB\r
+ cl_qpool_put(&p_port->send_mgr.send_pool, (cl_pool_item_t* )s_buf);\r
+ \r
cl_perf_stop( &p_port->p_adapter->perf, SendComp );\r
/* Dereference the enpoint used for the transfer. */\r
ipoib_endpt_deref( p_endpt );\r
\r
if( p_send_buf )\r
{\r
+ //TODO restore \r
cl_perf_start( FreeSendBuf );\r
NdisFreeToNPagedLookasideList( &p_port->buf_mgr.send_buf_list,\r
p_send_buf );\r
/* If we didn't use up every WC, break out. */\r
} while( !p_free );\r
\r
+\r
+ /* Resume any sends awaiting resources. */\r
+ cl_perf_start( PortResume );\r
+ ipoib_port_resume( p_port, TRUE );\r
+ cl_perf_stop( &p_port->p_adapter->perf, PortResume );\r
+\r
/* Rearm the CQ. */\r
cl_perf_start( RearmSend );\r
status = p_port->p_adapter->p_ifc->rearm_cq( p_port->ib_mgr.h_send_cq, FALSE );\r
cl_perf_stop( &p_port->p_adapter->perf, RearmSend );\r
CL_ASSERT( status == IB_SUCCESS );\r
\r
- /* Resume any sends awaiting resources. */\r
- cl_perf_start( PortResume );\r
- ipoib_port_resume( p_port, TRUE );\r
- cl_perf_stop( &p_port->p_adapter->perf, PortResume );\r
\r
ipoib_port_deref( p_port, ref_send_cb );\r
\r
cl_perf_stop( &p_port->p_adapter->perf, SendCb );\r
cl_perf_update_ctr( &p_port->p_adapter->perf, SendCompBundle );\r
-\r
+ cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
+ cl_spinlock_release( &p_port->send_lock );\r
IPOIB_EXIT( IPOIB_DBG_SEND );\r
+ \r
}\r
\r
\r
&p_port->p_local_endpt->gid_item );\r
cl_qmap_remove_item( &p_port->endpt_mgr.mac_endpts,\r
&p_port->p_local_endpt->mac_item );\r
- cl_qmap_remove_item( &p_port->endpt_mgr.lid_endpts,\r
- &p_port->p_local_endpt->lid_item );\r
+ if( p_port->p_local_endpt->dlid ) {\r
+ cl_qmap_remove_item( &p_port->endpt_mgr.lid_endpts,\r
+ &p_port->p_local_endpt->lid_item );\r
+ p_port->p_local_endpt->dlid = 0;\r
+ }\r
\r
cl_qlist_insert_head(\r
&mc_list, &p_port->p_local_endpt->mac_item.pool_item.list_item );\r
{\r
cl_qmap_remove_item(\r
&p_port->endpt_mgr.lid_endpts, &p_endpt->lid_item );\r
+ p_endpt->dlid = 0;\r
}\r
\r
cl_obj_unlock( &p_port->obj );\r
if( status != IB_SUCCESS )\r
{\r
ipoib_port_deref( p_port, ref_get_bcast );\r
- ASSERT(FALSE);\r
+// ASSERT(FALSE);\r
IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
("ib_query returned %s\n", \r
p_port->p_adapter->p_ifc->get_err_str( status )) );\r
switch( __endpt_mgr_ref( p_port, mac, &p_endpt ) )\r
{\r
case NDIS_STATUS_NO_ROUTE_TO_DESTINATION:\r
+ IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_MCAST,\r
+ ("NDIS_STATUS_NO_ROUTE_TO_DESTINATION\n") );\r
break;\r
\r
case NDIS_STATUS_SUCCESS:\r
/* Fall through */\r
\r
case NDIS_STATUS_PENDING:\r
+ IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_MCAST,\r
+ ("<ipoib_port_join_mcast> PENDING\n") );\r
return IB_SUCCESS;\r
}\r
\r
("ib_join_mcast returned %s\n", \r
p_port->p_adapter->p_ifc->get_err_str( status )) );\r
}\r
+ IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_MCAST,\r
+ ("Joined MCAST group with MGID[10:15]= %0x %0x %0x %0x %0x %0x\n",\r
+ mcast_req.member_rec.mgid.raw[10],\r
+ mcast_req.member_rec.mgid.raw[11],\r
+ mcast_req.member_rec.mgid.raw[12],\r
+ mcast_req.member_rec.mgid.raw[13],\r
+ mcast_req.member_rec.mgid.raw[14],\r
+ mcast_req.member_rec.mgid.raw[15]) );\r
\r
IPOIB_EXIT( IPOIB_DBG_MCAST );\r
return status;\r
cl_obj_unlock( &p_port->obj );\r
\r
/* Try to send all pending sends. */\r
- ipoib_port_resume( p_port , FALSE);\r
+ cl_spinlock_acquire( &p_port->send_lock );\r
+ cl_dbg_out("Calling ipoib_port_resume from mcast_cb\n");\r
+ ipoib_port_resume(p_port , FALSE);\r
+ cl_spinlock_release( &p_port->send_lock );\r
\r
ipoib_port_deref( p_port, ref_join_mcast );\r
\r
IN ipoib_port_t* const p_port,\r
IN PVOID cancel_id )\r
{\r
- cl_list_item_t *p_item;\r
- PNET_BUFFER_LIST p_nbl;\r
+ cl_list_item_t *p_item, *p_next;\r
+ ipoib_send_NB_SG *s_buf;\r
PVOID nbl_id;\r
cl_qlist_t cancel_list;\r
ULONG send_complete_flags = 0;\r
IPOIB_ENTER( IPOIB_DBG_SEND );\r
\r
cl_qlist_init( &cancel_list );\r
+ \r
+ ASSERT(FALSE); //TODO ???????????????? Do we reach here ????????????\r
\r
cl_spinlock_acquire( &p_port->send_lock );\r
\r
+ \r
+\r
for( p_item = cl_qlist_head( &p_port->send_mgr.pending_list );\r
p_item != cl_qlist_end( &p_port->send_mgr.pending_list );\r
- p_item = cl_qlist_next( p_item ) )\r
+ p_item = p_next )\r
{\r
- p_nbl = IPOIB_PACKET_FROM_LIST_ITEM( p_item );\r
- nbl_id = NDIS_GET_NET_BUFFER_LIST_CANCEL_ID( p_nbl );\r
+ p_next = cl_qlist_next( p_item );\r
+ s_buf = (ipoib_send_NB_SG*) (PVOID) p_item; // TODO: Check this casting\r
+ nbl_id = NDIS_GET_NET_BUFFER_LIST_CANCEL_ID( s_buf->p_nbl );\r
if( nbl_id == cancel_id )\r
{\r
cl_qlist_remove_item( &p_port->send_mgr.pending_list, p_item );\r
- NET_BUFFER_LIST_STATUS( p_nbl) = NDIS_STATUS_REQUEST_ABORTED ;\r
- cl_qlist_insert_tail( &cancel_list, IPOIB_LIST_ITEM_FROM_PACKET( p_nbl ) );\r
+ NET_BUFFER_LIST_STATUS( s_buf->p_nbl) = NDIS_STATUS_REQUEST_ABORTED ;\r
+ cl_qlist_insert_tail( &cancel_list, (cl_list_item_t *) s_buf );\r
}\r
}\r
cl_spinlock_release( &p_port->send_lock );\r
while( ( p_item = cl_qlist_remove_head( &cancel_list )) \r
!= cl_qlist_end( &cancel_list ))\r
{\r
- p_nbl = IPOIB_PACKET_FROM_LIST_ITEM( p_item );\r
- NET_BUFFER_LIST_STATUS( p_nbl) = NDIS_STATUS_SEND_ABORTED;\r
- send_complete_flags = 0;\r
- if (NDIS_CURRENT_IRQL() == DISPATCH_LEVEL)\r
- {\r
- NDIS_SET_SEND_COMPLETE_FLAG(send_complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);\r
- }\r
- NdisMSendNetBufferListsComplete( p_port->p_adapter->h_adapter,\r
- p_nbl, send_complete_flags );\r
+ s_buf = (ipoib_send_NB_SG*) (PVOID) p_item;\r
+ IPOIB_DEC_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl);\r
+ if (IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl) == 0) {\r
+ \r
+ NET_BUFFER_LIST_STATUS(s_buf->p_nbl) = NDIS_STATUS_SEND_ABORTED;\r
+ send_complete_flags = 0;\r
+ if (NDIS_CURRENT_IRQL() == DISPATCH_LEVEL)\r
+ {\r
+ NDIS_SET_SEND_COMPLETE_FLAG(send_complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);\r
+ }\r
+ NdisMSendNetBufferListsComplete(p_port->p_adapter->h_adapter,\r
+ s_buf->p_nbl, send_complete_flags);\r
+ \r
+ }\r
}\r
}\r
+ //TODO free send buffers !\r
IPOIB_EXIT( IPOIB_DBG_SEND );\r
}\r
\r