xref: /titanic_44/usr/src/lib/libdladm/common/linkprop.c (revision afdda45f890ee5dfc86e5131a30b11b354d51633)
10ba2cbe9Sxc151355 /*
20ba2cbe9Sxc151355  * CDDL HEADER START
30ba2cbe9Sxc151355  *
40ba2cbe9Sxc151355  * The contents of this file are subject to the terms of the
50ba2cbe9Sxc151355  * Common Development and Distribution License (the "License").
60ba2cbe9Sxc151355  * You may not use this file except in compliance with the License.
70ba2cbe9Sxc151355  *
80ba2cbe9Sxc151355  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90ba2cbe9Sxc151355  * or http://www.opensolaris.org/os/licensing.
100ba2cbe9Sxc151355  * See the License for the specific language governing permissions
110ba2cbe9Sxc151355  * and limitations under the License.
120ba2cbe9Sxc151355  *
130ba2cbe9Sxc151355  * When distributing Covered Code, include this CDDL HEADER in each
140ba2cbe9Sxc151355  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150ba2cbe9Sxc151355  * If applicable, add the following below this CDDL HEADER, with the
160ba2cbe9Sxc151355  * fields enclosed by brackets "[]" replaced with your own identifying
170ba2cbe9Sxc151355  * information: Portions Copyright [yyyy] [name of copyright owner]
180ba2cbe9Sxc151355  *
190ba2cbe9Sxc151355  * CDDL HEADER END
200ba2cbe9Sxc151355  */
210ba2cbe9Sxc151355 /*
22d62bc4baSyz147064  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
230ba2cbe9Sxc151355  * Use is subject to license terms.
240ba2cbe9Sxc151355  */
250ba2cbe9Sxc151355 
260ba2cbe9Sxc151355 #include <stdlib.h>
270ba2cbe9Sxc151355 #include <strings.h>
280ba2cbe9Sxc151355 #include <errno.h>
290ba2cbe9Sxc151355 #include <ctype.h>
30d62bc4baSyz147064 #include <stddef.h>
31f4b3ec61Sdh155122 #include <sys/types.h>
320ba2cbe9Sxc151355 #include <sys/stat.h>
33f4b3ec61Sdh155122 #include <sys/dld.h>
34f4b3ec61Sdh155122 #include <sys/zone.h>
35f4b3ec61Sdh155122 #include <fcntl.h>
36f4b3ec61Sdh155122 #include <unistd.h>
37f4b3ec61Sdh155122 #include <libdevinfo.h>
38f4b3ec61Sdh155122 #include <zone.h>
39f595a68aSyz147064 #include <libdllink.h>
400ba2cbe9Sxc151355 #include <libdladm_impl.h>
41d62bc4baSyz147064 #include <libdlwlan_impl.h>
42f595a68aSyz147064 #include <libdlwlan.h>
43d62bc4baSyz147064 #include <libdlvlan.h>
44f4b3ec61Sdh155122 #include <dlfcn.h>
45f4b3ec61Sdh155122 #include <link.h>
46d62bc4baSyz147064 #include <inet/wifi_ioctl.h>
47e7801d59Ssowmini #include <libdladm.h>
48e7801d59Ssowmini #include <sys/param.h>
49e7801d59Ssowmini #include <inttypes.h>
50e7801d59Ssowmini #include <sys/ethernet.h>
51bcb5c89dSSowmini Varadhan #include <net/wpa.h>
52bcb5c89dSSowmini Varadhan #include <sys/sysmacros.h>
53f4b3ec61Sdh155122 
54*afdda45fSVasumathi Sundaram - Sun Microsystems #define	PERM_READ_ONLY 	"r-"
55*afdda45fSVasumathi Sundaram - Sun Microsystems #define	PERM_READ_WRITE	"rw"
56*afdda45fSVasumathi Sundaram - Sun Microsystems 
57d62bc4baSyz147064 /*
58d62bc4baSyz147064  * The linkprop get() callback.
59e7801d59Ssowmini  * - pd: 	pointer to the struct prop_desc
60d62bc4baSyz147064  * - propstrp:	a property string array to keep the returned property.
61d62bc4baSyz147064  *		Caller allocated.
62d62bc4baSyz147064  * - cntp:	number of returned properties.
63d62bc4baSyz147064  *		Caller also uses it to indicate how many it expects.
64d62bc4baSyz147064  */
65e7801d59Ssowmini struct prop_desc;
66e7801d59Ssowmini 
67e7801d59Ssowmini typedef dladm_status_t	pd_getf_t(struct prop_desc *pd,
686b9e797cSsowmini 			datalink_id_t, char **propstp, uint_t *cntp,
69*afdda45fSVasumathi Sundaram - Sun Microsystems 			datalink_media_t, uint_t, uint_t *);
70f4b3ec61Sdh155122 
71d62bc4baSyz147064 /*
72d62bc4baSyz147064  * The linkprop set() callback.
73d62bc4baSyz147064  * - propval:	a val_desc_t array which keeps the property values to be set.
74d62bc4baSyz147064  * - cnt:	number of properties to be set.
75e7801d59Ssowmini  * - flags: 	additional flags passed down the system call.
76e7801d59Ssowmini  *
77e7801d59Ssowmini  * pd_set takes val_desc_t given by pd_check(), translates it into
78e7801d59Ssowmini  * a format suitable for kernel consumption. This may require allocation
79e7801d59Ssowmini  * of ioctl buffers etc. pd_set() may call another common routine (used
80e7801d59Ssowmini  * by all other pd_sets) which invokes the ioctl.
81d62bc4baSyz147064  */
82e7801d59Ssowmini typedef dladm_status_t	pd_setf_t(struct prop_desc *, datalink_id_t,
836b9e797cSsowmini 			val_desc_t *propval, uint_t cnt, uint_t flags,
846b9e797cSsowmini 			datalink_media_t);
85f4b3ec61Sdh155122 
86f4b3ec61Sdh155122 
87d62bc4baSyz147064 /*
88d62bc4baSyz147064  * The linkprop check() callback.
89d62bc4baSyz147064  * - propstrp:	property string array which keeps the property to be checked.
90d62bc4baSyz147064  * - cnt:	number of properties.
91d62bc4baSyz147064  * - propval:	return value; the property values of the given property strings.
92e7801d59Ssowmini  *
93e7801d59Ssowmini  * pd_check checks that the input values are valid. It does so by
94e7801d59Ssowmini  * iteraring through the pd_modval list for the property. If
95e7801d59Ssowmini  * the modifiable values cannot be expressed as a list, a pd_check
96e7801d59Ssowmini  * specific to this property can be used. If the input values are
97e7801d59Ssowmini  * verified to be valid, pd_check allocates a val_desc_t and fills it
98e7801d59Ssowmini  * with either a val_desc_t found on the pd_modval list or something
99e7801d59Ssowmini  * generated on the fly.
100d62bc4baSyz147064  */
101e7801d59Ssowmini typedef dladm_status_t	pd_checkf_t(struct prop_desc *pd,
102e7801d59Ssowmini 			    datalink_id_t, char **propstrp,
1036b9e797cSsowmini 			    uint_t cnt, val_desc_t *propval,
1046b9e797cSsowmini 			    datalink_media_t);
105f4b3ec61Sdh155122 
106bcb5c89dSSowmini Varadhan typedef struct link_attr_s {
1073fd94f8cSam223141 	mac_prop_id_t	pp_id;
108e7801d59Ssowmini 	size_t		pp_valsize;
109e7801d59Ssowmini 	char		*pp_name;
110bcb5c89dSSowmini Varadhan } link_attr_t;
111e7801d59Ssowmini 
112bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *i_dladm_buf_alloc_by_name(size_t, datalink_id_t,
113bcb5c89dSSowmini Varadhan 					const char *, uint_t, dladm_status_t *);
114bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *i_dladm_buf_alloc_by_id(size_t, datalink_id_t,
115bcb5c89dSSowmini Varadhan 					mac_prop_id_t, uint_t,
116bcb5c89dSSowmini Varadhan 					dladm_status_t *);
1173bc21d0aSAruna Ramakrishna - Sun Microsystems static dladm_status_t i_dladm_set_prop(datalink_id_t, const char *, char **,
118e7801d59Ssowmini 					uint_t, uint_t);
1193bc21d0aSAruna Ramakrishna - Sun Microsystems static dladm_status_t i_dladm_get_prop(datalink_id_t, const char *, char **,
1204045d941Ssowmini 					uint_t *, dladm_prop_type_t, uint_t);
121bcb5c89dSSowmini Varadhan static link_attr_t *dladm_name2prop(const char *);
122bcb5c89dSSowmini Varadhan static link_attr_t *dladm_id2prop(mac_prop_id_t);
1233bc21d0aSAruna Ramakrishna - Sun Microsystems static dld_ioc_macprop_t *i_dladm_get_public_prop(datalink_id_t, char *, uint_t,
1243bc21d0aSAruna Ramakrishna - Sun Microsystems 					dladm_status_t *);
125d62bc4baSyz147064 static pd_getf_t	do_get_zone, do_get_autopush, do_get_rate_mod,
126d62bc4baSyz147064 			do_get_rate_prop, do_get_channel_prop,
127e7801d59Ssowmini 			do_get_powermode_prop, do_get_radio_prop,
1283bc21d0aSAruna Ramakrishna - Sun Microsystems 			i_dladm_duplex_get, i_dladm_status_get,
1293bc21d0aSAruna Ramakrishna - Sun Microsystems 			i_dladm_binary_get, i_dladm_uint32_get,
1303bc21d0aSAruna Ramakrishna - Sun Microsystems 			i_dladm_flowctl_get;
1313bc21d0aSAruna Ramakrishna - Sun Microsystems static pd_setf_t	do_set_zone, do_set_rate_prop,
132e7801d59Ssowmini 			do_set_powermode_prop, do_set_radio_prop,
1333bc21d0aSAruna Ramakrishna - Sun Microsystems 			i_dladm_set_public_prop;
134e7801d59Ssowmini static pd_checkf_t	do_check_zone, do_check_autopush, do_check_rate,
1353bc21d0aSAruna Ramakrishna - Sun Microsystems 			i_dladm_defmtu_check;
136f4b3ec61Sdh155122 
1373bc21d0aSAruna Ramakrishna - Sun Microsystems static dladm_status_t	i_dladm_speed_get(struct prop_desc *, datalink_id_t,
1384045d941Ssowmini 			char **, uint_t *, uint_t);
139bcb5c89dSSowmini Varadhan static dladm_status_t	i_dladm_wlan_get_legacy_ioctl(datalink_id_t, void *,
140bcb5c89dSSowmini Varadhan 			    uint_t, uint_t);
141bcb5c89dSSowmini Varadhan static dladm_status_t	i_dladm_wlan_set_legacy_ioctl(datalink_id_t, void *,
142bcb5c89dSSowmini Varadhan 			    uint_t, uint_t);
143bcb5c89dSSowmini Varadhan static dladm_status_t	i_dladm_macprop(void *, boolean_t);
1446b9e797cSsowmini 
145f4b3ec61Sdh155122 typedef struct prop_desc {
146d62bc4baSyz147064 	/*
147d62bc4baSyz147064 	 * link property name
148d62bc4baSyz147064 	 */
149f4b3ec61Sdh155122 	char			*pd_name;
150d62bc4baSyz147064 
151d62bc4baSyz147064 	/*
152d62bc4baSyz147064 	 * default property value, can be set to { "", NULL }
153d62bc4baSyz147064 	 */
154f4b3ec61Sdh155122 	val_desc_t		pd_defval;
155d62bc4baSyz147064 
156d62bc4baSyz147064 	/*
157d62bc4baSyz147064 	 * list of optional property values, can be NULL.
158d62bc4baSyz147064 	 *
159d62bc4baSyz147064 	 * This is set to non-NULL if there is a list of possible property
160d62bc4baSyz147064 	 * values.  pd_optval would point to the array of possible values.
161d62bc4baSyz147064 	 */
162d62bc4baSyz147064 	val_desc_t		*pd_optval;
163d62bc4baSyz147064 
164d62bc4baSyz147064 	/*
165d62bc4baSyz147064 	 * count of the above optional property values. 0 if pd_optval is NULL.
166d62bc4baSyz147064 	 */
167d62bc4baSyz147064 	uint_t			pd_noptval;
168d62bc4baSyz147064 
169d62bc4baSyz147064 	/*
170d62bc4baSyz147064 	 * callback to set link property;
171d62bc4baSyz147064 	 * set to NULL if this property is read-only
172d62bc4baSyz147064 	 */
173f4b3ec61Sdh155122 	pd_setf_t		*pd_set;
174d62bc4baSyz147064 
175d62bc4baSyz147064 	/*
176d62bc4baSyz147064 	 * callback to get modifiable link property
177d62bc4baSyz147064 	 */
178f4b3ec61Sdh155122 	pd_getf_t		*pd_getmod;
179d62bc4baSyz147064 
180d62bc4baSyz147064 	/*
181d62bc4baSyz147064 	 * callback to get current link property
182d62bc4baSyz147064 	 */
183f4b3ec61Sdh155122 	pd_getf_t		*pd_get;
184d62bc4baSyz147064 
185d62bc4baSyz147064 	/*
186d62bc4baSyz147064 	 * callback to validate link property value, set to NULL if pd_optval
187d62bc4baSyz147064 	 * is not NULL. In that case, validate the value by comparing it with
188d62bc4baSyz147064 	 * the pd_optval. Return a val_desc_t array pointer if the value is
189d62bc4baSyz147064 	 * valid.
190d62bc4baSyz147064 	 */
191f4b3ec61Sdh155122 	pd_checkf_t		*pd_check;
192d62bc4baSyz147064 
193d62bc4baSyz147064 	uint_t			pd_flags;
194e7801d59Ssowmini #define	PD_TEMPONLY	0x1	/* property is temporary only */
195e7801d59Ssowmini #define	PD_CHECK_ALLOC	0x2	/* alloc vd_val as part of pd_check */
196d62bc4baSyz147064 	/*
197d62bc4baSyz147064 	 * indicate link classes this property applies to.
198d62bc4baSyz147064 	 */
199d62bc4baSyz147064 	datalink_class_t	pd_class;
200d62bc4baSyz147064 
201d62bc4baSyz147064 	/*
202d62bc4baSyz147064 	 * indicate link media type this property applies to.
203d62bc4baSyz147064 	 */
204d62bc4baSyz147064 	datalink_media_t	pd_dmedia;
205f4b3ec61Sdh155122 } prop_desc_t;
206f4b3ec61Sdh155122 
2073fd94f8cSam223141 #define	MAC_PROP_BUFSIZE(v)	sizeof (dld_ioc_macprop_t) + (v) - 1
208e7801d59Ssowmini 
209bcb5c89dSSowmini Varadhan /*
210bcb5c89dSSowmini Varadhan  * Supported link properties enumerated in the prop_table[] array are
211bcb5c89dSSowmini Varadhan  * computed using the callback functions in that array. To compute the
212bcb5c89dSSowmini Varadhan  * property value, multiple distinct system calls may be needed (e.g.,
213bcb5c89dSSowmini Varadhan  * for wifi speed, we need to issue system calls to get desired/supported
214bcb5c89dSSowmini Varadhan  * rates). The link_attr[] table enumerates the interfaces to the kernel,
215bcb5c89dSSowmini Varadhan  * and the type/size of the data passed in the user-kernel interface.
216bcb5c89dSSowmini Varadhan  */
217bcb5c89dSSowmini Varadhan static link_attr_t link_attr[] = {
218bcb5c89dSSowmini Varadhan 	{ MAC_PROP_DUPLEX,	sizeof (link_duplex_t),	"duplex"},
219e7801d59Ssowmini 
220bcb5c89dSSowmini Varadhan 	{ MAC_PROP_SPEED,	sizeof (uint64_t),	"speed"},
221e7801d59Ssowmini 
222bcb5c89dSSowmini Varadhan 	{ MAC_PROP_STATUS,	sizeof (link_state_t),	"state"},
223e7801d59Ssowmini 
224bcb5c89dSSowmini Varadhan 	{ MAC_PROP_AUTONEG,	sizeof (uint8_t),	"adv_autoneg_cap"},
225e7801d59Ssowmini 
226bcb5c89dSSowmini Varadhan 	{ MAC_PROP_MTU,		sizeof (uint32_t),	"mtu"},
227e7801d59Ssowmini 
228bcb5c89dSSowmini Varadhan 	{ MAC_PROP_FLOWCTRL,	sizeof (link_flowctrl_t), "flowctrl"},
229e7801d59Ssowmini 
230bcb5c89dSSowmini Varadhan 	{ MAC_PROP_ZONE,	sizeof (dld_ioc_zid_t),	"zone"},
231e7801d59Ssowmini 
232bcb5c89dSSowmini Varadhan 	{ MAC_PROP_AUTOPUSH,	sizeof (struct dlautopush), "autopush"},
2333bc21d0aSAruna Ramakrishna - Sun Microsystems 
234bcb5c89dSSowmini Varadhan 	{ MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t),	"adv_1000fdx_cap"},
2353bc21d0aSAruna Ramakrishna - Sun Microsystems 
236bcb5c89dSSowmini Varadhan 	{ MAC_PROP_EN_1000FDX_CAP, sizeof (uint8_t),	"en_1000fdx_cap"},
237e7801d59Ssowmini 
238bcb5c89dSSowmini Varadhan 	{ MAC_PROP_ADV_1000HDX_CAP, sizeof (uint8_t),	"adv_1000hdx_cap"},
239e7801d59Ssowmini 
240bcb5c89dSSowmini Varadhan 	{ MAC_PROP_EN_1000HDX_CAP, sizeof (uint8_t),	"en_1000hdx_cap"},
241e7801d59Ssowmini 
242bcb5c89dSSowmini Varadhan 	{ MAC_PROP_ADV_100FDX_CAP, sizeof (uint8_t),	"adv_100fdx_cap"},
243e7801d59Ssowmini 
244bcb5c89dSSowmini Varadhan 	{ MAC_PROP_EN_100FDX_CAP, sizeof (uint8_t),	"en_100fdx_cap"},
245e7801d59Ssowmini 
246bcb5c89dSSowmini Varadhan 	{ MAC_PROP_ADV_100HDX_CAP, sizeof (uint8_t),	"adv_100hdx_cap"},
247e7801d59Ssowmini 
248bcb5c89dSSowmini Varadhan 	{ MAC_PROP_EN_100HDX_CAP, sizeof (uint8_t),	"en_100hdx_cap"},
249e7801d59Ssowmini 
250bcb5c89dSSowmini Varadhan 	{ MAC_PROP_ADV_10FDX_CAP, sizeof (uint8_t),	"adv_10fdx_cap"},
251e7801d59Ssowmini 
252bcb5c89dSSowmini Varadhan 	{ MAC_PROP_EN_10FDX_CAP, sizeof (uint8_t),	"en_10fdx_cap"},
253e7801d59Ssowmini 
254bcb5c89dSSowmini Varadhan 	{ MAC_PROP_ADV_10HDX_CAP, sizeof (uint8_t),	"adv_10hdx_cap"},
255e7801d59Ssowmini 
256bcb5c89dSSowmini Varadhan 	{ MAC_PROP_EN_10HDX_CAP, sizeof (uint8_t),	"en_10hdx_cap"},
257e7801d59Ssowmini 
258bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_ESSID,	sizeof (wl_linkstatus_t), "essid"},
259e7801d59Ssowmini 
260bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_BSSID,	sizeof (wl_bssid_t),	"bssid"},
261bcb5c89dSSowmini Varadhan 
262bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_BSSTYPE,	sizeof (wl_bss_type_t),	"bsstype"},
263bcb5c89dSSowmini Varadhan 
264bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_LINKSTATUS, sizeof (wl_linkstatus_t), "wl_linkstatus"},
265bcb5c89dSSowmini Varadhan 
266bcb5c89dSSowmini Varadhan 	/* wl_rates_t has variable length */
267bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_DESIRED_RATES, sizeof (wl_rates_t), "desired_rates"},
268bcb5c89dSSowmini Varadhan 
269bcb5c89dSSowmini Varadhan 	/* wl_rates_t has variable length */
270bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_SUPPORTED_RATES, sizeof (wl_rates_t), "supported_rates"},
271bcb5c89dSSowmini Varadhan 
272bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_AUTH_MODE, sizeof (wl_authmode_t), "authmode"},
273bcb5c89dSSowmini Varadhan 
274bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_ENCRYPTION, sizeof (wl_encryption_t), "encryption"},
275bcb5c89dSSowmini Varadhan 
276bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_RSSI,	sizeof (wl_rssi_t),	"signal"},
277bcb5c89dSSowmini Varadhan 
278bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_PHY_CONFIG, sizeof (wl_phy_conf_t), "phy_conf"},
279bcb5c89dSSowmini Varadhan 
280bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_CAPABILITY, sizeof (wl_capability_t), "capability"},
281bcb5c89dSSowmini Varadhan 
282bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_WPA,	sizeof (wl_wpa_t),	"wpa"},
283bcb5c89dSSowmini Varadhan 
284bcb5c89dSSowmini Varadhan 	/*  wl_wpa_ess_t has variable length */
285bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"},
286bcb5c89dSSowmini Varadhan 
287bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"},
288bcb5c89dSSowmini Varadhan 
289bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_RADIO,	sizeof (dladm_wlan_radio_t), "wl_radio"},
290bcb5c89dSSowmini Varadhan 
291bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_ESS_LIST, sizeof (wl_ess_list_t),	"wl_ess_list"},
292bcb5c89dSSowmini Varadhan 
293bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_KEY_TAB,	sizeof (wl_wep_key_tab_t), "wl_wep_key"},
294bcb5c89dSSowmini Varadhan 
295bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_CREATE_IBSS, sizeof (wl_create_ibss_t), "createibss"},
296bcb5c89dSSowmini Varadhan 
297bcb5c89dSSowmini Varadhan 	/* wl_wpa_ie_t has variable length */
298bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_SETOPTIE,	sizeof (wl_wpa_ie_t),	"set_ie"},
299bcb5c89dSSowmini Varadhan 
300bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_DELKEY,	sizeof (wl_del_key_t),	"wpa_del_key"},
301bcb5c89dSSowmini Varadhan 
302bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_KEY,	sizeof (wl_key_t),	"wl_key"},
303bcb5c89dSSowmini Varadhan 
304bcb5c89dSSowmini Varadhan 	{ MAC_PROP_WL_MLME,	sizeof (wl_mlme_t),	"mlme"},
305bcb5c89dSSowmini Varadhan 
306bcb5c89dSSowmini Varadhan 	{ MAC_PROP_PRIVATE,	0,			"driver-private"}
307e7801d59Ssowmini };
308e7801d59Ssowmini 
309e7801d59Ssowmini static  val_desc_t	link_duplex_vals[] = {
310e7801d59Ssowmini 	{ "half", 	LINK_DUPLEX_HALF	},
311e7801d59Ssowmini 	{ "full", 	LINK_DUPLEX_HALF	}
312e7801d59Ssowmini };
313e7801d59Ssowmini static  val_desc_t	link_status_vals[] = {
314e7801d59Ssowmini 	{ "up",		LINK_STATE_UP		},
315e7801d59Ssowmini 	{ "down",	LINK_STATE_DOWN		}
316e7801d59Ssowmini };
317e7801d59Ssowmini static  val_desc_t	link_01_vals[] = {
318e7801d59Ssowmini 	{ "1",		1			},
319e7801d59Ssowmini 	{ "0",		0			}
320e7801d59Ssowmini };
321e7801d59Ssowmini static  val_desc_t	link_flow_vals[] = {
322e7801d59Ssowmini 	{ "no",		LINK_FLOWCTRL_NONE	},
323e7801d59Ssowmini 	{ "tx",		LINK_FLOWCTRL_TX	},
324e7801d59Ssowmini 	{ "rx",		LINK_FLOWCTRL_RX	},
325e7801d59Ssowmini 	{ "bi",		LINK_FLOWCTRL_BI	}
326e7801d59Ssowmini };
327e7801d59Ssowmini 
328e7801d59Ssowmini #define	VALCNT(vals)    (sizeof ((vals)) / sizeof (val_desc_t))
329e7801d59Ssowmini 
330d62bc4baSyz147064 static val_desc_t	dladm_wlan_radio_vals[] = {
331d62bc4baSyz147064 	{ "on",		DLADM_WLAN_RADIO_ON	},
332d62bc4baSyz147064 	{ "off",	DLADM_WLAN_RADIO_OFF	}
333d62bc4baSyz147064 };
334d62bc4baSyz147064 
335d62bc4baSyz147064 static val_desc_t	dladm_wlan_powermode_vals[] = {
336d62bc4baSyz147064 	{ "off",	DLADM_WLAN_PM_OFF	},
337d62bc4baSyz147064 	{ "fast",	DLADM_WLAN_PM_FAST	},
338d62bc4baSyz147064 	{ "max",	DLADM_WLAN_PM_MAX	}
339d62bc4baSyz147064 };
340d62bc4baSyz147064 
341f4b3ec61Sdh155122 static prop_desc_t	prop_table[] = {
342d62bc4baSyz147064 
343e7801d59Ssowmini 	{ "channel",	{ NULL, 0 },
344e7801d59Ssowmini 	    NULL, 0, NULL, NULL,
345d62bc4baSyz147064 	    do_get_channel_prop, NULL, 0,
346d62bc4baSyz147064 	    DATALINK_CLASS_PHYS, DL_WIFI },
347d62bc4baSyz147064 
348d62bc4baSyz147064 	{ "powermode",	{ "off", DLADM_WLAN_PM_OFF },
349d62bc4baSyz147064 	    dladm_wlan_powermode_vals, VALCNT(dladm_wlan_powermode_vals),
350d62bc4baSyz147064 	    do_set_powermode_prop, NULL,
351d62bc4baSyz147064 	    do_get_powermode_prop, NULL, 0,
352d62bc4baSyz147064 	    DATALINK_CLASS_PHYS, DL_WIFI },
353d62bc4baSyz147064 
354d62bc4baSyz147064 	{ "radio",	{ "on", DLADM_WLAN_RADIO_ON },
355d62bc4baSyz147064 	    dladm_wlan_radio_vals, VALCNT(dladm_wlan_radio_vals),
356d62bc4baSyz147064 	    do_set_radio_prop, NULL,
357d62bc4baSyz147064 	    do_get_radio_prop, NULL, 0,
358d62bc4baSyz147064 	    DATALINK_CLASS_PHYS, DL_WIFI },
359d62bc4baSyz147064 
360d62bc4baSyz147064 	{ "speed",	{ "", 0 }, NULL, 0,
361d62bc4baSyz147064 	    do_set_rate_prop, do_get_rate_mod,
362d62bc4baSyz147064 	    do_get_rate_prop, do_check_rate, 0,
3636b9e797cSsowmini 	    DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE },
364d62bc4baSyz147064 
3654045d941Ssowmini 	{ "autopush",	{ "", 0 }, NULL, 0,
3663bc21d0aSAruna Ramakrishna - Sun Microsystems 	    i_dladm_set_public_prop, NULL,
3673bc21d0aSAruna Ramakrishna - Sun Microsystems 	    do_get_autopush, do_check_autopush, PD_CHECK_ALLOC,
368d62bc4baSyz147064 	    DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE },
369d62bc4baSyz147064 
3704045d941Ssowmini 	{ "zone",	{ "", 0 }, NULL, 0,
371f4b3ec61Sdh155122 	    do_set_zone, NULL,
3723bc21d0aSAruna Ramakrishna - Sun Microsystems 	    do_get_zone, do_check_zone, PD_TEMPONLY|PD_CHECK_ALLOC,
373e7801d59Ssowmini 	    DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE },
374e7801d59Ssowmini 
3754045d941Ssowmini 	{ "duplex", { "", 0 },
376e7801d59Ssowmini 	    link_duplex_vals, VALCNT(link_duplex_vals),
3773bc21d0aSAruna Ramakrishna - Sun Microsystems 	    NULL, NULL, i_dladm_duplex_get, NULL,
378e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
379e7801d59Ssowmini 
3806b9e797cSsowmini 	{ "state", { "up", LINK_STATE_UP },
381e7801d59Ssowmini 	    link_status_vals, VALCNT(link_status_vals),
3823bc21d0aSAruna Ramakrishna - Sun Microsystems 	    NULL, NULL, i_dladm_status_get, NULL,
3834045d941Ssowmini 	    0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE },
384e7801d59Ssowmini 
385e7801d59Ssowmini 	{ "adv_autoneg_cap", { "1", 1 },
386e7801d59Ssowmini 	    link_01_vals, VALCNT(link_01_vals),
3873bc21d0aSAruna Ramakrishna - Sun Microsystems 	    i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
388e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
389e7801d59Ssowmini 
3904045d941Ssowmini 	{ "mtu", { "", 0 }, NULL, 0,
3913bc21d0aSAruna Ramakrishna - Sun Microsystems 	    i_dladm_set_public_prop, NULL, i_dladm_uint32_get,
3923bc21d0aSAruna Ramakrishna - Sun Microsystems 	    i_dladm_defmtu_check, 0, DATALINK_CLASS_ALL,
3933bc21d0aSAruna Ramakrishna - Sun Microsystems 	    DATALINK_ANY_MEDIATYPE },
394e7801d59Ssowmini 
3954045d941Ssowmini 	{ "flowctrl", { "", 0 },
396e7801d59Ssowmini 	    link_flow_vals, VALCNT(link_flow_vals),
3973bc21d0aSAruna Ramakrishna - Sun Microsystems 	    i_dladm_set_public_prop, NULL, i_dladm_flowctl_get, NULL,
398e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
399e7801d59Ssowmini 
4004045d941Ssowmini 	{ "adv_1000fdx_cap", { "", 0 },
4014045d941Ssowmini 	    link_01_vals, VALCNT(link_01_vals),
4023bc21d0aSAruna Ramakrishna - Sun Microsystems 	    NULL, NULL, i_dladm_binary_get, NULL,
403e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
404e7801d59Ssowmini 
4054045d941Ssowmini 	{ "en_1000fdx_cap", { "", 0 },
406e7801d59Ssowmini 	    link_01_vals, VALCNT(link_01_vals),
4073bc21d0aSAruna Ramakrishna - Sun Microsystems 	    i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
408e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
409e7801d59Ssowmini 
4104045d941Ssowmini 	{ "adv_1000hdx_cap", { "", 0 },
411e7801d59Ssowmini 	    link_01_vals, VALCNT(link_01_vals),
4123bc21d0aSAruna Ramakrishna - Sun Microsystems 	    NULL, NULL, i_dladm_binary_get, NULL,
413e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
414e7801d59Ssowmini 
4154045d941Ssowmini 	{ "en_1000hdx_cap", { "", 0 },
416e7801d59Ssowmini 	    link_01_vals, VALCNT(link_01_vals),
4173bc21d0aSAruna Ramakrishna - Sun Microsystems 	    i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
418e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
419e7801d59Ssowmini 
4204045d941Ssowmini 	{ "adv_100fdx_cap", { "", 0 },
421e7801d59Ssowmini 	    link_01_vals, VALCNT(link_01_vals),
4223bc21d0aSAruna Ramakrishna - Sun Microsystems 	    NULL, NULL, i_dladm_binary_get, NULL,
423e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
424e7801d59Ssowmini 
4254045d941Ssowmini 	{ "en_100fdx_cap", { "", 0 },
426e7801d59Ssowmini 	    link_01_vals, VALCNT(link_01_vals),
4273bc21d0aSAruna Ramakrishna - Sun Microsystems 	    i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
428e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
429e7801d59Ssowmini 
4304045d941Ssowmini 	{ "adv_100hdx_cap", { "", 0 },
431e7801d59Ssowmini 	    link_01_vals, VALCNT(link_01_vals),
4323bc21d0aSAruna Ramakrishna - Sun Microsystems 	    NULL, NULL, i_dladm_binary_get, NULL,
433e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
434e7801d59Ssowmini 
4354045d941Ssowmini 	{ "en_100hdx_cap", { "", 0 },
436e7801d59Ssowmini 	    link_01_vals, VALCNT(link_01_vals),
4373bc21d0aSAruna Ramakrishna - Sun Microsystems 	    i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
438e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
439e7801d59Ssowmini 
4404045d941Ssowmini 	{ "adv_10fdx_cap", { "", 0 },
441e7801d59Ssowmini 	    link_01_vals, VALCNT(link_01_vals),
4423bc21d0aSAruna Ramakrishna - Sun Microsystems 	    NULL, NULL, i_dladm_binary_get, NULL,
443e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
444e7801d59Ssowmini 
4454045d941Ssowmini 	{ "en_10fdx_cap", { "", 0 },
446e7801d59Ssowmini 	    link_01_vals, VALCNT(link_01_vals),
4473bc21d0aSAruna Ramakrishna - Sun Microsystems 	    i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
448e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
449e7801d59Ssowmini 
4504045d941Ssowmini 	{ "adv_10hdx_cap", { "", 0 },
451e7801d59Ssowmini 	    link_01_vals, VALCNT(link_01_vals),
4523bc21d0aSAruna Ramakrishna - Sun Microsystems 	    NULL, NULL, i_dladm_binary_get, NULL,
453e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER },
454e7801d59Ssowmini 
4554045d941Ssowmini 	{ "en_10hdx_cap", { "", 0 },
456e7801d59Ssowmini 	    link_01_vals, VALCNT(link_01_vals),
4573bc21d0aSAruna Ramakrishna - Sun Microsystems 	    i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
458e7801d59Ssowmini 	    0, DATALINK_CLASS_PHYS, DL_ETHER }
459e7801d59Ssowmini 
460f4b3ec61Sdh155122 };
461f4b3ec61Sdh155122 
462d62bc4baSyz147064 #define	DLADM_MAX_PROPS	(sizeof (prop_table) / sizeof (prop_desc_t))
4630ba2cbe9Sxc151355 
464bcb5c89dSSowmini Varadhan /*
465bcb5c89dSSowmini Varadhan  * when retrieving  private properties, we pass down a buffer with
466bcb5c89dSSowmini Varadhan  * DLADM_PROP_BUF_CHUNK of space for the driver to return the property value.
467bcb5c89dSSowmini Varadhan  */
468bcb5c89dSSowmini Varadhan #define	DLADM_PROP_BUF_CHUNK	1024
469bcb5c89dSSowmini Varadhan 
470d62bc4baSyz147064 static dladm_status_t	i_dladm_set_linkprop_db(datalink_id_t, const char *,
471d62bc4baSyz147064 			    char **, uint_t);
472d62bc4baSyz147064 static dladm_status_t	i_dladm_get_linkprop_db(datalink_id_t, const char *,
473d62bc4baSyz147064 			    char **, uint_t *);
474d62bc4baSyz147064 static dladm_status_t	i_dladm_set_single_prop(datalink_id_t, datalink_class_t,
475d62bc4baSyz147064 			    uint32_t, prop_desc_t *, char **, uint_t, uint_t);
476d62bc4baSyz147064 static dladm_status_t	i_dladm_set_linkprop(datalink_id_t, const char *,
477d62bc4baSyz147064 			    char **, uint_t, uint_t);
4784045d941Ssowmini static dladm_status_t	i_dladm_getset_defval(prop_desc_t *, datalink_id_t,
4794045d941Ssowmini 			    datalink_media_t, uint_t);
480d62bc4baSyz147064 /*
481d62bc4baSyz147064  * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all
482d62bc4baSyz147064  * rates to be retrieved. However, we cannot increase it at this
483d62bc4baSyz147064  * time because it will break binary compatibility with unbundled
484d62bc4baSyz147064  * WiFi drivers and utilities. So for now we define an additional
485d62bc4baSyz147064  * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved.
486d62bc4baSyz147064  */
487d62bc4baSyz147064 #define	MAX_SUPPORT_RATES	64
488d62bc4baSyz147064 
489d62bc4baSyz147064 #define	AP_ANCHOR	"[anchor]"
490d62bc4baSyz147064 #define	AP_DELIMITER	'.'
491d62bc4baSyz147064 
492d62bc4baSyz147064 static dladm_status_t
493d62bc4baSyz147064 do_check_prop(prop_desc_t *pdp, char **prop_val, uint_t val_cnt,
494d62bc4baSyz147064     val_desc_t *vdp)
4950ba2cbe9Sxc151355 {
496d62bc4baSyz147064 	int		i, j;
4970ba2cbe9Sxc151355 	dladm_status_t	status = DLADM_STATUS_OK;
4980ba2cbe9Sxc151355 
499d62bc4baSyz147064 	for (j = 0; j < val_cnt; j++) {
500d62bc4baSyz147064 		for (i = 0; i < pdp->pd_noptval; i++) {
501d62bc4baSyz147064 			if (strcasecmp(*prop_val,
502d62bc4baSyz147064 			    pdp->pd_optval[i].vd_name) == 0) {
5030ba2cbe9Sxc151355 				break;
5040ba2cbe9Sxc151355 			}
5050ba2cbe9Sxc151355 		}
506d62bc4baSyz147064 		if (i == pdp->pd_noptval) {
507d62bc4baSyz147064 			status = DLADM_STATUS_BADVAL;
508d62bc4baSyz147064 			goto done;
509d62bc4baSyz147064 		}
510d62bc4baSyz147064 		(void) memcpy(vdp + j, &pdp->pd_optval[i], sizeof (val_desc_t));
5110ba2cbe9Sxc151355 	}
5120ba2cbe9Sxc151355 
513d62bc4baSyz147064 done:
514d62bc4baSyz147064 	return (status);
5150ba2cbe9Sxc151355 }
5160ba2cbe9Sxc151355 
5170ba2cbe9Sxc151355 static dladm_status_t
518d62bc4baSyz147064 i_dladm_set_single_prop(datalink_id_t linkid, datalink_class_t class,
519d62bc4baSyz147064     uint32_t media, prop_desc_t *pdp, char **prop_val, uint_t val_cnt,
520d62bc4baSyz147064     uint_t flags)
5210ba2cbe9Sxc151355 {
5220ba2cbe9Sxc151355 	dladm_status_t	status = DLADM_STATUS_OK;
523d62bc4baSyz147064 	val_desc_t	*vdp = NULL;
524d62bc4baSyz147064 	boolean_t	needfree = B_FALSE;
525d62bc4baSyz147064 	uint_t		cnt, i;
5260ba2cbe9Sxc151355 
527d62bc4baSyz147064 	if (!(pdp->pd_class & class))
528d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
5290ba2cbe9Sxc151355 
530d62bc4baSyz147064 	if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media))
531d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
532d62bc4baSyz147064 
533d62bc4baSyz147064 	if ((flags & DLADM_OPT_PERSIST) && (pdp->pd_flags & PD_TEMPONLY))
534d62bc4baSyz147064 		return (DLADM_STATUS_TEMPONLY);
535d62bc4baSyz147064 
536d62bc4baSyz147064 	if (!(flags & DLADM_OPT_ACTIVE))
537d62bc4baSyz147064 		return (DLADM_STATUS_OK);
538d62bc4baSyz147064 
539d62bc4baSyz147064 	if (pdp->pd_set == NULL)
540d62bc4baSyz147064 		return (DLADM_STATUS_PROPRDONLY);
541d62bc4baSyz147064 
542e7801d59Ssowmini 	if (pdp->pd_flags & PD_CHECK_ALLOC)
543e7801d59Ssowmini 		needfree = B_TRUE;
544e7801d59Ssowmini 	else
545e7801d59Ssowmini 		needfree = B_FALSE;
546d62bc4baSyz147064 	if (prop_val != NULL) {
547d62bc4baSyz147064 		vdp = malloc(sizeof (val_desc_t) * val_cnt);
548d62bc4baSyz147064 		if (vdp == NULL)
549d62bc4baSyz147064 			return (DLADM_STATUS_NOMEM);
550d62bc4baSyz147064 
551e7801d59Ssowmini 
552d62bc4baSyz147064 		if (pdp->pd_check != NULL) {
553e7801d59Ssowmini 			status = pdp->pd_check(pdp, linkid, prop_val, val_cnt,
5546b9e797cSsowmini 			    vdp, media);
555d62bc4baSyz147064 		} else if (pdp->pd_optval != NULL) {
556d62bc4baSyz147064 			status = do_check_prop(pdp, prop_val, val_cnt, vdp);
557d62bc4baSyz147064 		} else {
558d62bc4baSyz147064 			status = DLADM_STATUS_BADARG;
5590ba2cbe9Sxc151355 		}
5600ba2cbe9Sxc151355 
561d62bc4baSyz147064 		if (status != DLADM_STATUS_OK)
562d62bc4baSyz147064 			goto done;
563d62bc4baSyz147064 
564d62bc4baSyz147064 		cnt = val_cnt;
565d62bc4baSyz147064 	} else {
566d62bc4baSyz147064 		if (pdp->pd_defval.vd_name == NULL)
567d62bc4baSyz147064 			return (DLADM_STATUS_NOTSUP);
568d62bc4baSyz147064 
5693bc21d0aSAruna Ramakrishna - Sun Microsystems 		cnt = 1;
5703bc21d0aSAruna Ramakrishna - Sun Microsystems 		if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 ||
5714045d941Ssowmini 		    strlen(pdp->pd_defval.vd_name) > 0) {
572d62bc4baSyz147064 			if ((vdp = malloc(sizeof (val_desc_t))) == NULL)
573d62bc4baSyz147064 				return (DLADM_STATUS_NOMEM);
5743bc21d0aSAruna Ramakrishna - Sun Microsystems 
5753bc21d0aSAruna Ramakrishna - Sun Microsystems 			if (pdp->pd_check != NULL) {
5763bc21d0aSAruna Ramakrishna - Sun Microsystems 				status = pdp->pd_check(pdp, linkid, prop_val,
5773bc21d0aSAruna Ramakrishna - Sun Microsystems 				    cnt, vdp, media);
5783bc21d0aSAruna Ramakrishna - Sun Microsystems 				if (status != DLADM_STATUS_OK)
5793bc21d0aSAruna Ramakrishna - Sun Microsystems 					goto done;
5803bc21d0aSAruna Ramakrishna - Sun Microsystems 			} else {
5814045d941Ssowmini 				(void) memcpy(vdp, &pdp->pd_defval,
5824045d941Ssowmini 				    sizeof (val_desc_t));
5833bc21d0aSAruna Ramakrishna - Sun Microsystems 			}
5844045d941Ssowmini 		} else {
5854045d941Ssowmini 			status = i_dladm_getset_defval(pdp, linkid,
5864045d941Ssowmini 			    media, flags);
5874045d941Ssowmini 			return (status);
5884045d941Ssowmini 		}
589d62bc4baSyz147064 	}
5906b9e797cSsowmini 	status = pdp->pd_set(pdp, linkid, vdp, cnt, flags, media);
591d62bc4baSyz147064 	if (needfree) {
592d62bc4baSyz147064 		for (i = 0; i < cnt; i++)
593e7801d59Ssowmini 			free((void *)((val_desc_t *)vdp + i)->vd_val);
594d62bc4baSyz147064 	}
595d62bc4baSyz147064 done:
596d62bc4baSyz147064 	free(vdp);
597d62bc4baSyz147064 	return (status);
598d62bc4baSyz147064 }
599d62bc4baSyz147064 
600d62bc4baSyz147064 static dladm_status_t
601d62bc4baSyz147064 i_dladm_set_linkprop(datalink_id_t linkid, const char *prop_name,
602d62bc4baSyz147064     char **prop_val, uint_t val_cnt, uint_t flags)
603d62bc4baSyz147064 {
604d62bc4baSyz147064 	int			i;
605d62bc4baSyz147064 	boolean_t		found = B_FALSE;
606d62bc4baSyz147064 	datalink_class_t	class;
607d62bc4baSyz147064 	uint32_t		media;
608d62bc4baSyz147064 	dladm_status_t		status = DLADM_STATUS_OK;
609d62bc4baSyz147064 
610d62bc4baSyz147064 	status = dladm_datalink_id2info(linkid, NULL, &class, &media, NULL, 0);
611d62bc4baSyz147064 	if (status != DLADM_STATUS_OK)
6120ba2cbe9Sxc151355 		return (status);
6130ba2cbe9Sxc151355 
614d62bc4baSyz147064 	for (i = 0; i < DLADM_MAX_PROPS; i++) {
615d62bc4baSyz147064 		prop_desc_t	*pdp = &prop_table[i];
616d62bc4baSyz147064 		dladm_status_t	s;
6170ba2cbe9Sxc151355 
618d62bc4baSyz147064 		if (prop_name != NULL &&
619d62bc4baSyz147064 		    (strcasecmp(prop_name, pdp->pd_name) != 0))
620d62bc4baSyz147064 			continue;
621d62bc4baSyz147064 
622d62bc4baSyz147064 		found = B_TRUE;
623d62bc4baSyz147064 		s = i_dladm_set_single_prop(linkid, class, media, pdp, prop_val,
624d62bc4baSyz147064 		    val_cnt, flags);
625d62bc4baSyz147064 
626d62bc4baSyz147064 		if (prop_name != NULL) {
627d62bc4baSyz147064 			status = s;
628d62bc4baSyz147064 			break;
629d62bc4baSyz147064 		} else {
630d62bc4baSyz147064 			if (s != DLADM_STATUS_OK &&
631d62bc4baSyz147064 			    s != DLADM_STATUS_NOTSUP)
632d62bc4baSyz147064 				status = s;
633d62bc4baSyz147064 		}
634d62bc4baSyz147064 	}
635e7801d59Ssowmini 	if (!found) {
636e7801d59Ssowmini 		if (prop_name[0] == '_') {
637e7801d59Ssowmini 			/* other private properties */
6383bc21d0aSAruna Ramakrishna - Sun Microsystems 			status = i_dladm_set_prop(linkid, prop_name, prop_val,
639e7801d59Ssowmini 			    val_cnt, flags);
640e7801d59Ssowmini 		} else  {
6410ba2cbe9Sxc151355 			status = DLADM_STATUS_NOTFOUND;
642e7801d59Ssowmini 		}
643e7801d59Ssowmini 	}
6440ba2cbe9Sxc151355 
6450ba2cbe9Sxc151355 	return (status);
6460ba2cbe9Sxc151355 }
6470ba2cbe9Sxc151355 
648d62bc4baSyz147064 /*
649d62bc4baSyz147064  * Set/reset link property for specific link
650d62bc4baSyz147064  */
651d62bc4baSyz147064 dladm_status_t
652d62bc4baSyz147064 dladm_set_linkprop(datalink_id_t linkid, const char *prop_name, char **prop_val,
653d62bc4baSyz147064     uint_t val_cnt, uint_t flags)
6540ba2cbe9Sxc151355 {
655d62bc4baSyz147064 	dladm_status_t	status = DLADM_STATUS_OK;
6560ba2cbe9Sxc151355 
657d62bc4baSyz147064 	if ((linkid == DATALINK_INVALID_LINKID) || (flags == 0) ||
658d62bc4baSyz147064 	    (prop_val == NULL && val_cnt > 0) ||
659d62bc4baSyz147064 	    (prop_val != NULL && val_cnt == 0) ||
660d62bc4baSyz147064 	    (prop_name == NULL && prop_val != NULL)) {
661d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
6620ba2cbe9Sxc151355 	}
6630ba2cbe9Sxc151355 
664d62bc4baSyz147064 	status = i_dladm_set_linkprop(linkid, prop_name, prop_val,
665d62bc4baSyz147064 	    val_cnt, flags);
666d62bc4baSyz147064 	if (status != DLADM_STATUS_OK)
667d62bc4baSyz147064 		return (status);
668d62bc4baSyz147064 
669d62bc4baSyz147064 	if (flags & DLADM_OPT_PERSIST) {
670d62bc4baSyz147064 		status = i_dladm_set_linkprop_db(linkid, prop_name,
671d62bc4baSyz147064 		    prop_val, val_cnt);
672d62bc4baSyz147064 	}
673d62bc4baSyz147064 	return (status);
674d62bc4baSyz147064 }
675d62bc4baSyz147064 
676d62bc4baSyz147064 /*
677d62bc4baSyz147064  * Walk link properties of the given specific link.
678d62bc4baSyz147064  */
679d62bc4baSyz147064 dladm_status_t
680d62bc4baSyz147064 dladm_walk_linkprop(datalink_id_t linkid, void *arg,
681d62bc4baSyz147064     int (*func)(datalink_id_t, const char *, void *))
6820ba2cbe9Sxc151355 {
683d62bc4baSyz147064 	dladm_status_t		status;
684d62bc4baSyz147064 	datalink_class_t	class;
685d62bc4baSyz147064 	uint_t			media;
686d62bc4baSyz147064 	int			i;
6870ba2cbe9Sxc151355 
688d62bc4baSyz147064 	if (linkid == DATALINK_INVALID_LINKID || func == NULL)
689d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
6900ba2cbe9Sxc151355 
691d62bc4baSyz147064 	status = dladm_datalink_id2info(linkid, NULL, &class, &media, NULL, 0);
692d62bc4baSyz147064 	if (status != DLADM_STATUS_OK)
693d62bc4baSyz147064 		return (status);
694d62bc4baSyz147064 
695d62bc4baSyz147064 	for (i = 0; i < DLADM_MAX_PROPS; i++) {
696d62bc4baSyz147064 		if (!(prop_table[i].pd_class & class))
697d62bc4baSyz147064 			continue;
698d62bc4baSyz147064 
699d62bc4baSyz147064 		if (!DATALINK_MEDIA_ACCEPTED(prop_table[i].pd_dmedia, media))
700d62bc4baSyz147064 			continue;
701d62bc4baSyz147064 
702d62bc4baSyz147064 		if (func(linkid, prop_table[i].pd_name, arg) ==
703d62bc4baSyz147064 		    DLADM_WALK_TERMINATE) {
704d62bc4baSyz147064 			break;
705d62bc4baSyz147064 		}
706d62bc4baSyz147064 	}
707d62bc4baSyz147064 
708d62bc4baSyz147064 	return (DLADM_STATUS_OK);
709d62bc4baSyz147064 }
710d62bc4baSyz147064 
711d62bc4baSyz147064 /*
712d62bc4baSyz147064  * Get linkprop of the given specific link.
713d62bc4baSyz147064  */
714d62bc4baSyz147064 dladm_status_t
715d62bc4baSyz147064 dladm_get_linkprop(datalink_id_t linkid, dladm_prop_type_t type,
716d62bc4baSyz147064     const char *prop_name, char **prop_val, uint_t *val_cntp)
717d62bc4baSyz147064 {
718d62bc4baSyz147064 	dladm_status_t		status = DLADM_STATUS_OK;
719d62bc4baSyz147064 	datalink_class_t	class;
720d62bc4baSyz147064 	uint_t			media;
721d62bc4baSyz147064 	prop_desc_t		*pdp;
7224045d941Ssowmini 	uint_t			cnt, dld_flags = 0;
723d62bc4baSyz147064 	int			i;
724*afdda45fSVasumathi Sundaram - Sun Microsystems 	uint_t			perm_flags;
725d62bc4baSyz147064 
7264045d941Ssowmini 	if (type == DLADM_PROP_VAL_DEFAULT)
7273fd94f8cSam223141 		dld_flags = MAC_PROP_DEFAULT;
7284045d941Ssowmini 
729d62bc4baSyz147064 	if (linkid == DATALINK_INVALID_LINKID || prop_name == NULL ||
730d62bc4baSyz147064 	    prop_val == NULL || val_cntp == NULL || *val_cntp == 0)
731d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
732d62bc4baSyz147064 
733d62bc4baSyz147064 	for (i = 0; i < DLADM_MAX_PROPS; i++)
734d62bc4baSyz147064 		if (strcasecmp(prop_name, prop_table[i].pd_name) == 0)
735d62bc4baSyz147064 			break;
736d62bc4baSyz147064 
737e7801d59Ssowmini 	if (i == DLADM_MAX_PROPS) {
738e7801d59Ssowmini 		if (prop_name[0] == '_') {
739e7801d59Ssowmini 			/*
740e7801d59Ssowmini 			 * private property.
741e7801d59Ssowmini 			 */
7423bc21d0aSAruna Ramakrishna - Sun Microsystems 			return (i_dladm_get_prop(linkid, prop_name,
7434045d941Ssowmini 			    prop_val, val_cntp, type, dld_flags));
744e7801d59Ssowmini 		} else {
745d62bc4baSyz147064 			return (DLADM_STATUS_NOTFOUND);
746e7801d59Ssowmini 		}
747e7801d59Ssowmini 	}
748d62bc4baSyz147064 
749d62bc4baSyz147064 	pdp = &prop_table[i];
750d62bc4baSyz147064 
751d62bc4baSyz147064 	status = dladm_datalink_id2info(linkid, NULL, &class, &media, NULL, 0);
752d62bc4baSyz147064 	if (status != DLADM_STATUS_OK)
753d62bc4baSyz147064 		return (status);
754d62bc4baSyz147064 
755d62bc4baSyz147064 	if (!(pdp->pd_class & class))
756d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
757d62bc4baSyz147064 
758d62bc4baSyz147064 	if (!DATALINK_MEDIA_ACCEPTED(pdp->pd_dmedia, media))
759d62bc4baSyz147064 		return (DLADM_STATUS_BADARG);
760d62bc4baSyz147064 
761d62bc4baSyz147064 	switch (type) {
762d62bc4baSyz147064 	case DLADM_PROP_VAL_CURRENT:
7634045d941Ssowmini 		status = pdp->pd_get(pdp, linkid, prop_val, val_cntp, media,
764*afdda45fSVasumathi Sundaram - Sun Microsystems 		    dld_flags, &perm_flags);
765*afdda45fSVasumathi Sundaram - Sun Microsystems 		break;
766*afdda45fSVasumathi Sundaram - Sun Microsystems 
767*afdda45fSVasumathi Sundaram - Sun Microsystems 	case DLADM_PROP_VAL_PERM:
768*afdda45fSVasumathi Sundaram - Sun Microsystems 		if (pdp->pd_set == NULL) {
769*afdda45fSVasumathi Sundaram - Sun Microsystems 			perm_flags = MAC_PROP_PERM_READ;
770*afdda45fSVasumathi Sundaram - Sun Microsystems 			*val_cntp = 1;
771*afdda45fSVasumathi Sundaram - Sun Microsystems 		} else {
772*afdda45fSVasumathi Sundaram - Sun Microsystems 			status = pdp->pd_get(pdp, linkid, prop_val, val_cntp,
773*afdda45fSVasumathi Sundaram - Sun Microsystems 			    media, dld_flags, &perm_flags);
774*afdda45fSVasumathi Sundaram - Sun Microsystems 		}
775*afdda45fSVasumathi Sundaram - Sun Microsystems 
776*afdda45fSVasumathi Sundaram - Sun Microsystems 		*prop_val[0] = '\0';
777*afdda45fSVasumathi Sundaram - Sun Microsystems 		switch (perm_flags) {
778*afdda45fSVasumathi Sundaram - Sun Microsystems 			case MAC_PROP_PERM_READ:
779*afdda45fSVasumathi Sundaram - Sun Microsystems 				(void) strncpy(*prop_val, PERM_READ_ONLY,
780*afdda45fSVasumathi Sundaram - Sun Microsystems 				    DLADM_PROP_VAL_MAX);
781*afdda45fSVasumathi Sundaram - Sun Microsystems 				break;
782*afdda45fSVasumathi Sundaram - Sun Microsystems 			case MAC_PROP_PERM_RW:
783*afdda45fSVasumathi Sundaram - Sun Microsystems 				(void) strncpy(*prop_val, PERM_READ_WRITE,
784*afdda45fSVasumathi Sundaram - Sun Microsystems 				    DLADM_PROP_VAL_MAX);
785*afdda45fSVasumathi Sundaram - Sun Microsystems 				break;
786*afdda45fSVasumathi Sundaram - Sun Microsystems 		}
787d62bc4baSyz147064 		break;
788d62bc4baSyz147064 
789d62bc4baSyz147064 	case DLADM_PROP_VAL_DEFAULT:
79013a55820Sar224390 		/*
79113a55820Sar224390 		 * If defaults are not defined for the property,
79213a55820Sar224390 		 * pd_defval.vd_name should be null. If the driver
79313a55820Sar224390 		 * has to be contacted for the value, vd_name should
79413a55820Sar224390 		 * be the empty string (""). Otherwise, dladm will
79513a55820Sar224390 		 * just print whatever is in the table.
79613a55820Sar224390 		 */
797d62bc4baSyz147064 		if (pdp->pd_defval.vd_name == NULL) {
798d62bc4baSyz147064 			status = DLADM_STATUS_NOTSUP;
799d62bc4baSyz147064 			break;
800d62bc4baSyz147064 		}
8014045d941Ssowmini 
8024045d941Ssowmini 		if (strlen(pdp->pd_defval.vd_name) == 0) {
8034045d941Ssowmini 			status = pdp->pd_get(pdp, linkid, prop_val, val_cntp,
804*afdda45fSVasumathi Sundaram - Sun Microsystems 			    media, dld_flags, &perm_flags);
8054045d941Ssowmini 		} else {
806d62bc4baSyz147064 			(void) strcpy(*prop_val, pdp->pd_defval.vd_name);
8074045d941Ssowmini 		}
808d62bc4baSyz147064 		*val_cntp = 1;
809d62bc4baSyz147064 		break;
810d62bc4baSyz147064 
811d62bc4baSyz147064 	case DLADM_PROP_VAL_MODIFIABLE:
812d62bc4baSyz147064 		if (pdp->pd_getmod != NULL) {
813e7801d59Ssowmini 			status = pdp->pd_getmod(pdp, linkid, prop_val,
814*afdda45fSVasumathi Sundaram - Sun Microsystems 			    val_cntp, media, dld_flags, &perm_flags);
815d62bc4baSyz147064 			break;
816d62bc4baSyz147064 		}
817d62bc4baSyz147064 		cnt = pdp->pd_noptval;
818d62bc4baSyz147064 		if (cnt == 0) {
819d62bc4baSyz147064 			status = DLADM_STATUS_NOTSUP;
820d62bc4baSyz147064 		} else if (cnt > *val_cntp) {
821d62bc4baSyz147064 			status = DLADM_STATUS_TOOSMALL;
822d62bc4baSyz147064 		} else {
823d62bc4baSyz147064 			for (i = 0; i < cnt; i++) {
824d62bc4baSyz147064 				(void) strcpy(prop_val[i],
825d62bc4baSyz147064 				    pdp->pd_optval[i].vd_name);
826d62bc4baSyz147064 			}
827d62bc4baSyz147064 			*val_cntp = cnt;
828d62bc4baSyz147064 		}
829d62bc4baSyz147064 		break;
830d62bc4baSyz147064 	case DLADM_PROP_VAL_PERSISTENT:
831d62bc4baSyz147064 		if (pdp->pd_flags & PD_TEMPONLY)
832d62bc4baSyz147064 			return (DLADM_STATUS_TEMPONLY);
833d62bc4baSyz147064 		status = i_dladm_get_linkprop_db(linkid, prop_name,
834d62bc4baSyz147064 		    prop_val, val_cntp);
835d62bc4baSyz147064 		break;
836d62bc4baSyz147064 	default:
837d62bc4baSyz147064 		status = DLADM_STATUS_BADARG;
838d62bc4baSyz147064 		break;
839d62bc4baSyz147064 	}
840d62bc4baSyz147064 
841d62bc4baSyz147064 	return (status);
842d62bc4baSyz147064 }
843d62bc4baSyz147064 
844d62bc4baSyz147064 /*ARGSUSED*/
845d62bc4baSyz147064 static int
846d62bc4baSyz147064 i_dladm_init_one_prop(datalink_id_t linkid, const char *prop_name, void *arg)
847d62bc4baSyz147064 {
848d62bc4baSyz147064 	char	*buf, **propvals;
849d62bc4baSyz147064 	uint_t	i, valcnt = DLADM_MAX_PROP_VALCNT;
850d62bc4baSyz147064 
851d62bc4baSyz147064 	if ((buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) *
852d62bc4baSyz147064 	    DLADM_MAX_PROP_VALCNT)) == NULL) {
853d62bc4baSyz147064 		return (DLADM_WALK_CONTINUE);
854d62bc4baSyz147064 	}
855d62bc4baSyz147064 
856d62bc4baSyz147064 	propvals = (char **)(void *)buf;
857d62bc4baSyz147064 	for (i = 0; i < valcnt; i++) {
858d62bc4baSyz147064 		propvals[i] = buf +
859d62bc4baSyz147064 		    sizeof (char *) * DLADM_MAX_PROP_VALCNT +
860d62bc4baSyz147064 		    i * DLADM_PROP_VAL_MAX;
861d62bc4baSyz147064 	}
862d62bc4baSyz147064 
863d62bc4baSyz147064 	if (dladm_get_linkprop(linkid, DLADM_PROP_VAL_PERSISTENT, prop_name,
864d62bc4baSyz147064 	    propvals, &valcnt) != DLADM_STATUS_OK) {
865d62bc4baSyz147064 		goto done;
866d62bc4baSyz147064 	}
867d62bc4baSyz147064 
868d62bc4baSyz147064 	(void) dladm_set_linkprop(linkid, prop_name, propvals, valcnt,
869d62bc4baSyz147064 	    DLADM_OPT_ACTIVE);
870d62bc4baSyz147064 
871d62bc4baSyz147064 done:
872d62bc4baSyz147064 	if (buf != NULL)
873d62bc4baSyz147064 		free(buf);
874d62bc4baSyz147064 
875d62bc4baSyz147064 	return (DLADM_WALK_CONTINUE);
876d62bc4baSyz147064 }
877d62bc4baSyz147064 
878d62bc4baSyz147064 /*ARGSUSED*/
879d62bc4baSyz147064 static int
880d62bc4baSyz147064 i_dladm_init_linkprop(datalink_id_t linkid, void *arg)
881d62bc4baSyz147064 {
88230890389Sartem 	(void) dladm_init_linkprop(linkid, B_TRUE);
883d62bc4baSyz147064 	return (DLADM_WALK_CONTINUE);
8840ba2cbe9Sxc151355 }
8850ba2cbe9Sxc151355 
8860ba2cbe9Sxc151355 dladm_status_t
88730890389Sartem dladm_init_linkprop(datalink_id_t linkid, boolean_t any_media)
8880ba2cbe9Sxc151355 {
88930890389Sartem 	datalink_media_t	dmedia;
89030890389Sartem 	uint32_t		media;
89130890389Sartem 
89230890389Sartem 	dmedia = any_media ? DATALINK_ANY_MEDIATYPE : DL_WIFI;
89330890389Sartem 
894d62bc4baSyz147064 	if (linkid == DATALINK_ALL_LINKID) {
895d62bc4baSyz147064 		(void) dladm_walk_datalink_id(i_dladm_init_linkprop, NULL,
89630890389Sartem 		    DATALINK_CLASS_ALL, dmedia, DLADM_OPT_PERSIST);
89730890389Sartem 	} else if (any_media || ((dladm_datalink_id2info(linkid, NULL, NULL,
89830890389Sartem 	    &media, NULL, 0) == DLADM_STATUS_OK) &&
89930890389Sartem 	    DATALINK_MEDIA_ACCEPTED(dmedia, media))) {
900d62bc4baSyz147064 		(void) dladm_walk_linkprop(linkid, NULL, i_dladm_init_one_prop);
901d62bc4baSyz147064 	}
902d62bc4baSyz147064 	return (DLADM_STATUS_OK);
9030ba2cbe9Sxc151355 }
904f4b3ec61Sdh155122 
905e7801d59Ssowmini /* ARGSUSED */
906f4b3ec61Sdh155122 static dladm_status_t
907e7801d59Ssowmini do_get_zone(struct prop_desc *pd, datalink_id_t linkid,
908*afdda45fSVasumathi Sundaram - Sun Microsystems     char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags,
909*afdda45fSVasumathi Sundaram - Sun Microsystems     uint_t *perm_flags)
910f4b3ec61Sdh155122 {
911d62bc4baSyz147064 	char		zone_name[ZONENAME_MAX];
912d62bc4baSyz147064 	zoneid_t	zid;
913d62bc4baSyz147064 	dladm_status_t	status;
9143bc21d0aSAruna Ramakrishna - Sun Microsystems 	char		*cp;
9153bc21d0aSAruna Ramakrishna - Sun Microsystems 	dld_ioc_macprop_t	*dip;
916f4b3ec61Sdh155122 
9174045d941Ssowmini 	if (flags != 0)
9184045d941Ssowmini 		return (DLADM_STATUS_NOTSUP);
9194045d941Ssowmini 
9203bc21d0aSAruna Ramakrishna - Sun Microsystems 	dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status);
921d62bc4baSyz147064 	if (status != DLADM_STATUS_OK)
922d62bc4baSyz147064 		return (status);
923d62bc4baSyz147064 
924*afdda45fSVasumathi Sundaram - Sun Microsystems 	*perm_flags = dip->pr_perm_flags;
9253bc21d0aSAruna Ramakrishna - Sun Microsystems 	cp = dip->pr_val;
9263bc21d0aSAruna Ramakrishna - Sun Microsystems 	(void) memcpy(&zid, cp, sizeof (zid));
9273bc21d0aSAruna Ramakrishna - Sun Microsystems 	free(dip);
9283bc21d0aSAruna Ramakrishna - Sun Microsystems 
929d62bc4baSyz147064 	*val_cnt = 1;
930d62bc4baSyz147064 	if (zid != GLOBAL_ZONEID) {
931*afdda45fSVasumathi Sundaram - Sun Microsystems 		if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0) {
932*afdda45fSVasumathi Sundaram - Sun Microsystems 			*perm_flags = 0;
933f4b3ec61Sdh155122 			return (dladm_errno2status(errno));
934*afdda45fSVasumathi Sundaram - Sun Microsystems 		}
935f4b3ec61Sdh155122 
936d62bc4baSyz147064 		(void) strncpy(*prop_val, zone_name, DLADM_PROP_VAL_MAX);
93747a01978Sbw 	} else {
938d62bc4baSyz147064 		*prop_val[0] = '\0';
939*afdda45fSVasumathi Sundaram - Sun Microsystems 		*perm_flags = 0;
94047a01978Sbw 	}
941f4b3ec61Sdh155122 
942f4b3ec61Sdh155122 	return (DLADM_STATUS_OK);
943f4b3ec61Sdh155122 }
944f4b3ec61Sdh155122 
945f4b3ec61Sdh155122 typedef int (*zone_get_devroot_t)(char *, char *, size_t);
946f4b3ec61Sdh155122 
947f4b3ec61Sdh155122 static int
948f4b3ec61Sdh155122 i_dladm_get_zone_dev(char *zone_name, char *dev, size_t devlen)
949f4b3ec61Sdh155122 {
950f4b3ec61Sdh155122 	char			root[MAXPATHLEN];
951f4b3ec61Sdh155122 	zone_get_devroot_t	real_zone_get_devroot;
952f4b3ec61Sdh155122 	void			*dlhandle;
953f4b3ec61Sdh155122 	void			*sym;
954f4b3ec61Sdh155122 	int			ret;
955f4b3ec61Sdh155122 
956f4b3ec61Sdh155122 	if ((dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY)) == NULL)
957f4b3ec61Sdh155122 		return (-1);
958f4b3ec61Sdh155122 
959f4b3ec61Sdh155122 	if ((sym = dlsym(dlhandle, "zone_get_devroot")) == NULL) {
960f4b3ec61Sdh155122 		(void) dlclose(dlhandle);
961f4b3ec61Sdh155122 		return (-1);
962f4b3ec61Sdh155122 	}
963f4b3ec61Sdh155122 
964f4b3ec61Sdh155122 	real_zone_get_devroot = (zone_get_devroot_t)sym;
965f4b3ec61Sdh155122 
966f4b3ec61Sdh155122 	if ((ret = real_zone_get_devroot(zone_name, root, sizeof (root))) == 0)
967f4b3ec61Sdh155122 		(void) snprintf(dev, devlen, "%s%s", root, "/dev");
968f4b3ec61Sdh155122 	(void) dlclose(dlhandle);
969f4b3ec61Sdh155122 	return (ret);
970f4b3ec61Sdh155122 }
971f4b3ec61Sdh155122 
972f4b3ec61Sdh155122 static dladm_status_t
973d62bc4baSyz147064 i_dladm_update_deventry(zoneid_t zid, datalink_id_t linkid, boolean_t add)
974f4b3ec61Sdh155122 {
975f4b3ec61Sdh155122 	char		path[MAXPATHLEN];
976d62bc4baSyz147064 	char		name[MAXLINKNAMELEN];
977f4b3ec61Sdh155122 	di_prof_t	prof = NULL;
978f4b3ec61Sdh155122 	char		zone_name[ZONENAME_MAX];
979f4b3ec61Sdh155122 	dladm_status_t	status;
980d62bc4baSyz147064 	int		ret;
981f4b3ec61Sdh155122 
982f4b3ec61Sdh155122 	if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0)
983f4b3ec61Sdh155122 		return (dladm_errno2status(errno));
984f4b3ec61Sdh155122 	if (i_dladm_get_zone_dev(zone_name, path, sizeof (path)) != 0)
985f4b3ec61Sdh155122 		return (dladm_errno2status(errno));
986f4b3ec61Sdh155122 	if (di_prof_init(path, &prof) != 0)
987f4b3ec61Sdh155122 		return (dladm_errno2status(errno));
988f4b3ec61Sdh155122 
989d62bc4baSyz147064 	status = dladm_linkid2legacyname(linkid, name, MAXLINKNAMELEN);
990f4b3ec61Sdh155122 	if (status != DLADM_STATUS_OK)
991d62bc4baSyz147064 		goto cleanup;
992f4b3ec61Sdh155122 
993d62bc4baSyz147064 	if (add)
994d62bc4baSyz147064 		ret = di_prof_add_dev(prof, name);
995d62bc4baSyz147064 	else
996d62bc4baSyz147064 		ret = di_prof_add_exclude(prof, name);
997f4b3ec61Sdh155122 
998d62bc4baSyz147064 	if (ret != 0) {
999d62bc4baSyz147064 		status = dladm_errno2status(errno);
1000d62bc4baSyz147064 		goto cleanup;
1001f4b3ec61Sdh155122 	}
1002f4b3ec61Sdh155122 
1003d62bc4baSyz147064 	if (di_prof_commit(prof) != 0)
1004d62bc4baSyz147064 		status = dladm_errno2status(errno);
1005d62bc4baSyz147064 cleanup:
1006d62bc4baSyz147064 	if (prof)
1007d62bc4baSyz147064 		di_prof_fini(prof);
1008d62bc4baSyz147064 
1009d62bc4baSyz147064 	return (status);
1010f4b3ec61Sdh155122 }
1011f4b3ec61Sdh155122 
1012e7801d59Ssowmini /* ARGSUSED */
1013f4b3ec61Sdh155122 static dladm_status_t
10146b9e797cSsowmini do_set_zone(prop_desc_t *pd, datalink_id_t linkid, val_desc_t *vdp,
10156b9e797cSsowmini     uint_t val_cnt, uint_t flags, datalink_media_t media)
1016f4b3ec61Sdh155122 {
10173bc21d0aSAruna Ramakrishna - Sun Microsystems 	dladm_status_t	status = DLADM_STATUS_OK;
1018f4b3ec61Sdh155122 	zoneid_t	zid_old, zid_new;
1019d62bc4baSyz147064 	char		link[MAXLINKNAMELEN];
10203bc21d0aSAruna Ramakrishna - Sun Microsystems 	char		*cp;
10213bc21d0aSAruna Ramakrishna - Sun Microsystems 	dld_ioc_macprop_t	*dip;
10223bc21d0aSAruna Ramakrishna - Sun Microsystems 	dld_ioc_zid_t		*dzp;
1023f4b3ec61Sdh155122 
1024f4b3ec61Sdh155122 	if (val_cnt != 1)
1025f4b3ec61Sdh155122 		return (DLADM_STATUS_BADVALCNT);
1026f4b3ec61Sdh155122 
10273bc21d0aSAruna Ramakrishna - Sun Microsystems 	dzp = (dld_ioc_zid_t *)vdp->vd_val;
10283bc21d0aSAruna Ramakrishna - Sun Microsystems 
10293bc21d0aSAruna Ramakrishna - Sun Microsystems 	/*
10303bc21d0aSAruna Ramakrishna - Sun Microsystems 	 * If diz_is_ppa_hack is set, then an implicit vlan must be created.
10313bc21d0aSAruna Ramakrishna - Sun Microsystems 	 * There is no old value to compare against, and vdp->vd_val is
10323bc21d0aSAruna Ramakrishna - Sun Microsystems 	 * already populated with the zoneid and linkname in the function
10333bc21d0aSAruna Ramakrishna - Sun Microsystems 	 * do_check_zone().
10343bc21d0aSAruna Ramakrishna - Sun Microsystems 	 */
10353bc21d0aSAruna Ramakrishna - Sun Microsystems 
10363bc21d0aSAruna Ramakrishna - Sun Microsystems 	if (dzp->diz_is_ppa_hack) {
10373bc21d0aSAruna Ramakrishna - Sun Microsystems 		zid_old = GLOBAL_ZONEID;
10383bc21d0aSAruna Ramakrishna - Sun Microsystems 	} else {
10393bc21d0aSAruna Ramakrishna - Sun Microsystems 		dip = i_dladm_get_public_prop(linkid, pd->pd_name,
10403bc21d0aSAruna Ramakrishna - Sun Microsystems 		    flags, &status);
1041f4b3ec61Sdh155122 		if (status != DLADM_STATUS_OK)
1042f4b3ec61Sdh155122 			return (status);
1043f4b3ec61Sdh155122 
10443bc21d0aSAruna Ramakrishna - Sun Microsystems 		cp = dip->pr_val;
10453bc21d0aSAruna Ramakrishna - Sun Microsystems 		(void) memcpy(&zid_old, cp, sizeof (zid_old));
10463bc21d0aSAruna Ramakrishna - Sun Microsystems 		free(dip);
1047d62bc4baSyz147064 	}
1048f4b3ec61Sdh155122 
10493bc21d0aSAruna Ramakrishna - Sun Microsystems 	zid_new = dzp->diz_zid;
10503bc21d0aSAruna Ramakrishna - Sun Microsystems 	(void) strlcpy(link, dzp->diz_link, MAXLINKNAMELEN);
10513bc21d0aSAruna Ramakrishna - Sun Microsystems 
10523bc21d0aSAruna Ramakrishna - Sun Microsystems 	/* Do nothing if setting to current value */
10533bc21d0aSAruna Ramakrishna - Sun Microsystems 	if (zid_new == zid_old)
10543bc21d0aSAruna Ramakrishna - Sun Microsystems 		return (status);
10553bc21d0aSAruna Ramakrishna - Sun Microsystems 
1056d62bc4baSyz147064 	if (zid_new != GLOBAL_ZONEID) {
1057d62bc4baSyz147064 		/*
1058d62bc4baSyz147064 		 * If the new zoneid is the global zone, we could destroy
1059d62bc4baSyz147064 		 * the link (in the case of an implicitly-created VLAN) as a
10603bc21d0aSAruna Ramakrishna - Sun Microsystems 		 * result of setting the zoneid. In that case, we defer the
10613bc21d0aSAruna Ramakrishna - Sun Microsystems 		 * operation to the end of this function to avoid recreating
10623bc21d0aSAruna Ramakrishna - Sun Microsystems 		 * the VLAN and getting a different linkid during the rollback
10633bc21d0aSAruna Ramakrishna - Sun Microsystems 		 * if other operation fails.
1064d62bc4baSyz147064 		 *
10653bc21d0aSAruna Ramakrishna - Sun Microsystems 		 * Otherwise, this operation will hold a reference to the
1066d62bc4baSyz147064 		 * link and prevent a link renaming, so we need to do it
1067d62bc4baSyz147064 		 * before other operations.
1068d62bc4baSyz147064 		 */
10693bc21d0aSAruna Ramakrishna - Sun Microsystems 		status = i_dladm_set_public_prop(pd, linkid, vdp, val_cnt,
10703bc21d0aSAruna Ramakrishna - Sun Microsystems 		    flags, media);
1071d62bc4baSyz147064 		if (status != DLADM_STATUS_OK)
1072d62bc4baSyz147064 			return (status);
1073d62bc4baSyz147064 	}
1074d62bc4baSyz147064 
1075d62bc4baSyz147064 	if (zid_old != GLOBAL_ZONEID) {
1076d62bc4baSyz147064 		if (zone_remove_datalink(zid_old, link) != 0 &&
1077f4b3ec61Sdh155122 		    errno != ENXIO) {
1078f4b3ec61Sdh155122 			status = dladm_errno2status(errno);
1079f4b3ec61Sdh155122 			goto rollback1;
1080f4b3ec61Sdh155122 		}
1081f4b3ec61Sdh155122 
1082d62bc4baSyz147064 		/*
1083d62bc4baSyz147064 		 * It is okay to fail to update the /dev entry (some
1084d62bc4baSyz147064 		 * vanity-named links do not have a /dev entry).
1085d62bc4baSyz147064 		 */
1086d62bc4baSyz147064 		(void) i_dladm_update_deventry(zid_old, linkid, B_FALSE);
1087d62bc4baSyz147064 	}
1088d62bc4baSyz147064 
1089d62bc4baSyz147064 	if (zid_new != GLOBAL_ZONEID) {
1090d62bc4baSyz147064 		if (zone_add_datalink(zid_new, link) != 0) {
1091d62bc4baSyz147064 			status = dladm_errno2status(errno);
1092d62bc4baSyz147064 			goto rollback2;
1093d62bc4baSyz147064 		}
1094d62bc4baSyz147064 
10953bc21d0aSAruna Ramakrishna - Sun Microsystems 		if (dzp->diz_is_ppa_hack) {
10963bc21d0aSAruna Ramakrishna - Sun Microsystems 			if ((status = dladm_name2info(link, &linkid, NULL, NULL,
10973bc21d0aSAruna Ramakrishna - Sun Microsystems 			    NULL)) != DLADM_STATUS_OK) {
10983bc21d0aSAruna Ramakrishna - Sun Microsystems 				return (status);
10993bc21d0aSAruna Ramakrishna - Sun Microsystems 			}
11003bc21d0aSAruna Ramakrishna - Sun Microsystems 		}
11013bc21d0aSAruna Ramakrishna - Sun Microsystems 
1102d62bc4baSyz147064 		(void) i_dladm_update_deventry(zid_new, linkid, B_TRUE);
1103d62bc4baSyz147064 	} else {
11043bc21d0aSAruna Ramakrishna - Sun Microsystems 		status = i_dladm_set_public_prop(pd, linkid, vdp, val_cnt,
11053bc21d0aSAruna Ramakrishna - Sun Microsystems 		    flags, media);
1106f4b3ec61Sdh155122 		if (status != DLADM_STATUS_OK)
1107f4b3ec61Sdh155122 			goto rollback2;
1108f4b3ec61Sdh155122 	}
1109f4b3ec61Sdh155122 
1110f4b3ec61Sdh155122 	return (DLADM_STATUS_OK);
1111f4b3ec61Sdh155122 
1112f4b3ec61Sdh155122 rollback2:
1113f4b3ec61Sdh155122 	if (zid_old != GLOBAL_ZONEID)
1114d62bc4baSyz147064 		(void) i_dladm_update_deventry(zid_old, linkid, B_TRUE);
1115d62bc4baSyz147064 	if (zid_old != GLOBAL_ZONEID)
1116d62bc4baSyz147064 		(void) zone_add_datalink(zid_old, link);
1117f4b3ec61Sdh155122 rollback1:
11183bc21d0aSAruna Ramakrishna - Sun Microsystems 	if (zid_new != GLOBAL_ZONEID) {
11193bc21d0aSAruna Ramakrishna - Sun Microsystems 		dzp->diz_zid = zid_old;
11203bc21d0aSAruna Ramakrishna - Sun Microsystems 		(void) i_dladm_set_public_prop(pd, linkid, vdp, val_cnt,
11213bc21d0aSAruna Ramakrishna - Sun Microsystems 		    flags, media);
11223bc21d0aSAruna Ramakrishna - Sun Microsystems 	}
11233bc21d0aSAruna Ramakrishna - Sun Microsystems 
1124f4b3ec61Sdh155122 	return (status);
1125f4b3ec61Sdh155122 }
1126f4b3ec61Sdh155122 
1127f4b3ec61Sdh155122 /* ARGSUSED */
1128f4b3ec61Sdh155122 static dladm_status_t
1129e7801d59Ssowmini do_check_zone(struct prop_desc *pd, datalink_id_t linkid, char **prop_val,
11306b9e797cSsowmini     uint_t val_cnt, val_desc_t *vdp, datalink_media_t media)
1131f4b3ec61Sdh155122 {
11323bc21d0aSAruna Ramakrishna - Sun Microsystems 	char		*zone_name;
11333bc21d0aSAruna Ramakrishna - Sun Microsystems 	char		linkname[MAXLINKNAMELEN];
11343bc21d0aSAruna Ramakrishna - Sun Microsystems 	zoneid_t	zoneid;
11353bc21d0aSAruna Ramakrishna - Sun Microsystems 	char		*cp;
11363bc21d0aSAruna Ramakrishna - Sun Microsystems 	dladm_status_t	status = DLADM_STATUS_OK;
11373bc21d0aSAruna Ramakrishna - Sun Microsystems 	boolean_t	is_ppa_hack = B_FALSE;
11383bc21d0aSAruna Ramakrishna - Sun Microsystems 	dld_ioc_zid_t	*dzp;
1139f4b3ec61Sdh155122 
1140f4b3ec61Sdh155122 	if (val_cnt != 1)
1141f4b3ec61Sdh155122 		return (DLADM_STATUS_BADVALCNT);
1142f4b3ec61Sdh155122 
11433bc21d0aSAruna Ramakrishna - Sun Microsystems 	dzp = malloc(sizeof (dld_ioc_zid_t));
11443bc21d0aSAruna Ramakrishna - Sun Microsystems 	if (dzp == NULL)
11453bc21d0aSAruna Ramakrishna - Sun Microsystems 		return (DLADM_STATUS_NOMEM);
1146f4b3ec61Sdh155122 
11473bc21d0aSAruna Ramakrishna - Sun Microsystems 	if (prop_val) {
11483bc21d0aSAruna Ramakrishna - Sun Microsystems 		/*
11493bc21d0aSAruna Ramakrishna - Sun Microsystems 		 * The prop_val contains zone_name{:linkname}. The linkname is
11503bc21d0aSAruna Ramakrishna - Sun Microsystems 		 * present only when the link is a ppa-hacked vlan.
11513bc21d0aSAruna Ramakrishna - Sun Microsystems 		 */
11523bc21d0aSAruna Ramakrishna - Sun Microsystems 		cp = strchr(*prop_val, ':');
11533bc21d0aSAruna Ramakrishna - Sun Microsystems 		if (cp) {
11543bc21d0aSAruna Ramakrishna - Sun Microsystems 			(void) strlcpy(linkname, cp + 1, MAXLINKNAMELEN);
11553bc21d0aSAruna Ramakrishna - Sun Microsystems 			*cp = '\0';
11563bc21d0aSAruna Ramakrishna - Sun Microsystems 			is_ppa_hack = B_TRUE;
11573bc21d0aSAruna Ramakrishna - Sun Microsystems 		} else {
11583bc21d0aSAruna Ramakrishna - Sun Microsystems 			status = dladm_datalink_id2info(linkid, NULL, NULL,
11593bc21d0aSAruna Ramakrishna - Sun Microsystems 			    NULL, linkname, MAXLINKNAMELEN);
11603bc21d0aSAruna Ramakrishna - Sun Microsystems 			if (status != DLADM_STATUS_OK) {
11613bc21d0aSAruna Ramakrishna - Sun Microsystems 				goto done;
11623bc21d0aSAruna Ramakrishna - Sun Microsystems 			}
11633bc21d0aSAruna Ramakrishna - Sun Microsystems 		}
11643bc21d0aSAruna Ramakrishna - Sun Microsystems 		zone_name = *prop_val;
11653bc21d0aSAruna Ramakrishna - Sun Microsystems 	} else {
11663bc21d0aSAruna Ramakrishna - Sun Microsystems 		zone_name = GLOBAL_ZONENAME;
11673bc21d0aSAruna Ramakrishna - Sun Microsystems 		if ((status = dladm_datalink_id2info(linkid, NULL, NULL, NULL,
11683bc21d0aSAruna Ramakrishna - Sun Microsystems 		    linkname, MAXLINKNAMELEN)) != DLADM_STATUS_OK) {
11693bc21d0aSAruna Ramakrishna - Sun Microsystems 			goto done;
11703bc21d0aSAruna Ramakrishna - Sun Microsystems 		}
11713bc21d0aSAruna Ramakrishna - Sun Microsystems 	}
11723bc21d0aSAruna Ramakrishna - Sun Microsystems 
11733bc21d0aSAruna Ramakrishna - Sun Microsystems 	if (strlen(linkname) > MAXLINKNAMELEN) {
11743bc21d0aSAruna Ramakrishna - Sun Microsystems 		status = DLADM_STATUS_BADVAL;
11753bc21d0aSAruna Ramakrishna - Sun Microsystems 		goto done;
11763bc21d0aSAruna Ramakrishna - Sun Microsystems 	}
11773bc21d0aSAruna Ramakrishna - Sun Microsystems 
11783bc21d0aSAruna Ramakrishna - Sun Microsystems 	if ((zoneid = getzoneidbyname(zone_name)) == -1) {
11793bc21d0aSAruna Ramakrishna - Sun Microsystems 		status = DLADM_STATUS_BADVAL;
11803bc21d0aSAruna Ramakrishna - Sun Microsystems 		goto done;
11813bc21d0aSAruna Ramakrishna - Sun Microsystems 	}
11823bc21d0aSAruna Ramakrishna - Sun Microsystems 
11833bc21d0aSAruna Ramakrishna - Sun Microsystems 	if (zoneid != GLOBAL_ZONEID) {
1184f4b3ec61Sdh155122 		ushort_t	flags;
1185f4b3ec61Sdh155122 
11863bc21d0aSAruna Ramakrishna - Sun Microsystems 		if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags,
1187f4b3ec61Sdh155122 		    sizeof (flags)) < 0) {
11883bc21d0aSAruna Ramakrishna - Sun Microsystems 			status = dladm_errno2status(errno);
11893bc21d0aSAruna Ramakrishna - Sun Microsystems 			goto done;
1190f4b3ec61Sdh155122 		}
1191f4b3ec61Sdh155122 
1192f4b3ec61Sdh155122 		if (!(flags & ZF_NET_EXCL)) {
11933bc21d0aSAruna Ramakrishna - Sun Microsystems 			status = DLADM_STATUS_BADVAL;
11943bc21d0aSAruna Ramakrishna - Sun Microsystems 			goto done;
1195f4b3ec61Sdh155122 		}
1196f4b3ec61Sdh155122 	}
1197f4b3ec61Sdh155122 
11983bc21d0aSAruna Ramakrishna - Sun Microsystems 	(void) memset(dzp, 0, sizeof (dld_ioc_zid_t));
11993bc21d0aSAruna Ramakrishna - Sun Microsystems 
12003bc21d0aSAruna Ramakrishna - Sun Microsystems 	dzp->diz_zid = zoneid;
12013bc21d0aSAruna Ramakrishna - Sun Microsystems 	(void) strlcpy(dzp->diz_link, linkname, MAXLINKNAMELEN);
12023bc21d0aSAruna Ramakrishna - Sun Microsystems 	dzp->diz_is_ppa_hack = is_ppa_hack;
12033bc21d0aSAruna Ramakrishna - Sun Microsystems 
12043bc21d0aSAruna Ramakrishna - Sun Microsystems 	vdp->vd_val = (uintptr_t)dzp;
1205f4b3ec61Sdh155122 	return (DLADM_STATUS_OK);
12063bc21d0aSAruna Ramakrishna - Sun Microsystems done:
12073bc21d0aSAruna Ramakrishna - Sun Microsystems 	free(dzp);
12083bc21d0aSAruna Ramakrishna - Sun Microsystems 	return (status);
1209f4b3ec61Sdh155122 }
1210f4b3ec61Sdh155122 
1211e7801d59Ssowmini /* ARGSUSED */
1212f4b3ec61Sdh155122 static dladm_status_t
1213e7801d59Ssowmini do_get_autopush(struct prop_desc *pd, datalink_id_t linkid,
1214*afdda45fSVasumathi Sundaram - Sun Microsystems     char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags,
1215*afdda45fSVasumathi Sundaram - Sun Microsystems     uint_t *perm_flags)
1216d62bc4baSyz147064 {
12173bc21d0aSAruna Ramakrishna - Sun Microsystems 	struct		dlautopush dlap;
12183bc21d0aSAruna Ramakrishna - Sun Microsystems 	int		i, len;
12193bc21d0aSAruna Ramakrishna - Sun Microsystems 	dladm_status_t	status;
12203bc21d0aSAruna Ramakrishna - Sun Microsystems 	dld_ioc_macprop_t	*dip;
1221d62bc4baSyz147064 
12223fd94f8cSam223141 	if (flags & MAC_PROP_DEFAULT)
1223149b7eb2SSowmini Varadhan 		return (DLADM_STATUS_NOTDEFINED);
12244045d941Ssowmini 
1225d62bc4baSyz147064 	*val_cnt = 1;
12263bc21d0aSAruna Ramakrishna - Sun Microsystems 	dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status);
12273bc21d0aSAruna Ramakrishna - Sun Microsystems 	if (dip == NULL) {
1228d62bc4baSyz147064 		(*prop_val)[0] = '\0';
1229d62bc4baSyz147064 		goto done;
1230d62bc4baSyz147064 	}
12313bc21d0aSAruna Ramakrishna - Sun Microsystems 	(void) memcpy(&dlap, dip->pr_val, sizeof (dlap));
1232d62bc4baSyz147064 
12333bc21d0aSAruna Ramakrishna - Sun Microsystems 	for (i = 0, len = 0; i < dlap.dap_npush; i++) {
1234d62bc4baSyz147064 		if (i != 0) {
1235d62bc4baSyz147064 			(void) snprintf(*prop_val + len,
1236d62bc4baSyz147064 			    DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER);
1237d62bc4baSyz147064 			len += 1;
1238d62bc4baSyz147064 		}
1239d62bc4baSyz147064 		(void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len,
12403bc21d0aSAruna Ramakrishna - Sun Microsystems 		    "%s", dlap.dap_aplist[i]);
12413bc21d0aSAruna Ramakrishna - Sun Microsystems 		len += strlen(dlap.dap_aplist[i]);
12423bc21d0aSAruna Ramakrishna - Sun Microsystems 		if (dlap.dap_anchor - 1 == i) {
1243d62bc4baSyz147064 			(void) snprintf(*prop_val + len,
1244d62bc4baSyz147064 			    DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER,
1245d62bc4baSyz147064 			    AP_ANCHOR);
1246d62bc4baSyz147064 			len += (strlen(AP_ANCHOR) + 1);
1247d62bc4baSyz147064 		}
1248d62bc4baSyz147064 	}
1249d62bc4baSyz147064 
1250*afdda45fSVasumathi Sundaram - Sun Microsystems 	*perm_flags = dip->pr_perm_flags;
12513bc21d0aSAruna Ramakrishna - Sun Microsystems 	free(dip);
1252d62bc4baSyz147064 done:
1253d62bc4baSyz147064 	return (DLADM_STATUS_OK);
1254d62bc4baSyz147064 }
1255d62bc4baSyz147064 
1256d62bc4baSyz147064 /*
1257d62bc4baSyz147064  * Add the specified module to the dlautopush structure; returns a
1258d62bc4baSyz147064  * DLADM_STATUS_* code.
1259d62bc4baSyz147064  */
1260d62bc4baSyz147064 dladm_status_t
1261d62bc4baSyz147064 i_dladm_add_ap_module(const char *module, struct dlautopush *dlap)
1262d62bc4baSyz147064 {
1263d62bc4baSyz147064 	if ((strlen(module) == 0) || (strlen(module) > FMNAMESZ))
1264d62bc4baSyz147064 		return (DLADM_STATUS_BADVAL);
1265d62bc4baSyz147064 
1266d62bc4baSyz147064 	if (strncasecmp(module, AP_ANCHOR, strlen(AP_ANCHOR)) == 0) {
1267d62bc4baSyz147064 		/*
1268d62bc4baSyz147064 		 * We don't allow multiple anchors, and the anchor must
1269d62bc4baSyz147064 		 * be after at least one module.
1270d62bc4baSyz147064 		 */
1271d62bc4baSyz147064 		if (dlap->dap_anchor != 0)
1272d62bc4baSyz147064 			return (DLADM_STATUS_BADVAL);
1273d62bc4baSyz147064 		if (dlap->dap_npush == 0)
1274d62bc4baSyz147064 			return (DLADM_STATUS_BADVAL);
1275d62bc4baSyz147064 
1276d62bc4baSyz147064 		dlap->dap_anchor = dlap->dap_npush;
1277d62bc4baSyz147064 		return (DLADM_STATUS_OK);
1278d62bc4baSyz147064 	}
1279d62bc4baSyz147064 	if (dlap->dap_npush > MAXAPUSH)
1280d62bc4baSyz147064 		return (DLADM_STATUS_BADVALCNT);
1281d62bc4baSyz147064 
1282d62bc4baSyz147064 	(void) strlcpy(dlap->dap_aplist[dlap->dap_npush++], module,
1283d62bc4baSyz147064 	    FMNAMESZ + 1);
1284d62bc4baSyz147064 
1285d62bc4baSyz147064 	return (DLADM_STATUS_OK);
1286d62bc4baSyz147064 }
1287d62bc4baSyz147064 
1288d62bc4baSyz147064 /*
1289d62bc4baSyz147064  * Currently, both '.' and ' '(space) can be used as the delimiters between
1290d62bc4baSyz147064  * autopush modules. The former is used in dladm set-linkprop, and the
1291d62bc4baSyz147064  * latter is used in the autopush(1M) file.
1292d62bc4baSyz147064  */
1293d62bc4baSyz147064 /* ARGSUSED */
1294d62bc4baSyz147064 static dladm_status_t
1295e7801d59Ssowmini do_check_autopush(struct prop_desc *pd, datalink_id_t linkid, char **prop_val,
12966b9e797cSsowmini     uint_t val_cnt, val_desc_t *vdp, datalink_media_t media)
1297d62bc4baSyz147064 {
1298d62bc4baSyz147064 	char			*module;
1299d62bc4baSyz147064 	struct dlautopush	*dlap;
1300d62bc4baSyz147064 	dladm_status_t		status;
1301d62bc4baSyz147064 	char			val[DLADM_PROP_VAL_MAX];
1302d62bc4baSyz147064 	char			delimiters[4];
1303d62bc4baSyz147064 
1304d62bc4baSyz147064 	if (val_cnt != 1)
1305d62bc4baSyz147064 		return (DLADM_STATUS_BADVALCNT);
1306d62bc4baSyz147064 
13073bc21d0aSAruna Ramakrishna - Sun Microsystems 	if (prop_val != NULL) {
1308d62bc4baSyz147064 		dlap = malloc(sizeof (struct dlautopush));
1309d62bc4baSyz147064 		if (dlap == NULL)
1310d62bc4baSyz147064 			return (DLADM_STATUS_NOMEM);
1311d62bc4baSyz147064 
1312d62bc4baSyz147064 		(void) memset(dlap, 0, sizeof (struct dlautopush));
1313d62bc4baSyz147064 		(void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER);
1314d62bc4baSyz147064 		bcopy(*prop_val, val, DLADM_PROP_VAL_MAX);
1315d62bc4baSyz147064 		module = strtok(val, delimiters);
1316d62bc4baSyz147064 		while (module != NULL) {
1317d62bc4baSyz147064 			status = i_dladm_add_ap_module(module, dlap);
1318d62bc4baSyz147064 			if (status != DLADM_STATUS_OK)
1319d62bc4baSyz147064 				return (status);
1320d62bc4baSyz147064 			module = strtok(NULL, delimiters);
1321d62bc4baSyz147064 		}
1322d62bc4baSyz147064 
1323d62bc4baSyz147064 		vdp->vd_val = (uintptr_t)dlap;
13243bc21d0aSAruna Ramakrishna - Sun Microsystems 	} else {
13253bc21d0aSAruna Ramakrishna - Sun Microsystems 		vdp->vd_val = 0;
13263bc21d0aSAruna Ramakrishna - Sun Microsystems 	}
1327d62bc4baSyz147064 	return (DLADM_STATUS_OK);
1328d62bc4baSyz147064 }
1329d62bc4baSyz147064 
1330bcb5c89dSSowmini Varadhan #define	WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET)
1331bcb5c89dSSowmini Varadhan 
1332e7801d59Ssowmini /* ARGSUSED */
1333d62bc4baSyz147064 static dladm_status_t
1334e7801d59Ssowmini do_get_rate_common(struct prop_desc *pd, datalink_id_t linkid,
1335e7801d59Ssowmini     char **prop_val, uint_t *val_cnt, uint_t id)
1336d62bc4baSyz147064 {
1337d62bc4baSyz147064 	wl_rates_t	*wrp;
1338d62bc4baSyz147064 	uint_t		i;
1339d62bc4baSyz147064 	dladm_status_t	status = DLADM_STATUS_OK;
1340d62bc4baSyz147064 
1341bcb5c89dSSowmini Varadhan 	wrp = malloc(WLDP_BUFSIZE);
1342bcb5c89dSSowmini Varadhan 	if (wrp == NULL)
1343bcb5c89dSSowmini Varadhan 		return (DLADM_STATUS_NOMEM);
1344d62bc4baSyz147064 
1345bcb5c89dSSowmini Varadhan 	status = i_dladm_wlan_param(linkid, wrp, id, WLDP_BUFSIZE, B_FALSE);
1346d62bc4baSyz147064 	if (status != DLADM_STATUS_OK)
1347d62bc4baSyz147064 		goto done;
1348d62bc4baSyz147064 
1349d62bc4baSyz147064 	if (wrp->wl_rates_num > *val_cnt) {
1350d62bc4baSyz147064 		status = DLADM_STATUS_TOOSMALL;
1351d62bc4baSyz147064 		goto done;
1352d62bc4baSyz147064 	}
1353d62bc4baSyz147064 
1354d62bc4baSyz147064 	if (wrp->wl_rates_rates[0] == 0) {
1355d62bc4baSyz147064 		prop_val[0][0] = '\0';
1356d62bc4baSyz147064 		*val_cnt = 1;
1357d62bc4baSyz147064 		goto done;
1358d62bc4baSyz147064 	}
1359d62bc4baSyz147064 
1360d62bc4baSyz147064 	for (i = 0; i < wrp->wl_rates_num; i++) {
1361d62bc4baSyz147064 		(void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f",
1362d62bc4baSyz147064 		    wrp->wl_rates_rates[i] % 2,
1363d62bc4baSyz147064 		    (float)wrp->wl_rates_rates[i] / 2);
1364d62bc4baSyz147064 	}
1365d62bc4baSyz147064 	*val_cnt = wrp->wl_rates_num;
1366d62bc4baSyz147064 
1367d62bc4baSyz147064 done:
1368bcb5c89dSSowmini Varadhan 	free(wrp);
1369d62bc4baSyz147064 	return (status);
1370d62bc4baSyz147064 }
1371d62bc4baSyz147064 
1372d62bc4baSyz147064 static dladm_status_t
1373e7801d59Ssowmini do_get_rate_prop(struct prop_desc *pd, datalink_id_t linkid,
1374*afdda45fSVasumathi Sundaram - Sun Microsystems     char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags,
1375*afdda45fSVasumathi Sundaram - Sun Microsystems     uint_t *perm_flags)
1376d62bc4baSyz147064 {
1377*afdda45fSVasumathi Sundaram - Sun Microsystems 	if (media != DL_WIFI) {
1378*afdda45fSVasumathi Sundaram - Sun Microsystems 		*perm_flags = MAC_PROP_PERM_READ;
13793bc21d0aSAruna Ramakrishna - Sun Microsystems 		return (i_dladm_speed_get(pd, linkid, prop_val,
13803bc21d0aSAruna Ramakrishna - Sun Microsystems 		    val_cnt, flags));
1381*afdda45fSVasumathi Sundaram - Sun Microsystems 	}
13826b9e797cSsowmini 
1383*afdda45fSVasumathi Sundaram - Sun Microsystems 	*perm_flags = MAC_PROP_PERM_RW;
1384e7801d59Ssowmini 	return (do_get_rate_common(pd, linkid, prop_val, val_cnt,
1385bcb5c89dSSowmini Varadhan 	    MAC_PROP_WL_DESIRED_RATES));
1386d62bc4baSyz147064 }
1387d62bc4baSyz147064 
13884045d941Ssowmini /* ARGSUSED */
1389d62bc4baSyz147064 static dladm_status_t
1390e7801d59Ssowmini do_get_rate_mod(struct prop_desc *pd, datalink_id_t linkid,
1391*afdda45fSVasumathi Sundaram - Sun Microsystems     char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags,
1392*afdda45fSVasumathi Sundaram - Sun Microsystems     uint_t *perm_flags)
1393d62bc4baSyz147064 {
1394*afdda45fSVasumathi Sundaram - Sun Microsystems 	*perm_flags = MAC_PROP_PERM_READ;
1395*afdda45fSVasumathi Sundaram - Sun Microsystems 
13966b9e797cSsowmini 	switch (media) {
13976b9e797cSsowmini 	case DL_ETHER:
13984045d941Ssowmini 		/*
13994045d941Ssowmini 		 * Speed for ethernet links is unbounded. E.g., 802.11b
14004045d941Ssowmini 		 * links can have a speed of 5.5 Gbps.
14014045d941Ssowmini 		 */
14024045d941Ssowmini 		return (DLADM_STATUS_NOTSUP);
14036b9e797cSsowmini 
14046b9e797cSsowmini 	case DL_WIFI:
1405e7801d59Ssowmini 		return (do_get_rate_common(pd, linkid, prop_val, val_cnt,
1406bcb5c89dSSowmini Varadhan 		    MAC_PROP_WL_SUPPORTED_RATES));
14076b9e797cSsowmini 	default:
14086b9e797cSsowmini 		return (DLADM_STATUS_BADARG);
14096b9e797cSsowmini 	}
1410d62bc4baSyz147064 }
1411d62bc4baSyz147064 
1412d62bc4baSyz147064 static dladm_status_t
1413d62bc4baSyz147064 do_set_rate(datalink_id_t linkid, dladm_wlan_rates_t *rates)
1414f4b3ec61Sdh155122 {
1415f4b3ec61Sdh155122 	int		i;
1416d62bc4baSyz147064 	uint_t		len;
1417d62bc4baSyz147064 	wl_rates_t	*wrp;
1418d62bc4baSyz147064 	dladm_status_t	status = DLADM_STATUS_OK;
1419d62bc4baSyz147064 
1420bcb5c89dSSowmini Varadhan 	wrp = malloc(WLDP_BUFSIZE);
1421bcb5c89dSSowmini Varadhan 	if (wrp == NULL)
1422d62bc4baSyz147064 		return (DLADM_STATUS_NOMEM);
1423d62bc4baSyz147064 
1424bcb5c89dSSowmini Varadhan 	bzero(wrp, WLDP_BUFSIZE);
1425d62bc4baSyz147064 	for (i = 0; i < rates->wr_cnt; i++)
1426d62bc4baSyz147064 		wrp->wl_rates_rates[i] = rates->wr_rates[i];
1427d62bc4baSyz147064 	wrp->wl_rates_num = rates->wr_cnt;
1428d62bc4baSyz147064 
1429d62bc4baSyz147064 	len = offsetof(wl_rates_t, wl_rates_rates) +
1430d62bc4baSyz147064 	    (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET;
1431bcb5c89dSSowmini Varadhan 	status = i_dladm_wlan_param(linkid, wrp, MAC_PROP_WL_DESIRED_RATES,
1432bcb5c89dSSowmini Varadhan 	    len, B_TRUE);
1433d62bc4baSyz147064 
1434bcb5c89dSSowmini Varadhan 	free(wrp);
1435d62bc4baSyz147064 	return (status);
1436d62bc4baSyz147064 }
1437d62bc4baSyz147064 
1438e7801d59Ssowmini /* ARGSUSED */
1439d62bc4baSyz147064 static dladm_status_t
1440e7801d59Ssowmini do_set_rate_prop(prop_desc_t *pd, datalink_id_t linkid,
14416b9e797cSsowmini     val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media)
1442d62bc4baSyz147064 {
1443d62bc4baSyz147064 	dladm_wlan_rates_t	rates;
1444f4b3ec61Sdh155122 	dladm_status_t		status;
1445f4b3ec61Sdh155122 
14466b9e797cSsowmini 	/*
14476b9e797cSsowmini 	 * can currently set rate on WIFI links only.
14486b9e797cSsowmini 	 */
14496b9e797cSsowmini 	if (media != DL_WIFI)
14506b9e797cSsowmini 		return (DLADM_STATUS_PROPRDONLY);
14516b9e797cSsowmini 
1452d62bc4baSyz147064 	if (val_cnt != 1)
1453d62bc4baSyz147064 		return (DLADM_STATUS_BADVALCNT);
1454f4b3ec61Sdh155122 
1455d62bc4baSyz147064 	rates.wr_cnt = 1;
1456d62bc4baSyz147064 	rates.wr_rates[0] = vdp[0].vd_val;
1457f4b3ec61Sdh155122 
1458d62bc4baSyz147064 	status = do_set_rate(linkid, &rates);
1459f4b3ec61Sdh155122 
1460d62bc4baSyz147064 done:
1461d62bc4baSyz147064 	return (status);
1462d62bc4baSyz147064 }
1463d62bc4baSyz147064 
1464d62bc4baSyz147064 /* ARGSUSED */
1465d62bc4baSyz147064 static dladm_status_t
1466e7801d59Ssowmini do_check_rate(struct prop_desc *pd, datalink_id_t linkid, char **prop_val,
14676b9e797cSsowmini     uint_t val_cnt, val_desc_t *vdp, datalink_media_t media)
1468d62bc4baSyz147064 {
1469d62bc4baSyz147064 	int		i;
1470d62bc4baSyz147064 	uint_t		modval_cnt = MAX_SUPPORT_RATES;
1471d62bc4baSyz147064 	char		*buf, **modval;
1472d62bc4baSyz147064 	dladm_status_t	status;
1473*afdda45fSVasumathi Sundaram - Sun Microsystems 	uint_t 		perm_flags;
1474d62bc4baSyz147064 
1475d62bc4baSyz147064 	if (val_cnt != 1)
1476d62bc4baSyz147064 		return (DLADM_STATUS_BADVALCNT);
1477d62bc4baSyz147064 
1478d62bc4baSyz147064 	buf = malloc((sizeof (char *) + DLADM_STRSIZE) *
1479d62bc4baSyz147064 	    MAX_SUPPORT_RATES);
1480d62bc4baSyz147064 	if (buf == NULL) {
1481d62bc4baSyz147064 		status = DLADM_STATUS_NOMEM;
1482d62bc4baSyz147064 		goto done;
1483d62bc4baSyz147064 	}
1484d62bc4baSyz147064 
1485d62bc4baSyz147064 	modval = (char **)(void *)buf;
1486d62bc4baSyz147064 	for (i = 0; i < MAX_SUPPORT_RATES; i++) {
1487d62bc4baSyz147064 		modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES +
1488d62bc4baSyz147064 		    i * DLADM_STRSIZE;
1489d62bc4baSyz147064 	}
1490d62bc4baSyz147064 
1491*afdda45fSVasumathi Sundaram - Sun Microsystems 	status = do_get_rate_mod(NULL, linkid, modval, &modval_cnt, media,
1492*afdda45fSVasumathi Sundaram - Sun Microsystems 	    0, &perm_flags);
1493d62bc4baSyz147064 	if (status != DLADM_STATUS_OK)
1494d62bc4baSyz147064 		goto done;
1495d62bc4baSyz147064 
1496d62bc4baSyz147064 	for (i = 0; i < modval_cnt; i++) {
1497d62bc4baSyz147064 		if (strcasecmp(*prop_val, modval[i]) == 0) {
1498e7801d59Ssowmini 			vdp->vd_val = (uintptr_t)(uint_t)
1499e7801d59Ssowmini 			    (atof(*prop_val) * 2);
1500f4b3ec61Sdh155122 			status = DLADM_STATUS_OK;
1501f4b3ec61Sdh155122 			break;
1502f4b3ec61Sdh155122 		}
1503d62bc4baSyz147064 	}
1504d62bc4baSyz147064 	if (i == modval_cnt)
1505d62bc4baSyz147064 		status = DLADM_STATUS_BADVAL;
1506d62bc4baSyz147064 done:
1507d62bc4baSyz147064 	free(buf);
1508d62bc4baSyz147064 	return (status);
1509d62bc4baSyz147064 }
1510f4b3ec61Sdh155122 
1511d62bc4baSyz147064 static dladm_status_t
1512bcb5c89dSSowmini Varadhan do_get_phyconf(datalink_id_t linkid, void *buf, int buflen)
1513d62bc4baSyz147064 {
1514bcb5c89dSSowmini Varadhan 	return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_PHY_CONFIG,
1515bcb5c89dSSowmini Varadhan 	    buflen, B_FALSE));
1516d62bc4baSyz147064 }
1517d62bc4baSyz147064 
1518e7801d59Ssowmini /* ARGSUSED */
1519d62bc4baSyz147064 static dladm_status_t
1520e7801d59Ssowmini do_get_channel_prop(struct prop_desc *pd, datalink_id_t linkid,
1521*afdda45fSVasumathi Sundaram - Sun Microsystems     char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags,
1522*afdda45fSVasumathi Sundaram - Sun Microsystems     uint_t *perm_flags)
1523d62bc4baSyz147064 {
1524d62bc4baSyz147064 	uint32_t	channel;
1525bcb5c89dSSowmini Varadhan 	char		buf[WLDP_BUFSIZE];
1526d62bc4baSyz147064 	dladm_status_t	status = DLADM_STATUS_OK;
1527bcb5c89dSSowmini Varadhan 	wl_phy_conf_t	wl_phy_conf;
1528d62bc4baSyz147064 
1529*afdda45fSVasumathi Sundaram - Sun Microsystems 	*perm_flags = MAC_PROP_PERM_READ;
1530bcb5c89dSSowmini Varadhan 	if ((status = do_get_phyconf(linkid, buf, sizeof (buf)))
1531bcb5c89dSSowmini Varadhan 	    != DLADM_STATUS_OK)
1532d62bc4baSyz147064 		goto done;
1533d62bc4baSyz147064 
1534bcb5c89dSSowmini Varadhan 	(void) memcpy(&wl_phy_conf, buf, sizeof (wl_phy_conf));
1535bcb5c89dSSowmini Varadhan 	if (!i_dladm_wlan_convert_chan(&wl_phy_conf, &channel)) {
1536d62bc4baSyz147064 		status = DLADM_STATUS_NOTFOUND;
1537d62bc4baSyz147064 		goto done;
1538d62bc4baSyz147064 	}
1539d62bc4baSyz147064 
1540d62bc4baSyz147064 	(void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel);
1541d62bc4baSyz147064 	*val_cnt = 1;
1542d62bc4baSyz147064 
1543d62bc4baSyz147064 done:
1544d62bc4baSyz147064 	return (status);
1545d62bc4baSyz147064 }
1546d62bc4baSyz147064 
1547d62bc4baSyz147064 static dladm_status_t
1548bcb5c89dSSowmini Varadhan do_get_powermode(datalink_id_t linkid, void *buf, int buflen)
1549d62bc4baSyz147064 {
1550bcb5c89dSSowmini Varadhan 	return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_POWER_MODE,
1551bcb5c89dSSowmini Varadhan 	    buflen, B_FALSE));
1552d62bc4baSyz147064 }
1553d62bc4baSyz147064 
1554e7801d59Ssowmini /* ARGSUSED */
1555d62bc4baSyz147064 static dladm_status_t
1556e7801d59Ssowmini do_get_powermode_prop(struct prop_desc *pd, datalink_id_t linkid,
1557*afdda45fSVasumathi Sundaram - Sun Microsystems     char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags,
1558*afdda45fSVasumathi Sundaram - Sun Microsystems     uint_t *perm_flags)
1559d62bc4baSyz147064 {
1560bcb5c89dSSowmini Varadhan 	wl_ps_mode_t	mode;
1561d62bc4baSyz147064 	const char	*s;
1562bcb5c89dSSowmini Varadhan 	char		buf[WLDP_BUFSIZE];
1563d62bc4baSyz147064 	dladm_status_t	status = DLADM_STATUS_OK;
1564d62bc4baSyz147064 
1565bcb5c89dSSowmini Varadhan 	if ((status = do_get_powermode(linkid, buf, sizeof (buf)))
1566bcb5c89dSSowmini Varadhan 	    != DLADM_STATUS_OK)
1567d62bc4baSyz147064 		goto done;
1568d62bc4baSyz147064 
1569bcb5c89dSSowmini Varadhan 	(void) memcpy(&mode, buf, sizeof (mode));
1570bcb5c89dSSowmini Varadhan 	switch (mode.wl_ps_mode) {
1571d62bc4baSyz147064 	case WL_PM_AM:
1572d62bc4baSyz147064 		s = "off";
1573f4b3ec61Sdh155122 		break;
1574d62bc4baSyz147064 	case WL_PM_MPS:
1575d62bc4baSyz147064 		s = "max";
1576d62bc4baSyz147064 		break;
1577d62bc4baSyz147064 	case WL_PM_FAST:
1578d62bc4baSyz147064 		s = "fast";
1579f4b3ec61Sdh155122 		break;
1580f4b3ec61Sdh155122 	default:
1581d62bc4baSyz147064 		status = DLADM_STATUS_NOTFOUND;
1582d62bc4baSyz147064 		goto done;
1583f4b3ec61Sdh155122 	}
1584d62bc4baSyz147064 	(void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s);
1585d62bc4baSyz147064 	*val_cnt = 1;
1586d62bc4baSyz147064 
1587d62bc4baSyz147064 done:
1588*afdda45fSVasumathi Sundaram - Sun Microsystems 	if (status == DLADM_STATUS_OK)
1589*afdda45fSVasumathi Sundaram - Sun Microsystems 		*perm_flags = MAC_PROP_PERM_RW;
1590*afdda45fSVasumathi Sundaram - Sun Microsystems 	else
1591*afdda45fSVasumathi Sundaram - Sun Microsystems 		*perm_flags = 0;
1592d62bc4baSyz147064 	return (status);
1593d62bc4baSyz147064 }
1594d62bc4baSyz147064 
1595d62bc4baSyz147064 static dladm_status_t
1596d62bc4baSyz147064 do_set_powermode(datalink_id_t linkid, dladm_wlan_powermode_t *pm)
1597d62bc4baSyz147064 {
1598d62bc4baSyz147064 	wl_ps_mode_t    ps_mode;
1599d62bc4baSyz147064 
1600d62bc4baSyz147064 	(void) memset(&ps_mode, 0xff, sizeof (ps_mode));
1601d62bc4baSyz147064 
1602d62bc4baSyz147064 	switch (*pm) {
1603d62bc4baSyz147064 	case DLADM_WLAN_PM_OFF:
1604d62bc4baSyz147064 		ps_mode.wl_ps_mode = WL_PM_AM;
1605d62bc4baSyz147064 		break;
1606d62bc4baSyz147064 	case DLADM_WLAN_PM_MAX:
1607d62bc4baSyz147064 		ps_mode.wl_ps_mode = WL_PM_MPS;
1608d62bc4baSyz147064 		break;
1609d62bc4baSyz147064 	case DLADM_WLAN_PM_FAST:
1610d62bc4baSyz147064 		ps_mode.wl_ps_mode = WL_PM_FAST;
1611d62bc4baSyz147064 		break;
1612d62bc4baSyz147064 	default:
1613d62bc4baSyz147064 		return (DLADM_STATUS_NOTSUP);
1614d62bc4baSyz147064 	}
1615bcb5c89dSSowmini Varadhan 	return (i_dladm_wlan_param(linkid, &ps_mode, MAC_PROP_WL_POWER_MODE,
1616bcb5c89dSSowmini Varadhan 	    sizeof (ps_mode), B_TRUE));
1617d62bc4baSyz147064 }
1618d62bc4baSyz147064 
1619d62bc4baSyz147064 /* ARGSUSED */
1620d62bc4baSyz147064 static dladm_status_t
1621e7801d59Ssowmini do_set_powermode_prop(prop_desc_t *pd, datalink_id_t linkid,
16226b9e797cSsowmini     val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media)
1623d62bc4baSyz147064 {
1624d62bc4baSyz147064 	dladm_wlan_powermode_t powermode = (dladm_wlan_powermode_t)vdp->vd_val;
1625d62bc4baSyz147064 	dladm_status_t status;
1626d62bc4baSyz147064 
1627d62bc4baSyz147064 	if (val_cnt != 1)
1628d62bc4baSyz147064 		return (DLADM_STATUS_BADVALCNT);
1629d62bc4baSyz147064 
1630d62bc4baSyz147064 	status = do_set_powermode(linkid, &powermode);
1631f4b3ec61Sdh155122 
1632f4b3ec61Sdh155122 	return (status);
1633f4b3ec61Sdh155122 }
1634f4b3ec61Sdh155122 
1635f4b3ec61Sdh155122 static dladm_status_t
1636bcb5c89dSSowmini Varadhan do_get_radio(datalink_id_t linkid, void *buf, int buflen)
1637f4b3ec61Sdh155122 {
1638bcb5c89dSSowmini Varadhan 	return (i_dladm_wlan_param(linkid, buf, MAC_PROP_WL_RADIO, buflen,
1639bcb5c89dSSowmini Varadhan 	    B_FALSE));
1640d62bc4baSyz147064 }
1641d62bc4baSyz147064 
1642e7801d59Ssowmini /* ARGSUSED */
1643d62bc4baSyz147064 static dladm_status_t
1644e7801d59Ssowmini do_get_radio_prop(struct prop_desc *pd, datalink_id_t linkid,
1645*afdda45fSVasumathi Sundaram - Sun Microsystems     char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags,
1646*afdda45fSVasumathi Sundaram - Sun Microsystems     uint_t *perm_flags)
1647d62bc4baSyz147064 {
1648d62bc4baSyz147064 	wl_radio_t	radio;
1649d62bc4baSyz147064 	const char	*s;
1650bcb5c89dSSowmini Varadhan 	char		buf[WLDP_BUFSIZE];
1651d62bc4baSyz147064 	dladm_status_t	status = DLADM_STATUS_OK;
1652d62bc4baSyz147064 
1653bcb5c89dSSowmini Varadhan 	if ((status = do_get_radio(linkid, buf, sizeof (buf)))
1654bcb5c89dSSowmini Varadhan 	    != DLADM_STATUS_OK)
1655d62bc4baSyz147064 		goto done;
1656d62bc4baSyz147064 
1657bcb5c89dSSowmini Varadhan 	(void) memcpy(&radio, buf, sizeof (radio));
1658d62bc4baSyz147064 	switch (radio) {
1659d62bc4baSyz147064 	case B_TRUE:
1660d62bc4baSyz147064 		s = "on";
1661d62bc4baSyz147064 		break;
1662d62bc4baSyz147064 	case B_FALSE:
1663d62bc4baSyz147064 		s = "off";
1664d62bc4baSyz147064 		break;
1665d62bc4baSyz147064 	default:
1666d62bc4baSyz147064 		status = DLADM_STATUS_NOTFOUND;
1667d62bc4baSyz147064 		goto done;
1668d62bc4baSyz147064 	}
1669d62bc4baSyz147064 	(void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s);
1670d62bc4baSyz147064 	*val_cnt = 1;
1671d62bc4baSyz147064 
1672d62bc4baSyz147064 done:
1673*afdda45fSVasumathi Sundaram - Sun Microsystems 	if (status == DLADM_STATUS_OK)
1674*afdda45fSVasumathi Sundaram - Sun Microsystems 		*perm_flags = MAC_PROP_PERM_RW;
1675*afdda45fSVasumathi Sundaram - Sun Microsystems 	else
1676*afdda45fSVasumathi Sundaram - Sun Microsystems 		*perm_flags = 0;
1677d62bc4baSyz147064 	return (status);
1678d62bc4baSyz147064 }
1679d62bc4baSyz147064 
1680d62bc4baSyz147064 static dladm_status_t
1681d62bc4baSyz147064 do_set_radio(datalink_id_t linkid, dladm_wlan_radio_t *radio)
1682d62bc4baSyz147064 {
1683d62bc4baSyz147064 	wl_radio_t r;
1684d62bc4baSyz147064 
1685d62bc4baSyz147064 	switch (*radio) {
1686d62bc4baSyz147064 	case DLADM_WLAN_RADIO_ON:
1687d62bc4baSyz147064 		r = B_TRUE;
1688d62bc4baSyz147064 		break;
1689d62bc4baSyz147064 	case DLADM_WLAN_RADIO_OFF:
1690d62bc4baSyz147064 		r = B_FALSE;
1691d62bc4baSyz147064 		break;
1692d62bc4baSyz147064 	default:
1693d62bc4baSyz147064 		return (DLADM_STATUS_NOTSUP);
1694d62bc4baSyz147064 	}
1695bcb5c89dSSowmini Varadhan 	return (i_dladm_wlan_param(linkid, &r, MAC_PROP_WL_RADIO,
1696bcb5c89dSSowmini Varadhan 	    sizeof (r), B_TRUE));
1697d62bc4baSyz147064 }
1698d62bc4baSyz147064 
1699d62bc4baSyz147064 /* ARGSUSED */
1700d62bc4baSyz147064 static dladm_status_t
1701e7801d59Ssowmini do_set_radio_prop(prop_desc_t *pd, datalink_id_t linkid,
17026b9e797cSsowmini     val_desc_t *vdp, uint_t val_cnt, uint_t fags, datalink_media_t media)
1703d62bc4baSyz147064 {
1704d62bc4baSyz147064 	dladm_wlan_radio_t radio = (dladm_wlan_radio_t)vdp->vd_val;
1705f4b3ec61Sdh155122 	dladm_status_t status;
1706f4b3ec61Sdh155122 
1707d62bc4baSyz147064 	if (val_cnt != 1)
1708d62bc4baSyz147064 		return (DLADM_STATUS_BADVALCNT);
1709f4b3ec61Sdh155122 
1710d62bc4baSyz147064 	status = do_set_radio(linkid, &radio);
1711f4b3ec61Sdh155122 
1712d62bc4baSyz147064 	return (status);
1713d62bc4baSyz147064 }
1714f4b3ec61Sdh155122 
1715d62bc4baSyz147064 static dladm_status_t
1716d62bc4baSyz147064 i_dladm_set_linkprop_db(datalink_id_t linkid, const char *prop_name,
1717d62bc4baSyz147064     char **prop_val, uint_t val_cnt)
1718d62bc4baSyz147064 {
1719d62bc4baSyz147064 	char		buf[MAXLINELEN];
1720d62bc4baSyz147064 	int		i;
1721d62bc4baSyz147064 	dladm_conf_t	conf;
1722d62bc4baSyz147064 	dladm_status_t	status;
1723d62bc4baSyz147064 
1724d62bc4baSyz147064 	status = dladm_read_conf(linkid, &conf);
1725f4b3ec61Sdh155122 	if (status != DLADM_STATUS_OK)
1726f4b3ec61Sdh155122 		return (status);
1727f4b3ec61Sdh155122 
1728d62bc4baSyz147064 	/*
1729d62bc4baSyz147064 	 * reset case.
1730d62bc4baSyz147064 	 */
1731d62bc4baSyz147064 	if (val_cnt == 0) {
1732d62bc4baSyz147064 		status = dladm_unset_conf_field(conf, prop_name);
1733d62bc4baSyz147064 		if (status == DLADM_STATUS_OK)
1734d62bc4baSyz147064 			status = dladm_write_conf(conf);
1735d62bc4baSyz147064 		goto done;
1736f4b3ec61Sdh155122 	}
1737f4b3ec61Sdh155122 
1738d62bc4baSyz147064 	buf[0] = '\0';
1739d62bc4baSyz147064 	for (i = 0; i < val_cnt; i++) {
1740d62bc4baSyz147064 		(void) strlcat(buf, prop_val[i], MAXLINELEN);
1741d62bc4baSyz147064 		if (i != val_cnt - 1)
1742d62bc4baSyz147064 			(void) strlcat(buf, ",", MAXLINELEN);
1743d62bc4baSyz147064 	}
1744f4b3ec61Sdh155122 
1745d62bc4baSyz147064 	status = dladm_set_conf_field(conf, prop_name, DLADM_TYPE_STR, buf);
1746d62bc4baSyz147064 	if (status == DLADM_STATUS_OK)
1747d62bc4baSyz147064 		status = dladm_write_conf(conf);
1748d62bc4baSyz147064 
1749d62bc4baSyz147064 done:
1750d62bc4baSyz147064 	dladm_destroy_conf(conf);
1751f4b3ec61Sdh155122 	return (status);
1752f4b3ec61Sdh155122 }
1753f4b3ec61Sdh155122 
1754f4b3ec61Sdh155122 static dladm_status_t
1755d62bc4baSyz147064 i_dladm_get_linkprop_db(datalink_id_t linkid, const char *prop_name,
1756d62bc4baSyz147064     char **prop_val, uint_t *val_cntp)
1757f4b3ec61Sdh155122 {
1758d62bc4baSyz147064 	char		buf[MAXLINELEN], *str;
1759d62bc4baSyz147064 	uint_t		cnt = 0;
1760d62bc4baSyz147064 	dladm_conf_t	conf;
1761d62bc4baSyz147064 	dladm_status_t	status;
1762f4b3ec61Sdh155122 
1763d62bc4baSyz147064 	status = dladm_read_conf(linkid, &conf);
1764d62bc4baSyz147064 	if (status != DLADM_STATUS_OK)
1765f4b3ec61Sdh155122 		return (status);
1766d62bc4baSyz147064 
1767d62bc4baSyz147064 	status = dladm_get_conf_field(conf, prop_name, buf, MAXLINELEN);
1768d62bc4baSyz147064 	if (status != DLADM_STATUS_OK)
1769d62bc4baSyz147064 		goto done;
1770d62bc4baSyz147064 
1771d62bc4baSyz147064 	str = strtok(buf, ",");
1772d62bc4baSyz147064 	while (str != NULL) {
1773d62bc4baSyz147064 		if (cnt == *val_cntp) {
1774d62bc4baSyz147064 			status = DLADM_STATUS_TOOSMALL;
1775d62bc4baSyz147064 			goto done;
1776d62bc4baSyz147064 		}
1777d62bc4baSyz147064 		(void) strlcpy(prop_val[cnt++], str, DLADM_PROP_VAL_MAX);
1778d62bc4baSyz147064 		str = strtok(NULL, ",");
1779f4b3ec61Sdh155122 	}
1780f4b3ec61Sdh155122 
1781d62bc4baSyz147064 	*val_cntp = cnt;
1782f4b3ec61Sdh155122 
1783d62bc4baSyz147064 done:
1784d62bc4baSyz147064 	dladm_destroy_conf(conf);
1785d62bc4baSyz147064 	return (status);
1786f4b3ec61Sdh155122 }
1787e7801d59Ssowmini 
1788bcb5c89dSSowmini Varadhan static link_attr_t *
1789e7801d59Ssowmini dladm_name2prop(const char *prop_name)
1790e7801d59Ssowmini {
1791bcb5c89dSSowmini Varadhan 	link_attr_t *p;
1792e7801d59Ssowmini 
1793bcb5c89dSSowmini Varadhan 	for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) {
1794e7801d59Ssowmini 		if (strcmp(p->pp_name, prop_name) == 0)
1795e7801d59Ssowmini 			break;
1796e7801d59Ssowmini 	}
1797e7801d59Ssowmini 	return (p);
1798e7801d59Ssowmini }
1799e7801d59Ssowmini 
1800bcb5c89dSSowmini Varadhan static link_attr_t *
1801bcb5c89dSSowmini Varadhan dladm_id2prop(mac_prop_id_t propid)
1802bcb5c89dSSowmini Varadhan {
1803bcb5c89dSSowmini Varadhan 	link_attr_t *p;
1804bcb5c89dSSowmini Varadhan 
1805bcb5c89dSSowmini Varadhan 	for (p = link_attr; p->pp_id != MAC_PROP_PRIVATE; p++) {
1806bcb5c89dSSowmini Varadhan 		if (p->pp_id == propid)
1807bcb5c89dSSowmini Varadhan 			break;
1808bcb5c89dSSowmini Varadhan 	}
1809bcb5c89dSSowmini Varadhan 	return (p);
1810bcb5c89dSSowmini Varadhan }
1811e7801d59Ssowmini 
18123fd94f8cSam223141 static dld_ioc_macprop_t *
1813bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_impl(size_t valsize, datalink_id_t linkid,
1814bcb5c89dSSowmini Varadhan     const char *prop_name, mac_prop_id_t propid, uint_t flags,
1815bcb5c89dSSowmini Varadhan     dladm_status_t *status)
1816e7801d59Ssowmini {
1817e7801d59Ssowmini 	int dsize;
18183fd94f8cSam223141 	dld_ioc_macprop_t *dip;
1819e7801d59Ssowmini 
1820e7801d59Ssowmini 	*status = DLADM_STATUS_OK;
18213fd94f8cSam223141 	dsize = MAC_PROP_BUFSIZE(valsize);
1822e7801d59Ssowmini 	dip = malloc(dsize);
1823e7801d59Ssowmini 	if (dip == NULL) {
1824e7801d59Ssowmini 		*status = DLADM_STATUS_NOMEM;
1825e7801d59Ssowmini 		return (NULL);
1826e7801d59Ssowmini 	}
1827e7801d59Ssowmini 	bzero(dip, dsize);
1828e7801d59Ssowmini 	dip->pr_valsize = valsize;
18294045d941Ssowmini 	(void) strlcpy(dip->pr_name, prop_name, sizeof (dip->pr_name));
18303fd94f8cSam223141 	dip->pr_version = MAC_PROP_VERSION;
18316b9e797cSsowmini 	dip->pr_linkid = linkid;
1832bcb5c89dSSowmini Varadhan 	dip->pr_num = propid;
18334045d941Ssowmini 	dip->pr_flags = flags;
1834e7801d59Ssowmini 	return (dip);
1835e7801d59Ssowmini }
1836e7801d59Ssowmini 
1837bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *
1838bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_name(size_t valsize, datalink_id_t linkid,
1839bcb5c89dSSowmini Varadhan     const char *prop_name, uint_t flags, dladm_status_t *status)
1840bcb5c89dSSowmini Varadhan {
1841bcb5c89dSSowmini Varadhan 	link_attr_t *p;
1842bcb5c89dSSowmini Varadhan 
1843bcb5c89dSSowmini Varadhan 	p = dladm_name2prop(prop_name);
1844bcb5c89dSSowmini Varadhan 	valsize = MAX(p->pp_valsize, valsize);
1845bcb5c89dSSowmini Varadhan 	return (i_dladm_buf_alloc_impl(valsize, linkid, prop_name, p->pp_id,
1846bcb5c89dSSowmini Varadhan 	    flags, status));
1847bcb5c89dSSowmini Varadhan }
1848bcb5c89dSSowmini Varadhan 
1849bcb5c89dSSowmini Varadhan static dld_ioc_macprop_t *
1850bcb5c89dSSowmini Varadhan i_dladm_buf_alloc_by_id(size_t valsize, datalink_id_t linkid,
1851bcb5c89dSSowmini Varadhan     mac_prop_id_t propid, uint_t flags, dladm_status_t *status)
1852bcb5c89dSSowmini Varadhan {
1853bcb5c89dSSowmini Varadhan 	link_attr_t *p;
1854bcb5c89dSSowmini Varadhan 
1855bcb5c89dSSowmini Varadhan 	p = dladm_id2prop(propid);
1856bcb5c89dSSowmini Varadhan 	valsize = MAX(p->pp_valsize, valsize);
1857bcb5c89dSSowmini Varadhan 	return (i_dladm_buf_alloc_impl(valsize, linkid, p->pp_name, propid,
1858bcb5c89dSSowmini Varadhan 	    flags, status));
1859bcb5c89dSSowmini Varadhan }
1860bcb5c89dSSowmini Varadhan 
1861e7801d59Ssowmini /* ARGSUSED */
1862e7801d59Ssowmini static dladm_status_t
18633bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_public_prop(prop_desc_t *pd, datalink_id_t linkid,
18646b9e797cSsowmini     val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media)
1865e7801d59Ssowmini {
18663fd94f8cSam223141 	dld_ioc_macprop_t	*dip;
1867e7801d59Ssowmini 	dladm_status_t	status = DLADM_STATUS_OK;
1868e7801d59Ssowmini 	uint8_t		u8;
1869e7801d59Ssowmini 	uint16_t	u16;
1870e7801d59Ssowmini 	uint32_t	u32;
1871e7801d59Ssowmini 	void		*val;
1872e7801d59Ssowmini 
1873bcb5c89dSSowmini Varadhan 	dip = i_dladm_buf_alloc_by_name(0, linkid, pd->pd_name, 0, &status);
1874e7801d59Ssowmini 	if (dip == NULL)
1875e7801d59Ssowmini 		return (status);
1876e7801d59Ssowmini 
1877e7801d59Ssowmini 	if (pd->pd_flags & PD_CHECK_ALLOC)
1878e7801d59Ssowmini 		val = (void *)vdp->vd_val;
1879e7801d59Ssowmini 	else {
1880e7801d59Ssowmini 		/*
1881e7801d59Ssowmini 		 * Currently all 1/2/4-byte size properties are byte/word/int.
1882e7801d59Ssowmini 		 * No need (yet) to distinguish these from arrays of same size.
1883e7801d59Ssowmini 		 */
1884e7801d59Ssowmini 		switch (dip->pr_valsize) {
1885e7801d59Ssowmini 		case 1:
1886e7801d59Ssowmini 			u8 = vdp->vd_val;
1887e7801d59Ssowmini 			val = &u8;
1888e7801d59Ssowmini 			break;
1889e7801d59Ssowmini 		case 2:
1890e7801d59Ssowmini 			u16 = vdp->vd_val;
1891e7801d59Ssowmini 			val = &u16;
1892e7801d59Ssowmini 			break;
1893e7801d59Ssowmini 		case 4:
1894e7801d59Ssowmini 			u32 = vdp->vd_val;
1895e7801d59Ssowmini 			val = &u32;
1896e7801d59Ssowmini 			break;
1897e7801d59Ssowmini 		default:
1898e7801d59Ssowmini 			val = &vdp->vd_val;
1899e7801d59Ssowmini 			break;
1900e7801d59Ssowmini 		}
1901e7801d59Ssowmini 	}
1902e7801d59Ssowmini 
19033bc21d0aSAruna Ramakrishna - Sun Microsystems 	if (val != NULL)
1904e7801d59Ssowmini 		(void) memcpy(dip->pr_val, val, dip->pr_valsize);
19053bc21d0aSAruna Ramakrishna - Sun Microsystems 	else
19063bc21d0aSAruna Ramakrishna - Sun Microsystems 		dip->pr_valsize = 0;
19073bc21d0aSAruna Ramakrishna - Sun Microsystems 
1908bcb5c89dSSowmini Varadhan 	status = i_dladm_macprop(dip, B_TRUE);
1909bcb5c89dSSowmini Varadhan 
1910bcb5c89dSSowmini Varadhan done:
1911bcb5c89dSSowmini Varadhan 	free(dip);
1912bcb5c89dSSowmini Varadhan 	return (status);
1913bcb5c89dSSowmini Varadhan }
1914bcb5c89dSSowmini Varadhan 
1915bcb5c89dSSowmini Varadhan dladm_status_t
1916bcb5c89dSSowmini Varadhan i_dladm_macprop(void *dip, boolean_t set)
1917bcb5c89dSSowmini Varadhan {
1918bcb5c89dSSowmini Varadhan 	int fd;
1919bcb5c89dSSowmini Varadhan 	dladm_status_t status = DLADM_STATUS_OK;
1920bcb5c89dSSowmini Varadhan 
1921e7801d59Ssowmini 	if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) {
1922e7801d59Ssowmini 		status = dladm_errno2status(errno);
1923bcb5c89dSSowmini Varadhan 		return (status);
1924e7801d59Ssowmini 	}
1925bcb5c89dSSowmini Varadhan 	if (ioctl(fd, (set ? DLDIOC_SETMACPROP : DLDIOC_GETMACPROP), dip))
1926e7801d59Ssowmini 		status = dladm_errno2status(errno);
1927e7801d59Ssowmini 
1928e7801d59Ssowmini 	(void) close(fd);
1929e7801d59Ssowmini 	return (status);
1930e7801d59Ssowmini }
1931e7801d59Ssowmini 
19323fd94f8cSam223141 static dld_ioc_macprop_t *
19333bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_get_public_prop(datalink_id_t linkid, char *prop_name, uint_t flags,
19344045d941Ssowmini     dladm_status_t *status)
1935e7801d59Ssowmini {
19363fd94f8cSam223141 	dld_ioc_macprop_t *dip = NULL;
19374045d941Ssowmini 
1938bcb5c89dSSowmini Varadhan 	dip = i_dladm_buf_alloc_by_name(0, linkid, prop_name, flags, status);
19394045d941Ssowmini 	if (dip == NULL)
19404045d941Ssowmini 		return (NULL);
1941e7801d59Ssowmini 
1942bcb5c89dSSowmini Varadhan 	*status = i_dladm_macprop(dip, B_FALSE);
19434045d941Ssowmini 	if (*status != DLADM_STATUS_OK) {
19444045d941Ssowmini 		free(dip);
19454045d941Ssowmini 		return (NULL);
19464045d941Ssowmini 	}
19474045d941Ssowmini 	return (dip);
1948e7801d59Ssowmini }
1949e7801d59Ssowmini 
1950e7801d59Ssowmini /* ARGSUSED */
1951e7801d59Ssowmini static dladm_status_t
19523bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_defmtu_check(struct prop_desc *pd, datalink_id_t linkid,
19533bc21d0aSAruna Ramakrishna - Sun Microsystems     char **prop_val, uint_t val_cnt, val_desc_t *v, datalink_media_t media)
1954e7801d59Ssowmini {
1955e7801d59Ssowmini 	if (val_cnt != 1)
1956e7801d59Ssowmini 		return (DLADM_STATUS_BADVAL);
19574045d941Ssowmini 	v->vd_val = atoi(prop_val[0]);
1958e7801d59Ssowmini 	return (DLADM_STATUS_OK);
1959e7801d59Ssowmini }
1960e7801d59Ssowmini 
1961e7801d59Ssowmini /* ARGSUSED */
1962e7801d59Ssowmini static dladm_status_t
19633bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_duplex_get(struct prop_desc *pd, datalink_id_t linkid,
1964*afdda45fSVasumathi Sundaram - Sun Microsystems     char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags,
1965*afdda45fSVasumathi Sundaram - Sun Microsystems     uint_t *perm_flags)
1966e7801d59Ssowmini {
1967e7801d59Ssowmini 	link_duplex_t   link_duplex;
1968e7801d59Ssowmini 	dladm_status_t  status;
1969e7801d59Ssowmini 
1970e7801d59Ssowmini 	if ((status = dladm_get_single_mac_stat(linkid, "link_duplex",
1971e7801d59Ssowmini 	    KSTAT_DATA_UINT32, &link_duplex)) != 0)
1972e7801d59Ssowmini 		return (status);
1973e7801d59Ssowmini 
1974e7801d59Ssowmini 	switch (link_duplex) {
1975e7801d59Ssowmini 	case LINK_DUPLEX_FULL:
1976e7801d59Ssowmini 		(void) strcpy(*prop_val, "full");
1977e7801d59Ssowmini 		break;
1978e7801d59Ssowmini 	case LINK_DUPLEX_HALF:
1979e7801d59Ssowmini 		(void) strcpy(*prop_val, "half");
1980e7801d59Ssowmini 		break;
1981e7801d59Ssowmini 	default:
1982e7801d59Ssowmini 		(void) strcpy(*prop_val, "unknown");
1983e7801d59Ssowmini 		break;
1984e7801d59Ssowmini 	}
1985e7801d59Ssowmini 	*val_cnt = 1;
1986e7801d59Ssowmini 	return (DLADM_STATUS_OK);
1987e7801d59Ssowmini }
1988e7801d59Ssowmini 
1989e7801d59Ssowmini /* ARGSUSED */
1990e7801d59Ssowmini static dladm_status_t
19913bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_speed_get(struct prop_desc *pd, datalink_id_t linkid,
19924045d941Ssowmini     char **prop_val, uint_t *val_cnt, uint_t flags)
1993e7801d59Ssowmini {
1994e7801d59Ssowmini 	uint64_t	ifspeed = 0;
1995e7801d59Ssowmini 	dladm_status_t status;
1996e7801d59Ssowmini 
1997e7801d59Ssowmini 	if ((status = dladm_get_single_mac_stat(linkid, "ifspeed",
1998e7801d59Ssowmini 	    KSTAT_DATA_UINT64, &ifspeed)) != 0)
1999e7801d59Ssowmini 		return (status);
20004045d941Ssowmini 
20016b9e797cSsowmini 	if ((ifspeed % 1000000) != 0) {
20026b9e797cSsowmini 		(void) snprintf(*prop_val, DLADM_PROP_VAL_MAX,
20036b9e797cSsowmini 		    "%llf", ifspeed / (float)1000000); /* Mbps */
20046b9e797cSsowmini 	} else {
2005e7801d59Ssowmini 		(void) snprintf(*prop_val, DLADM_PROP_VAL_MAX,
2006e7801d59Ssowmini 		    "%llu", ifspeed / 1000000); /* Mbps */
20076b9e797cSsowmini 	}
2008e7801d59Ssowmini 	*val_cnt = 1;
2009e7801d59Ssowmini 	return (DLADM_STATUS_OK);
2010e7801d59Ssowmini }
2011e7801d59Ssowmini 
2012e7801d59Ssowmini /* ARGSUSED */
2013e7801d59Ssowmini static dladm_status_t
20143bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_status_get(struct prop_desc *pd, datalink_id_t linkid,
2015*afdda45fSVasumathi Sundaram - Sun Microsystems     char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags,
2016*afdda45fSVasumathi Sundaram - Sun Microsystems     uint_t *perm_flags)
2017e7801d59Ssowmini {
2018e7801d59Ssowmini 	link_state_t	link_state;
2019e7801d59Ssowmini 	dladm_status_t	status;
20204045d941Ssowmini 	uchar_t 	*cp;
20213fd94f8cSam223141 	dld_ioc_macprop_t  *dip;
2022e7801d59Ssowmini 
20233bc21d0aSAruna Ramakrishna - Sun Microsystems 	dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status);
20244045d941Ssowmini 	if (status != DLADM_STATUS_OK)
2025e7801d59Ssowmini 		return (status);
20264045d941Ssowmini 	cp = (uchar_t *)dip->pr_val;
20274045d941Ssowmini 	(void) memcpy(&link_state, cp, sizeof (link_state));
2028e7801d59Ssowmini 
2029e7801d59Ssowmini 	switch (link_state) {
2030e7801d59Ssowmini 	case LINK_STATE_UP:
2031e7801d59Ssowmini 		(void) strcpy(*prop_val, "up");
2032e7801d59Ssowmini 		break;
2033e7801d59Ssowmini 	case LINK_STATE_DOWN:
2034e7801d59Ssowmini 		(void) strcpy(*prop_val, "down");
2035e7801d59Ssowmini 		break;
2036e7801d59Ssowmini 	default:
2037e7801d59Ssowmini 		(void) strcpy(*prop_val, "unknown");
2038e7801d59Ssowmini 		break;
2039e7801d59Ssowmini 	}
2040e7801d59Ssowmini 	*val_cnt = 1;
2041*afdda45fSVasumathi Sundaram - Sun Microsystems 	*perm_flags = dip->pr_perm_flags;
20424045d941Ssowmini 	free(dip);
2043e7801d59Ssowmini 	return (DLADM_STATUS_OK);
2044e7801d59Ssowmini }
2045e7801d59Ssowmini 
2046e7801d59Ssowmini /* ARGSUSED */
2047e7801d59Ssowmini static dladm_status_t
20483bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_binary_get(struct prop_desc *pd, datalink_id_t linkid,
2049*afdda45fSVasumathi Sundaram - Sun Microsystems     char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags,
2050*afdda45fSVasumathi Sundaram - Sun Microsystems     uint_t *perm_flags)
2051e7801d59Ssowmini {
20523fd94f8cSam223141 	dld_ioc_macprop_t *dip;
2053e7801d59Ssowmini 	dladm_status_t status;
2054e7801d59Ssowmini 
20553bc21d0aSAruna Ramakrishna - Sun Microsystems 	dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status);
20564045d941Ssowmini 	if (dip == NULL)
2057e7801d59Ssowmini 		return (status);
2058e7801d59Ssowmini 	(void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%x", dip->pr_val[0]);
2059*afdda45fSVasumathi Sundaram - Sun Microsystems 	*perm_flags = dip->pr_perm_flags;
2060e7801d59Ssowmini 	free(dip);
2061e7801d59Ssowmini 	*val_cnt = 1;
2062e7801d59Ssowmini 	return (DLADM_STATUS_OK);
2063e7801d59Ssowmini }
2064e7801d59Ssowmini 
20656b9e797cSsowmini /* ARGSUSED */
2066e7801d59Ssowmini static dladm_status_t
20673bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_uint32_get(struct prop_desc *pd, datalink_id_t linkid,
2068*afdda45fSVasumathi Sundaram - Sun Microsystems     char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags,
2069*afdda45fSVasumathi Sundaram - Sun Microsystems     uint_t *perm_flags)
2070e7801d59Ssowmini {
20713fd94f8cSam223141 	dld_ioc_macprop_t *dip;
20724045d941Ssowmini 	uint32_t v  = 0;
2073e7801d59Ssowmini 	uchar_t *cp;
2074e7801d59Ssowmini 	dladm_status_t status;
2075e7801d59Ssowmini 
20763bc21d0aSAruna Ramakrishna - Sun Microsystems 	dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status);
20774045d941Ssowmini 	if (dip == NULL)
2078e7801d59Ssowmini 		return (status);
2079e7801d59Ssowmini 	cp = (uchar_t *)dip->pr_val;
2080e7801d59Ssowmini 	(void) memcpy(&v, cp, sizeof (v));
20814045d941Ssowmini 	(void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%ld", v);
2082*afdda45fSVasumathi Sundaram - Sun Microsystems 	*perm_flags = dip->pr_perm_flags;
2083e7801d59Ssowmini 	free(dip);
2084e7801d59Ssowmini 	*val_cnt = 1;
2085e7801d59Ssowmini 	return (DLADM_STATUS_OK);
2086e7801d59Ssowmini }
2087e7801d59Ssowmini 
20886b9e797cSsowmini /* ARGSUSED */
2089e7801d59Ssowmini static dladm_status_t
20903bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_flowctl_get(struct prop_desc *pd, datalink_id_t linkid,
2091*afdda45fSVasumathi Sundaram - Sun Microsystems     char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags,
2092*afdda45fSVasumathi Sundaram - Sun Microsystems     uint_t *perm_flags)
2093e7801d59Ssowmini {
20943fd94f8cSam223141 	dld_ioc_macprop_t *dip;
2095e7801d59Ssowmini 	link_flowctrl_t v;
2096e7801d59Ssowmini 	dladm_status_t status;
2097e7801d59Ssowmini 	uchar_t *cp;
2098e7801d59Ssowmini 
20993bc21d0aSAruna Ramakrishna - Sun Microsystems 	dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status);
21004045d941Ssowmini 	if (dip == NULL)
2101e7801d59Ssowmini 		return (status);
2102e7801d59Ssowmini 	cp = (uchar_t *)dip->pr_val;
2103e7801d59Ssowmini 	(void) memcpy(&v, cp, sizeof (v));
2104e7801d59Ssowmini 	switch (v) {
2105e7801d59Ssowmini 	case LINK_FLOWCTRL_NONE:
2106e7801d59Ssowmini 		(void) sprintf(*prop_val, "no");
2107e7801d59Ssowmini 		break;
2108e7801d59Ssowmini 	case LINK_FLOWCTRL_RX:
2109e7801d59Ssowmini 		(void) sprintf(*prop_val, "rx");
2110e7801d59Ssowmini 		break;
2111e7801d59Ssowmini 	case LINK_FLOWCTRL_TX:
2112e7801d59Ssowmini 		(void) sprintf(*prop_val, "tx");
2113e7801d59Ssowmini 		break;
2114e7801d59Ssowmini 	case LINK_FLOWCTRL_BI:
2115e7801d59Ssowmini 		(void) sprintf(*prop_val, "bi");
2116e7801d59Ssowmini 		break;
2117e7801d59Ssowmini 	}
2118*afdda45fSVasumathi Sundaram - Sun Microsystems 	*perm_flags = dip->pr_perm_flags;
2119e7801d59Ssowmini 	free(dip);
2120e7801d59Ssowmini 	*val_cnt = 1;
2121e7801d59Ssowmini 	return (DLADM_STATUS_OK);
2122e7801d59Ssowmini }
2123e7801d59Ssowmini 
2124e7801d59Ssowmini 
2125e7801d59Ssowmini /* ARGSUSED */
2126e7801d59Ssowmini static dladm_status_t
21273bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_set_prop(datalink_id_t linkid, const char *prop_name,
2128e7801d59Ssowmini     char **prop_val, uint_t val_cnt, uint_t flags)
2129e7801d59Ssowmini {
2130bcb5c89dSSowmini Varadhan 	int		i, slen;
2131eae72b5bSSebastien Roy 	int 		bufsize = 0;
21323fd94f8cSam223141 	dld_ioc_macprop_t *dip = NULL;
2133e7801d59Ssowmini 	uchar_t 	*dp;
2134bcb5c89dSSowmini Varadhan 	link_attr_t *p;
21354045d941Ssowmini 	dladm_status_t	status = DLADM_STATUS_OK;
2136e7801d59Ssowmini 
2137e7801d59Ssowmini 	if ((prop_name == NULL && prop_val != NULL) ||
2138e7801d59Ssowmini 	    (prop_val != NULL && val_cnt == 0))
2139e7801d59Ssowmini 		return (DLADM_STATUS_BADARG);
2140e7801d59Ssowmini 	p = dladm_name2prop(prop_name);
21413fd94f8cSam223141 	if (p->pp_id != MAC_PROP_PRIVATE)
2142e7801d59Ssowmini 		return (DLADM_STATUS_BADARG);
2143e7801d59Ssowmini 
2144e7801d59Ssowmini 	/*
2145e7801d59Ssowmini 	 * private properties: all parsing is done in the kernel.
2146e7801d59Ssowmini 	 * allocate a enough space for each property + its separator (',').
2147e7801d59Ssowmini 	 */
2148e7801d59Ssowmini 	for (i = 0; i < val_cnt; i++) {
2149e7801d59Ssowmini 		bufsize += strlen(prop_val[i]) + 1;
2150e7801d59Ssowmini 	}
21514045d941Ssowmini 
21524045d941Ssowmini 	if (prop_val == NULL) {
21534045d941Ssowmini 		/*
21544045d941Ssowmini 		 * getting default value. so use more buffer space.
21554045d941Ssowmini 		 */
2156bcb5c89dSSowmini Varadhan 		bufsize += DLADM_PROP_BUF_CHUNK;
21574045d941Ssowmini 	}
21584045d941Ssowmini 
2159bcb5c89dSSowmini Varadhan 	dip = i_dladm_buf_alloc_by_name(bufsize + 1, linkid, prop_name,
21603fd94f8cSam223141 	    (prop_val != NULL ? 0 : MAC_PROP_DEFAULT), &status);
2161e7801d59Ssowmini 	if (dip == NULL)
2162e7801d59Ssowmini 		return (status);
2163e7801d59Ssowmini 
2164e7801d59Ssowmini 	dp = (uchar_t *)dip->pr_val;
2165e7801d59Ssowmini 	slen = 0;
2166bcb5c89dSSowmini Varadhan 
21674045d941Ssowmini 	if (prop_val == NULL) {
2168bcb5c89dSSowmini Varadhan 		status = i_dladm_macprop(dip, B_FALSE);
21694045d941Ssowmini 	} else {
2170e7801d59Ssowmini 		for (i = 0; i < val_cnt; i++) {
2171e7801d59Ssowmini 			int plen = 0;
2172e7801d59Ssowmini 
2173e7801d59Ssowmini 			plen = strlen(prop_val[i]);
2174e7801d59Ssowmini 			bcopy(prop_val[i], dp, plen);
2175e7801d59Ssowmini 			slen += plen;
2176e7801d59Ssowmini 			/*
2177e7801d59Ssowmini 			 * add a "," separator and update dp.
2178e7801d59Ssowmini 			 */
2179e7801d59Ssowmini 			if (i != (val_cnt -1))
2180e7801d59Ssowmini 				dp[slen++] = ',';
2181e7801d59Ssowmini 			dp += (plen + 1);
2182e7801d59Ssowmini 		}
2183bcb5c89dSSowmini Varadhan 		status = i_dladm_macprop(dip, B_TRUE);
2184e7801d59Ssowmini 	}
21854045d941Ssowmini 
2186e7801d59Ssowmini 	free(dip);
2187e7801d59Ssowmini 	return (status);
2188e7801d59Ssowmini }
2189e7801d59Ssowmini 
2190e7801d59Ssowmini static dladm_status_t
21913bc21d0aSAruna Ramakrishna - Sun Microsystems i_dladm_get_prop(datalink_id_t linkid, const char *prop_name,
21924045d941Ssowmini     char **prop_val, uint_t *val_cnt, dladm_prop_type_t type, uint_t dld_flags)
2193e7801d59Ssowmini {
2194e7801d59Ssowmini 	dladm_status_t	status = DLADM_STATUS_OK;
21953fd94f8cSam223141 	dld_ioc_macprop_t *dip = NULL;
2196bcb5c89dSSowmini Varadhan 	link_attr_t *p;
2197e7801d59Ssowmini 	char tmp = '\0';
2198e7801d59Ssowmini 
2199e7801d59Ssowmini 	if ((prop_name == NULL && prop_val != NULL) ||
2200e7801d59Ssowmini 	    (prop_val != NULL && val_cnt == 0))
2201e7801d59Ssowmini 		return (DLADM_STATUS_BADARG);
2202e7801d59Ssowmini 
2203e7801d59Ssowmini 	p = dladm_name2prop(prop_name);
22043fd94f8cSam223141 	if (p->pp_id != MAC_PROP_PRIVATE)
2205e7801d59Ssowmini 		return (DLADM_STATUS_BADARG);
2206e7801d59Ssowmini 
22074045d941Ssowmini 	if (type == DLADM_PROP_VAL_MODIFIABLE) {
2208e7801d59Ssowmini 		*prop_val = &tmp;
2209e7801d59Ssowmini 		*val_cnt = 1;
2210e7801d59Ssowmini 		return (DLADM_STATUS_OK);
2211e7801d59Ssowmini 	}
2212e7801d59Ssowmini 
2213e7801d59Ssowmini 	/*
2214e7801d59Ssowmini 	 * private properties: all parsing is done in the kernel.
2215e7801d59Ssowmini 	 */
2216bcb5c89dSSowmini Varadhan 	dip = i_dladm_buf_alloc_by_name(DLADM_PROP_BUF_CHUNK, linkid, prop_name,
2217bcb5c89dSSowmini Varadhan 	    dld_flags, &status);
2218e7801d59Ssowmini 	if (dip == NULL)
2219e7801d59Ssowmini 		return (status);
2220e7801d59Ssowmini 
2221bcb5c89dSSowmini Varadhan 	if ((status = i_dladm_macprop(dip, B_FALSE)) == DLADM_STATUS_OK) {
2222*afdda45fSVasumathi Sundaram - Sun Microsystems 		if (type == DLADM_PROP_VAL_PERM) {
2223*afdda45fSVasumathi Sundaram - Sun Microsystems 			switch (dip->pr_perm_flags) {
2224*afdda45fSVasumathi Sundaram - Sun Microsystems 				case MAC_PROP_PERM_READ:
2225*afdda45fSVasumathi Sundaram - Sun Microsystems 					(void) strncpy(*prop_val,
2226*afdda45fSVasumathi Sundaram - Sun Microsystems 					    PERM_READ_ONLY, DLADM_PROP_VAL_MAX);
2227*afdda45fSVasumathi Sundaram - Sun Microsystems 					break;
2228*afdda45fSVasumathi Sundaram - Sun Microsystems 				case MAC_PROP_PERM_RW:
2229*afdda45fSVasumathi Sundaram - Sun Microsystems 					(void) strncpy(*prop_val,
2230*afdda45fSVasumathi Sundaram - Sun Microsystems 					    PERM_READ_WRITE,
2231*afdda45fSVasumathi Sundaram - Sun Microsystems 					    DLADM_PROP_VAL_MAX);
2232*afdda45fSVasumathi Sundaram - Sun Microsystems 					break;
2233*afdda45fSVasumathi Sundaram - Sun Microsystems 			}
2234*afdda45fSVasumathi Sundaram - Sun Microsystems 		} else {
2235*afdda45fSVasumathi Sundaram - Sun Microsystems 			(void) strncpy(*prop_val, dip->pr_val,
2236*afdda45fSVasumathi Sundaram - Sun Microsystems 			    DLADM_PROP_VAL_MAX);
2237*afdda45fSVasumathi Sundaram - Sun Microsystems 		}
2238e7801d59Ssowmini 		*val_cnt = 1;
2239e7801d59Ssowmini 	}
22404045d941Ssowmini 	free(dip);
22414045d941Ssowmini 	return (status);
22424045d941Ssowmini }
22434045d941Ssowmini 
22444045d941Ssowmini 
22454045d941Ssowmini static dladm_status_t
22464045d941Ssowmini i_dladm_getset_defval(prop_desc_t *pdp, datalink_id_t linkid,
22474045d941Ssowmini     datalink_media_t media, uint_t flags)
22484045d941Ssowmini {
22494045d941Ssowmini 	dladm_status_t status;
22504045d941Ssowmini 	char **prop_vals = NULL, *buf;
22514045d941Ssowmini 	size_t bufsize;
22524045d941Ssowmini 	uint_t cnt;
22534045d941Ssowmini 	int i;
2254*afdda45fSVasumathi Sundaram - Sun Microsystems 	uint_t perm_flags;
22554045d941Ssowmini 
22564045d941Ssowmini 	/*
22574045d941Ssowmini 	 * Allocate buffer needed for prop_vals array. We can have at most
22584045d941Ssowmini 	 * DLADM_MAX_PROP_VALCNT char *prop_vals[] entries, where
22594045d941Ssowmini 	 * each entry has max size DLADM_PROP_VAL_MAX
22604045d941Ssowmini 	 */
22614045d941Ssowmini 	bufsize =
22624045d941Ssowmini 	    (sizeof (char *) + DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT;
22634045d941Ssowmini 	buf = malloc(bufsize);
22644045d941Ssowmini 	prop_vals = (char **)(void *)buf;
22654045d941Ssowmini 	for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) {
22664045d941Ssowmini 		prop_vals[i] = buf +
22674045d941Ssowmini 		    sizeof (char *) * DLADM_MAX_PROP_VALCNT +
22684045d941Ssowmini 		    i * DLADM_PROP_VAL_MAX;
22694045d941Ssowmini 	}
227013a55820Sar224390 
227113a55820Sar224390 	/*
22723bc21d0aSAruna Ramakrishna - Sun Microsystems 	 * For properties which have pdp->pd_defval.vd_name as a non-empty
22733bc21d0aSAruna Ramakrishna - Sun Microsystems 	 * string, the "" itself is used to reset the property (exceptions
22743bc21d0aSAruna Ramakrishna - Sun Microsystems 	 * are zone and autopush, which populate vdp->vd_val). So
22753bc21d0aSAruna Ramakrishna - Sun Microsystems 	 * libdladm can copy pdp->pd_defval over to the val_desc_t passed
22763bc21d0aSAruna Ramakrishna - Sun Microsystems 	 * down on the setprop using the global values in the table. For
22773bc21d0aSAruna Ramakrishna - Sun Microsystems 	 * other cases (vd_name is ""), doing reset-linkprop will cause
22783bc21d0aSAruna Ramakrishna - Sun Microsystems 	 * libdladm to do a getprop to find the default value and then do
22793bc21d0aSAruna Ramakrishna - Sun Microsystems 	 * a setprop to reset the value to default.
228013a55820Sar224390 	 */
22813fd94f8cSam223141 	status = pdp->pd_get(pdp, linkid, prop_vals, &cnt, media,
2282*afdda45fSVasumathi Sundaram - Sun Microsystems 	    MAC_PROP_DEFAULT, &perm_flags);
22834045d941Ssowmini 	if (status == DLADM_STATUS_OK) {
2284*afdda45fSVasumathi Sundaram - Sun Microsystems 		if (perm_flags == MAC_PROP_PERM_RW) {
22854045d941Ssowmini 			status = i_dladm_set_single_prop(linkid, pdp->pd_class,
22864045d941Ssowmini 			    media, pdp, prop_vals, cnt, flags);
22874045d941Ssowmini 		}
2288*afdda45fSVasumathi Sundaram - Sun Microsystems 		else
2289*afdda45fSVasumathi Sundaram - Sun Microsystems 			status = DLADM_STATUS_NOTSUP;
2290*afdda45fSVasumathi Sundaram - Sun Microsystems 	}
22914045d941Ssowmini 	free(buf);
2292e7801d59Ssowmini 	return (status);
2293e7801d59Ssowmini }
2294bcb5c89dSSowmini Varadhan 
2295bcb5c89dSSowmini Varadhan int
2296bcb5c89dSSowmini Varadhan macprop_to_wifi(mac_prop_id_t wl_prop)
2297bcb5c89dSSowmini Varadhan {
2298bcb5c89dSSowmini Varadhan 	switch (wl_prop) {
2299bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_ESSID:
2300bcb5c89dSSowmini Varadhan 		return (WL_ESSID);
2301bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_BSSID:
2302bcb5c89dSSowmini Varadhan 		return (WL_BSSID);
2303bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_BSSTYPE:
2304bcb5c89dSSowmini Varadhan 		return (WL_BSS_TYPE);
2305bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_LINKSTATUS:
2306bcb5c89dSSowmini Varadhan 		return (WL_LINKSTATUS);
2307bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_DESIRED_RATES:
2308bcb5c89dSSowmini Varadhan 		return (WL_DESIRED_RATES);
2309bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_SUPPORTED_RATES:
2310bcb5c89dSSowmini Varadhan 		return (WL_SUPPORTED_RATES);
2311bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_AUTH_MODE:
2312bcb5c89dSSowmini Varadhan 		return (WL_AUTH_MODE);
2313bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_ENCRYPTION:
2314bcb5c89dSSowmini Varadhan 		return (WL_ENCRYPTION);
2315bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_RSSI:
2316bcb5c89dSSowmini Varadhan 		return (WL_RSSI);
2317bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_PHY_CONFIG:
2318bcb5c89dSSowmini Varadhan 		return (WL_PHY_CONFIG);
2319bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_CAPABILITY:
2320bcb5c89dSSowmini Varadhan 		return (WL_CAPABILITY);
2321bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_WPA:
2322bcb5c89dSSowmini Varadhan 		return (WL_WPA);
2323bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_SCANRESULTS:
2324bcb5c89dSSowmini Varadhan 		return (WL_SCANRESULTS);
2325bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_POWER_MODE:
2326bcb5c89dSSowmini Varadhan 		return (WL_POWER_MODE);
2327bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_RADIO:
2328bcb5c89dSSowmini Varadhan 		return (WL_RADIO);
2329bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_ESS_LIST:
2330bcb5c89dSSowmini Varadhan 		return (WL_ESS_LIST);
2331bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_KEY_TAB:
2332bcb5c89dSSowmini Varadhan 		return (WL_WEP_KEY_TAB);
2333bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_CREATE_IBSS:
2334bcb5c89dSSowmini Varadhan 		return (WL_CREATE_IBSS);
2335bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_SETOPTIE:
2336bcb5c89dSSowmini Varadhan 		return (WL_SETOPTIE);
2337bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_DELKEY:
2338bcb5c89dSSowmini Varadhan 		return (WL_DELKEY);
2339bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_KEY:
2340bcb5c89dSSowmini Varadhan 		return (WL_KEY);
2341bcb5c89dSSowmini Varadhan 	case MAC_PROP_WL_MLME:
2342bcb5c89dSSowmini Varadhan 		return (WL_MLME);
2343bcb5c89dSSowmini Varadhan 	default:
2344bcb5c89dSSowmini Varadhan 		return (-1);
2345bcb5c89dSSowmini Varadhan 	}
2346bcb5c89dSSowmini Varadhan }
2347bcb5c89dSSowmini Varadhan 
2348bcb5c89dSSowmini Varadhan dladm_status_t
2349bcb5c89dSSowmini Varadhan i_dladm_wlan_param(datalink_id_t linkid, void *buf, mac_prop_id_t cmd,
2350bcb5c89dSSowmini Varadhan     size_t len, boolean_t set)
2351bcb5c89dSSowmini Varadhan {
2352bcb5c89dSSowmini Varadhan 	uint32_t		flags;
2353bcb5c89dSSowmini Varadhan 	dladm_status_t		status;
2354bcb5c89dSSowmini Varadhan 	uint32_t		media;
2355bcb5c89dSSowmini Varadhan 	dld_ioc_macprop_t	*dip;
2356bcb5c89dSSowmini Varadhan 	void			*dp;
2357bcb5c89dSSowmini Varadhan 
2358bcb5c89dSSowmini Varadhan 	if ((status = dladm_datalink_id2info(linkid, &flags, NULL, &media,
2359bcb5c89dSSowmini Varadhan 	    NULL, 0)) != DLADM_STATUS_OK) {
2360bcb5c89dSSowmini Varadhan 		return (status);
2361bcb5c89dSSowmini Varadhan 	}
2362bcb5c89dSSowmini Varadhan 
2363bcb5c89dSSowmini Varadhan 	if (media != DL_WIFI)
2364bcb5c89dSSowmini Varadhan 		return (DLADM_STATUS_BADARG);
2365bcb5c89dSSowmini Varadhan 
2366bcb5c89dSSowmini Varadhan 	if (!(flags & DLADM_OPT_ACTIVE))
2367bcb5c89dSSowmini Varadhan 		return (DLADM_STATUS_TEMPONLY);
2368bcb5c89dSSowmini Varadhan 
2369bcb5c89dSSowmini Varadhan 	if (len == (MAX_BUF_LEN - WIFI_BUF_OFFSET))
2370bcb5c89dSSowmini Varadhan 		len = MAX_BUF_LEN - sizeof (dld_ioc_macprop_t) - 1;
2371bcb5c89dSSowmini Varadhan 
2372bcb5c89dSSowmini Varadhan 	dip = i_dladm_buf_alloc_by_id(len, linkid, cmd, 0, &status);
2373bcb5c89dSSowmini Varadhan 	if (dip == NULL)
2374bcb5c89dSSowmini Varadhan 		return (DLADM_STATUS_NOMEM);
2375bcb5c89dSSowmini Varadhan 
2376bcb5c89dSSowmini Varadhan 	dp = (uchar_t *)dip->pr_val;
2377bcb5c89dSSowmini Varadhan 	if (set)
2378bcb5c89dSSowmini Varadhan 		(void) memcpy(dp, buf, len);
2379bcb5c89dSSowmini Varadhan 
2380bcb5c89dSSowmini Varadhan 	status = i_dladm_macprop(dip, set);
2381bcb5c89dSSowmini Varadhan 	if (status == DLADM_STATUS_NOTSUP) {
2382bcb5c89dSSowmini Varadhan 		if (set) {
2383bcb5c89dSSowmini Varadhan 			status = i_dladm_wlan_set_legacy_ioctl(linkid,
2384bcb5c89dSSowmini Varadhan 			    buf, len, macprop_to_wifi(cmd));
2385bcb5c89dSSowmini Varadhan 		} else {
2386bcb5c89dSSowmini Varadhan 			status = i_dladm_wlan_get_legacy_ioctl(linkid,
2387bcb5c89dSSowmini Varadhan 			    buf, len, macprop_to_wifi(cmd));
2388bcb5c89dSSowmini Varadhan 		}
2389bcb5c89dSSowmini Varadhan 	} else if (status == DLADM_STATUS_OK) {
2390bcb5c89dSSowmini Varadhan 		if (!set)
2391bcb5c89dSSowmini Varadhan 			(void) memcpy(buf, dp, len);
2392bcb5c89dSSowmini Varadhan 	}
2393bcb5c89dSSowmini Varadhan 
2394bcb5c89dSSowmini Varadhan 	free(dip);
2395bcb5c89dSSowmini Varadhan 	return (status);
2396bcb5c89dSSowmini Varadhan }
2397bcb5c89dSSowmini Varadhan 
2398bcb5c89dSSowmini Varadhan static dladm_status_t
2399bcb5c89dSSowmini Varadhan i_dladm_wlan_get_legacy_ioctl(datalink_id_t linkid, void *buf, uint_t buflen,
2400bcb5c89dSSowmini Varadhan     uint_t id)
2401bcb5c89dSSowmini Varadhan {
2402bcb5c89dSSowmini Varadhan 	wldp_t *gbuf;
2403bcb5c89dSSowmini Varadhan 	dladm_status_t status;
2404bcb5c89dSSowmini Varadhan 
2405bcb5c89dSSowmini Varadhan 	if ((gbuf = malloc(MAX_BUF_LEN)) == NULL)
2406bcb5c89dSSowmini Varadhan 		return (DLADM_STATUS_NOMEM);
2407bcb5c89dSSowmini Varadhan 
2408bcb5c89dSSowmini Varadhan 	(void) memset(gbuf, 0, MAX_BUF_LEN);
2409bcb5c89dSSowmini Varadhan 	status = i_dladm_wlan_legacy_ioctl(linkid, gbuf, id, MAX_BUF_LEN,
2410bcb5c89dSSowmini Varadhan 	    WLAN_GET_PARAM, sizeof (wldp_t));
2411bcb5c89dSSowmini Varadhan 	if (status == DLADM_STATUS_OK)
2412bcb5c89dSSowmini Varadhan 		(void) memcpy(buf, gbuf->wldp_buf, buflen);
2413bcb5c89dSSowmini Varadhan 
2414bcb5c89dSSowmini Varadhan 	free(gbuf);
2415bcb5c89dSSowmini Varadhan 	return (status);
2416bcb5c89dSSowmini Varadhan }
2417bcb5c89dSSowmini Varadhan 
2418bcb5c89dSSowmini Varadhan static dladm_status_t
2419bcb5c89dSSowmini Varadhan i_dladm_wlan_set_legacy_ioctl(datalink_id_t linkid,  void *buf, uint_t buflen,
2420bcb5c89dSSowmini Varadhan     uint_t id)
2421bcb5c89dSSowmini Varadhan {
2422bcb5c89dSSowmini Varadhan 	wldp_t *gbuf;
2423bcb5c89dSSowmini Varadhan 	dladm_status_t status = DLADM_STATUS_OK;
2424bcb5c89dSSowmini Varadhan 
2425bcb5c89dSSowmini Varadhan 	if ((gbuf = malloc(MAX_BUF_LEN)) == NULL)
2426bcb5c89dSSowmini Varadhan 		return (DLADM_STATUS_NOMEM);
2427bcb5c89dSSowmini Varadhan 
2428bcb5c89dSSowmini Varadhan 	(void) memset(gbuf, 0, MAX_BUF_LEN);
2429bcb5c89dSSowmini Varadhan 	(void) memcpy(gbuf->wldp_buf, buf, buflen);
2430bcb5c89dSSowmini Varadhan 	buflen += WIFI_BUF_OFFSET;
2431bcb5c89dSSowmini Varadhan 	status = i_dladm_wlan_legacy_ioctl(linkid, gbuf, id, buflen,
2432bcb5c89dSSowmini Varadhan 	    WLAN_SET_PARAM, buflen);
2433bcb5c89dSSowmini Varadhan 
2434bcb5c89dSSowmini Varadhan 	free(gbuf);
2435bcb5c89dSSowmini Varadhan 	return (status);
2436bcb5c89dSSowmini Varadhan }
2437