From 6dc3311225eb9dfcf0c55ef096e520f45b7e67a9 Mon Sep 17 00:00:00 2001 From: Stan Smith Date: Mon, 15 Nov 2010 20:05:46 +0000 Subject: [PATCH] [WOF2-3] integrate trunk commits 2980 - 2989 git-svn-id: svn://openib.tc.cornell.edu/gen1@2991 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- branches/WOF2-3/inc/complib/cl_log.h | 2 +- branches/WOF2-3/inc/kernel/ip_packet.h | 80 +++++- .../WOF2-3/ulp/ipoib_NDIS6_CM/kernel/SOURCES | 2 +- .../ipoib_NDIS6_CM/kernel/ipoib_adapter.cpp | 16 +- .../ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.h | 1 + .../ulp/ipoib_NDIS6_CM/kernel/ipoib_debug.h | 1 + .../ipoib_NDIS6_CM/kernel/ipoib_driver.cpp | 32 +-- .../ulp/ipoib_NDIS6_CM/kernel/ipoib_ibat.cpp | 4 + .../ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp | 244 ++++++++++++++---- .../ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h | 4 + .../ulp/ipoib_NDIS6_CM/kernel/precompile.h | 10 +- 11 files changed, 311 insertions(+), 85 deletions(-) diff --git a/branches/WOF2-3/inc/complib/cl_log.h b/branches/WOF2-3/inc/complib/cl_log.h index 1563cbe7..d78e6258 100644 --- a/branches/WOF2-3/inc/complib/cl_log.h +++ b/branches/WOF2-3/inc/complib/cl_log.h @@ -214,7 +214,7 @@ cl_event_log_write( extern WCHAR g_cl_wlog[ CL_LOG_BUF_LEN ]; extern UCHAR g_cl_slog[ CL_LOG_BUF_LEN ]; -static void __build_str( const char * format, ... ) +static inline void __build_str( const char * format, ... ) { NTSTATUS status; va_list p_arg; diff --git a/branches/WOF2-3/inc/kernel/ip_packet.h b/branches/WOF2-3/inc/kernel/ip_packet.h index 663729da..6c7ddf77 100644 --- a/branches/WOF2-3/inc/kernel/ip_packet.h +++ b/branches/WOF2-3/inc/kernel/ip_packet.h @@ -200,6 +200,7 @@ typedef struct _arp_pkt #define IP_PROT_UDP 17 #define IP_PROT_IGMP 2 #define IP_PROT_ICMP 1 +#define IP_PROT_ICMPV6 58 #include @@ -263,6 +264,72 @@ typedef struct _ip_hdr *********/ #include +#include +/****s* IB Network Drivers/ipv6_hdr_t +* NAME +* ipv6_hdr_t +* +* DESCRIPTION +* Defines the IPV6 header for IPV6 packets. +* +* SYNOPSIS +*/ +typedef struct _ipv6_hdr +{ + uint32_t ver_tc_fl; + uint16_t payload_length; + uint8_t next_header; + uint8_t hop_limit; + uint8_t src_addr[16]; + uint8_t dest_addr[16]; + +} PACK_SUFFIX ipv6_hdr_t; +/* +* FIELDS +* ver_tc_fl +* This field contains of 3 subfields: +* 1.Version (4 bits) +* The constant 6 (bit sequence 0110). +* 2.Traffic Class (8 bits) +* The bits of this field hold two values. The 6 most-significant bits are used +* for DSCP, which is used to classify packets. The remaining two bits +* are used for ECN; priority values subdivide into ranges: traffic where +* the source provides congestion control and non-congestion control traffic. +* 3.Flow Label (20 bits) +* Originally created for giving real-time applications special service. +* Flow Label specifications and minimum requirements are described, +* and first uses of this field are emerging. +* +* +* payload_length; +* The size of the payload in octets, including any extension headers. +* The length is set to zero when a Hop-by-Hop extension header carries +* a Jumbo Payload option. +* +* next_header +* Specifies the type of the next header. This field usually specifies the +* transport layer protocol used by a packet's payload. When extension headers +* are present in the packet this field indicates which extension header follows. +* The values are shared with those used for the IPv4 protocol field, +* as both fields have the same function +* +* hop_limit +* Replaces the time to live field of IPv4. This value is decremented by +* one at each intermediate node the packet visits. When the counter reaches +* 0 the packet is discarded +* +* src_addr +* The IPv6 address of the sending node. +* +* dest_addr +* The IPv6 address of the destination node(s). +* +* +* SEE ALSO +* IB Network Drivers, eth_hdr_t, arp_pkt_t, tcp_hdr_t, udp_hdr_t +*********/ +#include + #include /****s* IB Network Drivers/tcp_hdr_t @@ -432,8 +499,11 @@ typedef struct _igmp_v2_hdr *********/ #include -#define DHCP_PORT_SERVER CL_HTON16(67) -#define DHCP_PORT_CLIENT CL_HTON16(68) +#define DHCP_PORT_SERVER CL_HTON16(67) +#define DHCP_PORT_CLIENT CL_HTON16(68) +#define DHCP_IPV6_PORT_SERVER_OR_AGENT CL_HTON16(547) +#define DHCP_IPV6_PORT_CLIENT CL_HTON16(546) + #define DHCP_PORT_PROXY_SERVER CL_HTON16(4011) #define DHCP_REQUEST 1 @@ -534,7 +604,11 @@ typedef struct _udp_pkt typedef struct _ip_pkt { - ip_hdr_t hdr; + union + { + ip_hdr_t hdr; + ipv6_hdr_t hdr_ipv6; + } PACK_SUFFIX ; union _ip_payload { tcp_hdr_t tcp; diff --git a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/SOURCES b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/SOURCES index 2710aaf4..5e291b49 100644 --- a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/SOURCES +++ b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/SOURCES @@ -15,7 +15,7 @@ ENABLE_EVENT_TRACING=1 !endif -SOURCES= ipoib_log.mc \ +SOURCES=ipoib_log.mc \ ipoib.rc \ ipoib_driver.cpp \ ipoib_adapter.cpp \ diff --git a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.cpp b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.cpp index 94e32eb4..ec2cad06 100644 --- a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.cpp +++ b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.cpp @@ -429,7 +429,8 @@ adapter_init( p_adapter->p_ifc->get_err_str( status )) ); return status; } - + + p_adapter->ipoib_state = IPOIB_UNINIT; IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT, ("Shutter Init, state = %d\n", p_adapter->ipoib_state) ); IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV, @@ -1024,7 +1025,6 @@ ipoib_reset_adapter( { h_pnp = p_adapter->h_pnp; p_adapter->h_pnp = NULL; - status = p_adapter->p_ifc->dereg_pnp( h_pnp, __ipoib_pnp_dereg ); // Wait until NDIS will return all indicated NBLs that were received // Avoid shutting the shutter twice @@ -1037,20 +1037,20 @@ ipoib_reset_adapter( ("[%I64u] ipoib_state was IPOIB_RUNNING and IPOIB_RESET_OR_DOWN flag was set \n", cl_get_time_stamp()) ); } KeReleaseInStackQueuedSpinLock( &hdl ); + status = p_adapter->p_ifc->dereg_pnp( h_pnp, __ipoib_pnp_dereg ); if( status == IB_SUCCESS ) + { status = IB_NOT_DONE; + } } else { status = __ipoib_pnp_reg( p_adapter, IB_PNP_FLAG_REG_COMPLETE ); - if( status == IB_SUCCESS ) - p_adapter->hung = FALSE; - } - if (status == IB_NOT_DONE) { - p_adapter->reset = TRUE; } - else { + + if ( status != IB_NOT_DONE ) + { //do not call to __ipoib_complete_reset, because we return completion status directly from here p_adapter->reset = FALSE; diff --git a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.h b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.h index 22a04296..28f1a85b 100644 --- a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.h +++ b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.h @@ -71,6 +71,7 @@ typedef enum } csum_flag_t; typedef uint32_t ipoib_state_t; +#define IPOIB_UNINIT 0 #define IPOIB_INIT 1 #define IPOIB_PAUSED 2 #define IPOIB_PAUSING 4 diff --git a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_debug.h b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_debug.h index d45f9054..0cb3d5a0 100644 --- a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_debug.h +++ b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_debug.h @@ -205,6 +205,7 @@ enum ipoib_perf_counters BuildSendDesc, SendMgrFilter, FilterIp, + FilterIpV6, QueryIp, SendTcp, FilterUdp, diff --git a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp index dd5864f5..5f3104f7 100644 --- a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp +++ b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp @@ -34,7 +34,6 @@ #include "Precompile.h" - #if defined(EVENT_TRACING) #ifdef offsetof #undef offsetof @@ -48,12 +47,9 @@ #include #include #include -#include "ntstrsafe.h" #include "strsafe.h" #include - - #define MAJOR_DRIVER_VERSION 2 #define MINOR_DRIVER_VERSION 1 @@ -64,8 +60,6 @@ PDRIVER_OBJECT g_p_drv_obj; - - static const NDIS_OID SUPPORTED_OIDS[] = { OID_GEN_SUPPORTED_LIST, @@ -265,22 +259,33 @@ ipoib_create_log( } +extern "C" DRIVER_INITIALIZE DriverEntry; extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT p_drv_obj, IN PUNICODE_STRING p_reg_path ); +#ifdef _DEBUG_ +#pragma NDIS_PAGEABLE_FUNCTION(DriverEntry) +#endif + VOID ipoib_unload( IN PDRIVER_OBJECT p_drv_obj ); +#ifdef _DEBUG_ +extern "C" +#endif NDIS_STATUS ipoib_initialize_ex( IN NDIS_HANDLE h_adapter, IN NDIS_HANDLE config_context, IN PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters); +#ifdef _DEBUG_ +#pragma NDIS_PAGEABLE_FUNCTION(ipoib_initialize_ex) +#endif BOOLEAN ipoib_check_for_hang( @@ -735,7 +740,7 @@ ipoib_get_adapter_params( (sizeof(eth_hdr_t) + p_adapter->params.cm_payload_mtu); } - p_adapter->params.xfer_block_size = + p_adapter->params.xfer_block_size = (sizeof(eth_hdr_t) + p_adapter->params.payload_mtu); NdisReadNetworkAddress( &status, (PVOID *) p_mac, p_len, h_config ); @@ -1029,7 +1034,7 @@ SetGenericAttributes( gat.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1; gat.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES); - gat.MediaType = NdisMedium802_3; + gat.MediaType = NdisMedium802_3; gat.MaxXmitLinkSpeed = IPOIB_MEDIA_MAX_SPEED; gat.MaxRcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED; gat.XmitLinkSpeed = NDIS_LINK_SPEED_UNKNOWN; @@ -1402,10 +1407,9 @@ SetAttributes( ipoib_adapter_t *p_adapter, NDIS_HANDLE h_adapter ) - { +{ NTSTATUS Status; - Status = SetDeviceRegistrationAttributes(p_adapter, h_adapter); if (Status != NDIS_STATUS_SUCCESS) { @@ -1876,9 +1880,6 @@ if(cl_get_time_stamp_sec() < 30) { ("ipoib_create_adapter returned status %d.\n", ib_status ) ); return NDIS_STATUS_FAILURE; } - p_adapter->ipoib_state = IPOIB_INIT; - IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SHUTTER, - ("ipoib_state changed to IPOIB_INIT\n") ); status = SetAttributes(p_adapter, h_adapter); if (status != NDIS_STATUS_SUCCESS) { @@ -2605,7 +2606,7 @@ ipoib_query_info( case OID_PNP_QUERY_POWER: IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID, - ("Port %d received query for OID_TCP_TASK_OFFLOAD\n", port_num) ); + ("Port %d received query for OID_PNP_QUERY_POWER\n", port_num) ); // Status is pre-set in this routine to Success status = NDIS_STATUS_SUCCESS; break; @@ -2666,7 +2667,7 @@ ipoib_query_info( IPOIB_EXIT( IPOIB_DBG_OID ); return NDIS_STATUS_PENDING; } - + static NDIS_STATUS ipoib_complete_query( @@ -3299,7 +3300,6 @@ ipoib_shutdown_ex( shutter_shut( &p_adapter->recv_shutter ); // Notify that shutter was already shut p_adapter->ipoib_state |= IPOIB_RESET_OR_DOWN; - ASSERT( p_adapter->ipoib_state == IPOIB_RUNNING ); IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SHUTTER, ("ipoib_state was IPOIB_RUNNING and IPOIB_RESET_OR_DOWN flag was set\n") ); } diff --git a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_ibat.cpp b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_ibat.cpp index 2053b796..459129a2 100644 --- a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_ibat.cpp +++ b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_ibat.cpp @@ -44,21 +44,25 @@ extern PDRIVER_OBJECT g_p_drv_obj; +static DRIVER_DISPATCH __ipoib_create; static NTSTATUS __ipoib_create( IN DEVICE_OBJECT* const pDevObj, IN IRP* const pIrp ); +static DRIVER_DISPATCH __ipoib_cleanup; static NTSTATUS __ipoib_cleanup( IN DEVICE_OBJECT* const pDevObj, IN IRP* const pIrp ); +static DRIVER_DISPATCH __ipoib_close; static NTSTATUS __ipoib_close( IN DEVICE_OBJECT* const pDevObj, IN IRP* const pIrp ); +static DRIVER_DISPATCH __ipoib_dispatch; static NTSTATUS __ipoib_dispatch( IN DEVICE_OBJECT* const pDevObj, diff --git a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp index db092b70..8c844038 100644 --- a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp +++ b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp @@ -73,7 +73,9 @@ ib_gid_t bcast_mgid_template = { ipoib_port_t *gp_ipoib_port; #endif +static KDEFERRED_ROUTINE __port_mcast_garbage_dpc; static void __port_mcast_garbage_dpc(KDPC *p_gc_dpc,void *context,void *s_arg1, void *s_arg2); + static void __port_do_mcast_garbage(ipoib_port_t* const p_port ); #if 0 @@ -347,9 +349,10 @@ __send_mgr_filter_igmp_v2( static NDIS_STATUS __send_mgr_filter_udp( - IN const ip_hdr_t* const p_ip_hdr, + IN const void* const p_ip_hdr, IN MDL* p_mdl, IN size_t buf_len, + IN uint8_t prot, IN OUT ipoib_send_NB_SG* const s_buf); static NDIS_STATUS @@ -607,11 +610,17 @@ inline void ipoib_port_deref(ipoib_port_t * p_port, int type) /* function returns pointer to payload that is going after IP header. * asssuming that payload and IP header are in the same buffer */ -static void* GetIpPayloadPtr(const ip_hdr_t* const p_ip_hdr) +static inline void* GetIpPayloadPtr(const ip_hdr_t* const p_ip_hdr) { return (void*)((uint8_t*)p_ip_hdr + IP_HEADER_LENGTH(p_ip_hdr)); } +static inline void* GetIpv6PayloadPtr(const ipv6_hdr_t* const p_ipv6_hdr) +{ + return (void*)((uint8_t*)p_ipv6_hdr + p_ipv6_hdr->payload_length); +} + + /****************************************************************************** * * Implementation @@ -840,15 +849,19 @@ __port_init( V. NDIS calls to ipoib_restart that calls to shutter_alive. Shutter counter is 0 and we can start working */ - if ( p_adapter->ipoib_state == IPOIB_INIT) { - IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV, - ("Shutter shut, state = %d\n", p_adapter->ipoib_state)); + if ( p_adapter->ipoib_state == IPOIB_UNINIT ) + { + p_adapter->ipoib_state = IPOIB_INIT; + IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SHUTTER, + ("Shutter shut, state = %d\n", p_adapter->ipoib_state)); shutter_shut ( &p_adapter->recv_shutter ); + } + else + { + IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SHUTTER, + ("Shutter wasn't shut, state = %d\n", p_adapter->ipoib_state)); } - else { - IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_RECV, - ("*****Shutter wasn't shut, state = %d*****\n", p_adapter->ipoib_state)); - } + IPOIB_EXIT( IPOIB_DBG_INIT ); return IB_SUCCESS; } @@ -1101,10 +1114,23 @@ __ib_mgr_init( qp_create.rq_sge = 2; /* To support buffers spanning pages. */ qp_create.h_rq_cq = p_port->ib_mgr.h_recv_cq; qp_create.sq_depth = p_port->p_adapter->params.sq_depth; - + + // p_ca_attrs->max_sges contains the maximum number of SG elements + // available by HW. 3 of the them are reserved for an internal use + // Thus, the maximum of SGE for UD QP is limited by (p_ca_attrs->max_sges - 3) #define UD_QP_USED_SGE 3 - qp_create.sq_sge = MAX_SEND_SGE < p_port->p_ca_attrs->max_sges ? - MAX_SEND_SGE : ( p_port->p_ca_attrs->max_sges - UD_QP_USED_SGE ); + if ( p_port->p_ca_attrs->max_sges > MAX_SEND_SGE ) + { + p_port->max_sq_sge_supported = MAX_SEND_SGE - UD_QP_USED_SGE; + } + else + { + p_port->max_sq_sge_supported = p_port->p_ca_attrs->max_sges - UD_QP_USED_SGE; + } + + p_port->p_ca_attrs->max_sges -= UD_QP_USED_SGE; + qp_create.sq_sge = p_port->max_sq_sge_supported; + if ( !p_port->p_ca_attrs->ipoib_csum ) { /* checksum is not supported by device @@ -1153,6 +1179,8 @@ __ib_mgr_init( p_port->p_adapter->p_ifc->get_err_str( status )) ); return status; } + + ASSERT( qp_attr.sq_sge >= qp_create.sq_sge); p_port->ib_mgr.qpn = qp_attr.num; /* Register all of physical memory */ @@ -1987,6 +2015,7 @@ __recv_cb_internal( IN uint32_t *p_recv_cnt ); +static IO_WORKITEM_ROUTINE __iopoib_WorkItem; static void __iopoib_WorkItem( @@ -2008,9 +2037,15 @@ __iopoib_WorkItem( total_recv_cnt += recv_cnt; } - if (WorkToDo) { - IoQueueWorkItem( p_port->pPoWorkItem, __iopoib_WorkItem, DelayedWorkQueue, p_port); - } else { + if (WorkToDo) + { + IoQueueWorkItem( p_port->pPoWorkItem, + (PIO_WORKITEM_ROUTINE) __iopoib_WorkItem, + DelayedWorkQueue, + p_port ); + } + else + { // Release the reference count that was incremented when queued the work item. ipoib_port_deref( p_port, ref_recv_cb ); } @@ -2513,6 +2548,67 @@ __recv_mgr_filter( switch( p_ipoib->hdr.type ) { + case ETH_PROT_TYPE_IPV6: + if( len < (sizeof(ipoib_hdr_t) + sizeof(ipv6_hdr_t)) ) + { + IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, + ("Received IP packet < min size\n") ); + status = IB_INVALID_SETTING; + break; + } + + if( p_ipoib->type.ip.hdr_ipv6.next_header != IP_PROT_UDP ) + { + /* Unfiltered. Setup the ethernet header and report. */ + cl_perf_start( RecvTcp ); + status = __recv_gen( p_ipoib, p_eth, p_src, p_dst ); + cl_perf_stop( &p_port->p_adapter->perf, RecvTcp ); + break; + } + //ASSERT( p_ipoib->type.ip.hdr_ipv6.payload_length == sizeof(ipv6_hdr_t) ); + + /* First packet of a UDP transfer. */ + if( len < + (sizeof(ipoib_hdr_t) + sizeof(ipv6_hdr_t) + sizeof(udp_hdr_t)) ) + { + IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, + ("Received UDP packet < min size\n") ); + status = IB_INVALID_SETTING; + break; + } + + /* Check if DHCP conversion is required. */ + if( (p_ipoib->type.ip.prot.udp.hdr.dst_port == DHCP_IPV6_PORT_SERVER_OR_AGENT&& + p_ipoib->type.ip.prot.udp.hdr.src_port == DHCP_IPV6_PORT_CLIENT) || + (p_ipoib->type.ip.prot.udp.hdr.dst_port == DHCP_IPV6_PORT_CLIENT && + p_ipoib->type.ip.prot.udp.hdr.src_port == DHCP_IPV6_PORT_SERVER_OR_AGENT)) + { + //TODO should be DHCP IPv6 + if( len < (sizeof(ipoib_hdr_t) + sizeof(ipv6_hdr_t) + + sizeof(udp_hdr_t) /*+ DHCP_MIN_SIZE*/) ) + { + IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, + ("Received DHCP < min size\n") ); + status = IB_INVALID_SETTING; + break; + } + + /* UDP packet with BOOTP ports in src/dst port numbers. */ + cl_perf_start( RecvDhcp ); + //TODO implement this function + //status = __recv_dhcp_ipv6( p_port, p_ipoib, p_eth, p_src, p_dst ); + status = IB_INVALID_SETTING; + cl_perf_stop( &p_port->p_adapter->perf, RecvDhcp ); + } + else + { + /* Unfiltered. Setup the ethernet header and report. */ + cl_perf_start( RecvUdp ); + status = __recv_gen( p_ipoib, p_eth, p_src, p_dst ); + cl_perf_stop( &p_port->p_adapter->perf, RecvUdp ); + } + break; + case ETH_PROT_TYPE_IP: if( len < (sizeof(ipoib_hdr_t) + sizeof(ip_hdr_t)) ) { @@ -3470,6 +3566,11 @@ __send_mgr_filter( switch( p_eth_hdr->type ) { + case ETH_PROT_TYPE_IPV6: + cl_perf_start( FilterIpV6 ); + status = __send_mgr_filter_ip( p_eth_hdr, p_mdl, buf_len, s_buf ); + cl_perf_stop( &p_port->p_adapter->perf, FilterIpV6 ); + break; case ETH_PROT_TYPE_IP: cl_perf_start( FilterIp ); status = __send_mgr_filter_ip( p_eth_hdr, p_mdl, buf_len, s_buf ); @@ -3717,7 +3818,7 @@ __send_gen( } /* Remember that one of the DS entries is reserved for the IPoIB header. */ - if( num_pages >= MAX_SEND_SGE ) + if( num_pages >= p_port->max_sq_sge_supported ) { IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_SEND, ("Too many buffers to fit in WR ds_array. Copying data.\n") ); @@ -4188,13 +4289,14 @@ __send_gen( Copy only N+1-MAX_SEND_SGE, where N is a lenght of SG List Remember that one of the DS entries is reserved for the IPoIB header. */ - if( ( p_sgl->NumberOfElements >= MAX_SEND_SGE || + if( ( p_sgl->NumberOfElements >= s_buf->p_port->max_sq_sge_supported || p_sgl->Elements[0].Length < sizeof(eth_hdr_t)) ) { IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_SEND, ("Too many buffers %d to fit in WR ds_array[%d] \ Or buffer[0] length %d < Eth header. Copying data.\n", - p_sgl->NumberOfElements, MAX_SEND_SGE, p_sgl->Elements[0].Length ) ); + p_sgl->NumberOfElements, s_buf->p_port->max_sq_sge_supported , + p_sgl->Elements[0].Length ) ); if( !s_buf->p_port->p_adapter->params.cm_enabled ) { @@ -4202,8 +4304,10 @@ __send_gen( status = __send_copy( s_buf->p_port, s_buf, lso_header_size ); cl_perf_stop( &s_buf->p_port->p_adapter->perf, SendCopy ); } - - status = NDIS_STATUS_RESOURCES; + else + { + status = NDIS_STATUS_RESOURCES; + } IPOIB_EXIT( IPOIB_DBG_SEND ); return status; } @@ -4285,10 +4389,12 @@ __send_mgr_filter_ip( IN ipoib_send_NB_SG *s_buf ) { NDIS_STATUS status; - ip_hdr_t *p_ip_hdr; + PVOID p_ip_hdr; uint32_t ip_packet_len; size_t iph_size_in_bytes; size_t iph_options_size; + uint8_t prot; + size_t hdr_size; PERF_DECLARE( QueryIp ); PERF_DECLARE( SendTcp ); @@ -4319,10 +4425,20 @@ __send_mgr_filter_ip( } else { - p_ip_hdr = (ip_hdr_t*)(p_eth_hdr + 1); + p_ip_hdr = (PVOID) (p_eth_hdr + 1); } - - if( buf_len < sizeof(ip_hdr_t) ) + + if ( p_eth_hdr->type == ETH_PROT_TYPE_IPV6 ) + { + prot = ((ipv6_hdr_t *) p_ip_hdr)->next_header; + hdr_size = sizeof(ipv6_hdr_t); + } + else //IPv4 + { + prot = ((ip_hdr_t *) p_ip_hdr)->prot; + hdr_size = sizeof(ip_hdr_t); + } + if( buf_len < hdr_size ) { /* This buffer is done for. Get the next buffer. */ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, @@ -4330,12 +4446,12 @@ __send_mgr_filter_ip( return NDIS_STATUS_BUFFER_TOO_SHORT; } - switch( p_ip_hdr->prot ) + switch( prot ) { case IP_PROT_UDP: cl_perf_start( FilterUdp ); status = __send_mgr_filter_udp( p_ip_hdr, p_mdl, - (buf_len - sizeof(ip_hdr_t)), s_buf ); + (buf_len - hdr_size), prot, s_buf ); cl_perf_stop( &p_port->p_adapter->perf, FilterUdp ); if( status == NDIS_STATUS_PENDING ) { /* not DHCP packet, keep going */ @@ -4357,7 +4473,7 @@ __send_mgr_filter_ip( 2. ip options So to get the IGMP packet we need to skip the ip options NDIS_BUFFER */ - iph_size_in_bytes = (p_ip_hdr->ver_hl & 0xf) * 4; + iph_size_in_bytes = (((ip_hdr_t*)p_ip_hdr)->ver_hl & 0xf) * 4; iph_options_size = iph_size_in_bytes - buf_len; buf_len -= sizeof(ip_hdr_t);//without ipheader @@ -4367,7 +4483,7 @@ __send_mgr_filter_ip( We anyway pass it to __send_mgr_filter_igmp_v2(). */ status = __send_mgr_filter_igmp_v2( s_buf->p_port, - p_ip_hdr, + (ip_hdr_t*) p_ip_hdr, iph_options_size, p_mdl, buf_len ); @@ -4375,6 +4491,7 @@ __send_mgr_filter_ip( return status; case IP_PROT_ICMP: + case IP_PROT_ICMPV6: p_desc->send_dir = SEND_UD_QP; default: break; @@ -4391,7 +4508,7 @@ __send_mgr_filter_ip( } if( p_desc->send_dir == SEND_UD_QP ) { - ip_packet_len = cl_ntoh16( p_ip_hdr->length ); + ip_packet_len = cl_ntoh16( ((ip_hdr_t*)p_ip_hdr)->length ); //TODO add IPv6 support for CM flow if( ip_packet_len > s_buf->p_port->p_adapter->params.payload_mtu ) { //TODO: NDIS60 @@ -4556,10 +4673,11 @@ __send_mgr_filter_igmp_v2( static NDIS_STATUS __send_mgr_filter_udp( - IN const ip_hdr_t* const p_ip_hdr, - IN MDL* p_mdl, - IN size_t buf_len, - IN OUT ipoib_send_NB_SG* s_buf ) + IN const void* const p_ip_hdr, + IN MDL* p_mdl, + IN size_t buf_len, + IN uint8_t prot, + IN OUT ipoib_send_NB_SG* s_buf ) { NDIS_STATUS status; udp_hdr_t *p_udp_hdr; @@ -4589,17 +4707,25 @@ __send_mgr_filter_udp( } else { - p_udp_hdr = (udp_hdr_t*)GetIpPayloadPtr(p_ip_hdr); + if ( prot == ETH_PROT_TYPE_IPV6 ) + { + p_udp_hdr = (udp_hdr_t*)GetIpv6PayloadPtr((ipv6_hdr_t*)p_ip_hdr); + } + else //IPv4 + { + p_udp_hdr = (udp_hdr_t*)GetIpPayloadPtr((ip_hdr_t*)p_ip_hdr); + if (((ip_hdr_t*)p_ip_hdr)->offset > 0) { + /* This is a fragmented part of UDP packet + * Only first packet will contain UDP header in such case + * So, return if offset > 0 + */ + return NDIS_STATUS_PENDING; + } + } } /* Get the UDP header and check the destination port numbers. */ - if (p_ip_hdr->offset > 0) { - /* This is a fragmented part of UDP packet - * Only first packet will contain UDP header in such case - * So, return if offset > 0 - */ - return NDIS_STATUS_PENDING; - } + if( buf_len < sizeof(udp_hdr_t) ) { @@ -4608,13 +4734,26 @@ __send_mgr_filter_udp( return NDIS_STATUS_BUFFER_TOO_SHORT; } - if( (p_udp_hdr->src_port != DHCP_PORT_CLIENT || - p_udp_hdr->dst_port != DHCP_PORT_SERVER) && - (p_udp_hdr->src_port != DHCP_PORT_SERVER || - p_udp_hdr->dst_port != DHCP_PORT_CLIENT) ) + if ( prot == ETH_PROT_TYPE_IPV6 ) { + if( (p_udp_hdr->src_port != DHCP_PORT_CLIENT || + p_udp_hdr->dst_port != DHCP_PORT_SERVER) && + (p_udp_hdr->src_port != DHCP_PORT_SERVER || + p_udp_hdr->dst_port != DHCP_PORT_CLIENT) ) + { + /* Not a DHCP packet. */ + return NDIS_STATUS_PENDING; + } + } + else //IPv4 { - /* Not a DHCP packet. */ - return NDIS_STATUS_PENDING; + if( (p_udp_hdr->src_port != DHCP_IPV6_PORT_CLIENT|| + p_udp_hdr->dst_port != DHCP_IPV6_PORT_SERVER_OR_AGENT) && + (p_udp_hdr->src_port != DHCP_IPV6_PORT_SERVER_OR_AGENT || + p_udp_hdr->dst_port != DHCP_IPV6_PORT_CLIENT) ) + { + /* Not a DHCP packet. */ + return NDIS_STATUS_PENDING; + } } buf_len -= sizeof(udp_hdr_t); @@ -4629,7 +4768,16 @@ __send_mgr_filter_udp( return NDIS_STATUS_RESOURCES; } /* Copy the IP and UDP headers. */ - cl_memcpy( &s_buf->p_send_buf->ip.hdr, p_ip_hdr , sizeof(ip_hdr_t) ); + //TODO: in this case we limited IP size to 20, but it can be bigger, according to GetIpPayloadPtr + if ( prot == ETH_PROT_TYPE_IPV6 ) + { + cl_memcpy( &s_buf->p_send_buf->ip.hdr_ipv6, p_ip_hdr , sizeof(ipv6_hdr_t) ); + } + else + { + cl_memcpy( &s_buf->p_send_buf->ip.hdr, p_ip_hdr , sizeof(ip_hdr_t) ); + } + cl_memcpy( &s_buf->p_send_buf->ip.prot.udp.hdr, p_udp_hdr, sizeof(udp_hdr_t) ); diff --git a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h index 973333fe..501f3f51 100644 --- a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h +++ b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h @@ -590,6 +590,7 @@ typedef struct _ipoib_port struct _ipoib_adapter *p_adapter; uint8_t port_num; + uint32_t max_sq_sge_supported; KEVENT sa_event; @@ -653,6 +654,9 @@ typedef struct _ipoib_port * port_num * Port number of this adapter. * +* max_sq_sge_supported +* The actual number of SGEs that will be used for UD QP +* * ib_mgr * IB resource manager. * diff --git a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/precompile.h b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/precompile.h index b331ad00..4aae2098 100644 --- a/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/precompile.h +++ b/branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/precompile.h @@ -11,16 +11,10 @@ #include #include #include "ipoib_debug.h" - - #include "ipoib_driver.h" -#include "ipoib_debug.h" - #include "ipoib_endpoint.h" #include "ipoib_port.h" +#include -#include "ipoib_adapter.h" - - -#endif __precomp_h \ No newline at end of file +#endif __precomp_h -- 2.46.0