|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2009 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 <stdio.h> ! 26: #include <unistd.h> ! 27: #include <byteswap.h> ! 28: #include <ipxe/settings.h> ! 29: #include <ipxe/infiniband.h> ! 30: #include <ipxe/iobuf.h> ! 31: #include <ipxe/ib_mi.h> ! 32: #include <ipxe/ib_sma.h> ! 33: ! 34: /** ! 35: * @file ! 36: * ! 37: * Infiniband Subnet Management Agent ! 38: * ! 39: */ ! 40: ! 41: /** ! 42: * Node information ! 43: * ! 44: * @v ibdev Infiniband device ! 45: * @v mi Management interface ! 46: * @v mad Received MAD ! 47: * @v av Source address vector ! 48: */ ! 49: static void ib_sma_node_info ( struct ib_device *ibdev, ! 50: struct ib_mad_interface *mi, ! 51: union ib_mad *mad, ! 52: struct ib_address_vector *av ) { ! 53: struct ib_node_info *node_info = &mad->smp.smp_data.node_info; ! 54: int rc; ! 55: ! 56: /* Fill in information */ ! 57: memset ( node_info, 0, sizeof ( *node_info ) ); ! 58: node_info->base_version = IB_MGMT_BASE_VERSION; ! 59: node_info->class_version = IB_SMP_CLASS_VERSION; ! 60: node_info->node_type = IB_NODE_TYPE_HCA; ! 61: node_info->num_ports = ib_count_ports ( ibdev ); ! 62: memcpy ( &node_info->sys_guid, &ibdev->node_guid, ! 63: sizeof ( node_info->sys_guid ) ); ! 64: memcpy ( &node_info->node_guid, &ibdev->node_guid, ! 65: sizeof ( node_info->node_guid ) ); ! 66: memcpy ( &node_info->port_guid, &ibdev->gid.s.guid, ! 67: sizeof ( node_info->port_guid ) ); ! 68: node_info->partition_cap = htons ( 1 ); ! 69: node_info->local_port_num = ibdev->port; ! 70: ! 71: /* Send GetResponse */ ! 72: mad->hdr.method = IB_MGMT_METHOD_GET_RESP; ! 73: if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) { ! 74: DBGC ( mi, "SMA %p could not send NodeInfo GetResponse: %s\n", ! 75: mi, strerror ( rc ) ); ! 76: return; ! 77: } ! 78: } ! 79: ! 80: /** ! 81: * Node description ! 82: * ! 83: * @v ibdev Infiniband device ! 84: * @v mi Management interface ! 85: * @v mad Received MAD ! 86: * @v av Source address vector ! 87: */ ! 88: static void ib_sma_node_desc ( struct ib_device *ibdev, ! 89: struct ib_mad_interface *mi, ! 90: union ib_mad *mad, ! 91: struct ib_address_vector *av ) { ! 92: struct ib_node_desc *node_desc = &mad->smp.smp_data.node_desc; ! 93: union ib_guid *guid = &ibdev->node_guid; ! 94: char hostname[ sizeof ( node_desc->node_string ) ]; ! 95: int hostname_len; ! 96: int rc; ! 97: ! 98: /* Fill in information */ ! 99: memset ( node_desc, 0, sizeof ( *node_desc ) ); ! 100: hostname_len = fetch_string_setting ( NULL, &hostname_setting, ! 101: hostname, sizeof ( hostname ) ); ! 102: snprintf ( node_desc->node_string, sizeof ( node_desc->node_string ), ! 103: "iPXE %s%s%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x (%s)", ! 104: hostname, ( ( hostname_len >= 0 ) ? " " : "" ), ! 105: guid->bytes[0], guid->bytes[1], guid->bytes[2], ! 106: guid->bytes[3], guid->bytes[4], guid->bytes[5], ! 107: guid->bytes[6], guid->bytes[7], ibdev->dev->name ); ! 108: ! 109: /* Send GetResponse */ ! 110: mad->hdr.method = IB_MGMT_METHOD_GET_RESP; ! 111: if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) { ! 112: DBGC ( mi, "SMA %p could not send NodeDesc GetResponse: %s\n", ! 113: mi, strerror ( rc ) ); ! 114: return; ! 115: } ! 116: } ! 117: ! 118: /** ! 119: * GUID information ! 120: * ! 121: * @v ibdev Infiniband device ! 122: * @v mi Management interface ! 123: * @v mad Received MAD ! 124: * @v av Source address vector ! 125: */ ! 126: static void ib_sma_guid_info ( struct ib_device *ibdev, ! 127: struct ib_mad_interface *mi, ! 128: union ib_mad *mad, ! 129: struct ib_address_vector *av ) { ! 130: struct ib_guid_info *guid_info = &mad->smp.smp_data.guid_info; ! 131: int rc; ! 132: ! 133: /* Fill in information */ ! 134: memset ( guid_info, 0, sizeof ( *guid_info ) ); ! 135: memcpy ( guid_info->guid[0], &ibdev->gid.s.guid, ! 136: sizeof ( guid_info->guid[0] ) ); ! 137: ! 138: /* Send GetResponse */ ! 139: mad->hdr.method = IB_MGMT_METHOD_GET_RESP; ! 140: if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) { ! 141: DBGC ( mi, "SMA %p could not send GuidInfo GetResponse: %s\n", ! 142: mi, strerror ( rc ) ); ! 143: return; ! 144: } ! 145: } ! 146: ! 147: /** ! 148: * Set port information ! 149: * ! 150: * @v ibdev Infiniband device ! 151: * @v mi Management interface ! 152: * @v mad Received MAD ! 153: * @ret rc Return status code ! 154: */ ! 155: static int ib_sma_set_port_info ( struct ib_device *ibdev, ! 156: struct ib_mad_interface *mi, ! 157: union ib_mad *mad ) { ! 158: const struct ib_port_info *port_info = &mad->smp.smp_data.port_info; ! 159: unsigned int link_width_enabled; ! 160: unsigned int link_speed_enabled; ! 161: int rc; ! 162: ! 163: /* Set parameters */ ! 164: memcpy ( &ibdev->gid.s.prefix, port_info->gid_prefix, ! 165: sizeof ( ibdev->gid.s.prefix ) ); ! 166: ibdev->lid = ntohs ( port_info->lid ); ! 167: ibdev->sm_lid = ntohs ( port_info->mastersm_lid ); ! 168: if ( ( link_width_enabled = port_info->link_width_enabled ) ) ! 169: ibdev->link_width_enabled = link_width_enabled; ! 170: if ( ( link_speed_enabled = ! 171: ( port_info->link_speed_active__link_speed_enabled & 0xf ) ) ) ! 172: ibdev->link_speed_enabled = link_speed_enabled; ! 173: ibdev->sm_sl = ( port_info->neighbour_mtu__mastersm_sl & 0xf ); ! 174: DBGC ( mi, "SMA %p set LID %04x SMLID %04x link width %02x speed " ! 175: "%02x\n", mi, ibdev->lid, ibdev->sm_lid, ! 176: ibdev->link_width_enabled, ibdev->link_speed_enabled ); ! 177: ! 178: /* Update parameters on device */ ! 179: if ( ( rc = ib_set_port_info ( ibdev, mad ) ) != 0 ) { ! 180: DBGC ( mi, "SMA %p could not set port information: %s\n", ! 181: mi, strerror ( rc ) ); ! 182: return rc; ! 183: } ! 184: ! 185: return 0; ! 186: } ! 187: ! 188: /** ! 189: * Port information ! 190: * ! 191: * @v ibdev Infiniband device ! 192: * @v mi Management interface ! 193: * @v mad Received MAD ! 194: * @v av Source address vector ! 195: */ ! 196: static void ib_sma_port_info ( struct ib_device *ibdev, ! 197: struct ib_mad_interface *mi, ! 198: union ib_mad *mad, ! 199: struct ib_address_vector *av ) { ! 200: struct ib_port_info *port_info = &mad->smp.smp_data.port_info; ! 201: int rc; ! 202: ! 203: /* Set parameters if applicable */ ! 204: if ( mad->hdr.method == IB_MGMT_METHOD_SET ) { ! 205: if ( ( rc = ib_sma_set_port_info ( ibdev, mi, mad ) ) != 0 ) { ! 206: mad->hdr.status = ! 207: htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR ); ! 208: /* Fall through to generate GetResponse */ ! 209: } ! 210: } ! 211: ! 212: /* Fill in information */ ! 213: memset ( port_info, 0, sizeof ( *port_info ) ); ! 214: memcpy ( port_info->gid_prefix, &ibdev->gid.s.prefix, ! 215: sizeof ( port_info->gid_prefix ) ); ! 216: port_info->lid = ntohs ( ibdev->lid ); ! 217: port_info->mastersm_lid = ntohs ( ibdev->sm_lid ); ! 218: port_info->local_port_num = ibdev->port; ! 219: port_info->link_width_enabled = ibdev->link_width_enabled; ! 220: port_info->link_width_supported = ibdev->link_width_supported; ! 221: port_info->link_width_active = ibdev->link_width_active; ! 222: port_info->link_speed_supported__port_state = ! 223: ( ( ibdev->link_speed_supported << 4 ) | ibdev->port_state ); ! 224: port_info->port_phys_state__link_down_def_state = ! 225: ( ( IB_PORT_PHYS_STATE_POLLING << 4 ) | ! 226: IB_PORT_PHYS_STATE_POLLING ); ! 227: port_info->link_speed_active__link_speed_enabled = ! 228: ( ( ibdev->link_speed_active << 4 ) | ! 229: ibdev->link_speed_enabled ); ! 230: port_info->neighbour_mtu__mastersm_sl = ! 231: ( ( IB_MTU_2048 << 4 ) | ibdev->sm_sl ); ! 232: port_info->vl_cap__init_type = ( IB_VL_0 << 4 ); ! 233: port_info->init_type_reply__mtu_cap = IB_MTU_2048; ! 234: port_info->operational_vls__enforcement = ( IB_VL_0 << 4 ); ! 235: port_info->guid_cap = 1; ! 236: ! 237: /* Send GetResponse */ ! 238: mad->hdr.method = IB_MGMT_METHOD_GET_RESP; ! 239: if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) { ! 240: DBGC ( mi, "SMA %p could not send PortInfo GetResponse: %s\n", ! 241: mi, strerror ( rc ) ); ! 242: return; ! 243: } ! 244: } ! 245: ! 246: /** ! 247: * Set partition key table ! 248: * ! 249: * @v ibdev Infiniband device ! 250: * @v mi Management interface ! 251: * @v mad Received MAD ! 252: * @ret rc Return status code ! 253: */ ! 254: static int ib_sma_set_pkey_table ( struct ib_device *ibdev, ! 255: struct ib_mad_interface *mi, ! 256: union ib_mad *mad ) { ! 257: struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table; ! 258: int rc; ! 259: ! 260: /* Set parameters */ ! 261: ibdev->pkey = ntohs ( pkey_table->pkey[0] ); ! 262: DBGC ( mi, "SMA %p set pkey %04x\n", mi, ibdev->pkey ); ! 263: ! 264: /* Update parameters on device */ ! 265: if ( ( rc = ib_set_pkey_table ( ibdev, mad ) ) != 0 ) { ! 266: DBGC ( mi, "SMA %p could not set pkey table: %s\n", ! 267: mi, strerror ( rc ) ); ! 268: return rc; ! 269: } ! 270: ! 271: return 0; ! 272: } ! 273: ! 274: /** ! 275: * Partition key table ! 276: * ! 277: * @v ibdev Infiniband device ! 278: * @v mi Management interface ! 279: * @v mad Received MAD ! 280: * @v av Source address vector ! 281: */ ! 282: static void ib_sma_pkey_table ( struct ib_device *ibdev, ! 283: struct ib_mad_interface *mi, ! 284: union ib_mad *mad, ! 285: struct ib_address_vector *av ) { ! 286: struct ib_pkey_table *pkey_table = &mad->smp.smp_data.pkey_table; ! 287: int rc; ! 288: ! 289: /* Set parameters, if applicable */ ! 290: if ( mad->hdr.method == IB_MGMT_METHOD_SET ) { ! 291: if ( ( rc = ib_sma_set_pkey_table ( ibdev, mi, mad ) ) != 0 ) { ! 292: mad->hdr.status = ! 293: htons ( IB_MGMT_STATUS_UNSUPPORTED_METHOD_ATTR ); ! 294: /* Fall through to generate GetResponse */ ! 295: } ! 296: } ! 297: ! 298: /* Fill in information */ ! 299: mad->hdr.method = IB_MGMT_METHOD_GET_RESP; ! 300: memset ( pkey_table, 0, sizeof ( *pkey_table ) ); ! 301: pkey_table->pkey[0] = htons ( ibdev->pkey ); ! 302: ! 303: /* Send GetResponse */ ! 304: mad->hdr.method = IB_MGMT_METHOD_GET_RESP; ! 305: if ( ( rc = ib_mi_send ( ibdev, mi, mad, av ) ) != 0 ) { ! 306: DBGC ( mi, "SMA %p could not send PKeyTable GetResponse: %s\n", ! 307: mi, strerror ( rc ) ); ! 308: return; ! 309: } ! 310: } ! 311: ! 312: /** Subnet management agent */ ! 313: struct ib_mad_agent ib_sma_agent[] __ib_mad_agent = { ! 314: { ! 315: .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, ! 316: .class_version = IB_SMP_CLASS_VERSION, ! 317: .attr_id = htons ( IB_SMP_ATTR_NODE_INFO ), ! 318: .handle = ib_sma_node_info, ! 319: }, ! 320: { ! 321: .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, ! 322: .class_version = IB_SMP_CLASS_VERSION, ! 323: .attr_id = htons ( IB_SMP_ATTR_NODE_DESC ), ! 324: .handle = ib_sma_node_desc, ! 325: }, ! 326: { ! 327: .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, ! 328: .class_version = IB_SMP_CLASS_VERSION, ! 329: .attr_id = htons ( IB_SMP_ATTR_GUID_INFO ), ! 330: .handle = ib_sma_guid_info, ! 331: }, ! 332: { ! 333: .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, ! 334: .class_version = IB_SMP_CLASS_VERSION, ! 335: .attr_id = htons ( IB_SMP_ATTR_PORT_INFO ), ! 336: .handle = ib_sma_port_info, ! 337: }, ! 338: { ! 339: .mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED, ! 340: .class_version = IB_SMP_CLASS_VERSION, ! 341: .attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE ), ! 342: .handle = ib_sma_pkey_table, ! 343: }, ! 344: }; ! 345: ! 346: /** ! 347: * Create subnet management agent and interface ! 348: * ! 349: * @v ibdev Infiniband device ! 350: * @v mi Management interface ! 351: * @ret rc Return status code ! 352: */ ! 353: int ib_create_sma ( struct ib_device *ibdev, struct ib_mad_interface *mi ) { ! 354: ! 355: /* Nothing to do */ ! 356: DBGC ( ibdev, "IBDEV %p SMA using SMI %p\n", ibdev, mi ); ! 357: ! 358: return 0; ! 359: } ! 360: ! 361: /** ! 362: * Destroy subnet management agent and interface ! 363: * ! 364: * @v ibdev Infiniband device ! 365: * @v mi Management interface ! 366: */ ! 367: void ib_destroy_sma ( struct ib_device *ibdev __unused, ! 368: struct ib_mad_interface *mi __unused ) { ! 369: /* Nothing to do */ ! 370: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.