xref: /onnv-gate/usr/src/lib/libdladm/common/libdlib.c (revision 12824:66c93397e15b)
112163SRamaswamy.Tummala@Sun.COM /*
212163SRamaswamy.Tummala@Sun.COM  * CDDL HEADER START
312163SRamaswamy.Tummala@Sun.COM  *
412163SRamaswamy.Tummala@Sun.COM  * The contents of this file are subject to the terms of the
512163SRamaswamy.Tummala@Sun.COM  * Common Development and Distribution License (the "License").
612163SRamaswamy.Tummala@Sun.COM  * You may not use this file except in compliance with the License.
712163SRamaswamy.Tummala@Sun.COM  *
812163SRamaswamy.Tummala@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
912163SRamaswamy.Tummala@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1012163SRamaswamy.Tummala@Sun.COM  * See the License for the specific language governing permissions
1112163SRamaswamy.Tummala@Sun.COM  * and limitations under the License.
1212163SRamaswamy.Tummala@Sun.COM  *
1312163SRamaswamy.Tummala@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1412163SRamaswamy.Tummala@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1512163SRamaswamy.Tummala@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1612163SRamaswamy.Tummala@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1712163SRamaswamy.Tummala@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1812163SRamaswamy.Tummala@Sun.COM  *
1912163SRamaswamy.Tummala@Sun.COM  * CDDL HEADER END
2012163SRamaswamy.Tummala@Sun.COM  */
2112163SRamaswamy.Tummala@Sun.COM /*
2212163SRamaswamy.Tummala@Sun.COM  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2312163SRamaswamy.Tummala@Sun.COM  */
2412163SRamaswamy.Tummala@Sun.COM 
2512163SRamaswamy.Tummala@Sun.COM #include <stdio.h>
2612163SRamaswamy.Tummala@Sun.COM #include <libdevinfo.h>
2712163SRamaswamy.Tummala@Sun.COM #include <sys/types.h>
2812163SRamaswamy.Tummala@Sun.COM #include <sys/stat.h>
2912163SRamaswamy.Tummala@Sun.COM #include <string.h>
3012163SRamaswamy.Tummala@Sun.COM #include <fcntl.h>
3112163SRamaswamy.Tummala@Sun.COM #include <unistd.h>
3212163SRamaswamy.Tummala@Sun.COM #include <stropts.h>
3312163SRamaswamy.Tummala@Sun.COM #include <stdlib.h>
3412163SRamaswamy.Tummala@Sun.COM #include <errno.h>
3512163SRamaswamy.Tummala@Sun.COM #include <strings.h>
3612163SRamaswamy.Tummala@Sun.COM #include <libintl.h>
3712163SRamaswamy.Tummala@Sun.COM #include <net/if_types.h>
3812163SRamaswamy.Tummala@Sun.COM #include <net/if_dl.h>
3912163SRamaswamy.Tummala@Sun.COM #include <sys/dld.h>
4012163SRamaswamy.Tummala@Sun.COM #include <sys/ib/ib_types.h>
4112163SRamaswamy.Tummala@Sun.COM #include <sys/ibpart.h>
4212163SRamaswamy.Tummala@Sun.COM #include <libdllink.h>
4312163SRamaswamy.Tummala@Sun.COM #include <libdladm.h>
4412163SRamaswamy.Tummala@Sun.COM #include <libdlib.h>
4512163SRamaswamy.Tummala@Sun.COM #include <libdladm_impl.h>
4612163SRamaswamy.Tummala@Sun.COM 
4712163SRamaswamy.Tummala@Sun.COM /*
4812163SRamaswamy.Tummala@Sun.COM  * IP over IB administration API; see PSARC/2010/085
4912163SRamaswamy.Tummala@Sun.COM  */
5012163SRamaswamy.Tummala@Sun.COM 
5112163SRamaswamy.Tummala@Sun.COM /*
5212163SRamaswamy.Tummala@Sun.COM  * Function prototypes
5312163SRamaswamy.Tummala@Sun.COM  */
5412163SRamaswamy.Tummala@Sun.COM dladm_status_t dladm_part_create(dladm_handle_t, datalink_id_t, ib_pkey_t,
5512163SRamaswamy.Tummala@Sun.COM     uint32_t, char *, datalink_id_t *, dladm_arg_list_t *);
5612163SRamaswamy.Tummala@Sun.COM static dladm_status_t	i_dladm_part_create(dladm_handle_t,
5712163SRamaswamy.Tummala@Sun.COM     dladm_part_attr_t *);
5812303SRajkumar.Sivaprakasam@Sun.COM static dladm_status_t	dladm_part_persist_conf(dladm_handle_t, const char *,
5912303SRajkumar.Sivaprakasam@Sun.COM     dladm_part_attr_t *);
6012163SRamaswamy.Tummala@Sun.COM static dladm_status_t i_dladm_part_delete(dladm_handle_t, datalink_id_t);
6112163SRamaswamy.Tummala@Sun.COM dladm_status_t	dladm_part_delete(dladm_handle_t, datalink_id_t, int);
6212163SRamaswamy.Tummala@Sun.COM static int	i_dladm_part_up(dladm_handle_t, datalink_id_t, void *);
6312163SRamaswamy.Tummala@Sun.COM dladm_status_t	dladm_part_up(dladm_handle_t, datalink_id_t, uint32_t);
6412163SRamaswamy.Tummala@Sun.COM 
6512163SRamaswamy.Tummala@Sun.COM /*
6612163SRamaswamy.Tummala@Sun.COM  * Convert a error status returned by the IP over IB kernel driver to a
6712163SRamaswamy.Tummala@Sun.COM  * valid dladm status.
6812163SRamaswamy.Tummala@Sun.COM  */
6912163SRamaswamy.Tummala@Sun.COM static dladm_status_t
dladm_ib_ioctl_err2status(int err)7012163SRamaswamy.Tummala@Sun.COM dladm_ib_ioctl_err2status(int err)
7112163SRamaswamy.Tummala@Sun.COM {
7212163SRamaswamy.Tummala@Sun.COM 	switch (err) {
7312163SRamaswamy.Tummala@Sun.COM 	case 0:
7412163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_OK);
7512163SRamaswamy.Tummala@Sun.COM 	case IBD_INVALID_PORT_INST:
7612163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_INVALID_PORT_INSTANCE);
7712163SRamaswamy.Tummala@Sun.COM 	case IBD_PORT_IS_DOWN:
7812163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_PORT_IS_DOWN);
7912163SRamaswamy.Tummala@Sun.COM 	case IBD_PKEY_NOT_PRESENT:
8012163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_PKEY_NOT_PRESENT);
8112163SRamaswamy.Tummala@Sun.COM 	case IBD_PARTITION_EXISTS:
8212163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_PARTITION_EXISTS);
8312163SRamaswamy.Tummala@Sun.COM 	case IBD_INVALID_PKEY:
8412163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_INVALID_PKEY);
8512163SRamaswamy.Tummala@Sun.COM 	case IBD_NO_HW_RESOURCE:
8612163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_NO_IB_HW_RESOURCE);
8712163SRamaswamy.Tummala@Sun.COM 	case IBD_INVALID_PKEY_TBL_SIZE:
8812163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_INVALID_PKEY_TBL_SIZE);
8912163SRamaswamy.Tummala@Sun.COM 	default:
9012163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_FAILED);
9112163SRamaswamy.Tummala@Sun.COM 	}
9212163SRamaswamy.Tummala@Sun.COM }
9312163SRamaswamy.Tummala@Sun.COM 
9412163SRamaswamy.Tummala@Sun.COM static dladm_status_t
i_dladm_ib_ioctl(dladm_handle_t handle,int ioccmd,ibd_ioctl_t * iocp)9512163SRamaswamy.Tummala@Sun.COM i_dladm_ib_ioctl(dladm_handle_t handle, int ioccmd, ibd_ioctl_t *iocp)
9612163SRamaswamy.Tummala@Sun.COM {
9712163SRamaswamy.Tummala@Sun.COM 	if (ioctl(dladm_dld_fd(handle), ioccmd, iocp) == 0)
9812163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_OK);
9912163SRamaswamy.Tummala@Sun.COM 
10012163SRamaswamy.Tummala@Sun.COM 	if (iocp->ioc_status == 0)
10112163SRamaswamy.Tummala@Sun.COM 		return (dladm_errno2status(errno));
10212163SRamaswamy.Tummala@Sun.COM 
10312163SRamaswamy.Tummala@Sun.COM 	return (dladm_ib_ioctl_err2status(iocp->ioc_status));
10412163SRamaswamy.Tummala@Sun.COM }
10512163SRamaswamy.Tummala@Sun.COM 
10612163SRamaswamy.Tummala@Sun.COM /*
10712163SRamaswamy.Tummala@Sun.COM  * Get the active configuration information for the partition given by
10812163SRamaswamy.Tummala@Sun.COM  * the 'linkid'.
10912163SRamaswamy.Tummala@Sun.COM  */
11012163SRamaswamy.Tummala@Sun.COM static dladm_status_t
i_dladm_part_info_active(dladm_handle_t handle,datalink_id_t linkid,dladm_part_attr_t * attrp)11112163SRamaswamy.Tummala@Sun.COM i_dladm_part_info_active(dladm_handle_t handle, datalink_id_t linkid,
11212163SRamaswamy.Tummala@Sun.COM     dladm_part_attr_t *attrp)
11312163SRamaswamy.Tummala@Sun.COM {
11412163SRamaswamy.Tummala@Sun.COM 	ibpart_ioctl_t ioc;
11512163SRamaswamy.Tummala@Sun.COM 	dladm_status_t status = DLADM_STATUS_OK;
11612163SRamaswamy.Tummala@Sun.COM 
11712163SRamaswamy.Tummala@Sun.COM 	bzero(&ioc, sizeof (ioc));
11812163SRamaswamy.Tummala@Sun.COM 	bzero(attrp, sizeof (*attrp));
11912163SRamaswamy.Tummala@Sun.COM 	/*
12012163SRamaswamy.Tummala@Sun.COM 	 * The ioc_linkid here will contain the data link id of the IB partition
12112163SRamaswamy.Tummala@Sun.COM 	 * object.
12212163SRamaswamy.Tummala@Sun.COM 	 */
12312163SRamaswamy.Tummala@Sun.COM 	ioc.ibdioc.ioc_linkid = linkid;
12412163SRamaswamy.Tummala@Sun.COM 	ioc.ibdioc.ioc_info_cmd = IBD_INFO_CMD_IBPART;
12512163SRamaswamy.Tummala@Sun.COM 
12612163SRamaswamy.Tummala@Sun.COM 	status = i_dladm_ib_ioctl(handle, IBD_INFO_IBPART, (ibd_ioctl_t *)&ioc);
12712163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK)
12812163SRamaswamy.Tummala@Sun.COM 		goto bail;
12912163SRamaswamy.Tummala@Sun.COM 
13012163SRamaswamy.Tummala@Sun.COM 	/*
13112163SRamaswamy.Tummala@Sun.COM 	 * On return from the ioctl ioc_linkid field contains the IB port's
13212163SRamaswamy.Tummala@Sun.COM 	 * linkid.
13312163SRamaswamy.Tummala@Sun.COM 	 */
13412163SRamaswamy.Tummala@Sun.COM 	attrp->dia_physlinkid = ioc.ibdioc.ioc_linkid;
13512163SRamaswamy.Tummala@Sun.COM 	attrp->dia_partlinkid = ioc.ioc_partid;
13612163SRamaswamy.Tummala@Sun.COM 	attrp->dia_pkey = ioc.ioc_pkey;
13712163SRamaswamy.Tummala@Sun.COM 	attrp->dia_portnum = ioc.ibdioc.ioc_portnum;
13812163SRamaswamy.Tummala@Sun.COM 	attrp->dia_hca_guid = ioc.ibdioc.ioc_hcaguid;
13912163SRamaswamy.Tummala@Sun.COM 	attrp->dia_port_guid = ioc.ibdioc.ioc_portguid;
14012163SRamaswamy.Tummala@Sun.COM 	attrp->dia_instance = ioc.ibdioc.ioc_port_inst;
14112163SRamaswamy.Tummala@Sun.COM 
14212163SRamaswamy.Tummala@Sun.COM 	/*
14312163SRamaswamy.Tummala@Sun.COM 	 * If the IP over IB driver reports that this partition was created
14412163SRamaswamy.Tummala@Sun.COM 	 * forcibly, then set the force create flag.
14512163SRamaswamy.Tummala@Sun.COM 	 */
14612163SRamaswamy.Tummala@Sun.COM 	if (ioc.ioc_force_create)
14712303SRajkumar.Sivaprakasam@Sun.COM 		attrp->dia_flags |= DLADM_PART_FORCE_CREATE;
14812163SRamaswamy.Tummala@Sun.COM 
14912163SRamaswamy.Tummala@Sun.COM bail:
15012163SRamaswamy.Tummala@Sun.COM 	return (status);
15112163SRamaswamy.Tummala@Sun.COM }
15212163SRamaswamy.Tummala@Sun.COM 
15312163SRamaswamy.Tummala@Sun.COM /*
15412163SRamaswamy.Tummala@Sun.COM  * Get the configuration information about the IB partition 'linkid' from the
15512163SRamaswamy.Tummala@Sun.COM  * persistent configuration.
15612163SRamaswamy.Tummala@Sun.COM  */
15712163SRamaswamy.Tummala@Sun.COM static dladm_status_t
i_dladm_part_info_persist(dladm_handle_t handle,datalink_id_t linkid,dladm_part_attr_t * attrp)15812163SRamaswamy.Tummala@Sun.COM i_dladm_part_info_persist(dladm_handle_t handle, datalink_id_t linkid,
15912163SRamaswamy.Tummala@Sun.COM     dladm_part_attr_t *attrp)
16012163SRamaswamy.Tummala@Sun.COM {
16112163SRamaswamy.Tummala@Sun.COM 	dladm_conf_t conf;
16212163SRamaswamy.Tummala@Sun.COM 	dladm_status_t status;
16312163SRamaswamy.Tummala@Sun.COM 	char linkover[MAXLINKNAMELEN];
16412163SRamaswamy.Tummala@Sun.COM 	datalink_class_t class;
16512163SRamaswamy.Tummala@Sun.COM 	boolean_t force = B_FALSE;
16612163SRamaswamy.Tummala@Sun.COM 
16712163SRamaswamy.Tummala@Sun.COM 	/* Get the IB partition's datalink ID */
16812163SRamaswamy.Tummala@Sun.COM 	if ((status = dladm_datalink_id2info(handle, linkid, NULL, &class,
16912163SRamaswamy.Tummala@Sun.COM 	    NULL, NULL, 0)) != DLADM_STATUS_OK)
17012163SRamaswamy.Tummala@Sun.COM 		goto done;
17112163SRamaswamy.Tummala@Sun.COM 
17212163SRamaswamy.Tummala@Sun.COM 	bzero(attrp, sizeof (*attrp));
17312163SRamaswamy.Tummala@Sun.COM 	attrp->dia_partlinkid = linkid;
174*12824SCathy.Zhou@Sun.COM 	if ((status = dladm_getsnap_conf(handle, linkid, &conf)) !=
17512163SRamaswamy.Tummala@Sun.COM 	    DLADM_STATUS_OK)
17612163SRamaswamy.Tummala@Sun.COM 		return (status);
17712163SRamaswamy.Tummala@Sun.COM 
17812163SRamaswamy.Tummala@Sun.COM 	/*
17912163SRamaswamy.Tummala@Sun.COM 	 * Get the name of the IB Phys link over which IB partition was
18012163SRamaswamy.Tummala@Sun.COM 	 * created.
18112163SRamaswamy.Tummala@Sun.COM 	 */
18212163SRamaswamy.Tummala@Sun.COM 	status = dladm_get_conf_field(handle, conf, FLINKOVER, linkover,
18312163SRamaswamy.Tummala@Sun.COM 	    sizeof (linkover));
18412163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK) {
18512163SRamaswamy.Tummala@Sun.COM 		attrp->dia_physlinkid = DATALINK_INVALID_LINKID;
18612163SRamaswamy.Tummala@Sun.COM 		goto done;
18712163SRamaswamy.Tummala@Sun.COM 	} else {
18812163SRamaswamy.Tummala@Sun.COM 		/* Get the IB Phys link's datalink ID */
18912163SRamaswamy.Tummala@Sun.COM 		if ((status = dladm_name2info(handle, linkover,
19012163SRamaswamy.Tummala@Sun.COM 		    &attrp->dia_physlinkid, NULL, NULL, NULL)) !=
19112163SRamaswamy.Tummala@Sun.COM 		    DLADM_STATUS_OK)
19212163SRamaswamy.Tummala@Sun.COM 			goto done;
19312163SRamaswamy.Tummala@Sun.COM 	}
19412163SRamaswamy.Tummala@Sun.COM 
19512163SRamaswamy.Tummala@Sun.COM 	/* Get the IB partition's P_Key */
19612163SRamaswamy.Tummala@Sun.COM 	status = dladm_get_conf_field(handle, conf, FPORTPKEY,
19712163SRamaswamy.Tummala@Sun.COM 	    &attrp->dia_pkey, sizeof (uint64_t));
19812163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK)
19912163SRamaswamy.Tummala@Sun.COM 		goto done;
20012163SRamaswamy.Tummala@Sun.COM 
20112163SRamaswamy.Tummala@Sun.COM 	if (class != DATALINK_CLASS_PART) {
20212163SRamaswamy.Tummala@Sun.COM 		status = DLADM_STATUS_BADARG;
20312163SRamaswamy.Tummala@Sun.COM 		goto done;
20412163SRamaswamy.Tummala@Sun.COM 	}
20512163SRamaswamy.Tummala@Sun.COM 
20612163SRamaswamy.Tummala@Sun.COM 	/*
20712163SRamaswamy.Tummala@Sun.COM 	 * If the FFORCE field is set in the persistent configuration database
20812163SRamaswamy.Tummala@Sun.COM 	 * set the force create flag in the partition attributes.
20912163SRamaswamy.Tummala@Sun.COM 	 */
21012163SRamaswamy.Tummala@Sun.COM 	status = dladm_get_conf_field(handle, conf, FFORCE, &force,
21112163SRamaswamy.Tummala@Sun.COM 	    sizeof (boolean_t));
21212163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK) {
21312163SRamaswamy.Tummala@Sun.COM 		if (status != DLADM_STATUS_NOTFOUND)
21412163SRamaswamy.Tummala@Sun.COM 			goto done;
21512163SRamaswamy.Tummala@Sun.COM 	} else if (force == B_TRUE) {
21612303SRajkumar.Sivaprakasam@Sun.COM 		attrp->dia_flags |= DLADM_PART_FORCE_CREATE;
21712163SRamaswamy.Tummala@Sun.COM 	}
21812163SRamaswamy.Tummala@Sun.COM 
21912163SRamaswamy.Tummala@Sun.COM 	status = DLADM_STATUS_OK;
22012163SRamaswamy.Tummala@Sun.COM done:
22112163SRamaswamy.Tummala@Sun.COM 	dladm_destroy_conf(handle, conf);
22212163SRamaswamy.Tummala@Sun.COM 	return (status);
22312163SRamaswamy.Tummala@Sun.COM }
22412163SRamaswamy.Tummala@Sun.COM 
22512163SRamaswamy.Tummala@Sun.COM /*
22612163SRamaswamy.Tummala@Sun.COM  * Get the configuration information for the IB partition given by the datalink
22712163SRamaswamy.Tummala@Sun.COM  * ID 'linkid'. Based on the 'flags' field the information is either from the
22812163SRamaswamy.Tummala@Sun.COM  * active system (DLADM_OPT_ACTIVE) or from the persistent configuration
22912163SRamaswamy.Tummala@Sun.COM  * database.
23012163SRamaswamy.Tummala@Sun.COM  */
23112163SRamaswamy.Tummala@Sun.COM dladm_status_t
dladm_part_info(dladm_handle_t handle,datalink_id_t linkid,dladm_part_attr_t * attrp,uint32_t flags)23212163SRamaswamy.Tummala@Sun.COM dladm_part_info(dladm_handle_t handle, datalink_id_t linkid,
23312163SRamaswamy.Tummala@Sun.COM     dladm_part_attr_t *attrp, uint32_t flags)
23412163SRamaswamy.Tummala@Sun.COM {
23512163SRamaswamy.Tummala@Sun.COM 	if (flags == DLADM_OPT_ACTIVE)
23612163SRamaswamy.Tummala@Sun.COM 		return (i_dladm_part_info_active(handle, linkid, attrp));
23712163SRamaswamy.Tummala@Sun.COM 	else if (flags == DLADM_OPT_PERSIST)
23812163SRamaswamy.Tummala@Sun.COM 		return (i_dladm_part_info_persist(handle, linkid, attrp));
23912163SRamaswamy.Tummala@Sun.COM 	else
24012163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_BADARG);
24112163SRamaswamy.Tummala@Sun.COM }
24212163SRamaswamy.Tummala@Sun.COM 
24312163SRamaswamy.Tummala@Sun.COM /*
24412163SRamaswamy.Tummala@Sun.COM  * Get the configuration information for the IB Phys link given by the datalink
24512163SRamaswamy.Tummala@Sun.COM  * ID 'linkid'.
24612163SRamaswamy.Tummala@Sun.COM  */
24712163SRamaswamy.Tummala@Sun.COM /* ARGSUSED */
24812163SRamaswamy.Tummala@Sun.COM dladm_status_t
dladm_ib_info(dladm_handle_t handle,datalink_id_t linkid,dladm_ib_attr_t * attrp,uint32_t flags)24912163SRamaswamy.Tummala@Sun.COM dladm_ib_info(dladm_handle_t handle, datalink_id_t linkid,
25012163SRamaswamy.Tummala@Sun.COM     dladm_ib_attr_t *attrp, uint32_t flags)
25112163SRamaswamy.Tummala@Sun.COM {
25212303SRajkumar.Sivaprakasam@Sun.COM 	uint_t instance;
25312163SRamaswamy.Tummala@Sun.COM 	ibport_ioctl_t ioc;
25412163SRamaswamy.Tummala@Sun.COM 	dladm_phys_attr_t	dpa;
25512163SRamaswamy.Tummala@Sun.COM 	dladm_status_t status = DLADM_STATUS_OK;
25612163SRamaswamy.Tummala@Sun.COM 
25712163SRamaswamy.Tummala@Sun.COM 	/*
25812163SRamaswamy.Tummala@Sun.COM 	 * We need to get the device name of the IB Phys link to get the
25912163SRamaswamy.Tummala@Sun.COM 	 * correct instance number of the IP over IB driver instance.
26012163SRamaswamy.Tummala@Sun.COM 	 */
26112163SRamaswamy.Tummala@Sun.COM 	if (dladm_phys_info(handle, linkid, &dpa, DLADM_OPT_ACTIVE)
26212163SRamaswamy.Tummala@Sun.COM 	    != DLADM_STATUS_OK)
26312163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_BADARG);
26412163SRamaswamy.Tummala@Sun.COM 
26512163SRamaswamy.Tummala@Sun.COM 	/*
26612163SRamaswamy.Tummala@Sun.COM 	 * Get the instance number of the IP over IB driver instance which
26712163SRamaswamy.Tummala@Sun.COM 	 * represents this IB Phys link.
26812163SRamaswamy.Tummala@Sun.COM 	 */
26912303SRajkumar.Sivaprakasam@Sun.COM 	if (dladm_parselink(dpa.dp_dev, NULL, &instance) != DLADM_STATUS_OK)
27012163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_FAILED);
27112163SRamaswamy.Tummala@Sun.COM 
27212163SRamaswamy.Tummala@Sun.COM 	bzero(&ioc, sizeof (ioc));
27312163SRamaswamy.Tummala@Sun.COM 	/*
27412163SRamaswamy.Tummala@Sun.COM 	 * The ioc_linkid here will contain IB port linkid here. We make the
27512163SRamaswamy.Tummala@Sun.COM 	 * first ioctl call to get the P_Key table size for this HCA port.
27612163SRamaswamy.Tummala@Sun.COM 	 */
27712163SRamaswamy.Tummala@Sun.COM 	ioc.ibdioc.ioc_linkid = linkid;
27812163SRamaswamy.Tummala@Sun.COM 	ioc.ibdioc.ioc_info_cmd = IBD_INFO_CMD_PKEYTBLSZ;
27912163SRamaswamy.Tummala@Sun.COM 	ioc.ioc_pkey_tbl_sz = 0;
28012163SRamaswamy.Tummala@Sun.COM 	ioc.ibdioc.ioc_port_inst = instance;
28112163SRamaswamy.Tummala@Sun.COM 
28212163SRamaswamy.Tummala@Sun.COM 	status = i_dladm_ib_ioctl(handle, IBD_INFO_IBPART, (ibd_ioctl_t *)&ioc);
28312163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK)
28412163SRamaswamy.Tummala@Sun.COM 		return (status);
28512163SRamaswamy.Tummala@Sun.COM 
28612163SRamaswamy.Tummala@Sun.COM 	/*
28712163SRamaswamy.Tummala@Sun.COM 	 * Now allocate the memory for the P_Key table based on the table size
28812163SRamaswamy.Tummala@Sun.COM 	 * return by the ioctl.
28912163SRamaswamy.Tummala@Sun.COM 	 */
29012163SRamaswamy.Tummala@Sun.COM 	ioc.ioc_pkeys = calloc(sizeof (ib_pkey_t), ioc.ioc_pkey_tbl_sz);
29112163SRamaswamy.Tummala@Sun.COM 	if (ioc.ioc_pkeys == NULL) {
29212163SRamaswamy.Tummala@Sun.COM 		status = dladm_errno2status(errno);
29312163SRamaswamy.Tummala@Sun.COM 		goto bail;
29412163SRamaswamy.Tummala@Sun.COM 	}
29512163SRamaswamy.Tummala@Sun.COM 
29612163SRamaswamy.Tummala@Sun.COM 	/*
29712163SRamaswamy.Tummala@Sun.COM 	 * Call the ioctl again to get the P_Key table and other IB Phys link
29812163SRamaswamy.Tummala@Sun.COM 	 * attributes.
29912163SRamaswamy.Tummala@Sun.COM 	 */
30012163SRamaswamy.Tummala@Sun.COM 	ioc.ibdioc.ioc_linkid = linkid;
30112163SRamaswamy.Tummala@Sun.COM 	ioc.ibdioc.ioc_port_inst = instance;
30212163SRamaswamy.Tummala@Sun.COM 	ioc.ibdioc.ioc_info_cmd = IBD_INFO_CMD_IBPORT;
30312163SRamaswamy.Tummala@Sun.COM 
30412163SRamaswamy.Tummala@Sun.COM 	status = i_dladm_ib_ioctl(handle, IBD_INFO_IBPART, (ibd_ioctl_t *)&ioc);
30512163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK)
30612163SRamaswamy.Tummala@Sun.COM 		goto bail;
30712163SRamaswamy.Tummala@Sun.COM 
30812163SRamaswamy.Tummala@Sun.COM 	attrp->dia_physlinkid = ioc.ibdioc.ioc_linkid;
30912163SRamaswamy.Tummala@Sun.COM 	attrp->dia_portnum = ioc.ibdioc.ioc_portnum;
31012163SRamaswamy.Tummala@Sun.COM 	attrp->dia_port_pkey_tbl_sz = ioc.ioc_pkey_tbl_sz;
31112163SRamaswamy.Tummala@Sun.COM 	attrp->dia_port_pkeys = ioc.ioc_pkeys;
31212163SRamaswamy.Tummala@Sun.COM 	attrp->dia_hca_guid = ioc.ibdioc.ioc_hcaguid;
31312163SRamaswamy.Tummala@Sun.COM 	attrp->dia_port_guid = ioc.ibdioc.ioc_portguid;
31412163SRamaswamy.Tummala@Sun.COM 	attrp->dia_instance = ioc.ibdioc.ioc_port_inst;
31512163SRamaswamy.Tummala@Sun.COM 	return (status);
31612163SRamaswamy.Tummala@Sun.COM bail:
31712163SRamaswamy.Tummala@Sun.COM 	free(ioc.ioc_pkeys);
31812163SRamaswamy.Tummala@Sun.COM 	return (status);
31912163SRamaswamy.Tummala@Sun.COM }
32012163SRamaswamy.Tummala@Sun.COM 
32112163SRamaswamy.Tummala@Sun.COM /*
32212163SRamaswamy.Tummala@Sun.COM  * Free the memory allocated for the IB HCA port's P_Key table by
32312163SRamaswamy.Tummala@Sun.COM  * dladm_ib_info library call.
32412163SRamaswamy.Tummala@Sun.COM  */
32512163SRamaswamy.Tummala@Sun.COM void
dladm_free_ib_info(dladm_ib_attr_t * attr)32612163SRamaswamy.Tummala@Sun.COM dladm_free_ib_info(dladm_ib_attr_t *attr)
32712163SRamaswamy.Tummala@Sun.COM {
32812163SRamaswamy.Tummala@Sun.COM 	if (attr && attr->dia_port_pkeys)
32912163SRamaswamy.Tummala@Sun.COM 		free(attr->dia_port_pkeys);
33012163SRamaswamy.Tummala@Sun.COM }
33112163SRamaswamy.Tummala@Sun.COM 
33212163SRamaswamy.Tummala@Sun.COM /*
33312163SRamaswamy.Tummala@Sun.COM  * Call into the IP over IB driver to create a partition object.
33412163SRamaswamy.Tummala@Sun.COM  */
33512163SRamaswamy.Tummala@Sun.COM static dladm_status_t
i_dladm_part_create(dladm_handle_t handle,dladm_part_attr_t * pattr)33612163SRamaswamy.Tummala@Sun.COM i_dladm_part_create(dladm_handle_t handle, dladm_part_attr_t *pattr)
33712163SRamaswamy.Tummala@Sun.COM {
33812163SRamaswamy.Tummala@Sun.COM 	ibpart_ioctl_t	ioc;
33912163SRamaswamy.Tummala@Sun.COM 
34012163SRamaswamy.Tummala@Sun.COM 	bzero(&ioc, sizeof (ioc));
34112163SRamaswamy.Tummala@Sun.COM 
34212163SRamaswamy.Tummala@Sun.COM 	/* IB Physical datalink ID */
34312163SRamaswamy.Tummala@Sun.COM 	ioc.ibdioc.ioc_linkid		= pattr->dia_physlinkid;
34412163SRamaswamy.Tummala@Sun.COM 	/* IB Partition datalink ID */
34512163SRamaswamy.Tummala@Sun.COM 	ioc.ioc_partid			= pattr->dia_partlinkid;
34612163SRamaswamy.Tummala@Sun.COM 	ioc.ioc_pkey			= pattr->dia_pkey;
34712163SRamaswamy.Tummala@Sun.COM 	ioc.ibdioc.ioc_port_inst	= pattr->dia_instance;
34812163SRamaswamy.Tummala@Sun.COM 	ioc.ioc_force_create		= ((pattr->dia_flags & DLADM_OPT_FORCE)
34912163SRamaswamy.Tummala@Sun.COM 	    != 0);
35012163SRamaswamy.Tummala@Sun.COM 
35112303SRajkumar.Sivaprakasam@Sun.COM 	return (i_dladm_ib_ioctl(handle, IBD_CREATE_IBPART, &ioc.ibdioc));
35212163SRamaswamy.Tummala@Sun.COM }
35312163SRamaswamy.Tummala@Sun.COM 
35412163SRamaswamy.Tummala@Sun.COM /*
35512163SRamaswamy.Tummala@Sun.COM  * Create an entry in the dladm persistent configuration database for the
35612163SRamaswamy.Tummala@Sun.COM  * partition specified by pattr.
35712163SRamaswamy.Tummala@Sun.COM  */
35812163SRamaswamy.Tummala@Sun.COM dladm_status_t
dladm_part_persist_conf(dladm_handle_t handle,const char * pname,dladm_part_attr_t * pattr)35912303SRajkumar.Sivaprakasam@Sun.COM dladm_part_persist_conf(dladm_handle_t handle, const char *pname,
36012303SRajkumar.Sivaprakasam@Sun.COM     dladm_part_attr_t *pattr)
36112163SRamaswamy.Tummala@Sun.COM {
36212163SRamaswamy.Tummala@Sun.COM 
36312163SRamaswamy.Tummala@Sun.COM 	dladm_conf_t	conf;
36412163SRamaswamy.Tummala@Sun.COM 	dladm_status_t	status;
36512163SRamaswamy.Tummala@Sun.COM 	char 		linkover[MAXLINKNAMELEN];
36612163SRamaswamy.Tummala@Sun.COM 	uint64_t	u64;
36712163SRamaswamy.Tummala@Sun.COM 
36812303SRajkumar.Sivaprakasam@Sun.COM 	status = dladm_create_conf(handle, pname, pattr->dia_partlinkid,
36912303SRajkumar.Sivaprakasam@Sun.COM 	    DATALINK_CLASS_PART, DL_IB, &conf);
37012163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK)
37112163SRamaswamy.Tummala@Sun.COM 		return (status);
37212163SRamaswamy.Tummala@Sun.COM 
37312163SRamaswamy.Tummala@Sun.COM 	/*
37412163SRamaswamy.Tummala@Sun.COM 	 * Get the name of the IB Phys link over which this partition was
37512163SRamaswamy.Tummala@Sun.COM 	 * created.
37612163SRamaswamy.Tummala@Sun.COM 	 */
37712163SRamaswamy.Tummala@Sun.COM 	status = dladm_datalink_id2info(handle, pattr->dia_physlinkid,
37812163SRamaswamy.Tummala@Sun.COM 	    NULL, NULL, NULL, linkover, sizeof (linkover));
37912163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK)
38012163SRamaswamy.Tummala@Sun.COM 		return (status);
38112163SRamaswamy.Tummala@Sun.COM 
38212163SRamaswamy.Tummala@Sun.COM 	/* Store IB Phys link name (linkover) */
38312163SRamaswamy.Tummala@Sun.COM 	status = dladm_set_conf_field(handle, conf, FLINKOVER, DLADM_TYPE_STR,
38412163SRamaswamy.Tummala@Sun.COM 	    linkover);
38512163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK)
38612163SRamaswamy.Tummala@Sun.COM 		return (status);
38712163SRamaswamy.Tummala@Sun.COM 
38812163SRamaswamy.Tummala@Sun.COM 	u64 = pattr->dia_pkey;
38912163SRamaswamy.Tummala@Sun.COM 
39012163SRamaswamy.Tummala@Sun.COM 	/* Store the IB Partitions P_Key */
39112163SRamaswamy.Tummala@Sun.COM 	status = dladm_set_conf_field(handle, conf, FPORTPKEY,
39212163SRamaswamy.Tummala@Sun.COM 	    DLADM_TYPE_UINT64, &u64);
39312163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK)
39412163SRamaswamy.Tummala@Sun.COM 		return (status);
39512163SRamaswamy.Tummala@Sun.COM 
39612163SRamaswamy.Tummala@Sun.COM 	if (pattr->dia_flags & DLADM_OPT_FORCE) {
39712163SRamaswamy.Tummala@Sun.COM 		boolean_t force = B_TRUE;
39812163SRamaswamy.Tummala@Sun.COM 		/* Store the force create flag. */
39912163SRamaswamy.Tummala@Sun.COM 		status = dladm_set_conf_field(handle, conf, FFORCE,
40012163SRamaswamy.Tummala@Sun.COM 		    DLADM_TYPE_BOOLEAN, &force);
40112163SRamaswamy.Tummala@Sun.COM 		if (status != DLADM_STATUS_OK)
40212163SRamaswamy.Tummala@Sun.COM 			goto done;
40312163SRamaswamy.Tummala@Sun.COM 	}
40412163SRamaswamy.Tummala@Sun.COM 
40512163SRamaswamy.Tummala@Sun.COM 	status = dladm_write_conf(handle, conf);
40612163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK)
40712163SRamaswamy.Tummala@Sun.COM 		return (status);
40812163SRamaswamy.Tummala@Sun.COM 
40912163SRamaswamy.Tummala@Sun.COM 	dladm_destroy_conf(handle, conf);
41012163SRamaswamy.Tummala@Sun.COM done:
41112163SRamaswamy.Tummala@Sun.COM 	return (status);
41212163SRamaswamy.Tummala@Sun.COM }
41312163SRamaswamy.Tummala@Sun.COM 
41412163SRamaswamy.Tummala@Sun.COM /*
41512163SRamaswamy.Tummala@Sun.COM  * Create a new IB Partition datalink of name 'pname' over the IB Physical link
41612163SRamaswamy.Tummala@Sun.COM  * given in 'physlinkid' with the P_key 'pkey' and return the datalink ID in
41712163SRamaswamy.Tummala@Sun.COM  * 'partlinkid'. If the 'force' option is set in the 'flags' argument, the
41812163SRamaswamy.Tummala@Sun.COM  * partition will be created even if the P_Key 'pkey' does not exist or if the
41912163SRamaswamy.Tummala@Sun.COM  * HCA port represented by the IB Phys link is down. If the 'temporary' flag is
42012163SRamaswamy.Tummala@Sun.COM  * set, then the configuration information is not added to the persistent
42112163SRamaswamy.Tummala@Sun.COM  * database.
42212163SRamaswamy.Tummala@Sun.COM  */
42312163SRamaswamy.Tummala@Sun.COM 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)42412163SRamaswamy.Tummala@Sun.COM dladm_part_create(dladm_handle_t handle, datalink_id_t physlinkid,
42512163SRamaswamy.Tummala@Sun.COM     ib_pkey_t pkey, uint32_t flags, char *pname, datalink_id_t *partlinkid,
42612163SRamaswamy.Tummala@Sun.COM     dladm_arg_list_t *proplist)
42712163SRamaswamy.Tummala@Sun.COM {
42812163SRamaswamy.Tummala@Sun.COM 	int			i;
42912163SRamaswamy.Tummala@Sun.COM 	dladm_status_t		status;
43012163SRamaswamy.Tummala@Sun.COM 	uint_t			media;
43112163SRamaswamy.Tummala@Sun.COM 	boolean_t		part_created = B_FALSE;
43212163SRamaswamy.Tummala@Sun.COM 	boolean_t		conf_set = B_FALSE;
43312163SRamaswamy.Tummala@Sun.COM 	dladm_phys_attr_t	dpa;
43412163SRamaswamy.Tummala@Sun.COM 	dladm_part_attr_t	pattr;
43512163SRamaswamy.Tummala@Sun.COM 
43612163SRamaswamy.Tummala@Sun.COM 	pattr.dia_pkey = pkey;
43712163SRamaswamy.Tummala@Sun.COM 	pattr.dia_physlinkid = physlinkid; /* IB Phys link's datalink id */
43812163SRamaswamy.Tummala@Sun.COM 	pattr.dia_flags = flags;
43912163SRamaswamy.Tummala@Sun.COM 
44012163SRamaswamy.Tummala@Sun.COM 	flags &= ~DLADM_OPT_FORCE;
44112163SRamaswamy.Tummala@Sun.COM 
44212163SRamaswamy.Tummala@Sun.COM 	/*
44312163SRamaswamy.Tummala@Sun.COM 	 * Check whether the PKEY is valid. If not, return immediately
44412163SRamaswamy.Tummala@Sun.COM 	 * Only full members are allowed as per the IPoIB specification
44512163SRamaswamy.Tummala@Sun.COM 	 */
44612163SRamaswamy.Tummala@Sun.COM 	if (pattr.dia_pkey <= IB_PKEY_INVALID_FULL)
44712163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_INVALID_PKEY);
44812163SRamaswamy.Tummala@Sun.COM 
44912163SRamaswamy.Tummala@Sun.COM 	/*
45012163SRamaswamy.Tummala@Sun.COM 	 * Get the media type of the Phys link datalink ID provided and
45112163SRamaswamy.Tummala@Sun.COM 	 * make sure that it is Infiniband media DL_IB)
45212163SRamaswamy.Tummala@Sun.COM 	 */
45312163SRamaswamy.Tummala@Sun.COM 	if ((status = dladm_datalink_id2info(handle, pattr.dia_physlinkid, NULL,
45412163SRamaswamy.Tummala@Sun.COM 	    NULL, &media, NULL, 0)) != DLADM_STATUS_OK)
45512163SRamaswamy.Tummala@Sun.COM 		return (status);
45612163SRamaswamy.Tummala@Sun.COM 
45712163SRamaswamy.Tummala@Sun.COM 	if (media != DL_IB)
45812163SRamaswamy.Tummala@Sun.COM 		return (dladm_errno2status(ENOTSUP));
45912163SRamaswamy.Tummala@Sun.COM 
46012163SRamaswamy.Tummala@Sun.COM 	/*
46112163SRamaswamy.Tummala@Sun.COM 	 * Get the instance number of the IP over IB driver instance which the
46212163SRamaswamy.Tummala@Sun.COM 	 * IB Phys link 'physlinkid' over which we will be creating our IB
46312163SRamaswamy.Tummala@Sun.COM 	 * partition.
46412163SRamaswamy.Tummala@Sun.COM 	 */
46512163SRamaswamy.Tummala@Sun.COM 	if ((status = dladm_phys_info(handle, pattr.dia_physlinkid, &dpa,
46612163SRamaswamy.Tummala@Sun.COM 	    DLADM_OPT_ACTIVE)) != DLADM_STATUS_OK)
46712163SRamaswamy.Tummala@Sun.COM 		return (status);
46812163SRamaswamy.Tummala@Sun.COM 
46912303SRajkumar.Sivaprakasam@Sun.COM 	if (dladm_parselink(dpa.dp_dev, NULL, (uint_t *)&pattr.dia_instance) !=
47012303SRajkumar.Sivaprakasam@Sun.COM 	    DLADM_STATUS_OK)
47112163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_FAILED);
47212163SRamaswamy.Tummala@Sun.COM 
47312163SRamaswamy.Tummala@Sun.COM 
47412303SRajkumar.Sivaprakasam@Sun.COM 	if ((status = dladm_create_datalink_id(handle, pname,
47512163SRamaswamy.Tummala@Sun.COM 	    DATALINK_CLASS_PART, DL_IB, flags, &pattr.dia_partlinkid)) !=
47612163SRamaswamy.Tummala@Sun.COM 	    DLADM_STATUS_OK)
47712163SRamaswamy.Tummala@Sun.COM 		return (status);
47812163SRamaswamy.Tummala@Sun.COM 
47912163SRamaswamy.Tummala@Sun.COM 	/*
48012163SRamaswamy.Tummala@Sun.COM 	 * Create the IB partition object.
48112163SRamaswamy.Tummala@Sun.COM 	 */
48212163SRamaswamy.Tummala@Sun.COM 	status = i_dladm_part_create(handle, &pattr);
48312163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK)
48412163SRamaswamy.Tummala@Sun.COM 		goto done;
48512163SRamaswamy.Tummala@Sun.COM 
48612163SRamaswamy.Tummala@Sun.COM 	part_created = B_TRUE;
48712163SRamaswamy.Tummala@Sun.COM 
48812163SRamaswamy.Tummala@Sun.COM 	/*
48912163SRamaswamy.Tummala@Sun.COM 	 * If the persist flag is set then write this partition information
49012163SRamaswamy.Tummala@Sun.COM 	 * to the persistent configuration.
49112163SRamaswamy.Tummala@Sun.COM 	 */
49212163SRamaswamy.Tummala@Sun.COM 	if (pattr.dia_flags & DLADM_OPT_PERSIST) {
49312303SRajkumar.Sivaprakasam@Sun.COM 		status = dladm_part_persist_conf(handle, pname, &pattr);
49412163SRamaswamy.Tummala@Sun.COM 		if (status != DLADM_STATUS_OK)
49512163SRamaswamy.Tummala@Sun.COM 			goto done;
49612163SRamaswamy.Tummala@Sun.COM 		conf_set = B_TRUE;
49712163SRamaswamy.Tummala@Sun.COM 	}
49812163SRamaswamy.Tummala@Sun.COM 
49912163SRamaswamy.Tummala@Sun.COM 	/*
50012163SRamaswamy.Tummala@Sun.COM 	 * If the name-value pair list of properties were provided set those
50112163SRamaswamy.Tummala@Sun.COM 	 * properties over the datalink.
50212163SRamaswamy.Tummala@Sun.COM 	 */
50312163SRamaswamy.Tummala@Sun.COM 	if (proplist != NULL) {
50412163SRamaswamy.Tummala@Sun.COM 		for (i = 0; i < proplist->al_count; i++) {
50512163SRamaswamy.Tummala@Sun.COM 			dladm_arg_info_t *aip = &proplist->al_info[i];
50612163SRamaswamy.Tummala@Sun.COM 
50712163SRamaswamy.Tummala@Sun.COM 			status = dladm_set_linkprop(handle,
50812163SRamaswamy.Tummala@Sun.COM 			    pattr.dia_partlinkid, aip->ai_name, aip->ai_val,
50912163SRamaswamy.Tummala@Sun.COM 			    aip->ai_count, pattr.dia_flags);
51012163SRamaswamy.Tummala@Sun.COM 			if (status != DLADM_STATUS_OK)
51112163SRamaswamy.Tummala@Sun.COM 				break;
51212163SRamaswamy.Tummala@Sun.COM 		}
51312163SRamaswamy.Tummala@Sun.COM 	}
51412163SRamaswamy.Tummala@Sun.COM done:
51512163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK) {
51612163SRamaswamy.Tummala@Sun.COM 		if (conf_set)
51712163SRamaswamy.Tummala@Sun.COM 			(void) dladm_remove_conf(handle, pattr.dia_partlinkid);
51812163SRamaswamy.Tummala@Sun.COM 		if (part_created)
51912163SRamaswamy.Tummala@Sun.COM 			(void) i_dladm_part_delete(handle,
52012163SRamaswamy.Tummala@Sun.COM 			    pattr.dia_partlinkid);
52112163SRamaswamy.Tummala@Sun.COM 		(void) dladm_destroy_datalink_id(handle, pattr.dia_partlinkid,
52212163SRamaswamy.Tummala@Sun.COM 		    flags);
52312163SRamaswamy.Tummala@Sun.COM 	}
52412163SRamaswamy.Tummala@Sun.COM 
52512163SRamaswamy.Tummala@Sun.COM 	if (partlinkid != NULL)
52612163SRamaswamy.Tummala@Sun.COM 		*partlinkid = pattr.dia_partlinkid;
52712163SRamaswamy.Tummala@Sun.COM 
52812163SRamaswamy.Tummala@Sun.COM 	return (status);
52912163SRamaswamy.Tummala@Sun.COM }
53012163SRamaswamy.Tummala@Sun.COM 
53112163SRamaswamy.Tummala@Sun.COM /*
53212163SRamaswamy.Tummala@Sun.COM  * Call into the IP over IB driver to delete the IB partition and free up all
53312163SRamaswamy.Tummala@Sun.COM  * the resources allocated for it.
53412163SRamaswamy.Tummala@Sun.COM  */
53512163SRamaswamy.Tummala@Sun.COM static dladm_status_t
i_dladm_part_delete(dladm_handle_t handle,datalink_id_t partid)53612163SRamaswamy.Tummala@Sun.COM i_dladm_part_delete(dladm_handle_t handle, datalink_id_t partid)
53712163SRamaswamy.Tummala@Sun.COM {
53812163SRamaswamy.Tummala@Sun.COM 	ibpart_ioctl_t ioc;
53912163SRamaswamy.Tummala@Sun.COM 
54012163SRamaswamy.Tummala@Sun.COM 	bzero(&ioc, sizeof (ioc));
54112163SRamaswamy.Tummala@Sun.COM 	ioc.ioc_partid = partid;
54212303SRajkumar.Sivaprakasam@Sun.COM 	return (i_dladm_ib_ioctl(handle, IBD_DELETE_IBPART, &ioc.ibdioc));
54312163SRamaswamy.Tummala@Sun.COM }
54412163SRamaswamy.Tummala@Sun.COM 
54512163SRamaswamy.Tummala@Sun.COM /*
54612163SRamaswamy.Tummala@Sun.COM  * Delete an IB partition if 'flags' contains the active flag. Update the
54712163SRamaswamy.Tummala@Sun.COM  * persistent configuration if 'flags' contains the persist flag.
54812163SRamaswamy.Tummala@Sun.COM  */
54912163SRamaswamy.Tummala@Sun.COM dladm_status_t
dladm_part_delete(dladm_handle_t handle,datalink_id_t partid,int flags)55012163SRamaswamy.Tummala@Sun.COM dladm_part_delete(dladm_handle_t handle, datalink_id_t partid, int flags)
55112163SRamaswamy.Tummala@Sun.COM {
55212163SRamaswamy.Tummala@Sun.COM 	dladm_status_t	status = DLADM_STATUS_OK;
55312163SRamaswamy.Tummala@Sun.COM 	datalink_class_t class;
55412163SRamaswamy.Tummala@Sun.COM 
55512163SRamaswamy.Tummala@Sun.COM 	if (flags == 0)
55612163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_BADARG);
55712163SRamaswamy.Tummala@Sun.COM 
55812163SRamaswamy.Tummala@Sun.COM 	/*
55912163SRamaswamy.Tummala@Sun.COM 	 * Make sure that the datalinkid provided is an IB partition class
56012163SRamaswamy.Tummala@Sun.COM 	 * datalink ID.
56112163SRamaswamy.Tummala@Sun.COM 	 */
56212163SRamaswamy.Tummala@Sun.COM 	if ((dladm_datalink_id2info(handle, partid, NULL, &class, NULL, NULL, 0)
56312163SRamaswamy.Tummala@Sun.COM 	    != DLADM_STATUS_OK))
56412163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_BADARG);
56512163SRamaswamy.Tummala@Sun.COM 
56612163SRamaswamy.Tummala@Sun.COM 	if (class != DATALINK_CLASS_PART)
56712163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_BADARG);
56812163SRamaswamy.Tummala@Sun.COM 
56912163SRamaswamy.Tummala@Sun.COM 	if ((flags & DLADM_OPT_ACTIVE) != 0) {
57012163SRamaswamy.Tummala@Sun.COM 		status = i_dladm_part_delete(handle, partid);
57112163SRamaswamy.Tummala@Sun.COM 		if (status == DLADM_STATUS_OK) {
57212163SRamaswamy.Tummala@Sun.COM 			(void) dladm_set_linkprop(handle, partid, NULL, NULL, 0,
57312163SRamaswamy.Tummala@Sun.COM 			    DLADM_OPT_ACTIVE);
57412163SRamaswamy.Tummala@Sun.COM 			(void) dladm_destroy_datalink_id(handle, partid,
57512163SRamaswamy.Tummala@Sun.COM 			    DLADM_OPT_ACTIVE);
57612163SRamaswamy.Tummala@Sun.COM 		} else if (status != DLADM_STATUS_NOTFOUND ||
57712163SRamaswamy.Tummala@Sun.COM 		    !(flags & DLADM_OPT_PERSIST)) {
57812163SRamaswamy.Tummala@Sun.COM 			return (status);
57912163SRamaswamy.Tummala@Sun.COM 		}
58012163SRamaswamy.Tummala@Sun.COM 	}
58112163SRamaswamy.Tummala@Sun.COM 
58212163SRamaswamy.Tummala@Sun.COM 	if ((flags & DLADM_OPT_PERSIST) != 0) {
58312163SRamaswamy.Tummala@Sun.COM 		dladm_status_t db_status;
58412163SRamaswamy.Tummala@Sun.COM 		db_status = dladm_remove_conf(handle, partid);
58512163SRamaswamy.Tummala@Sun.COM 
58612163SRamaswamy.Tummala@Sun.COM 		/*
58712163SRamaswamy.Tummala@Sun.COM 		 * A partition could have been temporarily deleted in which
58812163SRamaswamy.Tummala@Sun.COM 		 * case the delete of the active partition above would have
58912163SRamaswamy.Tummala@Sun.COM 		 * failed. In that case, we update the status to be returned
59012163SRamaswamy.Tummala@Sun.COM 		 * to that of the status returned for deleting the persistent
59112163SRamaswamy.Tummala@Sun.COM 		 * database entry.
59212163SRamaswamy.Tummala@Sun.COM 		 */
59312163SRamaswamy.Tummala@Sun.COM 		if (status == DLADM_STATUS_NOTFOUND)
59412163SRamaswamy.Tummala@Sun.COM 			status = db_status;
59512163SRamaswamy.Tummala@Sun.COM 
59612163SRamaswamy.Tummala@Sun.COM 		(void) dladm_destroy_datalink_id(handle, partid,
59712163SRamaswamy.Tummala@Sun.COM 		    DLADM_OPT_PERSIST);
59812163SRamaswamy.Tummala@Sun.COM 	}
59912163SRamaswamy.Tummala@Sun.COM 
60012163SRamaswamy.Tummala@Sun.COM 	return (status);
60112163SRamaswamy.Tummala@Sun.COM }
60212163SRamaswamy.Tummala@Sun.COM 
60312163SRamaswamy.Tummala@Sun.COM /*
60412163SRamaswamy.Tummala@Sun.COM  * Call into the IP over IB driver to create the active instances of one or all
60512163SRamaswamy.Tummala@Sun.COM  * IB partitions present in the persistent configuration.
60612163SRamaswamy.Tummala@Sun.COM  */
60712163SRamaswamy.Tummala@Sun.COM /* ARGSUSED */
60812163SRamaswamy.Tummala@Sun.COM static int
i_dladm_part_up(dladm_handle_t handle,datalink_id_t plinkid,void * arg)60912163SRamaswamy.Tummala@Sun.COM i_dladm_part_up(dladm_handle_t handle, datalink_id_t plinkid, void *arg)
61012163SRamaswamy.Tummala@Sun.COM {
61112163SRamaswamy.Tummala@Sun.COM 	dladm_conf_t	conf;
61212163SRamaswamy.Tummala@Sun.COM 	datalink_id_t	linkid;
61312163SRamaswamy.Tummala@Sun.COM 	ib_pkey_t	pkey;
61412163SRamaswamy.Tummala@Sun.COM 	uint64_t	u64;
61512163SRamaswamy.Tummala@Sun.COM 	char linkover[MAXLINKNAMELEN];
61612163SRamaswamy.Tummala@Sun.COM 	dladm_status_t	status;
61712163SRamaswamy.Tummala@Sun.COM 	dladm_phys_attr_t dpa;
61812163SRamaswamy.Tummala@Sun.COM 	dladm_part_attr_t pattr;
61912163SRamaswamy.Tummala@Sun.COM 
62012163SRamaswamy.Tummala@Sun.COM 	/*
62112163SRamaswamy.Tummala@Sun.COM 	 * plinkid is the IB partition datalink's ID. Get an handle to the
62212163SRamaswamy.Tummala@Sun.COM 	 * persistent configuration entry for this datalink ID. If this datalink
62312163SRamaswamy.Tummala@Sun.COM 	 * ID is not present in the persistent configuration return.
62412163SRamaswamy.Tummala@Sun.COM 	 */
625*12824SCathy.Zhou@Sun.COM 	if ((status = dladm_getsnap_conf(handle, plinkid, &conf)) !=
62612163SRamaswamy.Tummala@Sun.COM 	    DLADM_STATUS_OK)
62712163SRamaswamy.Tummala@Sun.COM 		return (status);
62812163SRamaswamy.Tummala@Sun.COM 
62912163SRamaswamy.Tummala@Sun.COM 	/*
63012163SRamaswamy.Tummala@Sun.COM 	 * Get the name of the IB Phys link over which this partition was
63112163SRamaswamy.Tummala@Sun.COM 	 * created.
63212163SRamaswamy.Tummala@Sun.COM 	 */
63312163SRamaswamy.Tummala@Sun.COM 	status = dladm_get_conf_field(handle, conf, FLINKOVER, linkover,
63412163SRamaswamy.Tummala@Sun.COM 	    sizeof (linkover));
63512163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK)
63612163SRamaswamy.Tummala@Sun.COM 		goto done;
63712163SRamaswamy.Tummala@Sun.COM 
63812163SRamaswamy.Tummala@Sun.COM 	if ((status = dladm_name2info(handle, linkover, &linkid, NULL, NULL,
63912163SRamaswamy.Tummala@Sun.COM 	    NULL)) != DLADM_STATUS_OK)
64012163SRamaswamy.Tummala@Sun.COM 		goto done;
64112163SRamaswamy.Tummala@Sun.COM 
64212163SRamaswamy.Tummala@Sun.COM 	/*
64312163SRamaswamy.Tummala@Sun.COM 	 * Get the phys attribute of the IB Phys link to get the device name
64412163SRamaswamy.Tummala@Sun.COM 	 * associated with the phys link. We need this to get the IP over IB
64512163SRamaswamy.Tummala@Sun.COM 	 * driver instance number.
64612163SRamaswamy.Tummala@Sun.COM 	 */
64712163SRamaswamy.Tummala@Sun.COM 	if (dladm_phys_info(handle, linkid, &dpa, DLADM_OPT_ACTIVE)
64812163SRamaswamy.Tummala@Sun.COM 	    != DLADM_STATUS_OK)
64912163SRamaswamy.Tummala@Sun.COM 		goto done;
65012163SRamaswamy.Tummala@Sun.COM 
65112163SRamaswamy.Tummala@Sun.COM 	/* Get the IB partition's P_key */
65212163SRamaswamy.Tummala@Sun.COM 	status = dladm_get_conf_field(handle, conf, FPORTPKEY, &u64,
65312163SRamaswamy.Tummala@Sun.COM 	    sizeof (u64));
65412163SRamaswamy.Tummala@Sun.COM 	if (status != DLADM_STATUS_OK)
65512163SRamaswamy.Tummala@Sun.COM 		goto done;
65612163SRamaswamy.Tummala@Sun.COM 
65712163SRamaswamy.Tummala@Sun.COM 	pkey = (ib_pkey_t)u64;
65812163SRamaswamy.Tummala@Sun.COM 
65912163SRamaswamy.Tummala@Sun.COM 	/*
66012163SRamaswamy.Tummala@Sun.COM 	 * We always set the force flag during dladm_part_up because we want
66112163SRamaswamy.Tummala@Sun.COM 	 * the partition creation to succeed even if the IB HCA port over which
66212163SRamaswamy.Tummala@Sun.COM 	 * the partition is being created is still down. Since dladm_part_up
66312163SRamaswamy.Tummala@Sun.COM 	 * is usually invoked during early boot sequence, it is possible under
66412163SRamaswamy.Tummala@Sun.COM 	 * some IB subnet configurations for dladm_up_part to be called before
66512163SRamaswamy.Tummala@Sun.COM 	 * the IB link negotiation is completed and port state is set to active
66612163SRamaswamy.Tummala@Sun.COM 	 * and P_Key table is updated.
66712163SRamaswamy.Tummala@Sun.COM 	 */
66812163SRamaswamy.Tummala@Sun.COM 	pattr.dia_flags = DLADM_OPT_FORCE | DLADM_OPT_ACTIVE |
66912163SRamaswamy.Tummala@Sun.COM 	    DLADM_OPT_PERSIST;
67012163SRamaswamy.Tummala@Sun.COM 	/* IB Phys link's datalink ID. */
67112163SRamaswamy.Tummala@Sun.COM 	pattr.dia_physlinkid = linkid;
67212163SRamaswamy.Tummala@Sun.COM 	/* IB Partition's datalink ID. */
67312163SRamaswamy.Tummala@Sun.COM 	pattr.dia_partlinkid = plinkid;
67412163SRamaswamy.Tummala@Sun.COM 	pattr.dia_pkey = pkey;
67512303SRajkumar.Sivaprakasam@Sun.COM 	if (dladm_parselink(dpa.dp_dev, NULL, (uint_t *)&pattr.dia_instance) !=
67612303SRajkumar.Sivaprakasam@Sun.COM 	    DLADM_STATUS_OK)
67712163SRamaswamy.Tummala@Sun.COM 		return (DLADM_WALK_CONTINUE);
67812163SRamaswamy.Tummala@Sun.COM 
67912163SRamaswamy.Tummala@Sun.COM 	/* Create the active IB Partition object. */
68012163SRamaswamy.Tummala@Sun.COM 	if (i_dladm_part_create(handle, &pattr) == DLADM_STATUS_OK &&
68112163SRamaswamy.Tummala@Sun.COM 	    dladm_up_datalink_id(handle, plinkid) != DLADM_STATUS_OK)
682*12824SCathy.Zhou@Sun.COM 		(void) i_dladm_part_delete(handle, linkid);
68312163SRamaswamy.Tummala@Sun.COM 
68412163SRamaswamy.Tummala@Sun.COM done:
68512163SRamaswamy.Tummala@Sun.COM 	dladm_destroy_conf(handle, conf);
68612163SRamaswamy.Tummala@Sun.COM 	return (DLADM_WALK_CONTINUE);
68712163SRamaswamy.Tummala@Sun.COM }
68812163SRamaswamy.Tummala@Sun.COM 
68912163SRamaswamy.Tummala@Sun.COM /*
69012163SRamaswamy.Tummala@Sun.COM  * Bring up one or all IB partition(s) present in the persistent configuration
69112163SRamaswamy.Tummala@Sun.COM  * database. If we need to bring up one IB Partition, its datalink ID is
69212163SRamaswamy.Tummala@Sun.COM  * provided in 'linkid'.
69312163SRamaswamy.Tummala@Sun.COM  */
69412163SRamaswamy.Tummala@Sun.COM /* ARGSUSED */
69512163SRamaswamy.Tummala@Sun.COM dladm_status_t
dladm_part_up(dladm_handle_t handle,datalink_id_t linkid,uint32_t flags)69612163SRamaswamy.Tummala@Sun.COM dladm_part_up(dladm_handle_t handle, datalink_id_t linkid, uint32_t flags)
69712163SRamaswamy.Tummala@Sun.COM {
69812163SRamaswamy.Tummala@Sun.COM 	dladm_status_t status = DLADM_STATUS_OK;
69912163SRamaswamy.Tummala@Sun.COM 
70012163SRamaswamy.Tummala@Sun.COM 	if (linkid == DATALINK_ALL_LINKID) {
70112163SRamaswamy.Tummala@Sun.COM 		(void) dladm_walk_datalink_id(i_dladm_part_up, handle,
70212163SRamaswamy.Tummala@Sun.COM 		    &status, DATALINK_CLASS_PART, DATALINK_ANY_MEDIATYPE,
70312163SRamaswamy.Tummala@Sun.COM 		    DLADM_OPT_PERSIST);
70412163SRamaswamy.Tummala@Sun.COM 		return (DLADM_STATUS_OK);
70512163SRamaswamy.Tummala@Sun.COM 	} else {
70612163SRamaswamy.Tummala@Sun.COM 		(void) i_dladm_part_up(handle, linkid, &status);
70712163SRamaswamy.Tummala@Sun.COM 		return (status);
70812163SRamaswamy.Tummala@Sun.COM 	}
70912163SRamaswamy.Tummala@Sun.COM }
710