* $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
#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
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
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
}\r
\r
\r
+\r
NDIS_STATUS\r
ipoib_get_adapter_params(\r
IN NDIS_HANDLE* const wrapper_config_context,\r
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
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
\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