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