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