[eth6] Add first version of ipoib NDIS 6.0 driver.
[mirror/winof/.git] / ulp / ipoib / kernel6 / ipoib_driver.c
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  * Copyright (c) 2006 Mellanox Technologies.  All rights reserved.\r
4  * Portions Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
5  *\r
6  * This software is available to you under the OpenIB.org BSD license\r
7  * below:\r
8  *\r
9  *     Redistribution and use in source and binary forms, with or\r
10  *     without modification, are permitted provided that the following\r
11  *     conditions are met:\r
12  *\r
13  *      - Redistributions of source code must retain the above\r
14  *        copyright notice, this list of conditions and the following\r
15  *        disclaimer.\r
16  *\r
17  *      - Redistributions in binary form must reproduce the above\r
18  *        copyright notice, this list of conditions and the following\r
19  *        disclaimer in the documentation and/or other materials\r
20  *        provided with the distribution.\r
21  *\r
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
25  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
26  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
27  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
28  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
29  * SOFTWARE.\r
30  *\r
31  * $Id: ipoib_driver.c 4226 2009-04-06 06:01:03Z xalex $\r
32  */\r
33 \r
34 #include "limits.h"\r
35 #include "ipoib_driver.h"\r
36 #include "ipoib_debug.h"\r
37 \r
38 #if defined(EVENT_TRACING)\r
39 #ifdef offsetof\r
40 #undef offsetof\r
41 #endif\r
42 #include "ipoib_driver.tmh"\r
43 #endif\r
44 \r
45 #include "ipoib_port.h"\r
46 #include "ipoib_ibat.h"\r
47 #include <complib/cl_bus_ifc.h>\r
48 #include <complib/cl_init.h>\r
49 #include <initguid.h>\r
50 #include <iba/ipoib_ifc.h>\r
51 #include "ntstrsafe.h"\r
52 #include "strsafe.h"\r
53 #include <offload.h>\r
54 \r
55 \r
56 \r
57 #define MAJOR_DRIVER_VERSION 2\r
58 #define MINOR_DRIVER_VERSION 1\r
59 #if defined(NDIS60_MINIPORT)\r
60 #define MAJOR_NDIS_VERSION 6\r
61 #define MINOR_NDIS_VERSION 0\r
62 \r
63 #else\r
64 #error NDIS Version not defined, try defining NDIS60_MINIPORT\r
65 #endif\r
66 \r
67 PDRIVER_OBJECT                          g_p_drv_obj;\r
68 \r
69 \r
70 \r
71 static const NDIS_OID SUPPORTED_OIDS[] =\r
72 {\r
73         OID_GEN_SUPPORTED_LIST,\r
74         OID_GEN_HARDWARE_STATUS,\r
75         OID_GEN_MEDIA_SUPPORTED,\r
76         OID_GEN_MEDIA_IN_USE,\r
77         OID_GEN_MAXIMUM_LOOKAHEAD,\r
78         OID_GEN_MAXIMUM_FRAME_SIZE,\r
79         OID_GEN_LINK_SPEED,\r
80         OID_GEN_TRANSMIT_BUFFER_SPACE,\r
81         OID_GEN_RECEIVE_BUFFER_SPACE,\r
82         OID_GEN_TRANSMIT_BLOCK_SIZE,\r
83         OID_GEN_RECEIVE_BLOCK_SIZE,\r
84         OID_GEN_VENDOR_ID,\r
85         OID_GEN_VENDOR_DESCRIPTION,\r
86         OID_GEN_CURRENT_PACKET_FILTER,\r
87         OID_GEN_CURRENT_LOOKAHEAD,\r
88         OID_GEN_DRIVER_VERSION,\r
89         OID_GEN_MAXIMUM_TOTAL_SIZE,\r
90         OID_GEN_PROTOCOL_OPTIONS,\r
91         OID_GEN_MAC_OPTIONS,\r
92         OID_GEN_MEDIA_CONNECT_STATUS,\r
93         OID_GEN_MAXIMUM_SEND_PACKETS,\r
94         OID_GEN_NETWORK_LAYER_ADDRESSES,\r
95         OID_GEN_VENDOR_DRIVER_VERSION,\r
96         OID_GEN_PHYSICAL_MEDIUM,\r
97         OID_GEN_XMIT_OK,\r
98         OID_GEN_RCV_OK,\r
99         OID_GEN_XMIT_ERROR,\r
100         OID_GEN_RCV_ERROR,\r
101         OID_GEN_RCV_NO_BUFFER,\r
102         OID_GEN_DIRECTED_BYTES_XMIT,\r
103         OID_GEN_DIRECTED_FRAMES_XMIT,\r
104         OID_GEN_MULTICAST_BYTES_XMIT,\r
105         OID_GEN_MULTICAST_FRAMES_XMIT,\r
106         OID_GEN_BROADCAST_BYTES_XMIT,\r
107         OID_GEN_BROADCAST_FRAMES_XMIT,\r
108         OID_GEN_DIRECTED_BYTES_RCV,\r
109         OID_GEN_DIRECTED_FRAMES_RCV,\r
110         OID_GEN_MULTICAST_BYTES_RCV,\r
111         OID_GEN_MULTICAST_FRAMES_RCV,\r
112         OID_GEN_BROADCAST_BYTES_RCV,\r
113         OID_GEN_BROADCAST_FRAMES_RCV,\r
114         OID_802_3_PERMANENT_ADDRESS,\r
115         OID_802_3_CURRENT_ADDRESS,\r
116         OID_802_3_MULTICAST_LIST,\r
117         OID_802_3_MAXIMUM_LIST_SIZE,\r
118         OID_802_3_MAC_OPTIONS,\r
119         OID_802_3_RCV_ERROR_ALIGNMENT,\r
120         OID_802_3_XMIT_ONE_COLLISION,\r
121         OID_802_3_XMIT_MORE_COLLISIONS,\r
122         OID_TCP_TASK_OFFLOAD\r
123 };\r
124 \r
125 static const unsigned char VENDOR_ID[] = {0x00, 0x06, 0x6A, 0x00};\r
126 \r
127 #define VENDOR_DESCRIPTION "Internet Protocol over InfiniBand"\r
128 \r
129 #define IB_INFINITE_SERVICE_LEASE       0xFFFFFFFF\r
130 \r
131 //The mask is 8 bit and can't contain more than 6 non-zero bits\r
132 #define MAX_GUID_MAX 0xFC\r
133 \r
134 \r
135 /* Global driver debug level */\r
136 uint32_t                g_ipoib_dbg_level = TRACE_LEVEL_ERROR;\r
137 uint32_t                g_ipoib_dbg_flags = 0x00000fff;\r
138 ipoib_globals_t g_ipoib = {0};\r
139 NDIS_HANDLE             g_IpoibMiniportDriverHandle = NULL;\r
140 NDIS_HANDLE             g_IpoibDriverContext = NULL;\r
141 \r
142 \r
143 \r
144 typedef struct _IPOIB_REG_ENTRY\r
145 {\r
146         NDIS_STRING RegName;                // variable name text\r
147         BOOLEAN     bRequired;              // 1 -> required, 0 -> optional\r
148         UINT        FieldOffset;            // offset in parent struct\r
149         UINT        FieldSize;              // size (in bytes) of the field\r
150         UINT        Default;                // default value to use\r
151         UINT        Min;                    // minimum value allowed\r
152         UINT        Max;                    // maximum value allowed\r
153 } IPOIB_REG_ENTRY, *PIPOIB_REG_ENTRY;\r
154 \r
155 IPOIB_REG_ENTRY HCARegTable[] = {\r
156         // reg value name             If Required  Offset in parentr struct             Field size                  Default         Min     Max\r
157         {NDIS_STRING_CONST("GUIDMask"),         0, IPOIB_OFFSET(guid_mask),             IPOIB_SIZE(guid_mask),          0,          0,    MAX_GUID_MAX},\r
158         /* GUIDMask should be the first element */\r
159         {NDIS_STRING_CONST("RqDepth"),          1, IPOIB_OFFSET(rq_depth),              IPOIB_SIZE(rq_depth),           512,        128,    1024},\r
160         {NDIS_STRING_CONST("RqLowWatermark"),   0, IPOIB_OFFSET(rq_low_watermark),      IPOIB_SIZE(rq_low_watermark),   4,          2,      8},\r
161         {NDIS_STRING_CONST("SqDepth"),          1, IPOIB_OFFSET(sq_depth),              IPOIB_SIZE(sq_depth),           512,        128,    1024},\r
162         {NDIS_STRING_CONST("SendChksum"),       1, IPOIB_OFFSET(send_chksum_offload),   IPOIB_SIZE(send_chksum_offload),CSUM_ENABLED,CSUM_DISABLED,CSUM_BYPASS},\r
163         {NDIS_STRING_CONST("RecvChksum"),       1, IPOIB_OFFSET(recv_chksum_offload),   IPOIB_SIZE(recv_chksum_offload),CSUM_ENABLED,CSUM_DISABLED,CSUM_BYPASS},\r
164         {NDIS_STRING_CONST("SaTimeout"),        1, IPOIB_OFFSET(sa_timeout),            IPOIB_SIZE(sa_timeout),         1000,       250,    UINT_MAX},\r
165         {NDIS_STRING_CONST("SaRetries"),        1, IPOIB_OFFSET(sa_retry_cnt),          IPOIB_SIZE(sa_retry_cnt),       10,         1,      UINT_MAX},\r
166         {NDIS_STRING_CONST("RecvRatio"),        1, IPOIB_OFFSET(recv_pool_ratio),       IPOIB_SIZE(recv_pool_ratio),    1,          1,      10},\r
167         {NDIS_STRING_CONST("PayloadMtu"),       1, IPOIB_OFFSET(payload_mtu),           IPOIB_SIZE(payload_mtu),        2044,       512,   MAX_UD_PAYLOAD_MTU},\r
168         {NDIS_STRING_CONST("lso"),              0, IPOIB_OFFSET(lso),                   IPOIB_SIZE(lso),                0,          0,      1},\r
169         {NDIS_STRING_CONST("MCLeaveRescan"),    1, IPOIB_OFFSET(mc_leave_rescan),       IPOIB_SIZE(mc_leave_rescan),    260,        1,    3600},\r
170         {NDIS_STRING_CONST("BCJoinRetry"),          1, IPOIB_OFFSET(bc_join_retry),                 IPOIB_SIZE(bc_join_retry),      50,         0,    1000},\r
171         {NDIS_STRING_CONST("CmEnabled"),        0, IPOIB_OFFSET(cm_enabled),            IPOIB_SIZE(cm_enabled),         FALSE,     FALSE, TRUE},\r
172         {NDIS_STRING_CONST("CmPayloadMtu"),     1, IPOIB_OFFSET(cm_payload_mtu),        IPOIB_SIZE(cm_payload_mtu),     MAX_CM_PAYLOAD_MTU, 512, MAX_CM_PAYLOAD_MTU}\r
173 \r
174 };  \r
175 \r
176 #define IPOIB_NUM_REG_PARAMS (sizeof (HCARegTable) / sizeof(IPOIB_REG_ENTRY))\r
177 \r
178 \r
179 void\r
180 ipoib_create_log(\r
181         NDIS_HANDLE h_adapter,\r
182         UINT ind,\r
183         ULONG eventLogMsgId)\r
184 \r
185 {\r
186 #define cMaxStrLen  40\r
187 #define cArrLen  3\r
188 \r
189         PWCHAR logMsgArray[cArrLen]; \r
190         WCHAR strVal[cMaxStrLen];\r
191         NDIS_STRING AdapterInstanceName;\r
192 \r
193         IPOIB_INIT_NDIS_STRING(&AdapterInstanceName);\r
194         if (NdisMQueryAdapterInstanceName(&AdapterInstanceName, h_adapter)!= NDIS_STATUS_SUCCESS ){\r
195                 ASSERT(FALSE);\r
196                 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,IPOIB_DBG_ERROR, ("[IPoIB] Init:Failed to retreive adapter name.\n"));\r
197                 return;\r
198         }\r
199         logMsgArray[0] = AdapterInstanceName.Buffer;\r
200         \r
201         if (RtlStringCbPrintfW(strVal, sizeof(strVal), L"0x%x", HCARegTable[ind].Default) != STATUS_SUCCESS) {\r
202                 ASSERT(FALSE);\r
203                 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,IPOIB_DBG_ERROR,\r
204                 ("[IPoIB] Init: Problem copying string value: exiting\n"));   \r
205                 return;\r
206         }\r
207         \r
208         logMsgArray[0] = AdapterInstanceName.Buffer;\r
209         logMsgArray[1] = HCARegTable[ind].RegName.Buffer;\r
210         logMsgArray[2] = strVal;\r
211         \r
212         NdisWriteEventLogEntry(g_p_drv_obj, eventLogMsgId, 0, cArrLen, &logMsgArray, 0, NULL);\r
213 \r
214 }\r
215 \r
216 \r
217 \r
218 NTSTATUS\r
219 DriverEntry(\r
220         IN                              PDRIVER_OBJECT                          p_drv_obj,\r
221         IN                              PUNICODE_STRING                         p_reg_path );\r
222 \r
223 VOID\r
224 ipoib_unload(\r
225         IN                              PDRIVER_OBJECT                          p_drv_obj );\r
226 \r
227 NDIS_STATUS\r
228 ipoib_initialize_ex(\r
229         IN                              NDIS_HANDLE                     h_adapter,\r
230     IN                          NDIS_HANDLE             config_context,\r
231     IN PNDIS_MINIPORT_INIT_PARAMETERS   MiniportInitParameters);\r
232 \r
233 BOOLEAN\r
234 ipoib_check_for_hang(\r
235         IN                              NDIS_HANDLE                                     adapter_context );\r
236 \r
237 void\r
238 ipoib_halt_ex(\r
239         IN NDIS_HANDLE  adapter_context,\r
240         IN                      NDIS_HALT_ACTION            HaltAction);\r
241 \r
242 NDIS_STATUS\r
243 ipoib_query_info(\r
244         IN                              NDIS_HANDLE                                     adapter_context,\r
245         IN                              NDIS_OID                                        oid,\r
246         IN                              PVOID                                           info_buf,\r
247         IN                              ULONG                                           info_buf_len,\r
248                 OUT                     PULONG                                          p_bytes_written,\r
249                 OUT                     PULONG                                          p_bytes_needed );\r
250 \r
251 \r
252 \r
253 NDIS_STATUS\r
254 ipoib_reset(\r
255     IN  NDIS_HANDLE     adapter_context,\r
256     OUT PBOOLEAN        p_addr_reset);\r
257 \r
258 NDIS_STATUS\r
259 ipoib_set_info(\r
260         IN                              NDIS_HANDLE                                     adapter_context,\r
261         IN                              NDIS_OID                                        oid,\r
262         IN                              PVOID                                           info_buf,\r
263         IN                              ULONG                                           info_buf_length,\r
264                 OUT                     PULONG                                          p_bytes_read,\r
265                 OUT                     PULONG                                          p_bytes_needed );\r
266 \r
267 //NDIS60\r
268 void\r
269 ipoib_send_net_buffer_list(\r
270     IN  NDIS_HANDLE         adapter_context,\r
271     IN  PNET_BUFFER_LIST    net_buffer_list,\r
272     IN  NDIS_PORT_NUMBER    port_num,\r
273     IN  ULONG               send_flags);\r
274 \r
275 void\r
276 ipoib_pnp_notify(\r
277         IN                              NDIS_HANDLE                                     adapter_context,\r
278         IN PNET_DEVICE_PNP_EVENT  pnp_event);\r
279 \r
280 VOID\r
281 ipoib_shutdown_ex(\r
282         IN NDIS_HANDLE  adapter_context,\r
283         IN NDIS_SHUTDOWN_ACTION  shutdown_action);\r
284 \r
285 \r
286 void\r
287 ipoib_cancel_xmit(\r
288         IN                              NDIS_HANDLE                                     adapter_context,\r
289         IN                              PVOID                                           cancel_id );\r
290 \r
291 \r
292 static void\r
293 ipoib_complete_query(\r
294         IN                              ipoib_adapter_t* const          p_adapter,\r
295         IN                              pending_oid_t* const            p_oid_info,\r
296         IN              const   NDIS_STATUS                                     status,\r
297         IN              const   void* const                                     p_buf,\r
298         IN              const   ULONG                                           buf_len );\r
299 \r
300 static NDIS_STATUS\r
301 __ipoib_set_net_addr(\r
302         IN              ipoib_adapter_t *       p_adapter,\r
303         IN              PVOID                           info_buf,\r
304         IN              ULONG                           info_buf_len,\r
305                 OUT     PULONG                          p_bytes_read,\r
306                 OUT     PULONG                          p_bytes_needed );\r
307 \r
308 static NDIS_STATUS\r
309 __ipoib_get_tcp_task_offload(\r
310         IN                              ipoib_adapter_t*                        p_adapter,\r
311         OUT                             pending_oid_t                           *pNdisRequest);\r
312 \r
313 static void\r
314 __ipoib_ats_reg_cb(\r
315         IN                              ib_reg_svc_rec_t                        *p_reg_svc_rec );\r
316 \r
317 static void\r
318 __ipoib_ats_dereg_cb(\r
319         IN                              void                                            *context );\r
320 \r
321 static NTSTATUS\r
322 __ipoib_read_registry(\r
323         IN                              UNICODE_STRING* const           p_registry_path );\r
324 \r
325 static NDIS_STATUS\r
326 ipoib_set_options(\r
327     IN NDIS_HANDLE  NdisMiniportDriverHandle,\r
328     IN NDIS_HANDLE  MiniportDriverContext);\r
329 \r
330 static NDIS_STATUS\r
331 ipoib_oid_handler(\r
332     IN  NDIS_HANDLE         adapter_context,\r
333     IN  PNDIS_OID_REQUEST   pNdisRequest);\r
334 \r
335 static void\r
336 ipoib_cancel_oid_request(\r
337     IN  NDIS_HANDLE            adapter_context,\r
338     IN  PVOID                  requestId);\r
339         \r
340 static NDIS_STATUS \r
341 ipoib_pause(\r
342     IN  NDIS_HANDLE                         adapter_context,    \r
343     IN  PNDIS_MINIPORT_PAUSE_PARAMETERS     pause_parameters);\r
344 \r
345 static NDIS_STATUS \r
346 ipoib_restart(\r
347     IN  NDIS_HANDLE                         adapter_context,    \r
348     IN  PNDIS_MINIPORT_RESTART_PARAMETERS   restart_parameters);\r
349 \r
350 \r
351 \r
352 //! Standard Windows Device Driver Entry Point\r
353 /*! DriverEntry is the first routine called after a driver is loaded, and\r
354 is responsible for initializing the driver.  On W2k this occurs when the PnP\r
355 Manager matched a PnP ID to one in an INF file that references this driver.\r
356 Any not success return value will cause the driver to fail to load.\r
357 IRQL = PASSIVE_LEVEL\r
358 \r
359 @param p_drv_obj Pointer to Driver Object for this device driver\r
360 @param p_registry_path Pointer to unicode string containing path to this driver's registry area\r
361 @return STATUS_SUCCESS, NDIS_STATUS_BAD_CHARACTERISTICS, NDIS_STATUS_BAD_VERSION,\r
362 NDIS_STATUS_RESOURCES, or NDIS_STATUS_FAILURE\r
363 */\r
364 NTSTATUS\r
365 DriverEntry(\r
366         IN                              PDRIVER_OBJECT                          p_drv_obj,\r
367         IN                              PUNICODE_STRING                         p_registry_path )\r
368 {\r
369         NDIS_STATUS                                             status;\r
370         NDIS_MINIPORT_DRIVER_CHARACTERISTICS characteristics;\r
371 \r
372         IPOIB_ENTER( IPOIB_DBG_INIT );\r
373         g_p_drv_obj = p_drv_obj;\r
374 \r
375 #ifdef _DEBUG_\r
376         PAGED_CODE();\r
377 #endif\r
378 #if defined(EVENT_TRACING)\r
379         WPP_INIT_TRACING(p_drv_obj, p_registry_path);\r
380 #endif\r
381         status = CL_INIT;\r
382         if( !NT_SUCCESS( status ) )\r
383         {\r
384                 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
385                         ("cl_init failed.\n") );\r
386                 return status;\r
387         }\r
388 \r
389         __ipoib_read_registry(p_registry_path);\r
390         \r
391         KeInitializeSpinLock( &g_ipoib.lock );\r
392         cl_qlist_init( &g_ipoib.adapter_list );\r
393 \r
394     NdisZeroMemory(&characteristics, sizeof(characteristics));\r
395 \r
396     characteristics.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS,\r
397     characteristics.Header.Size = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS);\r
398     characteristics.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;\r
399 \r
400         characteristics.MajorNdisVersion                = MAJOR_NDIS_VERSION;\r
401         characteristics.MinorNdisVersion                = MINOR_NDIS_VERSION;\r
402     characteristics.MajorDriverVersion          = MAJOR_DRIVER_VERSION;\r
403     characteristics.MinorDriverVersion          = MINOR_DRIVER_VERSION;\r
404 \r
405 \r
406         characteristics.CheckForHangHandlerEx           = ipoib_check_for_hang;\r
407         characteristics.HaltHandlerEx                           = ipoib_halt_ex;\r
408         characteristics.InitializeHandlerEx             = ipoib_initialize_ex;\r
409         characteristics.OidRequestHandler                       = ipoib_oid_handler;\r
410         characteristics.CancelOidRequestHandler         = ipoib_cancel_oid_request;\r
411         characteristics.ResetHandlerEx                          = ipoib_reset;\r
412         characteristics.DevicePnPEventNotifyHandler     = ipoib_pnp_notify;\r
413         characteristics.ReturnNetBufferListsHandler     = ipoib_return_net_buffer_list;\r
414         characteristics.SendNetBufferListsHandler       = ipoib_send_net_buffer_list;\r
415 \r
416         characteristics.SetOptionsHandler                       = ipoib_set_options;\r
417         characteristics.PauseHandler                            = ipoib_pause;\r
418         characteristics.RestartHandler                          = ipoib_restart;\r
419         characteristics.UnloadHandler                           = ipoib_unload;\r
420         characteristics.CancelSendHandler                       = ipoib_cancel_xmit;\r
421         characteristics.ShutdownHandlerEx                       = ipoib_shutdown_ex;\r
422 \r
423 \r
424 \r
425 //TODO NDIS60 set g_ prefix to global variables\r
426         status = NdisMRegisterMiniportDriver(\r
427                 p_drv_obj, p_registry_path,(PNDIS_HANDLE)g_IpoibDriverContext, &characteristics,&g_IpoibMiniportDriverHandle );\r
428         if( status != NDIS_STATUS_SUCCESS )\r
429         {\r
430                 IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, \r
431                         ("NdisMRegisterMiniportDriver failed with status of %d\n", status) );\r
432                 CL_DEINIT;\r
433         }\r
434 \r
435         IPOIB_EXIT( IPOIB_DBG_INIT );\r
436         return status;\r
437 }\r
438 \r
439 static NDIS_STATUS\r
440 ipoib_set_options(\r
441     IN NDIS_HANDLE  NdisMiniportDriverHandle,\r
442     IN NDIS_HANDLE  MiniportDriverContext\r
443     )\r
444 {\r
445         IPOIB_ENTER( IPOIB_DBG_INIT );\r
446 \r
447     UNREFERENCED_PARAMETER(NdisMiniportDriverHandle);\r
448     UNREFERENCED_PARAMETER(MiniportDriverContext);\r
449    \r
450         IPOIB_EXIT( IPOIB_DBG_INIT );\r
451     return NDIS_STATUS_SUCCESS;\r
452 }\r
453 \r
454 static NTSTATUS\r
455 __ipoib_read_registry(\r
456         IN                              UNICODE_STRING* const           p_registry_path )\r
457 {\r
458         NTSTATUS                                                status;\r
459         /* Remember the terminating entry in the table below. */\r
460         RTL_QUERY_REGISTRY_TABLE                table[4];\r
461         UNICODE_STRING                                  param_path;\r
462 \r
463         IPOIB_ENTER( IPOIB_DBG_INIT );\r
464         RtlInitUnicodeString( &param_path, NULL );\r
465         param_path.MaximumLength = p_registry_path->Length + \r
466                 sizeof(L"\\Parameters");\r
467         param_path.Buffer = cl_zalloc( param_path.MaximumLength );\r
468         if( !param_path.Buffer )\r
469         {\r
470                 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, \r
471                         ("Failed to allocate parameters path buffer.\n") );\r
472                 return STATUS_INSUFFICIENT_RESOURCES;\r
473         }\r
474 \r
475         RtlAppendUnicodeStringToString( &param_path, p_registry_path );\r
476         RtlAppendUnicodeToString( &param_path, L"\\Parameters" );\r
477 \r
478         /*\r
479          * Clear the table.  This clears all the query callback pointers,\r
480          * and sets up the terminating table entry.\r
481          */\r
482         cl_memclr( table, sizeof(table) );\r
483 \r
484         /* Setup the table entries. */\r
485         table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
486         table[0].Name = L"DebugLevel";\r
487         table[0].EntryContext = &g_ipoib_dbg_level;\r
488         table[0].DefaultType = REG_DWORD;\r
489         table[0].DefaultData = &g_ipoib_dbg_level;\r
490         table[0].DefaultLength = sizeof(ULONG);\r
491 \r
492         table[1].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
493         table[1].Name = L"DebugFlags";\r
494         table[1].EntryContext = &g_ipoib_dbg_flags;\r
495         table[1].DefaultType = REG_DWORD;\r
496         table[1].DefaultData = &g_ipoib_dbg_flags;\r
497         table[1].DefaultLength = sizeof(ULONG);\r
498 \r
499         table[2].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
500         table[2].Name = L"bypass_check_bcast_rate";\r
501         table[2].EntryContext = &g_ipoib.bypass_check_bcast_rate;\r
502         table[2].DefaultType = REG_DWORD;\r
503         table[2].DefaultData = &g_ipoib.bypass_check_bcast_rate;\r
504         table[2].DefaultLength = sizeof(ULONG);\r
505 \r
506         /* Have at it! */\r
507         status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, \r
508                 param_path.Buffer, table, NULL, NULL );\r
509 \r
510         IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
511                         ("debug level %d debug flags 0x%.8x\n",\r
512                         g_ipoib_dbg_level,\r
513                         g_ipoib_dbg_flags));\r
514 \r
515 #if DBG\r
516         if( g_ipoib_dbg_flags & IPOIB_DBG_ERR )\r
517                 g_ipoib_dbg_flags |= CL_DBG_ERROR;\r
518 #endif\r
519 \r
520         cl_free( param_path.Buffer );\r
521         IPOIB_EXIT( IPOIB_DBG_INIT );\r
522         return status;\r
523 }\r
524 \r
525 \r
526 VOID\r
527 ipoib_unload(\r
528         IN                              PDRIVER_OBJECT                          p_drv_obj )\r
529 {\r
530         IPOIB_ENTER( IPOIB_DBG_INIT );\r
531         UNREFERENCED_PARAMETER(p_drv_obj);\r
532         #if defined(EVENT_TRACING)\r
533         WPP_CLEANUP(p_drv_obj);\r
534         #endif\r
535         //NDIS6.0\r
536         NdisMDeregisterMiniportDriver(g_IpoibMiniportDriverHandle);\r
537         UNREFERENCED_PARAMETER( p_drv_obj );\r
538         CL_DEINIT;\r
539         IPOIB_EXIT( IPOIB_DBG_INIT );\r
540 }\r
541 \r
542 \r
543 \r
544 NDIS_STATUS\r
545 ipoib_get_adapter_params(\r
546         IN                              NDIS_HANDLE* const                      wrapper_config_context,\r
547         IN      OUT                     ipoib_adapter_t                         *p_adapter,\r
548         OUT                             PUCHAR                                          *p_mac,\r
549         OUT                             UINT                                            *p_len)\r
550 {\r
551         NDIS_STATUS                                             status;\r
552         NDIS_HANDLE                                             h_config;\r
553     NDIS_CONFIGURATION_OBJECT           config_obj;\r
554         NDIS_CONFIGURATION_PARAMETER    *p_param;\r
555         UINT                                                    value;\r
556         PIPOIB_REG_ENTRY                                pRegEntry;\r
557         UINT                                                    i;\r
558         PUCHAR                                                  structPointer;\r
559         \r
560         int sq_depth_step = 128;\r
561 \r
562         UNUSED_PARAM(wrapper_config_context);\r
563         IPOIB_ENTER( IPOIB_DBG_INIT );\r
564 \r
565     config_obj.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;\r
566     config_obj.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;\r
567     config_obj.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);\r
568     config_obj.NdisHandle = p_adapter->h_adapter;\r
569     config_obj.Flags = 0;\r
570 \r
571         status = NdisOpenConfigurationEx( &config_obj, &h_config);\r
572         if( status != NDIS_STATUS_SUCCESS )\r
573         {\r
574                 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
575                         ("NdisOpenConfigurationEx returned 0x%.8x\n", status) );\r
576                 return status;\r
577         }\r
578 \r
579         // read all the registry values \r
580         for (i = 0, pRegEntry = HCARegTable; i < IPOIB_NUM_REG_PARAMS; ++i)\r
581         {\r
582                 // initialize pointer to appropriate place inside 'params'\r
583                 structPointer = (PUCHAR) &p_adapter->params + pRegEntry[i].FieldOffset;\r
584 \r
585                 // Get the configuration value for a specific parameter.  Under NT the\r
586                 // parameters are all read in as DWORDs.\r
587                 NdisReadConfiguration(\r
588                         &status,\r
589                         &p_param,\r
590                         h_config,\r
591                         &pRegEntry[i].RegName,\r
592                         NdisParameterInteger);\r
593 \r
594                 // If the parameter was present, then check its value for validity.\r
595                 if (status == NDIS_STATUS_SUCCESS)\r
596                 {\r
597                         // Check that param value is not too small or too large\r
598                         if (p_param->ParameterData.IntegerData < pRegEntry[i].Min ||\r
599                                 p_param->ParameterData.IntegerData > pRegEntry[i].Max)\r
600                         {\r
601                                 value = pRegEntry[i].Default;\r
602                                 ipoib_create_log(p_adapter->h_adapter, i, EVENT_IPOIB_WRONG_PARAMETER_WRN);\r
603                                 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
604 \r
605                         }\r
606                         else\r
607                         {\r
608                                 value = p_param->ParameterData.IntegerData;\r
609                                 IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_INIT, ("Read configuration. Registry %S, Value= 0x%x\n", pRegEntry[i].RegName.Buffer, value));\r
610                         }\r
611                 }\r
612 \r
613                 else\r
614                 {\r
615                         value = pRegEntry[i].Default;\r
616                         status = NDIS_STATUS_SUCCESS;\r
617                         if (pRegEntry[i].bRequired)\r
618                         {\r
619                                 ipoib_create_log(p_adapter->h_adapter, i, EVENT_IPOIB_WRONG_PARAMETER_ERR);\r
620                                 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
621                         }\r
622                         else\r
623                         {\r
624                                 ipoib_create_log(p_adapter->h_adapter, i, EVENT_IPOIB_WRONG_PARAMETER_INFO);\r
625                                 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
626                         }\r
627 \r
628                 }\r
629                 //\r
630                 // Store the value in the adapter structure.\r
631                 //\r
632                 switch(pRegEntry[i].FieldSize)\r
633                 {\r
634                         case 1:\r
635                                 *((PUCHAR) structPointer) = (UCHAR) value;\r
636                                 break;\r
637 \r
638                         case 2:\r
639                                 *((PUSHORT) structPointer) = (USHORT) value;\r
640                                 break;\r
641 \r
642                         case 4:\r
643                                 *((PULONG) structPointer) = (ULONG) value;\r
644                                 break;\r
645 \r
646                         default:\r
647                                 IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Bogus field size %d\n", pRegEntry[i].FieldSize));\r
648                                 break;\r
649                 }\r
650         }\r
651 \r
652         // Send queue depth needs to be a power of two\r
653         //static const INT sq_depth_step = 128;\r
654 \r
655         if (p_adapter->params.sq_depth % sq_depth_step) {\r
656                 static const c_sq_ind = 2;\r
657                 p_adapter->params.sq_depth = sq_depth_step *(\r
658                         p_adapter->params.sq_depth / sq_depth_step + !!( (p_adapter->params.sq_depth % sq_depth_step) > (sq_depth_step/2) ));\r
659                 ipoib_create_log(p_adapter->h_adapter, c_sq_ind, EVENT_IPOIB_WRONG_PARAMETER_WRN);\r
660                 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
661 \r
662         }\r
663 \r
664 \r
665         // Adjusting the low watermark parameter\r
666         p_adapter->params.rq_low_watermark =\r
667                         p_adapter->params.rq_depth / p_adapter->params.rq_low_watermark;\r
668         \r
669         /* disable CM if LSO is active */\r
670         if( p_adapter->params.cm_enabled )\r
671         {\r
672                 p_adapter->params.cm_enabled = !p_adapter->params.lso;\r
673                 if( !p_adapter->params.cm_enabled )\r
674                 {\r
675                         NdisWriteErrorLogEntry( p_adapter->h_adapter,\r
676                                 EVENT_IPOIB_CONNECTED_MODE_ERR, 1, 0xbadc0de0 );\r
677                 }\r
678         }\r
679 \r
680         if( p_adapter->params.cm_enabled )\r
681         {\r
682                 p_adapter->params.cm_xfer_block_size = \r
683                         (sizeof(eth_hdr_t) + p_adapter->params.cm_payload_mtu);\r
684         }\r
685 \r
686                 p_adapter->params.xfer_block_size = \r
687                         (sizeof(eth_hdr_t) + p_adapter->params.payload_mtu);\r
688 \r
689         NdisReadNetworkAddress( &status, p_mac, p_len, h_config );\r
690 \r
691         NdisCloseConfiguration( h_config );\r
692 \r
693         IPOIB_EXIT( IPOIB_DBG_INIT );\r
694         return NDIS_STATUS_SUCCESS;\r
695 }\r
696 \r
697 \r
698 NDIS_STATUS\r
699 ipoib_get_adapter_guids(\r
700         IN                              NDIS_HANDLE* const                      h_adapter,\r
701         IN      OUT                     ipoib_adapter_t                         *p_adapter )\r
702 {\r
703         NTSTATUS                        status;\r
704         ib_al_ifc_data_t        data;\r
705         IO_STACK_LOCATION       io_stack, *p_fwd_io_stack;\r
706         DEVICE_OBJECT           *p_pdo;\r
707         IRP                                     *p_irp;\r
708         KEVENT                          event;\r
709         IO_STATUS_BLOCK         io_status;\r
710 \r
711         IPOIB_ENTER( IPOIB_DBG_INIT );\r
712 \r
713         NdisMGetDeviceProperty( h_adapter, &p_pdo, NULL, NULL, NULL, NULL );\r
714 \r
715         /* Query for our interface */\r
716         data.size = sizeof(ipoib_ifc_data_t);\r
717         data.version = IPOIB_INTERFACE_DATA_VERSION;\r
718         data.type = &GUID_IPOIB_INTERFACE_DATA;\r
719         data.p_data = &p_adapter->guids;\r
720 \r
721         io_stack.MinorFunction = IRP_MN_QUERY_INTERFACE;\r
722         io_stack.Parameters.QueryInterface.Version = AL_INTERFACE_VERSION;\r
723         io_stack.Parameters.QueryInterface.Size = sizeof(ib_al_ifc_t);\r
724         io_stack.Parameters.QueryInterface.Interface =\r
725                 (INTERFACE*)p_adapter->p_ifc;\r
726         io_stack.Parameters.QueryInterface.InterfaceSpecificData = &data;\r
727         io_stack.Parameters.QueryInterface.InterfaceType = \r
728                 &GUID_IB_AL_INTERFACE;\r
729 \r
730         KeInitializeEvent( &event, NotificationEvent, FALSE );\r
731 \r
732         /* Build the IRP for the HCA. */\r
733         p_irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, p_pdo,\r
734                 NULL, 0, NULL, &event, &io_status );\r
735         if( !p_irp )\r
736         {\r
737                 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
738                         ("Failed to allocate query interface IRP.\n") );\r
739                 return STATUS_INSUFFICIENT_RESOURCES;\r
740         }\r
741 \r
742         /* Copy the request query parameters. */\r
743         p_fwd_io_stack = IoGetNextIrpStackLocation( p_irp );\r
744         p_fwd_io_stack->MinorFunction = IRP_MN_QUERY_INTERFACE;\r
745         p_fwd_io_stack->Parameters.QueryInterface =\r
746                 io_stack.Parameters.QueryInterface;\r
747         p_irp->IoStatus.Status = STATUS_NOT_SUPPORTED;\r
748 \r
749         /* Send the IRP. */\r
750         status = IoCallDriver( p_pdo, p_irp );\r
751         if( status == STATUS_PENDING )\r
752         {\r
753                 KeWaitForSingleObject( &event, Executive, KernelMode,\r
754                         FALSE, NULL );\r
755                 status = io_status.Status;\r
756         }\r
757 \r
758         if( !NT_SUCCESS( status ) )\r
759         {\r
760                 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
761                         ("Query interface for IPOIB interface returned %08x.\n", status) );\r
762                 return status;\r
763         }\r
764 \r
765         /*\r
766          * Dereference the interface now so that the bus driver doesn't fail a\r
767          * query remove IRP.  We will always get unloaded before the bus driver\r
768          * since we're a child device.\r
769          */\r
770         if (p_adapter->p_ifc)\r
771         p_adapter->p_ifc->wdm.InterfaceDereference(\r
772                 p_adapter->p_ifc->wdm.Context );\r
773         IPOIB_EXIT( IPOIB_DBG_INIT );\r
774         return NDIS_STATUS_SUCCESS;\r
775 }\r
776 \r
777 \r
778 //! Initialization function called for each IOC discovered\r
779 /*  The MiniportInitialize function is a required function that sets up a\r
780 NIC (or virtual NIC) for network I/O operations, claims all hardware\r
781 resources necessary to the NIC in the registry, and allocates resources\r
782 the driver needs to carry out network I/O operations.\r
783 IRQL = PASSIVE_LEVEL\r
784 \r
785 @param p_open_status Pointer to a status field set if this function returns NDIS_STATUS_OPEN_ERROR\r
786 @param p_selected_medium_index Pointer to unsigned integer noting index into medium_array for this NIC\r
787 @param medium_array Array of mediums for this NIC\r
788 @param medium_array_size Number of elements in medium_array\r
789 @param h_adapter Handle assigned by NDIS for this NIC\r
790 @param wrapper_config_context Handle used for Ndis initialization functions\r
791 @return NDIS_STATUS_SUCCESS, NDIS_STATUS_UNSUPPORTED_MEDIA, NDIS_STATUS_RESOURCES,\r
792 NDIS_STATUS_NOT_SUPPORTED \r
793 */\r
794 \r
795 /*void foo1(int i)\r
796 {\r
797                 char temp[5200];\r
798                 if (i ==0) return;\r
799                 cl_msg_out("i = %d\n", i);\r
800                 foo1(i-1);\r
801          \r
802 }*/\r
803         \r
804 NDIS_STATUS\r
805 SetDeviceRegistrationAttributes(\r
806         ipoib_adapter_t *p_adapter,\r
807     NDIS_HANDLE h_adapter\r
808     )\r
809 {\r
810     NDIS_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES atr;\r
811     NTSTATUS Status;\r
812 \r
813     NdisZeroMemory(&atr, sizeof(NDIS_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES));\r
814 \r
815     //\r
816     // setting registration attributes\r
817     //\r
818     atr.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES;\r
819     atr.Header.Revision = NDIS_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES_REVISION_1;\r
820     atr.Header.Size = NDIS_SIZEOF_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES_REVISION_1;\r
821 \r
822 \r
823     atr.MiniportAddDeviceContext = (NDIS_HANDLE)p_adapter;\r
824     atr.Flags = 0; \r
825 \r
826     Status = NdisMSetMiniportAttributes(h_adapter,\r
827                     (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&atr);\r
828 \r
829     return Status;\r
830 }\r
831 \r
832 //NDIS 6.1\r
833 #if 0\r
834 NDIS_STATUS\r
835 SetHardwareAssistAttributes(\r
836     ipoib_adapter_t *p_adapter,\r
837     NDIS_HANDLE h_adapter\r
838     )\r
839 {\r
840     NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES atr;\r
841     NTSTATUS Status;\r
842 \r
843     NdisZeroMemory(&atr, sizeof(NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES));\r
844 \r
845     //\r
846     // setting registration attributes\r
847     //\r
848     atr.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES;\r
849     atr.Header.Revision = NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;\r
850     atr.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;\r
851 \r
852     NDIS_HD_SPLIT_ATTRIBUTES nhsa;\r
853     NdisZeroMemory(&nhsa, sizeof(nhsa));\r
854 \r
855     nhsa.Header.Type = NDIS_OBJECT_TYPE_HD_SPLIT_ATTRIBUTES;\r
856     nhsa.Header.Revision = NDIS_OFFLOAD_REVISION_1;\r
857     nhsa.Header.Size = NDIS_SIZEOF_HD_SPLIT_ATTRIBUTES_REVISION_1;\r
858 \r
859     // BUGBUG: We are just cheating here ...\r
860     nhsa.HardwareCapabilities = NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT;\r
861 #if 0\r
862     ... Only supported on B0\r
863 \r
864                                  NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV4_OPTIONS |\r
865                                  NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV6_EXTENSION_HEADERS |\r
866                                  NDIS_HD_SPLIT_CAPS_SUPPORTS_TCP_OPTIONS;\r
867 #endif\r
868 \r
869     // The bellow should be left zero\r
870     if (pPort->Config.HeaderDataSplit) {\r
871         nhsa.CurrentCapabilities = NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT;\r
872     } else {\r
873         nhsa.CurrentCapabilities = 0;\r
874     }\r
875 \r
876     nhsa.HDSplitFlags = 0;\r
877     nhsa.BackfillSize = 0;\r
878     nhsa.MaxHeaderSize = 0;    \r
879 \r
880     atr.HDSplitAttributes = &nhsa;\r
881 \r
882     Status = NdisMSetMiniportAttributes(h_adapter,\r
883                     (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&atr);\r
884 \r
885     if (nhsa.HDSplitFlags & NDIS_HD_SPLIT_ENABLE_HEADER_DATA_SPLIT) {\r
886         ASSERT(pPort->Config.HeaderDataSplit == TRUE);\r
887         pPort->Config.HeaderDataSplit = TRUE;\r
888     } \r
889     else {\r
890         ASSERT(pPort->Config.HeaderDataSplit == FALSE);\r
891         pPort->Config.HeaderDataSplit = FALSE;\r
892     }\r
893 \r
894     return Status;\r
895 }\r
896 #endif\r
897 \r
898 /*++\r
899 Routine Description:\r
900     the routine sets attributes that are associated with a miniport adapter.\r
901 \r
902 Arguments:\r
903     pPort - Pointer to port object\r
904 \r
905 Return Value:\r
906     NDIS_STATUS\r
907 \r
908 Note:\r
909     Should be called in PASSIVE_LEVEL\r
910     \r
911 --*/\r
912 NDIS_STATUS\r
913 SetAdapterRegistrationAttributes(\r
914         ipoib_adapter_t *p_adapter,\r
915         NDIS_HANDLE     h_adapter\r
916         )\r
917         {\r
918         NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES atr;\r
919         NTSTATUS Status;\r
920 \r
921         NdisZeroMemory(&atr, sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));\r
922 \r
923         /* setting registration attributes */\r
924 \r
925         atr.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;\r
926         atr.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;\r
927         atr.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;\r
928         //TODO NDIS60 Port or adapter\r
929         atr.MiniportAdapterContext = (NDIS_HANDLE)p_adapter; //(NDIS_HANDLE)pPort->p_adapter;\r
930         atr.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER;\r
931         atr.CheckForHangTimeInSeconds = 10;\r
932         atr.InterfaceType = NdisInterfacePci ;   // ???? UH\r
933         //TODO NDIS60 PNP or PCI ?\r
934         //RegistrationAttributes.InterfaceType = NdisInterfacePNPBus;\r
935 \r
936         Status = NdisMSetMiniportAttributes(h_adapter,\r
937                         (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&atr);\r
938 \r
939         return Status;\r
940 }\r
941 \r
942 \r
943 /*++\r
944 Routine Description:\r
945     the routine sets generic attributes that are associated with a miniport \r
946     adapter.\r
947 \r
948 Arguments:\r
949     pPort - Pointer to port object\r
950 \r
951 Return Value:\r
952     NDIS_STATUS\r
953 \r
954 Note:\r
955     Should be called in PASSIVE_LEVEL\r
956     \r
957 --*/\r
958 NDIS_STATUS\r
959 SetGenericAttributes(\r
960     ipoib_adapter_t *p_adapter,\r
961     NDIS_HANDLE h_adapter\r
962     )\r
963 {\r
964     NDIS_STATUS Status;\r
965 \r
966     NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES gat;\r
967     NdisZeroMemory(&gat, sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));\r
968 \r
969         /* set up generic attributes */\r
970 \r
971         gat.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;\r
972         gat.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;\r
973         gat.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);\r
974 \r
975         gat.MediaType = NdisMedium802_3;    \r
976         gat.MaxXmitLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
977         gat.MaxRcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
978         gat.XmitLinkSpeed = IPOIB_MEDIA_MAX_SPEED; //TODO NDIS60 NDIS_LINK_SPEED_UNKNOWN\r
979         gat.RcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED; // TODO NDIS60 NDIS_LINK_SPEED_UNKNOWN ???\r
980 \r
981         gat.MediaConnectState = MediaConnectStateConnected; //TODO NDIS60 Check the current state\r
982         gat.MediaDuplexState = MediaDuplexStateFull;\r
983 \r
984         gat.MtuSize = MAX_IB_MTU;\r
985         gat.LookaheadSize = MAX_XFER_BLOCK_SIZE;\r
986         gat.MacOptions = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \r
987                                          NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |\r
988                                          NDIS_MAC_OPTION_NO_LOOPBACK |\r
989                                          NDIS_MAC_OPTION_FULL_DUPLEX;\r
990                                         //NDIS_MAC_OPTION_8021P_PRIORITY; //TODO NDIS60\r
991                                         // DT: Enable for Header Data Split WHQL\r
992                                         // |  NDIS_MAC_OPTION_8021Q_VLAN;\r
993 \r
994         gat.SupportedPacketFilters =    NDIS_PACKET_TYPE_DIRECTED |\r
995                                                                         NDIS_PACKET_TYPE_MULTICAST |\r
996                                                                         //NDIS_PACKET_TYPE_ALL_MULTICAST |\r
997                                                                         NDIS_PACKET_TYPE_BROADCAST;\r
998                                          \r
999         gat.MaxMulticastListSize = MAX_MCAST;\r
1000 \r
1001         gat.MacAddressLength = HW_ADDR_LEN;\r
1002         \r
1003         NdisMoveMemory(gat.PermanentMacAddress,\r
1004                                         p_adapter->mac.addr,\r
1005                                         HW_ADDR_LEN);\r
1006 \r
1007         NdisMoveMemory(gat.CurrentMacAddress,\r
1008                                         p_adapter->params.conf_mac.addr,\r
1009                                         HW_ADDR_LEN);\r
1010 \r
1011 \r
1012         gat.PhysicalMediumType = NdisPhysicalMedium802_3;\r
1013         gat.AccessType = NET_IF_ACCESS_BROADCAST; \r
1014 \r
1015         gat.SupportedOidList = (PNDIS_OID)SUPPORTED_OIDS;\r
1016         gat.SupportedOidListLength = sizeof(SUPPORTED_OIDS);\r
1017 \r
1018 \r
1019         gat.DirectionType = NET_IF_DIRECTION_SENDRECEIVE; \r
1020         gat.ConnectionType = NET_IF_CONNECTION_DEDICATED; \r
1021         gat.IfType = IF_TYPE_ETHERNET_CSMACD; \r
1022         gat.IfConnectorPresent = TRUE; \r
1023         //TODO NDIS60 This value is absent for ETH driver\r
1024         gat.AccessType = NET_IF_ACCESS_BROADCAST; // NET_IF_ACCESS_BROADCAST for a typical ethernet adapter\r
1025 \r
1026 \r
1027         //TODO NDIS60 is it possible to reduce unsupported statistics\r
1028         gat.SupportedStatistics = \r
1029                                 NDIS_STATISTICS_XMIT_OK_SUPPORTED |\r
1030                                 NDIS_STATISTICS_RCV_OK_SUPPORTED |\r
1031                                 NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |\r
1032                                 NDIS_STATISTICS_RCV_ERROR_SUPPORTED |\r
1033                                 NDIS_STATISTICS_RCV_CRC_ERROR_SUPPORTED |\r
1034                                 NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED |\r
1035                                 NDIS_STATISTICS_TRANSMIT_QUEUE_LENGTH_SUPPORTED;\r
1036 \r
1037         //SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED |\r
1038                                                         // NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;\r
1039 \r
1040 \r
1041     //\r
1042     // Set power management capabilities\r
1043     //\r
1044     gat.PowerManagementCapabilities = NULL;\r
1045 #if 0\r
1046     NDIS_PNP_CAPABILITIES PowerManagementCapabilities;\r
1047     NdisZeroMemory(&PowerManagementCapabilities, sizeof(NDIS_PNP_CAPABILITIES));\r
1048     if (MPIsPoMgmtSupported(pPort))\r
1049     {\r
1050         MPFillPoMgmtCaps(pPort, &PowerManagementCapabilities, &Status, &unUsed);\r
1051         ASSERT(NT_SUCCESS(Status)); \r
1052         gat.PowerManagementCapabilities = &PowerManagementCapabilities;\r
1053     } \r
1054     else\r
1055     {\r
1056         \r
1057     }\r
1058 #endif\r
1059 \r
1060     //\r
1061     // Set RSS attributes\r
1062     //\r
1063     gat.RecvScaleCapabilities = NULL;\r
1064 #if 0\r
1065     NDIS_RECEIVE_SCALE_CAPABILITIES RssCapabilities;\r
1066     NdisZeroMemory(&RssCapabilities, sizeof(PNDIS_RECEIVE_SCALE_CAPABILITIES));\r
1067     Status = MPFillRssCapabilities(pPort, &RssCapabilities, &unUsed);\r
1068     if (NT_SUCCESS(Status)) \r
1069     {\r
1070         gat.RecvScaleCapabilities = &RssCapabilities;\r
1071     } \r
1072     else\r
1073     {\r
1074         //\r
1075         // do not fail the call because of failure to get PM caps\r
1076         //\r
1077         Status = NDIS_STATUS_SUCCESS;\r
1078         gat.RecvScaleCapabilities = NULL;\r
1079     }\r
1080 #endif\r
1081 \r
1082         Status = NdisMSetMiniportAttributes(h_adapter,\r
1083                         (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&gat);\r
1084 \r
1085         return Status;\r
1086 }\r
1087 \r
1088 \r
1089 /*++\r
1090 Routine Description:\r
1091     The routine sets an NDIS_OFFLOAD structure indicates the current offload \r
1092     capabilities that are provided by the miniport adapter \r
1093     \r
1094 Arguments:\r
1095     pPort - a pointer to port object\r
1096     offload - reference to NDIS_OFFLOAD object that should be filled\r
1097 \r
1098 Return Value:\r
1099     None.\r
1100     \r
1101 --*/\r
1102 static\r
1103 void\r
1104 OffloadConfig(\r
1105         ipoib_adapter_t *p_adapter,\r
1106         NDIS_OFFLOAD *p_offload\r
1107         )\r
1108\r
1109 \r
1110         ULONG ulEncapsulation = NDIS_ENCAPSULATION_IEEE_802_3 | NDIS_ENCAPSULATION_IEEE_802_3_P_AND_Q;\r
1111 \r
1112         NdisZeroMemory(p_offload, NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1);\r
1113 \r
1114         p_offload->Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;\r
1115         p_offload->Header.Revision = NDIS_OFFLOAD_REVISION_1; // BUGBUG: do we need to support revision 2? UH 17-May-2008\r
1116         p_offload->Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;\r
1117 \r
1118         p_offload->Checksum.IPv4Transmit.Encapsulation = ulEncapsulation;\r
1119         p_offload->Checksum.IPv4Transmit.IpOptionsSupported = \r
1120         p_offload->Checksum.IPv4Transmit.TcpOptionsSupported = \r
1121         p_offload->Checksum.IPv4Transmit.TcpChecksum = \r
1122         p_offload->Checksum.IPv4Transmit.UdpChecksum = \r
1123         p_offload->Checksum.IPv4Transmit.IpChecksum =!!(p_adapter->params.send_chksum_offload);\r
1124 \r
1125         p_offload->Checksum.IPv4Receive.Encapsulation = ulEncapsulation;\r
1126         p_offload->Checksum.IPv4Receive.IpOptionsSupported = \r
1127         p_offload->Checksum.IPv4Receive.TcpOptionsSupported = \r
1128         p_offload->Checksum.IPv4Receive.TcpChecksum = \r
1129         p_offload->Checksum.IPv4Receive.UdpChecksum = \r
1130         p_offload->Checksum.IPv4Receive.IpChecksum = !!(p_adapter->params.recv_chksum_offload); //TODO NDIS60\r
1131 \r
1132 \r
1133         p_offload->Checksum.IPv6Transmit.Encapsulation = ulEncapsulation;\r
1134         p_offload->Checksum.IPv6Transmit.IpExtensionHeadersSupported = \r
1135         p_offload->Checksum.IPv6Transmit.TcpOptionsSupported =\r
1136         p_offload->Checksum.IPv6Transmit.TcpChecksum = \r
1137         p_offload->Checksum.IPv6Transmit.UdpChecksum = FALSE;\r
1138 \r
1139 \r
1140         p_offload->Checksum.IPv6Receive.Encapsulation = ulEncapsulation;\r
1141         p_offload->Checksum.IPv6Receive.IpExtensionHeadersSupported = \r
1142         p_offload->Checksum.IPv6Receive.TcpOptionsSupported = \r
1143         p_offload->Checksum.IPv6Receive.TcpChecksum = \r
1144         p_offload->Checksum.IPv6Receive.UdpChecksum = FALSE;\r
1145 \r
1146         if (p_adapter->params.lso)\r
1147         {\r
1148                 p_offload->LsoV1.IPv4.Encapsulation = ulEncapsulation;\r
1149                 p_offload->LsoV1.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
1150 #define LSO_MIN_SEG_COUNT 2\r
1151                 p_offload->LsoV1.IPv4.MinSegmentCount = LSO_MIN_SEG_COUNT;\r
1152         \r
1153                 \r
1154                 p_offload->LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_SUPPORTED;\r
1155                 p_offload->LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_SUPPORTED;\r
1156 \r
1157                 p_offload->LsoV2.IPv4.Encapsulation = ulEncapsulation;\r
1158                 p_offload->LsoV2.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
1159                 p_offload->LsoV2.IPv4.MinSegmentCount = LSO_MIN_SEG_COUNT;\r
1160 \r
1161                 p_offload->LsoV2.IPv6.Encapsulation = ulEncapsulation;\r
1162                 p_offload->LsoV2.IPv6.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
1163                 p_offload->LsoV2.IPv6.MinSegmentCount = LSO_MIN_SEG_COUNT;\r
1164 \r
1165                 p_offload->LsoV2.IPv6.IpExtensionHeadersSupported = NDIS_OFFLOAD_NOT_SUPPORTED;\r
1166                 p_offload->LsoV2.IPv6.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;\r
1167         }\r
1168 \r
1169 }\r
1170 \r
1171 \r
1172 /*++\r
1173 Routine Description:\r
1174     The routine sets an NDIS_OFFLOAD structure that indicates all the task \r
1175     offload capabilites that are supported by the NIC. These capabilities include\r
1176     capabilities that are currently disabled by standardized keywords in the registry. \r
1177     \r
1178 Arguments:\r
1179     offload - reference to NDIS_OFFLOAD object that should be filled\r
1180 \r
1181 Return Value:\r
1182     None.\r
1183     \r
1184 --*/\r
1185 static\r
1186 void\r
1187 OffloadCapabilities(\r
1188         NDIS_OFFLOAD    *p_offload\r
1189         )\r
1190\r
1191         ULONG ulEncapsulation = NDIS_ENCAPSULATION_IEEE_802_3 | NDIS_ENCAPSULATION_IEEE_802_3_P_AND_Q ;\r
1192         NdisZeroMemory(p_offload, NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1);    \r
1193 \r
1194         p_offload->Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;\r
1195         p_offload->Header.Revision = NDIS_OFFLOAD_REVISION_1; // BUGBUG: do we need to support revision 2? UH 17-May-2008\r
1196         p_offload->Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;\r
1197 \r
1198         p_offload->Checksum.IPv4Transmit.Encapsulation = ulEncapsulation;\r
1199         p_offload->Checksum.IPv4Transmit.IpOptionsSupported = TRUE;\r
1200         p_offload->Checksum.IPv4Transmit.TcpOptionsSupported = TRUE;\r
1201         p_offload->Checksum.IPv4Transmit.TcpChecksum = TRUE;\r
1202         p_offload->Checksum.IPv4Transmit.UdpChecksum = TRUE;\r
1203         p_offload->Checksum.IPv4Transmit.IpChecksum = TRUE;\r
1204 \r
1205         p_offload->Checksum.IPv4Receive.Encapsulation = ulEncapsulation;\r
1206         p_offload->Checksum.IPv4Receive.IpOptionsSupported = TRUE;\r
1207         p_offload->Checksum.IPv4Receive.TcpOptionsSupported = TRUE;\r
1208         p_offload->Checksum.IPv4Receive.TcpChecksum = TRUE;\r
1209         p_offload->Checksum.IPv4Receive.UdpChecksum = TRUE; \r
1210         p_offload->Checksum.IPv4Receive.IpChecksum = TRUE;\r
1211 \r
1212 \r
1213         //\r
1214         //  BUGBUG::\r
1215         //  During a HW bug that didn't handle correctly packets with \r
1216         //  IPv6 Extension Headers -> we set IpExtensionHeadersSupported to TRUE\r
1217         //\r
1218         p_offload->Checksum.IPv6Transmit.Encapsulation = ulEncapsulation;\r
1219         p_offload->Checksum.IPv6Transmit.IpExtensionHeadersSupported = TRUE;\r
1220         p_offload->Checksum.IPv6Transmit.TcpOptionsSupported = TRUE;\r
1221         p_offload->Checksum.IPv6Transmit.TcpChecksum = TRUE;\r
1222         p_offload->Checksum.IPv6Transmit.UdpChecksum = TRUE;\r
1223 \r
1224 \r
1225         p_offload->Checksum.IPv6Receive.Encapsulation = ulEncapsulation;\r
1226         p_offload->Checksum.IPv6Receive.IpExtensionHeadersSupported = TRUE;\r
1227         p_offload->Checksum.IPv6Receive.TcpOptionsSupported = TRUE;\r
1228         p_offload->Checksum.IPv6Receive.TcpChecksum = TRUE;\r
1229         p_offload->Checksum.IPv6Receive.UdpChecksum = TRUE;\r
1230 \r
1231         p_offload->LsoV1.IPv4.Encapsulation = ulEncapsulation;\r
1232         p_offload->LsoV1.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
1233         p_offload->LsoV1.IPv4.MinSegmentCount = 2;\r
1234         p_offload->LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_SUPPORTED;\r
1235         p_offload->LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_SUPPORTED;\r
1236 \r
1237         p_offload->LsoV2.IPv4.Encapsulation = ulEncapsulation;\r
1238         p_offload->LsoV2.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
1239         p_offload->LsoV2.IPv4.MinSegmentCount = 2;\r
1240 \r
1241         p_offload->LsoV2.IPv6.Encapsulation = ulEncapsulation;\r
1242         p_offload->LsoV2.IPv6.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
1243         p_offload->LsoV2.IPv6.MinSegmentCount = 2;\r
1244 \r
1245         p_offload->LsoV2.IPv6.IpExtensionHeadersSupported = NDIS_OFFLOAD_NOT_SUPPORTED;\r
1246         p_offload->LsoV2.IPv6.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;\r
1247 \r
1248         }\r
1249 \r
1250 \r
1251 /*++\r
1252 Routine Description:\r
1253     The routine sets offload attributes that are associated with a miniport \r
1254     adapter.\r
1255 \r
1256 Arguments:\r
1257     pPort - Pointer to port object\r
1258 \r
1259 Return Value:\r
1260     NDIS_STATUS\r
1261 \r
1262 Note:\r
1263     Should be called in PASSIVE_LEVEL\r
1264     \r
1265 --*/\r
1266 NDIS_STATUS\r
1267 SetOffloadAttributes(\r
1268         ipoib_adapter_t *p_adapter,\r
1269         NDIS_HANDLE     h_adapter\r
1270         )\r
1271 {\r
1272         NDIS_STATUS Status;\r
1273         NDIS_OFFLOAD offload,hwOffload;\r
1274         //ULONG ulEncapsulation = NDIS_ENCAPSULATION_IEEE_802_3 | NDIS_ENCAPSULATION_IEEE_802_3_P_AND_Q;\r
1275 \r
1276         NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES oat;    \r
1277         NdisZeroMemory(&oat, sizeof(NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES));\r
1278 \r
1279         oat.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;\r
1280         oat.Header.Revision = NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;\r
1281         oat.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;\r
1282 \r
1283 \r
1284         OffloadConfig(p_adapter, &offload);\r
1285 \r
1286 \r
1287         OffloadCapabilities(&hwOffload);\r
1288 \r
1289         oat.DefaultOffloadConfiguration = &offload;\r
1290         oat.HardwareOffloadCapabilities = &hwOffload;\r
1291 \r
1292         Status = NdisMSetMiniportAttributes(h_adapter,\r
1293                                 (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&oat);\r
1294 \r
1295         return Status;\r
1296 }\r
1297 \r
1298 \r
1299 /*++\r
1300 \r
1301 Routine Description:\r
1302     An NDIS 6.0 miniport driver must call NdisMSetMiniportAttributes\r
1303     at least twice. The first call is to register itself with NDIS.\r
1304     The second call is to register the miniport driver's general\r
1305     attributes with NDIS.\r
1306 \r
1307     NdisMSetMiniportAttributes takes a parameter of type\r
1308     NDIS_MINIPORT_ADAPTER_ATTRIBUTES, which is a union of several miniport\r
1309     adapter attributes. Miniport drivers must first call\r
1310     NdisMSetMiniportAttributes and pass in an\r
1311     NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES structure\r
1312     that contains the pointer to its own context area, attribute flags,\r
1313     check-for-hang time, and interface type.\r
1314 \r
1315     All NDIS 6.0 miniport drivers are deserialized by default.\r
1316 \r
1317 Arguments:\r
1318     pPort - Pointer to port object\r
1319 \r
1320 Return Value:\r
1321     NDIS_STATUS\r
1322 \r
1323 Note:\r
1324     Should be called in PASSIVE_LEVEL\r
1325     \r
1326 --*/\r
1327         NDIS_STATUS\r
1328         SetAttributes(\r
1329         ipoib_adapter_t *p_adapter,\r
1330         NDIS_HANDLE     h_adapter\r
1331         )\r
1332         {\r
1333         NTSTATUS Status;\r
1334 \r
1335 \r
1336         Status = SetDeviceRegistrationAttributes(p_adapter, h_adapter);\r
1337         if (Status != NDIS_STATUS_SUCCESS)\r
1338         {\r
1339                 //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set device registration failed Error=0x%x\n", Status);\r
1340                 return Status;\r
1341         }\r
1342 \r
1343 \r
1344         Status = SetAdapterRegistrationAttributes(p_adapter, h_adapter);\r
1345         if (Status != NDIS_STATUS_SUCCESS)\r
1346         {\r
1347                 //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set adapter attributes failed Error=0x%x\n", Status);\r
1348                 return Status;\r
1349         }\r
1350 \r
1351         Status = SetOffloadAttributes(p_adapter, h_adapter);\r
1352         if (Status != NDIS_STATUS_SUCCESS)\r
1353         {\r
1354                 //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set OFFLOAD attributes failed Error=0x%x\n", Status);\r
1355                 return Status;\r
1356         }\r
1357         \r
1358 #if 0\r
1359         if(!pPort->Config.fWHQL)\r
1360         {\r
1361                 Status = SetHardwareAssistAttributes(pPort);\r
1362                 if (Status != NDIS_STATUS_SUCCESS)\r
1363                 {\r
1364                     //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set Hardware Assist Attributes failed Error=0x%x\n", Status);\r
1365                     return Status;\r
1366                 }\r
1367         }\r
1368 #endif\r
1369 \r
1370         Status = SetGenericAttributes(p_adapter, h_adapter);\r
1371         if (Status != NDIS_STATUS_SUCCESS)\r
1372         {\r
1373             //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set generic attributes failed Error=0x%x\n", Status);\r
1374             return Status;\r
1375         }\r
1376 \r
1377         return Status;\r
1378 }\r
1379 \r
1380 \r
1381 //TODO Don't pass h_adapter inside the function, use pPort->p_adapter->h_adapter\r
1382 NDIS_STATUS\r
1383 InitNdisScatterGatherDma(\r
1384         ipoib_adapter_t *p_adapter,\r
1385         NDIS_HANDLE             h_adapter\r
1386         )\r
1387 {\r
1388         NDIS_STATUS                                             status;\r
1389         NDIS_SG_DMA_DESCRIPTION                 DmaDescription;\r
1390         \r
1391         NdisZeroMemory(&DmaDescription, sizeof(DmaDescription));\r
1392 \r
1393         DmaDescription.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;\r
1394         DmaDescription.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1;\r
1395         DmaDescription.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION);\r
1396         DmaDescription.Flags = NDIS_SG_DMA_64_BIT_ADDRESS; \r
1397         //\r
1398         // Even if offload is enabled, the packet size for mapping shouldn't change\r
1399         //\r
1400         DmaDescription.MaximumPhysicalMapping = LARGE_SEND_OFFLOAD_SIZE + LSO_MAX_HEADER;\r
1401 \r
1402         DmaDescription.ProcessSGListHandler = ipoib_process_sg_list;\r
1403         DmaDescription.SharedMemAllocateCompleteHandler = NULL;\r
1404 \r
1405         DmaDescription.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;\r
1406         DmaDescription.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1;\r
1407         DmaDescription.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION);//NDIS_SIZEOF_SG_DMA_DESCRIPTION_REVISION_1;\r
1408 \r
1409         DmaDescription.Flags = NDIS_SG_DMA_64_BIT_ADDRESS;\r
1410         //DmaDescription.MaximumPhysicalMapping = pPort->p_adapter->params.xfer_block_size;\r
1411 \r
1412         DmaDescription.ProcessSGListHandler = ipoib_process_sg_list;\r
1413         DmaDescription.SharedMemAllocateCompleteHandler = NULL;\r
1414         \r
1415         status = NdisMRegisterScatterGatherDma(\r
1416                                         h_adapter,\r
1417                                         &DmaDescription,\r
1418                                         &p_adapter->NdisMiniportDmaHandle);\r
1419 \r
1420         if( status != NDIS_STATUS_SUCCESS )\r
1421         {\r
1422                 //TODO NDIS60\r
1423                 //ipoib_destroy_adapter( p_adapter );\r
1424                 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
1425                                                  ("NdisMRegisterScatterGatherDma returned 0x%.8x.\n", status) );\r
1426                 \r
1427         }\r
1428         //NDIS sets this value before it returns from NdisMRegisterScatterGatherDma. \r
1429                 //Miniport drivers should use this size to preallocate memory for each scatter/gather list. \r
1430         p_adapter->sg_list_size = DmaDescription.ScatterGatherListSize ;\r
1431         \r
1432         return status;\r
1433 }\r
1434 \r
1435 \r
1436 NDIS_STATUS\r
1437 ipoib_initialize_ex(\r
1438                 IN NDIS_HANDLE  h_adapter,\r
1439                 IN NDIS_HANDLE  config_context,\r
1440                 IN PNDIS_MINIPORT_INIT_PARAMETERS  MiniportInitParameters)\r
1441         {\r
1442                 NDIS_STATUS             status;\r
1443                 ib_api_status_t         ib_status;\r
1444                 ipoib_adapter_t         *p_adapter;\r
1445                 //NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES RegistrationAttributes;\r
1446                 //NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES              GeneralAttributes;\r
1447 #if IPOIB_USE_DMA\r
1448                 //NDIS_SG_DMA_DESCRIPTION       DmaDescription;\r
1449 #endif\r
1450                 IPOIB_ENTER( IPOIB_DBG_INIT );\r
1451         \r
1452 #ifdef _DEBUG_\r
1453                 PAGED_CODE();\r
1454 #endif\r
1455                 \r
1456                 UNUSED_PARAM( config_context );\r
1457                 UNUSED_PARAM( MiniportInitParameters );\r
1458                 \r
1459                 //foo1(100);\r
1460                 /* Create the adapter adapter */\r
1461                 ib_status = ipoib_create_adapter(config_context, h_adapter, &p_adapter );\r
1462                 if( ib_status != IB_SUCCESS )\r
1463                 {\r
1464                         IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
1465                                 ("ipoib_create_adapter returned status %d.\n", ib_status ) );\r
1466                         return NDIS_STATUS_FAILURE;\r
1467                 }\r
1468                 p_adapter->ipoib_state = IPOIB_PAUSED;\r
1469                 status  = SetAttributes(p_adapter, h_adapter);\r
1470                 if (status != NDIS_STATUS_SUCCESS) {\r
1471                         ASSERT(FALSE);\r
1472                 }\r
1473 #if 0\r
1474                 NdisZeroMemory(&RegistrationAttributes, sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));\r
1475                 NdisZeroMemory(&GeneralAttributes, sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));\r
1476         \r
1477                 /* setting registration attributes */\r
1478                 RegistrationAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;\r
1479                 RegistrationAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;\r
1480                 RegistrationAttributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;\r
1481         \r
1482                 RegistrationAttributes.MiniportAdapterContext = (NDIS_HANDLE)p_adapter;\r
1483                 RegistrationAttributes.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER;\r
1484                                                                                                                 \r
1485                 RegistrationAttributes.CheckForHangTimeInSeconds = 10;\r
1486                 RegistrationAttributes.InterfaceType = NdisInterfacePNPBus;\r
1487         \r
1488                 status = NdisMSetMiniportAttributes(h_adapter,\r
1489                                                                                    (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&RegistrationAttributes);\r
1490         \r
1491                 if (status != NDIS_STATUS_SUCCESS)\r
1492                 {\r
1493                         ipoib_destroy_adapter( p_adapter );\r
1494                         IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
1495                                 ("NdisMSetMiniportAttributes returned 0x%.8x.\n", status) );\r
1496                         return status;\r
1497                 }\r
1498         \r
1499                 /* set up generic attributes */\r
1500         \r
1501                  GeneralAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;\r
1502                  GeneralAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;\r
1503                  GeneralAttributes.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);\r
1504         \r
1505                  GeneralAttributes.MediaType = NdisMedium802_3;\r
1506                 //TODO\r
1507                  GeneralAttributes.MtuSize = MAX_IB_MTU;\r
1508                  GeneralAttributes.MaxXmitLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
1509                  GeneralAttributes.MaxRcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
1510                  GeneralAttributes.XmitLinkSpeed = NDIS_LINK_SPEED_UNKNOWN;\r
1511                  GeneralAttributes.RcvLinkSpeed = NDIS_LINK_SPEED_UNKNOWN;\r
1512                  GeneralAttributes.MediaConnectState = MediaConnectStateUnknown;\r
1513                  GeneralAttributes.MediaDuplexState = MediaDuplexStateUnknown;\r
1514                  GeneralAttributes.LookaheadSize = MAX_XFER_BLOCK_SIZE;\r
1515         \r
1516                  GeneralAttributes.PowerManagementCapabilities = NULL;\r
1517         \r
1518                  GeneralAttributes.MacOptions = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |\r
1519                                                                                 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |\r
1520                                                                                 NDIS_MAC_OPTION_NO_LOOPBACK |\r
1521                                                                                 NDIS_MAC_OPTION_FULL_DUPLEX;\r
1522         \r
1523                  GeneralAttributes.SupportedPacketFilters = NDIS_PACKET_TYPE_DIRECTED |\r
1524                                                                                                         NDIS_PACKET_TYPE_MULTICAST |\r
1525                                                                                                         NDIS_PACKET_TYPE_ALL_MULTICAST |\r
1526                                                                                                         NDIS_PACKET_TYPE_BROADCAST;\r
1527                         \r
1528                  GeneralAttributes.MaxMulticastListSize = MAX_MCAST;\r
1529                  GeneralAttributes.MacAddressLength = HW_ADDR_LEN;\r
1530         \r
1531                  NdisMoveMemory(GeneralAttributes.PermanentMacAddress,\r
1532                                                 p_adapter->mac.addr,\r
1533                                                 HW_ADDR_LEN);\r
1534         \r
1535                  NdisMoveMemory(GeneralAttributes.CurrentMacAddress,\r
1536                                                 p_adapter->params.conf_mac.addr,\r
1537                                                 HW_ADDR_LEN);\r
1538         \r
1539                         \r
1540                  GeneralAttributes.PhysicalMediumType = NdisPhysicalMediumUnspecified;\r
1541                  GeneralAttributes.RecvScaleCapabilities = NULL;\r
1542                  GeneralAttributes.AccessType = NET_IF_ACCESS_BROADCAST; // NET_IF_ACCESS_BROADCAST for a typical ethernet adapter\r
1543                  GeneralAttributes.DirectionType = NET_IF_DIRECTION_SENDRECEIVE; // NET_IF_DIRECTION_SENDRECEIVE for a typical ethernet adapter\r
1544                  GeneralAttributes.ConnectionType = NET_IF_CONNECTION_DEDICATED;  // NET_IF_CONNECTION_DEDICATED for a typical ethernet adapter\r
1545                  GeneralAttributes.IfType = IF_TYPE_ETHERNET_CSMACD; // IF_TYPE_ETHERNET_CSMACD for a typical ethernet adapter (regardless of speed)\r
1546                  GeneralAttributes.IfConnectorPresent = TRUE; // RFC 2665 TRUE if physical adapter\r
1547         \r
1548                  GeneralAttributes.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED |\r
1549                                                                                                  NDIS_STATISTICS_RCV_OK_SUPPORTED |\r
1550                                                                                                  NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |\r
1551                                                                                                  NDIS_STATISTICS_RCV_ERROR_SUPPORTED |\r
1552                                                                                                  NDIS_STATISTICS_RCV_CRC_ERROR_SUPPORTED |\r
1553                                                                                                  NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED |\r
1554                                                                                                  NDIS_STATISTICS_TRANSMIT_QUEUE_LENGTH_SUPPORTED |\r
1555                                                                                                  NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;\r
1556                                                   \r
1557                  GeneralAttributes.SupportedOidList = (PNDIS_OID)SUPPORTED_OIDS;\r
1558                  GeneralAttributes.SupportedOidListLength = sizeof(SUPPORTED_OIDS);\r
1559         \r
1560                  status = NdisMSetMiniportAttributes(h_adapter,\r
1561                                                                                         (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&GeneralAttributes);\r
1562         \r
1563                  if (status != NDIS_STATUS_SUCCESS)\r
1564                  {\r
1565                          IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
1566                                  ("NdisMSetMiniportAttributes returned 0x%.8x.\n", status) );\r
1567                  }\r
1568         \r
1569 #if IPOIB_USE_DMA\r
1570         \r
1571                  NdisZeroMemory(&DmaDescription, sizeof(DmaDescription));\r
1572         \r
1573                  DmaDescription.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;\r
1574                  DmaDescription.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1;\r
1575                  DmaDescription.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION);//NDIS_SIZEOF_SG_DMA_DESCRIPTION_REVISION_1;\r
1576         \r
1577                  DmaDescription.Flags = NDIS_SG_DMA_64_BIT_ADDRESS;\r
1578                  DmaDescription.MaximumPhysicalMapping = p_adapter->params.xfer_block_size;\r
1579                 \r
1580                  DmaDescription.ProcessSGListHandler = ipoib_process_sg_list;\r
1581                  DmaDescription.SharedMemAllocateCompleteHandler = NULL;\r
1582         \r
1583                  status = NdisMRegisterScatterGatherDma(\r
1584                                                 p_adapter->h_adapter,\r
1585                                                 &DmaDescription,\r
1586                                                 &p_adapter->NdisMiniportDmaHandle);\r
1587                                                 \r
1588                  if( status != NDIS_STATUS_SUCCESS )\r
1589                  {\r
1590                          ipoib_destroy_adapter( p_adapter );\r
1591                          IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
1592                                                          ("NdisMRegisterScatterGatherDma returned 0x%.8x.\n", status) );\r
1593                          return status;\r
1594                  }\r
1595 \r
1596                 \r
1597                 \r
1598 #endif\r
1599 #endif //if 0\r
1600 \r
1601 \r
1602 \r
1603 #if IPOIB_USE_DMA\r
1604 \r
1605                 InitNdisScatterGatherDma(p_adapter, h_adapter);\r
1606 \r
1607 \r
1608 \r
1609 #endif\r
1610                 /* Create the adapter adapter */\r
1611                 ib_status = ipoib_start_adapter( p_adapter );\r
1612                 if( ib_status != IB_SUCCESS )\r
1613                 {\r
1614                         NdisWriteErrorLogEntry( h_adapter,\r
1615                                 NDIS_ERROR_CODE_HARDWARE_FAILURE, 0 );\r
1616 #if  IPOIB_USE_DMA\r
1617                         NdisMDeregisterScatterGatherDma(p_adapter->NdisMiniportDmaHandle);\r
1618 #endif\r
1619                         ipoib_destroy_adapter( p_adapter );\r
1620                         IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
1621                                 ("ipoib_start_adapter returned status %d.\n", ib_status ) );\r
1622                         return NDIS_STATUS_FAILURE;\r
1623                 }\r
1624         \r
1625                 ipoib_ref_ibat();\r
1626         \r
1627                 IPOIB_EXIT( IPOIB_DBG_INIT );\r
1628                 return status;\r
1629         }\r
1630 \r
1631 \r
1632 //! Deallocates resources when the NIC is removed and halts the NIC..\r
1633 //TODO: Dispatch or Passive ?\r
1634 /*  IRQL = DISPATCH_LEVEL\r
1635 \r
1636 @param adapter_context The adapter context allocated at start\r
1637 */\r
1638 void\r
1639 ipoib_halt_ex(\r
1640         IN                              NDIS_HANDLE                                     adapter_context,\r
1641         IN                      NDIS_HALT_ACTION            HaltAction )\r
1642 {\r
1643         ipoib_adapter_t *p_adapter;\r
1644 \r
1645         IPOIB_ENTER( IPOIB_DBG_INIT );\r
1646 \r
1647         UNUSED_PARAM(HaltAction);\r
1648                 \r
1649         ipoib_deref_ibat();\r
1650 \r
1651         CL_ASSERT( adapter_context );\r
1652         p_adapter = (ipoib_adapter_t*)adapter_context;\r
1653 \r
1654         IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
1655                         ("Port %016I64x (CA %016I64x port %d) halting\n",\r
1656                         p_adapter->guids.port_guid.guid, p_adapter->guids.ca_guid,\r
1657                         p_adapter->guids.port_num) );\r
1658 \r
1659 #if IPOIB_USE_DMA\r
1660         if (p_adapter->NdisMiniportDmaHandle != NULL)\r
1661         {\r
1662                 NdisMDeregisterScatterGatherDma(p_adapter->NdisMiniportDmaHandle);\r
1663                 p_adapter->NdisMiniportDmaHandle = NULL;\r
1664         }\r
1665 #endif\r
1666         ipoib_destroy_adapter( p_adapter );\r
1667 \r
1668         IPOIB_EXIT( IPOIB_DBG_INIT );\r
1669 }\r
1670 \r
1671 \r
1672 //! Reports the state of the NIC, or monitors the responsiveness of an underlying device driver.\r
1673 /*  IRQL = DISPATCH_LEVEL\r
1674 \r
1675 @param adapter_context The adapter context allocated at start\r
1676 @return TRUE if the driver determines that its NIC is not operating\r
1677 */\r
1678 BOOLEAN\r
1679 ipoib_check_for_hang(\r
1680         IN                              NDIS_HANDLE                                     adapter_context )\r
1681 {\r
1682         ipoib_adapter_t *p_adapter;\r
1683 \r
1684         IPOIB_ENTER( IPOIB_DBG_INIT );\r
1685 \r
1686         CL_ASSERT( adapter_context );\r
1687         p_adapter = (ipoib_adapter_t*)adapter_context;\r
1688 \r
1689         if( p_adapter->reset )\r
1690         {\r
1691                 IPOIB_EXIT( IPOIB_DBG_INIT );\r
1692                 return FALSE;\r
1693         }\r
1694         if (p_adapter->hung) {\r
1695                 ipoib_resume_oids(p_adapter);\r
1696         }\r
1697 \r
1698         IPOIB_EXIT( IPOIB_DBG_INIT );\r
1699         return (p_adapter->hung? TRUE:FALSE);\r
1700 }\r
1701 \r
1702 \r
1703 /*++\r
1704 Routine Description:\r
1705         The routine sets an NDIS_OFFLOAD structure indicates the current offload \r
1706         capabilities that are provided by the miniport adapter \r
1707 \r
1708 Arguments:\r
1709         pPort - a pointer to port object\r
1710         offload - reference to NDIS_OFFLOAD object that should be filled\r
1711 \r
1712 Return Value:\r
1713         None.\r
1714 \r
1715 --*/\r
1716 //TODO\r
1717 #if 0\r
1718 static\r
1719 void\r
1720 __ipoib_get_offload_config(\r
1721         ipoib_port_t *pPort,\r
1722         NDIS_OFFLOAD *p_offload\r
1723         )\r
1724 {\r
1725         NDIS_STATUS Status;\r
1726         ULONG TxChksumOffload = ((MP_GET_PORT_CONFIG(pPort, TxChksumOffload) == TRUE) ? NDIS_OFFLOAD_SET_ON : NDIS_OFFLOAD_SET_OFF);\r
1727         ULONG RxChksumOffload = ((MP_GET_PORT_CONFIG(pPort, RxChksumOffload) == TRUE) ? NDIS_OFFLOAD_SET_ON : NDIS_OFFLOAD_SET_OFF);\r
1728         BOOLEAN fLargeSendOffload = MP_GET_PORT_CONFIG(pPort, LargeSendOffload);\r
1729         ULONG ulEncapsulation = NDIS_ENCAPSULATION_IEEE_802_3 | NDIS_ENCAPSULATION_IEEE_802_3_P_AND_Q;\r
1730             \r
1731         NdisZeroMemory(&*p_offload, sizeof(NDIS_OFFLOAD));\r
1732         *p_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;\r
1733         *p_offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; // BUGBUG: do we need to support revision 2? UH 17-May-2008\r
1734         *p_offload.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;\r
1735 \r
1736         *p_offload.Checksum.IPv4Transmit.Encapsulation = ulEncapsulation;\r
1737         *p_offload.Checksum.IPv4Transmit.IpOptionsSupported = TxChksumOffload;\r
1738         *p_offload.Checksum.IPv4Transmit.TcpOptionsSupported = TxChksumOffload;\r
1739         *p_offload.Checksum.IPv4Transmit.TcpChecksum = TxChksumOffload;\r
1740         *p_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_NOT_SUPPORTED;\r
1741         *p_offload.Checksum.IPv4Transmit.IpChecksum = TxChksumOffload;\r
1742 \r
1743         *p_offload.Checksum.IPv4Receive.Encapsulation = ulEncapsulation;\r
1744         *p_offload.Checksum.IPv4Receive.IpOptionsSupported = RxChksumOffload;\r
1745         *p_offload.Checksum.IPv4Receive.TcpOptionsSupported = RxChksumOffload;\r
1746         *p_offload.Checksum.IPv4Receive.TcpChecksum = RxChksumOffload;\r
1747         *p_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_NOT_SUPPORTED; \r
1748         *p_offload.Checksum.IPv4Receive.IpChecksum = RxChksumOffload;\r
1749 \r
1750         *p_offload.Checksum.IPv6Transmit.Encapsulation = ulEncapsulation;\r
1751         *p_offload.Checksum.IPv6Transmit.IpExtensionHeadersSupported = TxChksumOffload;\r
1752         *p_offload.Checksum.IPv6Transmit.TcpOptionsSupported = TxChksumOffload;\r
1753         *p_offload.Checksum.IPv6Transmit.TcpChecksum = TxChksumOffload;\r
1754         *p_offload.Checksum.IPv6Transmit.UdpChecksum = NDIS_OFFLOAD_NOT_SUPPORTED;\r
1755 \r
1756 \r
1757         *p_offload.Checksum.IPv6Receive.Encapsulation = ulEncapsulation;\r
1758         *p_offload.Checksum.IPv6Receive.IpExtensionHeadersSupported = RxChksumOffload;\r
1759         *p_offload.Checksum.IPv6Receive.TcpOptionsSupported = RxChksumOffload;\r
1760         *p_offload.Checksum.IPv6Receive.TcpChecksum = RxChksumOffload;\r
1761         *p_offload.Checksum.IPv6Receive.UdpChecksum = NDIS_OFFLOAD_NOT_SUPPORTED;\r
1762 \r
1763         if (fLargeSendOffload)\r
1764         {\r
1765             *p_offload.LsoV1.IPv4.Encapsulation = ulEncapsulation;\r
1766             *p_offload.LsoV1.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
1767             *p_offload.LsoV1.IPv4.MinSegmentCount = 1;\r
1768             *p_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_SUPPORTED;\r
1769             *p_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_SUPPORTED;\r
1770         }\r
1771 }\r
1772 #endif\r
1773 \r
1774 //! Returns information about the capabilities and status of the driver and/or its NIC.\r
1775 /*  IRQL = DISPATCH_LEVEL\r
1776 \r
1777 @param adapter_context The adapter context allocated at start\r
1778 @param oid Object ID representing the query operation to be carried out\r
1779 @param info_buf Buffer containing any input for this query and location for output\r
1780 @param info_buf_len Number of bytes available in info_buf\r
1781 @param p_bytes_written Pointer to number of bytes written into info_buf\r
1782 @param p_bytes_needed Pointer to number of bytes needed to satisfy this oid\r
1783 @return NDIS_STATUS_SUCCESS, NDIS_STATUS_PENDING, NDIS_STATUS_INVALID_OID,\r
1784 NDIS_STATUS_INVALID_LENGTH, NDIS_STATUS_NOT_ACCEPTED, NDIS_STATUS_NOT_SUPPORTED,\r
1785 NDIS_STATUS_RESOURCES\r
1786 */\r
1787         NDIS_STATUS\r
1788 ipoib_query_info(\r
1789         IN                              NDIS_HANDLE                                     adapter_context,\r
1790         IN                              NDIS_OID                                        oid,\r
1791         IN                              PVOID                                           info_buf,\r
1792         IN                              ULONG                                           info_buf_len,\r
1793                 OUT                     PULONG                                          p_bytes_written,\r
1794                 OUT                     PULONG                                          p_bytes_needed )\r
1795         {\r
1796         ipoib_adapter_t         *p_adapter;\r
1797                 NDIS_STATUS             status;\r
1798                 USHORT                          version;\r
1799         ULONG                           info;\r
1800                 PVOID                           src_buf;\r
1801                 ULONG                           buf_len;\r
1802                 pending_oid_t           oid_info;\r
1803         uint8_t                         port_num;\r
1804                 \r
1805                 IPOIB_ENTER( IPOIB_DBG_OID );\r
1806                 \r
1807                 oid_info.oid = oid;\r
1808                 oid_info.p_buf = info_buf;\r
1809                 oid_info.buf_len = info_buf_len;\r
1810                 oid_info.p_bytes_used = p_bytes_written;\r
1811                 oid_info.p_bytes_needed = p_bytes_needed;\r
1812                 \r
1813                 CL_ASSERT( adapter_context );\r
1814                 p_adapter = (ipoib_adapter_t*)adapter_context;\r
1815 \r
1816                 CL_ASSERT( p_bytes_written );\r
1817                 CL_ASSERT( p_bytes_needed );\r
1818                 CL_ASSERT( !p_adapter->pending_query );\r
1819                 \r
1820                         status = NDIS_STATUS_SUCCESS;\r
1821                         src_buf = &info;\r
1822                 buf_len = sizeof(info);\r
1823         \r
1824                 port_num = p_adapter->guids.port_num;\r
1825         \r
1826                 switch( oid )\r
1827                 {\r
1828                 /* Required General */\r
1829                 case OID_GEN_SUPPORTED_LIST:\r
1830                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1831                                 ("Port %d received query for OID_GEN_SUPPORTED_LIST\n", port_num) );\r
1832                         src_buf = (PVOID)SUPPORTED_OIDS;\r
1833                         buf_len = sizeof(SUPPORTED_OIDS);\r
1834                         break;\r
1835         \r
1836                 case OID_GEN_HARDWARE_STATUS:\r
1837                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1838                                 ("Port %d received query for OID_GEN_HARDWARE_STATUS\n", port_num) );\r
1839                         cl_obj_lock( &p_adapter->obj );\r
1840                         switch( p_adapter->state )\r
1841                         {\r
1842                         case IB_PNP_PORT_ADD:\r
1843                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1844                                         ("Port %d returning NdisHardwareStatusInitializing\n", port_num) );\r
1845                                 info = NdisHardwareStatusInitializing;\r
1846                                 break;\r
1847                                 \r
1848                         case IB_PNP_PORT_ACTIVE:\r
1849                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1850                                         ("Port %d returning NdisHardwareStatusReady\n", port_num) );\r
1851                                 info = NdisHardwareStatusReady;\r
1852                                 break;\r
1853         \r
1854                         default:\r
1855                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1856                                         ("Port %d returning NdisHardwareStatusNotReady\n", port_num) );\r
1857                                 info = NdisHardwareStatusNotReady;\r
1858                         }\r
1859                         cl_obj_unlock( &p_adapter->obj );\r
1860                         break;\r
1861         \r
1862                 case OID_GEN_MEDIA_SUPPORTED:\r
1863                 case OID_GEN_MEDIA_IN_USE:\r
1864                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1865                                 ("Port %d received query for OID_GEN_MEDIA_SUPPORTED "\r
1866                                 "or OID_GEN_MEDIA_IN_USE\n", port_num) );\r
1867                         info = NdisMedium802_3;\r
1868                         break;\r
1869         \r
1870                 case OID_GEN_MAXIMUM_FRAME_SIZE:\r
1871                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1872                                 ("Port %d received query for OID_GEN_MAXIMUM_FRAME_SIZE\n", port_num) );\r
1873                         if( p_adapter->params.cm_enabled )\r
1874                         {\r
1875                                 info = p_adapter->params.cm_payload_mtu;\r
1876                         }\r
1877                         else\r
1878                         {\r
1879                                 info = p_adapter->params.payload_mtu;\r
1880                         }\r
1881                         break;\r
1882         \r
1883                 case OID_GEN_LINK_SPEED:\r
1884                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1885                                 ("Port %d received query for OID_GEN_LINK_SPEED\n", port_num) );\r
1886                         if (info_buf_len < buf_len)\r
1887                         {\r
1888                                 break;\r
1889                         }\r
1890         \r
1891                         cl_obj_lock( &p_adapter->obj );\r
1892                         switch( p_adapter->state )\r
1893                         {\r
1894                         case IB_PNP_PORT_ADD:\r
1895                                 /* Mark the adapter as pending an OID */\r
1896                                 p_adapter->pending_query = TRUE;\r
1897         \r
1898                                 /* Save the request parameters. */\r
1899                                 p_adapter->query_oid = oid_info;\r
1900         \r
1901                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1902                                         ("Port %d returning NDIS_STATUS_PENDING\n", port_num) );\r
1903                                 status = NDIS_STATUS_PENDING;\r
1904                                 break;\r
1905         \r
1906                         case IB_PNP_PORT_REMOVE:\r
1907                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1908                                         ("Port %d returning NDIS_STATUS_NOT_ACCEPTED\n", port_num) );\r
1909                                 status = NDIS_STATUS_NOT_ACCEPTED;\r
1910                                 break;\r
1911         \r
1912                         default:\r
1913                                 CL_ASSERT( p_adapter->p_port );\r
1914                                 info = p_adapter->port_rate;\r
1915                                 break;\r
1916                         }\r
1917                         cl_obj_unlock( &p_adapter->obj );\r
1918                         break;\r
1919         \r
1920                 case OID_GEN_TRANSMIT_BUFFER_SPACE:\r
1921                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1922                                 ("Port %d received query for OID_GEN_TRANSMIT_BUFFER_SPACE\n", port_num) );\r
1923                         if( p_adapter->params.cm_enabled )\r
1924                                 info = p_adapter->params.sq_depth * p_adapter->params.cm_xfer_block_size;\r
1925                         else\r
1926                                 info = p_adapter->params.sq_depth * p_adapter->params.xfer_block_size;\r
1927                         break;\r
1928         \r
1929                 case OID_GEN_RECEIVE_BUFFER_SPACE:\r
1930                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1931                                 ("Port %d received query for OID_GEN_TRANSMIT_BUFFER_SPACE "\r
1932                                 "or OID_GEN_RECEIVE_BUFFER_SPACE\n", port_num) );\r
1933                         if( p_adapter->params.cm_enabled )\r
1934                                 info = p_adapter->params.rq_depth * p_adapter->params.cm_xfer_block_size;\r
1935                         else\r
1936                                 info = p_adapter->params.rq_depth * p_adapter->params.xfer_block_size;\r
1937                         break;\r
1938         \r
1939                 case OID_GEN_MAXIMUM_LOOKAHEAD:\r
1940                 case OID_GEN_CURRENT_LOOKAHEAD:\r
1941                 case OID_GEN_TRANSMIT_BLOCK_SIZE:\r
1942                 case OID_GEN_RECEIVE_BLOCK_SIZE:\r
1943                 case OID_GEN_MAXIMUM_TOTAL_SIZE:\r
1944                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1945                                 ("Port %d received query for OID_GEN_MAXIMUM_LOOKAHEAD "\r
1946                                 "or OID_GEN_CURRENT_LOOKAHEAD or "\r
1947                                 "OID_GEN_TRANSMIT_BLOCK_SIZE or "\r
1948                                 "OID_GEN_RECEIVE_BLOCK_SIZE or "\r
1949                                 "OID_GEN_MAXIMUM_TOTAL_SIZE\n", port_num) );\r
1950                         if( p_adapter->params.cm_enabled )\r
1951                                 info = p_adapter->params.cm_xfer_block_size;\r
1952                         else\r
1953                                 info = p_adapter->params.xfer_block_size;\r
1954                         break;\r
1955         \r
1956                 case OID_GEN_VENDOR_ID:\r
1957                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1958                                 ("Port %d received query for OID_GEN_VENDOR_ID\n", port_num) );\r
1959                         src_buf = (void*)VENDOR_ID;\r
1960                 buf_len = sizeof(VENDOR_ID);\r
1961                         break;\r
1962         \r
1963                 case OID_GEN_VENDOR_DESCRIPTION:\r
1964                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID, \r
1965                                 ("Port %d received query for OID_GEN_VENDOR_DESCRIPTION\n", port_num) );\r
1966                         src_buf = VENDOR_DESCRIPTION;\r
1967                 buf_len = sizeof(VENDOR_DESCRIPTION);\r
1968                         break;\r
1969         \r
1970                 case OID_GEN_VENDOR_DRIVER_VERSION:\r
1971                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1972                                 ("Port %d received query for OID_GEN_VENDOR_DRIVER_VERSION\n", port_num) );\r
1973                         src_buf = &version;\r
1974                 buf_len = sizeof(version);\r
1975                         //TODO: Figure out what the right version is.\r
1976                         version = 1 << 8 | 1;\r
1977                         break;\r
1978         \r
1979                 case OID_GEN_PHYSICAL_MEDIUM:\r
1980                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1981                                 ("Port %d received query for OID_GEN_PHYSICAL_MEDIUM\n", port_num) );\r
1982                         info = NdisPhysicalMediumUnspecified;\r
1983                         break;\r
1984         \r
1985                 case OID_GEN_CURRENT_PACKET_FILTER:\r
1986                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1987                                 ("Port %d received query for OID_GEN_CURRENT_PACKET_FILTER\n", port_num) );\r
1988                         info = p_adapter->packet_filter;\r
1989                         break;\r
1990         \r
1991                 case OID_GEN_DRIVER_VERSION:\r
1992                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
1993                                 ("Port %d received query for OID_GEN_DRIVER_VERSION\n", port_num) );\r
1994                         src_buf = &version;\r
1995                 buf_len = sizeof(version);\r
1996                         version = MAJOR_NDIS_VERSION << 8 | MINOR_NDIS_VERSION;\r
1997                         break;\r
1998         \r
1999                 case OID_GEN_MAC_OPTIONS:\r
2000                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2001                                 ("Port %d received query for OID_GEN_MAC_OPTIONS\n", port_num) );\r
2002                         info = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |\r
2003                                 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |\r
2004                                 NDIS_MAC_OPTION_NO_LOOPBACK |\r
2005                                 NDIS_MAC_OPTION_FULL_DUPLEX;\r
2006         //TODO: Figure out if we will support priority and VLANs.\r
2007         //                              NDIS_MAC_OPTION_8021P_PRIORITY;\r
2008         //#ifdef NDIS51_MINIPORT\r
2009         //                      info |= NDIS_MAC_OPTION_8021Q_VLAN;\r
2010         //#endif\r
2011                         break;\r
2012         \r
2013                 case OID_GEN_MEDIA_CONNECT_STATUS:\r
2014                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2015                                 ("Port %d received query for OID_GEN_MEDIA_CONNECT_STATUS\n", port_num) );\r
2016                         cl_obj_lock( &p_adapter->obj );\r
2017                         switch( p_adapter->state )\r
2018                         {\r
2019                         case IB_PNP_PORT_ADD:\r
2020                         case IB_PNP_PORT_INIT:\r
2021                                 /*\r
2022                                  * Delay reporting media state until we know whether the port is\r
2023                                  * either up or down.\r
2024                                  */\r
2025                                 p_adapter->pending_query = TRUE;\r
2026                                 p_adapter->query_oid = oid_info;\r
2027         \r
2028                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2029                                         ("Port %d returning NDIS_STATUS_PENDING\n", port_num) );\r
2030                                 status = NDIS_STATUS_PENDING;\r
2031                                 break;\r
2032         \r
2033                         case IB_PNP_PORT_ACTIVE:\r
2034                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2035                                         ("Port %d returning NdisMediaStateConnected\n", port_num) );\r
2036                                 info = NdisMediaStateConnected;\r
2037                                 break;\r
2038         \r
2039                         case IB_PNP_PORT_REMOVE:\r
2040                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2041                                         ("Port %d returning NDIS_STATUS_NOT_ACCEPTED\n", port_num) );\r
2042                                 status = NDIS_STATUS_NOT_ACCEPTED;\r
2043                                 break;\r
2044         \r
2045                         default:\r
2046                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2047                                         ("Port %d returning NdisMediaStateDisconnected\n", port_num) );\r
2048                                 info = NdisMediaStateDisconnected;\r
2049                         }\r
2050                         cl_obj_unlock( &p_adapter->obj );\r
2051                         break;\r
2052         \r
2053                 case OID_GEN_MAXIMUM_SEND_PACKETS:\r
2054                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2055                                 ("Port %d received query for OID_GEN_MAXIMUM_SEND_PACKETS\n", port_num) );\r
2056                         info = MINIPORT_MAX_SEND_PACKETS;\r
2057                         break;\r
2058         \r
2059                 /* Required General Statistics */\r
2060                 case OID_GEN_STATISTICS:\r
2061                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2062                                 ("Port %d received query for OID_GEN_STATISTICS\n", port_num) );\r
2063                         src_buf = NULL;   \r
2064                          buf_len =  sizeof(NDIS_STATISTICS_INFO);\r
2065                         if (info_buf_len < buf_len)\r
2066                         {\r
2067                            break;\r
2068                         } \r
2069                         status = ipoib_get_gen_stat(p_adapter, &oid_info );\r
2070                         break;\r
2071         \r
2072                 case OID_GEN_XMIT_OK:\r
2073                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2074                                 ("Port %d received query for OID_GEN_XMIT_OK\n", port_num) );\r
2075                         src_buf = NULL;\r
2076                         status = ipoib_get_send_stat( p_adapter, IP_STAT_SUCCESS, &oid_info );\r
2077                         break;\r
2078         \r
2079                 case OID_GEN_RCV_OK:\r
2080                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2081                                 ("Port %d received query for OID_GEN_RCV_OK\n", port_num) );\r
2082                         src_buf = NULL;\r
2083                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_SUCCESS, &oid_info );\r
2084                         break;\r
2085         \r
2086                 case OID_GEN_XMIT_ERROR:\r
2087                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2088                                 ("Port %d received query for OID_GEN_XMIT_ERROR\n", port_num) );\r
2089                         src_buf = NULL;\r
2090                         status = ipoib_get_send_stat( p_adapter, IP_STAT_ERROR, &oid_info );\r
2091                         break;\r
2092         \r
2093                 case OID_GEN_RCV_ERROR:\r
2094                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2095                                 ("Port %d received query for OID_GEN_RCV_ERROR\n", port_num) );\r
2096                         src_buf = NULL;\r
2097                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_ERROR, &oid_info );\r
2098                         break;\r
2099         \r
2100                 case OID_GEN_RCV_NO_BUFFER:\r
2101                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2102                                 ("Port %d received query for OID_GEN_RCV_NO_BUFFER\n", port_num) );\r
2103                         src_buf = NULL;\r
2104                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_DROPPED, &oid_info );\r
2105                         break;\r
2106         \r
2107                 case OID_GEN_DIRECTED_BYTES_XMIT:\r
2108                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2109                                 ("Port %d received query for OID_GEN_DIRECTED_BYTES_XMIT\n", port_num) );\r
2110                         src_buf = NULL;\r
2111                         status = ipoib_get_send_stat( p_adapter, IP_STAT_UCAST_BYTES, &oid_info );\r
2112                         break;\r
2113         \r
2114                 case OID_GEN_DIRECTED_FRAMES_XMIT:\r
2115                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2116                                 ("Port %d received query for OID_GEN_DIRECTED_FRAMES_XMIT\n", port_num) );\r
2117                         src_buf = NULL;\r
2118                         status = ipoib_get_send_stat( p_adapter, IP_STAT_UCAST_FRAMES, &oid_info );\r
2119                         break;\r
2120         \r
2121                 case OID_GEN_MULTICAST_BYTES_XMIT:\r
2122                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2123                                 ("Port %d received query for OID_GEN_MULTICAST_BYTES_XMIT\n", port_num) );\r
2124                         src_buf = NULL;\r
2125                         status = ipoib_get_send_stat( p_adapter, IP_STAT_MCAST_BYTES, &oid_info );\r
2126                         break;\r
2127         \r
2128                 case OID_GEN_MULTICAST_FRAMES_XMIT:\r
2129                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2130                                 ("Port %d received query for OID_GEN_MULTICAST_FRAMES_XMIT\n", port_num) );\r
2131                         src_buf = NULL;\r
2132                         status = ipoib_get_send_stat( p_adapter, IP_STAT_MCAST_FRAMES, &oid_info );\r
2133                         break;\r
2134         \r
2135                 case OID_GEN_BROADCAST_BYTES_XMIT:\r
2136                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2137                                 ("Port %d received query for OID_GEN_BROADCAST_BYTES_XMIT\n", port_num) );\r
2138                         src_buf = NULL;\r
2139                         status = ipoib_get_send_stat( p_adapter, IP_STAT_BCAST_BYTES, &oid_info );\r
2140                         break;\r
2141         \r
2142                 case OID_GEN_BROADCAST_FRAMES_XMIT:\r
2143                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2144                                 ("Port %d received query for OID_GEN_BROADCAST_FRAMES_XMIT\n", port_num) );\r
2145                         src_buf = NULL;\r
2146                         status = ipoib_get_send_stat( p_adapter, IP_STAT_BCAST_FRAMES, &oid_info );\r
2147                         break;\r
2148         \r
2149                 case OID_GEN_DIRECTED_BYTES_RCV:\r
2150                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2151                                 ("Port %d received query for OID_GEN_DIRECTED_BYTES_RCV\n", port_num) );\r
2152                         src_buf = NULL;\r
2153                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_UCAST_BYTES, &oid_info );\r
2154                         break;\r
2155         \r
2156                 case OID_GEN_DIRECTED_FRAMES_RCV:\r
2157                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2158                                 ("Port %d received query for OID_GEN_DIRECTED_FRAMES_RCV\n", port_num) );\r
2159                         src_buf = NULL;\r
2160                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_UCAST_FRAMES, &oid_info );\r
2161                         break;\r
2162         \r
2163                 case OID_GEN_MULTICAST_BYTES_RCV:\r
2164                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2165                                 ("Port %d received query for OID_GEN_MULTICAST_BYTES_RCV\n", port_num) );\r
2166                         src_buf = NULL;\r
2167                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_MCAST_BYTES, &oid_info );\r
2168                         break;\r
2169         \r
2170                 case OID_GEN_MULTICAST_FRAMES_RCV:\r
2171                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2172                                 ("Port %d received query for OID_GEN_MULTICAST_FRAMES_RCV\n", port_num) );\r
2173                         src_buf = NULL;\r
2174                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_MCAST_FRAMES, &oid_info );\r
2175                         break;\r
2176         \r
2177                 case OID_GEN_BROADCAST_BYTES_RCV:\r
2178                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2179                                 ("Port %d received query for OID_GEN_BROADCAST_BYTES_RCV\n", port_num) );\r
2180                         src_buf = NULL;\r
2181                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_BCAST_BYTES, &oid_info );\r
2182                         break;\r
2183         \r
2184                 case OID_GEN_BROADCAST_FRAMES_RCV:\r
2185                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2186                                 ("Port %d received query for OID_GEN_BROADCAST_FRAMES_RCV\n", port_num) );\r
2187                         src_buf = NULL;\r
2188                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_BCAST_FRAMES, &oid_info );\r
2189                         break;\r
2190         \r
2191                 /* Required Ethernet operational characteristics */\r
2192                 case OID_802_3_PERMANENT_ADDRESS:\r
2193                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2194                                 ("Port %d received query for OID_802_3_PERMANENT_ADDRESS\n", port_num) );\r
2195                         src_buf = &p_adapter->mac;\r
2196                 buf_len = sizeof(p_adapter->mac);\r
2197                         break;\r
2198         \r
2199                 case OID_802_3_CURRENT_ADDRESS:\r
2200                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2201                                 ("Port %d received query for OID_802_3_CURRENT_ADDRESS\n", port_num) );\r
2202                         src_buf = &p_adapter->params.conf_mac;\r
2203                 buf_len = sizeof(p_adapter->params.conf_mac);\r
2204                         break;\r
2205         \r
2206                 case OID_802_3_MULTICAST_LIST:\r
2207                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2208                                 ("Port %d received query for OID_802_3_MULTICAST_LIST\n", port_num) );\r
2209                         src_buf = p_adapter->mcast_array;\r
2210                 buf_len = p_adapter->mcast_array_size * sizeof(mac_addr_t);\r
2211                         break;\r
2212         \r
2213                 case OID_802_3_MAXIMUM_LIST_SIZE:\r
2214                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2215                                 ("Port %d received query for OID_802_3_MAXIMUM_LIST_SIZE\n", port_num) );\r
2216                         info = MAX_MCAST;\r
2217                         break;\r
2218         \r
2219                 case OID_802_3_MAC_OPTIONS:\r
2220                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2221                                 ("Port %d received query for OID_802_3_MAC_OPTIONS\n", port_num) );\r
2222                         info = 0;\r
2223                         break;\r
2224         \r
2225                 /* Required Ethernet stats */\r
2226                 case OID_802_3_RCV_ERROR_ALIGNMENT:\r
2227                 case OID_802_3_XMIT_ONE_COLLISION:\r
2228                 case OID_802_3_XMIT_MORE_COLLISIONS:\r
2229                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2230                                 ("Port %d received query for OID_802_3_RCV_ERROR_ALIGNMENT or "\r
2231                                 "OID_802_3_XMIT_ONE_COLLISION or "\r
2232                                 "OID_802_3_XMIT_MORE_COLLISIONS\n", port_num) );\r
2233                         info = 0;\r
2234                         break;\r
2235         \r
2236                 case OID_TCP_TASK_OFFLOAD:\r
2237                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2238                                 ("Port %d received query for OID_TCP_TASK_OFFLOAD\n", port_num) );\r
2239                         src_buf = NULL;\r
2240                         status = __ipoib_get_tcp_task_offload( p_adapter, &oid_info );\r
2241                         break;\r
2242         \r
2243                 /* Optional General */\r
2244                 case OID_GEN_SUPPORTED_GUIDS:\r
2245 #ifdef NDIS51_MINIPORT\r
2246                 case OID_GEN_VLAN_ID:\r
2247 #endif\r
2248         \r
2249                 /* Optional General Stats */\r
2250                 case OID_GEN_RCV_CRC_ERROR:\r
2251                 case OID_GEN_TRANSMIT_QUEUE_LENGTH:\r
2252         \r
2253                 /* Optional Ethernet Stats */\r
2254                 case OID_802_3_XMIT_DEFERRED:\r
2255                 case OID_802_3_XMIT_MAX_COLLISIONS:\r
2256                 case OID_802_3_RCV_OVERRUN:\r
2257                 case OID_802_3_XMIT_UNDERRUN:\r
2258                 case OID_802_3_XMIT_HEARTBEAT_FAILURE:\r
2259                 case OID_802_3_XMIT_TIMES_CRS_LOST:\r
2260                 case OID_802_3_XMIT_LATE_COLLISIONS:\r
2261                 case OID_PNP_CAPABILITIES:\r
2262                         status = NDIS_STATUS_NOT_SUPPORTED;\r
2263                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2264                                 ("Port %d received an unsupported oid of 0x%.8X!\n", port_num, oid) );\r
2265                         break;\r
2266         \r
2267                 case OID_GEN_PROTOCOL_OPTIONS:\r
2268                 case OID_GEN_NETWORK_LAYER_ADDRESSES:\r
2269                 case OID_GEN_TRANSPORT_HEADER_OFFSET:\r
2270                 case OID_PNP_ENABLE_WAKE_UP:\r
2271                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2272                                 ("Port %d received query for OID_GEN_PROTOCOL_OPTIONS or OID_GEN_NETWORK_LAYER_ADDRESSES or OID_GEN_TRANSPORT_HEADER_OFFSET  OID_PNP_ENABLE_WAKE_UPn", port_num) );\r
2273                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2274                                 ("Number of OID: 0x%.8X!\n", oid) );\r
2275                         status = NDIS_STATUS_SUCCESS; \r
2276                         break;\r
2277                         \r
2278                 case OID_PNP_QUERY_POWER:\r
2279                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2280                                 ("Port %d received query for OID_TCP_TASK_OFFLOAD\n", port_num) );\r
2281                         // Status is pre-set in this routine to Success\r
2282                         status = NDIS_STATUS_SUCCESS; \r
2283                         break;\r
2284         \r
2285                 case OID_TCP_OFFLOAD_CURRENT_CONFIG:\r
2286                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2287                                 ("Port %d received query for OID_PNP_QUERY_POWER\n", port_num) );\r
2288                                 //ulBytesAvailable = ulInfoLen = sizeof(NDIS_OFFLOAD);\r
2289                                 if (info_buf_len <  sizeof(NDIS_OFFLOAD))\r
2290                                 {\r
2291                                         status = NDIS_STATUS_BUFFER_TOO_SHORT;\r
2292                                         *p_bytes_needed = sizeof(NDIS_OFFLOAD) ;\r
2293                                         break;\r
2294                                 }\r
2295         \r
2296                                 //ipoib_offload_config(pPort, &offload);\r
2297                                 //pInfo = &offload;\r
2298                                 break;\r
2299         \r
2300                 default:\r
2301                         status = NDIS_STATUS_INVALID_OID;\r
2302                 //      IPOIB_PRINT( TRACE_LEVEL_ERROR,IPOIB_DBG_OID,\r
2303                         //      ("Port %d received an invalid oid of 0x%.8X!\n", port_num, oid) );\r
2304                         break;\r
2305                 }\r
2306         \r
2307                 /*\r
2308                  * Complete the request as if it was handled asynchronously to maximize\r
2309                  * code reuse for when we really handle the requests asynchronously.\r
2310                  * Note that this requires the QueryInformation entry point to always\r
2311                  * return NDIS_STATUS_PENDING\r
2312                  */\r
2313                 if( status != NDIS_STATUS_PENDING )\r
2314                 {\r
2315                         ipoib_complete_query(\r
2316                                 p_adapter, &oid_info, status, src_buf, buf_len );\r
2317                         return status;\r
2318                 }\r
2319         \r
2320                 IPOIB_EXIT( IPOIB_DBG_OID );\r
2321                 return NDIS_STATUS_PENDING;\r
2322         }\r
2323         \r
2324 \r
2325 static void\r
2326 ipoib_complete_query(\r
2327         IN                              ipoib_adapter_t* const          p_adapter,\r
2328         IN                              pending_oid_t* const            p_oid_info,\r
2329         IN              const   NDIS_STATUS                                     status,\r
2330         IN              const   void* const                                     p_buf,\r
2331         IN              const   ULONG                                           buf_len )\r
2332 {\r
2333         NDIS_STATUS             oid_status = status;\r
2334 \r
2335         IPOIB_ENTER( IPOIB_DBG_OID );\r
2336 \r
2337         CL_ASSERT( status != NDIS_STATUS_PENDING );\r
2338 \r
2339         if( status == NDIS_STATUS_SUCCESS )\r
2340         {\r
2341                 if( p_oid_info->buf_len < buf_len )\r
2342                 {\r
2343                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2344                                 ("Insufficient buffer space.  "\r
2345                                 "Returning NDIS_STATUS_INVALID_LENGTH.\n") );\r
2346                         oid_status = NDIS_STATUS_INVALID_LENGTH;\r
2347                         *p_oid_info->p_bytes_needed = buf_len;\r
2348                         *p_oid_info->p_bytes_used = 0;\r
2349                 }\r
2350                 else if( p_oid_info->p_buf )\r
2351                 {\r
2352                         /* Only copy if we have a distinct source buffer. */\r
2353                         if( p_buf )\r
2354                         {\r
2355                                 NdisMoveMemory( p_oid_info->p_buf, p_buf, buf_len );\r
2356                                 *p_oid_info->p_bytes_used = buf_len;\r
2357                         }\r
2358                 }\r
2359                 else\r
2360                 {\r
2361                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2362                                 ("Returning NDIS_NOT_ACCEPTED") );\r
2363                         oid_status = NDIS_STATUS_NOT_ACCEPTED;\r
2364                 }\r
2365         }\r
2366         else\r
2367         {\r
2368                 *p_oid_info->p_bytes_used = 0;\r
2369         }\r
2370 \r
2371         if (p_adapter->query_oid.p_pending_oid)\r
2372         {\r
2373                 NdisMOidRequestComplete(p_adapter->h_adapter,p_adapter->query_oid.p_pending_oid,oid_status); \r
2374                 p_adapter->query_oid.p_pending_oid = NULL;\r
2375         }\r
2376         p_adapter->pending_query = FALSE;\r
2377 \r
2378         IPOIB_EXIT( IPOIB_DBG_OID );\r
2379 }\r
2380 \r
2381 \r
2382 static NDIS_STATUS\r
2383 __ipoib_get_tcp_task_offload(\r
2384         IN                              ipoib_adapter_t*                        p_adapter,\r
2385         OUT                             pending_oid_t                           *pNdisRequest )\r
2386 {\r
2387 #ifndef NDIS60_MINIPORT\r
2388         NDIS_TASK_OFFLOAD_HEADER        *p_offload_hdr;\r
2389         NDIS_TASK_OFFLOAD                       *p_offload_task;\r
2390         NDIS_TASK_TCP_IP_CHECKSUM       *p_offload_chksum;\r
2391 \r
2392         NDIS_TASK_TCP_LARGE_SEND        *p_offload_lso;\r
2393         ULONG                                           buf_len;\r
2394 \r
2395         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2396                 ("Port %d received query for OID_TCP_TASK_OFFLOAD\n",\r
2397                 p_adapter->guids.port_num) );\r
2398 \r
2399         buf_len = sizeof(NDIS_TASK_OFFLOAD_HEADER) +\r
2400                 offsetof( NDIS_TASK_OFFLOAD, TaskBuffer ) +\r
2401                 sizeof(NDIS_TASK_TCP_IP_CHECKSUM) +\r
2402                 (p_adapter->params.lso  ? \r
2403                         sizeof(NDIS_TASK_OFFLOAD) + sizeof(NDIS_TASK_TCP_LARGE_SEND)\r
2404                         : 0);\r
2405 \r
2406         pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = buf_len;\r
2407 \r
2408         if( pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength < buf_len )\r
2409                 return NDIS_STATUS_INVALID_LENGTH;\r
2410 \r
2411         p_offload_hdr = (NDIS_TASK_OFFLOAD_HEADER*)pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;\r
2412         if( p_offload_hdr->Version != NDIS_TASK_OFFLOAD_VERSION )\r
2413                 return NDIS_STATUS_INVALID_DATA;\r
2414 \r
2415         if( p_offload_hdr->EncapsulationFormat.Encapsulation !=\r
2416                 IEEE_802_3_Encapsulation )\r
2417         {\r
2418                 return NDIS_STATUS_INVALID_DATA;\r
2419         }\r
2420 \r
2421         p_offload_hdr->OffsetFirstTask = sizeof(NDIS_TASK_OFFLOAD_HEADER);\r
2422         p_offload_task = (NDIS_TASK_OFFLOAD*)(p_offload_hdr + 1);\r
2423         p_offload_task->Version = NDIS_TASK_OFFLOAD_VERSION;\r
2424         p_offload_task->Size = sizeof(NDIS_TASK_OFFLOAD);\r
2425         p_offload_task->Task = TcpIpChecksumNdisTask;\r
2426         p_offload_task->OffsetNextTask = 0;\r
2427         p_offload_task->TaskBufferLength = sizeof(NDIS_TASK_TCP_IP_CHECKSUM);\r
2428         p_offload_chksum =\r
2429                 (NDIS_TASK_TCP_IP_CHECKSUM*)p_offload_task->TaskBuffer;\r
2430         \r
2431         p_offload_chksum->V4Transmit.IpOptionsSupported =\r
2432         p_offload_chksum->V4Transmit.TcpOptionsSupported =\r
2433         p_offload_chksum->V4Transmit.TcpChecksum =\r
2434         p_offload_chksum->V4Transmit.UdpChecksum =\r
2435         p_offload_chksum->V4Transmit.IpChecksum =\r
2436                 !!(p_adapter->params.send_chksum_offload);\r
2437 \r
2438         p_offload_chksum->V4Receive.IpOptionsSupported =\r
2439         p_offload_chksum->V4Receive.TcpOptionsSupported =\r
2440         p_offload_chksum->V4Receive.TcpChecksum =\r
2441         p_offload_chksum->V4Receive.UdpChecksum =\r
2442         p_offload_chksum->V4Receive.IpChecksum =\r
2443                 !!(p_adapter->params.recv_chksum_offload);\r
2444 \r
2445         p_offload_chksum->V6Transmit.IpOptionsSupported = FALSE;\r
2446         p_offload_chksum->V6Transmit.TcpOptionsSupported = FALSE;\r
2447         p_offload_chksum->V6Transmit.TcpChecksum = FALSE;\r
2448         p_offload_chksum->V6Transmit.UdpChecksum = FALSE;\r
2449 \r
2450         p_offload_chksum->V6Receive.IpOptionsSupported = FALSE;\r
2451         p_offload_chksum->V6Receive.TcpOptionsSupported = FALSE;\r
2452         p_offload_chksum->V6Receive.TcpChecksum = FALSE;\r
2453         p_offload_chksum->V6Receive.UdpChecksum = FALSE;\r
2454 \r
2455 \r
2456         if (p_adapter->params.lso) {\r
2457                 // set the previous pointer to the correct place\r
2458                 p_offload_task->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer) +\r
2459                                                 p_offload_task->TaskBufferLength;\r
2460                 // set the LSO packet\r
2461                 p_offload_task = (PNDIS_TASK_OFFLOAD)\r
2462                                                 ((PUCHAR)p_offload_task + p_offload_task->OffsetNextTask);\r
2463 \r
2464                 p_offload_task->Version = NDIS_TASK_OFFLOAD_VERSION;\r
2465                 p_offload_task->Size = sizeof(NDIS_TASK_OFFLOAD);\r
2466                 p_offload_task->Task = TcpLargeSendNdisTask;\r
2467                 p_offload_task->OffsetNextTask = 0;\r
2468                 p_offload_task->TaskBufferLength = sizeof(NDIS_TASK_TCP_LARGE_SEND);\r
2469 \r
2470                 p_offload_lso = (PNDIS_TASK_TCP_LARGE_SEND) p_offload_task->TaskBuffer;\r
2471 \r
2472                 p_offload_lso->Version = 0;\r
2473                 //TODO optimal size: 60000, 64000 or 65536\r
2474                 //TODO LSO_MIN_SEG_COUNT to be 1\r
2475                 p_offload_lso->MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE; \r
2476 #define LSO_MIN_SEG_COUNT 2\r
2477                 p_offload_lso->MinSegmentCount = LSO_MIN_SEG_COUNT;\r
2478                 p_offload_lso->TcpOptions = TRUE;\r
2479                 p_offload_lso->IpOptions = TRUE;\r
2480         }\r
2481 \r
2482                 pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten = buf_len\r
2483 \r
2484         return NDIS_STATUS_SUCCESS;\r
2485 #endif\r
2486         UNUSED_PARAM(p_adapter);\r
2487         UNUSED_PARAM(pNdisRequest);\r
2488         return NDIS_STATUS_NOT_SUPPORTED;\r
2489 \r
2490 }\r
2491 \r
2492 \r
2493 static NDIS_STATUS\r
2494 __ipoib_set_tcp_task_offload(\r
2495         IN                              ipoib_adapter_t*                        p_adapter,\r
2496         IN                              void* const                                     p_info_buf,\r
2497         IN                              ULONG* const                            p_info_len )\r
2498 {\r
2499 #ifndef NDIS60_MINIPORT\r
2500         NDIS_TASK_OFFLOAD_HEADER        *p_offload_hdr;\r
2501         NDIS_TASK_OFFLOAD                       *p_offload_task;\r
2502         NDIS_TASK_TCP_IP_CHECKSUM       *p_offload_chksum;\r
2503 \r
2504         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2505                 ("Port %d received set for OID_TCP_TASK_OFFLOAD\n",\r
2506                 p_adapter->guids.port_num) );\r
2507 \r
2508         p_offload_hdr = (NDIS_TASK_OFFLOAD_HEADER*)p_info_buf;\r
2509 \r
2510         if( *p_info_len < sizeof(NDIS_TASK_OFFLOAD_HEADER) )\r
2511                 return NDIS_STATUS_INVALID_LENGTH;\r
2512 \r
2513         if( p_offload_hdr->Version != NDIS_TASK_OFFLOAD_VERSION )\r
2514                 return NDIS_STATUS_INVALID_DATA;\r
2515 \r
2516         if( p_offload_hdr->Size != sizeof(NDIS_TASK_OFFLOAD_HEADER) )\r
2517                 return NDIS_STATUS_INVALID_LENGTH;\r
2518 \r
2519         if( !p_offload_hdr->OffsetFirstTask )\r
2520                 return NDIS_STATUS_SUCCESS;\r
2521 \r
2522         if( p_offload_hdr->EncapsulationFormat.Encapsulation !=\r
2523                 IEEE_802_3_Encapsulation )\r
2524         {\r
2525                 return NDIS_STATUS_INVALID_DATA;\r
2526         }\r
2527 \r
2528         p_offload_task = (NDIS_TASK_OFFLOAD*)\r
2529                 (((UCHAR*)p_offload_hdr) + p_offload_hdr->OffsetFirstTask);\r
2530 \r
2531         if( *p_info_len < sizeof(NDIS_TASK_OFFLOAD_HEADER) +\r
2532                 offsetof( NDIS_TASK_OFFLOAD, TaskBuffer ) +\r
2533                 sizeof(NDIS_TASK_TCP_IP_CHECKSUM) )\r
2534         {\r
2535                 return NDIS_STATUS_INVALID_LENGTH;\r
2536         }\r
2537 \r
2538         if( p_offload_task->Version != NDIS_TASK_OFFLOAD_VERSION )\r
2539                 return NDIS_STATUS_INVALID_DATA;\r
2540         p_offload_chksum =\r
2541                 (NDIS_TASK_TCP_IP_CHECKSUM*)p_offload_task->TaskBuffer;\r
2542 \r
2543         if( !p_adapter->params.send_chksum_offload &&\r
2544                 (p_offload_chksum->V4Transmit.IpOptionsSupported ||\r
2545                 p_offload_chksum->V4Transmit.TcpOptionsSupported ||\r
2546                 p_offload_chksum->V4Transmit.TcpChecksum ||\r
2547                 p_offload_chksum->V4Transmit.UdpChecksum ||\r
2548                 p_offload_chksum->V4Transmit.IpChecksum) )\r
2549         {\r
2550                 return NDIS_STATUS_NOT_SUPPORTED;\r
2551         }\r
2552 \r
2553         if( !p_adapter->params.recv_chksum_offload &&\r
2554                 (p_offload_chksum->V4Receive.IpOptionsSupported ||\r
2555                 p_offload_chksum->V4Receive.TcpOptionsSupported ||\r
2556                 p_offload_chksum->V4Receive.TcpChecksum ||\r
2557                 p_offload_chksum->V4Receive.UdpChecksum ||\r
2558                 p_offload_chksum->V4Receive.IpChecksum) )\r
2559         {\r
2560                 return NDIS_STATUS_NOT_SUPPORTED;\r
2561         }\r
2562 \r
2563         return NDIS_STATUS_SUCCESS;\r
2564 #endif \r
2565         UNUSED_PARAM(p_adapter);\r
2566         UNUSED_PARAM(p_info_buf);\r
2567         UNUSED_PARAM(p_info_len);\r
2568         return NDIS_STATUS_NOT_SUPPORTED;\r
2569 }\r
2570 \r
2571 \r
2572 //! Issues a hardware reset to the NIC and/or resets the driver's software state.\r
2573 /*  Tear down the connection and start over again.  This is only called when there is a problem.\r
2574 For example, if a send, query info, or set info had a time out.  MiniportCheckForHang will\r
2575 be called first.\r
2576 IRQL = DISPATCH_LEVEL\r
2577 \r
2578 @param p_addr_resetPointer to BOOLLEAN that is set to TRUE if the NDIS\r
2579 library should call MiniportSetInformation to restore addressing information to the current values.\r
2580 @param adapter_context The adapter context allocated at start\r
2581 @return NDIS_STATUS_SUCCESS, NDIS_STATUS_PENDING, NDIS_STATUS_NOT_RESETTABLE,\r
2582 NDIS_STATUS_RESET_IN_PROGRESS, NDIS_STATUS_SOFT_ERRORS, NDIS_STATUS_HARD_ERRORS\r
2583 */\r
2584 NDIS_STATUS\r
2585 ipoib_reset(\r
2586     IN  NDIS_HANDLE     adapter_context,\r
2587     OUT PBOOLEAN        p_addr_reset)\r
2588 {\r
2589         ipoib_adapter_t* p_adapter;\r
2590 \r
2591         IPOIB_ENTER( IPOIB_DBG_INIT );\r
2592 \r
2593         CL_ASSERT( p_addr_reset );\r
2594         CL_ASSERT( adapter_context );\r
2595         p_adapter = (ipoib_adapter_t*)adapter_context;\r
2596 \r
2597         switch( ipoib_reset_adapter( p_adapter ) )\r
2598         {\r
2599         case IB_NOT_DONE:\r
2600                 IPOIB_EXIT( IPOIB_DBG_INIT );\r
2601                 return NDIS_STATUS_PENDING;\r
2602 \r
2603         case IB_SUCCESS:\r
2604                 IPOIB_EXIT( IPOIB_DBG_INIT );\r
2605                 *p_addr_reset = TRUE;\r
2606                 return NDIS_STATUS_SUCCESS;\r
2607 \r
2608         case IB_INVALID_STATE:\r
2609                 IPOIB_EXIT( IPOIB_DBG_INIT );\r
2610                 return NDIS_STATUS_RESET_IN_PROGRESS;\r
2611 \r
2612         default:\r
2613                 IPOIB_EXIT( IPOIB_DBG_INIT );\r
2614                 return NDIS_STATUS_HARD_ERRORS;\r
2615         }\r
2616 }\r
2617 \r
2618 \r
2619 //! Request changes in the state information that the miniport driver maintains\r
2620 /*  For example, this is used to set multicast addresses and the packet filter.\r
2621 IRQL = DISPATCH_LEVEL\r
2622 \r
2623 @param adapter_context The adapter context allocated at start\r
2624 @param oid Object ID representing the set operation to be carried out\r
2625 @param info_buf Buffer containing input for this set and location for any output\r
2626 @param info_buf_len Number of bytes available in info_buf\r
2627 @param p_bytes_read Pointer to number of bytes read from info_buf\r
2628 @param p_bytes_needed Pointer to number of bytes needed to satisfy this oid\r
2629 @return NDIS_STATUS_SUCCESS, NDIS_STATUS_PENDING, NDIS_STATUS_INVALID_OID,\r
2630 NDIS_STATUS_INVALID_LENGTH, NDIS_STATUS_INVALID_DATA, NDIS_STATUS_NOT_ACCEPTED,\r
2631 NDIS_STATUS_NOT_SUPPORTED, NDIS_STATUS_RESOURCES\r
2632 */\r
2633 NDIS_STATUS\r
2634 ipoib_set_info(\r
2635         IN                              NDIS_HANDLE                                     adapter_context,\r
2636         IN                              NDIS_OID                                        oid,\r
2637         IN                              PVOID                                           info_buf,\r
2638         IN                              ULONG                                           info_buf_len,\r
2639                 OUT                     PULONG                                          p_bytes_read,\r
2640                 OUT                     PULONG                                          p_bytes_needed )\r
2641 {\r
2642         ipoib_adapter_t*        p_adapter;\r
2643         NDIS_STATUS                     status;\r
2644 \r
2645         ULONG                           buf_len;\r
2646         uint8_t                         port_num;\r
2647 \r
2648         KLOCK_QUEUE_HANDLE      hdl;\r
2649         \r
2650         IPOIB_ENTER( IPOIB_DBG_OID );\r
2651 \r
2652         CL_ASSERT( adapter_context );\r
2653         p_adapter = (ipoib_adapter_t*)adapter_context;\r
2654 \r
2655         CL_ASSERT( p_bytes_read );\r
2656         CL_ASSERT( p_bytes_needed );\r
2657         CL_ASSERT( !p_adapter->pending_set );\r
2658 \r
2659         status = NDIS_STATUS_SUCCESS;\r
2660         *p_bytes_needed = 0;\r
2661         buf_len = sizeof(ULONG);\r
2662 \r
2663         port_num = p_adapter->guids.port_num;\r
2664         \r
2665         cl_obj_lock( &p_adapter->obj );\r
2666 \r
2667         if( p_adapter->state == IB_PNP_PORT_REMOVE )\r
2668         {\r
2669                 *p_bytes_read = 0;\r
2670                 cl_obj_unlock( &p_adapter->obj );\r
2671                 return NDIS_STATUS_NOT_ACCEPTED;\r
2672         }\r
2673 \r
2674         cl_obj_unlock( &p_adapter->obj );\r
2675 \r
2676         switch( oid )\r
2677         {\r
2678         /* Required General */\r
2679         case OID_GEN_CURRENT_PACKET_FILTER:\r
2680                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2681                         ("Port %d received set for OID_GEN_CURRENT_PACKET_FILTER\n", port_num));\r
2682                 if( info_buf_len < sizeof(p_adapter->packet_filter) )\r
2683                 {\r
2684                         status = NDIS_STATUS_INVALID_LENGTH;\r
2685                 }\r
2686                 else if( !info_buf )\r
2687                 {\r
2688                         status = NDIS_STATUS_INVALID_DATA;\r
2689                 }\r
2690                 else\r
2691                 {\r
2692                         KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
2693                         cl_obj_lock( &p_adapter->obj );\r
2694                         switch( p_adapter->state )\r
2695                         {\r
2696                         case IB_PNP_PORT_ADD:\r
2697                                 p_adapter->set_oid.oid = oid;\r
2698                                 p_adapter->set_oid.p_buf = info_buf;\r
2699                                 p_adapter->set_oid.buf_len = info_buf_len;\r
2700                                 p_adapter->set_oid.p_bytes_used = p_bytes_read;\r
2701                                 p_adapter->set_oid.p_bytes_needed = p_bytes_needed;\r
2702                                 p_adapter->pending_set = TRUE;\r
2703                                 status = NDIS_STATUS_PENDING;\r
2704                                 break;\r
2705 \r
2706                         case IB_PNP_PORT_REMOVE:\r
2707                                 status = NDIS_STATUS_NOT_ACCEPTED;\r
2708                                 break;\r
2709 \r
2710                         default:\r
2711                                 if( !p_adapter->packet_filter && (*(uint32_t*)info_buf) )\r
2712                                 {\r
2713                                         cl_qlist_insert_tail(\r
2714                                                 &g_ipoib.adapter_list, &p_adapter->entry );\r
2715 \r
2716                                         /*\r
2717                                          * Filter was zero, now non-zero.  Register IP addresses\r
2718                                          * with SA.\r
2719                                          */\r
2720                                         ipoib_reg_addrs( p_adapter );\r
2721                                 }\r
2722                                 else if( p_adapter->packet_filter && !(*(uint32_t*)info_buf) )\r
2723                                 {\r
2724                                         /*\r
2725                                          * Filter was non-zero, now zero.  Deregister IP addresses.\r
2726                                          */\r
2727                                         ipoib_dereg_addrs( p_adapter );\r
2728 \r
2729                                         ASSERT( cl_qlist_count( &g_ipoib.adapter_list ) );\r
2730                                         cl_qlist_remove_item(\r
2731                                                 &g_ipoib.adapter_list, &p_adapter->entry );\r
2732                                 }\r
2733 \r
2734                                 p_adapter->packet_filter = *(uint32_t*)info_buf;\r
2735                         }\r
2736                         cl_obj_unlock( &p_adapter->obj );\r
2737                         KeReleaseInStackQueuedSpinLock( &hdl );\r
2738                 }\r
2739                 break;\r
2740 \r
2741         case OID_GEN_CURRENT_LOOKAHEAD:\r
2742                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2743                         ("Port %d received set for OID_GEN_CURRENT_LOOKAHEAD\n", port_num));\r
2744                 if( info_buf_len < buf_len )\r
2745                         status = NDIS_STATUS_INVALID_LENGTH;\r
2746                 break;\r
2747 \r
2748         case OID_GEN_PROTOCOL_OPTIONS:\r
2749                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2750                         ("Port %d received set for OID_GEN_PROTOCOL_OPTIONS\n", port_num));\r
2751                 if( info_buf_len < buf_len )\r
2752                         status = NDIS_STATUS_INVALID_LENGTH;\r
2753                 break;\r
2754 \r
2755         case OID_GEN_NETWORK_LAYER_ADDRESSES:\r
2756                 status = __ipoib_set_net_addr( p_adapter, info_buf, info_buf_len, p_bytes_read, p_bytes_needed);\r
2757                 break;\r
2758 \r
2759 #ifdef NDIS51_MINIPORT\r
2760         case OID_GEN_MACHINE_NAME:\r
2761                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID,\r
2762                         ("Port %d received set for OID_GEN_MACHINE_NAME\n", port_num) );\r
2763                 break;\r
2764 #endif\r
2765 \r
2766         /* Required Ethernet operational characteristics */\r
2767         case OID_802_3_MULTICAST_LIST:\r
2768                 IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID,\r
2769                         ("Port %d received set for OID_802_3_MULTICAST_LIST\n", port_num) );\r
2770                 if( info_buf_len > MAX_MCAST * sizeof(mac_addr_t) )\r
2771                 {\r
2772                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2773                                 ("Port %d OID_802_3_MULTICAST_LIST - Multicast list full.\n", port_num) );\r
2774                         status = NDIS_STATUS_MULTICAST_FULL;\r
2775                         *p_bytes_needed = MAX_MCAST * sizeof(mac_addr_t);\r
2776                 }\r
2777                 else if( info_buf_len % sizeof(mac_addr_t) )\r
2778                 {\r
2779                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2780                                 ("Port %d OID_802_3_MULTICAST_LIST - Invalid input buffer.\n", port_num) );\r
2781                         status = NDIS_STATUS_INVALID_DATA;\r
2782                 }\r
2783                 else if( !info_buf && info_buf_len )\r
2784                 {\r
2785                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2786                                 ("Port %d OID_802_3_MULTICAST_LIST - Invalid input buffer.\n", port_num) );\r
2787                         status = NDIS_STATUS_INVALID_DATA;\r
2788                 }\r
2789                 else\r
2790                 {\r
2791                         ipoib_refresh_mcast( p_adapter, (mac_addr_t*)info_buf,\r
2792                                 (uint8_t)(info_buf_len / sizeof(mac_addr_t)) );\r
2793 \r
2794                         buf_len = info_buf_len;\r
2795                         /*\r
2796                          * Note that we don't return pending.  It will likely take longer\r
2797                          * for our SA transactions to complete than NDIS will give us\r
2798                          * before reseting the adapter.  If an SA failure is encountered,\r
2799                          * the adapter will be marked as hung and we will get reset.\r
2800                          */\r
2801                         status = NDIS_STATUS_SUCCESS;\r
2802                 }\r
2803                 break;\r
2804 \r
2805         case OID_TCP_TASK_OFFLOAD:\r
2806                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2807                         ("Port %d received set for OID_TCP_TASK_OFFLOAD\n", port_num) );\r
2808 \r
2809                 buf_len = info_buf_len;\r
2810                 status =\r
2811                         __ipoib_set_tcp_task_offload( p_adapter, info_buf, &buf_len );\r
2812                 break;\r
2813 \r
2814         /* Optional General */\r
2815         case OID_GEN_TRANSPORT_HEADER_OFFSET:\r
2816 #ifdef NDIS51_MINIPORT\r
2817         case OID_GEN_RNDIS_CONFIG_PARAMETER:\r
2818         case OID_GEN_VLAN_ID:\r
2819 #endif\r
2820                 status = NDIS_STATUS_NOT_SUPPORTED;\r
2821                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2822                         ("Port %d received an unsupported oid of 0x%.8X!\n", port_num, oid));\r
2823                 break;\r
2824 \r
2825         case OID_GEN_SUPPORTED_LIST:\r
2826         case OID_GEN_HARDWARE_STATUS:\r
2827         case OID_GEN_MEDIA_SUPPORTED:\r
2828         case OID_GEN_MEDIA_IN_USE:\r
2829         case OID_GEN_MAXIMUM_FRAME_SIZE:\r
2830         case OID_GEN_LINK_SPEED:\r
2831         case OID_GEN_TRANSMIT_BUFFER_SPACE:\r
2832         case OID_GEN_RECEIVE_BUFFER_SPACE:\r
2833         case OID_GEN_MAXIMUM_LOOKAHEAD:\r
2834         case OID_GEN_TRANSMIT_BLOCK_SIZE:\r
2835         case OID_GEN_RECEIVE_BLOCK_SIZE:\r
2836         case OID_GEN_MAXIMUM_TOTAL_SIZE:\r
2837         case OID_GEN_VENDOR_ID:\r
2838         case OID_GEN_VENDOR_DESCRIPTION:\r
2839         case OID_GEN_VENDOR_DRIVER_VERSION:\r
2840         case OID_GEN_DRIVER_VERSION:\r
2841         case OID_GEN_MAC_OPTIONS:\r
2842         case OID_GEN_MEDIA_CONNECT_STATUS:\r
2843         case OID_GEN_MAXIMUM_SEND_PACKETS:\r
2844         case OID_GEN_SUPPORTED_GUIDS:\r
2845         case OID_GEN_PHYSICAL_MEDIUM:\r
2846         default:\r
2847                 status = NDIS_STATUS_INVALID_OID;\r
2848                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2849                         ("Port %d received an invalid oid of 0x%.8X!\n", port_num, oid));\r
2850                 break;\r
2851         }\r
2852 \r
2853         if( status == NDIS_STATUS_SUCCESS )\r
2854         {\r
2855                 *p_bytes_read = buf_len;\r
2856         }\r
2857         else\r
2858         {\r
2859                 if( status == NDIS_STATUS_INVALID_LENGTH )\r
2860                 {\r
2861                         if ( !*p_bytes_needed )\r
2862                         {\r
2863                                 *p_bytes_needed = buf_len;\r
2864                         }\r
2865                 }\r
2866 \r
2867                 *p_bytes_read = 0;\r
2868         }\r
2869 \r
2870         IPOIB_EXIT( IPOIB_DBG_OID );\r
2871         return status;\r
2872 }\r
2873 \r
2874 #ifdef NNN\r
2875 NDIS_STATUS\r
2876 ipoib_set_info(\r
2877         ipoib_adapter_t*           p_adapter,\r
2878         IN PNDIS_OID_REQUEST   pNdisRequest)\r
2879 {\r
2880         NDIS_STATUS                     status;\r
2881         NDIS_OID            oid;\r
2882         UINT                            info_buf_len;\r
2883         UINT                            buf_len;\r
2884         uint8_t                         port_num;\r
2885         PVOID                           info_buf;\r
2886         UINT                            *p_bytes_needed;\r
2887         KLOCK_QUEUE_HANDLE      hdl;\r
2888 \r
2889         IPOIB_ENTER( IPOIB_DBG_OID );\r
2890 \r
2891     oid                         = pNdisRequest->DATA.SET_INFORMATION.Oid;\r
2892     info_buf            = pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;\r
2893     info_buf_len        = pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;\r
2894         p_bytes_needed  = &pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;\r
2895         status = NDIS_STATUS_SUCCESS;\r
2896 \r
2897         buf_len = sizeof(UINT);\r
2898         port_num = p_adapter->guids.port_num;\r
2899 \r
2900         switch( oid )\r
2901         {\r
2902         /* Required General */\r
2903         case OID_GEN_CURRENT_PACKET_FILTER:\r
2904                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2905                         ("Port %d received set for OID_GEN_CURRENT_PACKET_FILTER\n", port_num));\r
2906                 if( info_buf_len < sizeof(p_adapter->packet_filter) )\r
2907                 {\r
2908                         status = NDIS_STATUS_INVALID_LENGTH;\r
2909                 }\r
2910                 else if( !info_buf )\r
2911                 {\r
2912                         status = NDIS_STATUS_INVALID_DATA;\r
2913                 }\r
2914                 else\r
2915                 {\r
2916                         KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
2917                         cl_obj_lock( &p_adapter->obj );\r
2918                         switch( p_adapter->state )\r
2919                         {\r
2920                         case IB_PNP_PORT_ADD:\r
2921                                 p_adapter->p_oid_request = pNdisRequest;\r
2922                                 status = NDIS_STATUS_PENDING;\r
2923                                 break;\r
2924 \r
2925                         case IB_PNP_PORT_REMOVE:\r
2926                                 status = NDIS_STATUS_NOT_ACCEPTED;\r
2927                                 break;\r
2928 \r
2929                         default:\r
2930                                 if( !p_adapter->packet_filter && (*(uint32_t*)info_buf) )\r
2931                                 {\r
2932                                         cl_qlist_insert_tail(\r
2933                                                 &g_ipoib.adapter_list, &p_adapter->entry );\r
2934 \r
2935                                         /*\r
2936                                          * Filter was zero, now non-zero.  Register IP addresses\r
2937                                          * with SA.\r
2938                                          */\r
2939                                         ipoib_reg_addrs( p_adapter );\r
2940                                 }\r
2941                                 else if( p_adapter->packet_filter && !(*(uint32_t*)info_buf) )\r
2942                                 {\r
2943                                         /*\r
2944                                          * Filter was non-zero, now zero.  Deregister IP addresses.\r
2945                                          */\r
2946                                         ipoib_dereg_addrs( p_adapter );\r
2947 \r
2948                                         ASSERT( cl_qlist_count( &g_ipoib.adapter_list ) );\r
2949                                         cl_qlist_remove_item(\r
2950                                                 &g_ipoib.adapter_list, &p_adapter->entry );\r
2951                                 }\r
2952 \r
2953                                 p_adapter->packet_filter = *(uint32_t*)info_buf;\r
2954                         }\r
2955                         cl_obj_unlock( &p_adapter->obj );\r
2956                         KeReleaseInStackQueuedSpinLock( &hdl );\r
2957                 }\r
2958                 break;\r
2959 \r
2960         case OID_GEN_CURRENT_LOOKAHEAD:\r
2961                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2962                         ("Port %d received set for OID_GEN_CURRENT_LOOKAHEAD\n", port_num));\r
2963                 if( info_buf_len < buf_len )\r
2964                         status = NDIS_STATUS_INVALID_LENGTH;\r
2965                 break;\r
2966 \r
2967         case OID_GEN_PROTOCOL_OPTIONS:\r
2968                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2969                         ("Port %d received set for OID_GEN_PROTOCOL_OPTIONS\n", port_num));\r
2970                 if( info_buf_len < buf_len )\r
2971                         status = NDIS_STATUS_INVALID_LENGTH;\r
2972                 break;\r
2973 \r
2974         case OID_GEN_NETWORK_LAYER_ADDRESSES:\r
2975                 status = __ipoib_set_net_addr( p_adapter, pNdisRequest);\r
2976                 break;\r
2977 \r
2978         case OID_GEN_MACHINE_NAME:\r
2979                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID,\r
2980                         ("Port %d received set for OID_GEN_MACHINE_NAME\n", port_num) );\r
2981                 break;\r
2982 \r
2983 \r
2984         /* Required Ethernet operational characteristics */\r
2985         case OID_802_3_MULTICAST_LIST:\r
2986                 IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID,\r
2987                         ("Port %d received set for OID_802_3_MULTICAST_LIST\n", port_num) );\r
2988                 if( info_buf_len > MAX_MCAST * sizeof(mac_addr_t) )\r
2989                 {\r
2990                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2991                                 ("Port %d OID_802_3_MULTICAST_LIST - Multicast list full.\n", port_num) );\r
2992                         status = NDIS_STATUS_MULTICAST_FULL;\r
2993                         *p_bytes_needed = MAX_MCAST * sizeof(mac_addr_t);\r
2994                 }\r
2995                 else if( info_buf_len % sizeof(mac_addr_t) )\r