選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

ib_smc.c 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
  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. FILE_LICENCE ( GPL2_OR_LATER );
  19. #include <stdint.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <errno.h>
  23. #include <unistd.h>
  24. #include <byteswap.h>
  25. #include <gpxe/infiniband.h>
  26. #include <gpxe/ib_smc.h>
  27. /**
  28. * @file
  29. *
  30. * Infiniband Subnet Management Client
  31. *
  32. */
  33. /**
  34. * Get port information
  35. *
  36. * @v ibdev Infiniband device
  37. * @v local_mad Method for issuing local MADs
  38. * @v mad Management datagram to fill in
  39. * @ret rc Return status code
  40. */
  41. static int ib_smc_get_port_info ( struct ib_device *ibdev,
  42. ib_local_mad_t local_mad,
  43. union ib_mad *mad ) {
  44. int rc;
  45. /* Construct MAD */
  46. memset ( mad, 0, sizeof ( *mad ) );
  47. mad->hdr.base_version = IB_MGMT_BASE_VERSION;
  48. mad->hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
  49. mad->hdr.class_version = 1;
  50. mad->hdr.method = IB_MGMT_METHOD_GET;
  51. mad->hdr.attr_id = htons ( IB_SMP_ATTR_PORT_INFO );
  52. mad->hdr.attr_mod = htonl ( ibdev->port );
  53. if ( ( rc = local_mad ( ibdev, mad ) ) != 0 ) {
  54. DBGC ( ibdev, "IBDEV %p could not get port info: %s\n",
  55. ibdev, strerror ( rc ) );
  56. return rc;
  57. }
  58. return 0;
  59. }
  60. /**
  61. * Get GUID information
  62. *
  63. * @v ibdev Infiniband device
  64. * @v local_mad Method for issuing local MADs
  65. * @v mad Management datagram to fill in
  66. * @ret rc Return status code
  67. */
  68. static int ib_smc_get_guid_info ( struct ib_device *ibdev,
  69. ib_local_mad_t local_mad,
  70. union ib_mad *mad ) {
  71. int rc;
  72. /* Construct MAD */
  73. memset ( mad, 0, sizeof ( *mad ) );
  74. mad->hdr.base_version = IB_MGMT_BASE_VERSION;
  75. mad->hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
  76. mad->hdr.class_version = 1;
  77. mad->hdr.method = IB_MGMT_METHOD_GET;
  78. mad->hdr.attr_id = htons ( IB_SMP_ATTR_GUID_INFO );
  79. if ( ( rc = local_mad ( ibdev, mad ) ) != 0 ) {
  80. DBGC ( ibdev, "IBDEV %p could not get GUID info: %s\n",
  81. ibdev, strerror ( rc ) );
  82. return rc;
  83. }
  84. return 0;
  85. }
  86. /**
  87. * Get partition key table
  88. *
  89. * @v ibdev Infiniband device
  90. * @v local_mad Method for issuing local MADs
  91. * @v mad Management datagram to fill in
  92. * @ret rc Return status code
  93. */
  94. static int ib_smc_get_pkey_table ( struct ib_device *ibdev,
  95. ib_local_mad_t local_mad,
  96. union ib_mad *mad ) {
  97. int rc;
  98. /* Construct MAD */
  99. memset ( mad, 0, sizeof ( *mad ) );
  100. mad->hdr.base_version = IB_MGMT_BASE_VERSION;
  101. mad->hdr.mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
  102. mad->hdr.class_version = 1;
  103. mad->hdr.method = IB_MGMT_METHOD_GET;
  104. mad->hdr.attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE );
  105. if ( ( rc = local_mad ( ibdev, mad ) ) != 0 ) {
  106. DBGC ( ibdev, "IBDEV %p could not get pkey table: %s\n",
  107. ibdev, strerror ( rc ) );
  108. return rc;
  109. }
  110. return 0;
  111. }
  112. /**
  113. * Get MAD parameters
  114. *
  115. * @v ibdev Infiniband device
  116. * @v local_mad Method for issuing local MADs
  117. * @ret rc Return status code
  118. */
  119. int ib_smc_update ( struct ib_device *ibdev, ib_local_mad_t local_mad ) {
  120. union ib_mad mad;
  121. struct ib_port_info *port_info = &mad.smp.smp_data.port_info;
  122. struct ib_guid_info *guid_info = &mad.smp.smp_data.guid_info;
  123. struct ib_pkey_table *pkey_table = &mad.smp.smp_data.pkey_table;
  124. int rc;
  125. /* Port info gives us the link state, the first half of the
  126. * port GID and the SM LID.
  127. */
  128. if ( ( rc = ib_smc_get_port_info ( ibdev, local_mad, &mad ) ) != 0 )
  129. return rc;
  130. memcpy ( &ibdev->gid.u.half[0], port_info->gid_prefix,
  131. sizeof ( ibdev->gid.u.half[0] ) );
  132. ibdev->lid = ntohs ( port_info->lid );
  133. ibdev->sm_lid = ntohs ( port_info->mastersm_lid );
  134. ibdev->link_width_enabled = port_info->link_width_enabled;
  135. ibdev->link_width_supported = port_info->link_width_supported;
  136. ibdev->link_width_active = port_info->link_width_active;
  137. ibdev->link_speed_supported =
  138. ( port_info->link_speed_supported__port_state >> 4 );
  139. ibdev->port_state =
  140. ( port_info->link_speed_supported__port_state & 0xf );
  141. ibdev->link_speed_active =
  142. ( port_info->link_speed_active__link_speed_enabled >> 4 );
  143. ibdev->link_speed_enabled =
  144. ( port_info->link_speed_active__link_speed_enabled & 0xf );
  145. ibdev->sm_sl = ( port_info->neighbour_mtu__mastersm_sl & 0xf );
  146. /* GUID info gives us the second half of the port GID */
  147. if ( ( rc = ib_smc_get_guid_info ( ibdev, local_mad, &mad ) ) != 0 )
  148. return rc;
  149. memcpy ( &ibdev->gid.u.half[1], guid_info->guid[0],
  150. sizeof ( ibdev->gid.u.half[1] ) );
  151. /* Get partition key */
  152. if ( ( rc = ib_smc_get_pkey_table ( ibdev, local_mad, &mad ) ) != 0 )
  153. return rc;
  154. ibdev->pkey = ntohs ( pkey_table->pkey[0] );
  155. DBGC ( ibdev, "IBDEV %p port GID is %08x:%08x:%08x:%08x\n", ibdev,
  156. htonl ( ibdev->gid.u.dwords[0] ),
  157. htonl ( ibdev->gid.u.dwords[1] ),
  158. htonl ( ibdev->gid.u.dwords[2] ),
  159. htonl ( ibdev->gid.u.dwords[3] ) );
  160. return 0;
  161. }