usr/src/cmd/ofusr/libibverbs/solaris_compatibility.c
changeset 62 aa9ba7d986b5
parent 58 2605957be88f
--- a/usr/src/cmd/ofusr/libibverbs/solaris_compatibility.c	Thu Jan 06 02:11:29 2011 -0800
+++ b/usr/src/cmd/ofusr/libibverbs/solaris_compatibility.c	Sat Jan 15 11:18:46 2011 -0800
@@ -38,6 +38,8 @@
  */
 #if defined(__SVR4) && defined(__sun)
 
+#pragma ident	"@(#)solaris_compatibility.c	1.3	10/12/22 SMI"
+
 #include <stdarg.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -46,6 +48,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <strings.h>
+#include <sys/ib/adapters/hermon/hermon_ioctl.h>
+#include <sys/ib/adapters/tavor/tavor_ioctl.h>
 
 #include <alloca.h>
 #include "../include/infiniband/arch.h"
@@ -126,6 +130,7 @@
 	char		ibd_sys_image_guid[20];
 	char		ibd_fw_ver[16];
 	char		ibd_name[8];
+	int		ibd_boardid_index;
 } ibdev_cache_info_t;
 
 /* tavor and hermon - hence 2 */
@@ -151,6 +156,209 @@
 } umad_cache_info_t;
 static umad_cache_info_t umad_dev_cache[MAX_HCAS * MAX_HCA_PORTS];
 
+/*
+ * Structure to hold the part number  & PSID for an HCA card
+ * This is a sub-set of the file :
+ * /ws/onnv-clone/usr/src/cmd/fwflash/plugins/hdrs/MELLANOX.h
+ */
+typedef struct mlx_mdr_s {
+	char *mlx_pn;
+	char *mlx_psid;
+} mlx_mdr_t;
+
+/*
+ * Magic decoder ring for matching HCA hardware/firmware.
+ * Part Number / PSID / String ID
+ */
+mlx_mdr_t mlx_mdr[] = {
+	/* For failure case, use unknown as "board-id" */
+	{ "unknown",		"unknown"	},
+
+	/* Part No		PSID		*/
+	{ "375-3605-01",	"SUN0160000001" },
+	{ "375-3382-01",	"SUN0030000001" },
+	{ "375-3481-01",	"SUN0040000001" },
+	{ "375-3418-01",	"SUN0040000001" },
+	{ "375-3259-01",	"SUN0010000001" },
+	{ "375-3259-03",	"SUN0010000001" },
+	{ "X1289A-Z",		"SUN0010010001" },
+	{ "375-3548-01",	"SUN0060000001" },
+	{ "375-3549-01",	"SUN0070000001" },
+	{ "375-3549-01",	"SUN0070130001" },
+	{ "375-3481-01",	"SUN0050000001" },
+	{ "375-3439-01",	"SUN0051000001" },
+	{ "375-3260-03",	"SUN0020000001" },
+	{ "375-3605-01",	"SUN0160000002" },
+	{ "375-3697-01",	"SUN0160000002" },
+	{ "375-3606-01",	"SUN0150000001" },
+	{ "375-3606-02",	"SUN0150000009" },
+	{ "375-3606-03",	"SUN0150000009" },
+	{ "375-3606-02",	"SUN0170000009" },
+	{ "375-3696-01",	"SUN0170000009" },
+	{ "375-3551-05",	"SUN0080000001" },
+	{ "MHEA28-XS",		"MT_0250000001" },
+	{ "MHEA28-XSC",		"MT_0390110001" },
+	{ "MHEA28-XT",		"MT_0150000001" },
+	{ "MHEA28-XTC",		"MT_0370110001" },
+	{ "MHGA28-XT",		"MT_0150000002" },
+	{ "MHGA28-XTC",		"MT_0370110002" },
+	{ "MHGA28-XTC",		"MT_0370130002" },
+	{ "MHGA28-XS",		"MT_0250000002" },
+	{ "MHGA28-XSC",		"MT_0390110002" },
+	{ "MHGA28-XSC",		"MT_0390130002" },
+	{ "MHEL-CF128",		"MT_0190000001" },
+	{ "MHEL-CF128-T",	"MT_00A0000001" },
+	{ "MTLP25208-CF128T",	"MT_00A0000001" },
+	{ "MHEL-CF128-TC",	"MT_00A0010001" },
+	{ "MHEL-CF128-TC",	"MT_0140010001" },
+	{ "MHEL-CF128-SC",	"MT_0190010001" },
+	{ "MHEA28-1TC",		"MT_02F0110001" },
+	{ "MHEA28-1SC",		"MT_0330110001" },
+	{ "MHGA28-1T",		"MT_0200000001" },
+	{ "MHGA28-1TC",		"MT_02F0110002" },
+	{ "MHGA28-1SC",		"MT_0330110002" },
+	{ "MHGA28-1S",		"MT_0430000001" },
+	{ "MHEL-CF256-T",	"MT_00B0000001" },
+	{ "MTLP25208-CF256T",	"MT_00B0000001" },
+	{ "MHEL-CF256-TC",	"MT_00B0010001" },
+	{ "MHEA28-2TC",		"MT_0300110001" },
+	{ "MHEA28-2SC",		"MT_0340110001" },
+	{ "MHGA28-2T",		"MT_0210000001" },
+	{ "MHGA28-2TC",		"MT_0300110002" },
+	{ "MHGA28-2SC",		"MT_0340110002" },
+	{ "MHEL-CF512-T",	"MT_00C0000001" },
+	{ "MTLP25208-CF512T",	"MT_00C0000001" },
+	{ "MHGA28-5T",		"MT_0220000001" },
+	{ "MHES14-XSC",		"MT_0410110001" },
+	{ "MHES14-XT",		"MT_01F0000001" },
+	{ "MHES14-XTC",		"MT_03F0110001" },
+	{ "MHES18-XS",		"MT_0260000001" },
+	{ "MHES18-XS",		"MT_0260010001" },
+	{ "MHES18-XSC",		"MT_03D0110001" },
+	{ "MHES18-XSC",		"MT_03D0120001" },
+	{ "MHES18-XSC",		"MT_03D0130001" },
+	{ "MHES18-XT",		"MT_0230000002" },
+	{ "MHES18-XT",		"MT_0230010002" },
+	{ "MHES18-XTC",		"MT_03B0110001" },
+	{ "MHES18-XTC",		"MT_03B0120001" },
+	{ "MHES18-XTC",		"MT_03B0140001" },
+	{ "MHGS18-XS",		"MT_0260000002" },
+	{ "MHGS18-XSC",		"MT_03D0110002" },
+	{ "MHGS18-XSC",		"MT_03D0120002" },
+	{ "MHGS18-XSC",		"MT_03D0130002" },
+	{ "MHGS18-XT",		"MT_0230000001" },
+	{ "MHGS18-XTC",		"MT_03B0110002" },
+	{ "MHGS18-XTC",		"MT_03B0120002" },
+	{ "MHGS18-XTC",		"MT_03B0140002" },
+	{ "MHXL-CF128",		"MT_0180000001" },
+	{ "MHXL-CF128-T",	"MT_0030000001" },
+	{ "MTLP23108-CF128T",	"MT_0030000001" },
+	{ "MHET2X-1SC",		"MT_0280110001" },
+	{ "MHET2X-1SC",		"MT_0280120001" },
+	{ "MHET2X-1TC",		"MT_0270110001" },
+	{ "MHET2X-1TC",		"MT_0270120001" },
+	{ "MHXL-CF256-T",	"MT_0040000001" },
+	{ "MHET2X-2SC",		"MT_02D0110001" },
+	{ "MHET2X-2SC",		"MT_02D0120001" },
+	{ "MHET2X-2TC",		"MT_02B0110001" },
+	{ "MHET2X-2TC",		"MT_02B0120001" },
+	{ "MHX-CE128-T",	"MT_0000000001" },
+	{ "MTPB23108-CE128",	"MT_0000000001" },
+	{ "MHX-CE256-T",	"MT_0010000001" },
+	{ "MTPB23108-CE256",	"MT_0010000001" },
+	{ "MHX-CE512-T",	"MT_0050000001" },
+	{ "MTPB23108-CE512",	"MT_0050000001" },
+	{ "MHEH28-XSC",		"MT_04C0110001" },
+	{ "MHEH28-XSC",		"MT_04C0130005" },
+	{ "MHEH28-XTC",		"MT_04A0110001" },
+	{ "MHEH28-XTC",		"MT_04A0130005" },
+	{ "MHGH28-XSC",		"MT_04C0110002" },
+	{ "MHGH28-XSC",		"MT_04C0120002" },
+	{ "MHGH28-XSC",		"MT_04C0140005" },
+	{ "MHGH28-XTC",		"MT_04A0110002" },
+	{ "MHGH28-XTC",		"MT_04A0120002" },
+	{ "MHGH28-XTC",		"MT_04A0140005" },
+	{ "MHGH29-XSC",		"MT_0A60110002" },
+	{ "MHGH29-XSC",		"MT_0A60120005" },
+	{ "MHGH29-XTC",		"MT_0A50110002" },
+	{ "MHGH29-XTC",		"MT_0A50120005" },
+	{ "MHJH29-XTC",		"MT_04E0110003" },
+	{ "MHJH29-XSC",		"MT_0500120005" },
+	{ "MHQH29-XTC",		"MT_04E0120005" },
+	{ "MHQH19-XTC",		"MT_0C40110009" },
+	{ "MHQH29-XTC",		"MT_0BB0110003" },
+	{ "MHQH29-XTC",		"MT_0BB0120003" },
+	{ "MHEH28B-XSR",	"MT_0D10110001" },
+	{ "MHEH28B-XTR",	"MT_0D20110001" },
+	{ "MHGH28B-XSR",	"MT_0D10110002" },
+	{ "MHGH28B-XTR",	"MT_0D20110002" },
+	{ "MHGH18B-XTR",	"MT_0D30110002" },
+	{ "MNEH28B-XSR",	"MT_0D40110004" },
+	{ "MNEH28B-XTR",	"MT_0D50110004" },
+	{ "MNEH29B-XSR",	"MT_0D40110010" },
+	{ "MNEH29B-XTR",	"MT_0D50110010" },
+	{ "MHGH29B-XSR",	"MT_0D10110008" },
+	{ "MHGH29B-XTR",	"MT_0D20110008" },
+	{ "MHJH29B-XSR",	"MT_0D10110009" },
+	{ "MHJH29B-XSR",	"MT_0D10120009" },
+	{ "MHJH29B-XTR",	"MT_0D20110009" },
+	{ "MHJH29B-XTR",	"MT_0D20120009" },
+	{ "MHGH19B-XSR",	"MT_0D60110008" },
+	{ "MHGH19B-XTR",	"MT_0D30110008" },
+	{ "MHJH19B-XTR",	"MT_0D30110009" },
+	{ "MHQH29B-XSR",	"MT_0D70110009" },
+	{ "MHQH29B-XTR",	"MT_0D80110009" },
+	{ "MHQH29B-XTR",	"MT_0D80120009" },
+	{ "MHQH29B-XTR",	"MT_0D80130009" },
+	{ "MHQH29B-XTR",	"MT_0E30110009" },
+	{ "MHRH29B-XSR",	"MT_0D70110008" },
+	{ "MHRH29B-XTR",	"MT_0D80110008" },
+	{ "MHQH19B-XTR",	"MT_0D90110009" },
+	{ "MHRH19B-XSR",	"MT_0E40110009" },
+	{ "MHRH19B-XTR",	"MT_0D90110008" },
+	{ "MNPH28C-XSR",	"MT_0DA0110004" },
+	{ "MNPH28C-XTR",	"MT_0DB0110004" },
+	{ "MNPH29C-XSR",	"MT_0DA0110010" },
+	{ "MNPH29C-XTR",	"MT_0DB0110010" },
+	{ "MNPH29C-XTR",	"MT_0DB0120010" },
+	{ "MNPH29C-XTR",	"MT_0DB0130010" },
+	{ "MNZH29-XSR",		"MT_0DC0110009" },
+	{ "MNZH29-XTR",		"MT_0DD0110009" },
+	{ "MNZH29-XTR",		"MT_0DD0120009" },
+	{ "MHQH19B-XNR",	"MT_0DF0110009" },
+	{ "MHQH19B-XNR",	"MT_0DF0120009" },
+	{ "MNQH19-XTR",		"MT_0D80110017" },
+	{ "MNQH19C-XTR",	"MT_0E20110017" },
+	{ "MHZH29B-XSR",	"MT_0E80110009" },
+	{ "MHZH29B-XTR",	"MT_0E90110009" },
+	{ "MHZH29B-XTR",	"MT_0E90110009" },
+	{ "MHQA19-XTR",		"MT_0EA0110009" },
+	{ "MHRA19-XTR",		"MT_0EB0110008" },
+	{ "MHQH29C-XTR",	"MT_0EF0110009" },
+	{ "MHQH29C-XSR",	"MT_0F00110009" },
+	{ "MHRH29C-XTR",	"MT_0F10110008" },
+	{ "MHRH29C-XSR",	"MT_0F20110008" },
+	{ "MHPH29D-XTR",	"MT_0F30110010" },
+	{ "MHPH29D-XSR",	"MT_0F40110010" },
+	{ "MNPA19-XTR",		"MT_0F60110010" },
+	{ "MNPA19-XSR",		"MT_0F70110010" },
+
+	/* Ethernet cards */
+	{ "MNEH28B-XTR",	"MT_0D50110004" },
+	{ "MNEH29B-XSR",	"MT_0D40110010" },
+	{ "MNEH29B-XTR",	"MT_0D50110010" },
+	{ "MNPH28C-XSR",	"MT_0DA0110004" },
+	{ "MNPH28C-XTR",	"MT_0DB0110004" },
+	{ "MNPH29C-XSR",	"MT_0DA0110010" },
+	{ "MNPH29C-XTR",	"MT_0DB0110010" },
+	{ "X6275 M2 10GbE",	"X6275M2_10G"   }
+};
+
+/* Get mlx_mdr[] array size */
+#define	MLX_SZ_MLX_MDR		sizeof (mlx_mdr)
+#define	MLX_SZ_MLX_MDR_STRUCT	sizeof (mlx_mdr[0])
+#define	MLX_MAX_ID		(MLX_SZ_MLX_MDR / MLX_SZ_MLX_MDR_STRUCT)
+
 pthread_once_t		oneTimeInit = PTHREAD_ONCE_INIT;
 static int 		umad_cache_cnt = 0;
 static int 		ibdev_cache_cnt = 0;
@@ -165,8 +373,8 @@
 
 static di_node_t	root_node;
 
-void __attribute__ ((constructor)) solaris_init(void);
-void __attribute__ ((destructor)) solaris_fini(void);
+void __attribute__((constructor))solaris_init(void);
+void __attribute__((destructor))solaris_fini(void);
 
 void
 solaris_init(void)
@@ -297,17 +505,17 @@
 
 		guid = ntohll(device_attr.node_guid);
 		sprintf(info.ibd_node_guid_str, "%04x:%04x:%04x:%04x",
-		    (unsigned) (guid >> 48) & 0xffff,
-		    (unsigned) (guid >> 32) & 0xffff,
-		    (unsigned) (guid >> 16) & 0xffff,
-		    (unsigned) (guid >>  0) & 0xffff);
+		    (unsigned)(guid >> 48) & 0xffff,
+		    (unsigned)(guid >> 32) & 0xffff,
+		    (unsigned)(guid >> 16) & 0xffff,
+		    (unsigned)(guid >>  0) & 0xffff);
 
 		guid = ntohll(device_attr.sys_image_guid);
 		sprintf(info.ibd_sys_image_guid, "%04x:%04x:%04x:%04x",
-		    (unsigned) (guid >> 48) & 0xffff,
-		    (unsigned) (guid >> 32) & 0xffff,
-		    (unsigned) (guid >> 16) & 0xffff,
-		    (unsigned) (guid >>  0) & 0xffff);
+		    (unsigned)(guid >> 48) & 0xffff,
+		    (unsigned)(guid >> 32) & 0xffff,
+		    (unsigned)(guid >> 16) & 0xffff,
+		    (unsigned)(guid >>  0) & 0xffff);
 
 		(void) strcpy(info.ibd_fw_ver, device_attr.fw_ver);
 		info.ibd_hw_rev = device_attr.hw_ver;
@@ -317,6 +525,8 @@
 		dev_num = atoi(p);
 		(void) strcpy(info.ibd_name, ibdev);
 
+		info.ibd_boardid_index = -1;
+
 		if (ibdev_cache_add(dev_num, &info)) {
 			fprintf(stderr, "failed to add dev %d to ibdev cache\n",
 			    dev_num);
@@ -386,12 +596,12 @@
 		info.uvc_vendor_id = *intv;
 
 		if (di_prop_lookup_ints(devt, node, "device-id", &intv) != 1) {
-		    goto error_exit1;
+			goto error_exit1;
 		}
 		info.uvc_device_id = *intv;
 
 		if (di_prop_lookup_int64(devt, node, "guid", &guid) != 1) {
-		    goto error_exit1;
+			goto error_exit1;
 		}
 
 		/* abi version only on minor node 0 */
@@ -895,7 +1105,7 @@
 	 * associated GUID to perform the mapping.
 	 */
 	uverbs_minor = strtol(dev_name + strlen(UVERBS_KERNEL_SYSFS_NAME) - 1,
-								NULL, 0);
+	    NULL, 0);
 	if (uverbs_minor >= MAX_HCAS) {
 		fprintf(stderr, "Invalid device %s\n", dev_name);
 		goto err_dev;
@@ -963,7 +1173,7 @@
 	if (check_path(path, CP_SOL_UVERBS, &device_num)) {
 
 		if (device_num >= MAX_HCAS) {
-		    fprintf(stderr, "Invalid path%s\n", path);
+			fprintf(stderr, "Invalid path%s\n", path);
 			goto exit;
 		}
 
@@ -1040,14 +1250,14 @@
 			    htonll(gids[gid_num].global.interface_id);
 			len = 1 + sprintf(buf,
 			    "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
-			    (unsigned) (subnet_prefix >>  48) & 0xffff,
-			    (unsigned) (subnet_prefix >>  32) & 0xffff,
-			    (unsigned) (subnet_prefix >>  16) & 0xffff,
-			    (unsigned) (subnet_prefix >>   0) & 0xffff,
-			    (unsigned) (interface_id  >>  48) & 0xffff,
-			    (unsigned) (interface_id  >>  32) & 0xffff,
-			    (unsigned) (interface_id  >>  16) & 0xffff,
-			    (unsigned) (interface_id  >>   0) & 0xffff);
+			    (unsigned)(subnet_prefix >>  48) & 0xffff,
+			    (unsigned)(subnet_prefix >>  32) & 0xffff,
+			    (unsigned)(subnet_prefix >>  16) & 0xffff,
+			    (unsigned)(subnet_prefix >>   0) & 0xffff,
+			    (unsigned)(interface_id  >>  48) & 0xffff,
+			    (unsigned)(interface_id  >>  32) & 0xffff,
+			    (unsigned)(interface_id  >>  16) & 0xffff,
+			    (unsigned)(interface_id  >>   0) & 0xffff);
 		}
 		if (gids)
 			free(gids);
@@ -1178,13 +1388,115 @@
 			len = 1 + sprintf(buf, "%f", rate);
 		} else if (strcmp(path, "cap_mask") == 0) {
 			len = 1 + sprintf(buf, "0x%08x",
-				port_attr.port_cap_flags);
+			    port_attr.port_cap_flags);
 		}
 	}
 exit:
 	return (len);
 }
 
+
+/*
+ * This function passes the HW Part number string obtained from driver
+ * IOCTL. The memory for "hca_hwpn" argument has to be passed by the
+ * caller and has to be at least 64 bytes in size.
+ */
+static int
+get_hca_hwpn_str(char *ibd_name, int fd, char *hca_hwpn)
+{
+	hermon_flash_init_ioctl_t	hermon_flash_info;
+	tavor_flash_init_ioctl_t	tavor_flash_info;
+	int				rc;
+
+	if (strncmp(ibd_name, "mthca", 5) == 0) {
+		if ((rc = ioctl(fd, TAVOR_IOCTL_FLASH_INIT,
+		    &tavor_flash_info)) != 0)
+			return (rc);
+		strncpy(hca_hwpn, tavor_flash_info.tf_hwpn, 64);
+	} else {
+		if ((rc = ioctl(fd, HERMON_IOCTL_FLASH_INIT,
+		    &hermon_flash_info)) != 0)
+			return (rc);
+		strncpy(hca_hwpn, hermon_flash_info.af_hwpn, 64);
+	}
+	return (0);
+}
+
+static void
+init_boardid_index(ibdev_cache_info_t *ibd_info)
+{
+	int	i;
+	int	fd;
+	char	*dev_path;
+	char	path_buf[MAXPATHLEN];
+	char	hca_hwpn[64];
+	char	*hwpnp;
+
+
+	if (pthread_mutex_lock(&uverbs_cache_mutex) != 0) {
+		fprintf(stderr, "failed: to acquire "
+		    "uverbs_cache_mutex %s\n",
+		    strerror(errno));
+		goto boardid_err;
+	}
+	if (!uverbs_cache_initialized) {
+		uverbs_cache_init();
+		uverbs_cache_initialized = B_TRUE;
+	}
+	(void) pthread_mutex_unlock(&uverbs_cache_mutex);
+
+	for (i = 0; i < MAX_HCAS; i++) {
+		if (uverbs_dev_cache[i].uvc_valid &&
+		    strcmp(uverbs_dev_cache[i].uvc_ibdev_name,
+		    ibd_info->ibd_name) == 0) {
+			break;
+		}
+	}
+
+	if (i == MAX_HCAS) {
+		fprintf(stderr, "failed to find uverbs_dev for %s\n",
+		    ibd_info->ibd_name);
+		goto boardid_err;
+	}
+
+	dev_path = uverbs_dev_cache[i].uvc_ibdev_hca_path;
+	strncpy(path_buf, "/devices", sizeof (path_buf));
+	strncat(path_buf, dev_path, sizeof (path_buf));
+	strncat(path_buf, ":devctl", sizeof (path_buf));
+
+	fd = open(path_buf, O_RDWR);
+	if (fd < 0) {
+		goto boardid_err;
+	}
+
+	if (get_hca_hwpn_str(ibd_info->ibd_name, fd, hca_hwpn)) {
+		close(fd);
+		goto boardid_err;
+	}
+	close(fd);
+	if ((hwpnp = strchr(hca_hwpn, ' ')) != NULL)
+		*hwpnp = '\0';
+
+	/*
+	 * Find part number, set the boardid_index,
+	 * Skip index 0, as it is for failure "unknown"
+	 * case.
+	 */
+	for (i = 1; i < MLX_MAX_ID; i++) {
+		if (strcmp((const char *)hca_hwpn,
+		    mlx_mdr[i].mlx_pn) == 0) {
+
+			/* Set boardid_index */
+			ibd_info->ibd_boardid_index = i;
+			return;
+		}
+	}
+
+boardid_err:
+	/* Failure case, default to "unknown" */
+	ibd_info->ibd_boardid_index = 0;
+}
+
 static int
 infiniband(char *path, char *buf, size_t size)
 {
@@ -1207,8 +1519,6 @@
 		len = infiniband_ports(path, buf, size, dev_name);
 	} else if (strcmp(path, "node_type") == 0) {
 		len = 1 + sprintf(buf, "%d", IBV_NODE_CA);
-	} else if (strcmp(path, "board_id") == 0) {
-		len = 1 + sprintf(buf, "unknown");
 	} else {
 		if (!(info = get_device_info(dev_name)))
 			goto exit;
@@ -1226,6 +1536,12 @@
 				len = 1 + sprintf(buf, "%d", 0);
 			else
 				len = 1 + sprintf(buf, "unavailable");
+		} else if (strcmp(path, "board_id") == 0) {
+			if (info->ibd_boardid_index == -1)
+				init_boardid_index(info);
+
+			len = 1 + sprintf(buf, "%s",
+			    mlx_mdr[info->ibd_boardid_index].mlx_psid);
 		}
 	}
 exit:
@@ -1311,7 +1627,7 @@
 		if (check_path(path, CP_RDMA_CM, NULL)) {
 			if (strcmp(path, "abi_version") == 0) {
 				len = 1 + sprintf(buf, "%d",
-					RDMA_USER_CM_MAX_ABI_VERSION);
+				    RDMA_USER_CM_MAX_ABI_VERSION);
 			}
 		}
 	}