[IPOIB] g_stat: added more fields: prev_port and halt thread.
[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 \r
881         NdisCloseConfiguration( h_config );\r
882 \r
883         IPOIB_EXIT( IPOIB_DBG_INIT );\r
884         return status;\r
885 }\r
886 \r
887 \r
888 NDIS_STATUS\r
889 ipoib_get_adapter_guids(\r
890         IN                              NDIS_HANDLE* const                      h_adapter,\r
891         IN      OUT                     ipoib_adapter_t                         *p_adapter )\r
892 {\r
893         NTSTATUS                        status;\r
894         ib_al_ifc_data_t        data;\r
895         IO_STACK_LOCATION       io_stack, *p_fwd_io_stack;\r
896         DEVICE_OBJECT           *p_pdo;\r
897         IRP                                     *p_irp;\r
898         KEVENT                          event;\r
899         IO_STATUS_BLOCK         io_status;\r
900 \r
901         IPOIB_ENTER( IPOIB_DBG_INIT );\r
902 \r
903         NdisMGetDeviceProperty( h_adapter, &p_pdo, NULL, NULL, NULL, NULL );\r
904 \r
905         /* Query for our interface */\r
906         data.size = sizeof(ipoib_ifc_data_t);\r
907         data.version = IPOIB_INTERFACE_DATA_VERSION;\r
908         data.type = &GUID_IPOIB_INTERFACE_DATA;\r
909         data.p_data = &p_adapter->guids;\r
910 \r
911         io_stack.MinorFunction = IRP_MN_QUERY_INTERFACE;\r
912         io_stack.Parameters.QueryInterface.Version = AL_INTERFACE_VERSION;\r
913         io_stack.Parameters.QueryInterface.Size = sizeof(ib_al_ifc_t);\r
914         io_stack.Parameters.QueryInterface.Interface =\r
915                 (INTERFACE*)p_adapter->p_ifc;\r
916         io_stack.Parameters.QueryInterface.InterfaceSpecificData = &data;\r
917         io_stack.Parameters.QueryInterface.InterfaceType = \r
918                 &GUID_IB_AL_INTERFACE;\r
919 \r
920         KeInitializeEvent( &event, NotificationEvent, FALSE );\r
921 \r
922         /* Build the IRP for the HCA. */\r
923         p_irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, p_pdo,\r
924                 NULL, 0, NULL, &event, &io_status );\r
925         if( !p_irp )\r
926         {\r
927                 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
928                         ("Failed to allocate query interface IRP.\n") );\r
929                 return STATUS_INSUFFICIENT_RESOURCES;\r
930         }\r
931 \r
932         /* Copy the request query parameters. */\r
933         p_fwd_io_stack = IoGetNextIrpStackLocation( p_irp );\r
934         p_fwd_io_stack->MinorFunction = IRP_MN_QUERY_INTERFACE;\r
935         p_fwd_io_stack->Parameters.QueryInterface =\r
936                 io_stack.Parameters.QueryInterface;\r
937         p_irp->IoStatus.Status = STATUS_NOT_SUPPORTED;\r
938 \r
939         /* Send the IRP. */\r
940         status = IoCallDriver( p_pdo, p_irp );\r
941         if( status == STATUS_PENDING )\r
942         {\r
943                 KeWaitForSingleObject( &event, Executive, KernelMode,\r
944                         FALSE, NULL );\r
945                 status = io_status.Status;\r
946         }\r
947 \r
948         if( !NT_SUCCESS( status ) )\r
949         {\r
950                 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
951                         ("Query interface for IPOIB interface returned %08x.\n", status) );\r
952                 return status;\r
953         }\r
954 \r
955         /*\r
956          * Dereference the interface now so that the bus driver doesn't fail a\r
957          * query remove IRP.  We will always get unloaded before the bus driver\r
958          * since we're a child device.\r
959          */\r
960         if (p_adapter->p_ifc)\r
961         p_adapter->p_ifc->wdm.InterfaceDereference(\r
962                 p_adapter->p_ifc->wdm.Context );\r
963         IPOIB_EXIT( IPOIB_DBG_INIT );\r
964         return NDIS_STATUS_SUCCESS;\r
965 }\r
966 \r
967 \r
968 //! Initialization function called for each IOC discovered\r
969 /*  The MiniportInitialize function is a required function that sets up a\r
970 NIC (or virtual NIC) for network I/O operations, claims all hardware\r
971 resources necessary to the NIC in the registry, and allocates resources\r
972 the driver needs to carry out network I/O operations.\r
973 IRQL = PASSIVE_LEVEL\r
974 \r
975 @param p_open_status Pointer to a status field set if this function returns NDIS_STATUS_OPEN_ERROR\r
976 @param p_selected_medium_index Pointer to unsigned integer noting index into medium_array for this NIC\r
977 @param medium_array Array of mediums for this NIC\r
978 @param medium_array_size Number of elements in medium_array\r
979 @param h_adapter Handle assigned by NDIS for this NIC\r
980 @param wrapper_config_context Handle used for Ndis initialization functions\r
981 @return NDIS_STATUS_SUCCESS, NDIS_STATUS_UNSUPPORTED_MEDIA, NDIS_STATUS_RESOURCES,\r
982 NDIS_STATUS_NOT_SUPPORTED \r
983 */\r
984 \r
985 /*void foo1(int i)\r
986 {\r
987                 char temp[5200];\r
988                 if (i ==0) return;\r
989                 cl_msg_out("i = %d\n", i);\r
990                 foo1(i-1);\r
991          \r
992 }*/\r
993         \r
994 NDIS_STATUS\r
995 SetDeviceRegistrationAttributes(\r
996         ipoib_adapter_t *p_adapter,\r
997     NDIS_HANDLE h_adapter\r
998     )\r
999 {\r
1000     NDIS_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES atr;\r
1001     NTSTATUS Status;\r
1002 \r
1003     NdisZeroMemory(&atr, sizeof(NDIS_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES));\r
1004 \r
1005     //\r
1006     // setting registration attributes\r
1007     //\r
1008     atr.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES;\r
1009     atr.Header.Revision = NDIS_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES_REVISION_1;\r
1010     atr.Header.Size = NDIS_SIZEOF_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES_REVISION_1;\r
1011 \r
1012 \r
1013     atr.MiniportAddDeviceContext = (NDIS_HANDLE)p_adapter;\r
1014     atr.Flags = 0; \r
1015 \r
1016     Status = NdisMSetMiniportAttributes(h_adapter,\r
1017                     (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&atr);\r
1018 \r
1019     return Status;\r
1020 }\r
1021 \r
1022 //NDIS 6.1\r
1023 #if 0\r
1024 NDIS_STATUS\r
1025 SetHardwareAssistAttributes(\r
1026     ipoib_adapter_t *p_adapter,\r
1027     NDIS_HANDLE h_adapter\r
1028     )\r
1029 {\r
1030     NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES atr;\r
1031     NTSTATUS Status;\r
1032 \r
1033     NdisZeroMemory(&atr, sizeof(NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES));\r
1034 \r
1035     //\r
1036     // setting registration attributes\r
1037     //\r
1038     atr.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES;\r
1039     atr.Header.Revision = NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;\r
1040     atr.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;\r
1041 \r
1042     NDIS_HD_SPLIT_ATTRIBUTES nhsa;\r
1043     NdisZeroMemory(&nhsa, sizeof(nhsa));\r
1044 \r
1045     nhsa.Header.Type = NDIS_OBJECT_TYPE_HD_SPLIT_ATTRIBUTES;\r
1046     nhsa.Header.Revision = NDIS_OFFLOAD_REVISION_1;\r
1047     nhsa.Header.Size = NDIS_SIZEOF_HD_SPLIT_ATTRIBUTES_REVISION_1;\r
1048 \r
1049     // BUGBUG: We are just cheating here ...\r
1050     nhsa.HardwareCapabilities = NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT;\r
1051 #if 0\r
1052     ... Only supported on B0\r
1053 \r
1054                                  NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV4_OPTIONS |\r
1055                                  NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV6_EXTENSION_HEADERS |\r
1056                                  NDIS_HD_SPLIT_CAPS_SUPPORTS_TCP_OPTIONS;\r
1057 #endif\r
1058 \r
1059     // The bellow should be left zero\r
1060     if (pPort->Config.HeaderDataSplit) {\r
1061         nhsa.CurrentCapabilities = NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT;\r
1062     } else {\r
1063         nhsa.CurrentCapabilities = 0;\r
1064     }\r
1065 \r
1066     nhsa.HDSplitFlags = 0;\r
1067     nhsa.BackfillSize = 0;\r
1068     nhsa.MaxHeaderSize = 0;    \r
1069 \r
1070     atr.HDSplitAttributes = &nhsa;\r
1071 \r
1072     Status = NdisMSetMiniportAttributes(h_adapter,\r
1073                     (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&atr);\r
1074 \r
1075     if (nhsa.HDSplitFlags & NDIS_HD_SPLIT_ENABLE_HEADER_DATA_SPLIT) {\r
1076         ASSERT(pPort->Config.HeaderDataSplit == TRUE);\r
1077         pPort->Config.HeaderDataSplit = TRUE;\r
1078     } \r
1079     else {\r
1080         ASSERT(pPort->Config.HeaderDataSplit == FALSE);\r
1081         pPort->Config.HeaderDataSplit = FALSE;\r
1082     }\r
1083 \r
1084     return Status;\r
1085 }\r
1086 #endif\r
1087 \r
1088 /*++\r
1089 Routine Description:\r
1090     the routine sets attributes that are associated with a miniport adapter.\r
1091 \r
1092 Arguments:\r
1093     pPort - Pointer to port object\r
1094 \r
1095 Return Value:\r
1096     NDIS_STATUS\r
1097 \r
1098 Note:\r
1099     Should be called in PASSIVE_LEVEL\r
1100     \r
1101 --*/\r
1102 NDIS_STATUS\r
1103 SetAdapterRegistrationAttributes(\r
1104         ipoib_adapter_t *p_adapter,\r
1105         NDIS_HANDLE     h_adapter\r
1106         )\r
1107         {\r
1108         NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES atr;\r
1109         NTSTATUS Status;\r
1110 \r
1111         NdisZeroMemory(&atr, sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));\r
1112 \r
1113         /* setting registration attributes */\r
1114 \r
1115         atr.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;\r
1116         atr.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;\r
1117         atr.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;\r
1118 \r
1119         atr.MiniportAdapterContext = (NDIS_HANDLE)p_adapter; \r
1120         atr.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER;\r
1121         atr.CheckForHangTimeInSeconds = 10;\r
1122         atr.InterfaceType = NdisInterfacePci ;   // ???? UH\r
1123         //TODO NDIS60 PNP or PCI ?\r
1124         //RegistrationAttributes.InterfaceType = NdisInterfacePNPBus;\r
1125 \r
1126         Status = NdisMSetMiniportAttributes(h_adapter,\r
1127                         (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&atr);\r
1128 \r
1129         return Status;\r
1130 }\r
1131 \r
1132 \r
1133 /*++\r
1134 Routine Description:\r
1135     the routine sets generic attributes that are associated with a miniport \r
1136     adapter.\r
1137 \r
1138 Arguments:\r
1139     pPort - Pointer to port object\r
1140 \r
1141 Return Value:\r
1142     NDIS_STATUS\r
1143 \r
1144 Note:\r
1145     Should be called in PASSIVE_LEVEL\r
1146     \r
1147 --*/\r
1148 NDIS_STATUS\r
1149 SetGenericAttributes(\r
1150     ipoib_adapter_t *p_adapter,\r
1151     NDIS_HANDLE h_adapter\r
1152     )\r
1153 {\r
1154     NDIS_STATUS Status;\r
1155 \r
1156     NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES gat;\r
1157     NdisZeroMemory(&gat, sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));\r
1158 \r
1159         /* set up generic attributes */\r
1160 \r
1161         gat.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;\r
1162         gat.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;\r
1163         gat.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);\r
1164 \r
1165         gat.MediaType = NdisMedium802_3;    \r
1166         gat.MaxXmitLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
1167         gat.MaxRcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
1168         gat.XmitLinkSpeed = IPOIB_MEDIA_MAX_SPEED; //TODO NDIS60 NDIS_LINK_SPEED_UNKNOWN\r
1169         gat.RcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED; // TODO NDIS60 NDIS_LINK_SPEED_UNKNOWN ???\r
1170 \r
1171         gat.MediaConnectState = MediaConnectStateConnected; //TODO NDIS60 Check the current state\r
1172         gat.MediaDuplexState = MediaDuplexStateFull;\r
1173 \r
1174         gat.MtuSize = DEFAULT_PAYLOAD_MTU;\r
1175         gat.LookaheadSize = MAX_XFER_BLOCK_SIZE;\r
1176         gat.MacOptions = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \r
1177                                          NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |\r
1178                                          NDIS_MAC_OPTION_NO_LOOPBACK |\r
1179                                          NDIS_MAC_OPTION_FULL_DUPLEX;\r
1180                                         //NDIS_MAC_OPTION_8021P_PRIORITY; //TODO NDIS60\r
1181                                         // DT: Enable for Header Data Split WHQL\r
1182                                         // |  NDIS_MAC_OPTION_8021Q_VLAN;\r
1183 \r
1184         gat.SupportedPacketFilters =    NDIS_PACKET_TYPE_DIRECTED |\r
1185                                                                         NDIS_PACKET_TYPE_MULTICAST |\r
1186                                                                         //NDIS_PACKET_TYPE_ALL_MULTICAST |\r
1187                                                                         NDIS_PACKET_TYPE_BROADCAST;\r
1188                                          \r
1189         gat.MaxMulticastListSize = MAX_MCAST;\r
1190 \r
1191         gat.MacAddressLength = HW_ADDR_LEN;\r
1192         \r
1193         NdisMoveMemory(gat.PermanentMacAddress,\r
1194                                         p_adapter->mac.addr,\r
1195                                         HW_ADDR_LEN);\r
1196 \r
1197         NdisMoveMemory(gat.CurrentMacAddress,\r
1198                                         p_adapter->params.conf_mac.addr,\r
1199                                         HW_ADDR_LEN);\r
1200 \r
1201 \r
1202         gat.PhysicalMediumType = NdisPhysicalMedium802_3;\r
1203         gat.AccessType = NET_IF_ACCESS_BROADCAST; \r
1204 \r
1205         gat.SupportedOidList = (PNDIS_OID)SUPPORTED_OIDS;\r
1206         gat.SupportedOidListLength = sizeof(SUPPORTED_OIDS);\r
1207 \r
1208 \r
1209         gat.DirectionType = NET_IF_DIRECTION_SENDRECEIVE; \r
1210         gat.ConnectionType = NET_IF_CONNECTION_DEDICATED; \r
1211         gat.IfType = IF_TYPE_ETHERNET_CSMACD; \r
1212         gat.IfConnectorPresent = TRUE; \r
1213         gat.AccessType = NET_IF_ACCESS_BROADCAST; // NET_IF_ACCESS_BROADCAST for a typical ethernet adapter\r
1214 \r
1215 \r
1216         //TODO NDIS60 is it possible to reduce unsupported statistics\r
1217         gat.SupportedStatistics = \r
1218                                 NDIS_STATISTICS_XMIT_OK_SUPPORTED |\r
1219                                 NDIS_STATISTICS_RCV_OK_SUPPORTED |\r
1220                                 NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |\r
1221                                 NDIS_STATISTICS_RCV_ERROR_SUPPORTED |\r
1222                                 NDIS_STATISTICS_RCV_CRC_ERROR_SUPPORTED |\r
1223                                 NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED |\r
1224                                 NDIS_STATISTICS_TRANSMIT_QUEUE_LENGTH_SUPPORTED;\r
1225 \r
1226         //SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED |\r
1227                                                         // NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;\r
1228 \r
1229 \r
1230     //\r
1231     // Set power management capabilities\r
1232     //\r
1233     gat.PowerManagementCapabilities = NULL;\r
1234 #if 0\r
1235     NDIS_PNP_CAPABILITIES PowerManagementCapabilities;\r
1236     NdisZeroMemory(&PowerManagementCapabilities, sizeof(NDIS_PNP_CAPABILITIES));\r
1237     if (MPIsPoMgmtSupported(pPort))\r
1238     {\r
1239         MPFillPoMgmtCaps(pPort, &PowerManagementCapabilities, &Status, &unUsed);\r
1240         ASSERT(NT_SUCCESS(Status)); \r
1241         gat.PowerManagementCapabilities = &PowerManagementCapabilities;\r
1242     } \r
1243     else\r
1244     {\r
1245         \r
1246     }\r
1247 #endif\r
1248 \r
1249     //\r
1250     // Set RSS attributes\r
1251     //\r
1252     gat.RecvScaleCapabilities = NULL;\r
1253 #if 0\r
1254     NDIS_RECEIVE_SCALE_CAPABILITIES RssCapabilities;\r
1255     NdisZeroMemory(&RssCapabilities, sizeof(PNDIS_RECEIVE_SCALE_CAPABILITIES));\r
1256     Status = MPFillRssCapabilities(pPort, &RssCapabilities, &unUsed);\r
1257     if (NT_SUCCESS(Status)) \r
1258     {\r
1259         gat.RecvScaleCapabilities = &RssCapabilities;\r
1260     } \r
1261     else\r
1262     {\r
1263         //\r
1264         // do not fail the call because of failure to get PM caps\r
1265         //\r
1266         Status = NDIS_STATUS_SUCCESS;\r
1267         gat.RecvScaleCapabilities = NULL;\r
1268     }\r
1269 #endif\r
1270 \r
1271         Status = NdisMSetMiniportAttributes(h_adapter,\r
1272                         (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&gat);\r
1273 \r
1274         return Status;\r
1275 }\r
1276 \r
1277 \r
1278 /*++\r
1279 Routine Description:\r
1280     The routine sets an NDIS_OFFLOAD structure indicates the current offload \r
1281     capabilities that are provided by the miniport adapter \r
1282     \r
1283 Arguments:\r
1284     pPort - a pointer to port object\r
1285     offload - reference to NDIS_OFFLOAD object that should be filled\r
1286 \r
1287 Return Value:\r
1288     None.\r
1289     \r
1290 --*/\r
1291 static\r
1292 void\r
1293 OffloadConfig(\r
1294         ipoib_adapter_t *p_adapter,\r
1295         NDIS_OFFLOAD *p_offload\r
1296         )\r
1297\r
1298 \r
1299         ULONG ulEncapsulation = NDIS_ENCAPSULATION_IEEE_802_3 | NDIS_ENCAPSULATION_IEEE_802_3_P_AND_Q;\r
1300 \r
1301         NdisZeroMemory(p_offload, NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1);\r
1302 \r
1303         p_offload->Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;\r
1304         p_offload->Header.Revision = NDIS_OFFLOAD_REVISION_1; // TODO: NDIS6.0. do we need to support revision 2? UH 17-May-2008\r
1305         p_offload->Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;\r
1306 \r
1307         p_offload->Checksum.IPv4Transmit.Encapsulation = ulEncapsulation;\r
1308         p_offload->Checksum.IPv4Transmit.IpOptionsSupported = \r
1309         p_offload->Checksum.IPv4Transmit.TcpOptionsSupported = \r
1310         p_offload->Checksum.IPv4Transmit.TcpChecksum = \r
1311         p_offload->Checksum.IPv4Transmit.UdpChecksum = \r
1312         p_offload->Checksum.IPv4Transmit.IpChecksum =!!(p_adapter->params.send_chksum_offload);\r
1313 \r
1314         p_offload->Checksum.IPv4Receive.Encapsulation = ulEncapsulation;\r
1315         p_offload->Checksum.IPv4Receive.IpOptionsSupported = \r
1316         p_offload->Checksum.IPv4Receive.TcpOptionsSupported = \r
1317         p_offload->Checksum.IPv4Receive.TcpChecksum = \r
1318         p_offload->Checksum.IPv4Receive.UdpChecksum = \r
1319         p_offload->Checksum.IPv4Receive.IpChecksum = !!(p_adapter->params.recv_chksum_offload); \r
1320 \r
1321 \r
1322         p_offload->Checksum.IPv6Transmit.Encapsulation = ulEncapsulation;\r
1323         p_offload->Checksum.IPv6Transmit.IpExtensionHeadersSupported = \r
1324         p_offload->Checksum.IPv6Transmit.TcpOptionsSupported =\r
1325         p_offload->Checksum.IPv6Transmit.TcpChecksum = \r
1326         p_offload->Checksum.IPv6Transmit.UdpChecksum = FALSE;\r
1327 \r
1328 \r
1329         p_offload->Checksum.IPv6Receive.Encapsulation = ulEncapsulation;\r
1330         p_offload->Checksum.IPv6Receive.IpExtensionHeadersSupported = \r
1331         p_offload->Checksum.IPv6Receive.TcpOptionsSupported = \r
1332         p_offload->Checksum.IPv6Receive.TcpChecksum = \r
1333         p_offload->Checksum.IPv6Receive.UdpChecksum = FALSE;\r
1334 \r
1335         if (p_adapter->params.lso)\r
1336         {\r
1337                 p_offload->LsoV1.IPv4.Encapsulation = ulEncapsulation;\r
1338                 p_offload->LsoV1.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
1339 #define LSO_MIN_SEG_COUNT 2\r
1340                 p_offload->LsoV1.IPv4.MinSegmentCount = LSO_MIN_SEG_COUNT;\r
1341         \r
1342                 \r
1343                 p_offload->LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_SUPPORTED;\r
1344                 p_offload->LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_SUPPORTED;\r
1345 \r
1346                 p_offload->LsoV2.IPv4.Encapsulation = ulEncapsulation;\r
1347                 p_offload->LsoV2.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
1348                 p_offload->LsoV2.IPv4.MinSegmentCount = LSO_MIN_SEG_COUNT;\r
1349 #if 0\r
1350                 p_offload->LsoV2.IPv6.Encapsulation = ulEncapsulation;\r
1351                 p_offload->LsoV2.IPv6.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
1352                 p_offload->LsoV2.IPv6.MinSegmentCount = LSO_MIN_SEG_COUNT;\r
1353 #endif \r
1354 \r
1355         } else {\r
1356                 p_offload->LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED;\r
1357                 p_offload->LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED;\r
1358         }\r
1359         \r
1360         p_offload->LsoV2.IPv6.IpExtensionHeadersSupported = NDIS_OFFLOAD_NOT_SUPPORTED;\r
1361         p_offload->LsoV2.IPv6.TcpOptionsSupported = NDIS_OFFLOAD_NOT_SUPPORTED;\r
1362 \r
1363 }\r
1364 \r
1365 \r
1366 /*++\r
1367 Routine Description:\r
1368     The routine sets an NDIS_OFFLOAD structure that indicates all the task \r
1369     offload capabilites that are supported by the NIC. These capabilities include\r
1370     capabilities that are currently disabled by standardized keywords in the registry. \r
1371     \r
1372 Arguments:\r
1373     offload - reference to NDIS_OFFLOAD object that should be filled\r
1374 \r
1375 Return Value:\r
1376     None.\r
1377     \r
1378 --*/\r
1379 static\r
1380 void\r
1381 OffloadCapabilities(\r
1382         ipoib_adapter_t *p_adapter,\r
1383         NDIS_OFFLOAD    *p_offload\r
1384         )\r
1385\r
1386         ULONG ulEncapsulation = NDIS_ENCAPSULATION_IEEE_802_3 | NDIS_ENCAPSULATION_IEEE_802_3_P_AND_Q ;\r
1387         NdisZeroMemory(p_offload, NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1);    \r
1388 \r
1389         p_offload->Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;\r
1390         p_offload->Header.Revision = NDIS_OFFLOAD_REVISION_1; // BUGBUG: do we need to support revision 2? UH 17-May-2008\r
1391         p_offload->Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;\r
1392 \r
1393         p_offload->Checksum.IPv4Transmit.Encapsulation = ulEncapsulation;\r
1394         p_offload->Checksum.IPv4Transmit.IpOptionsSupported = \r
1395         p_offload->Checksum.IPv4Transmit.TcpOptionsSupported = \r
1396         p_offload->Checksum.IPv4Transmit.TcpChecksum = \r
1397         p_offload->Checksum.IPv4Transmit.UdpChecksum = \r
1398         p_offload->Checksum.IPv4Transmit.IpChecksum = p_adapter->offload_cap.send_chksum_offload;\r
1399 \r
1400         p_offload->Checksum.IPv4Receive.Encapsulation = ulEncapsulation;\r
1401         p_offload->Checksum.IPv4Receive.IpOptionsSupported = \r
1402         p_offload->Checksum.IPv4Receive.TcpOptionsSupported = \r
1403         p_offload->Checksum.IPv4Receive.TcpChecksum = \r
1404         p_offload->Checksum.IPv4Receive.UdpChecksum = \r
1405         p_offload->Checksum.IPv4Receive.IpChecksum = p_adapter->offload_cap.recv_chksum_offload;\r
1406 \r
1407 \r
1408         //\r
1409         //  BUGBUG::\r
1410         //  During a HW bug that didn't handle correctly packets with \r
1411         //  IPv6 Extension Headers -> we set IpExtensionHeadersSupported to TRUE\r
1412         //\r
1413         p_offload->Checksum.IPv6Transmit.Encapsulation = ulEncapsulation;\r
1414         p_offload->Checksum.IPv6Transmit.IpExtensionHeadersSupported = \r
1415         p_offload->Checksum.IPv6Transmit.TcpOptionsSupported = \r
1416         p_offload->Checksum.IPv6Transmit.TcpChecksum = \r
1417         p_offload->Checksum.IPv6Transmit.UdpChecksum = FALSE;\r
1418 \r
1419 \r
1420         p_offload->Checksum.IPv6Receive.Encapsulation = ulEncapsulation;\r
1421         p_offload->Checksum.IPv6Receive.IpExtensionHeadersSupported = \r
1422         p_offload->Checksum.IPv6Receive.TcpOptionsSupported = \r
1423         p_offload->Checksum.IPv6Receive.TcpChecksum = \r
1424         p_offload->Checksum.IPv6Receive.UdpChecksum = FALSE;\r
1425 \r
1426         if (p_adapter->offload_cap.lso) {\r
1427 \r
1428                 p_offload->LsoV1.IPv4.Encapsulation = ulEncapsulation;\r
1429                 p_offload->LsoV1.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
1430                 p_offload->LsoV1.IPv4.MinSegmentCount = 2;\r
1431                 p_offload->LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_SUPPORTED;\r
1432                 p_offload->LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_SUPPORTED;\r
1433 \r
1434                 p_offload->LsoV2.IPv4.Encapsulation = ulEncapsulation;\r
1435                 p_offload->LsoV2.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
1436                 p_offload->LsoV2.IPv4.MinSegmentCount = 2;\r
1437 \r
1438         } else {\r
1439                 p_offload->LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED;\r
1440                 p_offload->LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED;\r
1441                 \r
1442         }\r
1443 \r
1444         /*p_offload->LsoV2.IPv6.Encapsulation = ulEncapsulation;\r
1445         p_offload->LsoV2.IPv6.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
1446         p_offload->LsoV2.IPv6.MinSegmentCount = 2;*/\r
1447 \r
1448         p_offload->LsoV2.IPv6.IpExtensionHeadersSupported = NDIS_OFFLOAD_NOT_SUPPORTED;\r
1449         p_offload->LsoV2.IPv6.TcpOptionsSupported = NDIS_OFFLOAD_NOT_SUPPORTED;\r
1450 \r
1451 }\r
1452 \r
1453 \r
1454 /*++\r
1455 Routine Description:\r
1456     The routine sets offload attributes that are associated with a miniport \r
1457     adapter.\r
1458 \r
1459 Arguments:\r
1460     pPort - Pointer to port object\r
1461 \r
1462 Return Value:\r
1463     NDIS_STATUS\r
1464 \r
1465 Note:\r
1466     Should be called in PASSIVE_LEVEL\r
1467     \r
1468 --*/\r
1469 NDIS_STATUS\r
1470 SetOffloadAttributes(\r
1471         ipoib_adapter_t *p_adapter,\r
1472         NDIS_HANDLE     h_adapter\r
1473         )\r
1474 {\r
1475         NDIS_STATUS Status;\r
1476         NDIS_OFFLOAD offload,hwOffload;\r
1477         //ULONG ulEncapsulation = NDIS_ENCAPSULATION_IEEE_802_3 | NDIS_ENCAPSULATION_IEEE_802_3_P_AND_Q;\r
1478 \r
1479         NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES oat;    \r
1480         NdisZeroMemory(&oat, sizeof(NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES));\r
1481 \r
1482         oat.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;\r
1483         oat.Header.Revision = NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;\r
1484         oat.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;\r
1485 \r
1486 \r
1487         OffloadConfig(p_adapter, &offload);\r
1488 \r
1489 \r
1490         OffloadCapabilities(p_adapter, &hwOffload);\r
1491 \r
1492         oat.DefaultOffloadConfiguration = &offload;\r
1493         oat.HardwareOffloadCapabilities = &hwOffload;\r
1494 \r
1495         Status = NdisMSetMiniportAttributes(h_adapter,\r
1496                                 (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&oat);\r
1497 \r
1498         return Status;\r
1499 }\r
1500 \r
1501 \r
1502 /*++\r
1503 \r
1504 Routine Description:\r
1505     An NDIS 6.0 miniport driver must call NdisMSetMiniportAttributes\r
1506     at least twice. The first call is to register itself with NDIS.\r
1507     The second call is to register the miniport driver's general\r
1508     attributes with NDIS.\r
1509 \r
1510     NdisMSetMiniportAttributes takes a parameter of type\r
1511     NDIS_MINIPORT_ADAPTER_ATTRIBUTES, which is a union of several miniport\r
1512     adapter attributes. Miniport drivers must first call\r
1513     NdisMSetMiniportAttributes and pass in an\r
1514     NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES structure\r
1515     that contains the pointer to its own context area, attribute flags,\r
1516     check-for-hang time, and interface type.\r
1517 \r
1518     All NDIS 6.0 miniport drivers are deserialized by default.\r
1519 \r
1520 Arguments:\r
1521     pPort - Pointer to port object\r
1522 \r
1523 Return Value:\r
1524     NDIS_STATUS\r
1525 \r
1526 Note:\r
1527     Should be called in PASSIVE_LEVEL\r
1528     \r
1529 --*/\r
1530 NDIS_STATUS\r
1531 SetAttributes(\r
1532         ipoib_adapter_t *p_adapter,\r
1533         NDIS_HANDLE     h_adapter\r
1534         )\r
1535         {\r
1536         NTSTATUS Status;\r
1537 \r
1538 \r
1539         Status = SetDeviceRegistrationAttributes(p_adapter, h_adapter);\r
1540         if (Status != NDIS_STATUS_SUCCESS)\r
1541         {\r
1542                 //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set device registration failed Error=0x%x\n", Status);\r
1543                 return Status;\r
1544         }\r
1545 \r
1546 \r
1547         Status = SetAdapterRegistrationAttributes(p_adapter, h_adapter);\r
1548         if (Status != NDIS_STATUS_SUCCESS)\r
1549         {\r
1550                 //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set adapter attributes failed Error=0x%x\n", Status);\r
1551                 return Status;\r
1552         }\r
1553 \r
1554         \r
1555         \r
1556 #if 0\r
1557         if(!pPort->Config.fWHQL)\r
1558         {\r
1559                 Status = SetHardwareAssistAttributes(pPort);\r
1560                 if (Status != NDIS_STATUS_SUCCESS)\r
1561                 {\r
1562                     //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set Hardware Assist Attributes failed Error=0x%x\n", Status);\r
1563                     return Status;\r
1564                 }\r
1565         }\r
1566 #endif\r
1567 \r
1568         Status = SetGenericAttributes(p_adapter, h_adapter);\r
1569         if (Status != NDIS_STATUS_SUCCESS)\r
1570         {\r
1571             //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set generic attributes failed Error=0x%x\n", Status);\r
1572             return Status;\r
1573         }\r
1574 \r
1575         return Status;\r
1576 }\r
1577 \r
1578 BOOLEAN\r
1579 IsValidOffloadConfig(ipoib_adapter_t *p_adapter, PNDIS_OFFLOAD_PARAMETERS pOffloadParam)\r
1580 {\r
1581     BOOLEAN bRet = TRUE;\r
1582 \r
1583     UCHAR CheckSumConfig[5]={0};\r
1584     CheckSumConfig[0] = pOffloadParam->IPv4Checksum;\r
1585     CheckSumConfig[1] = pOffloadParam->TCPIPv4Checksum;\r
1586     CheckSumConfig[2] = pOffloadParam->UDPIPv4Checksum;\r
1587     CheckSumConfig[3] = pOffloadParam->TCPIPv6Checksum;\r
1588     CheckSumConfig[4] = pOffloadParam->UDPIPv6Checksum;\r
1589 \r
1590     for(int i=0 ; i<5 ; i++)\r
1591     {\r
1592         if(CheckSumConfig[i] != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
1593         {\r
1594                 switch (CheckSumConfig[i]) {\r
1595                                 //return FALSE in any case when NDIS tries to set unsupported value\r
1596                                 case NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED:\r
1597                                         bRet = (BOOLEAN) p_adapter->offload_cap.send_chksum_offload;\r
1598                                         break;\r
1599                                 case NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED:\r
1600                                         bRet = (BOOLEAN) p_adapter->offload_cap.recv_chksum_offload;\r
1601                                         break;\r
1602                                 case NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED:\r
1603                                         bRet = (BOOLEAN) (p_adapter->offload_cap.send_chksum_offload && \r
1604                                                          p_adapter->offload_cap.recv_chksum_offload);\r
1605                                         break;\r
1606                                 default:\r
1607                                         ASSERT (FALSE);\r
1608                 }\r
1609                 \r
1610                         if (!bRet) \r
1611                                 return FALSE;\r
1612                                         \r
1613                                         \r
1614             for(int j=0 ; j<5 ; j++)\r
1615             {\r
1616                 if( (CheckSumConfig[j] != 0) && (CheckSumConfig[j] != CheckSumConfig[i])  )\r
1617                 {\r
1618                    bRet = FALSE;\r
1619                    goto Exit;\r
1620                 }\r
1621             }            \r
1622         }\r
1623     }\r
1624 \r
1625 \r
1626     UCHAR OffloadConfig[3]={0};\r
1627     OffloadConfig[0] = pOffloadParam->LsoV1;\r
1628     OffloadConfig[1] = pOffloadParam->LsoV2IPv4;\r
1629     OffloadConfig[2] = pOffloadParam->LsoV2IPv6;\r
1630 \r
1631         if (!p_adapter->offload_cap.lso) {\r
1632                 if ((pOffloadParam->LsoV1 == NDIS_OFFLOAD_PARAMETERS_LSOV1_ENABLED) ||\r
1633                         (pOffloadParam->LsoV2IPv4 == NDIS_OFFLOAD_PARAMETERS_LSOV1_ENABLED))\r
1634                 {\r
1635                         return FALSE;\r
1636                 }\r
1637         }\r
1638         \r
1639         pOffloadParam->LsoV1;\r
1640     OffloadConfig[1] = pOffloadParam->LsoV2IPv4;\r
1641 \r
1642     for(int i=0 ; i<3 ; i++)\r
1643     {\r
1644         if(OffloadConfig[i] != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
1645         {\r
1646             for(int j=0 ; j<3 ; j++)\r
1647             {\r
1648                 if( (OffloadConfig[j] != 0) && (OffloadConfig[j] != OffloadConfig[i])  )\r
1649                 {\r
1650                    bRet = FALSE;\r
1651                    goto Exit;\r
1652                 }\r
1653             }            \r
1654         }        \r
1655     }\r
1656    \r
1657 Exit:\r
1658     return bRet;        \r
1659 }\r
1660 \r
1661 static\r
1662 NDIS_STATUS \r
1663 SetOffloadParameters(\r
1664     ipoib_adapter_t * p_adapter,\r
1665     void* const pBuf,\r
1666     ULONG len \r
1667     )\r
1668 {\r
1669     IPOIB_ENTER(IPOIB_DBG_OID);\r
1670 \r
1671     ASSERT(pBuf != NULL); \r
1672     \r
1673     PNDIS_OFFLOAD_PARAMETERS pOffloadParam = NULL;\r
1674     PNDIS_OBJECT_HEADER pOffloadHeader = NULL;\r
1675     NDIS_STATUS Status = NDIS_STATUS_SUCCESS;\r
1676     bool StatusIndicationFlag = FALSE;\r
1677  \r
1678     if (len != NDIS_SIZEOF_OFFLOAD_PARAMETERS_REVISION_1)\r
1679     {\r
1680         ASSERT(FALSE);\r
1681         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_1, len));\r
1682         Status =  NDIS_STATUS_INVALID_LENGTH;\r
1683         goto Exit;\r
1684     }\r
1685 \r
1686     IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_OID, ("received set for OID_TCP_TASK_OFFLOAD\n"));\r
1687 \r
1688     pOffloadParam = (PNDIS_OFFLOAD_PARAMETERS) pBuf;\r
1689     pOffloadHeader = &(pOffloadParam->Header);\r
1690     \r
1691     if((pOffloadHeader->Type != NDIS_OBJECT_TYPE_DEFAULT) ||\r
1692        (pOffloadHeader->Revision != NDIS_OFFLOAD_PARAMETERS_REVISION_1) ||\r
1693        (pOffloadHeader->Size != NDIS_SIZEOF_OFFLOAD_PARAMETERS_REVISION_1))\r
1694     {       \r
1695         ASSERT(FALSE);\r
1696         IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_OID, ("Set offloading task Illegal header\n"));\r
1697         Status = NDIS_STATUS_INVALID_DATA;\r
1698         goto Exit;\r
1699     }\r
1700 \r
1701     if ((pOffloadParam->IPsecV1 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) ||\r
1702         (pOffloadParam->TcpConnectionIPv4 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) ||\r
1703         (pOffloadParam->TcpConnectionIPv6 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) ||\r
1704         (pOffloadParam->Flags != 0))\r
1705     {\r
1706         Status = NDIS_STATUS_NOT_SUPPORTED;\r
1707         goto Exit;\r
1708     }\r
1709 \r
1710         //Eliminate currently unsupported statistic\r
1711         if ((pOffloadParam->TCPIPv6Checksum != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) ||\r
1712                 (pOffloadParam->UDPIPv6Checksum != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) ||\r
1713                 (pOffloadParam->LsoV2IPv6               != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE))\r
1714         {\r
1715                 Status = NDIS_STATUS_NOT_SUPPORTED;\r
1716         goto Exit;\r
1717         }\r
1718                 \r
1719 \r
1720     BOOLEAN bRet = IsValidOffloadConfig(p_adapter, pOffloadParam);\r
1721     if(bRet == FALSE)\r
1722     {\r
1723         //ASSERT(FALSE);\r
1724         Status = NDIS_STATUS_NOT_SUPPORTED;\r
1725         goto Exit;        \r
1726     }\r
1727 \r
1728         // Set current offload configuration capabilites\r
1729         if ((pOffloadParam->IPv4Checksum ==     NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED) ||\r
1730                 (pOffloadParam->TCPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED) ||\r
1731                 (pOffloadParam->UDPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED))\r
1732         {\r
1733                 p_adapter->params.send_chksum_offload = CSUM_ENABLED;\r
1734                 p_adapter->params.recv_chksum_offload = CSUM_DISABLED;\r
1735                 StatusIndicationFlag = TRUE;\r
1736         }\r
1737 \r
1738         else if ((pOffloadParam->IPv4Checksum ==        NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED) ||\r
1739                 (pOffloadParam->TCPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED) ||\r
1740                 (pOffloadParam->UDPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED))\r
1741         {\r
1742                 p_adapter->params.recv_chksum_offload = CSUM_ENABLED;\r
1743                 p_adapter->params.send_chksum_offload = CSUM_DISABLED;\r
1744                 StatusIndicationFlag = TRUE;\r
1745         }\r
1746 \r
1747         else if ((pOffloadParam->IPv4Checksum ==        NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED ) ||\r
1748                 (pOffloadParam->TCPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED ) ||\r
1749                 (pOffloadParam->UDPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED ))\r
1750         {\r
1751                 p_adapter->params.send_chksum_offload = CSUM_ENABLED;\r
1752                 p_adapter->params.recv_chksum_offload = CSUM_ENABLED;\r
1753                 StatusIndicationFlag = TRUE;\r
1754         }\r
1755         else if ((pOffloadParam->IPv4Checksum ==        NDIS_OFFLOAD_PARAMETERS_TX_RX_DISABLED ) ||\r
1756                         (pOffloadParam->TCPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_TX_RX_DISABLED ) ||\r
1757                         (pOffloadParam->UDPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_TX_RX_DISABLED ))\r
1758         {\r
1759                 p_adapter->params.send_chksum_offload = CSUM_DISABLED;\r
1760                 p_adapter->params.recv_chksum_offload = CSUM_DISABLED;\r
1761                 StatusIndicationFlag = TRUE;\r
1762         }\r
1763         \r
1764                 \r
1765 \r
1766  #if 0  \r
1767     if(pOffloadParam->TCPIPv6Checksum != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
1768     {\r
1769         UpdateOffloadSeeting(pOffloadParam->TCPIPv6Checksum, pPort->Config.TCPUDPIPv4Chksum);        \r
1770         StatusIndicationFlag = TRUE;\r
1771     }\r
1772     \r
1773     if(pOffloadParam->UDPIPv6Checksum != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
1774     {\r
1775         UpdateOffloadSeeting(pOffloadParam->UDPIPv6Checksum, pPort->Config.TCPUDPIPv4Chksum);        \r
1776         StatusIndicationFlag = TRUE;\r
1777     }\r
1778 #endif\r
1779 \r
1780    // SetCheksumOffloadingModes(pPort->Config);\r
1781     \r
1782     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//\r
1783     \r
1784     //////////////////////////// OFFLOAD OFFLOAD ////////////////////////////\r
1785     if(pOffloadParam->LsoV1 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
1786     {\r
1787         p_adapter->params.lso = (pOffloadParam->LsoV1 == NDIS_OFFLOAD_PARAMETERS_LSOV1_ENABLED);   \r
1788         StatusIndicationFlag = TRUE;\r
1789     }\r
1790     \r
1791     if(pOffloadParam->LsoV2IPv4 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
1792     {        \r
1793         p_adapter->params.lso = (pOffloadParam->LsoV1 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED);\r
1794         StatusIndicationFlag = TRUE;\r
1795     }\r
1796 #if 0    \r
1797     if(pOffloadParam->LsoV2IPv6 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
1798     {        \r
1799         if(pOffloadParam->LsoV2IPv6 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED)\r
1800         {\r
1801             pPort->Config.LsoV2IPv6 = TRUE;            \r
1802         }\r
1803         else\r
1804         {\r
1805             pPort->Config.LsoV2IPv6 = FALSE;            \r
1806         }\r
1807         \r
1808         StatusIndicationFlag = TRUE;\r
1809     }\r
1810 #endif\r
1811 \r
1812    \r
1813     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//    \r
1814 \r
1815 \r
1816     if(StatusIndicationFlag)\r
1817     {        \r
1818         NDIS_OFFLOAD CurrentOffloadCapapilities;\r
1819         NDIS_STATUS_INDICATION StatusIndication;                \r
1820 \r
1821         OffloadConfig(p_adapter, &CurrentOffloadCapapilities);\r
1822 \r
1823                  \r
1824         IPOIB_INIT_NDIS_STATUS_INDICATION(&StatusIndication,\r
1825                                        p_adapter->h_adapter,\r
1826                                        NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG ,\r
1827                                        (PVOID)&CurrentOffloadCapapilities,\r
1828                                        sizeof(CurrentOffloadCapapilities));\r
1829                                        \r
1830         NdisMIndicateStatusEx(p_adapter->h_adapter, &StatusIndication);        \r
1831     }\r
1832                 \r
1833 Exit:   \r
1834     IPOIB_EXIT(IPOIB_DBG_OID);\r
1835     return Status;   \r
1836 }\r
1837 \r
1838 /*++\r
1839 \r
1840 Routine Description:\r
1841     The routine handles setting of OID_GEN_INTERRUPT_MODERATION.\r
1842 \r
1843 Arguments:\r
1844     InformationBuffer - Pointer to the buffer that contains the data\r
1845     InformationBufferLength - data length\r
1846     \r
1847 Return Value:\r
1848     NDIS_STAUS\r
1849     \r
1850 --*/\r
1851 static \r
1852 NDIS_STATUS\r
1853 SetInterruptModeration(\r
1854     PVOID InformationBuffer,\r
1855     ULONG InformationBufferLength\r
1856 )\r
1857 {\r
1858     IPOIB_ENTER(IPOIB_DBG_OID);\r
1859     \r
1860     NDIS_STATUS Status = NDIS_STATUS_SUCCESS;\r
1861     \r
1862     if (InformationBufferLength != sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS))\r
1863     {\r
1864         Status = NDIS_STATUS_INVALID_LENGTH;\r
1865         goto Exit;\r
1866     }\r
1867     \r
1868     PNDIS_INTERRUPT_MODERATION_PARAMETERS pInteruptModerationParam =\r
1869                     (PNDIS_INTERRUPT_MODERATION_PARAMETERS)InformationBuffer;\r
1870     \r
1871     if ((pInteruptModerationParam->Header.Type != NDIS_OBJECT_TYPE_DEFAULT) ||\r
1872         (pInteruptModerationParam->Header.Revision != NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1) ||\r
1873         (pInteruptModerationParam->Header.Size != NDIS_SIZEOF_INTERRUPT_MODERATION_PARAMETERS_REVISION_1))\r
1874     {\r
1875         Status = NDIS_STATUS_INVALID_DATA;\r
1876         goto Exit;\r
1877     }\r
1878     //\r
1879     // BUGBUG: Need to handle disabling of interrupt moderation \r
1880     //                          UH, 4-Jun-2008\r
1881     //\r
1882 //    ASSERT(pInteruptModerationParam->Flags == NDIS_INTERRUPT_MODERATION_CHANGE_NEEDS_RESET);\r
1883 //    ASSERT(pInteruptModerationParam->InterruptModeration == NdisInterruptModerationEnabled);\r
1884 \r
1885 Exit:\r
1886     IPOIB_EXIT(IPOIB_DBG_OID);\r
1887     return Status;\r
1888 }\r
1889 \r
1890 \r
1891 NDIS_STATUS\r
1892 InitNdisScatterGatherDma(\r
1893         ipoib_adapter_t *p_adapter,\r
1894         NDIS_HANDLE             h_adapter\r
1895         )\r
1896 {\r
1897         NDIS_STATUS                                             status;\r
1898         NDIS_SG_DMA_DESCRIPTION                 DmaDescription;\r
1899         \r
1900         NdisZeroMemory(&DmaDescription, sizeof(DmaDescription));\r
1901 \r
1902         DmaDescription.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;\r
1903         DmaDescription.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1;\r
1904         DmaDescription.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION);\r
1905         DmaDescription.Flags = NDIS_SG_DMA_64_BIT_ADDRESS; \r
1906         //\r
1907         // Even if offload is enabled, the packet size for mapping shouldn't change\r
1908         //\r
1909         //TODO bug ?\r
1910         DmaDescription.MaximumPhysicalMapping = LARGE_SEND_OFFLOAD_SIZE + LSO_MAX_HEADER;\r
1911 \r
1912         DmaDescription.ProcessSGListHandler = ipoib_process_sg_list;\r
1913         DmaDescription.SharedMemAllocateCompleteHandler = NULL;\r
1914 \r
1915         DmaDescription.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;\r
1916         DmaDescription.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1;\r
1917         DmaDescription.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION);//NDIS_SIZEOF_SG_DMA_DESCRIPTION_REVISION_1;\r
1918 \r
1919         DmaDescription.Flags = NDIS_SG_DMA_64_BIT_ADDRESS;\r
1920         //DmaDescription.MaximumPhysicalMapping = pPort->p_adapter->params.xfer_block_size;\r
1921 \r
1922         \r
1923         status = NdisMRegisterScatterGatherDma(\r
1924                                         h_adapter,\r
1925                                         &DmaDescription,\r
1926                                         &p_adapter->NdisMiniportDmaHandle);\r
1927 \r
1928         if( status != NDIS_STATUS_SUCCESS )\r
1929         {\r
1930                 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
1931                                                  ("NdisMRegisterScatterGatherDma returned 0x%.8x.\n", status) );\r
1932                 return status;\r
1933                 \r
1934         }\r
1935         //NDIS sets this value before it returns from NdisMRegisterScatterGatherDma. \r
1936         //Miniport drivers should use this size to preallocate memory for each scatter/gather list. \r
1937         p_adapter->sg_list_size = DmaDescription.ScatterGatherListSize ;\r
1938         \r
1939         return status;\r
1940 }\r
1941 \r
1942 \r
1943 \r
1944 \r
1945 /*++\r
1946 Routine Description:\r
1947 \r
1948     MiniportInitialize handler\r
1949 \r
1950 Arguments:\r
1951 \r
1952     MiniportAdapterHandle   The handle NDIS uses to refer to us\r
1953     MiniportDriverContext   Handle passed to NDIS when we registered the driver\r
1954     MiniportInitParameters  Initialization parameters\r
1955     \r
1956 Return Value:\r
1957 \r
1958     NDIS_STATUS_SUCCESS unless something goes wrong\r
1959 \r
1960 --*/\r
1961 \r
1962 NDIS_STATUS\r
1963 ipoib_initialize_ex(\r
1964                 IN NDIS_HANDLE  h_adapter,\r
1965                 IN NDIS_HANDLE  config_context,\r
1966                 IN PNDIS_MINIPORT_INIT_PARAMETERS  MiniportInitParameters)\r
1967         {\r
1968                 NDIS_STATUS             status;\r
1969                 ib_api_status_t         ib_status;\r
1970                 ipoib_adapter_t         *p_adapter;\r
1971 \r
1972                 IPOIB_ENTER( IPOIB_DBG_INIT );\r
1973 \r
1974 #if 0\r
1975 if(cl_get_time_stamp_sec() < 30) {\r
1976         cl_dbg_out("Disable/Enable IPoIB adapter to continue running\n");\r
1977         return NDIS_STATUS_HARD_ERRORS;\r
1978 }\r
1979 #endif\r
1980         \r
1981 #ifdef _DEBUG_\r
1982                 PAGED_CODE();\r
1983 #endif\r
1984                 \r
1985                 UNUSED_PARAM( config_context );\r
1986                 UNUSED_PARAM( MiniportInitParameters );\r
1987                 \r
1988                 /* Create the adapter adapter */\r
1989                 ib_status = ipoib_create_adapter( h_adapter, &p_adapter );\r
1990                 if( ib_status != IB_SUCCESS )\r
1991                 {\r
1992                         //ASSERT(FALSE);\r
1993                         IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
1994                                 ("ipoib_create_adapter returned status %d.\n", ib_status ) );\r
1995                         return NDIS_STATUS_FAILURE;\r
1996                 }\r
1997                 p_adapter->ipoib_state = IPOIB_PAUSED;\r
1998                 \r
1999                 status  = SetAttributes(p_adapter, h_adapter);\r
2000                 if (status != NDIS_STATUS_SUCCESS) {\r
2001                         //ASSERT(FALSE);\r
2002                         ipoib_destroy_adapter( p_adapter );\r
2003                         return NDIS_STATUS_FAILURE;\r
2004                 }\r
2005 \r
2006 \r
2007 #if IPOIB_USE_DMA\r
2008                 status = InitNdisScatterGatherDma(p_adapter, h_adapter);\r
2009                 if( status != NDIS_STATUS_SUCCESS )\r
2010                 {       \r
2011                         ipoib_destroy_adapter( p_adapter );\r
2012                         IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
2013                                 ("InitNdisScatterGatherDma returned status 0x%.8x.\n", status ) );\r
2014                         return NDIS_STATUS_FAILURE;\r
2015                 }\r
2016 \r
2017 #endif\r
2018 \r
2019                 \r
2020 \r
2021                 /* Create the adapter adapter */\r
2022                 ib_status = ipoib_start_adapter( p_adapter );\r
2023                 if( ib_status != IB_SUCCESS )\r
2024                 {\r
2025                         //ASSERT(FALSE);\r
2026                         NdisWriteErrorLogEntry( h_adapter,\r
2027                                 NDIS_ERROR_CODE_HARDWARE_FAILURE, 0 );\r
2028 #if  IPOIB_USE_DMA\r
2029                         NdisMDeregisterScatterGatherDma(p_adapter->NdisMiniportDmaHandle);\r
2030 #endif\r
2031                         ipoib_destroy_adapter( p_adapter );\r
2032                         IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
2033                                 ("ipoib_start_adapter returned status %d.\n", ib_status ) );\r
2034                         return NDIS_STATUS_FAILURE;\r
2035                 }\r
2036                 \r
2037                 status = SetOffloadAttributes(p_adapter, h_adapter);\r
2038                 if (status != NDIS_STATUS_SUCCESS)\r
2039                 {\r
2040 #if  IPOIB_USE_DMA\r
2041                         NdisMDeregisterScatterGatherDma(p_adapter->NdisMiniportDmaHandle);\r
2042 #endif\r
2043                         ipoib_destroy_adapter( p_adapter );\r
2044                         IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
2045                                 ("SetOffloadAttributes returned status 0x%.8x.\n", status ) );\r
2046                         return NDIS_STATUS_FAILURE;\r
2047                 }\r
2048 \r
2049                 p_adapter->p_stat = ipoib_st_dev_add();\r
2050                 if ( p_adapter->p_stat ) \r
2051                         p_adapter->p_stat->p_adapter = p_adapter;\r
2052 \r
2053                 ipoib_ref_ibat();\r
2054         \r
2055                 IPOIB_EXIT( IPOIB_DBG_INIT );\r
2056                 return status;\r
2057         }\r
2058 \r
2059 \r
2060 //! Deallocates resources when the NIC is removed and halts the NIC..\r
2061 //TODO: Dispatch or Passive ?\r
2062 /*  IRQL = DISPATCH_LEVEL\r
2063 \r
2064 @param adapter_context The adapter context allocated at start\r
2065 */\r
2066 void\r
2067 ipoib_halt_ex(\r
2068         IN                              NDIS_HANDLE                                     adapter_context,\r
2069         IN                      NDIS_HALT_ACTION            HaltAction )\r
2070 {\r
2071         ipoib_adapter_t *p_adapter;\r
2072 \r
2073         IPOIB_ENTER( IPOIB_DBG_INIT );\r
2074 \r
2075         UNUSED_PARAM(HaltAction);\r
2076                 \r
2077         ipoib_deref_ibat();\r
2078 \r
2079         CL_ASSERT( adapter_context );\r
2080         p_adapter = (ipoib_adapter_t*)adapter_context;\r
2081 \r
2082         IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
2083                         ("Port %016I64x (CA %016I64x port %d) halting\n",\r
2084                         p_adapter->guids.port_guid.guid, p_adapter->guids.ca_guid,\r
2085                         p_adapter->guids.port_num) );\r
2086 \r
2087 #if IPOIB_USE_DMA\r
2088         if (p_adapter->NdisMiniportDmaHandle != NULL)\r
2089         {\r
2090                 NdisMDeregisterScatterGatherDma(p_adapter->NdisMiniportDmaHandle);\r
2091                 p_adapter->NdisMiniportDmaHandle = NULL;\r
2092         }\r
2093 #endif\r
2094 \r
2095         PIPOIB_ST_DEVICE p_stat = p_adapter->p_stat;\r
2096         p_stat->p_halt_thread = KeGetCurrentThread();\r
2097         ipoib_destroy_adapter( p_adapter );\r
2098         ipoib_st_dev_rmv( p_stat );\r
2099 \r
2100         IPOIB_EXIT( IPOIB_DBG_INIT );\r
2101 }\r
2102 \r
2103 \r
2104 //! Reports the state of the NIC, or monitors the responsiveness of an underlying device driver.\r
2105 /*  IRQL = DISPATCH_LEVEL\r
2106 \r
2107 @param adapter_context The adapter context allocated at start\r
2108 @return TRUE if the driver determines that its NIC is not operating\r
2109 */\r
2110 BOOLEAN\r
2111 ipoib_check_for_hang(\r
2112         IN                              NDIS_HANDLE                                     adapter_context )\r
2113 {\r
2114         ipoib_adapter_t *p_adapter;\r
2115 \r
2116         IPOIB_ENTER( IPOIB_DBG_INIT );\r
2117 \r
2118         CL_ASSERT( adapter_context );\r
2119         p_adapter = (ipoib_adapter_t*)adapter_context;\r
2120 \r
2121         if( p_adapter->reset )\r
2122         {\r
2123                 IPOIB_EXIT( IPOIB_DBG_INIT );\r
2124                 return FALSE;\r
2125         }\r
2126         \r
2127         if (p_adapter->p_port)\r
2128         {\r
2129                 if (p_adapter->p_port->send_mgr.pending_list.count > 0)\r
2130                 {\r
2131                         ++(p_adapter->p_port->n_no_progress);\r
2132                         if (p_adapter->p_port->n_no_progress >= 4)\r
2133                         {\r
2134                                 IPOIB_PRINT( TRACE_LEVEL_ERROR,IPOIB_DBG_ERROR, ("port got stuck, reseting it !!!\n"));\r
2135                                 //CL_ASSERT(FALSE); //?????\r
2136                                 p_adapter->hung = TRUE;\r
2137                         }\r
2138                 }\r
2139                 else \r
2140                 {\r
2141                         p_adapter->p_port->n_no_progress = 0;\r
2142                 }\r
2143         }\r
2144         \r
2145         if (p_adapter->hung) {\r
2146                 ipoib_resume_oids(p_adapter);\r
2147         }\r
2148 \r
2149         IPOIB_EXIT( IPOIB_DBG_INIT );\r
2150         return (p_adapter->hung? TRUE:FALSE);\r
2151 }\r
2152 \r
2153 \r
2154 /*++\r
2155 Routine Description:\r
2156         The routine sets an NDIS_OFFLOAD structure indicates the current offload \r
2157         capabilities that are provided by the miniport adapter \r
2158 \r
2159 Arguments:\r
2160         pPort - a pointer to port object\r
2161         offload - reference to NDIS_OFFLOAD object that should be filled\r
2162 \r
2163 Return Value:\r
2164         None.\r
2165 \r
2166 --*/\r
2167 //TODO\r
2168 #if 0\r
2169 static\r
2170 void\r
2171 __ipoib_get_offload_config(\r
2172         ipoib_port_t *pPort,\r
2173         NDIS_OFFLOAD *p_offload\r
2174         )\r
2175 {\r
2176         NDIS_STATUS Status;\r
2177         ULONG TxChksumOffload = ((MP_GET_PORT_CONFIG(pPort, TxChksumOffload) == TRUE) ? NDIS_OFFLOAD_SET_ON : NDIS_OFFLOAD_SET_OFF);\r
2178         ULONG RxChksumOffload = ((MP_GET_PORT_CONFIG(pPort, RxChksumOffload) == TRUE) ? NDIS_OFFLOAD_SET_ON : NDIS_OFFLOAD_SET_OFF);\r
2179         BOOLEAN fLargeSendOffload = MP_GET_PORT_CONFIG(pPort, LargeSendOffload);\r
2180         ULONG ulEncapsulation = NDIS_ENCAPSULATION_IEEE_802_3 | NDIS_ENCAPSULATION_IEEE_802_3_P_AND_Q;\r
2181             \r
2182         NdisZeroMemory(&*p_offload, sizeof(NDIS_OFFLOAD));\r
2183         *p_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;\r
2184         *p_offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; // BUGBUG: do we need to support revision 2? UH 17-May-2008\r
2185         *p_offload.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;\r
2186 \r
2187         *p_offload.Checksum.IPv4Transmit.Encapsulation = ulEncapsulation;\r
2188         *p_offload.Checksum.IPv4Transmit.IpOptionsSupported = TxChksumOffload;\r
2189         *p_offload.Checksum.IPv4Transmit.TcpOptionsSupported = TxChksumOffload;\r
2190         *p_offload.Checksum.IPv4Transmit.TcpChecksum = TxChksumOffload;\r
2191         *p_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_NOT_SUPPORTED;\r
2192         *p_offload.Checksum.IPv4Transmit.IpChecksum = TxChksumOffload;\r
2193 \r
2194         *p_offload.Checksum.IPv4Receive.Encapsulation = ulEncapsulation;\r
2195         *p_offload.Checksum.IPv4Receive.IpOptionsSupported = RxChksumOffload;\r
2196         *p_offload.Checksum.IPv4Receive.TcpOptionsSupported = RxChksumOffload;\r
2197         *p_offload.Checksum.IPv4Receive.TcpChecksum = RxChksumOffload;\r
2198         *p_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_NOT_SUPPORTED; \r
2199         *p_offload.Checksum.IPv4Receive.IpChecksum = RxChksumOffload;\r
2200 \r
2201         *p_offload.Checksum.IPv6Transmit.Encapsulation = ulEncapsulation;\r
2202         *p_offload.Checksum.IPv6Transmit.IpExtensionHeadersSupported = TxChksumOffload;\r
2203         *p_offload.Checksum.IPv6Transmit.TcpOptionsSupported = TxChksumOffload;\r
2204         *p_offload.Checksum.IPv6Transmit.TcpChecksum = TxChksumOffload;\r
2205         *p_offload.Checksum.IPv6Transmit.UdpChecksum = NDIS_OFFLOAD_NOT_SUPPORTED;\r
2206 \r
2207 \r
2208         *p_offload.Checksum.IPv6Receive.Encapsulation = ulEncapsulation;\r
2209         *p_offload.Checksum.IPv6Receive.IpExtensionHeadersSupported = RxChksumOffload;\r
2210         *p_offload.Checksum.IPv6Receive.TcpOptionsSupported = RxChksumOffload;\r
2211         *p_offload.Checksum.IPv6Receive.TcpChecksum = RxChksumOffload;\r
2212         *p_offload.Checksum.IPv6Receive.UdpChecksum = NDIS_OFFLOAD_NOT_SUPPORTED;\r
2213 \r
2214         if (fLargeSendOffload)\r
2215         {\r
2216             *p_offload.LsoV1.IPv4.Encapsulation = ulEncapsulation;\r
2217             *p_offload.LsoV1.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
2218             *p_offload.LsoV1.IPv4.MinSegmentCount = 1;\r
2219             *p_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_SUPPORTED;\r
2220             *p_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_SUPPORTED;\r
2221         }\r
2222 }\r
2223 #endif\r
2224 \r
2225 //! Returns information about the capabilities and status of the driver and/or its NIC.\r
2226 /*  IRQL = DISPATCH_LEVEL\r
2227 \r
2228 @param adapter_context The adapter context allocated at start\r
2229 @param oid Object ID representing the query operation to be carried out\r
2230 @param info_buf Buffer containing any input for this query and location for output\r
2231 @param info_buf_len Number of bytes available in info_buf\r
2232 @param p_bytes_written Pointer to number of bytes written into info_buf\r
2233 @param p_bytes_needed Pointer to number of bytes needed to satisfy this oid\r
2234 @return NDIS_STATUS_SUCCESS, NDIS_STATUS_PENDING, NDIS_STATUS_INVALID_OID,\r
2235 NDIS_STATUS_INVALID_LENGTH, NDIS_STATUS_NOT_ACCEPTED, NDIS_STATUS_NOT_SUPPORTED,\r
2236 NDIS_STATUS_RESOURCES\r
2237 */\r
2238 \r
2239 NDIS_STATUS\r
2240 ipoib_query_info(\r
2241     IN          NDIS_HANDLE         adapter_context,\r
2242     IN  OUT PNDIS_OID_REQUEST   pNdisRequest)\r
2243 \r
2244         {\r
2245                 ipoib_adapter_t         *p_adapter;\r
2246                 NDIS_STATUS             status;\r
2247                 ULONG                           version;\r
2248                 ULONG                           info;\r
2249                 PVOID                           src_buf;\r
2250                 ULONG                           buf_len;\r
2251                 pending_oid_t           oid_info;\r
2252                 uint8_t                         port_num;\r
2253                 NDIS_OFFLOAD        offload;\r
2254 \r
2255                 NDIS_INTERRUPT_MODERATION_PARAMETERS InterruptModerationParam;\r
2256 \r
2257                 \r
2258                 IPOIB_ENTER( IPOIB_DBG_OID );\r
2259                 \r
2260                 oid_info.oid = pNdisRequest->DATA.QUERY_INFORMATION.Oid;\r
2261                 oid_info.p_buf = pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;\r
2262                 oid_info.buf_len = pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;\r
2263                 oid_info.p_bytes_used = (PULONG)&pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten;\r
2264                 oid_info.p_bytes_needed = (PULONG)&pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;\r
2265                 oid_info.p_pending_oid = NULL;\r
2266                 \r
2267                 CL_ASSERT( adapter_context );\r
2268                 p_adapter = (ipoib_adapter_t*)adapter_context;\r
2269 \r
2270                 CL_ASSERT( oid_info.p_bytes_used );\r
2271                 CL_ASSERT( oid_info.p_bytes_needed );\r
2272                 CL_ASSERT( !p_adapter->pending_query );\r
2273                 \r
2274                 status = NDIS_STATUS_SUCCESS;\r
2275                 src_buf = &info;\r
2276                 buf_len = sizeof(info);\r
2277         \r
2278                 port_num = p_adapter->guids.port_num;\r
2279         \r
2280                 switch( oid_info.oid )\r
2281                 {\r
2282                 /* Required General */\r
2283                 case OID_GEN_SUPPORTED_LIST:\r
2284                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2285                                 ("Port %d received query for OID_GEN_SUPPORTED_LIST\n", port_num) );\r
2286                         src_buf = (PVOID)SUPPORTED_OIDS;\r
2287                         buf_len = sizeof(SUPPORTED_OIDS);\r
2288                         break;\r
2289         \r
2290                 case OID_GEN_HARDWARE_STATUS:\r
2291                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2292                                 ("Port %d received query for OID_GEN_HARDWARE_STATUS\n", port_num) );\r
2293         \r
2294                         cl_obj_lock( &p_adapter->obj );\r
2295                         switch( p_adapter->state )\r
2296                         {\r
2297                         case IB_PNP_PORT_ADD:\r
2298                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2299                                         ("Port %d returning NdisHardwareStatusInitializing\n", port_num) );\r
2300                                 info = NdisHardwareStatusInitializing;\r
2301                                 break;\r
2302                                 \r
2303                         case IB_PNP_PORT_ACTIVE:\r
2304                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2305                                         ("Port %d returning NdisHardwareStatusReady\n", port_num) );\r
2306                                 info = NdisHardwareStatusReady;\r
2307                                 break;\r
2308         \r
2309                         default:\r
2310                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2311                                         ("Port %d returning NdisHardwareStatusNotReady\n", port_num) );\r
2312                                 info = NdisHardwareStatusNotReady;\r
2313                         }\r
2314                         cl_obj_unlock( &p_adapter->obj );\r
2315                         break;\r
2316         \r
2317                 case OID_GEN_MEDIA_SUPPORTED:\r
2318                 case OID_GEN_MEDIA_IN_USE:\r
2319                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2320                                 ("Port %d received query for OID_GEN_MEDIA_SUPPORTED "\r
2321                                 "or OID_GEN_MEDIA_IN_USE\n", port_num) );\r
2322                         info = NdisMedium802_3;\r
2323                         break;\r
2324         \r
2325                 case OID_GEN_MAXIMUM_FRAME_SIZE:\r
2326                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2327                                 ("Port %d received query for OID_GEN_MAXIMUM_FRAME_SIZE\n", port_num) );\r
2328                         if( p_adapter->params.cm_enabled )\r
2329                         {\r
2330                                 info = p_adapter->params.cm_payload_mtu;\r
2331                         }\r
2332                         else\r
2333                         {\r
2334                                 info = p_adapter->params.payload_mtu;\r
2335                         }\r
2336                         break;\r
2337         \r
2338                 case OID_GEN_LINK_SPEED:\r
2339                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2340                                 ("Port %d received query for OID_GEN_LINK_SPEED\n", port_num) );\r
2341                         if (oid_info.buf_len < buf_len)\r
2342                         {\r
2343                                 break;\r
2344                         }\r
2345         \r
2346                         cl_obj_lock( &p_adapter->obj );\r
2347                         switch( p_adapter->state )\r
2348                         {\r
2349                         case IB_PNP_PORT_ADD:\r
2350                                 /* Mark the adapter as pending an OID */\r
2351                                 p_adapter->pending_query = TRUE;\r
2352         \r
2353                                 /* Save the request parameters. */\r
2354                                 p_adapter->query_oid = oid_info;\r
2355                                 p_adapter->query_oid.p_pending_oid = pNdisRequest;\r
2356         \r
2357                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2358                                         ("Port %d returning NDIS_STATUS_PENDING\n", port_num) );\r
2359                                 status = NDIS_STATUS_PENDING;\r
2360                                 break;\r
2361         \r
2362                         case IB_PNP_PORT_REMOVE:\r
2363                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2364                                         ("Port %d returning NDIS_STATUS_NOT_ACCEPTED\n", port_num) );\r
2365                                 status = NDIS_STATUS_NOT_ACCEPTED;\r
2366                                 break;\r
2367         \r
2368                         default:\r
2369                                 CL_ASSERT( p_adapter->p_port );\r
2370                                 info = p_adapter->port_rate;\r
2371                                 break;\r
2372                         }\r
2373                         cl_obj_unlock( &p_adapter->obj );\r
2374                         break;\r
2375         \r
2376                 case OID_GEN_TRANSMIT_BUFFER_SPACE:\r
2377                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2378                                 ("Port %d received query for OID_GEN_TRANSMIT_BUFFER_SPACE\n", port_num) );\r
2379                         if( p_adapter->params.cm_enabled )\r
2380                                 info = p_adapter->params.sq_depth * p_adapter->params.cm_xfer_block_size;\r
2381                         else\r
2382                                 info = p_adapter->params.sq_depth * p_adapter->params.xfer_block_size;\r
2383                         break;\r
2384         \r
2385                 case OID_GEN_RECEIVE_BUFFER_SPACE:\r
2386                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2387                                 ("Port %d received query for OID_GEN_TRANSMIT_BUFFER_SPACE "\r
2388                                 "or OID_GEN_RECEIVE_BUFFER_SPACE\n", port_num) );\r
2389                         if( p_adapter->params.cm_enabled )\r
2390                                 info = p_adapter->params.rq_depth * p_adapter->params.cm_xfer_block_size;\r
2391                         else\r
2392                                 info = p_adapter->params.rq_depth * p_adapter->params.xfer_block_size;\r
2393                         break;\r
2394         \r
2395                 case OID_GEN_MAXIMUM_LOOKAHEAD:\r
2396                 case OID_GEN_CURRENT_LOOKAHEAD:\r
2397                 case OID_GEN_TRANSMIT_BLOCK_SIZE:\r
2398                 case OID_GEN_RECEIVE_BLOCK_SIZE:\r
2399                 case OID_GEN_MAXIMUM_TOTAL_SIZE:\r
2400                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2401                                 ("Port %d received query for OID_GEN_MAXIMUM_LOOKAHEAD "\r
2402                                 "or OID_GEN_CURRENT_LOOKAHEAD or "\r
2403                                 "OID_GEN_TRANSMIT_BLOCK_SIZE or "\r
2404                                 "OID_GEN_RECEIVE_BLOCK_SIZE or "\r
2405                                 "OID_GEN_MAXIMUM_TOTAL_SIZE\n", port_num) );\r
2406                         if( p_adapter->params.cm_enabled )\r
2407                                 info = p_adapter->params.cm_xfer_block_size;\r
2408                         else\r
2409                                 info = p_adapter->params.xfer_block_size;\r
2410                         break;\r
2411         \r
2412                 case OID_GEN_VENDOR_ID:\r
2413                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2414                                 ("Port %d received query for OID_GEN_VENDOR_ID\n", port_num) );\r
2415                         src_buf = (void*)VENDOR_ID;\r
2416                         buf_len = sizeof(VENDOR_ID);\r
2417                         break;\r
2418         \r
2419                 case OID_GEN_VENDOR_DESCRIPTION:\r
2420                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID, \r
2421                                 ("Port %d received query for OID_GEN_VENDOR_DESCRIPTION\n", port_num) );\r
2422                         src_buf = VENDOR_DESCRIPTION;\r
2423                         buf_len = sizeof(VENDOR_DESCRIPTION);\r
2424                         break;\r
2425         \r
2426                 case OID_GEN_VENDOR_DRIVER_VERSION:\r
2427                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2428                                 ("Port %d received query for OID_GEN_VENDOR_DRIVER_VERSION\n", port_num) );\r
2429                         src_buf = &version;\r
2430                         buf_len = sizeof(version);\r
2431                         //TODO: Figure out what the right version is.\r
2432                         version = 1 << 8 | 1;\r
2433                         break;\r
2434         \r
2435                 case OID_GEN_PHYSICAL_MEDIUM:\r
2436                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2437                                 ("Port %d received query for OID_GEN_PHYSICAL_MEDIUM\n", port_num) );\r
2438                         info = NdisPhysicalMediumUnspecified;\r
2439                         break;\r
2440         \r
2441                 case OID_GEN_CURRENT_PACKET_FILTER:\r
2442                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2443                                 ("Port %d received query for OID_GEN_CURRENT_PACKET_FILTER\n", port_num) );\r
2444                         info = p_adapter->packet_filter;\r
2445                         break;\r
2446         \r
2447                 case OID_GEN_DRIVER_VERSION:\r
2448                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2449                                 ("Port %d received query for OID_GEN_DRIVER_VERSION\n", port_num) );\r
2450                         src_buf = &version;\r
2451                         buf_len = sizeof(version);\r
2452                         version = MAJOR_NDIS_VERSION << 8 | MINOR_NDIS_VERSION;\r
2453                         break;\r
2454         \r
2455                 case OID_GEN_MAC_OPTIONS:\r
2456                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2457                                 ("Port %d received query for OID_GEN_MAC_OPTIONS\n", port_num) );\r
2458                         info = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |\r
2459                                 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |\r
2460                                 NDIS_MAC_OPTION_NO_LOOPBACK |\r
2461                                 NDIS_MAC_OPTION_FULL_DUPLEX;\r
2462         //TODO: Figure out if we will support priority and VLANs.\r
2463         //                              NDIS_MAC_OPTION_8021P_PRIORITY;\r
2464         //#ifdef NDIS51_MINIPORT\r
2465         //                      info |= NDIS_MAC_OPTION_8021Q_VLAN;\r
2466         //#endif\r
2467                         break;\r
2468         \r
2469                 case OID_GEN_MEDIA_CONNECT_STATUS:\r
2470                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2471                                 ("Port %d received query for OID_GEN_MEDIA_CONNECT_STATUS\n", port_num) );\r
2472                         cl_obj_lock( &p_adapter->obj );\r
2473                         switch( p_adapter->state )\r
2474                         {\r
2475                         case IB_PNP_PORT_ADD:\r
2476                         case IB_PNP_PORT_INIT:\r
2477                                 /*\r
2478                                  * Delay reporting media state until we know whether the port is\r
2479                                  * either up or down.\r
2480                                  */\r
2481                                 p_adapter->pending_query = TRUE;\r
2482                                 p_adapter->query_oid = oid_info;\r
2483                                 p_adapter->query_oid.p_pending_oid = pNdisRequest;\r
2484         \r
2485                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2486                                         ("Port %d returning NDIS_STATUS_PENDING\n", port_num) );\r
2487                                 status = NDIS_STATUS_PENDING;\r
2488                                 break;\r
2489         \r
2490                         case IB_PNP_PORT_ACTIVE:\r
2491                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2492                                         ("Port %d returning NdisMediaStateConnected\n", port_num) );\r
2493                                 info = NdisMediaStateConnected;\r
2494                                 break;\r
2495         \r
2496                         case IB_PNP_PORT_REMOVE:\r
2497                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2498                                         ("Port %d returning NDIS_STATUS_NOT_ACCEPTED\n", port_num) );\r
2499                                 status = NDIS_STATUS_NOT_ACCEPTED;\r
2500                                 break;\r
2501         \r
2502                         default:\r
2503                                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2504                                         ("Port %d returning NdisMediaStateDisconnected\n", port_num) );\r
2505                                 info = NdisMediaStateDisconnected;\r
2506                         }\r
2507                         cl_obj_unlock( &p_adapter->obj );\r
2508                         break;\r
2509         \r
2510                 case OID_GEN_MAXIMUM_SEND_PACKETS:\r
2511                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2512                                 ("Port %d received query for OID_GEN_MAXIMUM_SEND_PACKETS\n", port_num) );\r
2513                         info = MINIPORT_MAX_SEND_PACKETS;\r
2514                         break;\r
2515         \r
2516                 /* Required General Statistics */\r
2517                 case OID_GEN_STATISTICS:\r
2518                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2519                                 ("Port %d received query for OID_GEN_STATISTICS\n", port_num) );\r
2520                         src_buf = NULL;   \r
2521                          buf_len =  sizeof(NDIS_STATISTICS_INFO);\r
2522                         if (oid_info.buf_len < buf_len)\r
2523                         {\r
2524                            break;\r
2525                         } \r
2526                         status = ipoib_get_gen_stat(p_adapter, &oid_info );\r
2527                         break;\r
2528         \r
2529                 case OID_GEN_XMIT_OK:\r
2530                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2531                                 ("Port %d received query for OID_GEN_XMIT_OK\n", port_num) );\r
2532                         src_buf = NULL;\r
2533                         status = ipoib_get_send_stat( p_adapter, IP_STAT_SUCCESS, &oid_info );\r
2534                         break;\r
2535         \r
2536                 case OID_GEN_RCV_OK:\r
2537                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2538                                 ("Port %d received query for OID_GEN_RCV_OK\n", port_num) );\r
2539                         src_buf = NULL;\r
2540                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_SUCCESS, &oid_info );\r
2541                         break;\r
2542         \r
2543                 case OID_GEN_XMIT_ERROR:\r
2544                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2545                                 ("Port %d received query for OID_GEN_XMIT_ERROR\n", port_num) );\r
2546                         src_buf = NULL;\r
2547                         status = ipoib_get_send_stat( p_adapter, IP_STAT_ERROR, &oid_info );\r
2548                         break;\r
2549         \r
2550                 case OID_GEN_RCV_ERROR:\r
2551                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2552                                 ("Port %d received query for OID_GEN_RCV_ERROR\n", port_num) );\r
2553                         src_buf = NULL;\r
2554                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_ERROR, &oid_info );\r
2555                         break;\r
2556         \r
2557                 case OID_GEN_RCV_NO_BUFFER:\r
2558                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2559                                 ("Port %d received query for OID_GEN_RCV_NO_BUFFER\n", port_num) );\r
2560                         src_buf = NULL;\r
2561                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_DROPPED, &oid_info );\r
2562                         break;\r
2563         \r
2564                 case OID_GEN_DIRECTED_BYTES_XMIT:\r
2565                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2566                                 ("Port %d received query for OID_GEN_DIRECTED_BYTES_XMIT\n", port_num) );\r
2567                         src_buf = NULL;\r
2568                         status = ipoib_get_send_stat( p_adapter, IP_STAT_UCAST_BYTES, &oid_info );\r
2569                         break;\r
2570         \r
2571                 case OID_GEN_DIRECTED_FRAMES_XMIT:\r
2572                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2573                                 ("Port %d received query for OID_GEN_DIRECTED_FRAMES_XMIT\n", port_num) );\r
2574                         src_buf = NULL;\r
2575                         status = ipoib_get_send_stat( p_adapter, IP_STAT_UCAST_FRAMES, &oid_info );\r
2576                         break;\r
2577         \r
2578                 case OID_GEN_MULTICAST_BYTES_XMIT:\r
2579                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2580                                 ("Port %d received query for OID_GEN_MULTICAST_BYTES_XMIT\n", port_num) );\r
2581                         src_buf = NULL;\r
2582                         status = ipoib_get_send_stat( p_adapter, IP_STAT_MCAST_BYTES, &oid_info );\r
2583                         break;\r
2584         \r
2585                 case OID_GEN_MULTICAST_FRAMES_XMIT:\r
2586                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2587                                 ("Port %d received query for OID_GEN_MULTICAST_FRAMES_XMIT\n", port_num) );\r
2588                         src_buf = NULL;\r
2589                         status = ipoib_get_send_stat( p_adapter, IP_STAT_MCAST_FRAMES, &oid_info );\r
2590                         break;\r
2591         \r
2592                 case OID_GEN_BROADCAST_BYTES_XMIT:\r
2593                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2594                                 ("Port %d received query for OID_GEN_BROADCAST_BYTES_XMIT\n", port_num) );\r
2595                         src_buf = NULL;\r
2596                         status = ipoib_get_send_stat( p_adapter, IP_STAT_BCAST_BYTES, &oid_info );\r
2597                         break;\r
2598         \r
2599                 case OID_GEN_BROADCAST_FRAMES_XMIT:\r
2600                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2601                                 ("Port %d received query for OID_GEN_BROADCAST_FRAMES_XMIT\n", port_num) );\r
2602                         src_buf = NULL;\r
2603                         status = ipoib_get_send_stat( p_adapter, IP_STAT_BCAST_FRAMES, &oid_info );\r
2604                         break;\r
2605         \r
2606                 case OID_GEN_DIRECTED_BYTES_RCV:\r
2607                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2608                                 ("Port %d received query for OID_GEN_DIRECTED_BYTES_RCV\n", port_num) );\r
2609                         src_buf = NULL;\r
2610                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_UCAST_BYTES, &oid_info );\r
2611                         break;\r
2612         \r
2613                 case OID_GEN_DIRECTED_FRAMES_RCV:\r
2614                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2615                                 ("Port %d received query for OID_GEN_DIRECTED_FRAMES_RCV\n", port_num) );\r
2616                         src_buf = NULL;\r
2617                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_UCAST_FRAMES, &oid_info );\r
2618                         break;\r
2619         \r
2620                 case OID_GEN_MULTICAST_BYTES_RCV:\r
2621                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2622                                 ("Port %d received query for OID_GEN_MULTICAST_BYTES_RCV\n", port_num) );\r
2623                         src_buf = NULL;\r
2624                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_MCAST_BYTES, &oid_info );\r
2625                         break;\r
2626         \r
2627                 case OID_GEN_MULTICAST_FRAMES_RCV:\r
2628                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2629                                 ("Port %d received query for OID_GEN_MULTICAST_FRAMES_RCV\n", port_num) );\r
2630                         src_buf = NULL;\r
2631                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_MCAST_FRAMES, &oid_info );\r
2632                         break;\r
2633         \r
2634                 case OID_GEN_BROADCAST_BYTES_RCV:\r
2635                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2636                                 ("Port %d received query for OID_GEN_BROADCAST_BYTES_RCV\n", port_num) );\r
2637                         src_buf = NULL;\r
2638                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_BCAST_BYTES, &oid_info );\r
2639                         break;\r
2640         \r
2641                 case OID_GEN_BROADCAST_FRAMES_RCV:\r
2642                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2643                                 ("Port %d received query for OID_GEN_BROADCAST_FRAMES_RCV\n", port_num) );\r
2644                         src_buf = NULL;\r
2645                         status = ipoib_get_recv_stat( p_adapter, IP_STAT_BCAST_FRAMES, &oid_info );\r
2646                         break;\r
2647         \r
2648                 /* Required Ethernet operational characteristics */\r
2649                 case OID_802_3_PERMANENT_ADDRESS:\r
2650                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2651                                 ("Port %d received query for OID_802_3_PERMANENT_ADDRESS\n", port_num) );\r
2652                         src_buf = &p_adapter->mac;\r
2653                 buf_len = sizeof(p_adapter->mac);\r
2654                         break;\r
2655         \r
2656                 case OID_802_3_CURRENT_ADDRESS:\r
2657                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2658                                 ("Port %d received query for OID_802_3_CURRENT_ADDRESS\n", port_num) );\r
2659                         src_buf = &p_adapter->params.conf_mac;\r
2660                 buf_len = sizeof(p_adapter->params.conf_mac);\r
2661                         break;\r
2662         \r
2663                 case OID_802_3_MULTICAST_LIST:\r
2664                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2665                                 ("Port %d received query for OID_802_3_MULTICAST_LIST\n", port_num) );\r
2666                         src_buf = p_adapter->mcast_array;\r
2667                 buf_len = p_adapter->mcast_array_size * sizeof(mac_addr_t);\r
2668                         break;\r
2669         \r
2670                 case OID_802_3_MAXIMUM_LIST_SIZE:\r
2671                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2672                                 ("Port %d received query for OID_802_3_MAXIMUM_LIST_SIZE\n", port_num) );\r
2673                         info = MAX_MCAST;\r
2674                         break;\r
2675         \r
2676                 case OID_802_3_MAC_OPTIONS:\r
2677                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2678                                 ("Port %d received query for OID_802_3_MAC_OPTIONS\n", port_num) );\r
2679                         info = 0;\r
2680                         break;\r
2681         \r
2682                 /* Required Ethernet stats */\r
2683                 case OID_802_3_RCV_ERROR_ALIGNMENT:\r
2684                 case OID_802_3_XMIT_ONE_COLLISION:\r
2685                 case OID_802_3_XMIT_MORE_COLLISIONS:\r
2686                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2687                                 ("Port %d received query for OID_802_3_RCV_ERROR_ALIGNMENT or "\r
2688                                 "OID_802_3_XMIT_ONE_COLLISION or "\r
2689                                 "OID_802_3_XMIT_MORE_COLLISIONS\n", port_num) );\r
2690                         info = 0;\r
2691                         break;\r
2692                 case OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES:\r
2693             buf_len = sizeof(NDIS_OFFLOAD);\r
2694             if (buf_len < oid_info.buf_len)\r
2695             {\r
2696                 *oid_info.p_bytes_needed = buf_len;\r
2697                                 return NDIS_STATUS_BUFFER_TOO_SHORT;\r
2698             }\r
2699 \r
2700             OffloadCapabilities(p_adapter, &offload);\r
2701             src_buf = &offload;\r
2702             break;                      \r
2703                 case OID_GEN_INTERRUPT_MODERATION:\r
2704             InterruptModerationParam.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;\r
2705             InterruptModerationParam.Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;\r
2706             InterruptModerationParam.Header.Size = NDIS_SIZEOF_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;\r
2707             InterruptModerationParam.Flags = NDIS_INTERRUPT_MODERATION_CHANGE_NEEDS_RESET ;\r
2708             InterruptModerationParam.InterruptModeration = NdisInterruptModerationNotSupported ;       \r
2709             buf_len = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);\r
2710             src_buf = (PVOID) &InterruptModerationParam;  \r
2711             break;\r
2712         \r
2713                 /* Optional General */\r
2714                 case OID_GEN_SUPPORTED_GUIDS:\r
2715 #ifdef NDIS51_MINIPORT\r
2716                 case OID_GEN_VLAN_ID:\r
2717 #endif\r
2718         \r
2719                 /* Optional General Stats */\r
2720                 case OID_GEN_RCV_CRC_ERROR:\r
2721                 case OID_GEN_TRANSMIT_QUEUE_LENGTH:\r
2722         \r
2723                 /* Optional Ethernet Stats */\r
2724                 case OID_802_3_XMIT_DEFERRED:\r
2725                 case OID_802_3_XMIT_MAX_COLLISIONS:\r
2726                 case OID_802_3_RCV_OVERRUN:\r
2727                 case OID_802_3_XMIT_UNDERRUN:\r
2728                 case OID_802_3_XMIT_HEARTBEAT_FAILURE:\r
2729                 case OID_802_3_XMIT_TIMES_CRS_LOST:\r
2730                 case OID_802_3_XMIT_LATE_COLLISIONS:\r
2731                 case OID_PNP_CAPABILITIES:\r
2732                         status = NDIS_STATUS_NOT_SUPPORTED;\r
2733                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2734                                 ("Port %d received an unsupported oid of 0x%.8X!\n", port_num, oid_info.oid) );\r
2735                         break;\r
2736         \r
2737                 case OID_GEN_PROTOCOL_OPTIONS:\r
2738                 case OID_GEN_NETWORK_LAYER_ADDRESSES:\r
2739                 case OID_GEN_TRANSPORT_HEADER_OFFSET:\r
2740                 case OID_PNP_ENABLE_WAKE_UP:\r
2741                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2742                                 ("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
2743                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2744                                 ("Number of OID: 0x%.8X!\n", oid_info.oid) );\r
2745                         status = NDIS_STATUS_SUCCESS; \r
2746                         break;\r
2747                         \r
2748                 case OID_PNP_QUERY_POWER:\r
2749                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2750                                 ("Port %d received query for OID_TCP_TASK_OFFLOAD\n", port_num) );\r
2751                         // Status is pre-set in this routine to Success\r
2752                         status = NDIS_STATUS_SUCCESS; \r
2753                         break;\r
2754         \r
2755                 case OID_TCP_OFFLOAD_CURRENT_CONFIG:\r
2756                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2757                                 ("Port %d received query for OID_PNP_QUERY_POWER\n", port_num) );\r
2758                                 //ulBytesAvailable = ulInfoLen = sizeof(NDIS_OFFLOAD);\r
2759                                 if (oid_info.buf_len <  sizeof(NDIS_OFFLOAD))\r
2760                                 {\r
2761                                         \r
2762                                         *oid_info.p_bytes_needed = sizeof(NDIS_OFFLOAD) ;\r
2763                                         return NDIS_STATUS_BUFFER_TOO_SHORT;\r
2764                                 }\r
2765         \r
2766                                 OffloadConfig( p_adapter, &offload);\r
2767                                 src_buf = &offload;\r
2768                                 break;\r
2769         \r
2770                 default:\r
2771                         status = NDIS_STATUS_INVALID_OID;\r
2772                         IPOIB_PRINT( TRACE_LEVEL_ERROR,IPOIB_DBG_ERROR,\r
2773                                 ("Port %d received an invalid oid of 0x%.8X!\n", port_num, oid_info.oid) );\r
2774                         break;\r
2775                 }\r
2776         \r
2777                 /*\r
2778                  * Complete the request as if it was handled asynchronously to maximize\r
2779                  * code reuse for when we really handle the requests asynchronously.\r
2780                  * Note that this requires the QueryInformation entry point to always\r
2781                  * return NDIS_STATUS_PENDING\r
2782                  */\r
2783                 if( status != NDIS_STATUS_PENDING )\r
2784                 {\r
2785                         return ipoib_complete_query(\r
2786                                 p_adapter, &oid_info, status, src_buf, buf_len );\r
2787                 }\r
2788         \r
2789                 IPOIB_EXIT( IPOIB_DBG_OID );\r
2790                 return NDIS_STATUS_PENDING;\r
2791         }\r
2792         \r
2793 \r
2794 static NDIS_STATUS\r
2795 ipoib_complete_query(\r
2796         IN                              ipoib_adapter_t* const          p_adapter,\r
2797         IN                              pending_oid_t* const            p_oid_info,\r
2798         IN              const   NDIS_STATUS                                     status,\r
2799         IN              const   void* const                                     p_buf,\r
2800         IN              const   ULONG                                           buf_len )\r
2801 {\r
2802         NDIS_STATUS             oid_status = status;\r
2803 \r
2804         IPOIB_ENTER( IPOIB_DBG_OID );\r
2805 \r
2806         CL_ASSERT( status != NDIS_STATUS_PENDING );\r
2807 \r
2808         if( status == NDIS_STATUS_SUCCESS )\r
2809         {\r
2810                 if( p_oid_info->buf_len < buf_len )\r
2811                 {\r
2812                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2813                                 ("Insufficient buffer space.  "\r
2814                                 "Returning NDIS_STATUS_INVALID_LENGTH.\n") );\r
2815                         //oid_status = NDIS_STATUS_INVALID_LENGTH;\r
2816                         oid_status = NDIS_STATUS_BUFFER_TOO_SHORT;\r
2817                         *p_oid_info->p_bytes_needed = buf_len;\r
2818                         *p_oid_info->p_bytes_used = 0;\r
2819                 }\r
2820                 else if( p_oid_info->p_buf )\r
2821                 {\r
2822                         /* Only copy if we have a distinct source buffer. */\r
2823                         if( p_buf )\r
2824                         {\r
2825                                 NdisMoveMemory( p_oid_info->p_buf, p_buf, buf_len );\r
2826                                 *p_oid_info->p_bytes_used = buf_len;\r
2827                         }\r
2828                 }\r
2829                 else\r
2830                 {\r
2831                         IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
2832                                 ("Returning NDIS_NOT_ACCEPTED") );\r
2833                         oid_status = NDIS_STATUS_NOT_ACCEPTED;\r
2834                 }\r
2835         }\r
2836         else\r
2837         {\r
2838                 *p_oid_info->p_bytes_used = 0;\r
2839         }\r
2840 \r
2841         if (p_adapter->query_oid.p_pending_oid)\r
2842         {\r
2843                 NdisMOidRequestComplete(p_adapter->h_adapter,p_adapter->query_oid.p_pending_oid,oid_status); \r
2844                 p_adapter->query_oid.p_pending_oid = NULL;\r
2845         }\r
2846         p_adapter->pending_query = FALSE;\r
2847         IPOIB_EXIT( IPOIB_DBG_OID );\r
2848         return oid_status;\r
2849 \r
2850         \r
2851 }\r
2852 \r
2853 static\r
2854 NDIS_STATUS \r
2855 SetOffloadEncapsulation(\r
2856     void* const pBuf,\r
2857     ULONG len \r
2858     )\r
2859 {\r
2860     ASSERT(pBuf != NULL);\r
2861     \r
2862     PNDIS_OFFLOAD_ENCAPSULATION pOffload;\r
2863     PNDIS_OBJECT_HEADER pOffloadHeader;\r
2864 \r
2865     if (len != sizeof(NDIS_OFFLOAD_ENCAPSULATION))\r
2866     {\r
2867         ASSERT(FALSE);\r
2868         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
2869         return  NDIS_STATUS_INVALID_DATA;\r
2870     } \r
2871 \r
2872     pOffload= (PNDIS_OFFLOAD_ENCAPSULATION) pBuf;\r
2873     pOffloadHeader = &(pOffload->Header);\r
2874 \r
2875     if((pOffloadHeader->Type != NDIS_OBJECT_TYPE_OFFLOAD_ENCAPSULATION) ||\r
2876        (pOffloadHeader->Revision != NDIS_OFFLOAD_ENCAPSULATION_REVISION_1) ||\r
2877        (pOffloadHeader->Size != NDIS_SIZEOF_OFFLOAD_ENCAPSULATION_REVISION_1))\r
2878     {       \r
2879         ASSERT(FALSE);\r
2880         IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_OID, ("Set offloading task Illegal header\n"));\r
2881         return NDIS_STATUS_INVALID_DATA;\r
2882     }\r
2883 \r
2884     //\r
2885     // BUGBUG: Need to handle the offload parameter setting\r
2886     //\r
2887     return NDIS_STATUS_SUCCESS;\r
2888 }\r
2889 \r
2890 \r
2891 //! Issues a hardware reset to the NIC and/or resets the driver's software state.\r
2892 /*  Tear down the connection and start over again.  This is only called when there is a problem.\r
2893 For example, if a send, query info, or set info had a time out.  MiniportCheckForHang will\r
2894 be called first.\r
2895 IRQL = DISPATCH_LEVEL\r
2896 \r
2897 @param p_addr_resetPointer to BOOLLEAN that is set to TRUE if the NDIS\r
2898 library should call MiniportSetInformation to restore addressing information to the current values.\r
2899 @param adapter_context The adapter context allocated at start\r
2900 @return NDIS_STATUS_SUCCESS, NDIS_STATUS_PENDING, NDIS_STATUS_NOT_RESETTABLE,\r
2901 NDIS_STATUS_RESET_IN_PROGRESS, NDIS_STATUS_SOFT_ERRORS, NDIS_STATUS_HARD_ERRORS\r
2902 */\r
2903 NDIS_STATUS\r
2904 ipoib_reset(\r
2905     IN  NDIS_HANDLE     adapter_context,\r
2906     OUT PBOOLEAN        p_addr_reset)\r
2907 {\r
2908         ipoib_adapter_t* p_adapter;\r
2909 \r
2910         IPOIB_ENTER( IPOIB_DBG_INIT );\r
2911         CL_ASSERT( p_addr_reset );\r
2912         CL_ASSERT( adapter_context );\r
2913         p_adapter = (ipoib_adapter_t*)adapter_context;\r
2914 \r
2915         switch( ipoib_reset_adapter( p_adapter ) )\r
2916         {\r
2917         case IB_NOT_DONE:\r
2918                 IPOIB_EXIT( IPOIB_DBG_INIT );\r
2919                 return NDIS_STATUS_PENDING;\r
2920 \r
2921         case IB_SUCCESS:\r
2922                 IPOIB_EXIT( IPOIB_DBG_INIT );\r
2923                 *p_addr_reset = TRUE;\r
2924                 return NDIS_STATUS_SUCCESS;\r
2925 \r
2926         case IB_INVALID_STATE:\r
2927                 IPOIB_EXIT( IPOIB_DBG_INIT );\r
2928                 return NDIS_STATUS_RESET_IN_PROGRESS;\r
2929 \r
2930         default:\r
2931                 IPOIB_EXIT( IPOIB_DBG_INIT );\r
2932                 return NDIS_STATUS_HARD_ERRORS;\r
2933         }\r
2934 }\r
2935 \r
2936 \r
2937 //! Request changes in the state information that the miniport driver maintains\r
2938 /*  For example, this is used to set multicast addresses and the packet filter.\r
2939 IRQL = DISPATCH_LEVEL\r
2940 \r
2941 @param adapter_context The adapter context allocated at start\r
2942 @param oid Object ID representing the set operation to be carried out\r
2943 @param info_buf Buffer containing input for this set and location for any output\r
2944 @param info_buf_len Number of bytes available in info_buf\r
2945 @param p_bytes_read Pointer to number of bytes read from info_buf\r
2946 @param p_bytes_needed Pointer to number of bytes needed to satisfy this oid\r
2947 @return NDIS_STATUS_SUCCESS, NDIS_STATUS_PENDING, NDIS_STATUS_INVALID_OID,\r
2948 NDIS_STATUS_INVALID_LENGTH, NDIS_STATUS_INVALID_DATA, NDIS_STATUS_NOT_ACCEPTED,\r
2949 NDIS_STATUS_NOT_SUPPORTED, NDIS_STATUS_RESOURCES\r
2950 */\r
2951 NDIS_STATUS\r
2952 ipoib_set_info(\r
2953     IN          NDIS_HANDLE         adapter_context,\r
2954     IN  OUT PNDIS_OID_REQUEST   pNdisRequest)\r
2955 \r
2956 {\r
2957         ipoib_adapter_t*        p_adapter;\r
2958         NDIS_STATUS                     status;\r
2959 \r
2960         ULONG                           buf_len;\r
2961         uint8_t                         port_num;\r
2962 \r
2963         KLOCK_QUEUE_HANDLE      hdl;\r
2964         \r
2965         IPOIB_ENTER( IPOIB_DBG_OID );\r
2966 \r
2967         CL_ASSERT( adapter_context );\r
2968         p_adapter = (ipoib_adapter_t*)adapter_context;\r
2969 \r
2970         NDIS_OID    oid = pNdisRequest->DATA.SET_INFORMATION.Oid;\r
2971         PVOID       info_buf = pNdisRequest->DATA.SET_INFORMATION.InformationBuffer;\r
2972         UINT        info_buf_len = pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength;\r
2973         PULONG          p_bytes_read = (PULONG)&pNdisRequest->DATA.SET_INFORMATION.BytesRead;\r
2974         PULONG          p_bytes_needed = (PULONG)&pNdisRequest->DATA.SET_INFORMATION.BytesNeeded;\r
2975         \r
2976         CL_ASSERT( p_bytes_read );\r
2977         CL_ASSERT( p_bytes_needed );\r
2978         CL_ASSERT( !p_adapter->pending_set );\r
2979 \r
2980         status = NDIS_STATUS_SUCCESS;\r
2981         *p_bytes_needed = 0;\r
2982         buf_len = sizeof(ULONG);\r
2983 \r
2984         port_num = p_adapter->guids.port_num;\r
2985         \r
2986         cl_obj_lock( &p_adapter->obj );\r
2987 \r
2988         if( p_adapter->state == IB_PNP_PORT_REMOVE )\r
2989         {\r
2990                 *p_bytes_read = 0;\r
2991                 cl_obj_unlock( &p_adapter->obj );\r
2992                 return NDIS_STATUS_NOT_ACCEPTED;\r
2993         }\r
2994 \r
2995         cl_obj_unlock( &p_adapter->obj );\r
2996 \r
2997         switch( oid )\r
2998         {\r
2999         /* Required General */\r
3000         case OID_GEN_CURRENT_PACKET_FILTER:\r
3001                 IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
3002                         ("Port %d received set for OID_GEN_CURRENT_PACKET_FILTER\n", port_num));\r
3003                 if( info_buf_len < sizeof(p_adapter->packet_filter) )\r
3004                 {\r
3005                         status = NDIS_STATUS_INVALID_LENGTH;\r
3006                 }\r
3007                 else if( !info_buf )\r
3008                 {\r
3009                         status = NDIS_STATUS_INVALID_DATA;\r
3010                 }\r
3011                 else\r
3012                 {\r
3013                         KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
3014                         cl_obj_lock( &p_adapter->obj );\r
3015                         switch( p_adapter->state )\r
3016                         {\r
3017                         case IB_PNP_PORT_ADD:\r
3018                                 p_adapter->set_oid.oid = oid;\r
3019                                 p_adapter->set_oid.p_buf = info_buf;\r
3020                                 p_adapter->set_oid.buf_len = info_buf_len;\r
3021                                 p_adapter->set_oid.p_bytes_used = p_bytes_read;\r
3022                                 p_adapter->set_oid.p_bytes_needed = p_bytes_needed;\r
3023                                 p_adapter->set_oid.p_pending_oid = pNdisRequest;\r
3024                                 p_adapter->pending_set = TRUE;\r
3025                                 status = NDIS_STATUS_PENDING;\r
3026                                 break;\r
3027 \r
3028                         case IB_PNP_PORT_REMOVE:\r
3029                                 status = NDIS_STATUS_NOT_ACCEPTED;\r
3030                                 break;\r
3031 \r
3032                         default:\r
3033                                 if( !p_adapter->packet_filter && (*(uint32_t*)info_buf) )\r
3034                                 {\r
3035                                         cl_qlist_insert_tail(\r
3036                                                 &g_ipoib.adapter_list, &p_adapter->entry );\r
3037 \r
3038                                         /*\r
3039                                          * Filter was zero, now non-zero.  Register IP addresses\r
3040                                          * with SA.\r
3041                                          */\r
3042                                         ipoib_reg_addrs( p_adapter );\r
3043                                 }\r
3044                                 else if( p_adapter->packet_filter && !(*(uint32_t*)info_buf) )\r
3045                                 {\r
3046                                         /*\r
3047                                          * Filter was non-zero, now zero.  Deregister IP addresses.\r
3048                                          */\r
3049                                         ipoib_dereg_addrs( p_adapter );\r
3050 \r