2 * Copyright (c) 2005 SilverStorm Technologies. All rights reserved.
\r
4 * This software is available to you under the OpenIB.org BSD license
\r
7 * Redistribution and use in source and binary forms, with or
\r
8 * without modification, are permitted provided that the following
\r
9 * conditions are met:
\r
11 * - Redistributions of source code must retain the above
\r
12 * copyright notice, this list of conditions and the following
\r
15 * - Redistributions in binary form must reproduce the above
\r
16 * copyright notice, this list of conditions and the following
\r
17 * disclaimer in the documentation and/or other materials
\r
18 * provided with the distribution.
\r
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
\r
24 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
\r
25 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\r
33 #include "ipoib_driver.h"
\r
34 #include "ipoib_debug.h"
\r
35 #include "ipoib_port.h"
\r
36 #include <complib/cl_bus_ifc.h>
\r
37 #include <initguid.h>
\r
38 #include <iba/ipoib_ifc.h>
\r
41 /* Default parameters values for optional parameters */
\r
42 #define DEF_WSDP_ENABLED FALSE
\r
43 #define DEF_STATIC_LID 0
\r
44 #define DEF_RECV_GROWTH 0
\r
47 #if defined(NDIS50_MINIPORT)
\r
48 #define MAJOR_NDIS_VERSION 5
\r
49 #define MINOR_NDIS_VERSION 0
\r
50 #elif defined (NDIS51_MINIPORT)
\r
51 #define MAJOR_NDIS_VERSION 5
\r
52 #define MINOR_NDIS_VERSION 1
\r
54 #error NDIS Version not defined, try defining NDIS50_MINIPORT or NDIS51_MINIPORT
\r
57 static const NDIS_OID SUPPORTED_OIDS[] =
\r
59 OID_GEN_SUPPORTED_LIST,
\r
60 OID_GEN_HARDWARE_STATUS,
\r
61 OID_GEN_MEDIA_SUPPORTED,
\r
62 OID_GEN_MEDIA_IN_USE,
\r
63 OID_GEN_MAXIMUM_LOOKAHEAD,
\r
64 OID_GEN_MAXIMUM_FRAME_SIZE,
\r
66 OID_GEN_TRANSMIT_BUFFER_SPACE,
\r
67 OID_GEN_RECEIVE_BUFFER_SPACE,
\r
68 OID_GEN_TRANSMIT_BLOCK_SIZE,
\r
69 OID_GEN_RECEIVE_BLOCK_SIZE,
\r
71 OID_GEN_VENDOR_DESCRIPTION,
\r
72 OID_GEN_CURRENT_PACKET_FILTER,
\r
73 OID_GEN_CURRENT_LOOKAHEAD,
\r
74 OID_GEN_DRIVER_VERSION,
\r
75 OID_GEN_MAXIMUM_TOTAL_SIZE,
\r
76 OID_GEN_PROTOCOL_OPTIONS,
\r
77 OID_GEN_MAC_OPTIONS,
\r
78 OID_GEN_MEDIA_CONNECT_STATUS,
\r
79 OID_GEN_MAXIMUM_SEND_PACKETS,
\r
80 OID_GEN_NETWORK_LAYER_ADDRESSES,
\r
81 OID_GEN_VENDOR_DRIVER_VERSION,
\r
82 OID_GEN_PHYSICAL_MEDIUM,
\r
87 OID_GEN_RCV_NO_BUFFER,
\r
88 OID_GEN_DIRECTED_BYTES_XMIT,
\r
89 OID_GEN_DIRECTED_FRAMES_XMIT,
\r
90 OID_GEN_MULTICAST_BYTES_XMIT,
\r
91 OID_GEN_MULTICAST_FRAMES_XMIT,
\r
92 OID_GEN_BROADCAST_BYTES_XMIT,
\r
93 OID_GEN_BROADCAST_FRAMES_XMIT,
\r
94 OID_GEN_DIRECTED_BYTES_RCV,
\r
95 OID_GEN_DIRECTED_FRAMES_RCV,
\r
96 OID_GEN_MULTICAST_BYTES_RCV,
\r
97 OID_GEN_MULTICAST_FRAMES_RCV,
\r
98 OID_GEN_BROADCAST_BYTES_RCV,
\r
99 OID_GEN_BROADCAST_FRAMES_RCV,
\r
100 OID_802_3_PERMANENT_ADDRESS,
\r
101 OID_802_3_CURRENT_ADDRESS,
\r
102 OID_802_3_MULTICAST_LIST,
\r
103 OID_802_3_MAXIMUM_LIST_SIZE,
\r
104 OID_802_3_MAC_OPTIONS,
\r
105 OID_802_3_RCV_ERROR_ALIGNMENT,
\r
106 OID_802_3_XMIT_ONE_COLLISION,
\r
107 OID_802_3_XMIT_MORE_COLLISIONS,
\r
108 OID_TCP_TASK_OFFLOAD
\r
111 static const unsigned char VENDOR_ID[] = {0x00, 0x06, 0x6A, 0x00};
\r
113 #define VENDOR_DESCRIPTION "Internet Protocol over InfiniBand"
\r
115 #define IB_INFINITE_SERVICE_LEASE 0xFFFFFFFF
\r
117 #define DEFAULT_SA_TIMEOUT 250
\r
118 #define DEFAULT_SA_RETRIES 3
\r
121 /* Global driver debug level */
\r
122 uint32_t g_ipoib_dbg_lvl = IPOIB_DBG_ERROR;
\r
127 IN PDRIVER_OBJECT p_drv_obj,
\r
128 IN PUNICODE_STRING p_reg_path );
\r
132 OUT PNDIS_STATUS p_open_err_status,
\r
133 OUT PUINT p_selected_medium_index,
\r
134 IN PNDIS_MEDIUM medium_array,
\r
135 IN UINT medium_array_size,
\r
136 IN NDIS_HANDLE h_adapter,
\r
137 IN NDIS_HANDLE wrapper_configuration_context );
\r
140 ipoib_check_for_hang(
\r
141 IN NDIS_HANDLE adapter_context );
\r
145 IN NDIS_HANDLE adapter_context );
\r
149 IN NDIS_HANDLE adapter_context,
\r
152 IN ULONG info_buf_len,
\r
153 OUT PULONG p_bytes_written,
\r
154 OUT PULONG p_bytes_needed );
\r
158 OUT PBOOLEAN p_addressing_reset,
\r
159 IN NDIS_HANDLE adapter_context );
\r
163 IN NDIS_HANDLE adapter_context,
\r
166 IN ULONG info_buf_length,
\r
167 OUT PULONG p_bytes_read,
\r
168 OUT PULONG p_bytes_needed );
\r
171 ipoib_send_packets(
\r
172 IN NDIS_HANDLE adapter_context,
\r
173 IN PPNDIS_PACKET packet_array,
\r
174 IN UINT num_packets );
\r
178 IN NDIS_HANDLE adapter_context,
\r
179 IN NDIS_DEVICE_PNP_EVENT pnp_event,
\r
181 IN ULONG info_buf_len );
\r
185 IN PVOID adapter_context );
\r
188 ipoib_complete_query(
\r
189 IN ipoib_adapter_t* const p_adapter,
\r
190 IN pending_oid_t* const p_oid_info,
\r
191 IN const NDIS_STATUS status,
\r
192 IN const void* const p_buf,
\r
193 IN const ULONG buf_len );
\r
196 __ipoib_set_net_addr(
\r
197 IN ipoib_adapter_t * p_adapter,
\r
199 IN ULONG info_buf_len,
\r
200 OUT PULONG p_bytes_read,
\r
201 OUT PULONG p_bytes_needed );
\r
204 __ipoib_get_tcp_task_offload(
\r
205 IN ipoib_adapter_t* p_adapter,
\r
206 IN pending_oid_t* const p_oid_info );
\r
209 __ipoib_ats_reg_cb(
\r
210 IN ib_reg_svc_rec_t *p_reg_svc_rec );
\r
213 __ipoib_ats_unreg_cb(
\r
214 IN void *context );
\r
217 __ipoib_dereg_addrs(
\r
218 IN ipoib_adapter_t* const p_adapter );
\r
221 //! Standard Windows Device Driver Entry Point
\r
222 /*! DriverEntry is the first routine called after a driver is loaded, and
\r
223 is responsible for initializing the driver. On W2k this occurs when the PnP
\r
224 Manager matched a PnP ID to one in an INF file that references this driver.
\r
225 Any not success return value will cause the driver to fail to load.
\r
226 IRQL = PASSIVE_LEVEL
\r
228 @param p_drv_obj Pointer to Driver Object for this device driver
\r
229 @param p_registry_path Pointer to unicode string containing path to this driver's registry area
\r
230 @return STATUS_SUCCESS, NDIS_STATUS_BAD_CHARACTERISTICS, NDIS_STATUS_BAD_VERSION,
\r
231 NDIS_STATUS_RESOURCES, or NDIS_STATUS_FAILURE
\r
235 IN PDRIVER_OBJECT p_drv_obj,
\r
236 IN PUNICODE_STRING p_registry_path )
\r
238 NDIS_STATUS status;
\r
239 NDIS_HANDLE ndis_handle;
\r
240 NDIS_MINIPORT_CHARACTERISTICS characteristics;
\r
242 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
248 status = NDIS_STATUS_SUCCESS;
\r
249 ndis_handle = NULL;
\r
251 NdisMInitializeWrapper( &ndis_handle, p_drv_obj, p_registry_path, NULL );
\r
253 memset(&characteristics, 0, sizeof(characteristics));
\r
254 characteristics.MajorNdisVersion = MAJOR_NDIS_VERSION;
\r
255 characteristics.MinorNdisVersion = MINOR_NDIS_VERSION;
\r
256 characteristics.CheckForHangHandler = ipoib_check_for_hang;
\r
257 characteristics.HaltHandler = ipoib_halt;
\r
258 characteristics.InitializeHandler = ipoib_initialize;
\r
259 characteristics.QueryInformationHandler = ipoib_query_info;
\r
260 characteristics.ResetHandler = ipoib_reset;
\r
261 characteristics.SetInformationHandler = ipoib_set_info;
\r
263 characteristics.ReturnPacketHandler = ipoib_return_packet;
\r
264 characteristics.SendPacketsHandler = ipoib_send_packets;
\r
266 #ifdef NDIS51_MINIPORT
\r
267 characteristics.PnPEventNotifyHandler = ipoib_pnp_notify;
\r
268 characteristics.AdapterShutdownHandler = ipoib_shutdown;
\r
271 status = NdisMRegisterMiniport(
\r
272 ndis_handle, &characteristics, sizeof(characteristics) );
\r
273 if( status != NDIS_STATUS_SUCCESS )
\r
275 IPOIB_TRACE( IPOIB_DBG_ERROR,
\r
276 ("NdisMRegisterMiniport failed with status of %s", status) );
\r
277 NdisTerminateWrapper( ndis_handle, NULL );
\r
280 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
286 ipoib_get_adapter_params(
\r
287 IN NDIS_HANDLE* const wrapper_config_context,
\r
288 OUT ipoib_params_t* const p_params )
\r
290 NDIS_STATUS status;
\r
291 NDIS_HANDLE h_config;
\r
292 NDIS_CONFIGURATION_PARAMETER *p_param;
\r
293 NDIS_STRING keyword;
\r
295 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
297 NdisOpenConfiguration( &status, &h_config, wrapper_config_context );
\r
298 if( status != NDIS_STATUS_SUCCESS )
\r
300 IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR,
\r
301 ("NdisOpenConfiguration returned 0x%.8x\n", status) );
\r
305 /* Required: Receive queue depth. */
\r
306 RtlInitUnicodeString( &keyword, L"RqDepth" );
\r
307 NdisReadConfiguration(
\r
308 &status, &p_param, h_config, &keyword, NdisParameterInteger );
\r
309 if( status != NDIS_STATUS_SUCCESS )
\r
311 IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR,
\r
312 ("Receive Queue Depth parameter missing.\n") );
\r
315 p_params->rq_depth = p_param->ParameterData.IntegerData;
\r
317 /* Required: Send queue depth. */
\r
318 RtlInitUnicodeString( &keyword, L"SqDepth" );
\r
319 NdisReadConfiguration(
\r
320 &status, &p_param, h_config, &keyword, NdisParameterInteger );
\r
321 if( status != NDIS_STATUS_SUCCESS )
\r
323 IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR,
\r
324 ("Send Queue Depth parameter missing.\n") );
\r
327 p_params->sq_depth = p_param->ParameterData.IntegerData;
\r
328 /* Send queue depth needs to be a power of two. */
\r
329 if( p_params->sq_depth <= 128 )
\r
330 p_params->sq_depth = 128;
\r
331 else if( p_params->sq_depth <= 256 )
\r
332 p_params->sq_depth = 256;
\r
333 else if( p_params->sq_depth <= 512 )
\r
334 p_params->sq_depth = 512;
\r
336 p_params->sq_depth = 1024;
\r
338 /* Required: Send Checksum Offload. */
\r
339 RtlInitUnicodeString( &keyword, L"SendChksum" );
\r
340 NdisReadConfiguration(
\r
341 &status, &p_param, h_config, &keyword, NdisParameterInteger );
\r
342 if( status != NDIS_STATUS_SUCCESS )
\r
344 IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR,
\r
345 ("Send Checksum Offload parameter missing.\n") );
\r
348 p_params->send_chksum_offload = (p_param->ParameterData.IntegerData != 0);
\r
350 /* Optional: WSDP support. */
\r
351 RtlInitUnicodeString( &keyword, L"WsdpEnabled" );
\r
352 NdisReadConfiguration(
\r
353 &status, &p_param, h_config, &keyword, NdisParameterInteger );
\r
354 if( status != NDIS_STATUS_SUCCESS )
\r
355 p_params->wsdp_enabled = DEF_WSDP_ENABLED;
\r
357 p_params->wsdp_enabled = (p_param->ParameterData.IntegerData != 0);
\r
359 /* Optional: Static LID assignment if SM is not up. */
\r
360 RtlInitUnicodeString( &keyword, L"StaticLid" );
\r
361 NdisReadConfiguration(
\r
362 &status, &p_param, h_config, &keyword, NdisParameterInteger );
\r
363 if( status != NDIS_STATUS_SUCCESS )
\r
364 p_params->static_lid = DEF_STATIC_LID;
\r
366 p_params->static_lid = (uint16_t)p_param->ParameterData.IntegerData;
\r
368 /* Required: SA query timeout, in milliseconds. */
\r
369 RtlInitUnicodeString( &keyword, L"SaTimeout" );
\r
370 NdisReadConfiguration(
\r
371 &status, &p_param, h_config, &keyword, NdisParameterInteger );
\r
372 if( status != NDIS_STATUS_SUCCESS )
\r
374 IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR,
\r
375 ("SA query timeout parameter missing.\n") );
\r
378 p_params->sa_timeout = p_param->ParameterData.IntegerData;
\r
380 /* Required: SA query retry count. */
\r
381 RtlInitUnicodeString( &keyword, L"SaRetries" );
\r
382 NdisReadConfiguration(
\r
383 &status, &p_param, h_config, &keyword, NdisParameterInteger );
\r
384 if( status != NDIS_STATUS_SUCCESS )
\r
386 IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR,
\r
387 ("SA query retry count parameter missing.\n") );
\r
390 p_params->sa_retry_cnt = p_param->ParameterData.IntegerData;
\r
392 /* Required: Receive pool to queue depth ratio. */
\r
393 RtlInitUnicodeString( &keyword, L"RecvRatio" );
\r
394 NdisReadConfiguration(
\r
395 &status, &p_param, h_config, &keyword, NdisParameterInteger );
\r
396 if( status != NDIS_STATUS_SUCCESS )
\r
398 IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR,
\r
399 ("Receive pool to queue depth ratio parameter missing.\n") );
\r
402 p_params->recv_pool_ratio = p_param->ParameterData.IntegerData;
\r
404 /* Required: Receive pool growth threshold. */
\r
405 RtlInitUnicodeString( &keyword, L"RecvGrowth" );
\r
406 NdisReadConfiguration(
\r
407 &status, &p_param, h_config, &keyword, NdisParameterInteger );
\r
408 if( status != NDIS_STATUS_SUCCESS )
\r
409 p_params->recv_growth = DEF_RECV_GROWTH;
\r
411 p_params->recv_growth = (p_param->ParameterData.IntegerData != 0);
\r
413 NdisCloseConfiguration( h_config );
\r
415 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
416 return NDIS_STATUS_SUCCESS;
\r
421 ipoib_get_adapter_guids(
\r
422 IN NDIS_HANDLE* const h_adapter,
\r
423 IN OUT ipoib_adapter_t *p_adapter )
\r
426 ib_al_ifc_data_t data;
\r
427 IO_STACK_LOCATION io_stack;
\r
428 DEVICE_OBJECT *p_pdo;
\r
430 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
432 NdisMGetDeviceProperty( h_adapter, &p_pdo, NULL, NULL, NULL, NULL );
\r
434 /* Query for our interface */
\r
435 data.size = sizeof(ipoib_ifc_data_t);
\r
436 data.version = IPOIB_INTERFACE_DATA_VERSION;
\r
437 data.type = &GUID_IPOIB_INTERFACE_DATA;
\r
438 data.p_data = &p_adapter->guids;
\r
440 io_stack.MinorFunction = IRP_MN_QUERY_INTERFACE;
\r
441 io_stack.Parameters.QueryInterface.Version = AL_INTERFACE_VERSION;
\r
442 io_stack.Parameters.QueryInterface.Size = sizeof(ib_al_ifc_t);
\r
443 io_stack.Parameters.QueryInterface.Interface =
\r
444 (INTERFACE*)p_adapter->p_ifc;
\r
445 io_stack.Parameters.QueryInterface.InterfaceSpecificData = &data;
\r
446 io_stack.Parameters.QueryInterface.InterfaceType =
\r
447 &GUID_IB_AL_INTERFACE;
\r
449 status = cl_fwd_query_ifc( p_pdo, &io_stack );
\r
450 if( !NT_SUCCESS( status ) )
\r
452 IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR,
\r
453 ("Query interface for IPOIB interface returned %08x.\n", status) );
\r
458 * Dereference the interface now so that the bus driver doesn't fail a
\r
459 * query remove IRP. We will always get unloaded before the bus driver
\r
460 * since we're a child device.
\r
462 p_adapter->p_ifc->wdm.InterfaceDereference(
\r
463 p_adapter->p_ifc->wdm.Context );
\r
464 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
465 return NDIS_STATUS_SUCCESS;
\r
469 //! Initialization function called for each IOC discovered
\r
470 /* The MiniportInitialize function is a required function that sets up a
\r
471 NIC (or virtual NIC) for network I/O operations, claims all hardware
\r
472 resources necessary to the NIC in the registry, and allocates resources
\r
473 the driver needs to carry out network I/O operations.
\r
474 IRQL = PASSIVE_LEVEL
\r
476 @param p_open_status Pointer to a status field set if this function returns NDIS_STATUS_OPEN_ERROR
\r
477 @param p_selected_medium_index Pointer to unsigned integer noting index into medium_array for this NIC
\r
478 @param medium_array Array of mediums for this NIC
\r
479 @param medium_array_size Number of elements in medium_array
\r
480 @param h_adapter Handle assigned by NDIS for this NIC
\r
481 @param wrapper_config_context Handle used for Ndis initialization functions
\r
482 @return NDIS_STATUS_SUCCESS, NDIS_STATUS_UNSUPPORTED_MEDIA, NDIS_STATUS_RESOURCES,
\r
483 NDIS_STATUS_NOT_SUPPORTED
\r
487 OUT PNDIS_STATUS p_open_status,
\r
488 OUT PUINT p_selected_medium_index,
\r
489 IN PNDIS_MEDIUM medium_array,
\r
490 IN UINT medium_array_size,
\r
491 IN NDIS_HANDLE h_adapter,
\r
492 IN NDIS_HANDLE wrapper_config_context )
\r
494 NDIS_STATUS status;
\r
495 ib_api_status_t ib_status;
\r
497 ipoib_adapter_t *p_adapter;
\r
499 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
505 UNUSED_PARAM( p_open_status );
\r
506 UNUSED_PARAM( wrapper_config_context );
\r
508 /* Search for our medium */
\r
509 for( medium_index = 0; medium_index < medium_array_size; ++medium_index )
\r
511 /* Check to see if we found our medium */
\r
512 if( medium_array[medium_index] == NdisMedium802_3 )
\r
516 if( medium_index == medium_array_size ) /* Never found it */
\r
518 IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("No supported media.\n") );
\r
519 return NDIS_STATUS_UNSUPPORTED_MEDIA;
\r
522 *p_selected_medium_index = medium_index;
\r
525 /* Create the adapter adapter */
\r
526 ib_status = ipoib_create_adapter( wrapper_config_context, h_adapter, &p_adapter );
\r
527 if( ib_status != IB_SUCCESS )
\r
529 IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR,
\r
530 ("ipoib_create_adapter returned status %d.\n", ib_status ) );
\r
531 return NDIS_STATUS_FAILURE;
\r
534 /* Allow ten seconds for all SA queries to finish up. */
\r
535 NdisMSetAttributesEx( h_adapter, p_adapter, 5,
\r
536 NDIS_ATTRIBUTE_BUS_MASTER | NDIS_ATTRIBUTE_DESERIALIZE |
\r
537 NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS,
\r
538 NdisInterfacePNPBus );
\r
542 NdisMInitializeScatterGatherDma( h_adapter, TRUE, XFER_BLOCK_SIZE );
\r
543 if( status != NDIS_STATUS_SUCCESS )
\r
545 ipoib_destroy_adapter( p_adapter );
\r
546 IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR,
\r
547 ("NdisMInitializeScatterGatherDma returned 0x%.8x.\n", status) );
\r
552 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
557 //! Deallocates resources when the NIC is removed and halts the NIC..
\r
558 /* IRQL = DISPATCH_LEVEL
\r
560 @param adapter_context The adapter context allocated at start
\r
564 IN NDIS_HANDLE adapter_context )
\r
566 ipoib_adapter_t *p_adapter;
\r
568 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
570 CL_ASSERT( adapter_context );
\r
571 p_adapter = (ipoib_adapter_t*)adapter_context;
\r
573 IPOIB_TRACE( IPOIB_DBG_INFO,
\r
574 ("Port %d halting\n", IPOIB_ADAPTER_GET_PORT_NUM(p_adapter)) );
\r
576 ipoib_destroy_adapter( p_adapter );
\r
578 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
582 //! Reports the state of the NIC, or monitors the responsiveness of an underlying device driver.
\r
583 /* IRQL = DISPATCH_LEVEL
\r
585 @param adapter_context The adapter context allocated at start
\r
586 @return TRUE if the driver determines that its NIC is not operating
\r
589 ipoib_check_for_hang(
\r
590 IN NDIS_HANDLE adapter_context )
\r
592 ipoib_adapter_t *p_adapter;
\r
594 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
595 CL_ASSERT( adapter_context );
\r
596 p_adapter = (ipoib_adapter_t*)adapter_context;
\r
597 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
598 return (p_adapter->hung? TRUE:FALSE);
\r
602 //! Returns information about the capabilities and status of the driver and/or its NIC.
\r
603 /* IRQL = DISPATCH_LEVEL
\r
605 @param adapter_context The adapter context allocated at start
\r
606 @param oid Object ID representing the query operation to be carried out
\r
607 @param info_buf Buffer containing any input for this query and location for output
\r
608 @param info_buf_len Number of bytes available in info_buf
\r
609 @param p_bytes_written Pointer to number of bytes written into info_buf
\r
610 @param p_bytes_needed Pointer to number of bytes needed to satisfy this oid
\r
611 @return NDIS_STATUS_SUCCESS, NDIS_STATUS_PENDING, NDIS_STATUS_INVALID_OID,
\r
612 NDIS_STATUS_INVALID_LENGTH, NDIS_STATUS_NOT_ACCEPTED, NDIS_STATUS_NOT_SUPPORTED,
\r
613 NDIS_STATUS_RESOURCES
\r
617 IN NDIS_HANDLE adapter_context,
\r
620 IN ULONG info_buf_len,
\r
621 OUT PULONG p_bytes_written,
\r
622 OUT PULONG p_bytes_needed )
\r
624 ipoib_adapter_t *p_adapter;
\r
625 NDIS_STATUS status;
\r
630 pending_oid_t oid_info;
\r
633 IPOIB_ENTER( IPOIB_DBG_OID );
\r
635 oid_info.oid = oid;
\r
636 oid_info.p_buf = info_buf;
\r
637 oid_info.buf_len = info_buf_len;
\r
638 oid_info.p_bytes_used = p_bytes_written;
\r
639 oid_info.p_bytes_needed = p_bytes_needed;
\r
641 CL_ASSERT( adapter_context );
\r
642 p_adapter = (ipoib_adapter_t*)adapter_context;
\r
644 CL_ASSERT( p_bytes_written );
\r
645 CL_ASSERT( p_bytes_needed );
\r
646 CL_ASSERT( !p_adapter->pending_query );
\r
648 status = NDIS_STATUS_SUCCESS;
\r
650 buf_len = sizeof(info);
\r
652 port_num = IPOIB_ADAPTER_GET_PORT_NUM(p_adapter);
\r
656 /* Required General */
\r
657 case OID_GEN_SUPPORTED_LIST:
\r
658 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
659 ("Port %d received query for OID_GEN_SUPPORTED_LIST\n", port_num) );
\r
660 src_buf = (PVOID)SUPPORTED_OIDS;
\r
661 buf_len = sizeof(SUPPORTED_OIDS);
\r
664 case OID_GEN_HARDWARE_STATUS:
\r
665 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
666 ("Port %d received query for OID_GEN_HARDWARE_STATUS\n", port_num) );
\r
667 cl_obj_lock( &p_adapter->obj );
\r
668 switch( p_adapter->state )
\r
670 case IB_PNP_PORT_ADD:
\r
671 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
672 ("Port %d returning NdisHardwareStatusInitializing\n", port_num) );
\r
673 info = NdisHardwareStatusInitializing;
\r
676 case IB_PNP_PORT_ACTIVE:
\r
677 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
678 ("Port %d returning NdisHardwareStatusReady\n", port_num) );
\r
679 info = NdisHardwareStatusReady;
\r
683 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
684 ("Port %d returning NdisHardwareStatusNotReady\n", port_num) );
\r
685 info = NdisHardwareStatusNotReady;
\r
687 cl_obj_unlock( &p_adapter->obj );
\r
690 case OID_GEN_MEDIA_SUPPORTED:
\r
691 case OID_GEN_MEDIA_IN_USE:
\r
692 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
693 ("Port %d received query for OID_GEN_MEDIA_SUPPORTED "
\r
694 "or OID_GEN_MEDIA_IN_USE\n", port_num) );
\r
695 info = NdisMedium802_3;
\r
698 case OID_GEN_MAXIMUM_FRAME_SIZE:
\r
699 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
700 ("Port %d received query for OID_GEN_MAXIMUM_FRAME_SIZE\n", port_num) );
\r
701 info = PAYLOAD_MTU;
\r
704 case OID_GEN_LINK_SPEED:
\r
705 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
706 ("Port %d received query for OID_GEN_LINK_SPEED\n", port_num) );
\r
707 cl_obj_lock( &p_adapter->obj );
\r
708 switch( p_adapter->state )
\r
710 case IB_PNP_PORT_ADD:
\r
711 /* Mark the adapter as pending an OID */
\r
712 p_adapter->pending_query = TRUE;
\r
714 /* Save the request parameters. */
\r
715 p_adapter->query_oid = oid_info;
\r
717 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
718 ("Port %d returning NDIS_STATUS_PENDING\n", port_num) );
\r
719 status = NDIS_STATUS_PENDING;
\r
722 case IB_PNP_PORT_REMOVE:
\r
723 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
724 ("Port %d returning NDIS_STATUS_NOT_ACCEPTED\n", port_num) );
\r
725 status = NDIS_STATUS_NOT_ACCEPTED;
\r
729 CL_ASSERT( p_adapter->p_port );
\r
730 info = p_adapter->rate;
\r
733 cl_obj_unlock( &p_adapter->obj );
\r
736 case OID_GEN_TRANSMIT_BUFFER_SPACE:
\r
737 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
738 ("Port %d received query for OID_GEN_TRANSMIT_BUFFER_SPACE\n", port_num) );
\r
739 info = p_adapter->params.sq_depth * XFER_BLOCK_SIZE;
\r
742 case OID_GEN_RECEIVE_BUFFER_SPACE:
\r
743 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
744 ("Port %d received query for OID_GEN_TRANSMIT_BUFFER_SPACE "
\r
745 "or OID_GEN_RECEIVE_BUFFER_SPACE\n", port_num) );
\r
746 info = p_adapter->params.rq_depth * XFER_BLOCK_SIZE;
\r
749 case OID_GEN_MAXIMUM_LOOKAHEAD:
\r
750 case OID_GEN_CURRENT_LOOKAHEAD:
\r
751 case OID_GEN_TRANSMIT_BLOCK_SIZE:
\r
752 case OID_GEN_RECEIVE_BLOCK_SIZE:
\r
753 case OID_GEN_MAXIMUM_TOTAL_SIZE:
\r
754 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
755 ("Port %d received query for OID_GEN_MAXIMUM_LOOKAHEAD "
\r
756 "or OID_GEN_CURRENT_LOOKAHEAD or "
\r
757 "OID_GEN_TRANSMIT_BLOCK_SIZE or "
\r
758 "OID_GEN_RECEIVE_BLOCK_SIZE or "
\r
759 "OID_GEN_MAXIMUM_TOTAL_SIZE\n", port_num) );
\r
760 info = XFER_BLOCK_SIZE;
\r
763 case OID_GEN_VENDOR_ID:
\r
764 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
765 ("Port %d received query for OID_GEN_VENDOR_ID\n", port_num) );
\r
766 src_buf = (void*)VENDOR_ID;
\r
767 buf_len = sizeof(VENDOR_ID);
\r
770 case OID_GEN_VENDOR_DESCRIPTION:
\r
771 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
772 ("Port %d received query for OID_GEN_VENDOR_DESCRIPTION\n", port_num) );
\r
773 src_buf = VENDOR_DESCRIPTION;
\r
774 buf_len = sizeof(VENDOR_DESCRIPTION);
\r
777 case OID_GEN_VENDOR_DRIVER_VERSION:
\r
778 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
779 ("Port %d received query for OID_GEN_VENDOR_DRIVER_VERSION\n", port_num) );
\r
780 src_buf = &version;
\r
781 buf_len = sizeof(version);
\r
782 //TODO: Figure out what the right version is.
\r
783 version = 1 << 8 | 1;
\r
786 case OID_GEN_PHYSICAL_MEDIUM:
\r
787 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
788 ("Port %d received query for OID_GEN_PHYSICAL_MEDIUM\n", port_num) );
\r
789 info = NdisPhysicalMediumUnspecified;
\r
792 case OID_GEN_CURRENT_PACKET_FILTER:
\r
793 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
794 ("Port %d received query for OID_GEN_CURRENT_PACKET_FILTER\n", port_num) );
\r
795 info = p_adapter->packet_filter;
\r
798 case OID_GEN_DRIVER_VERSION:
\r
799 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
800 ("Port %d received query for OID_GEN_DRIVER_VERSION\n", port_num) );
\r
801 src_buf = &version;
\r
802 buf_len = sizeof(version);
\r
803 version = MAJOR_NDIS_VERSION << 8 | MINOR_NDIS_VERSION;
\r
806 case OID_GEN_MAC_OPTIONS:
\r
807 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
808 ("Port %d received query for OID_GEN_MAC_OPTIONS\n", port_num) );
\r
809 info = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
\r
810 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
\r
811 NDIS_MAC_OPTION_NO_LOOPBACK |
\r
812 NDIS_MAC_OPTION_FULL_DUPLEX;
\r
813 //TODO: Figure out if we will support priority and VLANs.
\r
814 // NDIS_MAC_OPTION_8021P_PRIORITY;
\r
815 //#ifdef NDIS51_MINIPORT
\r
816 // info |= NDIS_MAC_OPTION_8021Q_VLAN;
\r
820 case OID_GEN_MEDIA_CONNECT_STATUS:
\r
821 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
822 ("Port %d received query for OID_GEN_MEDIA_CONNECT_STATUS\n", port_num) );
\r
823 cl_obj_lock( &p_adapter->obj );
\r
824 switch( p_adapter->state )
\r
826 case IB_PNP_PORT_ADD:
\r
828 * Delay reporting media state until we know whether the port is
\r
829 * either up or down.
\r
831 p_adapter->pending_query = TRUE;
\r
832 p_adapter->query_oid = oid_info;
\r
834 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
835 ("Port %d returning NDIS_STATUS_PENDING\n", port_num) );
\r
836 status = NDIS_STATUS_PENDING;
\r
839 case IB_PNP_PORT_ACTIVE:
\r
840 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
841 ("Port %d returning NdisMediaStateConnected\n", port_num) );
\r
842 info = NdisMediaStateConnected;
\r
845 case IB_PNP_PORT_REMOVE:
\r
846 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
847 ("Port %d returning NDIS_STATUS_NOT_ACCEPTED\n", port_num) );
\r
848 status = NDIS_STATUS_NOT_ACCEPTED;
\r
852 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
853 ("Port %d returning NdisMediaStateDisconnected\n", port_num) );
\r
854 info = NdisMediaStateDisconnected;
\r
856 cl_obj_unlock( &p_adapter->obj );
\r
859 case OID_GEN_MAXIMUM_SEND_PACKETS:
\r
860 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
861 ("Port %d received query for OID_GEN_MAXIMUM_SEND_PACKETS\n", port_num) );
\r
865 /* Required General Statistics */
\r
866 case OID_GEN_XMIT_OK:
\r
867 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
868 ("Port %d received query for OID_GEN_XMIT_OK\n", port_num) );
\r
870 status = ipoib_get_send_stat( p_adapter, IP_STAT_SUCCESS, &oid_info );
\r
873 case OID_GEN_RCV_OK:
\r
874 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
875 ("Port %d received query for OID_GEN_RCV_OK\n", port_num) );
\r
877 status = ipoib_get_recv_stat( p_adapter, IP_STAT_SUCCESS, &oid_info );
\r
880 case OID_GEN_XMIT_ERROR:
\r
881 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
882 ("Port %d received query for OID_GEN_XMIT_ERROR\n", port_num) );
\r
884 status = ipoib_get_send_stat( p_adapter, IP_STAT_ERROR, &oid_info );
\r
887 case OID_GEN_RCV_ERROR:
\r
888 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
889 ("Port %d received query for OID_GEN_RCV_ERROR\n", port_num) );
\r
891 status = ipoib_get_recv_stat( p_adapter, IP_STAT_ERROR, &oid_info );
\r
894 case OID_GEN_RCV_NO_BUFFER:
\r
895 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
896 ("Port %d received query for OID_GEN_RCV_NO_BUFFER\n", port_num) );
\r
898 status = ipoib_get_recv_stat( p_adapter, IP_STAT_DROPPED, &oid_info );
\r
901 case OID_GEN_DIRECTED_BYTES_XMIT:
\r
902 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
903 ("Port %d received query for OID_GEN_DIRECTED_BYTES_XMIT\n", port_num) );
\r
905 status = ipoib_get_send_stat( p_adapter, IP_STAT_UCAST_BYTES, &oid_info );
\r
908 case OID_GEN_DIRECTED_FRAMES_XMIT:
\r
909 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
910 ("Port %d received query for OID_GEN_DIRECTED_FRAMES_XMIT\n", port_num) );
\r
912 status = ipoib_get_send_stat( p_adapter, IP_STAT_UCAST_FRAMES, &oid_info );
\r
915 case OID_GEN_MULTICAST_BYTES_XMIT:
\r
916 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
917 ("Port %d received query for OID_GEN_MULTICAST_BYTES_XMIT\n", port_num) );
\r
919 status = ipoib_get_send_stat( p_adapter, IP_STAT_MCAST_BYTES, &oid_info );
\r
922 case OID_GEN_MULTICAST_FRAMES_XMIT:
\r
923 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
924 ("Port %d received query for OID_GEN_MULTICAST_FRAMES_XMIT\n", port_num) );
\r
926 status = ipoib_get_send_stat( p_adapter, IP_STAT_MCAST_FRAMES, &oid_info );
\r
929 case OID_GEN_BROADCAST_BYTES_XMIT:
\r
930 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
931 ("Port %d received query for OID_GEN_BROADCAST_BYTES_XMIT\n", port_num) );
\r
933 status = ipoib_get_send_stat( p_adapter, IP_STAT_BCAST_BYTES, &oid_info );
\r
936 case OID_GEN_BROADCAST_FRAMES_XMIT:
\r
937 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
938 ("Port %d received query for OID_GEN_BROADCAST_FRAMES_XMIT\n", port_num) );
\r
940 status = ipoib_get_send_stat( p_adapter, IP_STAT_BCAST_FRAMES, &oid_info );
\r
943 case OID_GEN_DIRECTED_BYTES_RCV:
\r
944 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
945 ("Port %d received query for OID_GEN_DIRECTED_BYTES_RCV\n", port_num) );
\r
947 status = ipoib_get_recv_stat( p_adapter, IP_STAT_UCAST_BYTES, &oid_info );
\r
950 case OID_GEN_DIRECTED_FRAMES_RCV:
\r
951 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
952 ("Port %d received query for OID_GEN_DIRECTED_FRAMES_RCV\n", port_num) );
\r
954 status = ipoib_get_recv_stat( p_adapter, IP_STAT_UCAST_FRAMES, &oid_info );
\r
957 case OID_GEN_MULTICAST_BYTES_RCV:
\r
958 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
959 ("Port %d received query for OID_GEN_MULTICAST_BYTES_RCV\n", port_num) );
\r
961 status = ipoib_get_recv_stat( p_adapter, IP_STAT_MCAST_BYTES, &oid_info );
\r
964 case OID_GEN_MULTICAST_FRAMES_RCV:
\r
965 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
966 ("Port %d received query for OID_GEN_MULTICAST_FRAMES_RCV\n", port_num) );
\r
968 status = ipoib_get_recv_stat( p_adapter, IP_STAT_MCAST_FRAMES, &oid_info );
\r
971 case OID_GEN_BROADCAST_BYTES_RCV:
\r
972 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
973 ("Port %d received query for OID_GEN_BROADCAST_BYTES_RCV\n", port_num) );
\r
975 status = ipoib_get_recv_stat( p_adapter, IP_STAT_BCAST_BYTES, &oid_info );
\r
978 case OID_GEN_BROADCAST_FRAMES_RCV:
\r
979 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
980 ("Port %d received query for OID_GEN_BROADCAST_FRAMES_RCV\n", port_num) );
\r
982 status = ipoib_get_recv_stat( p_adapter, IP_STAT_BCAST_FRAMES, &oid_info );
\r
985 /* Required Ethernet operational characteristics */
\r
986 case OID_802_3_PERMANENT_ADDRESS:
\r
987 case OID_802_3_CURRENT_ADDRESS:
\r
988 #if defined( _DEBUG_ )
\r
989 if( oid == OID_802_3_PERMANENT_ADDRESS )
\r
991 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
992 ("Port %d received query for OID_802_3_PERMANENT_ADDRESS\n", port_num) );
\r
996 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
997 ("Port %d received query for OID_802_3_CURRENT_ADDRESS\n", port_num) );
\r
999 #endif /* defined( _DEBUG_ )*/
\r
1000 src_buf = &p_adapter->mac;
\r
1001 buf_len = sizeof(p_adapter->mac);
\r
1004 case OID_802_3_MULTICAST_LIST:
\r
1005 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1006 ("Port %d received query for OID_802_3_MULTICAST_LIST\n", port_num) );
\r
1007 src_buf = p_adapter->mcast_array;
\r
1008 buf_len = p_adapter->mcast_array_size * sizeof(mac_addr_t);
\r
1011 case OID_802_3_MAXIMUM_LIST_SIZE:
\r
1012 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1013 ("Port %d received query for OID_802_3_MAXIMUM_LIST_SIZE\n", port_num) );
\r
1017 case OID_802_3_MAC_OPTIONS:
\r
1018 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1019 ("Port %d received query for OID_802_3_MAC_OPTIONS\n", port_num) );
\r
1023 /* Required Ethernet stats */
\r
1024 case OID_802_3_RCV_ERROR_ALIGNMENT:
\r
1025 case OID_802_3_XMIT_ONE_COLLISION:
\r
1026 case OID_802_3_XMIT_MORE_COLLISIONS:
\r
1027 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1028 ("Port %d received query for OID_802_3_RCV_ERROR_ALIGNMENT or "
\r
1029 "OID_802_3_XMIT_ONE_COLLISION or "
\r
1030 "OID_802_3_XMIT_MORE_COLLISIONS\n", port_num) );
\r
1034 case OID_TCP_TASK_OFFLOAD:
\r
1036 status = __ipoib_get_tcp_task_offload( p_adapter, &oid_info );
\r
1039 /* Optional General */
\r
1040 case OID_GEN_SUPPORTED_GUIDS:
\r
1041 #ifdef NDIS51_MINIPORT
\r
1042 case OID_GEN_VLAN_ID:
\r
1045 /* Optional General Stats */
\r
1046 case OID_GEN_RCV_CRC_ERROR:
\r
1047 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
\r
1049 /* Optional Ethernet Stats */
\r
1050 case OID_802_3_XMIT_DEFERRED:
\r
1051 case OID_802_3_XMIT_MAX_COLLISIONS:
\r
1052 case OID_802_3_RCV_OVERRUN:
\r
1053 case OID_802_3_XMIT_UNDERRUN:
\r
1054 case OID_802_3_XMIT_HEARTBEAT_FAILURE:
\r
1055 case OID_802_3_XMIT_TIMES_CRS_LOST:
\r
1056 case OID_802_3_XMIT_LATE_COLLISIONS:
\r
1057 case OID_PNP_CAPABILITIES:
\r
1058 status = NDIS_STATUS_NOT_SUPPORTED;
\r
1059 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1060 ("Port %d received an unsupported oid of 0x%.8X!\n", port_num, oid) );
\r
1063 case OID_GEN_PROTOCOL_OPTIONS:
\r
1064 case OID_GEN_NETWORK_LAYER_ADDRESSES:
\r
1065 case OID_GEN_TRANSPORT_HEADER_OFFSET:
\r
1066 #ifdef NDIS51_MINIPORT
\r
1067 case OID_GEN_MACHINE_NAME:
\r
1068 case OID_GEN_RNDIS_CONFIG_PARAMETER:
\r
1071 status = NDIS_STATUS_INVALID_OID;
\r
1072 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1073 ("Port %d received an invalid oid of 0x%.8X!\n", port_num, oid) );
\r
1078 * Complete the request as if it was handled asynchronously to maximize
\r
1079 * code reuse for when we really handle the requests asynchronously.
\r
1080 * Note that this requires the QueryInformation entry point to always
\r
1081 * return NDIS_STATUS_PENDING
\r
1083 if( status != NDIS_STATUS_PENDING )
\r
1085 ipoib_complete_query(
\r
1086 p_adapter, &oid_info, status, src_buf, buf_len );
\r
1089 IPOIB_EXIT( IPOIB_DBG_OID );
\r
1090 return NDIS_STATUS_PENDING;
\r
1095 ipoib_complete_query(
\r
1096 IN ipoib_adapter_t* const p_adapter,
\r
1097 IN pending_oid_t* const p_oid_info,
\r
1098 IN const NDIS_STATUS status,
\r
1099 IN const void* const p_buf,
\r
1100 IN const ULONG buf_len )
\r
1102 NDIS_STATUS oid_status = status;
\r
1104 IPOIB_ENTER( IPOIB_DBG_OID );
\r
1106 CL_ASSERT( status != NDIS_STATUS_PENDING );
\r
1108 if( status == NDIS_STATUS_SUCCESS )
\r
1110 if( p_oid_info->buf_len < buf_len )
\r
1112 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1113 ("Insufficient buffer space. "
\r
1114 "Returning NDIS_STATUS_INVALID_LENGTH.\n") );
\r
1115 oid_status = NDIS_STATUS_INVALID_LENGTH;
\r
1116 *p_oid_info->p_bytes_needed = buf_len;
\r
1117 *p_oid_info->p_bytes_used = 0;
\r
1119 else if( p_oid_info->p_buf )
\r
1121 /* Only copy if we have a distinct source buffer. */
\r
1124 NdisMoveMemory( p_oid_info->p_buf, p_buf, buf_len );
\r
1125 *p_oid_info->p_bytes_used = buf_len;
\r
1130 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1131 ("Returning NDIS_NOT_ACCEPTED") );
\r
1132 oid_status = NDIS_STATUS_NOT_ACCEPTED;
\r
1137 *p_oid_info->p_bytes_used = 0;
\r
1140 p_adapter->pending_query = FALSE;
\r
1142 NdisMQueryInformationComplete( p_adapter->h_adapter, oid_status );
\r
1144 IPOIB_EXIT( IPOIB_DBG_OID );
\r
1148 static NDIS_STATUS
\r
1149 __ipoib_get_tcp_task_offload(
\r
1150 IN ipoib_adapter_t* p_adapter,
\r
1151 IN pending_oid_t* const p_oid_info )
\r
1153 NDIS_TASK_OFFLOAD_HEADER *p_offload_hdr;
\r
1154 NDIS_TASK_OFFLOAD *p_offload_task;
\r
1155 NDIS_TASK_TCP_IP_CHECKSUM *p_offload_chksum;
\r
1159 port_num = IPOIB_ADAPTER_GET_PORT_NUM(p_adapter);
\r
1161 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1162 ("Port %d received query for OID_TCP_TASK_OFFLOAD\n", port_num) );
\r
1164 buf_len = sizeof(NDIS_TASK_OFFLOAD_HEADER) +
\r
1165 sizeof(NDIS_TASK_OFFLOAD) +
\r
1166 sizeof(NDIS_TASK_TCP_IP_CHECKSUM) - 1;
\r
1168 *(p_oid_info->p_bytes_needed) = buf_len;
\r
1170 if( p_oid_info->buf_len < buf_len )
\r
1171 return NDIS_STATUS_INVALID_LENGTH;
\r
1173 p_offload_hdr = (NDIS_TASK_OFFLOAD_HEADER*)p_oid_info->p_buf;
\r
1174 if( p_offload_hdr->Version != NDIS_TASK_OFFLOAD_VERSION )
\r
1175 return NDIS_STATUS_INVALID_DATA;
\r
1177 if( p_offload_hdr->EncapsulationFormat.Encapsulation !=
\r
1178 IEEE_802_3_Encapsulation )
\r
1180 return NDIS_STATUS_INVALID_DATA;
\r
1183 p_offload_hdr->OffsetFirstTask = sizeof(NDIS_TASK_OFFLOAD_HEADER);
\r
1184 p_offload_task = (NDIS_TASK_OFFLOAD*)(p_offload_hdr + 1);
\r
1185 p_offload_task->Version = NDIS_TASK_OFFLOAD_VERSION;
\r
1186 p_offload_task->Size = sizeof(NDIS_TASK_OFFLOAD);
\r
1187 p_offload_task->Task = TcpIpChecksumNdisTask;
\r
1188 p_offload_task->OffsetNextTask = 0;
\r
1189 p_offload_task->TaskBufferLength = sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
\r
1190 p_offload_chksum =
\r
1191 (NDIS_TASK_TCP_IP_CHECKSUM*)p_offload_task->TaskBuffer;
\r
1193 p_offload_chksum->V4Transmit.IpOptionsSupported =
\r
1194 p_adapter->params.send_chksum_offload;
\r
1195 p_offload_chksum->V4Transmit.TcpOptionsSupported =
\r
1196 p_adapter->params.send_chksum_offload;
\r
1197 p_offload_chksum->V4Transmit.TcpChecksum =
\r
1198 p_adapter->params.send_chksum_offload;
\r
1199 p_offload_chksum->V4Transmit.UdpChecksum =
\r
1200 p_adapter->params.send_chksum_offload;
\r
1201 p_offload_chksum->V4Transmit.IpChecksum =
\r
1202 p_adapter->params.send_chksum_offload;
\r
1205 * Only receive checksum can be offloaded thanks to
\r
1206 * the IB physical layer.
\r
1208 p_offload_chksum->V4Receive.IpOptionsSupported = TRUE;
\r
1209 p_offload_chksum->V4Receive.TcpOptionsSupported = TRUE;
\r
1210 p_offload_chksum->V4Receive.TcpChecksum = TRUE;
\r
1211 p_offload_chksum->V4Receive.UdpChecksum = TRUE;
\r
1212 p_offload_chksum->V4Receive.IpChecksum = TRUE;
\r
1214 p_offload_chksum->V6Transmit.IpOptionsSupported = FALSE;
\r
1215 p_offload_chksum->V6Transmit.TcpOptionsSupported = FALSE;
\r
1216 p_offload_chksum->V6Transmit.TcpChecksum = FALSE;
\r
1217 p_offload_chksum->V6Transmit.UdpChecksum = FALSE;
\r
1219 p_offload_chksum->V6Receive.IpOptionsSupported = FALSE;
\r
1220 p_offload_chksum->V6Receive.TcpOptionsSupported = FALSE;
\r
1221 p_offload_chksum->V6Receive.TcpChecksum = FALSE;
\r
1222 p_offload_chksum->V6Receive.UdpChecksum = FALSE;
\r
1224 *(p_oid_info->p_bytes_used) = buf_len;
\r
1226 return NDIS_STATUS_SUCCESS;
\r
1230 //! Issues a hardware reset to the NIC and/or resets the driver's software state.
\r
1231 /* Tear down the connection and start over again. This is only called when there is a problem.
\r
1232 For example, if a send, query info, or set info had a time out. MiniportCheckForHang will
\r
1234 IRQL = DISPATCH_LEVEL
\r
1236 @param p_addr_resetPointer to BOOLLEAN that is set to TRUE if the NDIS
\r
1237 library should call MiniportSetInformation to restore addressing information to the current values.
\r
1238 @param adapter_context The adapter context allocated at start
\r
1239 @return NDIS_STATUS_SUCCESS, NDIS_STATUS_PENDING, NDIS_STATUS_NOT_RESETTABLE,
\r
1240 NDIS_STATUS_RESET_IN_PROGRESS, NDIS_STATUS_SOFT_ERRORS, NDIS_STATUS_HARD_ERRORS
\r
1244 OUT PBOOLEAN p_addr_reset,
\r
1245 IN NDIS_HANDLE adapter_context)
\r
1247 ipoib_adapter_t* p_adapter;
\r
1249 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
1251 CL_ASSERT( p_addr_reset );
\r
1252 CL_ASSERT( adapter_context );
\r
1253 p_adapter = (ipoib_adapter_t*)adapter_context;
\r
1255 switch( ipoib_reset_adapter( p_adapter ) )
\r
1258 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
1259 return NDIS_STATUS_PENDING;
\r
1262 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
1263 *p_addr_reset = TRUE;
\r
1264 return NDIS_STATUS_SUCCESS;
\r
1267 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
1268 return NDIS_STATUS_HARD_ERRORS;
\r
1273 //! Request changes in the state information that the miniport driver maintains
\r
1274 /* For example, this is used to set multicast addresses and the packet filter.
\r
1275 IRQL = DISPATCH_LEVEL
\r
1277 @param adapter_context The adapter context allocated at start
\r
1278 @param oid Object ID representing the set operation to be carried out
\r
1279 @param info_buf Buffer containing input for this set and location for any output
\r
1280 @param info_buf_len Number of bytes available in info_buf
\r
1281 @param p_bytes_read Pointer to number of bytes read from info_buf
\r
1282 @param p_bytes_needed Pointer to number of bytes needed to satisfy this oid
\r
1283 @return NDIS_STATUS_SUCCESS, NDIS_STATUS_PENDING, NDIS_STATUS_INVALID_OID,
\r
1284 NDIS_STATUS_INVALID_LENGTH, NDIS_STATUS_INVALID_DATA, NDIS_STATUS_NOT_ACCEPTED,
\r
1285 NDIS_STATUS_NOT_SUPPORTED, NDIS_STATUS_RESOURCES
\r
1289 IN NDIS_HANDLE adapter_context,
\r
1291 IN PVOID info_buf,
\r
1292 IN ULONG info_buf_len,
\r
1293 OUT PULONG p_bytes_read,
\r
1294 OUT PULONG p_bytes_needed )
\r
1296 ipoib_adapter_t* p_adapter;
\r
1297 NDIS_STATUS status;
\r
1302 IPOIB_ENTER( IPOIB_DBG_OID );
\r
1304 CL_ASSERT( adapter_context );
\r
1305 p_adapter = (ipoib_adapter_t*)adapter_context;
\r
1307 CL_ASSERT( p_bytes_read );
\r
1308 CL_ASSERT( p_bytes_needed );
\r
1309 CL_ASSERT( !p_adapter->pending_set );
\r
1311 status = NDIS_STATUS_SUCCESS;
\r
1312 *p_bytes_needed = 0;
\r
1313 buf_len = sizeof(ULONG);
\r
1315 port_num = IPOIB_ADAPTER_GET_PORT_NUM(p_adapter);
\r
1319 /* Required General */
\r
1320 case OID_GEN_CURRENT_PACKET_FILTER:
\r
1321 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1322 ("Port %d received set for OID_GEN_CURRENT_PACKET_FILTER\n", port_num));
\r
1323 if( info_buf_len < sizeof(p_adapter->packet_filter) )
\r
1325 status = NDIS_STATUS_INVALID_LENGTH;
\r
1327 else if( !info_buf )
\r
1329 status = NDIS_STATUS_INVALID_DATA;
\r
1333 cl_obj_lock( &p_adapter->obj );
\r
1334 switch( p_adapter->state )
\r
1336 case IB_PNP_PORT_ADD:
\r
1337 p_adapter->set_oid.oid = oid;
\r
1338 p_adapter->set_oid.p_buf = info_buf;
\r
1339 p_adapter->set_oid.buf_len = info_buf_len;
\r
1340 p_adapter->set_oid.p_bytes_used = p_bytes_read;
\r
1341 p_adapter->set_oid.p_bytes_needed = p_bytes_needed;
\r
1342 p_adapter->pending_set = TRUE;
\r
1343 status = NDIS_STATUS_PENDING;
\r
1346 case IB_PNP_PORT_REMOVE:
\r
1347 status = NDIS_STATUS_NOT_ACCEPTED;
\r
1351 if( !p_adapter->packet_filter && (*(uint32_t*)info_buf) )
\r
1354 * Filter was zero, now non-zero. Register IP addresses
\r
1357 ipoib_reg_addrs( p_adapter );
\r
1359 else if( p_adapter->packet_filter && !(*(uint32_t*)info_buf) )
\r
1362 * Filter was non-zero, now zero. Deregister IP addresses.
\r
1364 __ipoib_dereg_addrs( p_adapter );
\r
1367 p_adapter->packet_filter = *(uint32_t*)info_buf;
\r
1369 cl_obj_unlock( &p_adapter->obj );
\r
1373 case OID_GEN_CURRENT_LOOKAHEAD:
\r
1374 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1375 ("Port %d received set for OID_GEN_CURRENT_LOOKAHEAD\n", port_num));
\r
1376 if( info_buf_len < buf_len )
\r
1377 status = NDIS_STATUS_INVALID_LENGTH;
\r
1380 case OID_GEN_PROTOCOL_OPTIONS:
\r
1381 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1382 ("Port %d received set for OID_GEN_PROTOCOL_OPTIONS\n", port_num));
\r
1383 if( info_buf_len < buf_len )
\r
1384 status = NDIS_STATUS_INVALID_LENGTH;
\r
1387 case OID_GEN_NETWORK_LAYER_ADDRESSES:
\r
1388 status = __ipoib_set_net_addr( p_adapter, info_buf, info_buf_len, p_bytes_read, p_bytes_needed);
\r
1391 #ifdef NDIS51_MINIPORT
\r
1392 case OID_GEN_MACHINE_NAME:
\r
1393 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1394 ("Port %d received set for OID_GEN_MACHINE_NAME\n", port_num) );
\r
1398 /* Required Ethernet operational characteristics */
\r
1399 case OID_802_3_MULTICAST_LIST:
\r
1400 IPOIB_TRACE( IPOIB_DBG_OID,
\r
1401 ("Port %d received set for OID_802_3_MULTICAST_LIST\n", port_num) );
\r
1402 if( info_buf_len > MAX_MCAST * sizeof(mac_addr_t) )
\r
1404 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1405 ("Port %d OID_802_3_MULTICAST_LIST - Multicast list full.\n", port_num) );
\r
1406 status = NDIS_STATUS_MULTICAST_FULL;
\r
1407 *p_bytes_needed = MAX_MCAST * sizeof(mac_addr_t);
\r
1409 else if( info_buf_len % sizeof(mac_addr_t) )
\r
1411 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1412 ("Port %d OID_802_3_MULTICAST_LIST - Invalid input buffer.\n", port_num) );
\r
1413 status = NDIS_STATUS_INVALID_DATA;
\r
1415 else if( !info_buf && info_buf_len )
\r
1417 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1418 ("Port %d OID_802_3_MULTICAST_LIST - Invalid input buffer.\n", port_num) );
\r
1419 status = NDIS_STATUS_INVALID_DATA;
\r
1423 ipoib_refresh_mcast( p_adapter, (mac_addr_t*)info_buf,
\r
1424 (uint8_t)(info_buf_len / sizeof(mac_addr_t)) );
\r
1426 buf_len = info_buf_len;
\r
1428 * Note that we don't return pending. It will likely take longer
\r
1429 * for our SA transactions to complete than NDIS will give us
\r
1430 * before reseting the adapter. If an SA failure is encountered,
\r
1431 * the adapter will be marked as hung and we will get reset.
\r
1433 status = NDIS_STATUS_SUCCESS;
\r
1437 case OID_TCP_TASK_OFFLOAD:
\r
1438 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1439 ("Port %d received set for OID_TCP_TASK_OFFLOAD\n", port_num) );
\r
1440 /* TODO: See if we need to handle this OID, or if just setting the
\r
1441 * checksum OK flags in the packets always works. */
\r
1444 /* Optional General */
\r
1445 case OID_GEN_TRANSPORT_HEADER_OFFSET:
\r
1446 #ifdef NDIS51_MINIPORT
\r
1447 case OID_GEN_RNDIS_CONFIG_PARAMETER:
\r
1448 case OID_GEN_VLAN_ID:
\r
1450 status = NDIS_STATUS_NOT_SUPPORTED;
\r
1451 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1452 ("Port %d received an unsupported oid of 0x%.8X!\n", port_num, oid));
\r
1455 case OID_GEN_SUPPORTED_LIST:
\r
1456 case OID_GEN_HARDWARE_STATUS:
\r
1457 case OID_GEN_MEDIA_SUPPORTED:
\r
1458 case OID_GEN_MEDIA_IN_USE:
\r
1459 case OID_GEN_MAXIMUM_FRAME_SIZE:
\r
1460 case OID_GEN_LINK_SPEED:
\r
1461 case OID_GEN_TRANSMIT_BUFFER_SPACE:
\r
1462 case OID_GEN_RECEIVE_BUFFER_SPACE:
\r
1463 case OID_GEN_MAXIMUM_LOOKAHEAD:
\r
1464 case OID_GEN_TRANSMIT_BLOCK_SIZE:
\r
1465 case OID_GEN_RECEIVE_BLOCK_SIZE:
\r
1466 case OID_GEN_MAXIMUM_TOTAL_SIZE:
\r
1467 case OID_GEN_VENDOR_ID:
\r
1468 case OID_GEN_VENDOR_DESCRIPTION:
\r
1469 case OID_GEN_VENDOR_DRIVER_VERSION:
\r
1470 case OID_GEN_DRIVER_VERSION:
\r
1471 case OID_GEN_MAC_OPTIONS:
\r
1472 case OID_GEN_MEDIA_CONNECT_STATUS:
\r
1473 case OID_GEN_MAXIMUM_SEND_PACKETS:
\r
1474 case OID_GEN_SUPPORTED_GUIDS:
\r
1475 case OID_GEN_PHYSICAL_MEDIUM:
\r
1477 status = NDIS_STATUS_INVALID_OID;
\r
1478 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1479 ("Port %d received an invalid oid of 0x%.8X!\n", port_num, oid));
\r
1483 if( status == NDIS_STATUS_SUCCESS )
\r
1485 *p_bytes_read = buf_len;
\r
1489 if( status == NDIS_STATUS_INVALID_LENGTH )
\r
1491 if ( !*p_bytes_needed )
\r
1493 *p_bytes_needed = buf_len;
\r
1497 *p_bytes_read = 0;
\r
1500 IPOIB_EXIT( IPOIB_DBG_OID );
\r
1505 //! Transfers some number of packets, specified as an array of packet pointers, over the network.
\r
1506 /* For a deserialized driver, these packets are completed asynchronously
\r
1507 using NdisMSendComplete.
\r
1508 IRQL <= DISPATCH_LEVEL
\r
1510 @param adapter_context Pointer to ipoib_adapter_t structure with per NIC state
\r
1511 @param packet_array Array of packets to send
\r
1512 @param numPackets Number of packets in the array
\r
1515 ipoib_send_packets(
\r
1516 IN NDIS_HANDLE adapter_context,
\r
1517 IN PPNDIS_PACKET packet_array,
\r
1518 IN UINT num_packets )
\r
1520 ipoib_adapter_t *p_adapter;
\r
1521 ipoib_port_t *p_port;
\r
1523 PERF_DECLARE( SendPackets );
\r
1524 PERF_DECLARE( PortSend );
\r
1526 IPOIB_ENTER( IPOIB_DBG_SEND );
\r
1528 cl_perf_start( SendPackets );
\r
1530 CL_ASSERT( adapter_context );
\r
1531 p_adapter = (ipoib_adapter_t*)adapter_context;
\r
1533 cl_obj_lock( &p_adapter->obj );
\r
1534 if( p_adapter->state != IB_PNP_PORT_ACTIVE || !p_adapter->p_port )
\r
1536 cl_obj_unlock( &p_adapter->obj );
\r
1537 for( packet_num = 0; packet_num < num_packets; ++packet_num )
\r
1539 ipoib_inc_send_stat( p_adapter, IP_STAT_DROPPED, 0 );
\r
1540 NdisMSendComplete( p_adapter->h_adapter,
\r
1541 packet_array[packet_num], NDIS_STATUS_ADAPTER_NOT_READY );
\r
1543 IPOIB_EXIT( IPOIB_DBG_SEND );
\r
1547 p_port = p_adapter->p_port;
\r
1548 cl_obj_ref( &p_port->obj );
\r
1549 cl_obj_unlock( &p_adapter->obj );
\r
1551 cl_perf_start( PortSend );
\r
1552 ipoib_port_send( p_port, packet_array, num_packets );
\r
1553 cl_perf_stop( &p_port->p_adapter->perf, PortSend );
\r
1554 cl_obj_deref( &p_port->obj );
\r
1556 cl_perf_stop( &p_adapter->perf, SendPackets );
\r
1558 cl_perf_log( &p_adapter->perf, SendBundle, num_packets );
\r
1560 IPOIB_EXIT( IPOIB_DBG_SEND );
\r
1566 IN NDIS_HANDLE adapter_context,
\r
1567 IN NDIS_DEVICE_PNP_EVENT pnp_event,
\r
1568 IN PVOID info_buf,
\r
1569 IN ULONG info_buf_len )
\r
1571 ipoib_adapter_t *p_adapter;
\r
1573 IPOIB_ENTER( IPOIB_DBG_PNP );
\r
1575 UNUSED_PARAM( info_buf );
\r
1576 UNUSED_PARAM( info_buf_len );
\r
1578 p_adapter = (ipoib_adapter_t*)adapter_context;
\r
1580 IPOIB_TRACE( IPOIB_DBG_PNP, ("Event %d\n", pnp_event) );
\r
1581 if( pnp_event != NdisDevicePnPEventPowerProfileChanged )
\r
1583 cl_obj_lock( &p_adapter->obj );
\r
1584 p_adapter->state = IB_PNP_PORT_REMOVE;
\r
1585 cl_obj_unlock( &p_adapter->obj );
\r
1587 ipoib_resume_oids( p_adapter );
\r
1590 IPOIB_EXIT( IPOIB_DBG_PNP );
\r
1596 IN PVOID adapter_context )
\r
1598 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
1599 UNUSED_PARAM( adapter_context );
\r
1600 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
1605 ipoib_resume_oids(
\r
1606 IN ipoib_adapter_t* const p_adapter )
\r
1609 NDIS_STATUS status;
\r
1610 boolean_t pending_query, pending_set;
\r
1611 pending_oid_t query_oid = {0};
\r
1612 pending_oid_t set_oid = {0};
\r
1614 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
1616 cl_obj_lock( &p_adapter->obj );
\r
1618 * Set the status depending on our state. Fail OID requests that
\r
1619 * are pending while we reset the adapter.
\r
1621 switch( p_adapter->state )
\r
1623 case IB_PNP_PORT_ADD:
\r
1624 status = NDIS_STATUS_FAILURE;
\r
1627 case IB_PNP_PORT_REMOVE:
\r
1628 status = NDIS_STATUS_NOT_ACCEPTED;
\r
1632 status = NDIS_STATUS_SUCCESS;
\r
1635 pending_query = p_adapter->pending_query;
\r
1636 if( pending_query )
\r
1638 query_oid = p_adapter->query_oid;
\r
1639 p_adapter->pending_query = FALSE;
\r
1641 pending_set = p_adapter->pending_set;
\r
1644 set_oid = p_adapter->set_oid;
\r
1645 p_adapter->pending_set = FALSE;
\r
1647 cl_obj_unlock( &p_adapter->obj );
\r
1650 * If we had a pending OID request for OID_GEN_LINK_SPEED,
\r
1651 * complete it now. Note that we hold the object lock since
\r
1652 * NdisMQueryInformationComplete is called at DISPATCH_LEVEL.
\r
1654 if( pending_query )
\r
1656 switch( query_oid.oid )
\r
1658 case OID_GEN_LINK_SPEED:
\r
1659 ipoib_complete_query( p_adapter, &query_oid,
\r
1660 status, &p_adapter->rate, sizeof(p_adapter->rate) );
\r
1663 case OID_GEN_MEDIA_CONNECT_STATUS:
\r
1664 info = NdisMediaStateConnected;
\r
1665 ipoib_complete_query( p_adapter, &query_oid,
\r
1666 status, &info, sizeof(info) );
\r
1670 CL_ASSERT( query_oid.oid == OID_GEN_LINK_SPEED ||
\r
1671 query_oid.oid == OID_GEN_MEDIA_CONNECT_STATUS );
\r
1678 switch( set_oid.oid )
\r
1680 case OID_GEN_CURRENT_PACKET_FILTER:
\r
1681 /* Validation already performed in the SetInformation path. */
\r
1683 cl_obj_lock( &p_adapter->obj );
\r
1684 if( !p_adapter->packet_filter && (*(PULONG)set_oid.p_buf) )
\r
1687 * Filter was zero, now non-zero. Register IP addresses
\r
1690 ipoib_reg_addrs( p_adapter );
\r
1692 else if( p_adapter->packet_filter && !(*(PULONG)set_oid.p_buf) )
\r
1695 * Filter was non-zero, now zero. Deregister IP addresses.
\r
1697 __ipoib_dereg_addrs( p_adapter );
\r
1699 cl_obj_unlock( &p_adapter->obj );
\r
1701 p_adapter->packet_filter = *(PULONG)set_oid.p_buf;
\r
1702 NdisMSetInformationComplete( p_adapter->h_adapter, status );
\r
1705 case OID_GEN_NETWORK_LAYER_ADDRESSES:
\r
1706 status = __ipoib_set_net_addr( p_adapter,
\r
1707 p_adapter->set_oid.p_buf,
\r
1708 p_adapter->set_oid.buf_len,
\r
1709 p_adapter->set_oid.p_bytes_used,
\r
1710 p_adapter->set_oid.p_bytes_needed );
\r
1711 if( status != NDIS_STATUS_PENDING )
\r
1713 NdisMSetInformationComplete( p_adapter->h_adapter, status );
\r
1718 CL_ASSERT( set_oid.oid && 0 );
\r
1723 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
1727 static NDIS_STATUS
\r
1728 __ipoib_set_net_addr(
\r
1729 IN ipoib_adapter_t * p_adapter,
\r
1730 IN PVOID info_buf,
\r
1731 IN ULONG info_buf_len,
\r
1732 OUT PULONG p_bytes_read,
\r
1733 OUT PULONG p_bytes_needed )
\r
1735 NDIS_STATUS status;
\r
1736 PNETWORK_ADDRESS_LIST p_net_addrs;
\r
1737 PNETWORK_ADDRESS p_net_addr_oid;
\r
1738 PNETWORK_ADDRESS_IP p_ip_addr;
\r
1740 net_address_item_t *p_addr_item;
\r
1742 cl_status_t cl_status;
\r
1751 IPOIB_ENTER( IPOIB_DBG_OID );
\r
1753 status = NDIS_STATUS_SUCCESS;
\r
1754 port_num = IPOIB_ADAPTER_GET_PORT_NUM(p_adapter);
\r
1756 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1757 ("Port %d received set for OID_GEN_NETWORK_LAYER_ADDRESSES\n",
\r
1762 IPOIB_TRACE( IPOIB_DBG_ERROR,
\r
1763 ("Port %d - OID_GEN_NETWORK_LAYER_ADDRESSES - "
\r
1764 "NULL buffer\n", port_num) );
\r
1765 IPOIB_EXIT( IPOIB_DBG_OID );
\r
1766 return NDIS_STATUS_INVALID_DATA;
\r
1770 * Must use field offset because the structures define array's of size one
\r
1771 * of a the incorrect type for what is really stored.
\r
1773 if( info_buf_len < FIELD_OFFSET(NETWORK_ADDRESS_LIST, Address) )
\r
1775 IPOIB_TRACE( IPOIB_DBG_ERROR,
\r
1776 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - "
\r
1777 "bad length of %d, not enough "
\r
1778 "for NETWORK_ADDRESS_LIST (%d)\n", port_num, info_buf_len,
\r
1779 FIELD_OFFSET(NETWORK_ADDRESS_LIST, Address)) );
\r
1780 *p_bytes_needed = FIELD_OFFSET(NETWORK_ADDRESS_LIST, Address);
\r
1781 IPOIB_EXIT( IPOIB_DBG_OID );
\r
1782 return NDIS_STATUS_INVALID_LENGTH;
\r
1785 p_net_addrs = (PNETWORK_ADDRESS_LIST)info_buf;
\r
1786 if( p_net_addrs->AddressCount == 0)
\r
1788 if( p_net_addrs->AddressType == NDIS_PROTOCOL_ID_TCP_IP )
\r
1790 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1791 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - "
\r
1792 "clear TCP/IP addresses\n", port_num) );
\r
1796 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1797 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - "
\r
1798 "Non TCP/IP address type of 0x%.4X on clear\n",
\r
1799 port_num, p_net_addrs->AddressType) );
\r
1800 IPOIB_EXIT( IPOIB_DBG_OID );
\r
1801 return NDIS_STATUS_SUCCESS;
\r
1805 addr_size = FIELD_OFFSET(NETWORK_ADDRESS, Address) +
\r
1806 NETWORK_ADDRESS_LENGTH_IP;
\r
1807 total_size = FIELD_OFFSET(NETWORK_ADDRESS_LIST, Address) +
\r
1808 addr_size * p_net_addrs->AddressCount;
\r
1810 if( info_buf_len < total_size )
\r
1812 IPOIB_TRACE( IPOIB_DBG_ERROR,
\r
1813 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - "
\r
1814 "bad length of %d, %d required for %d addresses\n",
\r
1815 port_num, info_buf_len, total_size, p_net_addrs->AddressCount) );
\r
1816 *p_bytes_needed = total_size;
\r
1817 IPOIB_EXIT( IPOIB_DBG_OID );
\r
1818 return NDIS_STATUS_INVALID_LENGTH;
\r
1821 /* Lock lists for duration since SA callbacks can occur on other CPUs */
\r
1822 cl_obj_lock( &p_adapter->obj );
\r
1824 /* Set the capacity of the vector to accomodate all assinged addresses. */
\r
1825 cl_status = cl_vector_set_capacity(
\r
1826 &p_adapter->ip_vector, p_net_addrs->AddressCount );
\r
1827 if( cl_status != CL_SUCCESS )
\r
1829 cl_obj_unlock( &p_adapter->obj );
\r
1830 IPOIB_TRACE( IPOIB_DBG_ERROR,
\r
1831 ("Port %d - OID_GEN_NETWORK_LAYER_ADDRESSES - "
\r
1832 "Failed to set IP vector capacity: %s\n",
\r
1833 CL_STATUS_MSG(cl_status)) );
\r
1834 IPOIB_EXIT( IPOIB_DBG_OID );
\r
1835 return NDIS_STATUS_RESOURCES;
\r
1838 *p_bytes_read = total_size;
\r
1840 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1841 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - List contains %d addresses\n",
\r
1842 port_num, p_net_addrs->AddressCount));
\r
1844 /* First look for addresses we had that should be removed */
\r
1845 for( idx = 0; idx != cl_vector_get_size( &p_adapter->ip_vector ); idx++ )
\r
1847 p_addr_item = (net_address_item_t*)
\r
1848 cl_vector_get_ptr( &p_adapter->ip_vector, idx );
\r
1849 p_net_addr_oid = (PNETWORK_ADDRESS)p_net_addrs->Address;
\r
1851 for( i = 0; i < p_net_addrs->AddressCount; ++i, p_net_addr_oid =
\r
1852 (PNETWORK_ADDRESS)((uint8_t *)p_net_addr_oid +
\r
1853 FIELD_OFFSET(NETWORK_ADDRESS, Address) +
\r
1854 p_net_addr_oid->AddressLength) )
\r
1857 if( p_net_addr_oid->AddressType != NDIS_PROTOCOL_ID_TCP_IP )
\r
1859 IPOIB_TRACE( IPOIB_DBG_WARN,
\r
1860 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong type of 0x%.4X, "
\r
1861 "should be 0x%.4X\n", port_num, i, p_net_addr_oid->AddressType,
\r
1862 NDIS_PROTOCOL_ID_TCP_IP));
\r
1866 if( p_net_addr_oid->AddressLength != NETWORK_ADDRESS_LENGTH_IP)
\r
1868 IPOIB_TRACE( IPOIB_DBG_WARN,
\r
1869 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong size of %d, "
\r
1870 "should be %d\n", port_num, i, p_net_addr_oid->AddressLength,
\r
1871 NETWORK_ADDRESS_LENGTH_IP));
\r
1875 p_ip_addr = (PNETWORK_ADDRESS_IP)p_net_addr_oid->Address;
\r
1876 if( !cl_memcmp( &p_ip_addr->in_addr,
\r
1877 &p_addr_item->address.as_ulong, sizeof(ULONG) ) )
\r
1883 if( i == p_net_addrs->AddressCount )
\r
1885 /* Didn't find a match, delete from SA */
\r
1886 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1887 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Deleting Address %d.%d.%d.%d\n",
\r
1889 p_addr_item->address.as_bytes[0],
\r
1890 p_addr_item->address.as_bytes[1],
\r
1891 p_addr_item->address.as_bytes[2],
\r
1892 p_addr_item->address.as_bytes[3]));
\r
1894 if( p_addr_item->h_reg_svc )
\r
1896 p_adapter->p_ifc->dereg_svc( p_addr_item->h_reg_svc, NULL );
\r
1897 p_addr_item->h_reg_svc = NULL;
\r
1899 p_addr_item->address.as_ulong = 0;
\r
1903 /* Now look for new addresses */
\r
1904 p_net_addr_oid = (NETWORK_ADDRESS *)p_net_addrs->Address;
\r
1906 for( i = 0; i < p_net_addrs->AddressCount; i++, p_net_addr_oid =
\r
1907 (PNETWORK_ADDRESS)((uint8_t *)p_net_addr_oid +
\r
1908 FIELD_OFFSET(NETWORK_ADDRESS, Address) + p_net_addr_oid->AddressLength) )
\r
1911 if( p_net_addr_oid->AddressType != NDIS_PROTOCOL_ID_TCP_IP )
\r
1913 IPOIB_TRACE( IPOIB_DBG_WARN,
\r
1914 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong type of 0x%.4X, "
\r
1915 "should be 0x%.4X\n", port_num, i, p_net_addr_oid->AddressType,
\r
1916 NDIS_PROTOCOL_ID_TCP_IP));
\r
1920 if( p_net_addr_oid->AddressLength != NETWORK_ADDRESS_LENGTH_IP)
\r
1922 IPOIB_TRACE( IPOIB_DBG_WARN,
\r
1923 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Address %d is wrong size of %d, "
\r
1924 "should be %d\n", port_num, i, p_net_addr_oid->AddressLength,
\r
1925 NETWORK_ADDRESS_LENGTH_IP));
\r
1929 p_ip_addr = (PNETWORK_ADDRESS_IP)p_net_addr_oid->Address;
\r
1931 /* Size the vector as needed. */
\r
1932 if( cl_vector_get_size( &p_adapter->ip_vector ) <= idx )
\r
1933 cl_vector_set_size( &p_adapter->ip_vector, idx + 1 );
\r
1935 p_addr_item = cl_vector_get_ptr( &p_adapter->ip_vector, idx );
\r
1936 if( !cl_memcmp( &p_ip_addr->in_addr, &p_addr_item->address.as_ulong,
\r
1940 /* Already have this address - no change needed */
\r
1945 * Copy the address information, but don't register yet - the port
\r
1948 p_addr_item->p_adapter = p_adapter;
\r
1949 if( p_addr_item->h_reg_svc )
\r
1951 /* If in use by some other address, deregister. */
\r
1952 p_adapter->p_ifc->dereg_svc( p_addr_item->h_reg_svc, NULL );
\r
1953 p_addr_item->h_reg_svc = NULL;
\r
1955 memcpy ((void *)&p_addr_item->address.as_ulong, (const void *)&p_ip_addr->in_addr, sizeof(ULONG) );
\r
1956 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
1957 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Adding Address %d.%d.%d.%d\n",
\r
1959 p_addr_item->address.as_bytes[0],
\r
1960 p_addr_item->address.as_bytes[1],
\r
1961 p_addr_item->address.as_bytes[2],
\r
1962 p_addr_item->address.as_bytes[3]) );
\r
1966 /* Now clear any extra entries that shouldn't be there. */
\r
1967 while( idx < cl_vector_get_size( &p_adapter->ip_vector ) )
\r
1969 p_addr_item = (net_address_item_t*)
\r
1970 cl_vector_get_ptr( &p_adapter->ip_vector,
\r
1971 cl_vector_get_size( &p_adapter->ip_vector ) - 1 );
\r
1973 if( p_addr_item->h_reg_svc )
\r
1975 p_adapter->p_ifc->dereg_svc( p_addr_item->h_reg_svc, NULL );
\r
1976 p_addr_item->h_reg_svc = NULL;
\r
1977 p_addr_item->address.as_ulong = 0;
\r
1980 /* No need to check return value - shrinking always succeeds. */
\r
1981 cl_vector_set_size( &p_adapter->ip_vector,
\r
1982 cl_vector_get_size( &p_adapter->ip_vector ) - 1 );
\r
1985 if( p_adapter->state == IB_PNP_PORT_ACTIVE && p_adapter->packet_filter )
\r
1986 ipoib_reg_addrs( p_adapter );
\r
1988 cl_obj_unlock( &p_adapter->obj );
\r
1990 IPOIB_EXIT( IPOIB_DBG_OID );
\r
1991 return NDIS_STATUS_SUCCESS;
\r
1995 /* Object lock is held when this function is called. */
\r
1998 IN ipoib_adapter_t* const p_adapter )
\r
2000 net_address_item_t *p_addr_item;
\r
2006 ib_api_status_t ib_status;
\r
2007 ib_reg_svc_req_t ib_service;
\r
2008 ib_gid_t port_gid;
\r
2010 IPOIB_ENTER( IPOIB_DBG_OID );
\r
2012 port_num = IPOIB_ADAPTER_GET_PORT_NUM( p_adapter );
\r
2014 /* Setup our service call with things common to all calls */
\r
2015 cl_memset( &ib_service, 0, sizeof(ib_service) );
\r
2017 /* BUGBUG Only register local subnet GID prefix for now */
\r
2018 ib_gid_set_default( &port_gid, p_adapter->guids.port_guid );
\r
2019 ib_service.svc_rec.service_gid = port_gid;
\r
2021 ib_service.svc_rec.service_pkey = IB_DEFAULT_PKEY;
\r
2022 ib_service.svc_rec.service_lease = IB_INFINITE_SERVICE_LEASE;
\r
2024 /* Must cast here because the service name is an array of unsigned chars but
\r
2025 * strcpy want a pointer to a signed char */
\r
2026 strcpy( (char *)ib_service.svc_rec.service_name, ATS_NAME );
\r
2028 /* IP Address in question will be put in below */
\r
2029 ib_service.port_guid = p_adapter->guids.port_guid;
\r
2030 ib_service.timeout_ms = DEFAULT_SA_TIMEOUT;
\r
2031 ib_service.retry_cnt = DEFAULT_SA_RETRIES;
\r
2032 ib_service.svc_context = p_adapter;
\r
2034 /* Can't set IB_FLAGS_SYNC here because I can't wait at dispatch */
\r
2035 ib_service.flags = 0;
\r
2037 /* Service context will be put in below */
\r
2039 ib_service.svc_data_mask = IB_SR_COMPMASK_SID |
\r
2040 IB_SR_COMPMASK_SGID |
\r
2041 IB_SR_COMPMASK_SPKEY |
\r
2042 IB_SR_COMPMASK_SLEASE |
\r
2043 IB_SR_COMPMASK_SNAME |
\r
2044 IB_SR_COMPMASK_SDATA8_12 |
\r
2045 IB_SR_COMPMASK_SDATA8_13 |
\r
2046 IB_SR_COMPMASK_SDATA8_14 |
\r
2047 IB_SR_COMPMASK_SDATA8_15;
\r
2048 ib_service.pfn_reg_svc_cb = __ipoib_ats_reg_cb;
\r
2050 for( idx = 0; idx < cl_vector_get_size( &p_adapter->ip_vector); idx++ )
\r
2052 p_addr_item = (net_address_item_t*)
\r
2053 cl_vector_get_ptr( &p_adapter->ip_vector, idx );
\r
2055 if( p_addr_item->h_reg_svc )
\r
2058 ib_service.svc_rec.service_id = ATS_SERVICE_ID;
\r
2059 ib_service.svc_rec.service_id |= ((uint64_t)idx) << 56;
\r
2061 cl_memcpy( &ib_service.svc_rec.service_data8[ATS_IPV4_OFFSET],
\r
2062 p_addr_item->address.as_bytes, IPV4_ADDR_SIZE );
\r
2064 ib_status = p_adapter->p_ifc->reg_svc(
\r
2065 p_adapter->h_al, &ib_service, &p_addr_item->h_reg_svc );
\r
2066 if( ib_status != IB_SUCCESS )
\r
2068 if( ib_status == IB_INVALID_GUID )
\r
2070 /* If this occurs, we log the error but do not fail the OID yet */
\r
2071 IPOIB_TRACE( IPOIB_DBG_WARN,
\r
2072 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - "
\r
2073 "Failed to register IP Address "
\r
2074 "of %d.%d.%d.%d with error IB_INVALID_GUID\n",
\r
2076 p_addr_item->address.as_bytes[0],
\r
2077 p_addr_item->address.as_bytes[1],
\r
2078 p_addr_item->address.as_bytes[2],
\r
2079 p_addr_item->address.as_bytes[3]) );
\r
2083 /* Fatal error. */
\r
2084 IPOIB_TRACE( IPOIB_DBG_ERROR,
\r
2085 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Failed to register IP Address "
\r
2086 "of %d.%d.%d.%d with error %s\n",
\r
2088 p_addr_item->address.as_bytes[0],
\r
2089 p_addr_item->address.as_bytes[1],
\r
2090 p_addr_item->address.as_bytes[2],
\r
2091 p_addr_item->address.as_bytes[3],
\r
2092 p_adapter->p_ifc->get_err_str( ib_status )) );
\r
2093 p_adapter->hung = TRUE;
\r
2098 IPOIB_EXIT( IPOIB_DBG_OID );
\r
2102 /* Object lock is held when this function is called. */
\r
2104 __ipoib_dereg_addrs(
\r
2105 IN ipoib_adapter_t* const p_adapter )
\r
2107 net_address_item_t *p_addr_item;
\r
2111 IPOIB_ENTER( IPOIB_DBG_OID );
\r
2113 for( idx = 0; idx < cl_vector_get_size( &p_adapter->ip_vector); idx++ )
\r
2115 p_addr_item = (net_address_item_t*)
\r
2116 cl_vector_get_ptr( &p_adapter->ip_vector, idx );
\r
2118 if( !p_addr_item->h_reg_svc )
\r
2121 p_adapter->p_ifc->dereg_svc(
\r
2122 p_addr_item->h_reg_svc, NULL );
\r
2123 p_addr_item->h_reg_svc = NULL;
\r
2126 IPOIB_EXIT( IPOIB_DBG_OID );
\r
2131 __ipoib_ats_reg_cb(
\r
2132 IN ib_reg_svc_rec_t *p_reg_svc_rec )
\r
2134 ipoib_adapter_t * p_adapter;
\r
2137 IPOIB_ENTER( IPOIB_DBG_OID );
\r
2139 CL_ASSERT( p_reg_svc_rec );
\r
2140 CL_ASSERT( p_reg_svc_rec->svc_context );
\r
2142 p_adapter = (ipoib_adapter_t* __ptr64)p_reg_svc_rec->svc_context;
\r
2143 port_num = IPOIB_ADAPTER_GET_PORT_NUM( p_adapter );
\r
2145 if( p_reg_svc_rec->req_status == IB_SUCCESS &&
\r
2146 !p_reg_svc_rec->resp_status )
\r
2148 IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,
\r
2149 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Registered IP Address "
\r
2150 "of %d.%d.%d.%d\n",
\r
2152 p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET],
\r
2153 p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+1],
\r
2154 p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+2],
\r
2155 p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+3]) );
\r
2157 else if( p_reg_svc_rec->req_status != IB_CANCELED )
\r
2159 IPOIB_TRACE( IPOIB_DBG_ERROR,
\r
2160 ("Port %d OID_GEN_NETWORK_LAYER_ADDRESSES - Failed to register IP Address "
\r
2161 "of %d.%d.%d.%d with error %s\n",
\r
2163 p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET],
\r
2164 p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+1],
\r
2165 p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+2],
\r
2166 p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+3],
\r
2167 p_adapter->p_ifc->get_err_str( p_reg_svc_rec->resp_status )) );
\r
2168 p_adapter->hung = TRUE;
\r
2171 IPOIB_EXIT( IPOIB_DBG_OID );
\r