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