|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2008 Michael Brown <[email protected]>. ! 3: * ! 4: * This program is free software; you can redistribute it and/or ! 5: * modify it under the terms of the GNU General Public License as ! 6: * published by the Free Software Foundation; either version 2 of the ! 7: * License, or any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, but ! 10: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 12: * General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License ! 15: * along with this program; if not, write to the Free Software ! 16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 17: */ ! 18: ! 19: FILE_LICENCE ( GPL2_OR_LATER ); ! 20: ! 21: #include <stdint.h> ! 22: #include <stdlib.h> ! 23: #include <string.h> ! 24: #include <errno.h> ! 25: #include <unistd.h> ! 26: #include <byteswap.h> ! 27: #include <ipxe/infiniband.h> ! 28: #include <ipxe/ib_smc.h> ! 29: ! 30: /** ! 31: * @file ! 32: * ! 33: * Infiniband Subnet Management Client ! 34: * ! 35: */ ! 36: ! 37: /** ! 38: * Issue local MAD ! 39: * ! 40: * @v ibdev Infiniband device ! 41: * @v attr_id Attribute ID, in network byte order ! 42: * @v attr_mod Attribute modifier, in network byte order ! 43: * @v local_mad Method for issuing local MADs ! 44: * @v mad Management datagram to fill in ! 45: * @ret rc Return status code ! 46: */ ! 47: static int ib_smc_mad ( struct ib_device *ibdev, uint16_t attr_id, ! 48: uint32_t attr_mod, ib_local_mad_t local_mad, ! 49: union ib_mad *mad ) { ! 50: int rc; ! 51: ! 52: /* Construct MAD */ ! 53: memset ( mad, 0, sizeof ( *mad ) ); ! 54: mad->hdr.base_version = IB_MGMT_BASE_VERSION; ! 55: mad->hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; ! 56: mad->hdr.class_version = 1; ! 57: mad->hdr.method = IB_MGMT_METHOD_GET; ! 58: mad->hdr.attr_id = attr_id; ! 59: mad->hdr.attr_mod = attr_mod; ! 60: ! 61: /* Issue MAD */ ! 62: if ( ( rc = local_mad ( ibdev, mad ) ) != 0 ) ! 63: return rc; ! 64: ! 65: return 0; ! 66: } ! 67: ! 68: /** ! 69: * Get node information ! 70: * ! 71: * @v ibdev Infiniband device ! 72: * @v local_mad Method for issuing local MADs ! 73: * @v mad Management datagram to fill in ! 74: * @ret rc Return status code ! 75: */ ! 76: static int ib_smc_get_node_info ( struct ib_device *ibdev, ! 77: ib_local_mad_t local_mad, ! 78: union ib_mad *mad ) { ! 79: int rc; ! 80: ! 81: /* Issue MAD */ ! 82: if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_NODE_INFO ), 0, ! 83: local_mad, mad ) ) != 0 ) { ! 84: DBGC ( ibdev, "IBDEV %p could not get node info: %s\n", ! 85: ibdev, strerror ( rc ) ); ! 86: return rc; ! 87: } ! 88: return 0; ! 89: } ! 90: ! 91: /** ! 92: * Get port information ! 93: * ! 94: * @v ibdev Infiniband device ! 95: * @v local_mad Method for issuing local MADs ! 96: * @v mad Management datagram to fill in ! 97: * @ret rc Return status code ! 98: */ ! 99: static int ib_smc_get_port_info ( struct ib_device *ibdev, ! 100: ib_local_mad_t local_mad, ! 101: union ib_mad *mad ) { ! 102: int rc; ! 103: ! 104: /* Issue MAD */ ! 105: if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_PORT_INFO ), ! 106: htonl ( ibdev->port ), local_mad, mad )) !=0){ ! 107: DBGC ( ibdev, "IBDEV %p could not get port info: %s\n", ! 108: ibdev, strerror ( rc ) ); ! 109: return rc; ! 110: } ! 111: return 0; ! 112: } ! 113: ! 114: /** ! 115: * Get GUID information ! 116: * ! 117: * @v ibdev Infiniband device ! 118: * @v local_mad Method for issuing local MADs ! 119: * @v mad Management datagram to fill in ! 120: * @ret rc Return status code ! 121: */ ! 122: static int ib_smc_get_guid_info ( struct ib_device *ibdev, ! 123: ib_local_mad_t local_mad, ! 124: union ib_mad *mad ) { ! 125: int rc; ! 126: ! 127: /* Issue MAD */ ! 128: if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_GUID_INFO ), 0, ! 129: local_mad, mad ) ) != 0 ) { ! 130: DBGC ( ibdev, "IBDEV %p could not get GUID info: %s\n", ! 131: ibdev, strerror ( rc ) ); ! 132: return rc; ! 133: } ! 134: return 0; ! 135: } ! 136: ! 137: /** ! 138: * Get partition key table ! 139: * ! 140: * @v ibdev Infiniband device ! 141: * @v local_mad Method for issuing local MADs ! 142: * @v mad Management datagram to fill in ! 143: * @ret rc Return status code ! 144: */ ! 145: static int ib_smc_get_pkey_table ( struct ib_device *ibdev, ! 146: ib_local_mad_t local_mad, ! 147: union ib_mad *mad ) { ! 148: int rc; ! 149: ! 150: /* Issue MAD */ ! 151: if ( ( rc = ib_smc_mad ( ibdev, htons ( IB_SMP_ATTR_PKEY_TABLE ), 0, ! 152: local_mad, mad ) ) != 0 ) { ! 153: DBGC ( ibdev, "IBDEV %p could not get pkey table: %s\n", ! 154: ibdev, strerror ( rc ) ); ! 155: return rc; ! 156: } ! 157: return 0; ! 158: } ! 159: ! 160: /** ! 161: * Get Infiniband parameters using SMC ! 162: * ! 163: * @v ibdev Infiniband device ! 164: * @v local_mad Method for issuing local MADs ! 165: * @ret rc Return status code ! 166: */ ! 167: static int ib_smc_get ( struct ib_device *ibdev, ib_local_mad_t local_mad ) { ! 168: union ib_mad mad; ! 169: struct ib_node_info *node_info = &mad.smp.smp_data.node_info; ! 170: struct ib_port_info *port_info = &mad.smp.smp_data.port_info; ! 171: struct ib_guid_info *guid_info = &mad.smp.smp_data.guid_info; ! 172: struct ib_pkey_table *pkey_table = &mad.smp.smp_data.pkey_table; ! 173: int rc; ! 174: ! 175: /* Node info gives us the node GUID */ ! 176: if ( ( rc = ib_smc_get_node_info ( ibdev, local_mad, &mad ) ) != 0 ) ! 177: return rc; ! 178: memcpy ( &ibdev->node_guid, &node_info->node_guid, ! 179: sizeof ( ibdev->node_guid ) ); ! 180: ! 181: /* Port info gives us the link state, the first half of the ! 182: * port GID and the SM LID. ! 183: */ ! 184: if ( ( rc = ib_smc_get_port_info ( ibdev, local_mad, &mad ) ) != 0 ) ! 185: return rc; ! 186: memcpy ( &ibdev->gid.s.prefix, port_info->gid_prefix, ! 187: sizeof ( ibdev->gid.s.prefix ) ); ! 188: ibdev->lid = ntohs ( port_info->lid ); ! 189: ibdev->sm_lid = ntohs ( port_info->mastersm_lid ); ! 190: ibdev->link_width_enabled = port_info->link_width_enabled; ! 191: ibdev->link_width_supported = port_info->link_width_supported; ! 192: ibdev->link_width_active = port_info->link_width_active; ! 193: ibdev->link_speed_supported = ! 194: ( port_info->link_speed_supported__port_state >> 4 ); ! 195: ibdev->port_state = ! 196: ( port_info->link_speed_supported__port_state & 0xf ); ! 197: ibdev->link_speed_active = ! 198: ( port_info->link_speed_active__link_speed_enabled >> 4 ); ! 199: ibdev->link_speed_enabled = ! 200: ( port_info->link_speed_active__link_speed_enabled & 0xf ); ! 201: ibdev->sm_sl = ( port_info->neighbour_mtu__mastersm_sl & 0xf ); ! 202: ! 203: /* GUID info gives us the second half of the port GID */ ! 204: if ( ( rc = ib_smc_get_guid_info ( ibdev, local_mad, &mad ) ) != 0 ) ! 205: return rc; ! 206: memcpy ( &ibdev->gid.s.guid, guid_info->guid[0], ! 207: sizeof ( ibdev->gid.s.guid ) ); ! 208: ! 209: /* Get partition key */ ! 210: if ( ( rc = ib_smc_get_pkey_table ( ibdev, local_mad, &mad ) ) != 0 ) ! 211: return rc; ! 212: ibdev->pkey = ntohs ( pkey_table->pkey[0] ); ! 213: ! 214: DBGC ( ibdev, "IBDEV %p port GID is " IB_GID_FMT "\n", ! 215: ibdev, IB_GID_ARGS ( &ibdev->gid ) ); ! 216: ! 217: return 0; ! 218: } ! 219: ! 220: /** ! 221: * Initialise Infiniband parameters using SMC ! 222: * ! 223: * @v ibdev Infiniband device ! 224: * @v local_mad Method for issuing local MADs ! 225: * @ret rc Return status code ! 226: */ ! 227: int ib_smc_init ( struct ib_device *ibdev, ib_local_mad_t local_mad ) { ! 228: int rc; ! 229: ! 230: /* Get MAD parameters */ ! 231: if ( ( rc = ib_smc_get ( ibdev, local_mad ) ) != 0 ) ! 232: return rc; ! 233: ! 234: return 0; ! 235: } ! 236: ! 237: /** ! 238: * Update Infiniband parameters using SMC ! 239: * ! 240: * @v ibdev Infiniband device ! 241: * @v local_mad Method for issuing local MADs ! 242: * @ret rc Return status code ! 243: */ ! 244: int ib_smc_update ( struct ib_device *ibdev, ib_local_mad_t local_mad ) { ! 245: int rc; ! 246: ! 247: /* Get MAD parameters */ ! 248: if ( ( rc = ib_smc_get ( ibdev, local_mad ) ) != 0 ) ! 249: return rc; ! 250: ! 251: /* Notify Infiniband core of potential link state change */ ! 252: ib_link_state_changed ( ibdev ); ! 253: ! 254: return 0; ! 255: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.