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