} IOCTL_IBAT_IP_TO_PORT_OUT;\r
\r
\r
+/** This IRP is used to convert a remote MAC addresses to a remote GID */\r
+#define IOCTL_IBAT_MAC_TO_PATH IOCTL_IBAT( 5 )\r
+\r
+typedef struct _IOCTL_IBAT_MAC_TO_PATH_IN\r
+{\r
+ ULONG Version;\r
+ UINT64 PortGuid;\r
+ UCHAR DestMac[IBAT_MAC_LEN];\r
+\r
+} IOCTL_IBAT_MAC_TO_PATH_IN;\r
+\r
+typedef struct _IOCTL_IBAT_MAC_TO_PATH_OUT\r
+{\r
+ ib_path_rec_t Path;\r
+\r
+} IOCTL_IBAT_MAC_TO_PATH_OUT;\r
+\r
+\r
#define IBAT_DEV_NAME L"\\Device\\ibat"\r
#define IBAT_DOS_DEV_NAME L"\\DosDevices\\Global\\ibat"\r
#define IBAT_WIN32_NAME L"\\\\.\\ibat"\r
}\r
\r
\r
+static NTSTATUS\r
+__ibat_mac_to_path(\r
+ IN IRP *pIrp,\r
+ IN IO_STACK_LOCATION *pIoStack )\r
+{\r
+ NTSTATUS status = STATUS_INVALID_PARAMETER;\r
+ IOCTL_IBAT_MAC_TO_PATH_IN *pIn;\r
+ IOCTL_IBAT_MAC_TO_PATH_OUT *pOut;\r
+ KLOCK_QUEUE_HANDLE hdl;\r
+ cl_list_item_t *pItem;\r
+ ipoib_adapter_t *pAdapter;\r
+\r
+ IPOIB_ENTER(IPOIB_DBG_IOCTL);\r
+\r
+ if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=\r
+ sizeof(IOCTL_IBAT_MAC_TO_PATH_IN) )\r
+ {\r
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("Invalid input buffer size.\n") );\r
+ return STATUS_INVALID_PARAMETER;\r
+ }\r
+ \r
+ if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength !=\r
+ sizeof(IOCTL_IBAT_MAC_TO_PATH_OUT) )\r
+ {\r
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("Invalid output buffer size.\n") );\r
+ return STATUS_INVALID_PARAMETER;\r
+ }\r
+\r
+ pIn = pIrp->AssociatedIrp.SystemBuffer;\r
+ pOut = pIrp->AssociatedIrp.SystemBuffer;\r
+\r
+ if( pIn->Version != IBAT_IOCTL_VERSION )\r
+ {\r
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("Invalid version.\n") );\r
+ return STATUS_INVALID_PARAMETER;\r
+ }\r
+\r
+ KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
+\r
+ for( pItem = cl_qlist_head( &g_ipoib.adapter_list );\r
+ pItem != cl_qlist_end( &g_ipoib.adapter_list );\r
+ pItem = cl_qlist_next( pItem ) )\r
+ {\r
+ pAdapter = CONTAINING_RECORD( pItem, ipoib_adapter_t, entry );\r
+ if( pIn->PortGuid != pAdapter->guids.port_guid.guid )\r
+ continue;\r
+\r
+ /* Found the port - lookup the MAC. */\r
+ cl_obj_lock( &pAdapter->obj );\r
+ if( pAdapter->p_port )\r
+ {\r
+ status = ipoib_mac_to_path(\r
+ pAdapter->p_port, *(mac_addr_t*)pIn->DestMac, &pOut->Path );\r
+\r
+ if( NT_SUCCESS( status ) )\r
+ {\r
+ pIrp->IoStatus.Information =\r
+ sizeof(IOCTL_IBAT_MAC_TO_PATH_OUT);\r
+ }\r
+ }\r
+ cl_obj_unlock( &pAdapter->obj );\r
+ break;\r
+ }\r
+\r
+ KeReleaseInStackQueuedSpinLock( &hdl );\r
+\r
+ IPOIB_EXIT( IPOIB_DBG_IOCTL );\r
+ return status;\r
+}\r
+\r
+\r
static NTSTATUS\r
__ibat_ip_to_port(\r
IN IRP *pIrp,\r
status = __ibat_ip_to_port( pIrp, pIoStack );\r
break;\r
\r
+ case IOCTL_IBAT_MAC_TO_PATH:\r
+ IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_IOCTL,\r
+ ("IOCTL_IBAT_MAC_TO_PATH received\n" ));\r
+ status = __ibat_mac_to_path( pIrp, pIoStack );\r
+ break;\r
+\r
default:\r
IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_IOCTL,\r
("unknow IOCTL code = 0x%x\n",\r
}\r
\r
\r
+NTSTATUS\r
+ipoib_mac_to_path(\r
+ IN ipoib_port_t* const p_port,\r
+ IN const mac_addr_t mac,\r
+ OUT ib_path_rec_t* p_path )\r
+{\r
+ ipoib_endpt_t* p_endpt;\r
+ cl_map_item_t *p_item;\r
+ uint64_t key = 0;\r
+ uint8_t sl;\r
+ net32_t flow_lbl;\r
+ uint8_t hop_limit;\r
+\r
+ IPOIB_ENTER( IPOIB_DBG_ENDPT );\r
+\r
+ cl_memcpy( &key, &mac, sizeof(mac_addr_t) );\r
+\r
+ cl_obj_lock( &p_port->obj );\r
+\r
+ if( p_port->p_local_endpt == NULL )\r
+ {\r
+ cl_obj_unlock( &p_port->obj );\r
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("No local endpoint.\n") );\r
+ return STATUS_INVALID_PARAMETER;\r
+ }\r
+\r
+ if( mac.addr[0] == 0 && mac.addr[1] == 0 && mac.addr[2] == 0 &&\r
+ mac.addr[3] == 0 && mac.addr[4] == 0 && mac.addr[5] == 0 )\r
+ {\r
+ p_endpt = p_port->p_local_endpt;\r
+ }\r
+ else\r
+ {\r
+ p_item = cl_qmap_get( &p_port->endpt_mgr.mac_endpts, key );\r
+ if( p_item == cl_qmap_end( &p_port->endpt_mgr.mac_endpts ) )\r
+ {\r
+ cl_obj_unlock( &p_port->obj );\r
+ IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ ("Failed endpoint lookup.\n") );\r
+ return STATUS_INVALID_PARAMETER;\r
+ }\r
+\r
+ p_endpt = PARENT_STRUCT( p_item, ipoib_endpt_t, mac_item );\r
+ }\r
+\r
+ p_path->resv0 = 0;\r
+ p_path->dgid = p_endpt->dgid;\r
+ p_path->sgid = p_port->p_local_endpt->dgid;\r
+ p_path->dlid = p_endpt->dlid;\r
+ p_path->slid = p_port->p_local_endpt->dlid;\r
+\r
+ ib_member_get_sl_flow_hop(\r
+ p_port->ib_mgr.bcast_rec.sl_flow_hop,\r
+ &sl,\r
+ &flow_lbl,\r
+ &hop_limit\r
+ );\r
+ ib_path_rec_set_hop_flow_raw( p_path, hop_limit, flow_lbl, FALSE );\r
+\r
+ p_path->tclass = p_port->ib_mgr.bcast_rec.tclass;\r
+ p_path->num_path = 1;\r
+ p_path->pkey = p_port->ib_mgr.bcast_rec.pkey;\r
+ p_path->mtu = p_port->ib_mgr.bcast_rec.mtu;\r
+ p_path->rate = p_port->ib_mgr.bcast_rec.rate;\r
+ if( p_path->slid == p_path->dlid )\r
+ p_path->pkt_life = 0;\r
+ else\r
+ p_path->pkt_life = p_port->ib_mgr.bcast_rec.pkt_life;\r
+ p_path->preference = 0;\r
+ p_path->resv1 = 0;\r
+ p_path->resv2 = 0;\r
+\r
+ cl_obj_unlock( &p_port->obj );\r
+\r
+ IPOIB_EXIT( IPOIB_DBG_ENDPT );\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+\r
static inline NDIS_STATUS\r
__endpt_mgr_ref(\r
IN ipoib_port_t* const p_port,\r
IN const mac_addr_t mac,\r
OUT ib_gid_t* p_gid );\r
\r
+NTSTATUS\r
+ipoib_mac_to_path(\r
+ IN ipoib_port_t* const p_port,\r
+ IN const mac_addr_t mac,\r
+ OUT ib_path_rec_t* p_path );\r
+\r
inline void ipoib_port_ref(\r
IN ipoib_port_t * p_port, \r
IN int type);\r