[ipoib] Fix for improper handling of IPoIB params
authortzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 8 Jul 2008 14:34:09 +0000 (14:34 +0000)
committertzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 8 Jul 2008 14:34:09 +0000 (14:34 +0000)
signed by:xalex

git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@1341 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

ulp/ipoib/kernel/SOURCES
ulp/ipoib/kernel/ipoib_driver.c
ulp/ipoib/kernel/ipoib_driver.h
ulp/ipoib/kernel/ipoib_log.mc

index d98b10f..b85a51b 100644 (file)
@@ -25,14 +25,16 @@ C_DEFINES=$(C_DEFINES) -DNDIS_MINIPORT_DRIVER -DNDIS_WDM=1 \
 \r
 TARGETLIBS= \\r
        $(TARGETPATH)\*\complib.lib \\r
-       $(DDK_LIB_PATH)\ndis.lib\r
+       $(DDK_LIB_PATH)\ndis.lib \\r
+       $(DDK_LIB_PATH)\ntstrsafe.lib \\r
+       $(DDK_LIB_PATH)\strsafe.lib\r
 \r
 !if !defined(DDK_TARGET_OS) || "$(DDK_TARGET_OS)"=="Win2K"\r
 #\r
 # The driver is built in the Win2K build environment\r
 # - use the library version of safe strings \r
 #\r
-TARGETLIBS= $(TARGETLIBS) $(DDK_LIB_PATH)\ntstrsafe.lib\r
+#TARGETLIBS= $(TARGETLIBS) $(DDK_LIB_PATH)\ntstrsafe.lib\r
 !endif\r
 \r
 !IFDEF ENABLE_EVENT_TRACING\r
index 48dacbe..9d7f75f 100644 (file)
@@ -30,7 +30,7 @@
  * $Id$\r
  */\r
 \r
-\r
+#include "limits.h"\r
 #include "ipoib_driver.h"\r
 #include "ipoib_debug.h"\r
 \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
+\r
+\r
 \r
 \r
 #if defined(NDIS50_MINIPORT)\r
@@ -59,6 +63,8 @@
 #error NDIS Version not defined, try defining NDIS50_MINIPORT or NDIS51_MINIPORT\r
 #endif\r
 \r
+PDRIVER_OBJECT                         g_p_drv_obj;\r
+\r
 static const NDIS_OID SUPPORTED_OIDS[] =\r
 {\r
        OID_GEN_SUPPORTED_LIST,\r
@@ -125,6 +131,71 @@ uint32_t           g_ipoib_dbg_level = TRACE_LEVEL_ERROR;
 uint32_t               g_ipoib_dbg_flags = 0x00000fff;\r
 ipoib_globals_t        g_ipoib = {0};\r
 \r
+typedef struct _IPOIB_REG_ENTRY\r
+{\r
+       NDIS_STRING RegName;                // variable name text\r
+       BOOLEAN     bRequired;              // 1 -> required, 0 -> optional\r
+       UINT        FieldOffset;            // offset in parent struct\r
+       UINT        FieldSize;              // size (in bytes) of the field\r
+       UINT        Default;                // default value to use\r
+       UINT        Min;                    // minimum value allowed\r
+       UINT        Max;                    // maximum value allowed\r
+} IPOIB_REG_ENTRY, *PIPOIB_REG_ENTRY;\r
+\r
+IPOIB_REG_ENTRY HCARegTable[] = {\r
+       // reg value name             If Required  Offset in parentr struct             Field size                  Default         Min     Max\r
+       {NDIS_STRING_CONST("RqDepth"),          1, IPOIB_OFFSET(rq_depth),              IPOIB_SIZE(rq_depth),           512,        128,    1024},\r
+       {NDIS_STRING_CONST("RqLowWatermark"),   0, IPOIB_OFFSET(rq_low_watermark),      IPOIB_SIZE(rq_low_watermark),   4,          2,      8},\r
+       {NDIS_STRING_CONST("SqDepth"),          1, IPOIB_OFFSET(sq_depth),              IPOIB_SIZE(sq_depth),           512,        128,    1024},\r
+       {NDIS_STRING_CONST("SendChksum"),       1, IPOIB_OFFSET(send_chksum_offload),   IPOIB_SIZE(send_chksum_offload),0,          0,      1},\r
+       {NDIS_STRING_CONST("RecvChksum"),       1, IPOIB_OFFSET(recv_chksum_offload),   IPOIB_SIZE(recv_chksum_offload),0,          0,      1},\r
+       {NDIS_STRING_CONST("SaTimeout"),        1, IPOIB_OFFSET(sa_timeout),            IPOIB_SIZE(sa_timeout),         1000,       250,    UINT_MAX},\r
+       {NDIS_STRING_CONST("SaRetries"),        1, IPOIB_OFFSET(sa_retry_cnt),          IPOIB_SIZE(sa_retry_cnt),       10,         1,      UINT_MAX},\r
+       {NDIS_STRING_CONST("RecvRatio"),        1, IPOIB_OFFSET(recv_pool_ratio),       IPOIB_SIZE(recv_pool_ratio),    1,          1,      10},\r
+       {NDIS_STRING_CONST("PayloadMtu"),       1, IPOIB_OFFSET(payload_mtu),           IPOIB_SIZE(payload_mtu),        2044,         60,   2044}\r
+};  \r
+\r
+#define IPOIB_NUM_REG_PARAMS (sizeof (HCARegTable) / sizeof(IPOIB_REG_ENTRY))\r
+\r
+\r
+static void\r
+ipoib_create_log(\r
+       NDIS_HANDLE h_adapter,\r
+       UINT ind,\r
+       ULONG eventLogMsgId)\r
+\r
+{\r
+#define cMaxStrLen  40\r
+#define cArrLen  3\r
+\r
+       PWCHAR logMsgArray[cArrLen]; \r
+       WCHAR strVal[cMaxStrLen];\r
+       NDIS_STRING AdapterInstanceName;\r
+\r
+       IPOIB_INIT_NDIS_STRING(&AdapterInstanceName);\r
+       if (NdisMQueryAdapterInstanceName(&AdapterInstanceName, h_adapter)!= NDIS_STATUS_SUCCESS ){\r
+               ASSERT(FALSE);\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,IPOIB_DBG_ERROR, ("[IPoIB] Init:Failed to retreive adapter name.\n"));\r
+               return;\r
+       }\r
+       logMsgArray[0] = AdapterInstanceName.Buffer;\r
+       \r
+       if (RtlStringCbPrintfW(strVal, sizeof(strVal), L"0x%x", HCARegTable[ind].Default) != STATUS_SUCCESS) {\r
+               ASSERT(FALSE);\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,IPOIB_DBG_ERROR,\r
+               ("[IPoIB] Init: Problem copying string value: exiting\n"));   \r
+               return;\r
+       }\r
+       \r
+       logMsgArray[0] = AdapterInstanceName.Buffer;\r
+       logMsgArray[1] = HCARegTable[ind].RegName.Buffer;\r
+       logMsgArray[2] = strVal;\r
+       \r
+       NdisWriteEventLogEntry(g_p_drv_obj, eventLogMsgId, 0, cArrLen, &logMsgArray, 0, NULL);\r
+\r
+}\r
+\r
+\r
 \r
 NTSTATUS\r
 DriverEntry(\r
@@ -248,6 +319,7 @@ DriverEntry(
        NDIS_MINIPORT_CHARACTERISTICS   characteristics;\r
 \r
        IPOIB_ENTER( IPOIB_DBG_INIT );\r
+       g_p_drv_obj = p_drv_obj;\r
 \r
 #ifdef _DEBUG_\r
        PAGED_CODE();\r
@@ -397,6 +469,7 @@ ipoib_unload(
 }\r
 \r
 \r
+\r
 NDIS_STATUS\r
 ipoib_get_adapter_params(\r
        IN                              NDIS_HANDLE* const                      wrapper_config_context,\r
@@ -405,9 +478,13 @@ ipoib_get_adapter_params(
        NDIS_STATUS                                             status;\r
        NDIS_HANDLE                                             h_config;\r
        NDIS_CONFIGURATION_PARAMETER    *p_param;\r
-       NDIS_STRING                                             keyword;\r
        PUCHAR                                                  mac;\r
        UINT                                                    len;\r
+       UINT                            value;\r
+       PIPOIB_REG_ENTRY                pRegEntry;\r
+       UINT                            i;\r
+       PUCHAR                          structPointer;\r
+       int sq_depth_step = 128;\r
 \r
        IPOIB_ENTER( IPOIB_DBG_INIT );\r
 \r
@@ -419,124 +496,96 @@ ipoib_get_adapter_params(
                return status;\r
        }\r
 \r
-       /* Required: Receive queue depth. */\r
-       RtlInitUnicodeString( &keyword, L"RqDepth" );\r
-       NdisReadConfiguration(\r
-               &status, &p_param, h_config, &keyword, NdisParameterInteger );\r
-       if( status != NDIS_STATUS_SUCCESS )\r
+       // read all the registry values \r
+       for (i = 0, pRegEntry = HCARegTable; i < IPOIB_NUM_REG_PARAMS; ++i)\r
        {\r
-               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
-                       ("Receive Queue Depth parameter missing.\n") );\r
-               return status;\r
-       }\r
-       p_adapter->params.rq_depth = p_param->ParameterData.IntegerData;\r
+               // initialize pointer to appropriate place inside 'params'\r
+               structPointer = (PUCHAR) &p_adapter->params + pRegEntry[i].FieldOffset;\r
+\r
+               // Get the configuration value for a specific parameter.  Under NT the\r
+               // parameters are all read in as DWORDs.\r
+               NdisReadConfiguration(\r
+                       &status,\r
+                       &p_param,\r
+                       h_config,\r
+                       &pRegEntry[i].RegName,\r
+                       NdisParameterInteger);\r
+\r
+               // If the parameter was present, then check its value for validity.\r
+               if (status == NDIS_STATUS_SUCCESS)\r
+               {\r
+                       // Check that param value is not too small or too large\r
+                       if (p_param->ParameterData.IntegerData < pRegEntry[i].Min ||\r
+                               p_param->ParameterData.IntegerData > pRegEntry[i].Max)\r
+                       {\r
+                               value = pRegEntry[i].Default;\r
+                               ipoib_create_log(p_adapter->h_adapter, i, EVENT_IPOIB_WRONG_PARAMETER_WRN);\r
+                               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_INIT, ("Read configuration.Registry %S value is out of range, setting default value= 0x%x\n", pRegEntry[i].RegName.Buffer, value));                                \r
 \r
-       /* Optional: Receive queue low watermark. */\r
-       RtlInitUnicodeString( &keyword, L"RqLowWatermark" );\r
-       NdisReadConfiguration(\r
-               &status, &p_param, h_config, &keyword, NdisParameterInteger );\r
-       if( status != NDIS_STATUS_SUCCESS || !p_param->ParameterData.IntegerData )\r
-       {\r
-               p_adapter->params.rq_low_watermark = p_adapter->params.rq_depth >> 2;\r
-       }\r
-       else\r
-       {\r
-               p_adapter->params.rq_low_watermark =\r
-                       p_adapter->params.rq_depth / p_param->ParameterData.IntegerData;\r
-       }\r
+                       }\r
+                       else\r
+                       {\r
+                               value = p_param->ParameterData.IntegerData;\r
+                               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_INIT, ("Read configuration. Registry %S, Value= 0x%x\n", pRegEntry[i].RegName.Buffer, value));\r
+                       }\r
+               }\r
 \r
-       /* Required: Send queue depth. */\r
-       RtlInitUnicodeString( &keyword, L"SqDepth" );\r
-       NdisReadConfiguration(\r
-               &status, &p_param, h_config, &keyword, NdisParameterInteger );\r
-       if( status != NDIS_STATUS_SUCCESS )\r
-       {\r
-               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
-                       ("Send Queue Depth parameter missing.\n") );\r
-               return status;\r
-       }\r
-       p_adapter->params.sq_depth = p_param->ParameterData.IntegerData;\r
-       /* Send queue depth needs to be a power of two. */\r
-       if( p_adapter->params.sq_depth <= 128 )\r
-               p_adapter->params.sq_depth = 128;\r
-       else if( p_adapter->params.sq_depth <= 256 )\r
-               p_adapter->params.sq_depth = 256;\r
-       else if( p_adapter->params.sq_depth <= 512 )\r
-               p_adapter->params.sq_depth = 512;\r
-       else\r
-               p_adapter->params.sq_depth = 1024;\r
+               else\r
+               {\r
+                       value = pRegEntry[i].Default;\r
+                       status = NDIS_STATUS_SUCCESS;\r
+                       if (pRegEntry[i].bRequired)\r
+                       {\r
+                               ipoib_create_log(p_adapter->h_adapter, i, EVENT_IPOIB_WRONG_PARAMETER_ERR);\r
+                               IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_INIT, ("Read configuration.Registry %S value not found, setting default value= 0x%x\n", pRegEntry[i].RegName.Buffer, value));\r
+                       }\r
+                       else\r
+                       {\r
+                               ipoib_create_log(p_adapter->h_adapter, i, EVENT_IPOIB_WRONG_PARAMETER_INFO);\r
+                               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_INIT, ("Read configuration. Registry %S value not found, Value= 0x%x\n", pRegEntry[i].RegName.Buffer, value));\r
+                       }\r
 \r
-       /* Required: Send Checksum Offload. */\r
-       RtlInitUnicodeString( &keyword, L"SendChksum" );\r
-       NdisReadConfiguration(\r
-               &status, &p_param, h_config, &keyword, NdisParameterInteger );\r
-       if( status != NDIS_STATUS_SUCCESS )\r
-       {\r
-               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
-                       ("Send Checksum Offload parameter missing.\n") );\r
-               return status;\r
-       }\r
-       p_adapter->params.send_chksum_offload = (p_param->ParameterData.IntegerData != 0);\r
+               }\r
+               //\r
+               // Store the value in the adapter structure.\r
+               //\r
+               switch(pRegEntry[i].FieldSize)\r
+               {\r
+                       case 1:\r
+                               *((PUCHAR) structPointer) = (UCHAR) value;\r
+                               break;\r
 \r
-       /* Required: Send Checksum Offload. */\r
-       RtlInitUnicodeString( &keyword, L"RecvChksum" );\r
-       NdisReadConfiguration(\r
-               &status, &p_param, h_config, &keyword, NdisParameterInteger );\r
-       if( status != NDIS_STATUS_SUCCESS )\r
-       {\r
-               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
-                       ("Recv Checksum Offload parameter missing.\n") );\r
-               return status;\r
-       }\r
-       p_adapter->params.recv_chksum_offload = (p_param->ParameterData.IntegerData != 0);\r
+                       case 2:\r
+                               *((PUSHORT) structPointer) = (USHORT) value;\r
+                               break;\r
 \r
-       /* Required: SA query timeout, in milliseconds. */\r
-       RtlInitUnicodeString( &keyword, L"SaTimeout" );\r
-       NdisReadConfiguration(\r
-               &status, &p_param, h_config, &keyword, NdisParameterInteger );\r
-       if( status != NDIS_STATUS_SUCCESS )\r
-       {\r
-               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
-                       ("SA query timeout parameter missing.\n") );\r
-               return status;\r
-       }\r
-       p_adapter->params.sa_timeout = p_param->ParameterData.IntegerData;\r
+                       case 4:\r
+                               *((PULONG) structPointer) = (ULONG) value;\r
+                               break;\r
 \r
-       /* Required: SA query retry count. */\r
-       RtlInitUnicodeString( &keyword, L"SaRetries" );\r
-       NdisReadConfiguration(\r
-               &status, &p_param, h_config, &keyword, NdisParameterInteger );\r
-       if( status != NDIS_STATUS_SUCCESS )\r
-       {\r
-               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
-                       ("SA query retry count parameter missing.\n") );\r
-               return status;\r
+                       default:\r
+                               IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Bogus field size %d\n", pRegEntry[i].FieldSize));\r
+                               break;\r
+               }\r
        }\r
-       p_adapter->params.sa_retry_cnt = p_param->ParameterData.IntegerData;\r
 \r
-       /* Required: Receive pool to queue depth ratio. */\r
-       RtlInitUnicodeString( &keyword, L"RecvRatio" );\r
-       NdisReadConfiguration(\r
-               &status, &p_param, h_config, &keyword, NdisParameterInteger );\r
-       if( status != NDIS_STATUS_SUCCESS )\r
-       {\r
-               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
-                       ("Receive pool to queue depth ratio parameter missing.\n") );\r
-               return status;\r
-       }\r
-       p_adapter->params.recv_pool_ratio = p_param->ParameterData.IntegerData;\r
+       // Send queue depth needs to be a power of two\r
+       //static const INT sq_depth_step = 128;\r
+\r
+       if (p_adapter->params.sq_depth % sq_depth_step) {\r
+               static const c_sq_ind = 2;\r
+               p_adapter->params.sq_depth = sq_depth_step *(\r
+                       p_adapter->params.sq_depth / sq_depth_step + !!( (p_adapter->params.sq_depth % sq_depth_step) > (sq_depth_step/2) ));\r
+               ipoib_create_log(p_adapter->h_adapter, c_sq_ind, EVENT_IPOIB_WRONG_PARAMETER_WRN);\r
+               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_INIT, ("SQ DEPTH value was rounded to the closest acceptable value of  0x%x\n", p_adapter->params.sq_depth ));\r
 \r
-       /* required: MTU size. */\r
-       RtlInitUnicodeString( &keyword, L"PayloadMtu" );\r
-       NdisReadConfiguration(\r
-               &status, &p_param, h_config, &keyword, NdisParameterInteger );\r
-       if( status != NDIS_STATUS_SUCCESS )\r
-       {\r
-               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
-                       ("PayloadMtu parameter missing. Use the default.\n") );\r
-               return status;\r
        }\r
-       p_adapter->params.payload_mtu = p_param->ParameterData.IntegerData;\r
+\r
+\r
+       // Adjusting the low watermark parameter\r
+       p_adapter->params.rq_low_watermark =\r
+                       p_adapter->params.rq_depth / p_adapter->params.rq_low_watermark;\r
+\r
        p_adapter->params.xfer_block_size = (sizeof(eth_hdr_t) + p_adapter->params.payload_mtu);\r
        NdisReadNetworkAddress( &status, &mac, &len, h_config );\r
 \r
@@ -2350,8 +2399,14 @@ ipoib_reg_addrs(
 \r
        /* Must cast here because the service name is an array of unsigned chars but\r
         * strcpy want a pointer to a signed char */\r
-       strcpy( (char *)ib_service.svc_rec.service_name, ATS_NAME );\r
-\r
+       if ( StringCchCopy( (char *)ib_service.svc_rec.service_name, \r
+               sizeof(ib_service.svc_rec.service_name) / sizeof(char), ATS_NAME ) != S_OK) {\r
+               ASSERT(FALSE);\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,IPOIB_DBG_ERROR,\r
+               ("Problem copying ATS name: exiting\n"));\r
+               return;\r
+       }\r
+    \r
        /* IP Address in question will be put in below */\r
        ib_service.port_guid            = p_adapter->guids.port_guid.guid;\r
        ib_service.timeout_ms           = p_adapter->params.sa_timeout;\r
index 01291c6..b80cb5a 100644 (file)
@@ -126,4 +126,13 @@ void
 ipoib_resume_oids(\r
        IN                              ipoib_adapter_t* const          p_adapter );\r
 \r
+#define IPOIB_OFFSET(field)   ((UINT)FIELD_OFFSET(ipoib_params_t,field))\r
+#define IPOIB_SIZE(field)     sizeof(((ipoib_params_t*)0)->field)\r
+#define IPOIB_INIT_NDIS_STRING(str)                        \\r
+    (str)->Length = 0;                                  \\r
+    (str)->MaximumLength = 0;                           \\r
+    (str)->Buffer = NULL;\r
+\r
+\r
+\r
 #endif /* _IPOIB_DRIVER_H_ */\r
index 9676ff2..646035e 100644 (file)
@@ -283,3 +283,27 @@ SymbolicName=EVENT_IPOIB_BCAST_RATE
 Language=English\r
 %2: The local port rate is too slow for the existing broadcast MC group.\r
 .\r
+\r
+MessageId=0x0058\r
+Facility=IPoIB\r
+Severity=Error\r
+SymbolicName=EVENT_IPOIB_WRONG_PARAMETER_ERR\r
+Language=English\r
+%2: Incorrect value or non-existing registry  for the required IPoIB parameter %3, overriding it by default value: %4\r
+.\r
+\r
+MessageId=0x0059\r
+Facility=IPoIB\r
+Severity=Warning\r
+SymbolicName=EVENT_IPOIB_WRONG_PARAMETER_WRN\r
+Language=English\r
+%2: Incorrect value or non-existing registry entry  for the required IPoIB parameter %3, overriding it by default value: %4\r
+.\r
+\r
+MessageId=0x005A\r
+Facility=IPoIB\r
+Severity=Informational\r
+SymbolicName=EVENT_IPOIB_WRONG_PARAMETER_INFO\r
+Language=English\r
+%2: Incorrect value or non-existing registry  for the optional IPoIB parameter %3, overriding it by default value: %4\r
+.\r