]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
[WOF2-3] integrate trunk commits 2980 - 2989
authorStan Smith <stan.smith@intel.com>
Mon, 15 Nov 2010 20:05:46 +0000 (20:05 +0000)
committerStan Smith <stan.smith@intel.com>
Mon, 15 Nov 2010 20:05:46 +0000 (20:05 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1@2991 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

branches/WOF2-3/inc/complib/cl_log.h
branches/WOF2-3/inc/kernel/ip_packet.h
branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/SOURCES
branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.cpp
branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.h
branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_debug.h
branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp
branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_ibat.cpp
branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp
branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h
branches/WOF2-3/ulp/ipoib_NDIS6_CM/kernel/precompile.h

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