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
6 * This software is available to you under the OpenIB.org BSD license
\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
13 * - Redistributions of source code must retain the above
\r
14 * copyright notice, this list of conditions and the following
\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
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
36 #include "ipoib_adapter.h"
\r
37 #include "ipoib_port.h"
\r
38 #include "ipoib_driver.h"
\r
39 #include "ipoib_debug.h"
\r
41 #if defined(EVENT_TRACING)
\r
45 #include "ipoib_adapter.tmh"
\r
49 #define ITEM_POOL_START 16
\r
50 #define ITEM_POOL_GROW 16
\r
53 /* IB Link speeds in 100bps */
\r
54 #define ONE_X_IN_100BPS 25000000
\r
55 #define FOUR_X_IN_100BPS 100000000
\r
56 #define TWELVE_X_IN_100BPS 300000000
\r
62 IN ipoib_adapter_t* const p_adapter );
\r
65 static ib_api_status_t
\r
67 IN ipoib_adapter_t* const p_adapter );
\r
71 __adapter_destroying(
\r
72 IN cl_obj_t* const p_obj );
\r
77 IN cl_obj_t* const p_obj );
\r
82 IN cl_obj_t* const p_obj );
\r
85 static ib_api_status_t
\r
87 IN ipoib_adapter_t* const p_adapter,
\r
88 IN ib_pnp_class_t flags );
\r
97 __ipoib_adapter_reset(
\r
101 static ib_api_status_t
\r
103 IN ib_pnp_rec_t *p_pnp_rec );
\r
108 IN ipoib_adapter_t* const p_adapter );
\r
111 /* Leaves all mcast groups when port goes down. */
\r
114 IN ipoib_port_t* const p_port );
\r
117 ipoib_get_adapter_guids(
\r
118 IN NDIS_HANDLE* const h_adapter,
\r
119 IN OUT ipoib_adapter_t *p_adapter );
\r
122 ipoib_get_adapter_params(
\r
123 IN NDIS_HANDLE* const wrapper_config_context,
\r
124 IN OUT ipoib_adapter_t *p_adapter );
\r
127 /* Implementation */
\r
129 ipoib_create_adapter(
\r
130 IN NDIS_HANDLE wrapper_config_context,
\r
131 IN void* const h_adapter,
\r
132 OUT ipoib_adapter_t** const pp_adapter )
\r
134 ipoib_adapter_t *p_adapter;
\r
135 ib_api_status_t status;
\r
136 cl_status_t cl_status;
\r
138 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
140 p_adapter = cl_zalloc( sizeof(ipoib_adapter_t) );
\r
143 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
144 ("Failed to allocate ipoib_adapter_t (%d bytes)",
\r
145 sizeof(ipoib_adapter_t)) );
\r
146 return IB_INSUFFICIENT_MEMORY;
\r
149 adapter_construct( p_adapter );
\r
151 p_adapter->h_adapter = h_adapter;
\r
153 p_adapter->p_ifc = cl_zalloc( sizeof(ib_al_ifc_t) );
\r
154 if( !p_adapter->p_ifc )
\r
156 __adapter_free( &p_adapter->obj );
\r
157 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
158 ("ipoib_create_adapter failed to alloc ipoib_ifc_t %d bytes\n",
\r
159 sizeof(ib_al_ifc_t)) );
\r
160 return IB_INSUFFICIENT_MEMORY;
\r
163 /* Get the CA and port GUID from the bus driver. */
\r
164 status = ipoib_get_adapter_guids( h_adapter, p_adapter );
\r
165 if( status != NDIS_STATUS_SUCCESS )
\r
167 __adapter_free( &p_adapter->obj );
\r
168 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
169 ("ipoib_get_adapter_guids returned 0x%.8X.\n", status) );
\r
173 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,
\r
174 ("Port %016I64x (CA %016I64x port %d) initializing\n",
\r
175 p_adapter->guids.port_guid.guid, p_adapter->guids.ca_guid,
\r
176 p_adapter->guids.port_num) );
\r
178 cl_status = cl_obj_init( &p_adapter->obj, CL_DESTROY_SYNC,
\r
179 __adapter_destroying, NULL, __adapter_free );
\r
180 if( cl_status != CL_SUCCESS )
\r
182 __adapter_free( &p_adapter->obj );
\r
183 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
184 ("cl_obj_init returned %#x\n", cl_status) );
\r
188 status = adapter_init( p_adapter );
\r
189 if( status != IB_SUCCESS )
\r
191 cl_obj_destroy( &p_adapter->obj );
\r
192 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
193 ("adapter_init returned %s.\n",
\r
194 p_adapter->p_ifc->get_err_str( status )) );
\r
198 /* Read configuration parameters. */
\r
199 status = ipoib_get_adapter_params( wrapper_config_context,
\r
201 if( status != NDIS_STATUS_SUCCESS )
\r
203 cl_obj_destroy( &p_adapter->obj );
\r
204 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
205 ("ipoib_get_adapter_params returned 0x%.8x.\n", status) );
\r
209 *pp_adapter = p_adapter;
\r
211 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
217 ipoib_start_adapter(
\r
218 IN ipoib_adapter_t* const p_adapter )
\r
220 ib_api_status_t status;
\r
222 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
224 status = __ipoib_pnp_reg( p_adapter,
\r
225 IB_PNP_FLAG_REG_SYNC | IB_PNP_FLAG_REG_COMPLETE );
\r
227 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
233 ipoib_destroy_adapter(
\r
234 IN ipoib_adapter_t* const p_adapter )
\r
236 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
238 CL_ASSERT( p_adapter );
\r
241 * Flag the adapter as being removed. We use the IB_PNP_PORT_REMOVE state
\r
242 * for this purpose. Note that we protect this state change with both the
\r
243 * mutex and the lock. The mutex provides synchronization as a whole
\r
244 * between destruction and AL callbacks (PnP, Query, Destruction).
\r
245 * The lock provides protection
\r
247 KeWaitForMutexObject(
\r
248 &p_adapter->mutex, Executive, KernelMode, FALSE, NULL );
\r
249 cl_obj_lock( &p_adapter->obj );
\r
250 p_adapter->state = IB_PNP_PORT_REMOVE;
\r
253 * Clear the pointer to the port object since the object destruction
\r
254 * will cascade to child objects. This prevents potential duplicate
\r
255 * destruction (or worse, stale pointer usage).
\r
257 p_adapter->p_port = NULL;
\r
259 cl_obj_unlock( &p_adapter->obj );
\r
261 KeReleaseMutex( &p_adapter->mutex, FALSE );
\r
263 cl_obj_destroy( &p_adapter->obj );
\r
265 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
271 IN ipoib_adapter_t* const p_adapter )
\r
273 cl_obj_construct( &p_adapter->obj, IPOIB_OBJ_INSTANCE );
\r
274 cl_spinlock_construct( &p_adapter->send_stat_lock );
\r
275 cl_spinlock_construct( &p_adapter->recv_stat_lock );
\r
276 cl_qpool_construct( &p_adapter->item_pool );
\r
277 KeInitializeMutex( &p_adapter->mutex, 0 );
\r
279 cl_thread_construct(&p_adapter->destroy_thread);
\r
281 cl_vector_construct( &p_adapter->ip_vector );
\r
283 cl_perf_construct( &p_adapter->perf );
\r
285 p_adapter->state = IB_PNP_PORT_ADD;
\r
286 p_adapter->rate = FOUR_X_IN_100BPS;
\r
290 static ib_api_status_t
\r
292 IN ipoib_adapter_t* const p_adapter )
\r
294 cl_status_t cl_status;
\r
295 ib_api_status_t status;
\r
297 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
299 cl_status = cl_perf_init( &p_adapter->perf, MaxPerf );
\r
300 if( cl_status != CL_SUCCESS )
\r
302 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
303 ("cl_perf_init returned %#x\n", cl_status) );
\r
307 cl_status = cl_spinlock_init( &p_adapter->send_stat_lock );
\r
308 if( cl_status != CL_SUCCESS )
\r
310 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
311 ("cl_spinlock_init returned %#x\n", cl_status) );
\r
315 cl_status = cl_spinlock_init( &p_adapter->recv_stat_lock );
\r
316 if( cl_status != CL_SUCCESS )
\r
318 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
319 ("cl_spinlock_init returned %#x\n", cl_status) );
\r
323 cl_status = cl_qpool_init( &p_adapter->item_pool, ITEM_POOL_START, 0,
\r
324 ITEM_POOL_GROW, sizeof(cl_pool_obj_t), NULL, NULL, NULL );
\r
325 if( cl_status != CL_SUCCESS )
\r
327 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
328 ("cl_qpool_init returned %#x\n", cl_status) );
\r
333 /* We manually manage the size and capacity of the vector. */
\r
334 cl_status = cl_vector_init( &p_adapter->ip_vector, 0,
\r
335 0, sizeof(net_address_item_t), NULL, NULL, p_adapter );
\r
336 if( cl_status != CL_SUCCESS )
\r
338 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
339 ("cl_vector_init for ip_vector returned %#x\n",
\r
345 /* Validate the port GUID and generate the MAC address. */
\r
347 ipoib_mac_from_guid( p_adapter->guids.port_guid.guid, p_adapter->params.guid_mask, &p_adapter->mac);
\r
348 if( status != IB_SUCCESS )
\r
350 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
351 ("ipoib_mac_from_guid returned %s\n",
\r
352 p_adapter->p_ifc->get_err_str( status )) );
\r
359 status = p_adapter->p_ifc->open_al( &p_adapter->h_al );
\r
360 if( status != IB_SUCCESS )
\r
362 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
363 ("ib_open_al returned %s\n",
\r
364 p_adapter->p_ifc->get_err_str( status )) );
\r
368 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
373 static ib_api_status_t
\r
375 IN ipoib_adapter_t* const p_adapter,
\r
376 IN ib_pnp_class_t flags )
\r
378 ib_api_status_t status;
\r
379 ib_pnp_req_t pnp_req;
\r
381 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
383 CL_ASSERT( !p_adapter->h_pnp );
\r
384 CL_ASSERT( !p_adapter->registering );
\r
386 p_adapter->registering = TRUE;
\r
388 /* Register for PNP events. */
\r
389 cl_memclr( &pnp_req, sizeof(pnp_req) );
\r
390 pnp_req.pnp_class = IB_PNP_PORT | flags;
\r
392 * Context is the cl_obj of the adapter to allow passing cl_obj_deref
\r
395 pnp_req.pnp_context = &p_adapter->obj;
\r
396 pnp_req.pfn_pnp_cb = __ipoib_pnp_cb;
\r
397 status = p_adapter->p_ifc->reg_pnp( p_adapter->h_al, &pnp_req, &p_adapter->h_pnp );
\r
398 if( status != IB_SUCCESS )
\r
400 p_adapter->registering = FALSE;
\r
401 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
402 ("ib_reg_pnp returned %s\n",
\r
403 p_adapter->p_ifc->get_err_str( status )) );
\r
407 * Reference the adapter on behalf of the PNP registration.
\r
408 * This allows the destruction to block until the PNP deregistration
\r
411 cl_obj_ref( &p_adapter->obj );
\r
413 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
419 __adapter_destroying(
\r
420 IN cl_obj_t* const p_obj )
\r
422 ipoib_adapter_t *p_adapter;
\r
423 KLOCK_QUEUE_HANDLE hdl;
\r
425 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
427 p_adapter = PARENT_STRUCT( p_obj, ipoib_adapter_t, obj );
\r
430 * The adapter's object will be dereferenced when the deregistration
\r
431 * completes. No need to lock here since all PnP related API calls
\r
432 * are driven by NDIS (via the Init/Reset/Destroy paths).
\r
434 if( p_adapter->h_pnp )
\r
436 p_adapter->p_ifc->dereg_pnp( p_adapter->h_pnp, cl_obj_deref );
\r
437 p_adapter->h_pnp = NULL;
\r
440 if( p_adapter->packet_filter )
\r
442 KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );
\r
443 cl_obj_lock( &p_adapter->obj );
\r
445 ASSERT( cl_qlist_count( &g_ipoib.adapter_list ) );
\r
446 cl_qlist_remove_item( &g_ipoib.adapter_list, &p_adapter->entry );
\r
448 p_adapter->packet_filter = 0;
\r
450 cl_obj_unlock( &p_adapter->obj );
\r
451 KeReleaseInStackQueuedSpinLock( &hdl );
\r
454 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
460 IN cl_obj_t* const p_obj )
\r
462 ipoib_adapter_t *p_adapter;
\r
464 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
466 p_adapter = PARENT_STRUCT( p_obj, ipoib_adapter_t, obj );
\r
468 if( p_adapter->p_ifc )
\r
470 if( p_adapter->h_al )
\r
471 p_adapter->p_ifc->close_al( p_adapter->h_al );
\r
473 cl_free( p_adapter->p_ifc );
\r
476 cl_vector_destroy( &p_adapter->ip_vector );
\r
477 cl_qpool_destroy( &p_adapter->item_pool );
\r
478 cl_spinlock_destroy( &p_adapter->recv_stat_lock );
\r
479 cl_spinlock_destroy( &p_adapter->send_stat_lock );
\r
480 cl_obj_deinit( p_obj );
\r
482 cl_perf_destroy( &p_adapter->perf, TRUE );
\r
484 cl_free( p_adapter );
\r
486 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
490 static ib_api_status_t
\r
491 ipoib_query_pkey_index(ipoib_adapter_t *p_adapter)
\r
493 ib_api_status_t status;
\r
494 ib_ca_attr_t *ca_attr;
\r
496 uint16_t index = 0;
\r
498 /* Query the CA for Pkey table */
\r
499 status = p_adapter->p_ifc->query_ca(p_adapter->p_port->ib_mgr.h_ca, NULL, &ca_size);
\r
500 if(status != IB_INSUFFICIENT_MEMORY)
\r
502 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
503 ("ib_query_ca failed\n"));
\r
507 ca_attr = (ib_ca_attr_t*)cl_zalloc(ca_size);
\r
510 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
511 ("cl_zalloc can't allocate %d\n",ca_size));
\r
512 return IB_INSUFFICIENT_MEMORY;
\r
515 status = p_adapter->p_ifc->query_ca(p_adapter->p_port->ib_mgr.h_ca, ca_attr,&ca_size);
\r
516 if( status != IB_SUCCESS )
\r
518 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
519 ("ib_query_ca returned %s\n",
\r
520 p_adapter->p_ifc->get_err_str( status )) );
\r
524 CL_ASSERT(ca_attr->p_port_attr->p_pkey_table[0] == IB_DEFAULT_PKEY);
\r
525 for(index = 0; index < ca_attr->p_port_attr->num_pkeys; index++)
\r
527 if(cl_hton16(p_adapter->guids.port_guid.pkey) == ca_attr->p_port_attr->p_pkey_table[index])
\r
530 if(index >= ca_attr->p_port_attr->num_pkeys)
\r
532 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
533 ("Pkey table is invalid, index not found\n"));
\r
534 NdisWriteErrorLogEntry( p_adapter->h_adapter,
\r
535 EVENT_IPOIB_PARTITION_ERR, 1, p_adapter->guids.port_guid.pkey );
\r
536 p_adapter->p_port->pkey_index = PKEY_INVALID_INDEX;
\r
540 p_adapter->p_port->pkey_index = index;
\r
541 IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_IB,
\r
542 ("for PKEY = 0x%04X got index = %d\n",p_adapter->guids.port_guid.pkey,index));
\r
550 static ib_api_status_t
\r
552 IN ib_pnp_rec_t *p_pnp_rec )
\r
554 ipoib_adapter_t *p_adapter;
\r
555 ipoib_port_t *p_port;
\r
556 ib_pnp_event_t old_state;
\r
557 ib_pnp_port_rec_t *p_port_rec;
\r
558 ib_api_status_t status = IB_SUCCESS;
\r
560 IPOIB_ENTER( IPOIB_DBG_PNP );
\r
562 CL_ASSERT( p_pnp_rec );
\r
565 PARENT_STRUCT( p_pnp_rec->pnp_context, ipoib_adapter_t, obj );
\r
567 CL_ASSERT( p_adapter );
\r
569 /* Synchronize with destruction */
\r
570 KeWaitForMutexObject(
\r
571 &p_adapter->mutex, Executive, KernelMode, FALSE, NULL );
\r
572 cl_obj_lock( &p_adapter->obj );
\r
573 old_state = p_adapter->state;
\r
574 cl_obj_unlock( &p_adapter->obj );
\r
575 if( old_state == IB_PNP_PORT_REMOVE )
\r
577 KeReleaseMutex( &p_adapter->mutex, FALSE );
\r
578 IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_PNP,
\r
579 ("Aborting - Adapter destroying.\n") );
\r
580 return IB_NOT_DONE;
\r
583 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_PNP,
\r
584 ("p_pnp_rec->pnp_event = 0x%x (%s)\n",
\r
585 p_pnp_rec->pnp_event, ib_get_pnp_event_str( p_pnp_rec->pnp_event )) );
\r
587 p_port_rec = (ib_pnp_port_rec_t*)p_pnp_rec;
\r
589 switch( p_pnp_rec->pnp_event )
\r
591 case IB_PNP_PORT_ADD:
\r
592 CL_ASSERT( !p_pnp_rec->context );
\r
593 /* Only process our port GUID. */
\r
594 if( p_pnp_rec->guid != p_adapter->guids.port_guid.guid )
\r
596 status = IB_NOT_DONE;
\r
600 /* Don't process if we're destroying. */
\r
601 if( p_adapter->obj.state == CL_DESTROYING )
\r
603 status = IB_NOT_DONE;
\r
607 CL_ASSERT( !p_adapter->p_port );
\r
608 /* Allocate all IB resources. */
\r
609 cl_obj_lock( &p_adapter->obj );
\r
610 p_adapter->state = IB_PNP_PORT_ADD;
\r
611 cl_obj_unlock( &p_adapter->obj );
\r
612 status = ipoib_create_port( p_adapter, p_port_rec, &p_port );
\r
613 cl_obj_lock( &p_adapter->obj );
\r
614 if( status != IB_SUCCESS )
\r
616 p_adapter->state = old_state;
\r
617 cl_obj_unlock( &p_adapter->obj );
\r
618 p_adapter->hung = TRUE;
\r
622 p_pnp_rec->context = p_port;
\r
624 p_adapter->p_port = p_port;
\r
625 cl_obj_unlock( &p_adapter->obj );
\r
628 case IB_PNP_PORT_REMOVE:
\r
629 /* Release all IB resources. */
\r
630 CL_ASSERT( p_pnp_rec->context );
\r
632 cl_obj_lock( &p_adapter->obj );
\r
633 p_adapter->state = IB_PNP_PORT_REMOVE;
\r
634 p_port = p_adapter->p_port;
\r
635 p_adapter->p_port = NULL;
\r
636 cl_obj_unlock( &p_adapter->obj );
\r
637 ipoib_port_destroy( p_port );
\r
638 p_pnp_rec->context = NULL;
\r
639 status = IB_SUCCESS;
\r
642 case IB_PNP_PORT_ACTIVE:
\r
643 /* Join multicast groups and put QP in RTS. */
\r
644 CL_ASSERT( p_pnp_rec->context );
\r
646 cl_obj_lock( &p_adapter->obj );
\r
647 p_adapter->state = IB_PNP_PORT_INIT;
\r
648 cl_obj_unlock( &p_adapter->obj );
\r
649 ipoib_port_up( p_adapter->p_port, p_port_rec );
\r
651 status = IB_SUCCESS;
\r
654 case IB_PNP_PORT_ARMED:
\r
655 status = IB_SUCCESS;
\r
658 case IB_PNP_PORT_INIT:
\r
660 * Init could happen if the SM brings the port down
\r
661 * without changing the physical link.
\r
663 case IB_PNP_PORT_DOWN:
\r
664 CL_ASSERT( p_pnp_rec->context );
\r
666 cl_obj_lock( &p_adapter->obj );
\r
667 old_state = p_adapter->state;
\r
668 p_adapter->state = IB_PNP_PORT_DOWN;
\r
669 cl_obj_unlock( &p_adapter->obj );
\r
670 status = IB_SUCCESS;
\r
672 if( !p_adapter->registering && old_state != IB_PNP_PORT_DOWN )
\r
674 NdisMIndicateStatus( p_adapter->h_adapter,
\r
675 NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0 );
\r
676 NdisMIndicateStatusComplete( p_adapter->h_adapter );
\r
678 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,
\r
679 ("Link DOWN!\n") );
\r
681 ipoib_port_down( p_adapter->p_port );
\r
685 case IB_PNP_REG_COMPLETE:
\r
686 if( p_adapter->registering )
\r
688 p_adapter->registering = FALSE;
\r
689 cl_obj_lock( &p_adapter->obj );
\r
690 old_state = p_adapter->state;
\r
691 cl_obj_unlock( &p_adapter->obj );
\r
693 if( old_state == IB_PNP_PORT_DOWN )
\r
695 /* If we were initializing, we might have pended some OIDs. */
\r
696 ipoib_resume_oids( p_adapter );
\r
697 NdisMIndicateStatus( p_adapter->h_adapter,
\r
698 NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0 );
\r
699 NdisMIndicateStatusComplete( p_adapter->h_adapter );
\r
703 if( p_adapter->reset && p_adapter->state != IB_PNP_PORT_INIT )
\r
705 p_adapter->reset = FALSE;
\r
706 NdisMResetComplete(
\r
707 p_adapter->h_adapter, NDIS_STATUS_SUCCESS, TRUE );
\r
709 status = IB_SUCCESS;
\r
713 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,
\r
714 ("IPOIB: Received unhandled PnP event 0x%x (%s)\n",
\r
715 p_pnp_rec->pnp_event, ib_get_pnp_event_str( p_pnp_rec->pnp_event )) );
\r
716 /* Fall through. */
\r
718 status = IB_SUCCESS;
\r
720 /* We ignore events below if the link is not active. */
\r
721 if( p_port_rec->p_port_attr->link_state != IB_LINK_ACTIVE )
\r
724 case IB_PNP_PKEY_CHANGE:
\r
725 if(p_pnp_rec->pnp_event == IB_PNP_PKEY_CHANGE &&
\r
726 p_adapter->guids.port_guid.pkey != IB_DEFAULT_PKEY)
\r
728 status = ipoib_query_pkey_index(p_adapter);
\r
729 if(status != IB_SUCCESS)
\r
733 case IB_PNP_SM_CHANGE:
\r
734 case IB_PNP_GID_CHANGE:
\r
735 case IB_PNP_LID_CHANGE:
\r
737 cl_obj_lock( &p_adapter->obj );
\r
738 old_state = p_adapter->state;
\r
739 switch( old_state )
\r
741 case IB_PNP_PORT_DOWN:
\r
742 p_adapter->state = IB_PNP_PORT_INIT;
\r
746 p_adapter->state = IB_PNP_PORT_DOWN;
\r
748 cl_obj_unlock( &p_adapter->obj );
\r
750 if( p_adapter->registering )
\r
753 switch( old_state )
\r
755 case IB_PNP_PORT_ACTIVE:
\r
756 case IB_PNP_PORT_INIT:
\r
757 NdisMIndicateStatus( p_adapter->h_adapter,
\r
758 NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0 );
\r
759 NdisMIndicateStatusComplete( p_adapter->h_adapter );
\r
761 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,
\r
762 ("Link DOWN!\n") );
\r
764 ipoib_port_down( p_adapter->p_port );
\r
765 /* Fall through. */
\r
767 case IB_PNP_PORT_DOWN:
\r
768 cl_obj_lock( &p_adapter->obj );
\r
769 p_adapter->state = IB_PNP_PORT_INIT;
\r
770 cl_obj_unlock( &p_adapter->obj );
\r
771 ipoib_port_up( p_adapter->p_port, (ib_pnp_port_rec_t*)p_pnp_rec );
\r
776 KeReleaseMutex( &p_adapter->mutex, FALSE );
\r
778 IPOIB_EXIT( IPOIB_DBG_PNP );
\r
783 /* Joins/leaves mcast groups based on currently programmed mcast MACs. */
\r
785 ipoib_refresh_mcast(
\r
786 IN ipoib_adapter_t* const p_adapter,
\r
787 IN mac_addr_t* const p_mac_array,
\r
788 IN const uint8_t num_macs )
\r
791 ipoib_port_t *p_port = NULL;
\r
793 IPOIB_ENTER( IPOIB_DBG_MCAST );
\r
794 cl_obj_lock( &p_adapter->obj );
\r
795 if( p_adapter->state == IB_PNP_PORT_ACTIVE )
\r
797 p_port = p_adapter->p_port;
\r
798 ipoib_port_ref( p_port, ref_refresh_mcast );
\r
800 cl_obj_unlock( &p_adapter->obj );
\r
804 /* Purge old entries. */
\r
805 for( i = 0; i < p_adapter->mcast_array_size; i++ )
\r
807 for( j = 0; j < num_macs; j++ )
\r
809 if( !cl_memcmp( &p_adapter->mcast_array[i], &p_mac_array[j],
\r
810 sizeof(mac_addr_t) ) )
\r
815 if( j != num_macs )
\r
818 ipoib_port_remove_endpt( p_port, p_adapter->mcast_array[i] );
\r
821 /* Add new entries */
\r
822 for( i = 0; i < num_macs; i++ )
\r
824 for( j = 0; j < p_adapter->mcast_array_size; j++ )
\r
826 if( !cl_memcmp( &p_adapter->mcast_array[j], &p_mac_array[i],
\r
827 sizeof(mac_addr_t) ) )
\r
833 if( j != p_adapter->mcast_array_size )
\r
835 if ( ( p_mac_array[i].addr[0] == 1 && p_mac_array[i].addr[1] == 0 && p_mac_array[i].addr[2] == 0x5e &&
\r
836 p_mac_array[i].addr[3] == 0 && p_mac_array[i].addr[4] == 0 && p_mac_array[i].addr[5] == 1 ) ||
\r
837 !( p_mac_array[i].addr[0] == 1 && p_mac_array[i].addr[1] == 0 && p_mac_array[i].addr[2] == 0x5e )
\r
840 ipoib_port_join_mcast( p_port, p_mac_array[i], IB_MC_REC_STATE_FULL_MEMBER );
\r
845 /* Copy the MAC array. */
\r
846 NdisMoveMemory( p_adapter->mcast_array, p_mac_array,
\r
847 num_macs * sizeof(mac_addr_t) );
\r
848 p_adapter->mcast_array_size = num_macs;
\r
851 ipoib_port_deref( p_port, ref_refresh_mcast );
\r
853 IPOIB_EXIT( IPOIB_DBG_MCAST );
\r
858 ipoib_reset_adapter(
\r
859 IN ipoib_adapter_t* const p_adapter )
\r
861 ib_api_status_t status;
\r
862 ib_pnp_handle_t h_pnp;
\r
864 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
866 if( p_adapter->reset )
\r
867 return IB_INVALID_STATE;
\r
869 p_adapter->hung = FALSE;
\r
870 p_adapter->reset = TRUE;
\r
872 if( p_adapter->h_pnp )
\r
874 h_pnp = p_adapter->h_pnp;
\r
875 p_adapter->h_pnp = NULL;
\r
876 status = p_adapter->p_ifc->dereg_pnp( h_pnp, __ipoib_pnp_dereg );
\r
877 if( status == IB_SUCCESS )
\r
878 status = IB_NOT_DONE;
\r
882 status = __ipoib_pnp_reg( p_adapter, IB_PNP_FLAG_REG_COMPLETE );
\r
883 if( status == IB_SUCCESS )
\r
884 p_adapter->hung = FALSE;
\r
886 if (status == IB_NOT_DONE) {
\r
887 p_adapter->reset = TRUE;
\r
890 p_adapter->reset = FALSE;
\r
892 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
901 ipoib_adapter_t* p_adapter;
\r
903 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
905 p_adapter = PARENT_STRUCT( context, ipoib_adapter_t, obj );
\r
907 cl_thread_init(&p_adapter->destroy_thread, __ipoib_adapter_reset, (void*)p_adapter, "destroy_thread");
\r
909 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
914 __ipoib_adapter_reset(
\r
918 ipoib_adapter_t *p_adapter;
\r
919 ipoib_port_t *p_port;
\r
920 ib_api_status_t status;
\r
921 ib_pnp_event_t state;
\r
923 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
925 p_adapter = (ipoib_adapter_t*)context;
\r
927 /* Synchronize with destruction */
\r
928 KeWaitForMutexObject(
\r
929 &p_adapter->mutex, Executive, KernelMode, FALSE, NULL );
\r
931 cl_obj_lock( &p_adapter->obj );
\r
933 CL_ASSERT( !p_adapter->h_pnp );
\r
935 if( p_adapter->state != IB_PNP_PORT_REMOVE )
\r
936 p_adapter->state = IB_PNP_PORT_ADD;
\r
938 state = p_adapter->state;
\r
940 /* Destroy the current port instance if it still exists. */
\r
941 p_port = p_adapter->p_port;
\r
942 p_adapter->p_port = NULL;
\r
943 cl_obj_unlock( &p_adapter->obj );
\r
946 ipoib_port_destroy( p_port );
\r
947 ASSERT(p_adapter->reset == TRUE);
\r
948 if( state != IB_PNP_PORT_REMOVE )
\r
950 status = __ipoib_pnp_reg( p_adapter, IB_PNP_FLAG_REG_COMPLETE );
\r
951 if( status != IB_SUCCESS )
\r
953 p_adapter->reset = FALSE;
\r
954 IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
955 ("__ipoib_pnp_reg returned %s\n",
\r
956 p_adapter->p_ifc->get_err_str( status )) );
\r
957 NdisMResetComplete(
\r
958 p_adapter->h_adapter, NDIS_STATUS_HARD_ERRORS, TRUE );
\r
963 p_adapter->reset = FALSE;
\r
964 NdisMResetComplete(
\r
965 p_adapter->h_adapter, NDIS_STATUS_SUCCESS, TRUE );
\r
966 status = IB_SUCCESS;
\r
969 /* Dereference the adapter since the previous registration is now gone. */
\r
970 cl_obj_deref( &p_adapter->obj );
\r
972 KeReleaseMutex( &p_adapter->mutex, FALSE );
\r
974 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
980 IN ipoib_adapter_t* const p_adapter,
\r
981 IN const uint8_t link_width,
\r
982 IN const uint8_t link_speed )
\r
986 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
988 /* Set the link speed based on the IB link speed (1x vs 4x, etc). */
\r
989 switch( link_speed )
\r
991 case IB_LINK_SPEED_ACTIVE_2_5:
\r
992 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,
\r
993 ("Link speed is 2.5Gs\n") );
\r
994 rate = IB_LINK_SPEED_ACTIVE_2_5;
\r
997 case IB_LINK_SPEED_ACTIVE_5:
\r
998 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,
\r
999 ("Link speed is 5G\n") );
\r
1000 rate = IB_LINK_SPEED_ACTIVE_5;
\r
1003 case IB_LINK_SPEED_ACTIVE_10:
\r
1004 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,
\r
1005 ("Link speed is 10G\n") );
\r
1006 rate = IB_LINK_SPEED_ACTIVE_10;
\r
1010 IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
1011 ("Invalid link speed %d.\n", link_speed) );
\r
1015 switch( link_width )
\r
1017 case IB_LINK_WIDTH_ACTIVE_1X:
\r
1018 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,
\r
1019 ("Link width is 1X\n") );
\r
1020 rate *= ONE_X_IN_100BPS;
\r
1023 case IB_LINK_WIDTH_ACTIVE_4X:
\r
1024 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,
\r
1025 ("Link width is 4X\n") );
\r
1026 rate *= FOUR_X_IN_100BPS;
\r
1029 case IB_LINK_WIDTH_ACTIVE_12X:
\r
1030 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,
\r
1031 ("Link width is 12X\n") );
\r
1032 rate *= TWELVE_X_IN_100BPS;
\r
1036 IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
\r
1037 ("Invalid link rate (%d).\n", link_width) );
\r
1041 p_adapter->rate = rate;
\r
1042 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
1048 IN ipoib_adapter_t* const p_adapter )
\r
1050 ib_pnp_event_t old_state;
\r
1053 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
1055 cl_obj_lock( &p_adapter->obj );
\r
1056 old_state = p_adapter->state;
\r
1058 /* Change the state to indicate that we are now connected and live. */
\r
1059 if( old_state == IB_PNP_PORT_INIT )
\r
1060 p_adapter->state = IB_PNP_PORT_ACTIVE;
\r
1062 cl_obj_unlock( &p_adapter->obj );
\r
1065 * If we had a pending OID request for OID_GEN_LINK_SPEED,
\r
1066 * complete it now.
\r
1068 switch( old_state )
\r
1070 case IB_PNP_PORT_ADD:
\r
1071 ipoib_reg_addrs( p_adapter );
\r
1072 /* Fall through. */
\r
1074 case IB_PNP_PORT_REMOVE:
\r
1075 ipoib_resume_oids( p_adapter );
\r
1079 if (p_adapter->guids.port_guid.pkey != IB_DEFAULT_PKEY)
\r
1080 ipoib_query_pkey_index(p_adapter);
\r
1082 /* Join all programmed multicast groups. */
\r
1083 for( i = 0; i < p_adapter->mcast_array_size; i++ )
\r
1085 ipoib_port_join_mcast(
\r
1086 p_adapter->p_port, p_adapter->mcast_array[i] ,IB_MC_REC_STATE_FULL_MEMBER);
\r
1089 /* Register all existing addresses. */
\r
1090 ipoib_reg_addrs( p_adapter );
\r
1092 ipoib_resume_oids( p_adapter );
\r
1095 * Now that we're in the broadcast group, notify that
\r
1098 IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT, ("Link UP!\n") );
\r
1099 NdisWriteErrorLogEntry( p_adapter->h_adapter,
\r
1100 EVENT_IPOIB_PORT_UP + (p_adapter->rate/ONE_X_IN_100BPS),
\r
1101 1, p_adapter->rate );
\r
1103 if( !p_adapter->reset )
\r
1105 NdisMIndicateStatus( p_adapter->h_adapter, NDIS_STATUS_MEDIA_CONNECT,
\r
1107 NdisMIndicateStatusComplete( p_adapter->h_adapter );
\r
1111 if( p_adapter->reset )
\r
1113 p_adapter->reset = FALSE;
\r
1114 NdisMResetComplete(
\r
1115 p_adapter->h_adapter, NDIS_STATUS_SUCCESS, TRUE );
\r
1118 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
1123 * If something goes wrong after the port goes active, e.g.
\r
1124 * - PortInfo query failure
\r
1125 * - MC Join timeout
\r
1127 * Mark the port state as down, resume any pended OIDS, etc.
\r
1130 ipoib_set_inactive(
\r
1131 IN ipoib_adapter_t* const p_adapter )
\r
1133 ib_pnp_event_t old_state;
\r
1135 IPOIB_ENTER( IPOIB_DBG_INIT );
\r
1137 cl_obj_lock( &p_adapter->obj );
\r
1138 old_state = p_adapter->state;
\r
1139 if( old_state != IB_PNP_PORT_REMOVE )
\r
1140 p_adapter->state = IB_PNP_PORT_DOWN;
\r
1141 cl_obj_unlock( &p_adapter->obj );
\r
1144 * If we had a pending OID request for OID_GEN_LINK_SPEED,
\r
1145 * complete it now.
\r
1147 if( old_state == IB_PNP_PORT_INIT )
\r
1149 NdisMIndicateStatus( p_adapter->h_adapter,
\r
1150 NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0 );
\r
1151 NdisMIndicateStatusComplete( p_adapter->h_adapter );
\r
1153 ipoib_resume_oids( p_adapter );
\r
1156 if( p_adapter->reset )
\r
1158 p_adapter->reset = FALSE;
\r
1159 NdisMResetComplete(
\r
1160 p_adapter->h_adapter, NDIS_STATUS_SUCCESS, TRUE );
\r
1163 IPOIB_EXIT( IPOIB_DBG_INIT );
\r
1168 ipoib_get_recv_stat(
\r
1169 IN ipoib_adapter_t* const p_adapter,
\r
1170 IN const ip_stat_sel_t stat_sel,
\r
1171 IN pending_oid_t* const p_oid_info )
\r
1175 IPOIB_ENTER( IPOIB_DBG_STAT );
\r
1177 CL_ASSERT( p_adapter );
\r
1179 cl_spinlock_acquire( &p_adapter->recv_stat_lock );
\r
1180 switch( stat_sel )
\r
1182 case IP_STAT_SUCCESS:
\r
1183 stat = p_adapter->recv_stats.comp.success;
\r
1186 case IP_STAT_ERROR:
\r
1187 stat = p_adapter->recv_stats.comp.error;
\r
1190 case IP_STAT_DROPPED:
\r
1191 stat = p_adapter->recv_stats.comp.dropped;
\r
1194 case IP_STAT_UCAST_BYTES:
\r
1195 stat = p_adapter->recv_stats.ucast.bytes;
\r
1198 case IP_STAT_UCAST_FRAMES:
\r
1199 stat = p_adapter->recv_stats.ucast.frames;
\r
1202 case IP_STAT_BCAST_BYTES:
\r
1203 stat = p_adapter->recv_stats.bcast.bytes;
\r
1206 case IP_STAT_BCAST_FRAMES:
\r
1207 stat = p_adapter->recv_stats.bcast.frames;
\r
1210 case IP_STAT_MCAST_BYTES:
\r
1211 stat = p_adapter->recv_stats.mcast.bytes;
\r
1214 case IP_STAT_MCAST_FRAMES:
\r
1215 stat = p_adapter->recv_stats.mcast.frames;
\r
1221 cl_spinlock_release( &p_adapter->recv_stat_lock );
\r
1223 *p_oid_info->p_bytes_needed = sizeof(uint64_t);
\r
1225 if( p_oid_info->buf_len >= sizeof(uint64_t) )
\r
1227 *((uint64_t*)p_oid_info->p_buf) = stat;
\r
1228 *p_oid_info->p_bytes_used = sizeof(uint64_t);
\r
1230 else if( p_oid_info->buf_len >= sizeof(uint32_t) )
\r
1232 *((uint32_t*)p_oid_info->p_buf) = (uint32_t)stat;
\r
1233 *p_oid_info->p_bytes_used = sizeof(uint32_t);
\r
1237 *p_oid_info->p_bytes_used = 0;
\r
1238 IPOIB_EXIT( IPOIB_DBG_STAT );
\r
1239 return NDIS_STATUS_INVALID_LENGTH;
\r
1242 IPOIB_EXIT( IPOIB_DBG_STAT );
\r
1243 return NDIS_STATUS_SUCCESS;
\r
1248 ipoib_inc_recv_stat(
\r
1249 IN ipoib_adapter_t* const p_adapter,
\r
1250 IN const ip_stat_sel_t stat_sel,
\r
1251 IN const size_t bytes OPTIONAL )
\r
1253 IPOIB_ENTER( IPOIB_DBG_STAT );
\r
1255 cl_spinlock_acquire( &p_adapter->recv_stat_lock );
\r
1256 switch( stat_sel )
\r
1258 case IP_STAT_ERROR:
\r
1259 p_adapter->recv_stats.comp.error++;
\r
1262 case IP_STAT_DROPPED:
\r
1263 p_adapter->recv_stats.comp.dropped++;
\r
1266 case IP_STAT_UCAST_BYTES:
\r
1267 case IP_STAT_UCAST_FRAMES:
\r
1268 p_adapter->recv_stats.comp.success++;
\r
1269 p_adapter->recv_stats.ucast.frames++;
\r
1270 p_adapter->recv_stats.ucast.bytes += bytes;
\r
1273 case IP_STAT_BCAST_BYTES:
\r
1274 case IP_STAT_BCAST_FRAMES:
\r
1275 p_adapter->recv_stats.comp.success++;
\r
1276 p_adapter->recv_stats.bcast.frames++;
\r
1277 p_adapter->recv_stats.bcast.bytes += bytes;
\r
1280 case IP_STAT_MCAST_BYTES:
\r
1281 case IP_STAT_MCAST_FRAMES:
\r
1282 p_adapter->recv_stats.comp.success++;
\r
1283 p_adapter->recv_stats.mcast.frames++;
\r
1284 p_adapter->recv_stats.mcast.bytes += bytes;
\r
1290 cl_spinlock_release( &p_adapter->recv_stat_lock );
\r
1292 IPOIB_EXIT( IPOIB_DBG_STAT );
\r
1296 ipoib_get_send_stat(
\r
1297 IN ipoib_adapter_t* const p_adapter,
\r
1298 IN const ip_stat_sel_t stat_sel,
\r
1299 IN pending_oid_t* const p_oid_info )
\r
1303 IPOIB_ENTER( IPOIB_DBG_STAT );
\r
1305 CL_ASSERT( p_adapter );
\r
1307 cl_spinlock_acquire( &p_adapter->send_stat_lock );
\r
1308 switch( stat_sel )
\r
1310 case IP_STAT_SUCCESS:
\r
1311 stat = p_adapter->send_stats.comp.success;
\r
1314 case IP_STAT_ERROR:
\r
1315 stat = p_adapter->send_stats.comp.error;
\r
1318 case IP_STAT_DROPPED:
\r
1319 stat = p_adapter->send_stats.comp.dropped;
\r
1322 case IP_STAT_UCAST_BYTES:
\r
1323 stat = p_adapter->send_stats.ucast.bytes;
\r
1326 case IP_STAT_UCAST_FRAMES:
\r
1327 stat = p_adapter->send_stats.ucast.frames;
\r
1330 case IP_STAT_BCAST_BYTES:
\r
1331 stat = p_adapter->send_stats.bcast.bytes;
\r
1334 case IP_STAT_BCAST_FRAMES:
\r
1335 stat = p_adapter->send_stats.bcast.frames;
\r
1338 case IP_STAT_MCAST_BYTES:
\r
1339 stat = p_adapter->send_stats.mcast.bytes;
\r
1342 case IP_STAT_MCAST_FRAMES:
\r
1343 stat = p_adapter->send_stats.mcast.frames;
\r
1349 cl_spinlock_release( &p_adapter->send_stat_lock );
\r
1351 *p_oid_info->p_bytes_needed = sizeof(uint64_t);
\r
1353 if( p_oid_info->buf_len >= sizeof(uint64_t) )
\r
1355 *((uint64_t*)p_oid_info->p_buf) = stat;
\r
1356 *p_oid_info->p_bytes_used = sizeof(uint64_t);
\r
1358 else if( p_oid_info->buf_len >= sizeof(uint32_t) )
\r
1360 *((uint32_t*)p_oid_info->p_buf) = (uint32_t)stat;
\r
1361 *p_oid_info->p_bytes_used = sizeof(uint32_t);
\r
1365 *p_oid_info->p_bytes_used = 0;
\r
1366 IPOIB_EXIT( IPOIB_DBG_STAT );
\r
1367 return NDIS_STATUS_INVALID_LENGTH;
\r
1370 IPOIB_EXIT( IPOIB_DBG_STAT );
\r
1371 return NDIS_STATUS_SUCCESS;
\r
1376 ipoib_inc_send_stat(
\r
1377 IN ipoib_adapter_t* const p_adapter,
\r
1378 IN const ip_stat_sel_t stat_sel,
\r
1379 IN const size_t bytes OPTIONAL )
\r
1381 IPOIB_ENTER( IPOIB_DBG_STAT );
\r
1383 cl_spinlock_acquire( &p_adapter->send_stat_lock );
\r
1384 switch( stat_sel )
\r
1386 case IP_STAT_ERROR:
\r
1387 p_adapter->send_stats.comp.error++;
\r
1390 case IP_STAT_DROPPED:
\r
1391 p_adapter->send_stats.comp.dropped++;
\r
1394 case IP_STAT_UCAST_BYTES:
\r
1395 case IP_STAT_UCAST_FRAMES:
\r
1396 p_adapter->send_stats.comp.success++;
\r
1397 p_adapter->send_stats.ucast.frames++;
\r
1398 p_adapter->send_stats.ucast.bytes += bytes;
\r
1401 case IP_STAT_BCAST_BYTES:
\r
1402 case IP_STAT_BCAST_FRAMES:
\r
1403 p_adapter->send_stats.comp.success++;
\r
1404 p_adapter->send_stats.bcast.frames++;
\r
1405 p_adapter->send_stats.bcast.bytes += bytes;
\r
1408 case IP_STAT_MCAST_BYTES:
\r
1409 case IP_STAT_MCAST_FRAMES:
\r
1410 p_adapter->send_stats.comp.success++;
\r
1411 p_adapter->send_stats.mcast.frames++;
\r
1412 p_adapter->send_stats.mcast.bytes += bytes;
\r
1418 cl_spinlock_release( &p_adapter->send_stat_lock );
\r
1420 IPOIB_EXIT( IPOIB_DBG_STAT );
\r