19da57d7bSbt /*
29da57d7bSbt  * CDDL HEADER START
39da57d7bSbt  *
49da57d7bSbt  * The contents of this file are subject to the terms of the
59da57d7bSbt  * Common Development and Distribution License (the "License").
69da57d7bSbt  * You may not use this file except in compliance with the License.
79da57d7bSbt  *
8da14cebeSEric Cheng  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da14cebeSEric Cheng  * or http://www.opensolaris.org/os/licensing.
109da57d7bSbt  * See the License for the specific language governing permissions
119da57d7bSbt  * and limitations under the License.
129da57d7bSbt  *
13da14cebeSEric Cheng  * When distributing Covered Code, include this CDDL HEADER in each
14da14cebeSEric Cheng  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159da57d7bSbt  * If applicable, add the following below this CDDL HEADER, with the
169da57d7bSbt  * fields enclosed by brackets "[]" replaced with your own identifying
179da57d7bSbt  * information: Portions Copyright [yyyy] [name of copyright owner]
189da57d7bSbt  *
199da57d7bSbt  * CDDL HEADER END
209da57d7bSbt  */
219da57d7bSbt 
229da57d7bSbt /*
235b6dd21fSchenlu chen - Sun Microsystems - Beijing China  * Copyright(c) 2007-2010 Intel Corporation. All rights reserved.
245b6dd21fSchenlu chen - Sun Microsystems - Beijing China  */
255b6dd21fSchenlu chen - Sun Microsystems - Beijing China 
265b6dd21fSchenlu chen - Sun Microsystems - Beijing China /*
275b6dd21fSchenlu chen - Sun Microsystems - Beijing China  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
2869b5a878SDan McDonald  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
29238d8f47SDale Ghent  * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved.
30bb54aa20SJohn Levon  * Copyright (c) 2019, Joyent, Inc.
31da14cebeSEric Cheng  */
329da57d7bSbt 
339da57d7bSbt #include "ixgbe_sw.h"
349da57d7bSbt 
359da57d7bSbt /*
369da57d7bSbt  * Bring the device out of the reset/quiesced state that it
379da57d7bSbt  * was in when the interface was registered.
389da57d7bSbt  */
399da57d7bSbt int
ixgbe_m_start(void * arg)409da57d7bSbt ixgbe_m_start(void *arg)
419da57d7bSbt {
429da57d7bSbt 	ixgbe_t *ixgbe = (ixgbe_t *)arg;
439da57d7bSbt 
449da57d7bSbt 	mutex_enter(&ixgbe->gen_lock);
459da57d7bSbt 
469da57d7bSbt 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
479da57d7bSbt 		mutex_exit(&ixgbe->gen_lock);
489da57d7bSbt 		return (ECANCELED);
499da57d7bSbt 	}
509da57d7bSbt 
51ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (ixgbe_start(ixgbe, B_TRUE) != IXGBE_SUCCESS) {
529da57d7bSbt 		mutex_exit(&ixgbe->gen_lock);
539da57d7bSbt 		return (EIO);
549da57d7bSbt 	}
559da57d7bSbt 
5662e6e1adSPaul Guo 	atomic_or_32(&ixgbe->ixgbe_state, IXGBE_STARTED);
579da57d7bSbt 
589da57d7bSbt 	mutex_exit(&ixgbe->gen_lock);
599da57d7bSbt 
609da57d7bSbt 	/*
619da57d7bSbt 	 * Enable and start the watchdog timer
629da57d7bSbt 	 */
639da57d7bSbt 	ixgbe_enable_watchdog_timer(ixgbe);
649da57d7bSbt 
659da57d7bSbt 	return (0);
669da57d7bSbt }
679da57d7bSbt 
689da57d7bSbt /*
699da57d7bSbt  * Stop the device and put it in a reset/quiesced state such
709da57d7bSbt  * that the interface can be unregistered.
719da57d7bSbt  */
729da57d7bSbt void
ixgbe_m_stop(void * arg)739da57d7bSbt ixgbe_m_stop(void *arg)
749da57d7bSbt {
759da57d7bSbt 	ixgbe_t *ixgbe = (ixgbe_t *)arg;
769da57d7bSbt 
779da57d7bSbt 	mutex_enter(&ixgbe->gen_lock);
789da57d7bSbt 
799da57d7bSbt 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
809da57d7bSbt 		mutex_exit(&ixgbe->gen_lock);
819da57d7bSbt 		return;
829da57d7bSbt 	}
839da57d7bSbt 
8462e6e1adSPaul Guo 	atomic_and_32(&ixgbe->ixgbe_state, ~IXGBE_STARTED);
859da57d7bSbt 
86ea65739eSchenlu chen - Sun Microsystems - Beijing China 	ixgbe_stop(ixgbe, B_TRUE);
879da57d7bSbt 
889da57d7bSbt 	mutex_exit(&ixgbe->gen_lock);
899da57d7bSbt 
909da57d7bSbt 	/*
919da57d7bSbt 	 * Disable and stop the watchdog timer
929da57d7bSbt 	 */
939da57d7bSbt 	ixgbe_disable_watchdog_timer(ixgbe);
949da57d7bSbt }
959da57d7bSbt 
969da57d7bSbt /*
979da57d7bSbt  * Set the promiscuity of the device.
989da57d7bSbt  */
999da57d7bSbt int
ixgbe_m_promisc(void * arg,boolean_t on)1009da57d7bSbt ixgbe_m_promisc(void *arg, boolean_t on)
1019da57d7bSbt {
1029da57d7bSbt 	ixgbe_t *ixgbe = (ixgbe_t *)arg;
1039da57d7bSbt 	uint32_t reg_val;
1049da57d7bSbt 	struct ixgbe_hw *hw = &ixgbe->hw;
1059da57d7bSbt 
1069da57d7bSbt 	mutex_enter(&ixgbe->gen_lock);
1079da57d7bSbt 
1089da57d7bSbt 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
1099da57d7bSbt 		mutex_exit(&ixgbe->gen_lock);
1109da57d7bSbt 		return (ECANCELED);
1119da57d7bSbt 	}
1129da57d7bSbt 	reg_val = IXGBE_READ_REG(hw, IXGBE_FCTRL);
1139da57d7bSbt 
1149da57d7bSbt 	if (on)
1159da57d7bSbt 		reg_val |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
1169da57d7bSbt 	else
1179da57d7bSbt 		reg_val &= (~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE));
1189da57d7bSbt 
1199da57d7bSbt 	IXGBE_WRITE_REG(&ixgbe->hw, IXGBE_FCTRL, reg_val);
1209da57d7bSbt 
1219da57d7bSbt 	mutex_exit(&ixgbe->gen_lock);
1229da57d7bSbt 
1239da57d7bSbt 	return (0);
1249da57d7bSbt }
1259da57d7bSbt 
1269da57d7bSbt /*
1279da57d7bSbt  * Add/remove the addresses to/from the set of multicast
1289da57d7bSbt  * addresses for which the device will receive packets.
1299da57d7bSbt  */
1309da57d7bSbt int
ixgbe_m_multicst(void * arg,boolean_t add,const uint8_t * mcst_addr)1319da57d7bSbt ixgbe_m_multicst(void *arg, boolean_t add, const uint8_t *mcst_addr)
1329da57d7bSbt {
1339da57d7bSbt 	ixgbe_t *ixgbe = (ixgbe_t *)arg;
1349da57d7bSbt 	int result;
1359da57d7bSbt 
1369da57d7bSbt 	mutex_enter(&ixgbe->gen_lock);
1379da57d7bSbt 
1389da57d7bSbt 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
1399da57d7bSbt 		mutex_exit(&ixgbe->gen_lock);
1409da57d7bSbt 		return (ECANCELED);
1419da57d7bSbt 	}
1429da57d7bSbt 
1439da57d7bSbt 	result = (add) ? ixgbe_multicst_add(ixgbe, mcst_addr)
1449da57d7bSbt 	    : ixgbe_multicst_remove(ixgbe, mcst_addr);
1459da57d7bSbt 
1469da57d7bSbt 	mutex_exit(&ixgbe->gen_lock);
1479da57d7bSbt 
1489da57d7bSbt 	return (result);
1499da57d7bSbt }
1509da57d7bSbt 
1519da57d7bSbt /*
1529da57d7bSbt  * Pass on M_IOCTL messages passed to the DLD, and support
1539da57d7bSbt  * private IOCTLs for debugging and ndd.
1549da57d7bSbt  */
1559da57d7bSbt void
ixgbe_m_ioctl(void * arg,queue_t * q,mblk_t * mp)1569da57d7bSbt ixgbe_m_ioctl(void *arg, queue_t *q, mblk_t *mp)
1579da57d7bSbt {
1589da57d7bSbt 	ixgbe_t *ixgbe = (ixgbe_t *)arg;
1599da57d7bSbt 	struct iocblk *iocp;
1609da57d7bSbt 	enum ioc_reply status;
1619da57d7bSbt 
1629da57d7bSbt 	iocp = (struct iocblk *)(uintptr_t)mp->b_rptr;
1639da57d7bSbt 	iocp->ioc_error = 0;
1649da57d7bSbt 
165ea65739eSchenlu chen - Sun Microsystems - Beijing China 	mutex_enter(&ixgbe->gen_lock);
166ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
167ea65739eSchenlu chen - Sun Microsystems - Beijing China 		mutex_exit(&ixgbe->gen_lock);
168ea65739eSchenlu chen - Sun Microsystems - Beijing China 		miocnak(q, mp, 0, EINVAL);
169ea65739eSchenlu chen - Sun Microsystems - Beijing China 		return;
170ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
171ea65739eSchenlu chen - Sun Microsystems - Beijing China 	mutex_exit(&ixgbe->gen_lock);
172ea65739eSchenlu chen - Sun Microsystems - Beijing China 
1739da57d7bSbt 	switch (iocp->ioc_cmd) {
1749da57d7bSbt 	case LB_GET_INFO_SIZE:
1759da57d7bSbt 	case LB_GET_INFO:
1769da57d7bSbt 	case LB_GET_MODE:
1779da57d7bSbt 	case LB_SET_MODE:
1789da57d7bSbt 		status = ixgbe_loopback_ioctl(ixgbe, iocp, mp);
1799da57d7bSbt 		break;
1809da57d7bSbt 
1819da57d7bSbt 	default:
1829da57d7bSbt 		status = IOC_INVAL;
1839da57d7bSbt 		break;
1849da57d7bSbt 	}
1859da57d7bSbt 
1869da57d7bSbt 	/*
1879da57d7bSbt 	 * Decide how to reply
1889da57d7bSbt 	 */
1899da57d7bSbt 	switch (status) {
1909da57d7bSbt 	default:
1919da57d7bSbt 	case IOC_INVAL:
1929da57d7bSbt 		/*
1939da57d7bSbt 		 * Error, reply with a NAK and EINVAL or the specified error
1949da57d7bSbt 		 */
1959da57d7bSbt 		miocnak(q, mp, 0, iocp->ioc_error == 0 ?
1969da57d7bSbt 		    EINVAL : iocp->ioc_error);
1979da57d7bSbt 		break;
1989da57d7bSbt 
1999da57d7bSbt 	case IOC_DONE:
2009da57d7bSbt 		/*
2019da57d7bSbt 		 * OK, reply already sent
2029da57d7bSbt 		 */
2039da57d7bSbt 		break;
2049da57d7bSbt 
2059da57d7bSbt 	case IOC_ACK:
2069da57d7bSbt 		/*
2079da57d7bSbt 		 * OK, reply with an ACK
2089da57d7bSbt 		 */
2099da57d7bSbt 		miocack(q, mp, 0, 0);
2109da57d7bSbt 		break;
2119da57d7bSbt 
2129da57d7bSbt 	case IOC_REPLY:
2139da57d7bSbt 		/*
2149da57d7bSbt 		 * OK, send prepared reply as ACK or NAK
2159da57d7bSbt 		 */
2169da57d7bSbt 		mp->b_datap->db_type = iocp->ioc_error == 0 ?
2179da57d7bSbt 		    M_IOCACK : M_IOCNAK;
2189da57d7bSbt 		qreply(q, mp);
2199da57d7bSbt 		break;
2209da57d7bSbt 	}
2219da57d7bSbt }
2229da57d7bSbt 
22337367bbaSRobert Mustacchi static int
ixgbe_led_set(void * arg,mac_led_mode_t mode,uint_t flags)22437367bbaSRobert Mustacchi ixgbe_led_set(void *arg, mac_led_mode_t mode, uint_t flags)
22537367bbaSRobert Mustacchi {
22637367bbaSRobert Mustacchi 	ixgbe_t *ixgbe = arg;
22737367bbaSRobert Mustacchi 	struct ixgbe_hw *hw = &ixgbe->hw;
22837367bbaSRobert Mustacchi 	uint32_t lidx = ixgbe->ixgbe_led_index;
22937367bbaSRobert Mustacchi 
23037367bbaSRobert Mustacchi 	if (flags != 0)
23137367bbaSRobert Mustacchi 		return (EINVAL);
23237367bbaSRobert Mustacchi 
23337367bbaSRobert Mustacchi 	if (mode != MAC_LED_DEFAULT &&
23437367bbaSRobert Mustacchi 	    mode != MAC_LED_IDENT &&
23537367bbaSRobert Mustacchi 	    mode != MAC_LED_OFF &&
23637367bbaSRobert Mustacchi 	    mode != MAC_LED_ON)
23737367bbaSRobert Mustacchi 		return (ENOTSUP);
23837367bbaSRobert Mustacchi 
23937367bbaSRobert Mustacchi 	if (ixgbe->ixgbe_led_blink && mode != MAC_LED_IDENT) {
24037367bbaSRobert Mustacchi 		if (ixgbe_blink_led_stop(hw, lidx) != IXGBE_SUCCESS) {
24137367bbaSRobert Mustacchi 			return (EIO);
24237367bbaSRobert Mustacchi 		}
24337367bbaSRobert Mustacchi 		ixgbe->ixgbe_led_blink = B_FALSE;
24437367bbaSRobert Mustacchi 	}
24537367bbaSRobert Mustacchi 
24637367bbaSRobert Mustacchi 	if (mode != MAC_LED_DEFAULT && !ixgbe->ixgbe_led_active) {
24737367bbaSRobert Mustacchi 		ixgbe->ixgbe_led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
24837367bbaSRobert Mustacchi 		ixgbe->ixgbe_led_active = B_TRUE;
24937367bbaSRobert Mustacchi 	}
25037367bbaSRobert Mustacchi 
25137367bbaSRobert Mustacchi 	switch (mode) {
25237367bbaSRobert Mustacchi 	case MAC_LED_DEFAULT:
25337367bbaSRobert Mustacchi 		if (ixgbe->ixgbe_led_active) {
25437367bbaSRobert Mustacchi 			IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ixgbe->ixgbe_led_reg);
25537367bbaSRobert Mustacchi 			ixgbe->ixgbe_led_active = B_FALSE;
25637367bbaSRobert Mustacchi 		}
25737367bbaSRobert Mustacchi 		break;
25837367bbaSRobert Mustacchi 	case MAC_LED_IDENT:
25937367bbaSRobert Mustacchi 		if (ixgbe_blink_led_start(hw, lidx) != IXGBE_SUCCESS)
26037367bbaSRobert Mustacchi 			return (EIO);
26137367bbaSRobert Mustacchi 		ixgbe->ixgbe_led_blink = B_TRUE;
26237367bbaSRobert Mustacchi 		break;
26337367bbaSRobert Mustacchi 	case MAC_LED_OFF:
26437367bbaSRobert Mustacchi 		if (ixgbe_led_off(hw, lidx) != IXGBE_SUCCESS)
26537367bbaSRobert Mustacchi 			return (EIO);
26637367bbaSRobert Mustacchi 		break;
26737367bbaSRobert Mustacchi 	case MAC_LED_ON:
26837367bbaSRobert Mustacchi 		if (ixgbe_led_on(hw, lidx) != IXGBE_SUCCESS)
26937367bbaSRobert Mustacchi 			return (EIO);
27037367bbaSRobert Mustacchi 		break;
27137367bbaSRobert Mustacchi 	default:
27237367bbaSRobert Mustacchi 		return (ENOTSUP);
27337367bbaSRobert Mustacchi 	}
27437367bbaSRobert Mustacchi 
27537367bbaSRobert Mustacchi 	return (0);
27637367bbaSRobert Mustacchi }
27737367bbaSRobert Mustacchi 
2789da57d7bSbt /*
2799da57d7bSbt  * Obtain the MAC's capabilities and associated data from
2809da57d7bSbt  * the driver.
2819da57d7bSbt  */
2829da57d7bSbt boolean_t
ixgbe_m_getcapab(void * arg,mac_capab_t cap,void * cap_data)2839da57d7bSbt ixgbe_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
2849da57d7bSbt {
2859da57d7bSbt 	ixgbe_t *ixgbe = (ixgbe_t *)arg;
2869da57d7bSbt 
2879da57d7bSbt 	switch (cap) {
2889da57d7bSbt 	case MAC_CAPAB_HCKSUM: {
2899da57d7bSbt 		uint32_t *tx_hcksum_flags = cap_data;
2909da57d7bSbt 
2919da57d7bSbt 		/*
2929da57d7bSbt 		 * We advertise our capabilities only if tx hcksum offload is
2939da57d7bSbt 		 * enabled.  On receive, the stack will accept checksummed
2949da57d7bSbt 		 * packets anyway, even if we haven't said we can deliver
2959da57d7bSbt 		 * them.
2969da57d7bSbt 		 */
2979da57d7bSbt 		if (!ixgbe->tx_hcksum_enable)
2989da57d7bSbt 			return (B_FALSE);
2999da57d7bSbt 
3009da57d7bSbt 		*tx_hcksum_flags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM;
3019da57d7bSbt 		break;
3029da57d7bSbt 	}
303c971fb7eSgg 	case MAC_CAPAB_LSO: {
304c971fb7eSgg 		mac_capab_lso_t *cap_lso = cap_data;
305c971fb7eSgg 
306c971fb7eSgg 		if (ixgbe->lso_enable) {
30785f496faSRobert Mustacchi 			cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4 |
30885f496faSRobert Mustacchi 			    LSO_TX_BASIC_TCP_IPV6;
309c971fb7eSgg 			cap_lso->lso_basic_tcp_ipv4.lso_max = IXGBE_LSO_MAXLEN;
31085f496faSRobert Mustacchi 			cap_lso->lso_basic_tcp_ipv6.lso_max = IXGBE_LSO_MAXLEN;
311c971fb7eSgg 			break;
312c971fb7eSgg 		} else {
313c971fb7eSgg 			return (B_FALSE);
314c971fb7eSgg 		}
315c971fb7eSgg 	}
316da14cebeSEric Cheng 	case MAC_CAPAB_RINGS: {
317da14cebeSEric Cheng 		mac_capab_rings_t *cap_rings = cap_data;
318da14cebeSEric Cheng 
319da14cebeSEric Cheng 		switch (cap_rings->mr_type) {
320da14cebeSEric Cheng 		case MAC_RING_TYPE_RX:
321da14cebeSEric Cheng 			cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
322da14cebeSEric Cheng 			cap_rings->mr_rnum = ixgbe->num_rx_rings;
323da14cebeSEric Cheng 			cap_rings->mr_gnum = ixgbe->num_rx_groups;
324da14cebeSEric Cheng 			cap_rings->mr_rget = ixgbe_fill_ring;
325da14cebeSEric Cheng 			cap_rings->mr_gget = ixgbe_fill_group;
326da14cebeSEric Cheng 			cap_rings->mr_gaddring = NULL;
327da14cebeSEric Cheng 			cap_rings->mr_gremring = NULL;
328da14cebeSEric Cheng 			break;
329da14cebeSEric Cheng 		case MAC_RING_TYPE_TX:
330da14cebeSEric Cheng 			cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
331da14cebeSEric Cheng 			cap_rings->mr_rnum = ixgbe->num_tx_rings;
332da14cebeSEric Cheng 			cap_rings->mr_gnum = 0;
333da14cebeSEric Cheng 			cap_rings->mr_rget = ixgbe_fill_ring;
334da14cebeSEric Cheng 			cap_rings->mr_gget = NULL;
335da14cebeSEric Cheng 			break;
336da14cebeSEric Cheng 		default:
337da14cebeSEric Cheng 			break;
338da14cebeSEric Cheng 		}
3399da57d7bSbt 		break;
3409da57d7bSbt 	}
34145d3dd98SRobert Mustacchi 	case MAC_CAPAB_TRANSCEIVER: {
34245d3dd98SRobert Mustacchi 		mac_capab_transceiver_t *mct = cap_data;
34345d3dd98SRobert Mustacchi 
34445d3dd98SRobert Mustacchi 		/*
34545d3dd98SRobert Mustacchi 		 * Rather than try and guess based on the media type whether or
34645d3dd98SRobert Mustacchi 		 * not we have a transceiver we can read, we instead will let
34745d3dd98SRobert Mustacchi 		 * the actual function calls figure that out for us.
34845d3dd98SRobert Mustacchi 		 */
34945d3dd98SRobert Mustacchi 		mct->mct_flags = 0;
35045d3dd98SRobert Mustacchi 		mct->mct_ntransceivers = 1;
35145d3dd98SRobert Mustacchi 		mct->mct_info = ixgbe_transceiver_info;
35245d3dd98SRobert Mustacchi 		mct->mct_read = ixgbe_transceiver_read;
35345d3dd98SRobert Mustacchi 		return (B_TRUE);
35445d3dd98SRobert Mustacchi 	}
35537367bbaSRobert Mustacchi 	case MAC_CAPAB_LED: {
35637367bbaSRobert Mustacchi 		mac_capab_led_t *mcl = cap_data;
35737367bbaSRobert Mustacchi 
35837367bbaSRobert Mustacchi 		mcl->mcl_flags = 0;
35937367bbaSRobert Mustacchi 		mcl->mcl_modes = MAC_LED_DEFAULT | MAC_LED_ON | MAC_LED_OFF |
36037367bbaSRobert Mustacchi 		    MAC_LED_IDENT;
36137367bbaSRobert Mustacchi 		mcl->mcl_set = ixgbe_led_set;
36237367bbaSRobert Mustacchi 		break;
36337367bbaSRobert Mustacchi 
36437367bbaSRobert Mustacchi 	}
3659da57d7bSbt 	default:
3669da57d7bSbt 		return (B_FALSE);
3679da57d7bSbt 	}
3689da57d7bSbt 	return (B_TRUE);
3699da57d7bSbt }
370ea65739eSchenlu chen - Sun Microsystems - Beijing China 
371ea65739eSchenlu chen - Sun Microsystems - Beijing China int
ixgbe_m_setprop(void * arg,const char * pr_name,mac_prop_id_t pr_num,uint_t pr_valsize,const void * pr_val)372ea65739eSchenlu chen - Sun Microsystems - Beijing China ixgbe_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
373ea65739eSchenlu chen - Sun Microsystems - Beijing China     uint_t pr_valsize, const void *pr_val)
374ea65739eSchenlu chen - Sun Microsystems - Beijing China {
375ea65739eSchenlu chen - Sun Microsystems - Beijing China 	ixgbe_t *ixgbe = (ixgbe_t *)arg;
376ea65739eSchenlu chen - Sun Microsystems - Beijing China 	struct ixgbe_hw *hw = &ixgbe->hw;
377ea65739eSchenlu chen - Sun Microsystems - Beijing China 	int err = 0;
378ea65739eSchenlu chen - Sun Microsystems - Beijing China 	uint32_t flow_control;
379ea65739eSchenlu chen - Sun Microsystems - Beijing China 	uint32_t cur_mtu, new_mtu;
380ea65739eSchenlu chen - Sun Microsystems - Beijing China 	uint32_t rx_size;
381ea65739eSchenlu chen - Sun Microsystems - Beijing China 	uint32_t tx_size;
382dc0cb1cdSDale Ghent 	ixgbe_link_speed speeds = 0;
383ea65739eSchenlu chen - Sun Microsystems - Beijing China 
384ea65739eSchenlu chen - Sun Microsystems - Beijing China 	mutex_enter(&ixgbe->gen_lock);
385ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
386ea65739eSchenlu chen - Sun Microsystems - Beijing China 		mutex_exit(&ixgbe->gen_lock);
387ea65739eSchenlu chen - Sun Microsystems - Beijing China 		return (ECANCELED);
388ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
389ea65739eSchenlu chen - Sun Microsystems - Beijing China 
390dc0cb1cdSDale Ghent 	/*
391dc0cb1cdSDale Ghent 	 * We cannot always rely on the common code maintaining
392dc0cb1cdSDale Ghent 	 * hw->phy.speeds_supported, therefore we fall back to use the recorded
393dc0cb1cdSDale Ghent 	 * supported speeds which were obtained during instance init in
394dc0cb1cdSDale Ghent 	 * ixgbe_init_params().
395dc0cb1cdSDale Ghent 	 */
396dc0cb1cdSDale Ghent 	speeds = hw->phy.speeds_supported;
397dc0cb1cdSDale Ghent 	if (speeds == 0)
398dc0cb1cdSDale Ghent 		speeds = ixgbe->speeds_supported;
399dc0cb1cdSDale Ghent 
400ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (ixgbe->loopback_mode != IXGBE_LB_NONE &&
401ea65739eSchenlu chen - Sun Microsystems - Beijing China 	    ixgbe_param_locked(pr_num)) {
402ea65739eSchenlu chen - Sun Microsystems - Beijing China 		/*
403ea65739eSchenlu chen - Sun Microsystems - Beijing China 		 * All en_* parameters are locked (read-only)
404ea65739eSchenlu chen - Sun Microsystems - Beijing China 		 * while the device is in any sort of loopback mode.
405ea65739eSchenlu chen - Sun Microsystems - Beijing China 		 */
406ea65739eSchenlu chen - Sun Microsystems - Beijing China 		mutex_exit(&ixgbe->gen_lock);
407ea65739eSchenlu chen - Sun Microsystems - Beijing China 		return (EBUSY);
408ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
409ea65739eSchenlu chen - Sun Microsystems - Beijing China 
410dc0cb1cdSDale Ghent 	/*
411dc0cb1cdSDale Ghent 	 * We allow speed changes only on baseT PHYs. MAC_PROP_EN_* are marked
412dc0cb1cdSDale Ghent 	 * read-only on non-baseT PHYs.
413dc0cb1cdSDale Ghent 	 */
414ea65739eSchenlu chen - Sun Microsystems - Beijing China 	switch (pr_num) {
415ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_EN_10GFDX_CAP:
416dc0cb1cdSDale Ghent 		if (hw->phy.media_type == ixgbe_media_type_copper &&
417dc0cb1cdSDale Ghent 		    speeds & IXGBE_LINK_SPEED_10GB_FULL) {
418ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->param_en_10000fdx_cap = *(uint8_t *)pr_val;
419ea65739eSchenlu chen - Sun Microsystems - Beijing China 			goto setup_link;
420dc0cb1cdSDale Ghent 		} else {
421dc0cb1cdSDale Ghent 			err = ENOTSUP;
422dc0cb1cdSDale Ghent 			break;
423ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
424dc0cb1cdSDale Ghent 	case MAC_PROP_EN_5000FDX_CAP:
425dc0cb1cdSDale Ghent 		if (hw->phy.media_type == ixgbe_media_type_copper &&
426dc0cb1cdSDale Ghent 		    speeds & IXGBE_LINK_SPEED_5GB_FULL) {
427dc0cb1cdSDale Ghent 			ixgbe->param_en_5000fdx_cap = *(uint8_t *)pr_val;
428dc0cb1cdSDale Ghent 			goto setup_link;
429dc0cb1cdSDale Ghent 		} else {
430ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = ENOTSUP;
431ea65739eSchenlu chen - Sun Microsystems - Beijing China 			break;
432dc0cb1cdSDale Ghent 		}
433dc0cb1cdSDale Ghent 	case MAC_PROP_EN_2500FDX_CAP:
434dc0cb1cdSDale Ghent 		if (hw->phy.media_type == ixgbe_media_type_copper &&
435dc0cb1cdSDale Ghent 		    speeds & IXGBE_LINK_SPEED_2_5GB_FULL) {
436dc0cb1cdSDale Ghent 			ixgbe->param_en_2500fdx_cap = *(uint8_t *)pr_val;
437dc0cb1cdSDale Ghent 			goto setup_link;
438ea65739eSchenlu chen - Sun Microsystems - Beijing China 		} else {
439dc0cb1cdSDale Ghent 			err = ENOTSUP;
440dc0cb1cdSDale Ghent 			break;
441dc0cb1cdSDale Ghent 		}
442dc0cb1cdSDale Ghent 	case MAC_PROP_EN_1000FDX_CAP:
443dc0cb1cdSDale Ghent 		if (hw->phy.media_type == ixgbe_media_type_copper &&
444dc0cb1cdSDale Ghent 		    speeds & IXGBE_LINK_SPEED_1GB_FULL) {
445ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->param_en_1000fdx_cap = *(uint8_t *)pr_val;
446ea65739eSchenlu chen - Sun Microsystems - Beijing China 			goto setup_link;
447dc0cb1cdSDale Ghent 		} else {
448ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = ENOTSUP;
449ea65739eSchenlu chen - Sun Microsystems - Beijing China 			break;
450dc0cb1cdSDale Ghent 		}
451dc0cb1cdSDale Ghent 	case MAC_PROP_EN_100FDX_CAP:
452dc0cb1cdSDale Ghent 		if (hw->phy.media_type == ixgbe_media_type_copper &&
453dc0cb1cdSDale Ghent 		    speeds & IXGBE_LINK_SPEED_100_FULL) {
454ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->param_en_100fdx_cap = *(uint8_t *)pr_val;
455ea65739eSchenlu chen - Sun Microsystems - Beijing China 			goto setup_link;
456dc0cb1cdSDale Ghent 		} else {
457dc0cb1cdSDale Ghent 			err = ENOTSUP;
458dc0cb1cdSDale Ghent 			break;
459ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
460ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_AUTONEG:
461ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
462ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = ENOTSUP;
463ea65739eSchenlu chen - Sun Microsystems - Beijing China 			break;
464ea65739eSchenlu chen - Sun Microsystems - Beijing China 		} else {
465ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->param_adv_autoneg_cap = *(uint8_t *)pr_val;
466ea65739eSchenlu chen - Sun Microsystems - Beijing China 			goto setup_link;
467ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
468ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_FLOWCTRL:
469ea65739eSchenlu chen - Sun Microsystems - Beijing China 		bcopy(pr_val, &flow_control, sizeof (flow_control));
470ea65739eSchenlu chen - Sun Microsystems - Beijing China 
471ea65739eSchenlu chen - Sun Microsystems - Beijing China 		switch (flow_control) {
472ea65739eSchenlu chen - Sun Microsystems - Beijing China 		default:
473ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
474ea65739eSchenlu chen - Sun Microsystems - Beijing China 			break;
475ea65739eSchenlu chen - Sun Microsystems - Beijing China 		case LINK_FLOWCTRL_NONE:
476ea65739eSchenlu chen - Sun Microsystems - Beijing China 			hw->fc.requested_mode = ixgbe_fc_none;
477ea65739eSchenlu chen - Sun Microsystems - Beijing China 			break;
478ea65739eSchenlu chen - Sun Microsystems - Beijing China 		case LINK_FLOWCTRL_RX:
479ea65739eSchenlu chen - Sun Microsystems - Beijing China 			hw->fc.requested_mode = ixgbe_fc_rx_pause;
480ea65739eSchenlu chen - Sun Microsystems - Beijing China 			break;
481ea65739eSchenlu chen - Sun Microsystems - Beijing China 		case LINK_FLOWCTRL_TX:
482ea65739eSchenlu chen - Sun Microsystems - Beijing China 			hw->fc.requested_mode = ixgbe_fc_tx_pause;
483ea65739eSchenlu chen - Sun Microsystems - Beijing China 			break;
484ea65739eSchenlu chen - Sun Microsystems - Beijing China 		case LINK_FLOWCTRL_BI:
485ea65739eSchenlu chen - Sun Microsystems - Beijing China 			hw->fc.requested_mode = ixgbe_fc_full;
486ea65739eSchenlu chen - Sun Microsystems - Beijing China 			break;
487ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
488ea65739eSchenlu chen - Sun Microsystems - Beijing China setup_link:
489ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (err == 0) {
490ea65739eSchenlu chen - Sun Microsystems - Beijing China 			if (ixgbe_driver_setup_link(ixgbe, B_TRUE) !=
491ea65739eSchenlu chen - Sun Microsystems - Beijing China 			    IXGBE_SUCCESS)
492ea65739eSchenlu chen - Sun Microsystems - Beijing China 				err = EINVAL;
493ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
494ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
495ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_ADV_10GFDX_CAP:
496dc0cb1cdSDale Ghent 	case MAC_PROP_ADV_5000FDX_CAP:
497dc0cb1cdSDale Ghent 	case MAC_PROP_ADV_2500FDX_CAP:
498ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_ADV_1000FDX_CAP:
499ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_ADV_100FDX_CAP:
500ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_STATUS:
501ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_SPEED:
502ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_DUPLEX:
503*633c5e5cSRobert Mustacchi 	case MAC_PROP_MEDIA:
504ea65739eSchenlu chen - Sun Microsystems - Beijing China 		err = ENOTSUP; /* read-only prop. Can't set this. */
505ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
506ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_MTU:
507ea65739eSchenlu chen - Sun Microsystems - Beijing China 		cur_mtu = ixgbe->default_mtu;
508ea65739eSchenlu chen - Sun Microsystems - Beijing China 		bcopy(pr_val, &new_mtu, sizeof (new_mtu));
509ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (new_mtu == cur_mtu) {
510ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = 0;
511ea65739eSchenlu chen - Sun Microsystems - Beijing China 			break;
512ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
513ea65739eSchenlu chen - Sun Microsystems - Beijing China 
5141fedc51fSWinson Wang - Sun Microsystems - Beijing China 		if (new_mtu < DEFAULT_MTU || new_mtu > ixgbe->capab->max_mtu) {
515ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
516ea65739eSchenlu chen - Sun Microsystems - Beijing China 			break;
517ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
518ea65739eSchenlu chen - Sun Microsystems - Beijing China 
519ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (ixgbe->ixgbe_state & IXGBE_STARTED) {
520ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EBUSY;
521ea65739eSchenlu chen - Sun Microsystems - Beijing China 			break;
522ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
523ea65739eSchenlu chen - Sun Microsystems - Beijing China 
524ea65739eSchenlu chen - Sun Microsystems - Beijing China 		err = mac_maxsdu_update(ixgbe->mac_hdl, new_mtu);
525ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (err == 0) {
526ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->default_mtu = new_mtu;
527ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->max_frame_size = ixgbe->default_mtu +
528ea65739eSchenlu chen - Sun Microsystems - Beijing China 			    sizeof (struct ether_vlan_header) + ETHERFCSL;
529ea65739eSchenlu chen - Sun Microsystems - Beijing China 
530ea65739eSchenlu chen - Sun Microsystems - Beijing China 			/*
531ea65739eSchenlu chen - Sun Microsystems - Beijing China 			 * Set rx buffer size
532ea65739eSchenlu chen - Sun Microsystems - Beijing China 			 */
533ea65739eSchenlu chen - Sun Microsystems - Beijing China 			rx_size = ixgbe->max_frame_size + IPHDR_ALIGN_ROOM;
534ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->rx_buf_size = ((rx_size >> 10) + ((rx_size &
535ea65739eSchenlu chen - Sun Microsystems - Beijing China 			    (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
536ea65739eSchenlu chen - Sun Microsystems - Beijing China 
537ea65739eSchenlu chen - Sun Microsystems - Beijing China 			/*
538ea65739eSchenlu chen - Sun Microsystems - Beijing China 			 * Set tx buffer size
539ea65739eSchenlu chen - Sun Microsystems - Beijing China 			 */
540ea65739eSchenlu chen - Sun Microsystems - Beijing China 			tx_size = ixgbe->max_frame_size;
541ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->tx_buf_size = ((tx_size >> 10) + ((tx_size &
542ea65739eSchenlu chen - Sun Microsystems - Beijing China 			    (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
543ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
544ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
545ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_PRIVATE:
546ea65739eSchenlu chen - Sun Microsystems - Beijing China 		err = ixgbe_set_priv_prop(ixgbe, pr_name, pr_valsize, pr_val);
547ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
548ea65739eSchenlu chen - Sun Microsystems - Beijing China 	default:
549238d8f47SDale Ghent 		err = ENOTSUP;
550ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
551ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
552ea65739eSchenlu chen - Sun Microsystems - Beijing China 	mutex_exit(&ixgbe->gen_lock);
553ea65739eSchenlu chen - Sun Microsystems - Beijing China 	return (err);
554ea65739eSchenlu chen - Sun Microsystems - Beijing China }
555ea65739eSchenlu chen - Sun Microsystems - Beijing China 
556ea65739eSchenlu chen - Sun Microsystems - Beijing China int
ixgbe_m_getprop(void * arg,const char * pr_name,mac_prop_id_t pr_num,uint_t pr_valsize,void * pr_val)557ea65739eSchenlu chen - Sun Microsystems - Beijing China ixgbe_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
5580dc2366fSVenugopal Iyer     uint_t pr_valsize, void *pr_val)
559ea65739eSchenlu chen - Sun Microsystems - Beijing China {
560ea65739eSchenlu chen - Sun Microsystems - Beijing China 	ixgbe_t *ixgbe = (ixgbe_t *)arg;
561ea65739eSchenlu chen - Sun Microsystems - Beijing China 	struct ixgbe_hw *hw = &ixgbe->hw;
562ea65739eSchenlu chen - Sun Microsystems - Beijing China 	int err = 0;
563ea65739eSchenlu chen - Sun Microsystems - Beijing China 	uint32_t flow_control;
564ea65739eSchenlu chen - Sun Microsystems - Beijing China 	uint64_t tmp = 0;
565dc0cb1cdSDale Ghent 	ixgbe_link_speed speeds = 0;
566dc0cb1cdSDale Ghent 
567dc0cb1cdSDale Ghent 	/*
568dc0cb1cdSDale Ghent 	 * We cannot always rely on the common code maintaining
569dc0cb1cdSDale Ghent 	 * hw->phy.speeds_supported, therefore we fall back to use the recorded
570dc0cb1cdSDale Ghent 	 * supported speeds which were obtained during instance init in
571dc0cb1cdSDale Ghent 	 * ixgbe_init_params().
572dc0cb1cdSDale Ghent 	 */
573dc0cb1cdSDale Ghent 	speeds = hw->phy.speeds_supported;
574dc0cb1cdSDale Ghent 	if (speeds == 0)
575dc0cb1cdSDale Ghent 		speeds = ixgbe->speeds_supported;
576ea65739eSchenlu chen - Sun Microsystems - Beijing China 
577ea65739eSchenlu chen - Sun Microsystems - Beijing China 	switch (pr_num) {
578ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_DUPLEX:
5790dc2366fSVenugopal Iyer 		ASSERT(pr_valsize >= sizeof (link_duplex_t));
5800dc2366fSVenugopal Iyer 		bcopy(&ixgbe->link_duplex, pr_val,
5810dc2366fSVenugopal Iyer 		    sizeof (link_duplex_t));
582ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
583ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_SPEED:
5840dc2366fSVenugopal Iyer 		ASSERT(pr_valsize >= sizeof (uint64_t));
5850dc2366fSVenugopal Iyer 		tmp = ixgbe->link_speed * 1000000ull;
5860dc2366fSVenugopal Iyer 		bcopy(&tmp, pr_val, sizeof (tmp));
587ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
588*633c5e5cSRobert Mustacchi 	case MAC_PROP_MEDIA:
589*633c5e5cSRobert Mustacchi 		mutex_enter(&ixgbe->gen_lock);
590*633c5e5cSRobert Mustacchi 		*(mac_ether_media_t *)pr_val = ixgbe_phy_to_media(ixgbe);
591*633c5e5cSRobert Mustacchi 		mutex_exit(&ixgbe->gen_lock);
592*633c5e5cSRobert Mustacchi 		break;
593ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_AUTONEG:
5940dc2366fSVenugopal Iyer 		*(uint8_t *)pr_val = ixgbe->param_adv_autoneg_cap;
595ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
596ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_FLOWCTRL:
5970dc2366fSVenugopal Iyer 		ASSERT(pr_valsize >= sizeof (uint32_t));
5980dc2366fSVenugopal Iyer 
5990dc2366fSVenugopal Iyer 		switch (hw->fc.requested_mode) {
6000dc2366fSVenugopal Iyer 			case ixgbe_fc_none:
601ea65739eSchenlu chen - Sun Microsystems - Beijing China 				flow_control = LINK_FLOWCTRL_NONE;
602ea65739eSchenlu chen - Sun Microsystems - Beijing China 				break;
6030dc2366fSVenugopal Iyer 			case ixgbe_fc_rx_pause:
6040dc2366fSVenugopal Iyer 				flow_control = LINK_FLOWCTRL_RX;
6050dc2366fSVenugopal Iyer 				break;
6060dc2366fSVenugopal Iyer 			case ixgbe_fc_tx_pause:
6070dc2366fSVenugopal Iyer 				flow_control = LINK_FLOWCTRL_TX;
6080dc2366fSVenugopal Iyer 				break;
6090dc2366fSVenugopal Iyer 			case ixgbe_fc_full:
6100dc2366fSVenugopal Iyer 				flow_control = LINK_FLOWCTRL_BI;
6110dc2366fSVenugopal Iyer 				break;
6120dc2366fSVenugopal Iyer 		}
6130dc2366fSVenugopal Iyer 		bcopy(&flow_control, pr_val, sizeof (flow_control));
614ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
615ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_ADV_10GFDX_CAP:
616dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_10GB_FULL)
617dc0cb1cdSDale Ghent 			*(uint8_t *)pr_val = ixgbe->param_adv_10000fdx_cap;
618dc0cb1cdSDale Ghent 		else
619dc0cb1cdSDale Ghent 			err = ENOTSUP;
620ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
621ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_EN_10GFDX_CAP:
622dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_10GB_FULL)
623dc0cb1cdSDale Ghent 			*(uint8_t *)pr_val = ixgbe->param_en_10000fdx_cap;
624dc0cb1cdSDale Ghent 		else
625dc0cb1cdSDale Ghent 			err = ENOTSUP;
626dc0cb1cdSDale Ghent 		break;
627dc0cb1cdSDale Ghent 	case MAC_PROP_ADV_5000FDX_CAP:
628dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_5GB_FULL)
629dc0cb1cdSDale Ghent 			*(uint8_t *)pr_val = ixgbe->param_adv_5000fdx_cap;
630dc0cb1cdSDale Ghent 		else
631dc0cb1cdSDale Ghent 			err = ENOTSUP;
632dc0cb1cdSDale Ghent 		break;
633dc0cb1cdSDale Ghent 	case MAC_PROP_EN_5000FDX_CAP:
634dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_5GB_FULL)
635dc0cb1cdSDale Ghent 			*(uint8_t *)pr_val = ixgbe->param_en_5000fdx_cap;
636dc0cb1cdSDale Ghent 		else
637dc0cb1cdSDale Ghent 			err = ENOTSUP;
638dc0cb1cdSDale Ghent 		break;
639dc0cb1cdSDale Ghent 	case MAC_PROP_ADV_2500FDX_CAP:
640dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL)
641dc0cb1cdSDale Ghent 			*(uint8_t *)pr_val = ixgbe->param_adv_2500fdx_cap;
642dc0cb1cdSDale Ghent 		else
643dc0cb1cdSDale Ghent 			err = ENOTSUP;
644dc0cb1cdSDale Ghent 		break;
645dc0cb1cdSDale Ghent 	case MAC_PROP_EN_2500FDX_CAP:
646dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL)
647dc0cb1cdSDale Ghent 			*(uint8_t *)pr_val = ixgbe->param_en_2500fdx_cap;
648dc0cb1cdSDale Ghent 		else
649dc0cb1cdSDale Ghent 			err = ENOTSUP;
650ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
651ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_ADV_1000FDX_CAP:
652dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_1GB_FULL)
653dc0cb1cdSDale Ghent 			*(uint8_t *)pr_val = ixgbe->param_adv_1000fdx_cap;
654dc0cb1cdSDale Ghent 		else
655dc0cb1cdSDale Ghent 			err = ENOTSUP;
656ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
657ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_EN_1000FDX_CAP:
658dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_1GB_FULL)
659dc0cb1cdSDale Ghent 			*(uint8_t *)pr_val = ixgbe->param_en_1000fdx_cap;
660dc0cb1cdSDale Ghent 		else
661dc0cb1cdSDale Ghent 			err = ENOTSUP;
662ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
663ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_ADV_100FDX_CAP:
664dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_100_FULL)
665dc0cb1cdSDale Ghent 			*(uint8_t *)pr_val = ixgbe->param_adv_100fdx_cap;
666dc0cb1cdSDale Ghent 		else
667dc0cb1cdSDale Ghent 			err = ENOTSUP;
668ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
669ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_EN_100FDX_CAP:
670dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_100_FULL)
671dc0cb1cdSDale Ghent 			*(uint8_t *)pr_val = ixgbe->param_en_100fdx_cap;
672dc0cb1cdSDale Ghent 		else
673dc0cb1cdSDale Ghent 			err = ENOTSUP;
674ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
675ea65739eSchenlu chen - Sun Microsystems - Beijing China 	case MAC_PROP_PRIVATE:
676ea65739eSchenlu chen - Sun Microsystems - Beijing China 		err = ixgbe_get_priv_prop(ixgbe, pr_name,
6770dc2366fSVenugopal Iyer 		    pr_valsize, pr_val);
678ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
679ea65739eSchenlu chen - Sun Microsystems - Beijing China 	default:
680238d8f47SDale Ghent 		err = ENOTSUP;
681ea65739eSchenlu chen - Sun Microsystems - Beijing China 		break;
682ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
683ea65739eSchenlu chen - Sun Microsystems - Beijing China 	return (err);
684ea65739eSchenlu chen - Sun Microsystems - Beijing China }
685ea65739eSchenlu chen - Sun Microsystems - Beijing China 
6860dc2366fSVenugopal Iyer void
ixgbe_m_propinfo(void * arg,const char * pr_name,mac_prop_id_t pr_num,mac_prop_info_handle_t prh)6870dc2366fSVenugopal Iyer ixgbe_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
6880dc2366fSVenugopal Iyer     mac_prop_info_handle_t prh)
6890dc2366fSVenugopal Iyer {
6900dc2366fSVenugopal Iyer 	ixgbe_t *ixgbe = (ixgbe_t *)arg;
691dc0cb1cdSDale Ghent 	struct ixgbe_hw *hw = &ixgbe->hw;
6920dc2366fSVenugopal Iyer 	uint_t perm;
693dc0cb1cdSDale Ghent 	uint8_t value;
694dc0cb1cdSDale Ghent 	ixgbe_link_speed speeds = 0;
695dc0cb1cdSDale Ghent 
696dc0cb1cdSDale Ghent 	/*
697dc0cb1cdSDale Ghent 	 * We cannot always rely on the common code maintaining
698dc0cb1cdSDale Ghent 	 * hw->phy.speeds_supported, therefore we fall back to use the
699dc0cb1cdSDale Ghent 	 * recorded supported speeds which were obtained during instance init in
700dc0cb1cdSDale Ghent 	 * ixgbe_init_params().
701dc0cb1cdSDale Ghent 	 */
702dc0cb1cdSDale Ghent 	speeds = hw->phy.speeds_supported;
703dc0cb1cdSDale Ghent 	if (speeds == 0)
704dc0cb1cdSDale Ghent 		speeds = ixgbe->speeds_supported;
7050dc2366fSVenugopal Iyer 
7060dc2366fSVenugopal Iyer 	switch (pr_num) {
7070dc2366fSVenugopal Iyer 	case MAC_PROP_DUPLEX:
7080dc2366fSVenugopal Iyer 	case MAC_PROP_SPEED:
7095b6dd21fSchenlu chen - Sun Microsystems - Beijing China 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
7105b6dd21fSchenlu chen - Sun Microsystems - Beijing China 		break;
7115b6dd21fSchenlu chen - Sun Microsystems - Beijing China 
7120dc2366fSVenugopal Iyer 	case MAC_PROP_ADV_100FDX_CAP:
713dc0cb1cdSDale Ghent 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
714dc0cb1cdSDale Ghent 		value = (speeds & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0;
715dc0cb1cdSDale Ghent 		mac_prop_info_set_default_uint8(prh, value);
716dc0cb1cdSDale Ghent 		break;
717dc0cb1cdSDale Ghent 
7180dc2366fSVenugopal Iyer 	case MAC_PROP_ADV_1000FDX_CAP:
719dc0cb1cdSDale Ghent 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
720dc0cb1cdSDale Ghent 		value = (speeds & IXGBE_LINK_SPEED_1GB_FULL) ? 1 : 0;
721dc0cb1cdSDale Ghent 		mac_prop_info_set_default_uint8(prh, value);
722dc0cb1cdSDale Ghent 		break;
723dc0cb1cdSDale Ghent 
724dc0cb1cdSDale Ghent 	case MAC_PROP_ADV_2500FDX_CAP:
725dc0cb1cdSDale Ghent 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
726dc0cb1cdSDale Ghent 		value = (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) ? 1 : 0;
727dc0cb1cdSDale Ghent 		mac_prop_info_set_default_uint8(prh, value);
728dc0cb1cdSDale Ghent 		break;
729dc0cb1cdSDale Ghent 
730dc0cb1cdSDale Ghent 	case MAC_PROP_ADV_5000FDX_CAP:
731dc0cb1cdSDale Ghent 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
732dc0cb1cdSDale Ghent 		value = (speeds & IXGBE_LINK_SPEED_5GB_FULL) ? 1 : 0;
733dc0cb1cdSDale Ghent 		mac_prop_info_set_default_uint8(prh, value);
734dc0cb1cdSDale Ghent 		break;
735dc0cb1cdSDale Ghent 
7360dc2366fSVenugopal Iyer 	case MAC_PROP_ADV_10GFDX_CAP:
7370dc2366fSVenugopal Iyer 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
738dc0cb1cdSDale Ghent 		value = (speeds & IXGBE_LINK_SPEED_10GB_FULL) ? 1 : 0;
739dc0cb1cdSDale Ghent 		mac_prop_info_set_default_uint8(prh, value);
7400dc2366fSVenugopal Iyer 		break;
7410dc2366fSVenugopal Iyer 
742dc0cb1cdSDale Ghent 	/*
743dc0cb1cdSDale Ghent 	 * We allow speed changes only on baseT PHYs. MAC_PROP_EN_* are marked
744dc0cb1cdSDale Ghent 	 * read-only on non-baseT (SFP) PHYs.
745dc0cb1cdSDale Ghent 	 */
7460dc2366fSVenugopal Iyer 	case MAC_PROP_AUTONEG:
747dc0cb1cdSDale Ghent 		perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
7480dc2366fSVenugopal Iyer 		    MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
7490dc2366fSVenugopal Iyer 		mac_prop_info_set_perm(prh, perm);
7505b6dd21fSchenlu chen - Sun Microsystems - Beijing China 		mac_prop_info_set_default_uint8(prh, 1);
7510dc2366fSVenugopal Iyer 		break;
7520dc2366fSVenugopal Iyer 
753dc0cb1cdSDale Ghent 	case MAC_PROP_EN_10GFDX_CAP:
754dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_10GB_FULL) {
755dc0cb1cdSDale Ghent 			perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
756dc0cb1cdSDale Ghent 			    MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
757dc0cb1cdSDale Ghent 			mac_prop_info_set_perm(prh, perm);
758dc0cb1cdSDale Ghent 			mac_prop_info_set_default_uint8(prh, 1);
759dc0cb1cdSDale Ghent 		}
760dc0cb1cdSDale Ghent 		break;
761dc0cb1cdSDale Ghent 
762dc0cb1cdSDale Ghent 	case MAC_PROP_EN_5000FDX_CAP:
763dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_5GB_FULL) {
764dc0cb1cdSDale Ghent 			perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
765dc0cb1cdSDale Ghent 			    MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
766dc0cb1cdSDale Ghent 			mac_prop_info_set_perm(prh, perm);
767dc0cb1cdSDale Ghent 			mac_prop_info_set_default_uint8(prh, 1);
768dc0cb1cdSDale Ghent 		}
769dc0cb1cdSDale Ghent 		break;
770dc0cb1cdSDale Ghent 
771dc0cb1cdSDale Ghent 	case MAC_PROP_EN_2500FDX_CAP:
772dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) {
773dc0cb1cdSDale Ghent 			perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
774dc0cb1cdSDale Ghent 			    MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
775dc0cb1cdSDale Ghent 			mac_prop_info_set_perm(prh, perm);
776dc0cb1cdSDale Ghent 			mac_prop_info_set_default_uint8(prh, 1);
777dc0cb1cdSDale Ghent 		}
778dc0cb1cdSDale Ghent 		break;
779dc0cb1cdSDale Ghent 
780dc0cb1cdSDale Ghent 	case MAC_PROP_EN_1000FDX_CAP:
781dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_1GB_FULL) {
782dc0cb1cdSDale Ghent 			perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
783dc0cb1cdSDale Ghent 			    MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
784dc0cb1cdSDale Ghent 			mac_prop_info_set_perm(prh, perm);
785dc0cb1cdSDale Ghent 			mac_prop_info_set_default_uint8(prh, 1);
786dc0cb1cdSDale Ghent 		}
787dc0cb1cdSDale Ghent 		break;
788dc0cb1cdSDale Ghent 
789dc0cb1cdSDale Ghent 	case MAC_PROP_EN_100FDX_CAP:
790dc0cb1cdSDale Ghent 		if (speeds & IXGBE_LINK_SPEED_100_FULL) {
791dc0cb1cdSDale Ghent 			perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
792dc0cb1cdSDale Ghent 			    MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
793dc0cb1cdSDale Ghent 			mac_prop_info_set_perm(prh, perm);
794dc0cb1cdSDale Ghent 			mac_prop_info_set_default_uint8(prh, 1);
795dc0cb1cdSDale Ghent 		}
796dc0cb1cdSDale Ghent 		break;
797dc0cb1cdSDale Ghent 
7980dc2366fSVenugopal Iyer 	case MAC_PROP_FLOWCTRL:
7990dc2366fSVenugopal Iyer 		mac_prop_info_set_default_link_flowctrl(prh,
8000dc2366fSVenugopal Iyer 		    LINK_FLOWCTRL_NONE);
8010dc2366fSVenugopal Iyer 		break;
8020dc2366fSVenugopal Iyer 
8030dc2366fSVenugopal Iyer 	case MAC_PROP_MTU:
8040dc2366fSVenugopal Iyer 		mac_prop_info_set_range_uint32(prh,
8050dc2366fSVenugopal Iyer 		    DEFAULT_MTU, ixgbe->capab->max_mtu);
8060dc2366fSVenugopal Iyer 		break;
8070dc2366fSVenugopal Iyer 
8080dc2366fSVenugopal Iyer 	case MAC_PROP_PRIVATE: {
8090dc2366fSVenugopal Iyer 		char valstr[64];
8100dc2366fSVenugopal Iyer 		int value;
8110dc2366fSVenugopal Iyer 
8120dc2366fSVenugopal Iyer 		bzero(valstr, sizeof (valstr));
8130dc2366fSVenugopal Iyer 
8140dc2366fSVenugopal Iyer 		if (strcmp(pr_name, "_adv_pause_cap") == 0 ||
8150dc2366fSVenugopal Iyer 		    strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
8160dc2366fSVenugopal Iyer 			mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
8170dc2366fSVenugopal Iyer 			return;
8180dc2366fSVenugopal Iyer 		}
8190dc2366fSVenugopal Iyer 
8200dc2366fSVenugopal Iyer 		if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
8210dc2366fSVenugopal Iyer 			value = DEFAULT_TX_COPY_THRESHOLD;
8220dc2366fSVenugopal Iyer 		} else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
8230dc2366fSVenugopal Iyer 			value = DEFAULT_TX_RECYCLE_THRESHOLD;
8240dc2366fSVenugopal Iyer 		} else if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
8250dc2366fSVenugopal Iyer 			value = DEFAULT_TX_OVERLOAD_THRESHOLD;
8260dc2366fSVenugopal Iyer 		} else if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
8270dc2366fSVenugopal Iyer 			value = DEFAULT_TX_RESCHED_THRESHOLD;
828bb54aa20SJohn Levon 		} else if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
8290dc2366fSVenugopal Iyer 			value = DEFAULT_RX_COPY_THRESHOLD;
830bb54aa20SJohn Levon 		} else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
8310dc2366fSVenugopal Iyer 			value = DEFAULT_RX_LIMIT_PER_INTR;
832bb54aa20SJohn Levon 		} else if (strcmp(pr_name, "_intr_throttling") == 0) {
8330dc2366fSVenugopal Iyer 			value = ixgbe->capab->def_intr_throttle;
8340dc2366fSVenugopal Iyer 		} else {
8350dc2366fSVenugopal Iyer 			return;
8360dc2366fSVenugopal Iyer 		}
8370dc2366fSVenugopal Iyer 
8380dc2366fSVenugopal Iyer 		(void) snprintf(valstr, sizeof (valstr), "%x", value);
8390dc2366fSVenugopal Iyer 	}
8400dc2366fSVenugopal Iyer 	}
8410dc2366fSVenugopal Iyer }
8420dc2366fSVenugopal Iyer 
843ea65739eSchenlu chen - Sun Microsystems - Beijing China boolean_t
ixgbe_param_locked(mac_prop_id_t pr_num)844ea65739eSchenlu chen - Sun Microsystems - Beijing China ixgbe_param_locked(mac_prop_id_t pr_num)
845ea65739eSchenlu chen - Sun Microsystems - Beijing China {
846ea65739eSchenlu chen - Sun Microsystems - Beijing China 	/*
847ea65739eSchenlu chen - Sun Microsystems - Beijing China 	 * All en_* parameters are locked (read-only) while
848ea65739eSchenlu chen - Sun Microsystems - Beijing China 	 * the device is in any sort of loopback mode ...
849ea65739eSchenlu chen - Sun Microsystems - Beijing China 	 */
850ea65739eSchenlu chen - Sun Microsystems - Beijing China 	switch (pr_num) {
851ea65739eSchenlu chen - Sun Microsystems - Beijing China 		case MAC_PROP_EN_10GFDX_CAP:
852dc0cb1cdSDale Ghent 		case MAC_PROP_EN_5000FDX_CAP:
853dc0cb1cdSDale Ghent 		case MAC_PROP_EN_2500FDX_CAP:
854ea65739eSchenlu chen - Sun Microsystems - Beijing China 		case MAC_PROP_EN_1000FDX_CAP:
855ea65739eSchenlu chen - Sun Microsystems - Beijing China 		case MAC_PROP_EN_100FDX_CAP:
856ea65739eSchenlu chen - Sun Microsystems - Beijing China 		case MAC_PROP_AUTONEG:
857ea65739eSchenlu chen - Sun Microsystems - Beijing China 		case MAC_PROP_FLOWCTRL:
858ea65739eSchenlu chen - Sun Microsystems - Beijing China 			return (B_TRUE);
859ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
860ea65739eSchenlu chen - Sun Microsystems - Beijing China 	return (B_FALSE);
861ea65739eSchenlu chen - Sun Microsystems - Beijing China }
862ea65739eSchenlu chen - Sun Microsystems - Beijing China 
863ea65739eSchenlu chen - Sun Microsystems - Beijing China /* ARGSUSED */
864ea65739eSchenlu chen - Sun Microsystems - Beijing China int
ixgbe_set_priv_prop(ixgbe_t * ixgbe,const char * pr_name,uint_t pr_valsize,const void * pr_val)865ea65739eSchenlu chen - Sun Microsystems - Beijing China ixgbe_set_priv_prop(ixgbe_t *ixgbe, const char *pr_name,
866ea65739eSchenlu chen - Sun Microsystems - Beijing China     uint_t pr_valsize, const void *pr_val)
867ea65739eSchenlu chen - Sun Microsystems - Beijing China {
868ea65739eSchenlu chen - Sun Microsystems - Beijing China 	int err = 0;
869ea65739eSchenlu chen - Sun Microsystems - Beijing China 	long result;
870ea65739eSchenlu chen - Sun Microsystems - Beijing China 	struct ixgbe_hw *hw = &ixgbe->hw;
871ea65739eSchenlu chen - Sun Microsystems - Beijing China 	int i;
872ea65739eSchenlu chen - Sun Microsystems - Beijing China 
873ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
874ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (pr_val == NULL) {
875ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
876ea65739eSchenlu chen - Sun Microsystems - Beijing China 			return (err);
877ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
878ea65739eSchenlu chen - Sun Microsystems - Beijing China 		(void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
879ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (result < MIN_TX_COPY_THRESHOLD ||
880ea65739eSchenlu chen - Sun Microsystems - Beijing China 		    result > MAX_TX_COPY_THRESHOLD)
881ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
882ea65739eSchenlu chen - Sun Microsystems - Beijing China 		else {
883ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->tx_copy_thresh = (uint32_t)result;
884ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
885ea65739eSchenlu chen - Sun Microsystems - Beijing China 		return (err);
886ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
887ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
888ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (pr_val == NULL) {
889ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
890ea65739eSchenlu chen - Sun Microsystems - Beijing China 			return (err);
891ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
892ea65739eSchenlu chen - Sun Microsystems - Beijing China 		(void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
893ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (result < MIN_TX_RECYCLE_THRESHOLD ||
894ea65739eSchenlu chen - Sun Microsystems - Beijing China 		    result > MAX_TX_RECYCLE_THRESHOLD)
895ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
896ea65739eSchenlu chen - Sun Microsystems - Beijing China 		else {
897ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->tx_recycle_thresh = (uint32_t)result;
898ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
899ea65739eSchenlu chen - Sun Microsystems - Beijing China 		return (err);
900ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
901ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
902ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (pr_val == NULL) {
903ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
904ea65739eSchenlu chen - Sun Microsystems - Beijing China 			return (err);
905ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
906ea65739eSchenlu chen - Sun Microsystems - Beijing China 		(void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
907ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (result < MIN_TX_OVERLOAD_THRESHOLD ||
908ea65739eSchenlu chen - Sun Microsystems - Beijing China 		    result > MAX_TX_OVERLOAD_THRESHOLD)
909ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
910ea65739eSchenlu chen - Sun Microsystems - Beijing China 		else {
911ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->tx_overload_thresh = (uint32_t)result;
912ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
913ea65739eSchenlu chen - Sun Microsystems - Beijing China 		return (err);
914ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
915ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
916ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (pr_val == NULL) {
917ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
918ea65739eSchenlu chen - Sun Microsystems - Beijing China 			return (err);
919ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
920ea65739eSchenlu chen - Sun Microsystems - Beijing China 		(void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
921ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (result < MIN_TX_RESCHED_THRESHOLD ||
922ea65739eSchenlu chen - Sun Microsystems - Beijing China 		    result > MAX_TX_RESCHED_THRESHOLD)
923ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
924ea65739eSchenlu chen - Sun Microsystems - Beijing China 		else {
925ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->tx_resched_thresh = (uint32_t)result;
926ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
927ea65739eSchenlu chen - Sun Microsystems - Beijing China 		return (err);
928ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
929ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
930ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (pr_val == NULL) {
931ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
932ea65739eSchenlu chen - Sun Microsystems - Beijing China 			return (err);
933ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
934ea65739eSchenlu chen - Sun Microsystems - Beijing China 		(void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
935ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (result < MIN_RX_COPY_THRESHOLD ||
936ea65739eSchenlu chen - Sun Microsystems - Beijing China 		    result > MAX_RX_COPY_THRESHOLD)
937ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
938ea65739eSchenlu chen - Sun Microsystems - Beijing China 		else {
939ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->rx_copy_thresh = (uint32_t)result;
940ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
941ea65739eSchenlu chen - Sun Microsystems - Beijing China 		return (err);
942ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
943ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
944ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (pr_val == NULL) {
945ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
946ea65739eSchenlu chen - Sun Microsystems - Beijing China 			return (err);
947ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
948ea65739eSchenlu chen - Sun Microsystems - Beijing China 		(void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
949ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (result < MIN_RX_LIMIT_PER_INTR ||
950ea65739eSchenlu chen - Sun Microsystems - Beijing China 		    result > MAX_RX_LIMIT_PER_INTR)
951ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
952ea65739eSchenlu chen - Sun Microsystems - Beijing China 		else {
953ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->rx_limit_per_intr = (uint32_t)result;
954ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
955ea65739eSchenlu chen - Sun Microsystems - Beijing China 		return (err);
956ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
957ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_intr_throttling") == 0) {
958ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (pr_val == NULL) {
959ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
960ea65739eSchenlu chen - Sun Microsystems - Beijing China 			return (err);
961ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
962ea65739eSchenlu chen - Sun Microsystems - Beijing China 		(void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
963ea65739eSchenlu chen - Sun Microsystems - Beijing China 
964ea65739eSchenlu chen - Sun Microsystems - Beijing China 		if (result < ixgbe->capab->min_intr_throttle ||
965ea65739eSchenlu chen - Sun Microsystems - Beijing China 		    result > ixgbe->capab->max_intr_throttle)
966ea65739eSchenlu chen - Sun Microsystems - Beijing China 			err = EINVAL;
967ea65739eSchenlu chen - Sun Microsystems - Beijing China 		else {
968ea65739eSchenlu chen - Sun Microsystems - Beijing China 			ixgbe->intr_throttling[0] = (uint32_t)result;
969ea65739eSchenlu chen - Sun Microsystems - Beijing China 
970ea65739eSchenlu chen - Sun Microsystems - Beijing China 			/*
971dc0cb1cdSDale Ghent 			 * 82599, X540 and X550 require the interrupt throttling
97269b5a878SDan McDonald 			 * rate is a multiple of 8. This is enforced by the
97369b5a878SDan McDonald 			 * register definiton.
974ea65739eSchenlu chen - Sun Microsystems - Beijing China 			 */
97569b5a878SDan McDonald 			if (hw->mac.type == ixgbe_mac_82599EB ||
976dc0cb1cdSDale Ghent 			    hw->mac.type == ixgbe_mac_X540 ||
977dc0cb1cdSDale Ghent 			    hw->mac.type == ixgbe_mac_X550 ||
978dc0cb1cdSDale Ghent 			    hw->mac.type == ixgbe_mac_X550EM_x) {
979ea65739eSchenlu chen - Sun Microsystems - Beijing China 				ixgbe->intr_throttling[0] =
980ea65739eSchenlu chen - Sun Microsystems - Beijing China 				    ixgbe->intr_throttling[0] & 0xFF8;
98169b5a878SDan McDonald 			}
982ea65739eSchenlu chen - Sun Microsystems - Beijing China 
983ea65739eSchenlu chen - Sun Microsystems - Beijing China 			for (i = 0; i < MAX_INTR_VECTOR; i++)
984ea65739eSchenlu chen - Sun Microsystems - Beijing China 				ixgbe->intr_throttling[i] =
985ea65739eSchenlu chen - Sun Microsystems - Beijing China 				    ixgbe->intr_throttling[0];
986ea65739eSchenlu chen - Sun Microsystems - Beijing China 
987ea65739eSchenlu chen - Sun Microsystems - Beijing China 			/* Set interrupt throttling rate */
988ea65739eSchenlu chen - Sun Microsystems - Beijing China 			for (i = 0; i < ixgbe->intr_cnt; i++)
989ea65739eSchenlu chen - Sun Microsystems - Beijing China 				IXGBE_WRITE_REG(hw, IXGBE_EITR(i),
990ea65739eSchenlu chen - Sun Microsystems - Beijing China 				    ixgbe->intr_throttling[i]);
991ea65739eSchenlu chen - Sun Microsystems - Beijing China 		}
992ea65739eSchenlu chen - Sun Microsystems - Beijing China 		return (err);
993ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
994ea65739eSchenlu chen - Sun Microsystems - Beijing China 	return (ENOTSUP);
995ea65739eSchenlu chen - Sun Microsystems - Beijing China }
996ea65739eSchenlu chen - Sun Microsystems - Beijing China 
997ea65739eSchenlu chen - Sun Microsystems - Beijing China int
ixgbe_get_priv_prop(ixgbe_t * ixgbe,const char * pr_name,uint_t pr_valsize,void * pr_val)998ea65739eSchenlu chen - Sun Microsystems - Beijing China ixgbe_get_priv_prop(ixgbe_t *ixgbe, const char *pr_name,
9990dc2366fSVenugopal Iyer     uint_t pr_valsize, void *pr_val)
1000ea65739eSchenlu chen - Sun Microsystems - Beijing China {
1001ea65739eSchenlu chen - Sun Microsystems - Beijing China 	int err = ENOTSUP;
1002ea65739eSchenlu chen - Sun Microsystems - Beijing China 	int value;
1003ea65739eSchenlu chen - Sun Microsystems - Beijing China 
1004ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_adv_pause_cap") == 0) {
10050dc2366fSVenugopal Iyer 		value = ixgbe->param_adv_pause_cap;
1006ea65739eSchenlu chen - Sun Microsystems - Beijing China 		err = 0;
1007ea65739eSchenlu chen - Sun Microsystems - Beijing China 		goto done;
1008ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
1009ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
10100dc2366fSVenugopal Iyer 		value = ixgbe->param_adv_asym_pause_cap;
1011ea65739eSchenlu chen - Sun Microsystems - Beijing China 		err = 0;
1012ea65739eSchenlu chen - Sun Microsystems - Beijing China 		goto done;
1013ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
1014ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
10150dc2366fSVenugopal Iyer 		value = ixgbe->tx_copy_thresh;
1016ea65739eSchenlu chen - Sun Microsystems - Beijing China 		err = 0;
1017ea65739eSchenlu chen - Sun Microsystems - Beijing China 		goto done;
1018ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
1019ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
10200dc2366fSVenugopal Iyer 		value = ixgbe->tx_recycle_thresh;
1021ea65739eSchenlu chen - Sun Microsystems - Beijing China 		err = 0;
1022ea65739eSchenlu chen - Sun Microsystems - Beijing China 		goto done;
1023ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
1024ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
10250dc2366fSVenugopal Iyer 		value = ixgbe->tx_overload_thresh;
1026ea65739eSchenlu chen - Sun Microsystems - Beijing China 		err = 0;
1027ea65739eSchenlu chen - Sun Microsystems - Beijing China 		goto done;
1028ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
1029ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
10300dc2366fSVenugopal Iyer 		value = ixgbe->tx_resched_thresh;
1031ea65739eSchenlu chen - Sun Microsystems - Beijing China 		err = 0;
1032ea65739eSchenlu chen - Sun Microsystems - Beijing China 		goto done;
1033ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
1034ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
10350dc2366fSVenugopal Iyer 		value = ixgbe->rx_copy_thresh;
1036ea65739eSchenlu chen - Sun Microsystems - Beijing China 		err = 0;
1037ea65739eSchenlu chen - Sun Microsystems - Beijing China 		goto done;
1038ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
1039ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
10400dc2366fSVenugopal Iyer 		value = ixgbe->rx_limit_per_intr;
1041ea65739eSchenlu chen - Sun Microsystems - Beijing China 		err = 0;
1042ea65739eSchenlu chen - Sun Microsystems - Beijing China 		goto done;
1043ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
1044ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (strcmp(pr_name, "_intr_throttling") == 0) {
10450dc2366fSVenugopal Iyer 		value = ixgbe->intr_throttling[0];
1046ea65739eSchenlu chen - Sun Microsystems - Beijing China 		err = 0;
1047ea65739eSchenlu chen - Sun Microsystems - Beijing China 		goto done;
1048ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
1049ea65739eSchenlu chen - Sun Microsystems - Beijing China done:
1050ea65739eSchenlu chen - Sun Microsystems - Beijing China 	if (err == 0) {
1051ea65739eSchenlu chen - Sun Microsystems - Beijing China 		(void) snprintf(pr_val, pr_valsize, "%d", value);
1052ea65739eSchenlu chen - Sun Microsystems - Beijing China 	}
1053ea65739eSchenlu chen - Sun Microsystems - Beijing China 	return (err);
1054ea65739eSchenlu chen - Sun Microsystems - Beijing China }
1055