11cfa752fSRamaswamy Tummala /*
21cfa752fSRamaswamy Tummala  * CDDL HEADER START
31cfa752fSRamaswamy Tummala  *
41cfa752fSRamaswamy Tummala  * The contents of this file are subject to the terms of the
51cfa752fSRamaswamy Tummala  * Common Development and Distribution License (the "License").
61cfa752fSRamaswamy Tummala  * You may not use this file except in compliance with the License.
71cfa752fSRamaswamy Tummala  *
81cfa752fSRamaswamy Tummala  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91cfa752fSRamaswamy Tummala  * or http://www.opensolaris.org/os/licensing.
101cfa752fSRamaswamy Tummala  * See the License for the specific language governing permissions
111cfa752fSRamaswamy Tummala  * and limitations under the License.
121cfa752fSRamaswamy Tummala  *
131cfa752fSRamaswamy Tummala  * When distributing Covered Code, include this CDDL HEADER in each
141cfa752fSRamaswamy Tummala  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151cfa752fSRamaswamy Tummala  * If applicable, add the following below this CDDL HEADER, with the
161cfa752fSRamaswamy Tummala  * fields enclosed by brackets "[]" replaced with your own identifying
171cfa752fSRamaswamy Tummala  * information: Portions Copyright [yyyy] [name of copyright owner]
181cfa752fSRamaswamy Tummala  *
191cfa752fSRamaswamy Tummala  * CDDL HEADER END
201cfa752fSRamaswamy Tummala  */
211cfa752fSRamaswamy Tummala /*
221cfa752fSRamaswamy Tummala  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
231cfa752fSRamaswamy Tummala  */
241cfa752fSRamaswamy Tummala 
251cfa752fSRamaswamy Tummala #include <stdio.h>
261cfa752fSRamaswamy Tummala #include <libdevinfo.h>
271cfa752fSRamaswamy Tummala #include <sys/types.h>
281cfa752fSRamaswamy Tummala #include <sys/stat.h>
291cfa752fSRamaswamy Tummala #include <string.h>
301cfa752fSRamaswamy Tummala #include <fcntl.h>
311cfa752fSRamaswamy Tummala #include <unistd.h>
321cfa752fSRamaswamy Tummala #include <stropts.h>
331cfa752fSRamaswamy Tummala #include <stdlib.h>
341cfa752fSRamaswamy Tummala #include <errno.h>
351cfa752fSRamaswamy Tummala #include <strings.h>
361cfa752fSRamaswamy Tummala #include <libintl.h>
371cfa752fSRamaswamy Tummala #include <net/if_types.h>
381cfa752fSRamaswamy Tummala #include <net/if_dl.h>
391cfa752fSRamaswamy Tummala #include <sys/dld.h>
401cfa752fSRamaswamy Tummala #include <sys/ib/ib_types.h>
411cfa752fSRamaswamy Tummala #include <sys/ibpart.h>
421cfa752fSRamaswamy Tummala #include <libdllink.h>
431cfa752fSRamaswamy Tummala #include <libdladm.h>
441cfa752fSRamaswamy Tummala #include <libdlib.h>
451cfa752fSRamaswamy Tummala #include <libdladm_impl.h>
461cfa752fSRamaswamy Tummala 
471cfa752fSRamaswamy Tummala /*
481cfa752fSRamaswamy Tummala  * IP over IB administration API; see PSARC/2010/085
491cfa752fSRamaswamy Tummala  */
501cfa752fSRamaswamy Tummala 
511cfa752fSRamaswamy Tummala /*
521cfa752fSRamaswamy Tummala  * Function prototypes
531cfa752fSRamaswamy Tummala  */
541cfa752fSRamaswamy Tummala dladm_status_t dladm_part_create(dladm_handle_t, datalink_id_t, ib_pkey_t,
551cfa752fSRamaswamy Tummala     uint32_t, char *, datalink_id_t *, dladm_arg_list_t *);
561cfa752fSRamaswamy Tummala static dladm_status_t	i_dladm_part_create(dladm_handle_t,
571cfa752fSRamaswamy Tummala     dladm_part_attr_t *);
58c87dd6b7SRajkumar Sivaprakasam static dladm_status_t	dladm_part_persist_conf(dladm_handle_t, const char *,
59c87dd6b7SRajkumar Sivaprakasam     dladm_part_attr_t *);
601cfa752fSRamaswamy Tummala static dladm_status_t i_dladm_part_delete(dladm_handle_t, datalink_id_t);
611cfa752fSRamaswamy Tummala dladm_status_t	dladm_part_delete(dladm_handle_t, datalink_id_t, int);
621cfa752fSRamaswamy Tummala static int	i_dladm_part_up(dladm_handle_t, datalink_id_t, void *);
631cfa752fSRamaswamy Tummala dladm_status_t	dladm_part_up(dladm_handle_t, datalink_id_t, uint32_t);
641cfa752fSRamaswamy Tummala 
651cfa752fSRamaswamy Tummala /*
661cfa752fSRamaswamy Tummala  * Convert a error status returned by the IP over IB kernel driver to a
671cfa752fSRamaswamy Tummala  * valid dladm status.
681cfa752fSRamaswamy Tummala  */
691cfa752fSRamaswamy Tummala static dladm_status_t
dladm_ib_ioctl_err2status(int err)701cfa752fSRamaswamy Tummala dladm_ib_ioctl_err2status(int err)
711cfa752fSRamaswamy Tummala {
721cfa752fSRamaswamy Tummala 	switch (err) {
731cfa752fSRamaswamy Tummala 	case 0:
741cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_OK);
751cfa752fSRamaswamy Tummala 	case IBD_INVALID_PORT_INST:
761cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_INVALID_PORT_INSTANCE);
771cfa752fSRamaswamy Tummala 	case IBD_PORT_IS_DOWN:
781cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_PORT_IS_DOWN);
791cfa752fSRamaswamy Tummala 	case IBD_PKEY_NOT_PRESENT:
801cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_PKEY_NOT_PRESENT);
811cfa752fSRamaswamy Tummala 	case IBD_PARTITION_EXISTS:
821cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_PARTITION_EXISTS);
831cfa752fSRamaswamy Tummala 	case IBD_INVALID_PKEY:
841cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_INVALID_PKEY);
851cfa752fSRamaswamy Tummala 	case IBD_NO_HW_RESOURCE:
861cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_NO_IB_HW_RESOURCE);
871cfa752fSRamaswamy Tummala 	case IBD_INVALID_PKEY_TBL_SIZE:
881cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_INVALID_PKEY_TBL_SIZE);
891cfa752fSRamaswamy Tummala 	default:
901cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_FAILED);
911cfa752fSRamaswamy Tummala 	}
921cfa752fSRamaswamy Tummala }
931cfa752fSRamaswamy Tummala 
941cfa752fSRamaswamy Tummala static dladm_status_t
i_dladm_ib_ioctl(dladm_handle_t handle,int ioccmd,ibd_ioctl_t * iocp)951cfa752fSRamaswamy Tummala i_dladm_ib_ioctl(dladm_handle_t handle, int ioccmd, ibd_ioctl_t *iocp)
961cfa752fSRamaswamy Tummala {
971cfa752fSRamaswamy Tummala 	if (ioctl(dladm_dld_fd(handle), ioccmd, iocp) == 0)
981cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_OK);
991cfa752fSRamaswamy Tummala 
1001cfa752fSRamaswamy Tummala 	if (iocp->ioc_status == 0)
1011cfa752fSRamaswamy Tummala 		return (dladm_errno2status(errno));
1021cfa752fSRamaswamy Tummala 
1031cfa752fSRamaswamy Tummala 	return (dladm_ib_ioctl_err2status(iocp->ioc_status));
1041cfa752fSRamaswamy Tummala }
1051cfa752fSRamaswamy Tummala 
1061cfa752fSRamaswamy Tummala /*
1071cfa752fSRamaswamy Tummala  * Get the active configuration information for the partition given by
1081cfa752fSRamaswamy Tummala  * the 'linkid'.
1091cfa752fSRamaswamy Tummala  */
1101cfa752fSRamaswamy Tummala static dladm_status_t
i_dladm_part_info_active(dladm_handle_t handle,datalink_id_t linkid,dladm_part_attr_t * attrp)1111cfa752fSRamaswamy Tummala i_dladm_part_info_active(dladm_handle_t handle, datalink_id_t linkid,
1121cfa752fSRamaswamy Tummala     dladm_part_attr_t *attrp)
1131cfa752fSRamaswamy Tummala {
1141cfa752fSRamaswamy Tummala 	ibpart_ioctl_t ioc;
1151cfa752fSRamaswamy Tummala 	dladm_status_t status = DLADM_STATUS_OK;
1161cfa752fSRamaswamy Tummala 
1171cfa752fSRamaswamy Tummala 	bzero(&ioc, sizeof (ioc));
1181cfa752fSRamaswamy Tummala 	bzero(attrp, sizeof (*attrp));
1191cfa752fSRamaswamy Tummala 	/*
1201cfa752fSRamaswamy Tummala 	 * The ioc_linkid here will contain the data link id of the IB partition
1211cfa752fSRamaswamy Tummala 	 * object.
1221cfa752fSRamaswamy Tummala 	 */
1231cfa752fSRamaswamy Tummala 	ioc.ibdioc.ioc_linkid = linkid;
1241cfa752fSRamaswamy Tummala 	ioc.ibdioc.ioc_info_cmd = IBD_INFO_CMD_IBPART;
1251cfa752fSRamaswamy Tummala 
1261cfa752fSRamaswamy Tummala 	status = i_dladm_ib_ioctl(handle, IBD_INFO_IBPART, (ibd_ioctl_t *)&ioc);
1271cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK)
1281cfa752fSRamaswamy Tummala 		goto bail;
1291cfa752fSRamaswamy Tummala 
1301cfa752fSRamaswamy Tummala 	/*
1311cfa752fSRamaswamy Tummala 	 * On return from the ioctl ioc_linkid field contains the IB port's
1321cfa752fSRamaswamy Tummala 	 * linkid.
1331cfa752fSRamaswamy Tummala 	 */
1341cfa752fSRamaswamy Tummala 	attrp->dia_physlinkid = ioc.ibdioc.ioc_linkid;
1351cfa752fSRamaswamy Tummala 	attrp->dia_partlinkid = ioc.ioc_partid;
1361cfa752fSRamaswamy Tummala 	attrp->dia_pkey = ioc.ioc_pkey;
1371cfa752fSRamaswamy Tummala 	attrp->dia_portnum = ioc.ibdioc.ioc_portnum;
1381cfa752fSRamaswamy Tummala 	attrp->dia_hca_guid = ioc.ibdioc.ioc_hcaguid;
1391cfa752fSRamaswamy Tummala 	attrp->dia_port_guid = ioc.ibdioc.ioc_portguid;
1401cfa752fSRamaswamy Tummala 	attrp->dia_instance = ioc.ibdioc.ioc_port_inst;
1411cfa752fSRamaswamy Tummala 
1421cfa752fSRamaswamy Tummala 	/*
1431cfa752fSRamaswamy Tummala 	 * If the IP over IB driver reports that this partition was created
1441cfa752fSRamaswamy Tummala 	 * forcibly, then set the force create flag.
1451cfa752fSRamaswamy Tummala 	 */
1461cfa752fSRamaswamy Tummala 	if (ioc.ioc_force_create)
147c87dd6b7SRajkumar Sivaprakasam 		attrp->dia_flags |= DLADM_PART_FORCE_CREATE;
1481cfa752fSRamaswamy Tummala 
1491cfa752fSRamaswamy Tummala bail:
1501cfa752fSRamaswamy Tummala 	return (status);
1511cfa752fSRamaswamy Tummala }
1521cfa752fSRamaswamy Tummala 
1531cfa752fSRamaswamy Tummala /*
1541cfa752fSRamaswamy Tummala  * Get the configuration information about the IB partition 'linkid' from the
1551cfa752fSRamaswamy Tummala  * persistent configuration.
1561cfa752fSRamaswamy Tummala  */
1571cfa752fSRamaswamy Tummala static dladm_status_t
i_dladm_part_info_persist(dladm_handle_t handle,datalink_id_t linkid,dladm_part_attr_t * attrp)1581cfa752fSRamaswamy Tummala i_dladm_part_info_persist(dladm_handle_t handle, datalink_id_t linkid,
1591cfa752fSRamaswamy Tummala     dladm_part_attr_t *attrp)
1601cfa752fSRamaswamy Tummala {
1611cfa752fSRamaswamy Tummala 	dladm_conf_t conf;
1621cfa752fSRamaswamy Tummala 	dladm_status_t status;
1631cfa752fSRamaswamy Tummala 	char linkover[MAXLINKNAMELEN];
1641cfa752fSRamaswamy Tummala 	datalink_class_t class;
1651cfa752fSRamaswamy Tummala 	boolean_t force = B_FALSE;
1661cfa752fSRamaswamy Tummala 
167f7952617SToomas Soome 	conf.ds_readonly = B_FALSE;
168f7952617SToomas Soome 	conf.ds_confid = DLADM_INVALID_CONF;
169f7952617SToomas Soome 
1701cfa752fSRamaswamy Tummala 	/* Get the IB partition's datalink ID */
1711cfa752fSRamaswamy Tummala 	if ((status = dladm_datalink_id2info(handle, linkid, NULL, &class,
1721cfa752fSRamaswamy Tummala 	    NULL, NULL, 0)) != DLADM_STATUS_OK)
1731cfa752fSRamaswamy Tummala 		goto done;
1741cfa752fSRamaswamy Tummala 
1751cfa752fSRamaswamy Tummala 	bzero(attrp, sizeof (*attrp));
1761cfa752fSRamaswamy Tummala 	attrp->dia_partlinkid = linkid;
17732715170SCathy Zhou 	if ((status = dladm_getsnap_conf(handle, linkid, &conf)) !=
1781cfa752fSRamaswamy Tummala 	    DLADM_STATUS_OK)
1791cfa752fSRamaswamy Tummala 		return (status);
1801cfa752fSRamaswamy Tummala 
1811cfa752fSRamaswamy Tummala 	/*
1821cfa752fSRamaswamy Tummala 	 * Get the name of the IB Phys link over which IB partition was
1831cfa752fSRamaswamy Tummala 	 * created.
1841cfa752fSRamaswamy Tummala 	 */
1851cfa752fSRamaswamy Tummala 	status = dladm_get_conf_field(handle, conf, FLINKOVER, linkover,
1861cfa752fSRamaswamy Tummala 	    sizeof (linkover));
1871cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK) {
1881cfa752fSRamaswamy Tummala 		attrp->dia_physlinkid = DATALINK_INVALID_LINKID;
1891cfa752fSRamaswamy Tummala 		goto done;
1901cfa752fSRamaswamy Tummala 	} else {
1911cfa752fSRamaswamy Tummala 		/* Get the IB Phys link's datalink ID */
1921cfa752fSRamaswamy Tummala 		if ((status = dladm_name2info(handle, linkover,
1931cfa752fSRamaswamy Tummala 		    &attrp->dia_physlinkid, NULL, NULL, NULL)) !=
1941cfa752fSRamaswamy Tummala 		    DLADM_STATUS_OK)
1951cfa752fSRamaswamy Tummala 			goto done;
1961cfa752fSRamaswamy Tummala 	}
1971cfa752fSRamaswamy Tummala 
1981cfa752fSRamaswamy Tummala 	/* Get the IB partition's P_Key */
1991cfa752fSRamaswamy Tummala 	status = dladm_get_conf_field(handle, conf, FPORTPKEY,
2001cfa752fSRamaswamy Tummala 	    &attrp->dia_pkey, sizeof (uint64_t));
2011cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK)
2021cfa752fSRamaswamy Tummala 		goto done;
2031cfa752fSRamaswamy Tummala 
2041cfa752fSRamaswamy Tummala 	if (class != DATALINK_CLASS_PART) {
2051cfa752fSRamaswamy Tummala 		status = DLADM_STATUS_BADARG;
2061cfa752fSRamaswamy Tummala 		goto done;
2071cfa752fSRamaswamy Tummala 	}
2081cfa752fSRamaswamy Tummala 
2091cfa752fSRamaswamy Tummala 	/*
2101cfa752fSRamaswamy Tummala 	 * If the FFORCE field is set in the persistent configuration database
2111cfa752fSRamaswamy Tummala 	 * set the force create flag in the partition attributes.
2121cfa752fSRamaswamy Tummala 	 */
2131cfa752fSRamaswamy Tummala 	status = dladm_get_conf_field(handle, conf, FFORCE, &force,
2141cfa752fSRamaswamy Tummala 	    sizeof (boolean_t));
2151cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK) {
2161cfa752fSRamaswamy Tummala 		if (status != DLADM_STATUS_NOTFOUND)
2171cfa752fSRamaswamy Tummala 			goto done;
2181cfa752fSRamaswamy Tummala 	} else if (force == B_TRUE) {
219c87dd6b7SRajkumar Sivaprakasam 		attrp->dia_flags |= DLADM_PART_FORCE_CREATE;
2201cfa752fSRamaswamy Tummala 	}
2211cfa752fSRamaswamy Tummala 
2221cfa752fSRamaswamy Tummala 	status = DLADM_STATUS_OK;
2231cfa752fSRamaswamy Tummala done:
2241cfa752fSRamaswamy Tummala 	dladm_destroy_conf(handle, conf);
2251cfa752fSRamaswamy Tummala 	return (status);
2261cfa752fSRamaswamy Tummala }
2271cfa752fSRamaswamy Tummala 
2281cfa752fSRamaswamy Tummala /*
2291cfa752fSRamaswamy Tummala  * Get the configuration information for the IB partition given by the datalink
2301cfa752fSRamaswamy Tummala  * ID 'linkid'. Based on the 'flags' field the information is either from the
2311cfa752fSRamaswamy Tummala  * active system (DLADM_OPT_ACTIVE) or from the persistent configuration
2321cfa752fSRamaswamy Tummala  * database.
2331cfa752fSRamaswamy Tummala  */
2341cfa752fSRamaswamy Tummala dladm_status_t
dladm_part_info(dladm_handle_t handle,datalink_id_t linkid,dladm_part_attr_t * attrp,uint32_t flags)2351cfa752fSRamaswamy Tummala dladm_part_info(dladm_handle_t handle, datalink_id_t linkid,
2361cfa752fSRamaswamy Tummala     dladm_part_attr_t *attrp, uint32_t flags)
2371cfa752fSRamaswamy Tummala {
2381cfa752fSRamaswamy Tummala 	if (flags == DLADM_OPT_ACTIVE)
2391cfa752fSRamaswamy Tummala 		return (i_dladm_part_info_active(handle, linkid, attrp));
2401cfa752fSRamaswamy Tummala 	else if (flags == DLADM_OPT_PERSIST)
2411cfa752fSRamaswamy Tummala 		return (i_dladm_part_info_persist(handle, linkid, attrp));
2421cfa752fSRamaswamy Tummala 	else
2431cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_BADARG);
2441cfa752fSRamaswamy Tummala }
2451cfa752fSRamaswamy Tummala 
2461cfa752fSRamaswamy Tummala /*
2471cfa752fSRamaswamy Tummala  * Get the configuration information for the IB Phys link given by the datalink
2481cfa752fSRamaswamy Tummala  * ID 'linkid'.
2491cfa752fSRamaswamy Tummala  */
2501cfa752fSRamaswamy Tummala dladm_status_t
dladm_ib_info(dladm_handle_t handle,datalink_id_t linkid,dladm_ib_attr_t * attrp,uint32_t flags __unused)2511cfa752fSRamaswamy Tummala dladm_ib_info(dladm_handle_t handle, datalink_id_t linkid,
25220535e13SToomas Soome     dladm_ib_attr_t *attrp, uint32_t flags __unused)
2531cfa752fSRamaswamy Tummala {
254c87dd6b7SRajkumar Sivaprakasam 	uint_t instance;
2551cfa752fSRamaswamy Tummala 	ibport_ioctl_t ioc;
2561cfa752fSRamaswamy Tummala 	dladm_phys_attr_t	dpa;
2571cfa752fSRamaswamy Tummala 	dladm_status_t status = DLADM_STATUS_OK;
2581cfa752fSRamaswamy Tummala 
2591cfa752fSRamaswamy Tummala 	/*
2601cfa752fSRamaswamy Tummala 	 * We need to get the device name of the IB Phys link to get the
2611cfa752fSRamaswamy Tummala 	 * correct instance number of the IP over IB driver instance.
2621cfa752fSRamaswamy Tummala 	 */
2631cfa752fSRamaswamy Tummala 	if (dladm_phys_info(handle, linkid, &dpa, DLADM_OPT_ACTIVE)
2641cfa752fSRamaswamy Tummala 	    != DLADM_STATUS_OK)
2651cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_BADARG);
2661cfa752fSRamaswamy Tummala 
2671cfa752fSRamaswamy Tummala 	/*
2681cfa752fSRamaswamy Tummala 	 * Get the instance number of the IP over IB driver instance which
2691cfa752fSRamaswamy Tummala 	 * represents this IB Phys link.
2701cfa752fSRamaswamy Tummala 	 */
271c87dd6b7SRajkumar Sivaprakasam 	if (dladm_parselink(dpa.dp_dev, NULL, &instance) != DLADM_STATUS_OK)
2721cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_FAILED);
2731cfa752fSRamaswamy Tummala 
2741cfa752fSRamaswamy Tummala 	bzero(&ioc, sizeof (ioc));
2751cfa752fSRamaswamy Tummala 	/*
2761cfa752fSRamaswamy Tummala 	 * The ioc_linkid here will contain IB port linkid here. We make the
2771cfa752fSRamaswamy Tummala 	 * first ioctl call to get the P_Key table size for this HCA port.
2781cfa752fSRamaswamy Tummala 	 */
2791cfa752fSRamaswamy Tummala 	ioc.ibdioc.ioc_linkid = linkid;
2801cfa752fSRamaswamy Tummala 	ioc.ibdioc.ioc_info_cmd = IBD_INFO_CMD_PKEYTBLSZ;
2811cfa752fSRamaswamy Tummala 	ioc.ioc_pkey_tbl_sz = 0;
2821cfa752fSRamaswamy Tummala 	ioc.ibdioc.ioc_port_inst = instance;
2831cfa752fSRamaswamy Tummala 
2841cfa752fSRamaswamy Tummala 	status = i_dladm_ib_ioctl(handle, IBD_INFO_IBPART, (ibd_ioctl_t *)&ioc);
2851cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK)
2861cfa752fSRamaswamy Tummala 		return (status);
2871cfa752fSRamaswamy Tummala 
2881cfa752fSRamaswamy Tummala 	/*
2891cfa752fSRamaswamy Tummala 	 * Now allocate the memory for the P_Key table based on the table size
2901cfa752fSRamaswamy Tummala 	 * return by the ioctl.
2911cfa752fSRamaswamy Tummala 	 */
2921cfa752fSRamaswamy Tummala 	ioc.ioc_pkeys = calloc(sizeof (ib_pkey_t), ioc.ioc_pkey_tbl_sz);
2931cfa752fSRamaswamy Tummala 	if (ioc.ioc_pkeys == NULL) {
2941cfa752fSRamaswamy Tummala 		status = dladm_errno2status(errno);
2951cfa752fSRamaswamy Tummala 		goto bail;
2961cfa752fSRamaswamy Tummala 	}
2971cfa752fSRamaswamy Tummala 
2981cfa752fSRamaswamy Tummala 	/*
2991cfa752fSRamaswamy Tummala 	 * Call the ioctl again to get the P_Key table and other IB Phys link
3001cfa752fSRamaswamy Tummala 	 * attributes.
3011cfa752fSRamaswamy Tummala 	 */
3021cfa752fSRamaswamy Tummala 	ioc.ibdioc.ioc_linkid = linkid;
3031cfa752fSRamaswamy Tummala 	ioc.ibdioc.ioc_port_inst = instance;
3041cfa752fSRamaswamy Tummala 	ioc.ibdioc.ioc_info_cmd = IBD_INFO_CMD_IBPORT;
3051cfa752fSRamaswamy Tummala 
3061cfa752fSRamaswamy Tummala 	status = i_dladm_ib_ioctl(handle, IBD_INFO_IBPART, (ibd_ioctl_t *)&ioc);
3071cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK)
3081cfa752fSRamaswamy Tummala 		goto bail;
3091cfa752fSRamaswamy Tummala 
3101cfa752fSRamaswamy Tummala 	attrp->dia_physlinkid = ioc.ibdioc.ioc_linkid;
3111cfa752fSRamaswamy Tummala 	attrp->dia_portnum = ioc.ibdioc.ioc_portnum;
3121cfa752fSRamaswamy Tummala 	attrp->dia_port_pkey_tbl_sz = ioc.ioc_pkey_tbl_sz;
3131cfa752fSRamaswamy Tummala 	attrp->dia_port_pkeys = ioc.ioc_pkeys;
3141cfa752fSRamaswamy Tummala 	attrp->dia_hca_guid = ioc.ibdioc.ioc_hcaguid;
3151cfa752fSRamaswamy Tummala 	attrp->dia_port_guid = ioc.ibdioc.ioc_portguid;
3161cfa752fSRamaswamy Tummala 	attrp->dia_instance = ioc.ibdioc.ioc_port_inst;
3171cfa752fSRamaswamy Tummala 	return (status);
3181cfa752fSRamaswamy Tummala bail:
3191cfa752fSRamaswamy Tummala 	free(ioc.ioc_pkeys);
3201cfa752fSRamaswamy Tummala 	return (status);
3211cfa752fSRamaswamy Tummala }
3221cfa752fSRamaswamy Tummala 
3231cfa752fSRamaswamy Tummala /*
3241cfa752fSRamaswamy Tummala  * Free the memory allocated for the IB HCA port's P_Key table by
3251cfa752fSRamaswamy Tummala  * dladm_ib_info library call.
3261cfa752fSRamaswamy Tummala  */
3271cfa752fSRamaswamy Tummala void
dladm_free_ib_info(dladm_ib_attr_t * attr)3281cfa752fSRamaswamy Tummala dladm_free_ib_info(dladm_ib_attr_t *attr)
3291cfa752fSRamaswamy Tummala {
3301cfa752fSRamaswamy Tummala 	if (attr && attr->dia_port_pkeys)
3311cfa752fSRamaswamy Tummala 		free(attr->dia_port_pkeys);
3321cfa752fSRamaswamy Tummala }
3331cfa752fSRamaswamy Tummala 
3341cfa752fSRamaswamy Tummala /*
3351cfa752fSRamaswamy Tummala  * Call into the IP over IB driver to create a partition object.
3361cfa752fSRamaswamy Tummala  */
3371cfa752fSRamaswamy Tummala static dladm_status_t
i_dladm_part_create(dladm_handle_t handle,dladm_part_attr_t * pattr)3381cfa752fSRamaswamy Tummala i_dladm_part_create(dladm_handle_t handle, dladm_part_attr_t *pattr)
3391cfa752fSRamaswamy Tummala {
3401cfa752fSRamaswamy Tummala 	ibpart_ioctl_t	ioc;
3411cfa752fSRamaswamy Tummala 
3421cfa752fSRamaswamy Tummala 	bzero(&ioc, sizeof (ioc));
3431cfa752fSRamaswamy Tummala 
3441cfa752fSRamaswamy Tummala 	/* IB Physical datalink ID */
3451cfa752fSRamaswamy Tummala 	ioc.ibdioc.ioc_linkid		= pattr->dia_physlinkid;
3461cfa752fSRamaswamy Tummala 	/* IB Partition datalink ID */
3471cfa752fSRamaswamy Tummala 	ioc.ioc_partid			= pattr->dia_partlinkid;
3481cfa752fSRamaswamy Tummala 	ioc.ioc_pkey			= pattr->dia_pkey;
3491cfa752fSRamaswamy Tummala 	ioc.ibdioc.ioc_port_inst	= pattr->dia_instance;
3501cfa752fSRamaswamy Tummala 	ioc.ioc_force_create		= ((pattr->dia_flags & DLADM_OPT_FORCE)
3511cfa752fSRamaswamy Tummala 	    != 0);
3521cfa752fSRamaswamy Tummala 
353c87dd6b7SRajkumar Sivaprakasam 	return (i_dladm_ib_ioctl(handle, IBD_CREATE_IBPART, &ioc.ibdioc));
3541cfa752fSRamaswamy Tummala }
3551cfa752fSRamaswamy Tummala 
3561cfa752fSRamaswamy Tummala /*
3571cfa752fSRamaswamy Tummala  * Create an entry in the dladm persistent configuration database for the
3581cfa752fSRamaswamy Tummala  * partition specified by pattr.
3591cfa752fSRamaswamy Tummala  */
3601cfa752fSRamaswamy Tummala dladm_status_t
dladm_part_persist_conf(dladm_handle_t handle,const char * pname,dladm_part_attr_t * pattr)361c87dd6b7SRajkumar Sivaprakasam dladm_part_persist_conf(dladm_handle_t handle, const char *pname,
362c87dd6b7SRajkumar Sivaprakasam     dladm_part_attr_t *pattr)
3631cfa752fSRamaswamy Tummala {
3641cfa752fSRamaswamy Tummala 
3651cfa752fSRamaswamy Tummala 	dladm_conf_t	conf;
3661cfa752fSRamaswamy Tummala 	dladm_status_t	status;
367f7952617SToomas Soome 	char		linkover[MAXLINKNAMELEN];
3681cfa752fSRamaswamy Tummala 	uint64_t	u64;
3691cfa752fSRamaswamy Tummala 
370c87dd6b7SRajkumar Sivaprakasam 	status = dladm_create_conf(handle, pname, pattr->dia_partlinkid,
371c87dd6b7SRajkumar Sivaprakasam 	    DATALINK_CLASS_PART, DL_IB, &conf);
3721cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK)
3731cfa752fSRamaswamy Tummala 		return (status);
3741cfa752fSRamaswamy Tummala 
3751cfa752fSRamaswamy Tummala 	/*
3761cfa752fSRamaswamy Tummala 	 * Get the name of the IB Phys link over which this partition was
3771cfa752fSRamaswamy Tummala 	 * created.
3781cfa752fSRamaswamy Tummala 	 */
3791cfa752fSRamaswamy Tummala 	status = dladm_datalink_id2info(handle, pattr->dia_physlinkid,
3801cfa752fSRamaswamy Tummala 	    NULL, NULL, NULL, linkover, sizeof (linkover));
3811cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK)
3821cfa752fSRamaswamy Tummala 		return (status);
3831cfa752fSRamaswamy Tummala 
3841cfa752fSRamaswamy Tummala 	/* Store IB Phys link name (linkover) */
3851cfa752fSRamaswamy Tummala 	status = dladm_set_conf_field(handle, conf, FLINKOVER, DLADM_TYPE_STR,
3861cfa752fSRamaswamy Tummala 	    linkover);
3871cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK)
3881cfa752fSRamaswamy Tummala 		return (status);
3891cfa752fSRamaswamy Tummala 
3901cfa752fSRamaswamy Tummala 	u64 = pattr->dia_pkey;
3911cfa752fSRamaswamy Tummala 
3921cfa752fSRamaswamy Tummala 	/* Store the IB Partitions P_Key */
3931cfa752fSRamaswamy Tummala 	status = dladm_set_conf_field(handle, conf, FPORTPKEY,
3941cfa752fSRamaswamy Tummala 	    DLADM_TYPE_UINT64, &u64);
3951cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK)
3961cfa752fSRamaswamy Tummala 		return (status);
3971cfa752fSRamaswamy Tummala 
3981cfa752fSRamaswamy Tummala 	if (pattr->dia_flags & DLADM_OPT_FORCE) {
3991cfa752fSRamaswamy Tummala 		boolean_t force = B_TRUE;
4001cfa752fSRamaswamy Tummala 		/* Store the force create flag. */
4011cfa752fSRamaswamy Tummala 		status = dladm_set_conf_field(handle, conf, FFORCE,
4021cfa752fSRamaswamy Tummala 		    DLADM_TYPE_BOOLEAN, &force);
4031cfa752fSRamaswamy Tummala 		if (status != DLADM_STATUS_OK)
4041cfa752fSRamaswamy Tummala 			goto done;
4051cfa752fSRamaswamy Tummala 	}
4061cfa752fSRamaswamy Tummala 
4071cfa752fSRamaswamy Tummala 	status = dladm_write_conf(handle, conf);
4081cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK)
4091cfa752fSRamaswamy Tummala 		return (status);
4101cfa752fSRamaswamy Tummala 
4111cfa752fSRamaswamy Tummala 	dladm_destroy_conf(handle, conf);
4121cfa752fSRamaswamy Tummala done:
4131cfa752fSRamaswamy Tummala 	return (status);
4141cfa752fSRamaswamy Tummala }
4151cfa752fSRamaswamy Tummala 
4161cfa752fSRamaswamy Tummala /*
4171cfa752fSRamaswamy Tummala  * Create a new IB Partition datalink of name 'pname' over the IB Physical link
4181cfa752fSRamaswamy Tummala  * given in 'physlinkid' with the P_key 'pkey' and return the datalink ID in
4191cfa752fSRamaswamy Tummala  * 'partlinkid'. If the 'force' option is set in the 'flags' argument, the
4201cfa752fSRamaswamy Tummala  * partition will be created even if the P_Key 'pkey' does not exist or if the
4211cfa752fSRamaswamy Tummala  * HCA port represented by the IB Phys link is down. If the 'temporary' flag is
4221cfa752fSRamaswamy Tummala  * set, then the configuration information is not added to the persistent
4231cfa752fSRamaswamy Tummala  * database.
4241cfa752fSRamaswamy Tummala  */
4251cfa752fSRamaswamy Tummala dladm_status_t
dladm_part_create(dladm_handle_t handle,datalink_id_t physlinkid,ib_pkey_t pkey,uint32_t flags,char * pname,datalink_id_t * partlinkid,dladm_arg_list_t * proplist)4261cfa752fSRamaswamy Tummala dladm_part_create(dladm_handle_t handle, datalink_id_t physlinkid,
4271cfa752fSRamaswamy Tummala     ib_pkey_t pkey, uint32_t flags, char *pname, datalink_id_t *partlinkid,
4281cfa752fSRamaswamy Tummala     dladm_arg_list_t *proplist)
4291cfa752fSRamaswamy Tummala {
430*4202e8bfSToomas Soome 	uint_t			i;
4311cfa752fSRamaswamy Tummala 	dladm_status_t		status;
4321cfa752fSRamaswamy Tummala 	uint_t			media;
4331cfa752fSRamaswamy Tummala 	boolean_t		part_created = B_FALSE;
4341cfa752fSRamaswamy Tummala 	boolean_t		conf_set = B_FALSE;
4351cfa752fSRamaswamy Tummala 	dladm_phys_attr_t	dpa;
4361cfa752fSRamaswamy Tummala 	dladm_part_attr_t	pattr;
4371cfa752fSRamaswamy Tummala 
4381cfa752fSRamaswamy Tummala 	pattr.dia_pkey = pkey;
4391cfa752fSRamaswamy Tummala 	pattr.dia_physlinkid = physlinkid; /* IB Phys link's datalink id */
4401cfa752fSRamaswamy Tummala 	pattr.dia_flags = flags;
4411cfa752fSRamaswamy Tummala 
4421cfa752fSRamaswamy Tummala 	flags &= ~DLADM_OPT_FORCE;
4431cfa752fSRamaswamy Tummala 
4441cfa752fSRamaswamy Tummala 	/*
4451cfa752fSRamaswamy Tummala 	 * Check whether the PKEY is valid. If not, return immediately
4461cfa752fSRamaswamy Tummala 	 * Only full members are allowed as per the IPoIB specification
4471cfa752fSRamaswamy Tummala 	 */
4481cfa752fSRamaswamy Tummala 	if (pattr.dia_pkey <= IB_PKEY_INVALID_FULL)
4491cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_INVALID_PKEY);
4501cfa752fSRamaswamy Tummala 
4511cfa752fSRamaswamy Tummala 	/*
4521cfa752fSRamaswamy Tummala 	 * Get the media type of the Phys link datalink ID provided and
4531cfa752fSRamaswamy Tummala 	 * make sure that it is Infiniband media DL_IB)
4541cfa752fSRamaswamy Tummala 	 */
4551cfa752fSRamaswamy Tummala 	if ((status = dladm_datalink_id2info(handle, pattr.dia_physlinkid, NULL,
4561cfa752fSRamaswamy Tummala 	    NULL, &media, NULL, 0)) != DLADM_STATUS_OK)
4571cfa752fSRamaswamy Tummala 		return (status);
4581cfa752fSRamaswamy Tummala 
4591cfa752fSRamaswamy Tummala 	if (media != DL_IB)
4601cfa752fSRamaswamy Tummala 		return (dladm_errno2status(ENOTSUP));
4611cfa752fSRamaswamy Tummala 
4621cfa752fSRamaswamy Tummala 	/*
4631cfa752fSRamaswamy Tummala 	 * Get the instance number of the IP over IB driver instance which the
4641cfa752fSRamaswamy Tummala 	 * IB Phys link 'physlinkid' over which we will be creating our IB
4651cfa752fSRamaswamy Tummala 	 * partition.
4661cfa752fSRamaswamy Tummala 	 */
4671cfa752fSRamaswamy Tummala 	if ((status = dladm_phys_info(handle, pattr.dia_physlinkid, &dpa,
4681cfa752fSRamaswamy Tummala 	    DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK)
4691cfa752fSRamaswamy Tummala 		return (status);
4701cfa752fSRamaswamy Tummala 
471c87dd6b7SRajkumar Sivaprakasam 	if (dladm_parselink(dpa.dp_dev, NULL, (uint_t *)&pattr.dia_instance) !=
472c87dd6b7SRajkumar Sivaprakasam 	    DLADM_STATUS_OK)
4731cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_FAILED);
4741cfa752fSRamaswamy Tummala 
4751cfa752fSRamaswamy Tummala 
476c87dd6b7SRajkumar Sivaprakasam 	if ((status = dladm_create_datalink_id(handle, pname,
4771cfa752fSRamaswamy Tummala 	    DATALINK_CLASS_PART, DL_IB, flags, &pattr.dia_partlinkid)) !=
4781cfa752fSRamaswamy Tummala 	    DLADM_STATUS_OK)
4791cfa752fSRamaswamy Tummala 		return (status);
4801cfa752fSRamaswamy Tummala 
4811cfa752fSRamaswamy Tummala 	/*
4821cfa752fSRamaswamy Tummala 	 * Create the IB partition object.
4831cfa752fSRamaswamy Tummala 	 */
4841cfa752fSRamaswamy Tummala 	status = i_dladm_part_create(handle, &pattr);
4851cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK)
4861cfa752fSRamaswamy Tummala 		goto done;
4871cfa752fSRamaswamy Tummala 
4881cfa752fSRamaswamy Tummala 	part_created = B_TRUE;
4891cfa752fSRamaswamy Tummala 
4901cfa752fSRamaswamy Tummala 	/*
4911cfa752fSRamaswamy Tummala 	 * If the persist flag is set then write this partition information
4921cfa752fSRamaswamy Tummala 	 * to the persistent configuration.
4931cfa752fSRamaswamy Tummala 	 */
4941cfa752fSRamaswamy Tummala 	if (pattr.dia_flags & DLADM_OPT_PERSIST) {
495c87dd6b7SRajkumar Sivaprakasam 		status = dladm_part_persist_conf(handle, pname, &pattr);
4961cfa752fSRamaswamy Tummala 		if (status != DLADM_STATUS_OK)
4971cfa752fSRamaswamy Tummala 			goto done;
4981cfa752fSRamaswamy Tummala 		conf_set = B_TRUE;
4991cfa752fSRamaswamy Tummala 	}
5001cfa752fSRamaswamy Tummala 
5011cfa752fSRamaswamy Tummala 	/*
5021cfa752fSRamaswamy Tummala 	 * If the name-value pair list of properties were provided set those
5031cfa752fSRamaswamy Tummala 	 * properties over the datalink.
5041cfa752fSRamaswamy Tummala 	 */
5051cfa752fSRamaswamy Tummala 	if (proplist != NULL) {
5061cfa752fSRamaswamy Tummala 		for (i = 0; i < proplist->al_count; i++) {
5071cfa752fSRamaswamy Tummala 			dladm_arg_info_t *aip = &proplist->al_info[i];
5081cfa752fSRamaswamy Tummala 
5091cfa752fSRamaswamy Tummala 			status = dladm_set_linkprop(handle,
5101cfa752fSRamaswamy Tummala 			    pattr.dia_partlinkid, aip->ai_name, aip->ai_val,
5111cfa752fSRamaswamy Tummala 			    aip->ai_count, pattr.dia_flags);
5121cfa752fSRamaswamy Tummala 			if (status != DLADM_STATUS_OK)
5131cfa752fSRamaswamy Tummala 				break;
5141cfa752fSRamaswamy Tummala 		}
5151cfa752fSRamaswamy Tummala 	}
5161cfa752fSRamaswamy Tummala done:
5171cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK) {
5181cfa752fSRamaswamy Tummala 		if (conf_set)
5191cfa752fSRamaswamy Tummala 			(void) dladm_remove_conf(handle, pattr.dia_partlinkid);
5201cfa752fSRamaswamy Tummala 		if (part_created)
5211cfa752fSRamaswamy Tummala 			(void) i_dladm_part_delete(handle,
5221cfa752fSRamaswamy Tummala 			    pattr.dia_partlinkid);
5231cfa752fSRamaswamy Tummala 		(void) dladm_destroy_datalink_id(handle, pattr.dia_partlinkid,
5241cfa752fSRamaswamy Tummala 		    flags);
5251cfa752fSRamaswamy Tummala 	}
5261cfa752fSRamaswamy Tummala 
5271cfa752fSRamaswamy Tummala 	if (partlinkid != NULL)
5281cfa752fSRamaswamy Tummala 		*partlinkid = pattr.dia_partlinkid;
5291cfa752fSRamaswamy Tummala 
5301cfa752fSRamaswamy Tummala 	return (status);
5311cfa752fSRamaswamy Tummala }
5321cfa752fSRamaswamy Tummala 
5331cfa752fSRamaswamy Tummala /*
5341cfa752fSRamaswamy Tummala  * Call into the IP over IB driver to delete the IB partition and free up all
5351cfa752fSRamaswamy Tummala  * the resources allocated for it.
5361cfa752fSRamaswamy Tummala  */
5371cfa752fSRamaswamy Tummala static dladm_status_t
i_dladm_part_delete(dladm_handle_t handle,datalink_id_t partid)5381cfa752fSRamaswamy Tummala i_dladm_part_delete(dladm_handle_t handle, datalink_id_t partid)
5391cfa752fSRamaswamy Tummala {
5401cfa752fSRamaswamy Tummala 	ibpart_ioctl_t ioc;
5411cfa752fSRamaswamy Tummala 
5421cfa752fSRamaswamy Tummala 	bzero(&ioc, sizeof (ioc));
5431cfa752fSRamaswamy Tummala 	ioc.ioc_partid = partid;
544c87dd6b7SRajkumar Sivaprakasam 	return (i_dladm_ib_ioctl(handle, IBD_DELETE_IBPART, &ioc.ibdioc));
5451cfa752fSRamaswamy Tummala }
5461cfa752fSRamaswamy Tummala 
5471cfa752fSRamaswamy Tummala /*
5481cfa752fSRamaswamy Tummala  * Delete an IB partition if 'flags' contains the active flag. Update the
5491cfa752fSRamaswamy Tummala  * persistent configuration if 'flags' contains the persist flag.
5501cfa752fSRamaswamy Tummala  */
5511cfa752fSRamaswamy Tummala dladm_status_t
dladm_part_delete(dladm_handle_t handle,datalink_id_t partid,int flags)5521cfa752fSRamaswamy Tummala dladm_part_delete(dladm_handle_t handle, datalink_id_t partid, int flags)
5531cfa752fSRamaswamy Tummala {
5541cfa752fSRamaswamy Tummala 	dladm_status_t	status = DLADM_STATUS_OK;
5551cfa752fSRamaswamy Tummala 	datalink_class_t class;
5561cfa752fSRamaswamy Tummala 
5571cfa752fSRamaswamy Tummala 	if (flags == 0)
5581cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_BADARG);
5591cfa752fSRamaswamy Tummala 
5601cfa752fSRamaswamy Tummala 	/*
5611cfa752fSRamaswamy Tummala 	 * Make sure that the datalinkid provided is an IB partition class
5621cfa752fSRamaswamy Tummala 	 * datalink ID.
5631cfa752fSRamaswamy Tummala 	 */
5641cfa752fSRamaswamy Tummala 	if ((dladm_datalink_id2info(handle, partid, NULL, &class, NULL, NULL, 0)
5651cfa752fSRamaswamy Tummala 	    != DLADM_STATUS_OK))
5661cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_BADARG);
5671cfa752fSRamaswamy Tummala 
5681cfa752fSRamaswamy Tummala 	if (class != DATALINK_CLASS_PART)
5691cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_BADARG);
5701cfa752fSRamaswamy Tummala 
5711cfa752fSRamaswamy Tummala 	if ((flags & DLADM_OPT_ACTIVE) != 0) {
5721cfa752fSRamaswamy Tummala 		status = i_dladm_part_delete(handle, partid);
5731cfa752fSRamaswamy Tummala 		if (status == DLADM_STATUS_OK) {
5741cfa752fSRamaswamy Tummala 			(void) dladm_set_linkprop(handle, partid, NULL, NULL, 0,
5751cfa752fSRamaswamy Tummala 			    DLADM_OPT_ACTIVE);
5761cfa752fSRamaswamy Tummala 			(void) dladm_destroy_datalink_id(handle, partid,
5771cfa752fSRamaswamy Tummala 			    DLADM_OPT_ACTIVE);
5781cfa752fSRamaswamy Tummala 		} else if (status != DLADM_STATUS_NOTFOUND ||
5791cfa752fSRamaswamy Tummala 		    !(flags & DLADM_OPT_PERSIST)) {
5801cfa752fSRamaswamy Tummala 			return (status);
5811cfa752fSRamaswamy Tummala 		}
5821cfa752fSRamaswamy Tummala 	}
5831cfa752fSRamaswamy Tummala 
5841cfa752fSRamaswamy Tummala 	if ((flags & DLADM_OPT_PERSIST) != 0) {
5851cfa752fSRamaswamy Tummala 		dladm_status_t db_status;
5861cfa752fSRamaswamy Tummala 		db_status = dladm_remove_conf(handle, partid);
5871cfa752fSRamaswamy Tummala 
5881cfa752fSRamaswamy Tummala 		/*
5891cfa752fSRamaswamy Tummala 		 * A partition could have been temporarily deleted in which
5901cfa752fSRamaswamy Tummala 		 * case the delete of the active partition above would have
5911cfa752fSRamaswamy Tummala 		 * failed. In that case, we update the status to be returned
5921cfa752fSRamaswamy Tummala 		 * to that of the status returned for deleting the persistent
5931cfa752fSRamaswamy Tummala 		 * database entry.
5941cfa752fSRamaswamy Tummala 		 */
5951cfa752fSRamaswamy Tummala 		if (status == DLADM_STATUS_NOTFOUND)
5961cfa752fSRamaswamy Tummala 			status = db_status;
5971cfa752fSRamaswamy Tummala 
5981cfa752fSRamaswamy Tummala 		(void) dladm_destroy_datalink_id(handle, partid,
5991cfa752fSRamaswamy Tummala 		    DLADM_OPT_PERSIST);
6001cfa752fSRamaswamy Tummala 	}
6011cfa752fSRamaswamy Tummala 
6021cfa752fSRamaswamy Tummala 	return (status);
6031cfa752fSRamaswamy Tummala }
6041cfa752fSRamaswamy Tummala 
6051cfa752fSRamaswamy Tummala /*
6061cfa752fSRamaswamy Tummala  * Call into the IP over IB driver to create the active instances of one or all
6071cfa752fSRamaswamy Tummala  * IB partitions present in the persistent configuration.
6081cfa752fSRamaswamy Tummala  */
6091cfa752fSRamaswamy Tummala static int
i_dladm_part_up(dladm_handle_t handle,datalink_id_t plinkid,void * arg __unused)61020535e13SToomas Soome i_dladm_part_up(dladm_handle_t handle, datalink_id_t plinkid,
61120535e13SToomas Soome     void *arg __unused)
6121cfa752fSRamaswamy Tummala {
6131cfa752fSRamaswamy Tummala 	dladm_conf_t	conf;
6141cfa752fSRamaswamy Tummala 	datalink_id_t	linkid;
6151cfa752fSRamaswamy Tummala 	ib_pkey_t	pkey;
6161cfa752fSRamaswamy Tummala 	uint64_t	u64;
6171cfa752fSRamaswamy Tummala 	char linkover[MAXLINKNAMELEN];
6181cfa752fSRamaswamy Tummala 	dladm_status_t	status;
6191cfa752fSRamaswamy Tummala 	dladm_phys_attr_t dpa;
6201cfa752fSRamaswamy Tummala 	dladm_part_attr_t pattr;
6211cfa752fSRamaswamy Tummala 
6221cfa752fSRamaswamy Tummala 	/*
6231cfa752fSRamaswamy Tummala 	 * plinkid is the IB partition datalink's ID. Get an handle to the
6241cfa752fSRamaswamy Tummala 	 * persistent configuration entry for this datalink ID. If this datalink
6251cfa752fSRamaswamy Tummala 	 * ID is not present in the persistent configuration return.
6261cfa752fSRamaswamy Tummala 	 */
62732715170SCathy Zhou 	if ((status = dladm_getsnap_conf(handle, plinkid, &conf)) !=
6281cfa752fSRamaswamy Tummala 	    DLADM_STATUS_OK)
6291cfa752fSRamaswamy Tummala 		return (status);
6301cfa752fSRamaswamy Tummala 
6311cfa752fSRamaswamy Tummala 	/*
6321cfa752fSRamaswamy Tummala 	 * Get the name of the IB Phys link over which this partition was
6331cfa752fSRamaswamy Tummala 	 * created.
6341cfa752fSRamaswamy Tummala 	 */
6351cfa752fSRamaswamy Tummala 	status = dladm_get_conf_field(handle, conf, FLINKOVER, linkover,
6361cfa752fSRamaswamy Tummala 	    sizeof (linkover));
6371cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK)
6381cfa752fSRamaswamy Tummala 		goto done;
6391cfa752fSRamaswamy Tummala 
6401cfa752fSRamaswamy Tummala 	if ((status = dladm_name2info(handle, linkover, &linkid, NULL, NULL,
6411cfa752fSRamaswamy Tummala 	    NULL)) != DLADM_STATUS_OK)
6421cfa752fSRamaswamy Tummala 		goto done;
6431cfa752fSRamaswamy Tummala 
6441cfa752fSRamaswamy Tummala 	/*
6451cfa752fSRamaswamy Tummala 	 * Get the phys attribute of the IB Phys link to get the device name
6461cfa752fSRamaswamy Tummala 	 * associated with the phys link. We need this to get the IP over IB
6471cfa752fSRamaswamy Tummala 	 * driver instance number.
6481cfa752fSRamaswamy Tummala 	 */
6491cfa752fSRamaswamy Tummala 	if (dladm_phys_info(handle, linkid, &dpa, DLADM_OPT_ACTIVE)
6501cfa752fSRamaswamy Tummala 	    != DLADM_STATUS_OK)
6511cfa752fSRamaswamy Tummala 		goto done;
6521cfa752fSRamaswamy Tummala 
6531cfa752fSRamaswamy Tummala 	/* Get the IB partition's P_key */
6541cfa752fSRamaswamy Tummala 	status = dladm_get_conf_field(handle, conf, FPORTPKEY, &u64,
6551cfa752fSRamaswamy Tummala 	    sizeof (u64));
6561cfa752fSRamaswamy Tummala 	if (status != DLADM_STATUS_OK)
6571cfa752fSRamaswamy Tummala 		goto done;
6581cfa752fSRamaswamy Tummala 
6591cfa752fSRamaswamy Tummala 	pkey = (ib_pkey_t)u64;
6601cfa752fSRamaswamy Tummala 
6611cfa752fSRamaswamy Tummala 	/*
6621cfa752fSRamaswamy Tummala 	 * We always set the force flag during dladm_part_up because we want
6631cfa752fSRamaswamy Tummala 	 * the partition creation to succeed even if the IB HCA port over which
6641cfa752fSRamaswamy Tummala 	 * the partition is being created is still down. Since dladm_part_up
6651cfa752fSRamaswamy Tummala 	 * is usually invoked during early boot sequence, it is possible under
6661cfa752fSRamaswamy Tummala 	 * some IB subnet configurations for dladm_up_part to be called before
6671cfa752fSRamaswamy Tummala 	 * the IB link negotiation is completed and port state is set to active
6681cfa752fSRamaswamy Tummala 	 * and P_Key table is updated.
6691cfa752fSRamaswamy Tummala 	 */
6701cfa752fSRamaswamy Tummala 	pattr.dia_flags = DLADM_OPT_FORCE | DLADM_OPT_ACTIVE |
6711cfa752fSRamaswamy Tummala 	    DLADM_OPT_PERSIST;
6721cfa752fSRamaswamy Tummala 	/* IB Phys link's datalink ID. */
6731cfa752fSRamaswamy Tummala 	pattr.dia_physlinkid = linkid;
6741cfa752fSRamaswamy Tummala 	/* IB Partition's datalink ID. */
6751cfa752fSRamaswamy Tummala 	pattr.dia_partlinkid = plinkid;
6761cfa752fSRamaswamy Tummala 	pattr.dia_pkey = pkey;
677c87dd6b7SRajkumar Sivaprakasam 	if (dladm_parselink(dpa.dp_dev, NULL, (uint_t *)&pattr.dia_instance) !=
678c87dd6b7SRajkumar Sivaprakasam 	    DLADM_STATUS_OK)
6791cfa752fSRamaswamy Tummala 		return (DLADM_WALK_CONTINUE);
6801cfa752fSRamaswamy Tummala 
6811cfa752fSRamaswamy Tummala 	/* Create the active IB Partition object. */
6821cfa752fSRamaswamy Tummala 	if (i_dladm_part_create(handle, &pattr) == DLADM_STATUS_OK &&
6831cfa752fSRamaswamy Tummala 	    dladm_up_datalink_id(handle, plinkid) != DLADM_STATUS_OK)
68432715170SCathy Zhou 		(void) i_dladm_part_delete(handle, linkid);
6851cfa752fSRamaswamy Tummala 
6861cfa752fSRamaswamy Tummala done:
6871cfa752fSRamaswamy Tummala 	dladm_destroy_conf(handle, conf);
6881cfa752fSRamaswamy Tummala 	return (DLADM_WALK_CONTINUE);
6891cfa752fSRamaswamy Tummala }
6901cfa752fSRamaswamy Tummala 
6911cfa752fSRamaswamy Tummala /*
6921cfa752fSRamaswamy Tummala  * Bring up one or all IB partition(s) present in the persistent configuration
6931cfa752fSRamaswamy Tummala  * database. If we need to bring up one IB Partition, its datalink ID is
6941cfa752fSRamaswamy Tummala  * provided in 'linkid'.
6951cfa752fSRamaswamy Tummala  */
6961cfa752fSRamaswamy Tummala dladm_status_t
dladm_part_up(dladm_handle_t handle,datalink_id_t linkid,uint32_t flags __unused)69720535e13SToomas Soome dladm_part_up(dladm_handle_t handle, datalink_id_t linkid,
69820535e13SToomas Soome     uint32_t flags __unused)
6991cfa752fSRamaswamy Tummala {
7001cfa752fSRamaswamy Tummala 	dladm_status_t status = DLADM_STATUS_OK;
7011cfa752fSRamaswamy Tummala 
7021cfa752fSRamaswamy Tummala 	if (linkid == DATALINK_ALL_LINKID) {
7031cfa752fSRamaswamy Tummala 		(void) dladm_walk_datalink_id(i_dladm_part_up, handle,
7041cfa752fSRamaswamy Tummala 		    &status, DATALINK_CLASS_PART, DATALINK_ANY_MEDIATYPE,
7051cfa752fSRamaswamy Tummala 		    DLADM_OPT_PERSIST);
7061cfa752fSRamaswamy Tummala 		return (DLADM_STATUS_OK);
7071cfa752fSRamaswamy Tummala 	} else {
7081cfa752fSRamaswamy Tummala 		(void) i_dladm_part_up(handle, linkid, &status);
7091cfa752fSRamaswamy Tummala 		return (status);
7101cfa752fSRamaswamy Tummala 	}
7111cfa752fSRamaswamy Tummala }
712