xref: /illumos-gate/usr/src/uts/common/io/bnx/bnxgldv3.c (revision fe803bd5)
1eef4f27bSRobert Mustacchi /*
2eef4f27bSRobert Mustacchi  * Copyright 2014-2017 Cavium, Inc.
3eef4f27bSRobert Mustacchi  * The contents of this file are subject to the terms of the Common Development
4eef4f27bSRobert Mustacchi  * and Distribution License, v.1,  (the "License").
5eef4f27bSRobert Mustacchi  *
6eef4f27bSRobert Mustacchi  * You may not use this file except in compliance with the License.
7eef4f27bSRobert Mustacchi  *
8eef4f27bSRobert Mustacchi  * You can obtain a copy of the License at available
9eef4f27bSRobert Mustacchi  * at http://opensource.org/licenses/CDDL-1.0
10eef4f27bSRobert Mustacchi  *
11eef4f27bSRobert Mustacchi  * See the License for the specific language governing permissions and
12eef4f27bSRobert Mustacchi  * limitations under the License.
13eef4f27bSRobert Mustacchi  */
14eef4f27bSRobert Mustacchi 
15eef4f27bSRobert Mustacchi /*
16eef4f27bSRobert Mustacchi  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
17eef4f27bSRobert Mustacchi  * Copyright (c) 2019, Joyent, Inc.
18*fe803bd5SRobert Mustacchi  * Copyright 2023 Oxide Computer Company
19eef4f27bSRobert Mustacchi  */
20eef4f27bSRobert Mustacchi 
21eef4f27bSRobert Mustacchi #include "bnxgld.h"
22eef4f27bSRobert Mustacchi #include "bnxhwi.h"
23eef4f27bSRobert Mustacchi #include "bnxsnd.h"
24eef4f27bSRobert Mustacchi #include "bnxrcv.h"
25eef4f27bSRobert Mustacchi #include "bnxcfg.h"
26eef4f27bSRobert Mustacchi 
27eef4f27bSRobert Mustacchi #include <sys/mac_provider.h>
28eef4f27bSRobert Mustacchi #include <sys/mac_ether.h>
29eef4f27bSRobert Mustacchi #include <sys/dlpi.h>
30eef4f27bSRobert Mustacchi #include <sys/policy.h>
31eef4f27bSRobert Mustacchi 
32eef4f27bSRobert Mustacchi /*
33eef4f27bSRobert Mustacchi  * Name:    bnx_m_start
34eef4f27bSRobert Mustacchi  *
35eef4f27bSRobert Mustacchi  * Input:   ptr to driver device structure.
36eef4f27bSRobert Mustacchi  *
37eef4f27bSRobert Mustacchi  * Return:  DDI_SUCCESS or DDI_FAILURE
38eef4f27bSRobert Mustacchi  *
39eef4f27bSRobert Mustacchi  * Description:
40eef4f27bSRobert Mustacchi  *          This routine is called by GLD to enable device for
41eef4f27bSRobert Mustacchi  *          packet reception and enable interrupts.
42eef4f27bSRobert Mustacchi  */
43eef4f27bSRobert Mustacchi static int
bnx_m_start(void * arg)44eef4f27bSRobert Mustacchi bnx_m_start(void *arg)
45eef4f27bSRobert Mustacchi {
46eef4f27bSRobert Mustacchi 	int rc;
47eef4f27bSRobert Mustacchi 	um_device_t *umdevice;
48eef4f27bSRobert Mustacchi 
49eef4f27bSRobert Mustacchi 	umdevice = (um_device_t *)arg;
50eef4f27bSRobert Mustacchi 
51eef4f27bSRobert Mustacchi 	mutex_enter(&umdevice->os_param.gld_mutex);
52eef4f27bSRobert Mustacchi 
53eef4f27bSRobert Mustacchi 	if (umdevice->dev_start == B_TRUE) {
54eef4f27bSRobert Mustacchi 		/* We're already started.  Success! */
55eef4f27bSRobert Mustacchi 		rc = 0;
56eef4f27bSRobert Mustacchi 		goto done;
57eef4f27bSRobert Mustacchi 	}
58eef4f27bSRobert Mustacchi 
59eef4f27bSRobert Mustacchi 	/* Always report the initial link state as unknown. */
60eef4f27bSRobert Mustacchi 	bnx_gld_link(umdevice, LINK_STATE_UNKNOWN);
61eef4f27bSRobert Mustacchi 
62eef4f27bSRobert Mustacchi 	umdevice->link_updates_ok = B_TRUE;
63eef4f27bSRobert Mustacchi 
64eef4f27bSRobert Mustacchi 	if (bnx_hdwr_acquire(umdevice)) {
65eef4f27bSRobert Mustacchi 		rc = EIO;
66eef4f27bSRobert Mustacchi 		goto done;
67eef4f27bSRobert Mustacchi 	}
68eef4f27bSRobert Mustacchi 
69eef4f27bSRobert Mustacchi 	umdevice->dev_start = B_TRUE;
70eef4f27bSRobert Mustacchi 
71eef4f27bSRobert Mustacchi 	rc = 0;
72eef4f27bSRobert Mustacchi 
73eef4f27bSRobert Mustacchi done:
74eef4f27bSRobert Mustacchi 	mutex_exit(&umdevice->os_param.gld_mutex);
75eef4f27bSRobert Mustacchi 
76eef4f27bSRobert Mustacchi 	return (rc);
77eef4f27bSRobert Mustacchi }
78eef4f27bSRobert Mustacchi 
79eef4f27bSRobert Mustacchi /*
80eef4f27bSRobert Mustacchi  * Name:    bnx_m_stop
81eef4f27bSRobert Mustacchi  *
82eef4f27bSRobert Mustacchi  * Input:   ptr to driver device structure.
83eef4f27bSRobert Mustacchi  *
84eef4f27bSRobert Mustacchi  * Return:  DDI_SUCCESS or DDI_FAILURE
85eef4f27bSRobert Mustacchi  *
86eef4f27bSRobert Mustacchi  * Description:
87eef4f27bSRobert Mustacchi  *          This routine stops packet reception by clearing RX MASK
88eef4f27bSRobert Mustacchi  *          register. Also interrupts are disabled for this device.
89eef4f27bSRobert Mustacchi  */
90eef4f27bSRobert Mustacchi static void
bnx_m_stop(void * arg)91eef4f27bSRobert Mustacchi bnx_m_stop(void *arg)
92eef4f27bSRobert Mustacchi {
93eef4f27bSRobert Mustacchi 	um_device_t *umdevice;
94eef4f27bSRobert Mustacchi 
95eef4f27bSRobert Mustacchi 	umdevice = (um_device_t *)arg;
96eef4f27bSRobert Mustacchi 
97eef4f27bSRobert Mustacchi 	mutex_enter(&umdevice->os_param.gld_mutex);
98eef4f27bSRobert Mustacchi 
99eef4f27bSRobert Mustacchi 	if (umdevice->dev_start == B_TRUE) {
100eef4f27bSRobert Mustacchi 		umdevice->dev_start = B_FALSE;
101eef4f27bSRobert Mustacchi 		umdevice->link_updates_ok = B_FALSE;
102eef4f27bSRobert Mustacchi 
103eef4f27bSRobert Mustacchi 		bnx_hdwr_release(umdevice);
104eef4f27bSRobert Mustacchi 
105eef4f27bSRobert Mustacchi 		/* Report the link state back to unknown. */
106eef4f27bSRobert Mustacchi 		bnx_gld_link(umdevice, LINK_STATE_UNKNOWN);
107eef4f27bSRobert Mustacchi 
108eef4f27bSRobert Mustacchi 		umdevice->dev_var.indLink   = 0;
109eef4f27bSRobert Mustacchi 		umdevice->dev_var.indMedium = 0;
110eef4f27bSRobert Mustacchi 	}
111eef4f27bSRobert Mustacchi 
112eef4f27bSRobert Mustacchi 	mutex_exit(&umdevice->os_param.gld_mutex);
113eef4f27bSRobert Mustacchi }
114eef4f27bSRobert Mustacchi 
115eef4f27bSRobert Mustacchi 
116eef4f27bSRobert Mustacchi 
117eef4f27bSRobert Mustacchi /*
118eef4f27bSRobert Mustacchi  * Name:    bnx_m_unicast
119eef4f27bSRobert Mustacchi  *
120eef4f27bSRobert Mustacchi  * Input:   ptr to driver device structure,
121eef4f27bSRobert Mustacchi  *          pointer to buffer containing MAC address.
122eef4f27bSRobert Mustacchi  *
123eef4f27bSRobert Mustacchi  * Return:  DDI_SUCCESS or DDI_FAILURE
124eef4f27bSRobert Mustacchi  *
125eef4f27bSRobert Mustacchi  * Description:
126eef4f27bSRobert Mustacchi  */
127eef4f27bSRobert Mustacchi static int
bnx_m_unicast(void * arg,const uint8_t * macaddr)128eef4f27bSRobert Mustacchi bnx_m_unicast(void *arg, const uint8_t *macaddr)
129eef4f27bSRobert Mustacchi {
130eef4f27bSRobert Mustacchi 	int rc;
131eef4f27bSRobert Mustacchi 	um_device_t *umdevice;
132eef4f27bSRobert Mustacchi 	lm_device_t *lmdevice;
133eef4f27bSRobert Mustacchi 
134eef4f27bSRobert Mustacchi 	umdevice = (um_device_t *)arg;
135eef4f27bSRobert Mustacchi 	lmdevice = &(umdevice->lm_dev);
136eef4f27bSRobert Mustacchi 
137eef4f27bSRobert Mustacchi 	mutex_enter(&umdevice->os_param.gld_mutex);
138eef4f27bSRobert Mustacchi 
139eef4f27bSRobert Mustacchi 	/* Validate MAC address */
140eef4f27bSRobert Mustacchi 	if (IS_ETH_MULTICAST(macaddr)) {
141eef4f27bSRobert Mustacchi 		cmn_err(CE_WARN, "%s: Attempt to program a multicast / "
142eef4f27bSRobert Mustacchi 		    "broadcast address as a MAC address.", umdevice->dev_name);
143eef4f27bSRobert Mustacchi 		rc = EINVAL;
144eef4f27bSRobert Mustacchi 		goto done;
145eef4f27bSRobert Mustacchi 	}
146eef4f27bSRobert Mustacchi 
147eef4f27bSRobert Mustacchi 	if (umdevice->dev_start == B_TRUE) {
148eef4f27bSRobert Mustacchi 		if (lm_set_mac_addr(lmdevice, 0,
149eef4f27bSRobert Mustacchi 		    &(lmdevice->params.mac_addr[0])) != LM_STATUS_SUCCESS) {
150eef4f27bSRobert Mustacchi 			cmn_err(CE_WARN, "%s: failed to program MAC address.",
151eef4f27bSRobert Mustacchi 			    umdevice->dev_name);
152eef4f27bSRobert Mustacchi 			rc = EIO;
153eef4f27bSRobert Mustacchi 			goto done;
154eef4f27bSRobert Mustacchi 		}
155eef4f27bSRobert Mustacchi 	}
156eef4f27bSRobert Mustacchi 
157eef4f27bSRobert Mustacchi 	bcopy(macaddr, &(lmdevice->params.mac_addr[0]), ETHERADDRL);
158eef4f27bSRobert Mustacchi 
159eef4f27bSRobert Mustacchi 	rc = 0;
160eef4f27bSRobert Mustacchi 
161eef4f27bSRobert Mustacchi done:
162eef4f27bSRobert Mustacchi 	mutex_exit(&umdevice->os_param.gld_mutex);
163eef4f27bSRobert Mustacchi 
164eef4f27bSRobert Mustacchi 	return (rc);
165eef4f27bSRobert Mustacchi }
166eef4f27bSRobert Mustacchi 
167eef4f27bSRobert Mustacchi static int
bnx_mc_add(um_device_t * umdevice,const uint8_t * const mc_addr)168eef4f27bSRobert Mustacchi bnx_mc_add(um_device_t *umdevice, const uint8_t *const mc_addr)
169eef4f27bSRobert Mustacchi {
170eef4f27bSRobert Mustacchi 	int rc;
171eef4f27bSRobert Mustacchi 	int index;
172eef4f27bSRobert Mustacchi 	lm_status_t   lmstatus;
173eef4f27bSRobert Mustacchi 	lm_device_t *lmdevice;
174eef4f27bSRobert Mustacchi 
175eef4f27bSRobert Mustacchi 	lmdevice = &(umdevice->lm_dev);
176eef4f27bSRobert Mustacchi 
177eef4f27bSRobert Mustacchi 	index = bnx_find_mchash_collision(&(lmdevice->mc_table), mc_addr);
178eef4f27bSRobert Mustacchi 	if (index == -1) {
179eef4f27bSRobert Mustacchi 		lmstatus = lm_add_mc(lmdevice, (u8_t *)mc_addr);
180eef4f27bSRobert Mustacchi 		if (lmstatus == LM_STATUS_SUCCESS) {
181eef4f27bSRobert Mustacchi 			umdevice->dev_var.rx_filter_mask |=
182eef4f27bSRobert Mustacchi 			    LM_RX_MASK_ACCEPT_MULTICAST;
183eef4f27bSRobert Mustacchi 			rc = 0;
184eef4f27bSRobert Mustacchi 		} else {
185eef4f27bSRobert Mustacchi 			rc = ENOMEM;
186eef4f27bSRobert Mustacchi 		}
187eef4f27bSRobert Mustacchi 	} else {
188eef4f27bSRobert Mustacchi 		lmdevice->mc_table.addr_arr[index].ref_cnt++;
189eef4f27bSRobert Mustacchi 		rc = 0;
190eef4f27bSRobert Mustacchi 	}
191eef4f27bSRobert Mustacchi 
192eef4f27bSRobert Mustacchi 	return (rc);
193eef4f27bSRobert Mustacchi }
194eef4f27bSRobert Mustacchi 
195eef4f27bSRobert Mustacchi static int
bnx_mc_del(um_device_t * umdevice,const uint8_t * const mc_addr)196eef4f27bSRobert Mustacchi bnx_mc_del(um_device_t *umdevice, const uint8_t *const mc_addr)
197eef4f27bSRobert Mustacchi {
198eef4f27bSRobert Mustacchi 	int rc;
199eef4f27bSRobert Mustacchi 	int index;
200eef4f27bSRobert Mustacchi 	lm_status_t lmstatus;
201eef4f27bSRobert Mustacchi 	lm_device_t *lmdevice;
202eef4f27bSRobert Mustacchi 
203eef4f27bSRobert Mustacchi 	lmdevice = &(umdevice->lm_dev);
204eef4f27bSRobert Mustacchi 
205eef4f27bSRobert Mustacchi 	index = bnx_find_mchash_collision(&(lmdevice->mc_table), mc_addr);
206eef4f27bSRobert Mustacchi 	if (index == -1) {
207eef4f27bSRobert Mustacchi 		rc = ENXIO;
208eef4f27bSRobert Mustacchi 	} else {
209eef4f27bSRobert Mustacchi 		lmstatus = lm_del_mc(lmdevice,
210eef4f27bSRobert Mustacchi 		    lmdevice->mc_table.addr_arr[index].mc_addr);
211eef4f27bSRobert Mustacchi 		if (lmstatus == LM_STATUS_SUCCESS) {
212eef4f27bSRobert Mustacchi 			if (lmdevice->mc_table.entry_cnt == 0) {
213eef4f27bSRobert Mustacchi 				umdevice->dev_var.rx_filter_mask &=
214eef4f27bSRobert Mustacchi 				    ~LM_RX_MASK_ACCEPT_MULTICAST;
215eef4f27bSRobert Mustacchi 			}
216eef4f27bSRobert Mustacchi 
217eef4f27bSRobert Mustacchi 			rc = 0;
218eef4f27bSRobert Mustacchi 		} else {
219eef4f27bSRobert Mustacchi 			rc = ENXIO;
220eef4f27bSRobert Mustacchi 		}
221eef4f27bSRobert Mustacchi 	}
222eef4f27bSRobert Mustacchi 
223eef4f27bSRobert Mustacchi 	return (rc);
224eef4f27bSRobert Mustacchi }
225eef4f27bSRobert Mustacchi 
226eef4f27bSRobert Mustacchi 
227eef4f27bSRobert Mustacchi 
228eef4f27bSRobert Mustacchi /*
229eef4f27bSRobert Mustacchi  * Name:    bnx_m_multicast
230eef4f27bSRobert Mustacchi  *
231eef4f27bSRobert Mustacchi  * Input:   ptr to driver device structure,
232eef4f27bSRobert Mustacchi  *          boolean describing whether to enable or disable this address,
233eef4f27bSRobert Mustacchi  *          pointer to buffer containing multicast address.
234eef4f27bSRobert Mustacchi  *
235eef4f27bSRobert Mustacchi  * Return:  DDI_SUCCESS or DDI_FAILURE
236eef4f27bSRobert Mustacchi  *
237eef4f27bSRobert Mustacchi  * Description:
238eef4f27bSRobert Mustacchi  *          This function is used to enable or disable multicast packet
239eef4f27bSRobert Mustacchi  *          reception for particular multicast addresses.
240eef4f27bSRobert Mustacchi  */
241eef4f27bSRobert Mustacchi static int
bnx_m_multicast(void * arg,boolean_t multiflag,const uint8_t * multicastaddr)242eef4f27bSRobert Mustacchi bnx_m_multicast(void * arg, boolean_t multiflag, const uint8_t *multicastaddr)
243eef4f27bSRobert Mustacchi {
244eef4f27bSRobert Mustacchi 	um_device_t *umdevice;
245eef4f27bSRobert Mustacchi 	int rc;
246eef4f27bSRobert Mustacchi 
247eef4f27bSRobert Mustacchi 	umdevice = (um_device_t *)arg;
248eef4f27bSRobert Mustacchi 
249eef4f27bSRobert Mustacchi 	mutex_enter(&umdevice->os_param.gld_mutex);
250eef4f27bSRobert Mustacchi 
251eef4f27bSRobert Mustacchi 	if (umdevice->dev_start != B_TRUE) {
252eef4f27bSRobert Mustacchi 		rc = EAGAIN;
253eef4f27bSRobert Mustacchi 		goto done;
254eef4f27bSRobert Mustacchi 	}
255eef4f27bSRobert Mustacchi 
256eef4f27bSRobert Mustacchi 	switch (multiflag) {
257eef4f27bSRobert Mustacchi 		case B_TRUE:
258eef4f27bSRobert Mustacchi 			rc = bnx_mc_add(umdevice, multicastaddr);
259eef4f27bSRobert Mustacchi 			break;
260eef4f27bSRobert Mustacchi 
261eef4f27bSRobert Mustacchi 		case B_FALSE:
262eef4f27bSRobert Mustacchi 			rc = bnx_mc_del(umdevice, multicastaddr);
263eef4f27bSRobert Mustacchi 			break;
264eef4f27bSRobert Mustacchi 
265eef4f27bSRobert Mustacchi 		default:
266eef4f27bSRobert Mustacchi 			rc = EINVAL;
267eef4f27bSRobert Mustacchi 			break;
268eef4f27bSRobert Mustacchi 	}
269eef4f27bSRobert Mustacchi 
270eef4f27bSRobert Mustacchi done:
271eef4f27bSRobert Mustacchi 	mutex_exit(&umdevice->os_param.gld_mutex);
272eef4f27bSRobert Mustacchi 
273eef4f27bSRobert Mustacchi 	return (rc);
274eef4f27bSRobert Mustacchi }
275eef4f27bSRobert Mustacchi 
276eef4f27bSRobert Mustacchi 
277eef4f27bSRobert Mustacchi 
278eef4f27bSRobert Mustacchi /*
279eef4f27bSRobert Mustacchi  * Name:    bnx_m_promiscuous
280eef4f27bSRobert Mustacchi  *
281eef4f27bSRobert Mustacchi  * Input:   ptr to driver device structure,
282eef4f27bSRobert Mustacchi  *          boolean describing whether to enable or disable promiscuous mode.
283eef4f27bSRobert Mustacchi  *
284eef4f27bSRobert Mustacchi  * Return:  DDI_SUCCESS or DDI_FAILURE
285eef4f27bSRobert Mustacchi  *
286eef4f27bSRobert Mustacchi  * Description:
287eef4f27bSRobert Mustacchi  *          This function enables promiscuous mode for this device.
288eef4f27bSRobert Mustacchi  *		'flags' argument determines the type of mode being set,
289eef4f27bSRobert Mustacchi  *		"PROMISC_PHY" enables reception of all packet types including
290eef4f27bSRobert Mustacchi  *		bad/error packets. "PROMISC_MULTI" mode will enable all
291eef4f27bSRobert Mustacchi  *		multicast packets, unicasts and broadcast packets to be
292eef4f27bSRobert Mustacchi  *		received. "PROMISC_NONE" will enable only broadcast and
293eef4f27bSRobert Mustacchi  *		unicast packets.
294eef4f27bSRobert Mustacchi  */
295eef4f27bSRobert Mustacchi static int
bnx_m_promiscuous(void * arg,boolean_t promiscflag)296eef4f27bSRobert Mustacchi bnx_m_promiscuous(void *arg, boolean_t promiscflag)
297eef4f27bSRobert Mustacchi {
298eef4f27bSRobert Mustacchi 	int rc;
299eef4f27bSRobert Mustacchi 	um_device_t *umdevice;
300eef4f27bSRobert Mustacchi 
301eef4f27bSRobert Mustacchi 	umdevice = (um_device_t *)arg;
302eef4f27bSRobert Mustacchi 
303eef4f27bSRobert Mustacchi 	mutex_enter(&umdevice->os_param.gld_mutex);
304eef4f27bSRobert Mustacchi 
305eef4f27bSRobert Mustacchi 	if (umdevice->dev_start != B_TRUE) {
306eef4f27bSRobert Mustacchi 		rc = EAGAIN;
307eef4f27bSRobert Mustacchi 		goto done;
308eef4f27bSRobert Mustacchi 	}
309eef4f27bSRobert Mustacchi 
310eef4f27bSRobert Mustacchi 	switch (promiscflag) {
311eef4f27bSRobert Mustacchi 		case B_TRUE:
312eef4f27bSRobert Mustacchi 			umdevice->dev_var.rx_filter_mask |=
313eef4f27bSRobert Mustacchi 			    LM_RX_MASK_PROMISCUOUS_MODE;
314eef4f27bSRobert Mustacchi 			break;
315eef4f27bSRobert Mustacchi 
316eef4f27bSRobert Mustacchi 		case B_FALSE:
317eef4f27bSRobert Mustacchi 			umdevice->dev_var.rx_filter_mask &=
318eef4f27bSRobert Mustacchi 			    ~LM_RX_MASK_PROMISCUOUS_MODE;
319eef4f27bSRobert Mustacchi 			break;
320eef4f27bSRobert Mustacchi 
321eef4f27bSRobert Mustacchi 		default:
322eef4f27bSRobert Mustacchi 			rc = EINVAL;
323eef4f27bSRobert Mustacchi 			goto done;
324eef4f27bSRobert Mustacchi 	}
325eef4f27bSRobert Mustacchi 
326eef4f27bSRobert Mustacchi 	(void) lm_set_rx_mask(&(umdevice->lm_dev), RX_FILTER_USER_IDX0,
327eef4f27bSRobert Mustacchi 	    umdevice->dev_var.rx_filter_mask);
328eef4f27bSRobert Mustacchi 
329eef4f27bSRobert Mustacchi 	rc = 0;
330eef4f27bSRobert Mustacchi 
331eef4f27bSRobert Mustacchi done:
332eef4f27bSRobert Mustacchi 	mutex_exit(&umdevice->os_param.gld_mutex);
333eef4f27bSRobert Mustacchi 
334eef4f27bSRobert Mustacchi 	return (rc);
335eef4f27bSRobert Mustacchi }
336eef4f27bSRobert Mustacchi 
337eef4f27bSRobert Mustacchi 
338eef4f27bSRobert Mustacchi static mblk_t *
bnx_m_tx(void * arg,mblk_t * mp)339eef4f27bSRobert Mustacchi bnx_m_tx(void *arg, mblk_t *mp)
340eef4f27bSRobert Mustacchi {
341eef4f27bSRobert Mustacchi 	int rc;
342eef4f27bSRobert Mustacchi 	mblk_t *nmp;
343eef4f27bSRobert Mustacchi 	um_device_t *umdevice;
344eef4f27bSRobert Mustacchi 
345eef4f27bSRobert Mustacchi 	umdevice = (um_device_t *)arg;
346eef4f27bSRobert Mustacchi 
347eef4f27bSRobert Mustacchi 	rw_enter(&umdevice->os_param.gld_snd_mutex, RW_READER);
348eef4f27bSRobert Mustacchi 
349eef4f27bSRobert Mustacchi 	if (umdevice->dev_start != B_TRUE ||
350eef4f27bSRobert Mustacchi 	    umdevice->nddcfg.link_speed == 0) {
351eef4f27bSRobert Mustacchi 		freemsgchain(mp);
352eef4f27bSRobert Mustacchi 		mp = NULL;
353eef4f27bSRobert Mustacchi 		goto done;
354eef4f27bSRobert Mustacchi 	}
355eef4f27bSRobert Mustacchi 
356eef4f27bSRobert Mustacchi 	nmp = NULL;
357eef4f27bSRobert Mustacchi 
358eef4f27bSRobert Mustacchi 	while (mp) {
359eef4f27bSRobert Mustacchi 		/* Save the next pointer, in case we do double copy. */
360eef4f27bSRobert Mustacchi 		nmp = mp->b_next;
361eef4f27bSRobert Mustacchi 		mp->b_next = NULL;
362eef4f27bSRobert Mustacchi 
363eef4f27bSRobert Mustacchi 		rc = bnx_xmit_ring_xmit_mblk(umdevice, 0, mp);
364eef4f27bSRobert Mustacchi 
365eef4f27bSRobert Mustacchi 		if (rc == BNX_SEND_GOODXMIT) {
366eef4f27bSRobert Mustacchi 			mp = nmp;
367eef4f27bSRobert Mustacchi 			continue;
368eef4f27bSRobert Mustacchi 		}
369eef4f27bSRobert Mustacchi 
370eef4f27bSRobert Mustacchi 		if (rc == BNX_SEND_DEFERPKT)
371eef4f27bSRobert Mustacchi 			mp = nmp;
372eef4f27bSRobert Mustacchi 		else
373eef4f27bSRobert Mustacchi 			mp->b_next = nmp;
374eef4f27bSRobert Mustacchi 
375eef4f27bSRobert Mustacchi 		break;
376eef4f27bSRobert Mustacchi 	}
377eef4f27bSRobert Mustacchi 
378eef4f27bSRobert Mustacchi done:
379eef4f27bSRobert Mustacchi 	rw_exit(&umdevice->os_param.gld_snd_mutex);
380eef4f27bSRobert Mustacchi 
381eef4f27bSRobert Mustacchi 	return (mp);
382eef4f27bSRobert Mustacchi }
383eef4f27bSRobert Mustacchi 
384eef4f27bSRobert Mustacchi 
385eef4f27bSRobert Mustacchi static u64_t
shift_left32(u32_t val)386eef4f27bSRobert Mustacchi shift_left32(u32_t val)
387eef4f27bSRobert Mustacchi {
388eef4f27bSRobert Mustacchi 	lm_u64_t tmp;
389eef4f27bSRobert Mustacchi 
390eef4f27bSRobert Mustacchi 	/* FIXME -- Get rid of shift_left32() */
391eef4f27bSRobert Mustacchi 
392eef4f27bSRobert Mustacchi 	tmp.as_u32.low = 0;
393eef4f27bSRobert Mustacchi 	tmp.as_u32.high = val;
394eef4f27bSRobert Mustacchi 
395eef4f27bSRobert Mustacchi 	return (tmp.as_u64);
396eef4f27bSRobert Mustacchi }
397eef4f27bSRobert Mustacchi 
398*fe803bd5SRobert Mustacchi static mac_ether_media_t
bnx_um_to_media(um_device_t * um)399*fe803bd5SRobert Mustacchi bnx_um_to_media(um_device_t *um)
400*fe803bd5SRobert Mustacchi {
401*fe803bd5SRobert Mustacchi 	if (um->nddcfg.link_speed == 0) {
402*fe803bd5SRobert Mustacchi 		return (ETHER_MEDIA_NONE);
403*fe803bd5SRobert Mustacchi 	}
404eef4f27bSRobert Mustacchi 
405*fe803bd5SRobert Mustacchi 	/*
406*fe803bd5SRobert Mustacchi 	 * bnx only supports 2.5G and 1G fiber. It does not support 100BASE-FX.
407*fe803bd5SRobert Mustacchi 	 * Similarly, it is too old to support 2500BASE-T and the NetExtreme II
408*fe803bd5SRobert Mustacchi 	 * programmer's guide makes it clear it only ever supported 100BASE-TX
409*fe803bd5SRobert Mustacchi 	 * and never -T2 or -T4.
410*fe803bd5SRobert Mustacchi 	 */
411*fe803bd5SRobert Mustacchi 	if (um->dev_var.isfiber) {
412*fe803bd5SRobert Mustacchi 		switch (um->nddcfg.link_speed) {
413*fe803bd5SRobert Mustacchi 		case 2500:
414*fe803bd5SRobert Mustacchi 			return (ETHER_MEDIA_2500BASE_X);
415*fe803bd5SRobert Mustacchi 		case 1000:
416*fe803bd5SRobert Mustacchi 			return (ETHER_MEDIA_1000BASE_X);
417*fe803bd5SRobert Mustacchi 		default:
418*fe803bd5SRobert Mustacchi 			break;
419*fe803bd5SRobert Mustacchi 		}
420*fe803bd5SRobert Mustacchi 	} else {
421*fe803bd5SRobert Mustacchi 		switch (um->nddcfg.link_speed) {
422*fe803bd5SRobert Mustacchi 		case 1000:
423*fe803bd5SRobert Mustacchi 			return (ETHER_MEDIA_1000BASE_T);
424*fe803bd5SRobert Mustacchi 		case 100:
425*fe803bd5SRobert Mustacchi 			return (ETHER_MEDIA_100BASE_TX);
426*fe803bd5SRobert Mustacchi 		case 10:
427*fe803bd5SRobert Mustacchi 			return (ETHER_MEDIA_10BASE_T);
428*fe803bd5SRobert Mustacchi 		default:
429*fe803bd5SRobert Mustacchi 			break;
430*fe803bd5SRobert Mustacchi 		}
431*fe803bd5SRobert Mustacchi 	}
432*fe803bd5SRobert Mustacchi 
433*fe803bd5SRobert Mustacchi 	return (ETHER_MEDIA_UNKNOWN);
434*fe803bd5SRobert Mustacchi }
435eef4f27bSRobert Mustacchi 
436eef4f27bSRobert Mustacchi /*
437eef4f27bSRobert Mustacchi  * Name:    bnx_m_stats
438eef4f27bSRobert Mustacchi  *
439eef4f27bSRobert Mustacchi  * Input:   ptr to mac info structure, ptr to gld_stats struct
440eef4f27bSRobert Mustacchi  *
441eef4f27bSRobert Mustacchi  * Return:  DDI_SUCCESS or DDI_FAILURE
442eef4f27bSRobert Mustacchi  *
443eef4f27bSRobert Mustacchi  * Description: bnx_m_stats() populates gld_stats structure elements
444eef4f27bSRobert Mustacchi  *              from latest data from statistic block.
445eef4f27bSRobert Mustacchi  */
446eef4f27bSRobert Mustacchi static int
bnx_m_stats(void * arg,uint_t stat,uint64_t * val)447eef4f27bSRobert Mustacchi bnx_m_stats(void * arg, uint_t stat, uint64_t *val)
448eef4f27bSRobert Mustacchi {
449eef4f27bSRobert Mustacchi 	int rc;
450eef4f27bSRobert Mustacchi 	um_device_t *umdevice;
451eef4f27bSRobert Mustacchi 	lm_device_t *lmdevice;
452eef4f27bSRobert Mustacchi 	const bnx_lnk_cfg_t *linkconf;
453eef4f27bSRobert Mustacchi 
454eef4f27bSRobert Mustacchi 	umdevice = (um_device_t *)arg;
455eef4f27bSRobert Mustacchi 
456eef4f27bSRobert Mustacchi 	if (umdevice == NULL || val == NULL) {
457eef4f27bSRobert Mustacchi 		return (EINVAL);
458eef4f27bSRobert Mustacchi 	}
459eef4f27bSRobert Mustacchi 
460eef4f27bSRobert Mustacchi 	lmdevice = &(umdevice->lm_dev);
461eef4f27bSRobert Mustacchi 
462eef4f27bSRobert Mustacchi 	/* FIXME -- Fix STATS collections */
463eef4f27bSRobert Mustacchi 
464eef4f27bSRobert Mustacchi 	if (umdevice->dev_var.isfiber) {
465eef4f27bSRobert Mustacchi 		linkconf = &bnx_serdes_config;
466eef4f27bSRobert Mustacchi 	} else {
467eef4f27bSRobert Mustacchi 		linkconf = &bnx_copper_config;
468eef4f27bSRobert Mustacchi 	}
469eef4f27bSRobert Mustacchi 
470eef4f27bSRobert Mustacchi 	mutex_enter(&umdevice->os_param.gld_mutex);
471eef4f27bSRobert Mustacchi 
472eef4f27bSRobert Mustacchi 	if (umdevice->dev_start != B_TRUE) {
473eef4f27bSRobert Mustacchi 		rc = EAGAIN;
474eef4f27bSRobert Mustacchi 		goto done;
475eef4f27bSRobert Mustacchi 	}
476eef4f27bSRobert Mustacchi 
477eef4f27bSRobert Mustacchi 	*val = 0;
478eef4f27bSRobert Mustacchi 	switch (stat) {
479eef4f27bSRobert Mustacchi 	case MAC_STAT_IFSPEED:
480eef4f27bSRobert Mustacchi 		*val = umdevice->nddcfg.link_speed * 1000000ull;
481eef4f27bSRobert Mustacchi 		break;
482eef4f27bSRobert Mustacchi 	case MAC_STAT_MULTIRCV:
483eef4f27bSRobert Mustacchi 		*val += shift_left32(
484eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_IfHCInMulticastPkts_hi);
485eef4f27bSRobert Mustacchi 		*val +=
486eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_IfHCInMulticastPkts_lo;
487eef4f27bSRobert Mustacchi 		break;
488eef4f27bSRobert Mustacchi 	case MAC_STAT_BRDCSTRCV:
489eef4f27bSRobert Mustacchi 		*val += shift_left32(
490eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_IfHCInBroadcastPkts_hi);
491eef4f27bSRobert Mustacchi 		*val +=
492eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_IfHCInBroadcastPkts_lo;
493eef4f27bSRobert Mustacchi 		break;
494eef4f27bSRobert Mustacchi 	case MAC_STAT_MULTIXMT:
495eef4f27bSRobert Mustacchi 		*val += shift_left32(
496eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_IfHCOutMulticastPkts_hi);
497eef4f27bSRobert Mustacchi 		*val +=
498eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_IfHCOutMulticastPkts_lo;
499eef4f27bSRobert Mustacchi 		break;
500eef4f27bSRobert Mustacchi 	case MAC_STAT_BRDCSTXMT:
501eef4f27bSRobert Mustacchi 		*val += shift_left32(
502eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_IfHCOutBroadcastPkts_hi);
503eef4f27bSRobert Mustacchi 		*val +=
504eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_IfHCOutBroadcastPkts_lo;
505eef4f27bSRobert Mustacchi 		break;
506eef4f27bSRobert Mustacchi 	case MAC_STAT_NORCVBUF:
507eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->stat_IfInMBUFDiscards;
508eef4f27bSRobert Mustacchi 		break;
509eef4f27bSRobert Mustacchi 	case ETHER_STAT_MACRCV_ERRORS:
510eef4f27bSRobert Mustacchi 	case MAC_STAT_IERRORS:
511eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->stat_Dot3StatsFCSErrors +
512eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_Dot3StatsAlignmentErrors +
513eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_EtherStatsUndersizePkts +
514eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_EtherStatsOverrsizePkts;
515eef4f27bSRobert Mustacchi 		break;
516eef4f27bSRobert Mustacchi 	case MAC_STAT_OERRORS:
517eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->
518eef4f27bSRobert Mustacchi 		    stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
519eef4f27bSRobert Mustacchi 		break;
520eef4f27bSRobert Mustacchi 	case MAC_STAT_COLLISIONS:
521eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->stat_EtherStatsCollisions;
522eef4f27bSRobert Mustacchi 		break;
523eef4f27bSRobert Mustacchi 	case MAC_STAT_RBYTES:
524eef4f27bSRobert Mustacchi 		*val += shift_left32(
525eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_IfHCInOctets_hi);
526eef4f27bSRobert Mustacchi 		*val +=
527eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_IfHCInOctets_lo;
528eef4f27bSRobert Mustacchi 		break;
529eef4f27bSRobert Mustacchi 	case MAC_STAT_IPACKETS:
530eef4f27bSRobert Mustacchi 		*val += shift_left32(lmdevice->vars.stats_virt->
531eef4f27bSRobert Mustacchi 		    stat_IfHCInUcastPkts_hi);
532eef4f27bSRobert Mustacchi 		*val += lmdevice->vars.stats_virt->stat_IfHCInUcastPkts_lo;
533eef4f27bSRobert Mustacchi 
534eef4f27bSRobert Mustacchi 		*val += shift_left32(lmdevice->vars.stats_virt->
535eef4f27bSRobert Mustacchi 		    stat_IfHCInMulticastPkts_hi);
536eef4f27bSRobert Mustacchi 		*val += lmdevice->vars.stats_virt->stat_IfHCInMulticastPkts_lo;
537eef4f27bSRobert Mustacchi 
538eef4f27bSRobert Mustacchi 		*val += shift_left32(lmdevice->vars.stats_virt->
539eef4f27bSRobert Mustacchi 		    stat_IfHCInBroadcastPkts_hi);
540eef4f27bSRobert Mustacchi 		*val += lmdevice->vars.stats_virt->stat_IfHCInBroadcastPkts_lo;
541eef4f27bSRobert Mustacchi 		break;
542eef4f27bSRobert Mustacchi 	case MAC_STAT_OBYTES:
543eef4f27bSRobert Mustacchi 		*val += shift_left32(
544eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_IfHCOutOctets_hi);
545eef4f27bSRobert Mustacchi 		*val +=
546eef4f27bSRobert Mustacchi 		    lmdevice->vars.stats_virt->stat_IfHCOutOctets_lo;
547eef4f27bSRobert Mustacchi 		break;
548eef4f27bSRobert Mustacchi 	case MAC_STAT_OPACKETS:
549eef4f27bSRobert Mustacchi 		*val += shift_left32(lmdevice->vars.stats_virt->
550eef4f27bSRobert Mustacchi 		    stat_IfHCOutUcastPkts_hi);
551eef4f27bSRobert Mustacchi 		*val += lmdevice->vars.stats_virt->stat_IfHCOutUcastPkts_lo;
552eef4f27bSRobert Mustacchi 
553eef4f27bSRobert Mustacchi 		*val += shift_left32(lmdevice->vars.stats_virt->
554eef4f27bSRobert Mustacchi 		    stat_IfHCOutMulticastPkts_hi);
555eef4f27bSRobert Mustacchi 		*val += lmdevice->vars.stats_virt->stat_IfHCOutMulticastPkts_lo;
556eef4f27bSRobert Mustacchi 
557eef4f27bSRobert Mustacchi 		*val += shift_left32(lmdevice->vars.stats_virt->
558eef4f27bSRobert Mustacchi 		    stat_IfHCOutBroadcastPkts_hi);
559eef4f27bSRobert Mustacchi 		*val += lmdevice->vars.stats_virt->stat_IfHCOutBroadcastPkts_lo;
560eef4f27bSRobert Mustacchi 		break;
561eef4f27bSRobert Mustacchi 	case ETHER_STAT_ALIGN_ERRORS:
562eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->stat_Dot3StatsAlignmentErrors;
563eef4f27bSRobert Mustacchi 		break;
564eef4f27bSRobert Mustacchi 	case ETHER_STAT_FCS_ERRORS:
565eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->stat_Dot3StatsFCSErrors;
566eef4f27bSRobert Mustacchi 		break;
567eef4f27bSRobert Mustacchi 	case ETHER_STAT_FIRST_COLLISIONS:
568eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->
569eef4f27bSRobert Mustacchi 		    stat_Dot3StatsSingleCollisionFrames;
570eef4f27bSRobert Mustacchi 		break;
571eef4f27bSRobert Mustacchi 	case ETHER_STAT_MULTI_COLLISIONS:
572eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->
573eef4f27bSRobert Mustacchi 		    stat_Dot3StatsMultipleCollisionFrames;
574eef4f27bSRobert Mustacchi 		break;
575eef4f27bSRobert Mustacchi 	case ETHER_STAT_DEFER_XMTS:
576eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->
577eef4f27bSRobert Mustacchi 		    stat_Dot3StatsDeferredTransmissions;
578eef4f27bSRobert Mustacchi 		break;
579eef4f27bSRobert Mustacchi 	case ETHER_STAT_TX_LATE_COLLISIONS:
580eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->
581eef4f27bSRobert Mustacchi 		    stat_Dot3StatsLateCollisions;
582eef4f27bSRobert Mustacchi 		break;
583eef4f27bSRobert Mustacchi 	case ETHER_STAT_EX_COLLISIONS:
584eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->
585eef4f27bSRobert Mustacchi 		    stat_Dot3StatsExcessiveCollisions;
586eef4f27bSRobert Mustacchi 		break;
587eef4f27bSRobert Mustacchi 	case ETHER_STAT_MACXMT_ERRORS:
588eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->
589eef4f27bSRobert Mustacchi 		    stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
590eef4f27bSRobert Mustacchi 		break;
591eef4f27bSRobert Mustacchi 	case ETHER_STAT_CARRIER_ERRORS:
592eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->
593eef4f27bSRobert Mustacchi 		    stat_Dot3StatsCarrierSenseErrors;
594eef4f27bSRobert Mustacchi 		break;
595eef4f27bSRobert Mustacchi 	case ETHER_STAT_TOOLONG_ERRORS:
596eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->
597eef4f27bSRobert Mustacchi 		    stat_EtherStatsOverrsizePkts;
598eef4f27bSRobert Mustacchi 		break;
599eef4f27bSRobert Mustacchi #if (MAC_VERSION > 1)
600eef4f27bSRobert Mustacchi 	case ETHER_STAT_TOOSHORT_ERRORS:
601eef4f27bSRobert Mustacchi 		*val = lmdevice->vars.stats_virt->
602eef4f27bSRobert Mustacchi 		    stat_EtherStatsUndersizePkts;
603eef4f27bSRobert Mustacchi 		break;
604eef4f27bSRobert Mustacchi #endif
605eef4f27bSRobert Mustacchi 	case ETHER_STAT_XCVR_ADDR:
606eef4f27bSRobert Mustacchi 		*val = lmdevice->params.phy_addr;
607eef4f27bSRobert Mustacchi 		break;
608eef4f27bSRobert Mustacchi 	case ETHER_STAT_XCVR_ID:
609eef4f27bSRobert Mustacchi 		*val = lmdevice->hw_info.phy_id;
610eef4f27bSRobert Mustacchi 		break;
611eef4f27bSRobert Mustacchi 	case ETHER_STAT_XCVR_INUSE:
612*fe803bd5SRobert Mustacchi 		*val = (uint64_t)bnx_um_to_media(umdevice);
613eef4f27bSRobert Mustacchi 		break;
614eef4f27bSRobert Mustacchi 	case ETHER_STAT_CAP_1000FDX:
615eef4f27bSRobert Mustacchi 		*val = 1;
616eef4f27bSRobert Mustacchi 		break;
617eef4f27bSRobert Mustacchi 	case ETHER_STAT_CAP_1000HDX:
618eef4f27bSRobert Mustacchi 		*val = linkconf->param_1000hdx;
619eef4f27bSRobert Mustacchi 		break;
620eef4f27bSRobert Mustacchi 	case ETHER_STAT_CAP_100FDX:
621eef4f27bSRobert Mustacchi 		*val = linkconf->param_100fdx;
622eef4f27bSRobert Mustacchi 		break;
623eef4f27bSRobert Mustacchi 	case ETHER_STAT_CAP_100HDX:
624eef4f27bSRobert Mustacchi 		*val = linkconf->param_100hdx;
625eef4f27bSRobert Mustacchi 		break;
626eef4f27bSRobert Mustacchi 	case ETHER_STAT_CAP_10FDX:
627eef4f27bSRobert Mustacchi 		*val = linkconf->param_10fdx;
628eef4f27bSRobert Mustacchi 		break;
629eef4f27bSRobert Mustacchi 	case ETHER_STAT_CAP_10HDX:
630eef4f27bSRobert Mustacchi 		*val = linkconf->param_10hdx;
631eef4f27bSRobert Mustacchi 		break;
632eef4f27bSRobert Mustacchi 	case ETHER_STAT_CAP_ASMPAUSE:
633eef4f27bSRobert Mustacchi 		*val = 1;
634eef4f27bSRobert Mustacchi 		break;
635eef4f27bSRobert Mustacchi 	case ETHER_STAT_CAP_PAUSE:
636eef4f27bSRobert Mustacchi 		*val = 1;
637eef4f27bSRobert Mustacchi 		break;
638eef4f27bSRobert Mustacchi 	case ETHER_STAT_CAP_AUTONEG:
639eef4f27bSRobert Mustacchi 		*val = 1;
640eef4f27bSRobert Mustacchi 		break;
641eef4f27bSRobert Mustacchi #if (MAC_VERSION > 1)
642eef4f27bSRobert Mustacchi 	case ETHER_STAT_CAP_REMFAULT:
643eef4f27bSRobert Mustacchi 		*val = 1;
644eef4f27bSRobert Mustacchi 		break;
645eef4f27bSRobert Mustacchi #endif
646eef4f27bSRobert Mustacchi 	case ETHER_STAT_ADV_CAP_1000FDX:
647eef4f27bSRobert Mustacchi 		*val = umdevice->curcfg.lnkcfg.param_1000fdx;
648eef4f27bSRobert Mustacchi 		break;
649eef4f27bSRobert Mustacchi 	case ETHER_STAT_ADV_CAP_1000HDX:
650eef4f27bSRobert Mustacchi 		*val = umdevice->curcfg.lnkcfg.param_1000hdx;
651eef4f27bSRobert Mustacchi 		break;
652eef4f27bSRobert Mustacchi 	case ETHER_STAT_ADV_CAP_100FDX:
653eef4f27bSRobert Mustacchi 		*val = umdevice->curcfg.lnkcfg.param_100fdx;
654eef4f27bSRobert Mustacchi 		break;
655eef4f27bSRobert Mustacchi 	case ETHER_STAT_ADV_CAP_100HDX:
656eef4f27bSRobert Mustacchi 		*val = umdevice->curcfg.lnkcfg.param_100hdx;
657eef4f27bSRobert Mustacchi 		break;
658eef4f27bSRobert Mustacchi 	case ETHER_STAT_ADV_CAP_10FDX:
659eef4f27bSRobert Mustacchi 		*val = umdevice->curcfg.lnkcfg.param_10fdx;
660eef4f27bSRobert Mustacchi 		break;
661eef4f27bSRobert Mustacchi 	case ETHER_STAT_ADV_CAP_10HDX:
662eef4f27bSRobert Mustacchi 		*val = umdevice->curcfg.lnkcfg.param_10hdx;
663eef4f27bSRobert Mustacchi 		break;
664eef4f27bSRobert Mustacchi 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
665eef4f27bSRobert Mustacchi 		*val = 1;
666eef4f27bSRobert Mustacchi 		break;
667eef4f27bSRobert Mustacchi 	case ETHER_STAT_ADV_CAP_PAUSE:
668eef4f27bSRobert Mustacchi 		*val = 1;
669eef4f27bSRobert Mustacchi 		break;
670eef4f27bSRobert Mustacchi 	case ETHER_STAT_ADV_CAP_AUTONEG:
671eef4f27bSRobert Mustacchi 		*val = umdevice->curcfg.lnkcfg.link_autoneg;
672eef4f27bSRobert Mustacchi 		break;
673eef4f27bSRobert Mustacchi #if (MAC_VERSION > 1)
674eef4f27bSRobert Mustacchi 	case ETHER_STAT_ADV_REMFAULT:
675eef4f27bSRobert Mustacchi 		*val = 1;
676eef4f27bSRobert Mustacchi 		break;
677eef4f27bSRobert Mustacchi #endif
678eef4f27bSRobert Mustacchi 	case ETHER_STAT_LP_CAP_1000FDX:
679eef4f27bSRobert Mustacchi 		*val = umdevice->remote.param_1000fdx;
680eef4f27bSRobert Mustacchi 		break;
681eef4f27bSRobert Mustacchi 	case ETHER_STAT_LP_CAP_1000HDX:
682eef4f27bSRobert Mustacchi 		*val = umdevice->remote.param_1000hdx;
683eef4f27bSRobert Mustacchi 		break;
684eef4f27bSRobert Mustacchi 	case ETHER_STAT_LP_CAP_100FDX:
685eef4f27bSRobert Mustacchi 		*val = umdevice->remote.param_100fdx;
686eef4f27bSRobert Mustacchi 		break;
687eef4f27bSRobert Mustacchi 	case ETHER_STAT_LP_CAP_100HDX:
688eef4f27bSRobert Mustacchi 		*val = umdevice->remote.param_100hdx;
689eef4f27bSRobert Mustacchi 		break;
690eef4f27bSRobert Mustacchi 	case ETHER_STAT_LP_CAP_10FDX:
691eef4f27bSRobert Mustacchi 		*val = umdevice->remote.param_10fdx;
692eef4f27bSRobert Mustacchi 		break;
693eef4f27bSRobert Mustacchi 	case ETHER_STAT_LP_CAP_10HDX:
694eef4f27bSRobert Mustacchi 		*val = umdevice->remote.param_10hdx;
695eef4f27bSRobert Mustacchi 		break;
696eef4f27bSRobert Mustacchi 	case ETHER_STAT_LP_CAP_ASMPAUSE:
697eef4f27bSRobert Mustacchi 		/* FIXME -- Implement LP_ASYM_PAUSE stat */
698eef4f27bSRobert Mustacchi 		break;
699eef4f27bSRobert Mustacchi 	case ETHER_STAT_LP_CAP_PAUSE:
700eef4f27bSRobert Mustacchi 		/* FIXME -- Implement LP_PAUSE stat */
701eef4f27bSRobert Mustacchi 		break;
702eef4f27bSRobert Mustacchi 	case ETHER_STAT_LP_CAP_AUTONEG:
703eef4f27bSRobert Mustacchi 		*val = umdevice->remote.link_autoneg;
704eef4f27bSRobert Mustacchi 		break;
705eef4f27bSRobert Mustacchi #if (MAC_VERSION > 1)
706eef4f27bSRobert Mustacchi 	case ETHER_STAT_LP_REMFAULT:
707eef4f27bSRobert Mustacchi 		/* FIXME -- Implement LP_REMFAULT stat */
708eef4f27bSRobert Mustacchi 		break;
709eef4f27bSRobert Mustacchi #endif
710eef4f27bSRobert Mustacchi 	case ETHER_STAT_LINK_ASMPAUSE:
711eef4f27bSRobert Mustacchi 		/* FIXME -- Implement ASMPAUSE stat */
712eef4f27bSRobert Mustacchi 		break;
713eef4f27bSRobert Mustacchi 	case ETHER_STAT_LINK_PAUSE:
714eef4f27bSRobert Mustacchi 		/* FIXME -- Implement PAUSE stat */
715eef4f27bSRobert Mustacchi 		break;
716eef4f27bSRobert Mustacchi 	case ETHER_STAT_LINK_AUTONEG:
717eef4f27bSRobert Mustacchi 		*val = umdevice->curcfg.lnkcfg.link_autoneg;
718eef4f27bSRobert Mustacchi 		break;
719eef4f27bSRobert Mustacchi 	case ETHER_STAT_LINK_DUPLEX:
720eef4f27bSRobert Mustacchi 		*val = umdevice->nddcfg.link_duplex == B_TRUE ?
721eef4f27bSRobert Mustacchi 		    LINK_DUPLEX_FULL: LINK_DUPLEX_HALF;
722eef4f27bSRobert Mustacchi 		break;
723eef4f27bSRobert Mustacchi 	default:
724eef4f27bSRobert Mustacchi 		rc = ENOTSUP;
725eef4f27bSRobert Mustacchi 	}
726eef4f27bSRobert Mustacchi 
727eef4f27bSRobert Mustacchi 	rc = 0;
728eef4f27bSRobert Mustacchi 
729eef4f27bSRobert Mustacchi done:
730eef4f27bSRobert Mustacchi 	mutex_exit(&umdevice->os_param.gld_mutex);
731eef4f27bSRobert Mustacchi 
732eef4f27bSRobert Mustacchi 	return (rc);
733eef4f27bSRobert Mustacchi }
734eef4f27bSRobert Mustacchi 
735eef4f27bSRobert Mustacchi static boolean_t
bnx_m_getcapab(void * arg,mac_capab_t cap,void * cap_data)736eef4f27bSRobert Mustacchi bnx_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
737eef4f27bSRobert Mustacchi {
738eef4f27bSRobert Mustacchi 	um_device_t *umdevice;
739eef4f27bSRobert Mustacchi 
740eef4f27bSRobert Mustacchi 	umdevice = (um_device_t *)arg;
741eef4f27bSRobert Mustacchi 
742eef4f27bSRobert Mustacchi 	switch (cap) {
743eef4f27bSRobert Mustacchi 	case MAC_CAPAB_HCKSUM: {
744eef4f27bSRobert Mustacchi 		uint32_t *txflags = cap_data;
745eef4f27bSRobert Mustacchi 
746eef4f27bSRobert Mustacchi 		*txflags = 0;
747eef4f27bSRobert Mustacchi 
748eef4f27bSRobert Mustacchi 		if (umdevice->dev_var.enabled_oflds &
749eef4f27bSRobert Mustacchi 		    (LM_OFFLOAD_TX_IP_CKSUM | LM_OFFLOAD_RX_IP_CKSUM)) {
750eef4f27bSRobert Mustacchi 			*txflags |= HCKSUM_IPHDRCKSUM;
751eef4f27bSRobert Mustacchi 		}
752eef4f27bSRobert Mustacchi 
753eef4f27bSRobert Mustacchi 		if (umdevice->dev_var.enabled_oflds &
754eef4f27bSRobert Mustacchi 		    (LM_OFFLOAD_TX_TCP_CKSUM | LM_OFFLOAD_TX_UDP_CKSUM |
755eef4f27bSRobert Mustacchi 		    LM_OFFLOAD_RX_TCP_CKSUM | LM_OFFLOAD_RX_UDP_CKSUM)) {
756eef4f27bSRobert Mustacchi 			*txflags |= HCKSUM_INET_FULL_V4;
757eef4f27bSRobert Mustacchi 		}
758eef4f27bSRobert Mustacchi 		break;
759eef4f27bSRobert Mustacchi 	}
760eef4f27bSRobert Mustacchi 	default:
761eef4f27bSRobert Mustacchi 		return (B_FALSE);
762eef4f27bSRobert Mustacchi 	}
763eef4f27bSRobert Mustacchi 
764eef4f27bSRobert Mustacchi 	return (B_TRUE);
765eef4f27bSRobert Mustacchi }
766eef4f27bSRobert Mustacchi 
767eef4f27bSRobert Mustacchi static int
bnx_refresh_rx_tx_pkts(um_device_t * umdevice)768eef4f27bSRobert Mustacchi bnx_refresh_rx_tx_pkts(um_device_t *umdevice)
769eef4f27bSRobert Mustacchi {
770eef4f27bSRobert Mustacchi 	if (umdevice->os_param.active_resc_flag & DRV_RESOURCE_HDWR_REGISTER) {
771eef4f27bSRobert Mustacchi 		bnx_hdwr_fini(umdevice);
772eef4f27bSRobert Mustacchi 		/*
773eef4f27bSRobert Mustacchi 		 * Initialize the adapter resource.  Mainly allocating memory
774eef4f27bSRobert Mustacchi 		 * needed by the driver, such as packet descriptors, shared
775eef4f27bSRobert Mustacchi 		 * memory, etc.
776eef4f27bSRobert Mustacchi 		 */
777eef4f27bSRobert Mustacchi 		if (lm_init_resc(&(umdevice->lm_dev)) != LM_STATUS_SUCCESS) {
778eef4f27bSRobert Mustacchi 			return (EIO);
779eef4f27bSRobert Mustacchi 		}
780eef4f27bSRobert Mustacchi 
781eef4f27bSRobert Mustacchi 		if (bnx_txpkts_init(umdevice)) {
782eef4f27bSRobert Mustacchi 			return (EIO);
783eef4f27bSRobert Mustacchi 		}
784eef4f27bSRobert Mustacchi 
785eef4f27bSRobert Mustacchi 		if (bnx_rxpkts_init(umdevice)) {
786eef4f27bSRobert Mustacchi 			return (EIO);
787eef4f27bSRobert Mustacchi 		}
788eef4f27bSRobert Mustacchi 	}
789eef4f27bSRobert Mustacchi 	return (0);
790eef4f27bSRobert Mustacchi }
791eef4f27bSRobert Mustacchi 
792eef4f27bSRobert Mustacchi static int
bnx_set_priv_prop(um_device_t * umdevice,const char * pr_name,uint_t pr_valsize,const void * pr_val)793eef4f27bSRobert Mustacchi bnx_set_priv_prop(um_device_t *umdevice, const char *pr_name,
794eef4f27bSRobert Mustacchi     uint_t pr_valsize, const void *pr_val)
795eef4f27bSRobert Mustacchi {
796eef4f27bSRobert Mustacchi 	boolean_t refresh = B_FALSE;
797eef4f27bSRobert Mustacchi 	long result;
798eef4f27bSRobert Mustacchi 	int err = 0;
799eef4f27bSRobert Mustacchi 
800eef4f27bSRobert Mustacchi 	if (strcmp(pr_name, "_adv_2500fdx_cap") == 0) {
801eef4f27bSRobert Mustacchi 		if (lm_get_medium(&umdevice->lm_dev) != LM_MEDIUM_TYPE_FIBER) {
802eef4f27bSRobert Mustacchi 			return (ENOTSUP);
803eef4f27bSRobert Mustacchi 		}
804eef4f27bSRobert Mustacchi 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) {
805eef4f27bSRobert Mustacchi 			return (EINVAL);
806eef4f27bSRobert Mustacchi 		}
807eef4f27bSRobert Mustacchi 		if (result != 1 && result != 0) {
808eef4f27bSRobert Mustacchi 			return (EINVAL);
809eef4f27bSRobert Mustacchi 		}
810eef4f27bSRobert Mustacchi 		if (umdevice->hwinit.lnkcfg.param_2500fdx != (uint32_t)result) {
811eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_2500fdx =
812eef4f27bSRobert Mustacchi 			    (uint32_t)result;
813eef4f27bSRobert Mustacchi 			umdevice->curcfg.lnkcfg.param_2500fdx =
814eef4f27bSRobert Mustacchi 			    (uint32_t)result;
815eef4f27bSRobert Mustacchi 			bnx_update_phy(umdevice);
816eef4f27bSRobert Mustacchi 		}
817eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_checksum") == 0) {
818eef4f27bSRobert Mustacchi 		if (umdevice->dev_start == B_TRUE) {
819eef4f27bSRobert Mustacchi 			return (EBUSY);
820eef4f27bSRobert Mustacchi 		}
821eef4f27bSRobert Mustacchi 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) {
822eef4f27bSRobert Mustacchi 			return (EINVAL);
823eef4f27bSRobert Mustacchi 		}
824eef4f27bSRobert Mustacchi 		switch (result) {
825eef4f27bSRobert Mustacchi 			case USER_OPTION_CKSUM_TX_ONLY:
826eef4f27bSRobert Mustacchi 				umdevice->dev_var.enabled_oflds =
827eef4f27bSRobert Mustacchi 				    LM_OFFLOAD_TX_IP_CKSUM |
828eef4f27bSRobert Mustacchi 				    LM_OFFLOAD_TX_TCP_CKSUM |
829eef4f27bSRobert Mustacchi 				    LM_OFFLOAD_TX_UDP_CKSUM;
830eef4f27bSRobert Mustacchi 				break;
831eef4f27bSRobert Mustacchi 
832eef4f27bSRobert Mustacchi 			case USER_OPTION_CKSUM_RX_ONLY:
833eef4f27bSRobert Mustacchi 				umdevice->dev_var.enabled_oflds =
834eef4f27bSRobert Mustacchi 				    LM_OFFLOAD_RX_IP_CKSUM |
835eef4f27bSRobert Mustacchi 				    LM_OFFLOAD_RX_TCP_CKSUM |
836eef4f27bSRobert Mustacchi 				    LM_OFFLOAD_RX_UDP_CKSUM;
837eef4f27bSRobert Mustacchi 				break;
838eef4f27bSRobert Mustacchi 
839eef4f27bSRobert Mustacchi 			case USER_OPTION_CKSUM_TX_RX:
840eef4f27bSRobert Mustacchi 				umdevice->dev_var.enabled_oflds =
841eef4f27bSRobert Mustacchi 				    LM_OFFLOAD_TX_IP_CKSUM |
842eef4f27bSRobert Mustacchi 				    LM_OFFLOAD_RX_IP_CKSUM |
843eef4f27bSRobert Mustacchi 				    LM_OFFLOAD_TX_TCP_CKSUM |
844eef4f27bSRobert Mustacchi 				    LM_OFFLOAD_RX_TCP_CKSUM |
845eef4f27bSRobert Mustacchi 				    LM_OFFLOAD_TX_UDP_CKSUM |
846eef4f27bSRobert Mustacchi 				    LM_OFFLOAD_RX_UDP_CKSUM;
847eef4f27bSRobert Mustacchi 				break;
848eef4f27bSRobert Mustacchi 
849eef4f27bSRobert Mustacchi 			case USER_OPTION_CKSUM_NONE:
850eef4f27bSRobert Mustacchi 				umdevice->dev_var.enabled_oflds =
851eef4f27bSRobert Mustacchi 				    LM_OFFLOAD_NONE;
852eef4f27bSRobert Mustacchi 				break;
853eef4f27bSRobert Mustacchi 
854eef4f27bSRobert Mustacchi 			default:
855eef4f27bSRobert Mustacchi 				return (EINVAL);
856eef4f27bSRobert Mustacchi 		}
857eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_descriptor_count") == 0) {
858eef4f27bSRobert Mustacchi 		if (umdevice->dev_start == B_TRUE) {
859eef4f27bSRobert Mustacchi 			return (EBUSY);
860eef4f27bSRobert Mustacchi 		}
861eef4f27bSRobert Mustacchi 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) {
862eef4f27bSRobert Mustacchi 			return (EINVAL);
863eef4f27bSRobert Mustacchi 		}
864eef4f27bSRobert Mustacchi 		if (result < USER_OPTION_TX_DESC_CNT_MIN ||
865eef4f27bSRobert Mustacchi 		    result > USER_OPTION_TX_DESC_CNT_MAX) {
866eef4f27bSRobert Mustacchi 			return (EINVAL);
867eef4f27bSRobert Mustacchi 		}
868eef4f27bSRobert Mustacchi 		_TX_QINFO(umdevice, 0).desc_cnt = result;
869eef4f27bSRobert Mustacchi 		umdevice->lm_dev.params.l2_tx_bd_page_cnt[0] =
870eef4f27bSRobert Mustacchi 		    result / MAX_BD_PER_PAGE;
871eef4f27bSRobert Mustacchi 		if (result % MAX_BD_PER_PAGE) {
872eef4f27bSRobert Mustacchi 			umdevice->lm_dev.params.l2_tx_bd_page_cnt[0]++;
873eef4f27bSRobert Mustacchi 		}
874eef4f27bSRobert Mustacchi 		if (umdevice->lm_dev.params.l2_tx_bd_page_cnt[0] > 127) {
875eef4f27bSRobert Mustacchi 			umdevice->lm_dev.params.l2_tx_bd_page_cnt[0] = 127;
876eef4f27bSRobert Mustacchi 		}
877eef4f27bSRobert Mustacchi 		refresh = B_TRUE;
878eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_descriptor_count") == 0) {
879eef4f27bSRobert Mustacchi 		if (umdevice->dev_start == B_TRUE) {
880eef4f27bSRobert Mustacchi 			return (EBUSY);
881eef4f27bSRobert Mustacchi 		}
882eef4f27bSRobert Mustacchi 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) {
883eef4f27bSRobert Mustacchi 			return (EINVAL);
884eef4f27bSRobert Mustacchi 		}
885eef4f27bSRobert Mustacchi 		if (result < USER_OPTION_RX_DESC_CNT_MIN ||
886eef4f27bSRobert Mustacchi 		    result > USER_OPTION_RX_DESC_CNT_MAX) {
887eef4f27bSRobert Mustacchi 			return (EINVAL);
888eef4f27bSRobert Mustacchi 		}
889eef4f27bSRobert Mustacchi 		umdevice->lm_dev.params.l2_rx_desc_cnt[0] = result;
890eef4f27bSRobert Mustacchi 		result = (result * BNX_RECV_MAX_FRAGS) / MAX_BD_PER_PAGE;
891eef4f27bSRobert Mustacchi 		umdevice->lm_dev.params.l2_rx_bd_page_cnt[0] = result;
892eef4f27bSRobert Mustacchi 		if (result % MAX_BD_PER_PAGE) {
893eef4f27bSRobert Mustacchi 			umdevice->lm_dev.params.l2_rx_bd_page_cnt[0]++;
894eef4f27bSRobert Mustacchi 		}
895eef4f27bSRobert Mustacchi 		refresh = B_TRUE;
896eef4f27bSRobert Mustacchi 	}
897eef4f27bSRobert Mustacchi #if 0
898eef4f27bSRobert Mustacchi 	/* Initialized by init_hc() */
899eef4f27bSRobert Mustacchi 	else if (strcmp(pr_name, "_tx_coalesce_ticks") == 0) {
900eef4f27bSRobert Mustacchi 		if (umdevice->dev_start == B_TRUE) {
901eef4f27bSRobert Mustacchi 			return (EBUSY);
902eef4f27bSRobert Mustacchi 		}
903eef4f27bSRobert Mustacchi 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) {
904eef4f27bSRobert Mustacchi 			return (EINVAL);
905eef4f27bSRobert Mustacchi 		}
906eef4f27bSRobert Mustacchi 		if (result < USER_OPTION_TICKS_MIN ||
907eef4f27bSRobert Mustacchi 		    result > USER_OPTION_TICKS_MAX) {
908eef4f27bSRobert Mustacchi 			return (EINVAL);
909eef4f27bSRobert Mustacchi 		}
910eef4f27bSRobert Mustacchi 		umdevice->lm_dev.params.tx_ticks = result;
911eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_coalesce_ticks_int") == 0) {
912eef4f27bSRobert Mustacchi 		if (umdevice->dev_start == B_TRUE) {
913eef4f27bSRobert Mustacchi 			return (EBUSY);
914eef4f27bSRobert Mustacchi 		}
915eef4f27bSRobert Mustacchi 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) {
916eef4f27bSRobert Mustacchi 			return (EINVAL);
917eef4f27bSRobert Mustacchi 		}
918eef4f27bSRobert Mustacchi 		if (result < USER_OPTION_TICKS_INT_MIN ||
919eef4f27bSRobert Mustacchi 		    result > USER_OPTION_TICKS_INT_MAX) {
920eef4f27bSRobert Mustacchi 			return (EINVAL);
921eef4f27bSRobert Mustacchi 		}
922eef4f27bSRobert Mustacchi 		umdevice->lm_dev.params.tx_ticks_int = result;
923eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_coalesce_ticks") == 0) {
924eef4f27bSRobert Mustacchi 		if (umdevice->dev_start == B_TRUE) {
925eef4f27bSRobert Mustacchi 			return (EBUSY);
926eef4f27bSRobert Mustacchi 		}
927eef4f27bSRobert Mustacchi 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) {
928eef4f27bSRobert Mustacchi 			return (EINVAL);
929eef4f27bSRobert Mustacchi 		}
930eef4f27bSRobert Mustacchi 		if (result < USER_OPTION_TICKS_MIN ||
931eef4f27bSRobert Mustacchi 		    result > USER_OPTION_TICKS_MAX) {
932eef4f27bSRobert Mustacchi 			return (EINVAL);
933eef4f27bSRobert Mustacchi 		}
934eef4f27bSRobert Mustacchi 		umdevice->lm_dev.params.rx_ticks = result;
935eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_coalesce_ticks_int") == 0) {
936eef4f27bSRobert Mustacchi 		if (umdevice->dev_start == B_TRUE) {
937eef4f27bSRobert Mustacchi 			return (EBUSY);
938eef4f27bSRobert Mustacchi 		}
939eef4f27bSRobert Mustacchi 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) {
940eef4f27bSRobert Mustacchi 			return (EINVAL);
941eef4f27bSRobert Mustacchi 		}
942eef4f27bSRobert Mustacchi 		if (result < USER_OPTION_TICKS_INT_MIN ||
943eef4f27bSRobert Mustacchi 		    result > USER_OPTION_TICKS_INT_MAX) {
944eef4f27bSRobert Mustacchi 			return (EINVAL);
945eef4f27bSRobert Mustacchi 		}
946eef4f27bSRobert Mustacchi 		umdevice->lm_dev.params.rx_ticks_int = result;
947eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_coalesce_frames") == 0) {
948eef4f27bSRobert Mustacchi 		if (umdevice->dev_start == B_TRUE) {
949eef4f27bSRobert Mustacchi 			return (EBUSY);
950eef4f27bSRobert Mustacchi 		}
951eef4f27bSRobert Mustacchi 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) {
952eef4f27bSRobert Mustacchi 			return (EINVAL);
953eef4f27bSRobert Mustacchi 		}
954eef4f27bSRobert Mustacchi 		if (result < USER_OPTION_FRAMES_MIN ||
955eef4f27bSRobert Mustacchi 		    result > USER_OPTION_FRAMES_MAX) {
956eef4f27bSRobert Mustacchi 			return (EINVAL);
957eef4f27bSRobert Mustacchi 		}
958eef4f27bSRobert Mustacchi 		umdevice->lm_dev.params.tx_quick_cons_trip = result;
959eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_coalesce_frames_int") == 0) {
960eef4f27bSRobert Mustacchi 		if (umdevice->dev_start == B_TRUE) {
961eef4f27bSRobert Mustacchi 			return (EBUSY);
962eef4f27bSRobert Mustacchi 		}
963eef4f27bSRobert Mustacchi 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) {
964eef4f27bSRobert Mustacchi 			return (EINVAL);
965eef4f27bSRobert Mustacchi 		}
966eef4f27bSRobert Mustacchi 		if (result < USER_OPTION_FRAMES_MIN ||
967eef4f27bSRobert Mustacchi 		    result > USER_OPTION_FRAMES_MAX) {
968eef4f27bSRobert Mustacchi 			return (EINVAL);
969eef4f27bSRobert Mustacchi 		}
970eef4f27bSRobert Mustacchi 		umdevice->lm_dev.params.tx_quick_cons_trip_int = result;
971eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_coalesce_frames") == 0) {
972eef4f27bSRobert Mustacchi 		if (umdevice->dev_start == B_TRUE) {
973eef4f27bSRobert Mustacchi 			return (EBUSY);
974eef4f27bSRobert Mustacchi 		}
975eef4f27bSRobert Mustacchi 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) {
976eef4f27bSRobert Mustacchi 			return (EINVAL);
977eef4f27bSRobert Mustacchi 		}
978eef4f27bSRobert Mustacchi 		if (result < USER_OPTION_FRAMES_MIN ||
979eef4f27bSRobert Mustacchi 		    result > USER_OPTION_FRAMES_MAX) {
980eef4f27bSRobert Mustacchi 			return (EINVAL);
981eef4f27bSRobert Mustacchi 		}
982eef4f27bSRobert Mustacchi 		umdevice->lm_dev.params.rx_quick_cons_trip = result;
983eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_coalesce_frames_int") == 0) {
984eef4f27bSRobert Mustacchi 		if (umdevice->dev_start == B_TRUE) {
985eef4f27bSRobert Mustacchi 			return (EBUSY);
986eef4f27bSRobert Mustacchi 		}
987eef4f27bSRobert Mustacchi 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) {
988eef4f27bSRobert Mustacchi 			return (EINVAL);
989eef4f27bSRobert Mustacchi 		}
990eef4f27bSRobert Mustacchi 		if (result < USER_OPTION_FRAMES_MIN ||
991eef4f27bSRobert Mustacchi 		    result > USER_OPTION_FRAMES_MAX) {
992eef4f27bSRobert Mustacchi 			return (EINVAL);
993eef4f27bSRobert Mustacchi 		}
994eef4f27bSRobert Mustacchi 		umdevice->lm_dev.params.rx_quick_cons_trip_int = result;
995eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_statticks") == 0) {
996eef4f27bSRobert Mustacchi 		if (umdevice->dev_start == B_TRUE) {
997eef4f27bSRobert Mustacchi 			return (EBUSY);
998eef4f27bSRobert Mustacchi 		}
999eef4f27bSRobert Mustacchi 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result)) {
1000eef4f27bSRobert Mustacchi 			return (EINVAL);
1001eef4f27bSRobert Mustacchi 		}
1002eef4f27bSRobert Mustacchi 		if (result < USER_OPTION_STATSTICKS_MIN ||
1003eef4f27bSRobert Mustacchi 		    result > USER_OPTION_STATSTICKS_MAX) {
1004eef4f27bSRobert Mustacchi 			return (EINVAL);
1005eef4f27bSRobert Mustacchi 		}
1006eef4f27bSRobert Mustacchi 		umdevice->lm_dev.params.stats_ticks = result;
1007eef4f27bSRobert Mustacchi 	}
1008eef4f27bSRobert Mustacchi #endif
1009eef4f27bSRobert Mustacchi 	else if (strcmp(pr_name, "_disable_msix") == 0) {
1010eef4f27bSRobert Mustacchi 		err = ENOTSUP;
1011eef4f27bSRobert Mustacchi 	} else {
1012eef4f27bSRobert Mustacchi 		err = ENOTSUP;
1013eef4f27bSRobert Mustacchi 	}
1014eef4f27bSRobert Mustacchi 
1015eef4f27bSRobert Mustacchi 	if (!err && refresh) {
1016eef4f27bSRobert Mustacchi 		err = bnx_refresh_rx_tx_pkts(umdevice);
1017eef4f27bSRobert Mustacchi 	}
1018eef4f27bSRobert Mustacchi 	return (err);
1019eef4f27bSRobert Mustacchi }
1020eef4f27bSRobert Mustacchi 
1021eef4f27bSRobert Mustacchi 
1022eef4f27bSRobert Mustacchi static int
bnx_m_setprop(void * arg,const char * pr_name,mac_prop_id_t pr_num,uint_t pr_valsize,const void * pr_val)1023eef4f27bSRobert Mustacchi bnx_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
1024eef4f27bSRobert Mustacchi     uint_t pr_valsize, const void *pr_val)
1025eef4f27bSRobert Mustacchi {
1026eef4f27bSRobert Mustacchi 	um_device_t *umdevice = arg;
1027eef4f27bSRobert Mustacchi 	boolean_t reprogram = B_FALSE;
1028eef4f27bSRobert Mustacchi 	boolean_t rxpause;
1029eef4f27bSRobert Mustacchi 	boolean_t txpause;
1030eef4f27bSRobert Mustacchi 	uint32_t mtu;
1031eef4f27bSRobert Mustacchi 	link_flowctrl_t fl;
1032eef4f27bSRobert Mustacchi 	int err = 0;
1033eef4f27bSRobert Mustacchi 
1034eef4f27bSRobert Mustacchi 	mutex_enter(&umdevice->os_param.gld_mutex);
1035eef4f27bSRobert Mustacchi 
1036eef4f27bSRobert Mustacchi 	if (lm_get_medium(&umdevice->lm_dev) == LM_MEDIUM_TYPE_FIBER) {
1037eef4f27bSRobert Mustacchi 		if (pr_num == MAC_PROP_EN_100FDX_CAP ||
1038eef4f27bSRobert Mustacchi 		    pr_num == MAC_PROP_EN_100HDX_CAP ||
1039eef4f27bSRobert Mustacchi 		    pr_num == MAC_PROP_EN_10FDX_CAP ||
1040eef4f27bSRobert Mustacchi 		    pr_num == MAC_PROP_EN_10HDX_CAP) {
1041eef4f27bSRobert Mustacchi 			mutex_exit(&umdevice->os_param.gld_mutex);
1042eef4f27bSRobert Mustacchi 			return (ENOTSUP);
1043eef4f27bSRobert Mustacchi 		}
1044eef4f27bSRobert Mustacchi 	}
1045eef4f27bSRobert Mustacchi 
1046eef4f27bSRobert Mustacchi 	switch (pr_num) {
1047eef4f27bSRobert Mustacchi 		/* read-only properties */
1048eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_1000FDX_CAP:
1049eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_1000HDX_CAP:
1050eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_100FDX_CAP:
1051eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_100HDX_CAP:
1052eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_10FDX_CAP:
1053eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_10HDX_CAP:
1054eef4f27bSRobert Mustacchi 		case MAC_PROP_STATUS:
1055eef4f27bSRobert Mustacchi 		case MAC_PROP_SPEED:
1056eef4f27bSRobert Mustacchi 		case MAC_PROP_DUPLEX:
1057*fe803bd5SRobert Mustacchi 		case MAC_PROP_MEDIA:
1058eef4f27bSRobert Mustacchi 		default:
1059eef4f27bSRobert Mustacchi 
1060eef4f27bSRobert Mustacchi 			err = ENOTSUP;
1061eef4f27bSRobert Mustacchi 			break;
1062eef4f27bSRobert Mustacchi 
1063eef4f27bSRobert Mustacchi 
1064eef4f27bSRobert Mustacchi /* BEGIN CSTYLED */
1065eef4f27bSRobert Mustacchi #define	BNX_SETPROP_CASE(cap, param)							\
1066eef4f27bSRobert Mustacchi 		case cap:								\
1067eef4f27bSRobert Mustacchi 			if (umdevice->hwinit.lnkcfg.param != *(uint8_t *)pr_val) {	\
1068eef4f27bSRobert Mustacchi 				umdevice->hwinit.lnkcfg.param = *(uint8_t *)pr_val;	\
1069eef4f27bSRobert Mustacchi 				umdevice->curcfg.lnkcfg.param = *(uint8_t *)pr_val;	\
1070eef4f27bSRobert Mustacchi 				reprogram = B_TRUE;					\
1071eef4f27bSRobert Mustacchi 			}								\
1072eef4f27bSRobert Mustacchi 			break
1073eef4f27bSRobert Mustacchi /* END CSTYLED */
1074eef4f27bSRobert Mustacchi 
1075eef4f27bSRobert Mustacchi 
1076eef4f27bSRobert Mustacchi 		BNX_SETPROP_CASE(MAC_PROP_EN_1000FDX_CAP, param_1000fdx);
1077eef4f27bSRobert Mustacchi 		BNX_SETPROP_CASE(MAC_PROP_EN_1000HDX_CAP, param_1000hdx);
1078eef4f27bSRobert Mustacchi 		BNX_SETPROP_CASE(MAC_PROP_EN_100FDX_CAP, param_100fdx);
1079eef4f27bSRobert Mustacchi 		BNX_SETPROP_CASE(MAC_PROP_EN_100HDX_CAP, param_100hdx);
1080eef4f27bSRobert Mustacchi 		BNX_SETPROP_CASE(MAC_PROP_EN_10FDX_CAP, param_10fdx);
1081eef4f27bSRobert Mustacchi 		BNX_SETPROP_CASE(MAC_PROP_EN_10HDX_CAP, param_10hdx);
1082eef4f27bSRobert Mustacchi 		BNX_SETPROP_CASE(MAC_PROP_AUTONEG, link_autoneg);
1083eef4f27bSRobert Mustacchi 
1084eef4f27bSRobert Mustacchi 		case MAC_PROP_FLOWCTRL:
1085eef4f27bSRobert Mustacchi 			bcopy(pr_val, &fl, sizeof (fl));
1086eef4f27bSRobert Mustacchi 			switch (fl) {
1087eef4f27bSRobert Mustacchi 				case LINK_FLOWCTRL_NONE:
1088eef4f27bSRobert Mustacchi 
1089eef4f27bSRobert Mustacchi 					rxpause = B_FALSE;
1090eef4f27bSRobert Mustacchi 					txpause = B_FALSE;
1091eef4f27bSRobert Mustacchi 					break;
1092eef4f27bSRobert Mustacchi 
1093eef4f27bSRobert Mustacchi 				case LINK_FLOWCTRL_RX:
1094eef4f27bSRobert Mustacchi 
1095eef4f27bSRobert Mustacchi 					rxpause = B_TRUE;
1096eef4f27bSRobert Mustacchi 					txpause = B_FALSE;
1097eef4f27bSRobert Mustacchi 					break;
1098eef4f27bSRobert Mustacchi 
1099eef4f27bSRobert Mustacchi 				case LINK_FLOWCTRL_TX:
1100eef4f27bSRobert Mustacchi 
1101eef4f27bSRobert Mustacchi 					rxpause = B_FALSE;
1102eef4f27bSRobert Mustacchi 					txpause = B_TRUE;
1103eef4f27bSRobert Mustacchi 					break;
1104eef4f27bSRobert Mustacchi 
1105eef4f27bSRobert Mustacchi 				case LINK_FLOWCTRL_BI:
1106eef4f27bSRobert Mustacchi 
1107eef4f27bSRobert Mustacchi 					rxpause = B_TRUE;
1108eef4f27bSRobert Mustacchi 					txpause = B_TRUE;
1109eef4f27bSRobert Mustacchi 					break;
1110eef4f27bSRobert Mustacchi 
1111eef4f27bSRobert Mustacchi 				default:
1112eef4f27bSRobert Mustacchi 
1113eef4f27bSRobert Mustacchi 					err = ENOTSUP;
1114eef4f27bSRobert Mustacchi 					break;
1115eef4f27bSRobert Mustacchi 			}
1116eef4f27bSRobert Mustacchi 
1117eef4f27bSRobert Mustacchi 			if (err == 0) {
1118eef4f27bSRobert Mustacchi 				if (umdevice->hwinit.lnkcfg.param_tx_pause !=
1119eef4f27bSRobert Mustacchi 				    txpause ||
1120eef4f27bSRobert Mustacchi 				    umdevice->hwinit.lnkcfg.param_rx_pause !=
1121eef4f27bSRobert Mustacchi 				    rxpause) {
1122eef4f27bSRobert Mustacchi 					umdevice->hwinit.lnkcfg.param_tx_pause =
1123eef4f27bSRobert Mustacchi 					    txpause;
1124eef4f27bSRobert Mustacchi 					umdevice->hwinit.lnkcfg.param_rx_pause =
1125eef4f27bSRobert Mustacchi 					    rxpause;
1126eef4f27bSRobert Mustacchi 					umdevice->curcfg.lnkcfg.param_tx_pause =
1127eef4f27bSRobert Mustacchi 					    txpause;
1128eef4f27bSRobert Mustacchi 					umdevice->curcfg.lnkcfg.param_rx_pause =
1129eef4f27bSRobert Mustacchi 					    rxpause;
1130eef4f27bSRobert Mustacchi 					reprogram = B_TRUE;
1131eef4f27bSRobert Mustacchi 				}
1132eef4f27bSRobert Mustacchi 			}
1133eef4f27bSRobert Mustacchi 
1134eef4f27bSRobert Mustacchi 			break;
1135eef4f27bSRobert Mustacchi 
1136eef4f27bSRobert Mustacchi 		case MAC_PROP_MTU:
1137eef4f27bSRobert Mustacchi 			if (umdevice->dev_start == B_TRUE) {
1138eef4f27bSRobert Mustacchi 				err = EBUSY;
1139eef4f27bSRobert Mustacchi 				break;
1140eef4f27bSRobert Mustacchi 			}
1141eef4f27bSRobert Mustacchi 
1142eef4f27bSRobert Mustacchi 			bcopy(pr_val, &mtu, sizeof (mtu));
1143eef4f27bSRobert Mustacchi 
1144eef4f27bSRobert Mustacchi 			if (mtu < USER_OPTION_MTU_MIN ||
1145eef4f27bSRobert Mustacchi 			    mtu > USER_OPTION_MTU_MAX) {
1146eef4f27bSRobert Mustacchi 				err = EINVAL;
1147eef4f27bSRobert Mustacchi 				break;
1148eef4f27bSRobert Mustacchi 			}
1149eef4f27bSRobert Mustacchi 
1150eef4f27bSRobert Mustacchi 			if (umdevice->dev_var.mtu == mtu) {
1151eef4f27bSRobert Mustacchi 				break;
1152eef4f27bSRobert Mustacchi 			}
1153eef4f27bSRobert Mustacchi 
1154eef4f27bSRobert Mustacchi 			umdevice->dev_var.mtu = mtu;
1155eef4f27bSRobert Mustacchi 			umdevice->lm_dev.params.mtu = umdevice->dev_var.mtu
1156eef4f27bSRobert Mustacchi 			    + sizeof (struct ether_header) + VLAN_TAGSZ;
1157eef4f27bSRobert Mustacchi 
1158eef4f27bSRobert Mustacchi 			if (bnx_refresh_rx_tx_pkts(umdevice) != 0) {
1159eef4f27bSRobert Mustacchi 				err = EIO;
1160eef4f27bSRobert Mustacchi 			} else {
1161eef4f27bSRobert Mustacchi 				reprogram = B_TRUE;
1162eef4f27bSRobert Mustacchi 			}
1163eef4f27bSRobert Mustacchi 			break;
1164eef4f27bSRobert Mustacchi 
1165eef4f27bSRobert Mustacchi 		case MAC_PROP_PRIVATE:
1166eef4f27bSRobert Mustacchi 			err = bnx_set_priv_prop(umdevice, pr_name, pr_valsize,
1167eef4f27bSRobert Mustacchi 			    pr_val);
1168eef4f27bSRobert Mustacchi 			reprogram = B_TRUE;
1169eef4f27bSRobert Mustacchi 			break;
1170eef4f27bSRobert Mustacchi 	}
1171eef4f27bSRobert Mustacchi 
1172eef4f27bSRobert Mustacchi 	if (!err && reprogram) {
1173eef4f27bSRobert Mustacchi 		bnx_update_phy(umdevice);
1174eef4f27bSRobert Mustacchi 	}
1175eef4f27bSRobert Mustacchi 
1176eef4f27bSRobert Mustacchi 	mutex_exit(&umdevice->os_param.gld_mutex);
1177eef4f27bSRobert Mustacchi 
1178eef4f27bSRobert Mustacchi 	return (err);
1179eef4f27bSRobert Mustacchi }
1180eef4f27bSRobert Mustacchi 
1181eef4f27bSRobert Mustacchi static int
bnx_get_priv_prop(um_device_t * umdevice,const char * pr_name,uint_t pr_valsize,void * pr_val)1182eef4f27bSRobert Mustacchi bnx_get_priv_prop(um_device_t *umdevice, const char *pr_name,
1183eef4f27bSRobert Mustacchi     uint_t pr_valsize, void *pr_val)
1184eef4f27bSRobert Mustacchi {
1185eef4f27bSRobert Mustacchi 	int value;
1186eef4f27bSRobert Mustacchi 
1187eef4f27bSRobert Mustacchi 	if (strcmp(pr_name, "_adv_2500fdx_cap") == 0) {
1188eef4f27bSRobert Mustacchi 		if (lm_get_medium(&umdevice->lm_dev) !=
1189eef4f27bSRobert Mustacchi 		    LM_MEDIUM_TYPE_FIBER) {
1190eef4f27bSRobert Mustacchi 			return (ENOTSUP);
1191eef4f27bSRobert Mustacchi 		}
1192eef4f27bSRobert Mustacchi 		value = umdevice->curcfg.lnkcfg.param_2500fdx;
1193eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_checksum") == 0) {
1194eef4f27bSRobert Mustacchi 		value = umdevice->dev_var.enabled_oflds;
1195eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_descriptor_count") == 0) {
1196eef4f27bSRobert Mustacchi 		value = _TX_QINFO(umdevice, 0).desc_cnt;
1197eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_descriptor_count") == 0) {
1198eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.l2_rx_desc_cnt[0];
1199eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_coalesce_ticks") == 0) {
1200eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.tx_ticks;
1201eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_coalesce_ticks_int") == 0) {
1202eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.tx_ticks_int;
1203eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_coalesce_ticks") == 0) {
1204eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.rx_ticks;
1205eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_coalesce_ticks_int") == 0) {
1206eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.rx_ticks_int;
1207eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_coalesce_frames") == 0) {
1208eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.tx_quick_cons_trip;
1209eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_coalesce_frames_int") == 0) {
1210eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.tx_quick_cons_trip_int;
1211eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_coalesce_frames") == 0) {
1212eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.rx_quick_cons_trip;
1213eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_coalesce_frames_int") == 0) {
1214eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.rx_quick_cons_trip_int;
1215eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_statticks") == 0) {
1216eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.stats_ticks;
1217eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_disable_msix") == 0) {
1218eef4f27bSRobert Mustacchi 		value = umdevice->dev_var.disableMsix;
1219eef4f27bSRobert Mustacchi 	} else {
1220eef4f27bSRobert Mustacchi 		return (ENOTSUP);
1221eef4f27bSRobert Mustacchi 	}
1222eef4f27bSRobert Mustacchi 
1223eef4f27bSRobert Mustacchi 	(void) snprintf(pr_val, pr_valsize, "%d", value);
1224eef4f27bSRobert Mustacchi 	return (0);
1225eef4f27bSRobert Mustacchi 
1226eef4f27bSRobert Mustacchi }
1227eef4f27bSRobert Mustacchi 
1228eef4f27bSRobert Mustacchi static int
bnx_m_getprop(void * arg,const char * pr_name,mac_prop_id_t pr_num,uint_t pr_valsize,void * pr_val)1229eef4f27bSRobert Mustacchi bnx_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
1230eef4f27bSRobert Mustacchi     uint_t pr_valsize, void *pr_val)
1231eef4f27bSRobert Mustacchi {
1232eef4f27bSRobert Mustacchi 	um_device_t *umdevice = arg;
1233eef4f27bSRobert Mustacchi 	link_duplex_t link_duplex;
1234eef4f27bSRobert Mustacchi 	uint64_t link_speed;
1235eef4f27bSRobert Mustacchi 	link_state_t link_state;
1236eef4f27bSRobert Mustacchi 	link_flowctrl_t fl;
1237*fe803bd5SRobert Mustacchi 	mac_ether_media_t media;
1238eef4f27bSRobert Mustacchi 
1239eef4f27bSRobert Mustacchi 	if (lm_get_medium(&umdevice->lm_dev) == LM_MEDIUM_TYPE_FIBER) {
1240eef4f27bSRobert Mustacchi 		if (pr_num == MAC_PROP_EN_100FDX_CAP ||
1241eef4f27bSRobert Mustacchi 		    pr_num == MAC_PROP_EN_100HDX_CAP ||
1242eef4f27bSRobert Mustacchi 		    pr_num == MAC_PROP_EN_10FDX_CAP ||
1243eef4f27bSRobert Mustacchi 		    pr_num == MAC_PROP_EN_10HDX_CAP) {
1244eef4f27bSRobert Mustacchi 			return (ENOTSUP);
1245eef4f27bSRobert Mustacchi 		}
1246eef4f27bSRobert Mustacchi 	}
1247eef4f27bSRobert Mustacchi 
1248eef4f27bSRobert Mustacchi 	switch (pr_num) {
1249eef4f27bSRobert Mustacchi 		case MAC_PROP_DUPLEX:
1250eef4f27bSRobert Mustacchi 			link_duplex = umdevice->nddcfg.link_duplex == B_TRUE ?
1251eef4f27bSRobert Mustacchi 			    LINK_DUPLEX_FULL: LINK_DUPLEX_HALF;
1252eef4f27bSRobert Mustacchi 
1253eef4f27bSRobert Mustacchi 			ASSERT(pr_valsize >= sizeof (link_duplex_t));
1254eef4f27bSRobert Mustacchi 
1255eef4f27bSRobert Mustacchi 			bcopy(&link_duplex, pr_val, sizeof (link_duplex_t));
1256eef4f27bSRobert Mustacchi 			break;
1257eef4f27bSRobert Mustacchi 
1258eef4f27bSRobert Mustacchi 		case MAC_PROP_SPEED:
1259eef4f27bSRobert Mustacchi 			link_speed = umdevice->nddcfg.link_speed * 1000000ull;
1260eef4f27bSRobert Mustacchi 
1261eef4f27bSRobert Mustacchi 			ASSERT(pr_valsize >= sizeof (link_speed));
1262eef4f27bSRobert Mustacchi 
1263eef4f27bSRobert Mustacchi 			bcopy(&link_speed, pr_val, sizeof (link_speed));
1264eef4f27bSRobert Mustacchi 			break;
1265eef4f27bSRobert Mustacchi 
1266eef4f27bSRobert Mustacchi 		case MAC_PROP_STATUS:
1267eef4f27bSRobert Mustacchi 			link_state = umdevice->nddcfg.link_speed ?
1268eef4f27bSRobert Mustacchi 			    LINK_STATE_UP : LINK_STATE_DOWN;
1269eef4f27bSRobert Mustacchi 
1270eef4f27bSRobert Mustacchi 			ASSERT(pr_valsize >= sizeof (link_state_t));
1271eef4f27bSRobert Mustacchi 
1272eef4f27bSRobert Mustacchi 			bcopy(&link_state, pr_val, sizeof (link_state));
1273eef4f27bSRobert Mustacchi 			break;
1274eef4f27bSRobert Mustacchi 
1275*fe803bd5SRobert Mustacchi 		case MAC_PROP_MEDIA:
1276*fe803bd5SRobert Mustacchi 			media = bnx_um_to_media(umdevice);
1277*fe803bd5SRobert Mustacchi 
1278*fe803bd5SRobert Mustacchi 			ASSERT(pr_valsize >= sizeof (mac_ether_media_t));
1279*fe803bd5SRobert Mustacchi 
1280*fe803bd5SRobert Mustacchi 			bcopy(&media, pr_val, sizeof (link_state));
1281*fe803bd5SRobert Mustacchi 			break;
1282*fe803bd5SRobert Mustacchi 
1283eef4f27bSRobert Mustacchi 		case MAC_PROP_AUTONEG:
1284eef4f27bSRobert Mustacchi 			*(uint8_t *)pr_val =
1285eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.link_autoneg;
1286eef4f27bSRobert Mustacchi 			break;
1287eef4f27bSRobert Mustacchi 
1288eef4f27bSRobert Mustacchi 		case MAC_PROP_FLOWCTRL:
1289eef4f27bSRobert Mustacchi 			ASSERT(pr_valsize >= sizeof (fl));
1290eef4f27bSRobert Mustacchi 
1291eef4f27bSRobert Mustacchi 			boolean_t txpause =
1292eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_tx_pause;
1293eef4f27bSRobert Mustacchi 			boolean_t rxpause =
1294eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_rx_pause;
1295eef4f27bSRobert Mustacchi 			if (txpause) {
1296eef4f27bSRobert Mustacchi 				if (rxpause) {
1297eef4f27bSRobert Mustacchi 					fl = LINK_FLOWCTRL_BI;
1298eef4f27bSRobert Mustacchi 				} else {
1299eef4f27bSRobert Mustacchi 					fl = LINK_FLOWCTRL_TX;
1300eef4f27bSRobert Mustacchi 				}
1301eef4f27bSRobert Mustacchi 			} else {
1302eef4f27bSRobert Mustacchi 				if (rxpause) {
1303eef4f27bSRobert Mustacchi 					fl = LINK_FLOWCTRL_RX;
1304eef4f27bSRobert Mustacchi 				} else {
1305eef4f27bSRobert Mustacchi 					fl = LINK_FLOWCTRL_NONE;
1306eef4f27bSRobert Mustacchi 				}
1307eef4f27bSRobert Mustacchi 			}
1308eef4f27bSRobert Mustacchi 			bcopy(&fl, pr_val, sizeof (fl));
1309eef4f27bSRobert Mustacchi 			break;
1310eef4f27bSRobert Mustacchi 
1311eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_1000FDX_CAP:
1312eef4f27bSRobert Mustacchi 			*(uint8_t *)pr_val =
1313eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_1000fdx;
1314eef4f27bSRobert Mustacchi 			break;
1315eef4f27bSRobert Mustacchi 
1316eef4f27bSRobert Mustacchi 		case MAC_PROP_EN_1000FDX_CAP:
1317eef4f27bSRobert Mustacchi 			*(uint8_t *)pr_val =
1318eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_1000fdx;
1319eef4f27bSRobert Mustacchi 			break;
1320eef4f27bSRobert Mustacchi 
1321eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_1000HDX_CAP:
1322eef4f27bSRobert Mustacchi 			*(uint8_t *)pr_val =
1323eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_1000hdx;
1324eef4f27bSRobert Mustacchi 			break;
1325eef4f27bSRobert Mustacchi 
1326eef4f27bSRobert Mustacchi 		case MAC_PROP_EN_1000HDX_CAP:
1327eef4f27bSRobert Mustacchi 			*(uint8_t *)pr_val =
1328eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_1000hdx;
1329eef4f27bSRobert Mustacchi 			break;
1330eef4f27bSRobert Mustacchi 
1331eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_100FDX_CAP:
1332eef4f27bSRobert Mustacchi 			*(uint8_t *)pr_val =
1333eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_100fdx;
1334eef4f27bSRobert Mustacchi 			break;
1335eef4f27bSRobert Mustacchi 
1336eef4f27bSRobert Mustacchi 		case MAC_PROP_EN_100FDX_CAP:
1337eef4f27bSRobert Mustacchi 			*(uint8_t *)pr_val =
1338eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_100fdx;
1339eef4f27bSRobert Mustacchi 			break;
1340eef4f27bSRobert Mustacchi 
1341eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_100HDX_CAP:
1342eef4f27bSRobert Mustacchi 			*(uint8_t *)pr_val =
1343eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_100hdx;
1344eef4f27bSRobert Mustacchi 			break;
1345eef4f27bSRobert Mustacchi 
1346eef4f27bSRobert Mustacchi 		case MAC_PROP_EN_100HDX_CAP:
1347eef4f27bSRobert Mustacchi 			*(uint8_t *)pr_val =
1348eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_100hdx;
1349eef4f27bSRobert Mustacchi 			break;
1350eef4f27bSRobert Mustacchi 
1351eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_10FDX_CAP:
1352eef4f27bSRobert Mustacchi 			*(uint8_t *)pr_val =
1353eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_10fdx;
1354eef4f27bSRobert Mustacchi 			break;
1355eef4f27bSRobert Mustacchi 
1356eef4f27bSRobert Mustacchi 		case MAC_PROP_EN_10FDX_CAP:
1357eef4f27bSRobert Mustacchi 			*(uint8_t *)pr_val =
1358eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_10fdx;
1359eef4f27bSRobert Mustacchi 			break;
1360eef4f27bSRobert Mustacchi 
1361eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_10HDX_CAP:
1362eef4f27bSRobert Mustacchi 			*(uint8_t *)pr_val =
1363eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_10hdx;
1364eef4f27bSRobert Mustacchi 			break;
1365eef4f27bSRobert Mustacchi 
1366eef4f27bSRobert Mustacchi 		case MAC_PROP_EN_10HDX_CAP:
1367eef4f27bSRobert Mustacchi 			*(uint8_t *)pr_val =
1368eef4f27bSRobert Mustacchi 			    umdevice->curcfg.lnkcfg.param_10hdx;
1369eef4f27bSRobert Mustacchi 			break;
1370eef4f27bSRobert Mustacchi 
1371eef4f27bSRobert Mustacchi 		case MAC_PROP_PRIVATE:
1372eef4f27bSRobert Mustacchi 			return (bnx_get_priv_prop(umdevice, pr_name, pr_valsize,
1373eef4f27bSRobert Mustacchi 			    pr_val));
1374eef4f27bSRobert Mustacchi 
1375eef4f27bSRobert Mustacchi 		default:
1376eef4f27bSRobert Mustacchi 
1377eef4f27bSRobert Mustacchi 			return (ENOTSUP);
1378eef4f27bSRobert Mustacchi 
1379eef4f27bSRobert Mustacchi 	}
1380eef4f27bSRobert Mustacchi 
1381eef4f27bSRobert Mustacchi 	return (0);
1382eef4f27bSRobert Mustacchi 
1383eef4f27bSRobert Mustacchi }
1384eef4f27bSRobert Mustacchi 
1385eef4f27bSRobert Mustacchi static void
bnx_priv_propinfo(um_device_t * umdevice,const char * pr_name,mac_prop_info_handle_t prh)1386eef4f27bSRobert Mustacchi bnx_priv_propinfo(um_device_t *umdevice, const char *pr_name,
1387eef4f27bSRobert Mustacchi     mac_prop_info_handle_t prh)
1388eef4f27bSRobert Mustacchi {
1389eef4f27bSRobert Mustacchi 	char valstr[64];
1390eef4f27bSRobert Mustacchi 	int value;
1391eef4f27bSRobert Mustacchi 
1392eef4f27bSRobert Mustacchi 	if (strcmp(pr_name, "_adv_2500fdx_cap") == 0) {
1393eef4f27bSRobert Mustacchi 		if (lm_get_medium(&umdevice->lm_dev) != LM_MEDIUM_TYPE_FIBER) {
1394eef4f27bSRobert Mustacchi 			return;
1395eef4f27bSRobert Mustacchi 		}
1396eef4f27bSRobert Mustacchi 		value = umdevice->curcfg.lnkcfg.param_2500fdx;
1397eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_checksum") == 0) {
1398eef4f27bSRobert Mustacchi 		value = umdevice->dev_var.enabled_oflds;
1399eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_descriptor_count") == 0) {
1400eef4f27bSRobert Mustacchi 		value = _TX_QINFO(umdevice, 0).desc_cnt;
1401eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_descriptor_count") == 0) {
1402eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.l2_rx_desc_cnt[0];
1403eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_coalesce_ticks") == 0) {
1404eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.tx_ticks;
1405eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_coalesce_ticks_int") == 0) {
1406eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.tx_ticks_int;
1407eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_coalesce_ticks") == 0) {
1408eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.rx_ticks;
1409eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_coalesce_ticks_int") == 0) {
1410eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.rx_ticks_int;
1411eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_coalesce_frames") == 0) {
1412eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.tx_quick_cons_trip;
1413eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_tx_coalesce_frames_int") == 0) {
1414eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.tx_quick_cons_trip_int;
1415eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_coalesce_frames") == 0) {
1416eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.rx_quick_cons_trip;
1417eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_rx_coalesce_frames_int") == 0) {
1418eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.rx_quick_cons_trip_int;
1419eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_statticks") == 0) {
1420eef4f27bSRobert Mustacchi 		value = umdevice->lm_dev.params.stats_ticks;
1421eef4f27bSRobert Mustacchi 	} else if (strcmp(pr_name, "_disable_msix") == 0) {
1422eef4f27bSRobert Mustacchi 		value = umdevice->dev_var.disableMsix;
1423eef4f27bSRobert Mustacchi 	} else {
1424eef4f27bSRobert Mustacchi 		return;
1425eef4f27bSRobert Mustacchi 	}
1426eef4f27bSRobert Mustacchi 
1427eef4f27bSRobert Mustacchi 	(void) snprintf(valstr, sizeof (valstr), "%d", value);
1428eef4f27bSRobert Mustacchi 	mac_prop_info_set_default_str(prh, valstr);
1429eef4f27bSRobert Mustacchi 
1430eef4f27bSRobert Mustacchi }
1431eef4f27bSRobert Mustacchi 
1432eef4f27bSRobert Mustacchi static void
bnx_m_propinfo(void * arg,const char * pr_name,mac_prop_id_t pr_num,mac_prop_info_handle_t prh)1433eef4f27bSRobert Mustacchi bnx_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
1434eef4f27bSRobert Mustacchi     mac_prop_info_handle_t prh)
1435eef4f27bSRobert Mustacchi {
1436eef4f27bSRobert Mustacchi 	um_device_t *umdevice = arg;
1437eef4f27bSRobert Mustacchi 
1438eef4f27bSRobert Mustacchi 	if (lm_get_medium(&umdevice->lm_dev) == LM_MEDIUM_TYPE_FIBER) {
1439eef4f27bSRobert Mustacchi 		if (pr_num == MAC_PROP_EN_100FDX_CAP ||
1440eef4f27bSRobert Mustacchi 		    pr_num == MAC_PROP_ADV_100FDX_CAP ||
1441eef4f27bSRobert Mustacchi 		    pr_num == MAC_PROP_EN_100HDX_CAP ||
1442eef4f27bSRobert Mustacchi 		    pr_num == MAC_PROP_ADV_100HDX_CAP ||
1443eef4f27bSRobert Mustacchi 		    pr_num == MAC_PROP_EN_10FDX_CAP ||
1444eef4f27bSRobert Mustacchi 		    pr_num == MAC_PROP_ADV_10FDX_CAP ||
1445eef4f27bSRobert Mustacchi 		    pr_num == MAC_PROP_EN_10HDX_CAP ||
1446eef4f27bSRobert Mustacchi 		    pr_num == MAC_PROP_ADV_10HDX_CAP) {
1447eef4f27bSRobert Mustacchi 			mac_prop_info_set_default_uint8(prh, 0);
1448eef4f27bSRobert Mustacchi 			return;
1449eef4f27bSRobert Mustacchi 		}
1450eef4f27bSRobert Mustacchi 	}
1451eef4f27bSRobert Mustacchi 	switch (pr_num) {
1452eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_1000FDX_CAP:
1453eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_1000HDX_CAP:
1454eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_100FDX_CAP:
1455eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_100HDX_CAP:
1456eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_10FDX_CAP:
1457eef4f27bSRobert Mustacchi 		case MAC_PROP_ADV_10HDX_CAP:
1458eef4f27bSRobert Mustacchi 		case MAC_PROP_STATUS:
1459eef4f27bSRobert Mustacchi 		case MAC_PROP_SPEED:
1460eef4f27bSRobert Mustacchi 		case MAC_PROP_DUPLEX:
1461eef4f27bSRobert Mustacchi 
1462eef4f27bSRobert Mustacchi 			mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1463eef4f27bSRobert Mustacchi 			break;
1464eef4f27bSRobert Mustacchi 
1465eef4f27bSRobert Mustacchi 		case MAC_PROP_EN_1000FDX_CAP:
1466eef4f27bSRobert Mustacchi 
1467eef4f27bSRobert Mustacchi 			mac_prop_info_set_default_uint8(prh, 1);
1468eef4f27bSRobert Mustacchi 			break;
1469eef4f27bSRobert Mustacchi 
1470eef4f27bSRobert Mustacchi 		case MAC_PROP_EN_1000HDX_CAP:
1471eef4f27bSRobert Mustacchi 		case MAC_PROP_EN_100FDX_CAP:
1472eef4f27bSRobert Mustacchi 		case MAC_PROP_EN_100HDX_CAP:
1473eef4f27bSRobert Mustacchi 		case MAC_PROP_EN_10FDX_CAP:
1474eef4f27bSRobert Mustacchi 		case MAC_PROP_EN_10HDX_CAP:
1475eef4f27bSRobert Mustacchi 
1476eef4f27bSRobert Mustacchi 			if (lm_get_medium(&umdevice->lm_dev) ==
1477eef4f27bSRobert Mustacchi 			    LM_MEDIUM_TYPE_FIBER) {
1478eef4f27bSRobert Mustacchi 				mac_prop_info_set_default_uint8(prh, 0);
1479eef4f27bSRobert Mustacchi 			} else {
1480eef4f27bSRobert Mustacchi 				mac_prop_info_set_default_uint8(prh, 1);
1481eef4f27bSRobert Mustacchi 			}
1482eef4f27bSRobert Mustacchi 			break;
1483eef4f27bSRobert Mustacchi 
1484eef4f27bSRobert Mustacchi 		case MAC_PROP_AUTONEG:
1485eef4f27bSRobert Mustacchi 
1486eef4f27bSRobert Mustacchi 			mac_prop_info_set_default_uint8(prh, 1);
1487eef4f27bSRobert Mustacchi 			break;
1488eef4f27bSRobert Mustacchi 
1489eef4f27bSRobert Mustacchi 		case MAC_PROP_FLOWCTRL:
1490eef4f27bSRobert Mustacchi 
1491eef4f27bSRobert Mustacchi 			mac_prop_info_set_default_link_flowctrl(prh,
1492eef4f27bSRobert Mustacchi 			    LINK_FLOWCTRL_BI);
1493eef4f27bSRobert Mustacchi 			break;
1494eef4f27bSRobert Mustacchi 
1495eef4f27bSRobert Mustacchi 		case MAC_PROP_MTU:
1496eef4f27bSRobert Mustacchi 
1497eef4f27bSRobert Mustacchi 			mac_prop_info_set_range_uint32(prh,
1498eef4f27bSRobert Mustacchi 			    USER_OPTION_MTU_MIN, USER_OPTION_MTU_MAX);
1499eef4f27bSRobert Mustacchi 			break;
1500eef4f27bSRobert Mustacchi 
1501eef4f27bSRobert Mustacchi 		case MAC_PROP_PRIVATE:
1502eef4f27bSRobert Mustacchi 
1503eef4f27bSRobert Mustacchi 			bnx_priv_propinfo(umdevice, pr_name, prh);
1504eef4f27bSRobert Mustacchi 			break;
1505eef4f27bSRobert Mustacchi 		default:
1506eef4f27bSRobert Mustacchi 			break;
1507eef4f27bSRobert Mustacchi 	}
1508eef4f27bSRobert Mustacchi }
1509eef4f27bSRobert Mustacchi 
1510eef4f27bSRobert Mustacchi static mac_callbacks_t bnx_callbacks = {
1511eef4f27bSRobert Mustacchi 	(MC_GETCAPAB | MC_SETPROP | MC_GETPROP| MC_PROPINFO),
1512eef4f27bSRobert Mustacchi 	bnx_m_stats,
1513eef4f27bSRobert Mustacchi 	bnx_m_start,
1514eef4f27bSRobert Mustacchi 	bnx_m_stop,
1515eef4f27bSRobert Mustacchi 	bnx_m_promiscuous,
1516eef4f27bSRobert Mustacchi 	bnx_m_multicast,
1517eef4f27bSRobert Mustacchi 	bnx_m_unicast,
1518eef4f27bSRobert Mustacchi 	bnx_m_tx,
1519eef4f27bSRobert Mustacchi 	NULL,
1520eef4f27bSRobert Mustacchi 	NULL,
1521eef4f27bSRobert Mustacchi 	bnx_m_getcapab,
1522eef4f27bSRobert Mustacchi 	NULL,
1523eef4f27bSRobert Mustacchi 	NULL,
1524eef4f27bSRobert Mustacchi 	bnx_m_setprop,
1525eef4f27bSRobert Mustacchi 	bnx_m_getprop,
1526eef4f27bSRobert Mustacchi 	bnx_m_propinfo
1527eef4f27bSRobert Mustacchi };
1528eef4f27bSRobert Mustacchi 
1529eef4f27bSRobert Mustacchi 
1530eef4f27bSRobert Mustacchi 
1531eef4f27bSRobert Mustacchi /*
1532eef4f27bSRobert Mustacchi  * Name:    bnx_gld_init
1533eef4f27bSRobert Mustacchi  *
1534eef4f27bSRobert Mustacchi  * Input:   ptr to device structure.
1535eef4f27bSRobert Mustacchi  *
1536eef4f27bSRobert Mustacchi  * Return:  DDI_SUCCESS or DDI_FAILURE
1537eef4f27bSRobert Mustacchi  *
1538eef4f27bSRobert Mustacchi  * Description:
1539eef4f27bSRobert Mustacchi  *          This routine populates mac info structure for this device
1540eef4f27bSRobert Mustacchi  *          instance and registers device with GLD.
1541eef4f27bSRobert Mustacchi  */
1542eef4f27bSRobert Mustacchi int
bnx_gld_init(um_device_t * const umdevice)1543eef4f27bSRobert Mustacchi bnx_gld_init(um_device_t *const umdevice)
1544eef4f27bSRobert Mustacchi {
1545eef4f27bSRobert Mustacchi 	mac_register_t *macp;
1546eef4f27bSRobert Mustacchi 	int rc;
1547eef4f27bSRobert Mustacchi 
1548eef4f27bSRobert Mustacchi 	umdevice->dev_start = B_FALSE;
1549eef4f27bSRobert Mustacchi 
1550eef4f27bSRobert Mustacchi 	mutex_init(&umdevice->os_param.gld_mutex, NULL,
1551eef4f27bSRobert Mustacchi 	    MUTEX_DRIVER, DDI_INTR_PRI(umdevice->intrPriority));
1552eef4f27bSRobert Mustacchi 
1553eef4f27bSRobert Mustacchi 	rw_init(&umdevice->os_param.gld_snd_mutex, NULL, RW_DRIVER, NULL);
1554eef4f27bSRobert Mustacchi 
1555eef4f27bSRobert Mustacchi 	macp = mac_alloc(MAC_VERSION);
1556eef4f27bSRobert Mustacchi 	if (macp == NULL) {
1557eef4f27bSRobert Mustacchi 		cmn_err(CE_WARN,
1558eef4f27bSRobert Mustacchi 		    "%s: Failed to allocate GLD MAC memory.\n",
1559eef4f27bSRobert Mustacchi 		    umdevice->dev_name);
1560eef4f27bSRobert Mustacchi 		goto error;
1561eef4f27bSRobert Mustacchi 	}
1562eef4f27bSRobert Mustacchi 
1563eef4f27bSRobert Mustacchi 	macp->m_driver = umdevice;
1564eef4f27bSRobert Mustacchi 	macp->m_dip = umdevice->os_param.dip;
1565eef4f27bSRobert Mustacchi 	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
1566eef4f27bSRobert Mustacchi 	macp->m_callbacks = &bnx_callbacks;
1567eef4f27bSRobert Mustacchi 	macp->m_min_sdu = 0;
1568eef4f27bSRobert Mustacchi 	macp->m_max_sdu = umdevice->dev_var.mtu;
1569eef4f27bSRobert Mustacchi 	macp->m_src_addr  = &(umdevice->lm_dev.params.mac_addr[0]);
1570eef4f27bSRobert Mustacchi 
1571eef4f27bSRobert Mustacchi 	macp->m_margin = VLAN_TAG_SIZE;
1572eef4f27bSRobert Mustacchi 
1573eef4f27bSRobert Mustacchi 	/*
1574eef4f27bSRobert Mustacchi 	 * Call mac_register() after initializing all
1575eef4f27bSRobert Mustacchi 	 * the required elements of mac_t struct.
1576eef4f27bSRobert Mustacchi 	 */
1577eef4f27bSRobert Mustacchi 	rc = mac_register(macp, &umdevice->os_param.macp);
1578eef4f27bSRobert Mustacchi 
1579eef4f27bSRobert Mustacchi 	mac_free(macp);
1580eef4f27bSRobert Mustacchi 
1581eef4f27bSRobert Mustacchi 	if (rc != 0) {
1582eef4f27bSRobert Mustacchi 		cmn_err(CE_WARN,
1583eef4f27bSRobert Mustacchi 		    "%s: Failed to register with GLD.\n",
1584eef4f27bSRobert Mustacchi 		    umdevice->dev_name);
1585eef4f27bSRobert Mustacchi 		goto error;
1586eef4f27bSRobert Mustacchi 	}
1587eef4f27bSRobert Mustacchi 
1588eef4f27bSRobert Mustacchi 	/* Always report the initial link state as unknown. */
1589eef4f27bSRobert Mustacchi 	bnx_gld_link(umdevice, LINK_STATE_UNKNOWN);
1590eef4f27bSRobert Mustacchi 
1591eef4f27bSRobert Mustacchi 	return (0);
1592eef4f27bSRobert Mustacchi 
1593eef4f27bSRobert Mustacchi error:
1594eef4f27bSRobert Mustacchi 	rw_destroy(&umdevice->os_param.gld_snd_mutex);
1595eef4f27bSRobert Mustacchi 	mutex_destroy(&umdevice->os_param.gld_mutex);
1596eef4f27bSRobert Mustacchi 
1597eef4f27bSRobert Mustacchi 	return (-1);
1598eef4f27bSRobert Mustacchi }
1599eef4f27bSRobert Mustacchi 
1600eef4f27bSRobert Mustacchi void
bnx_gld_link(um_device_t * const umdevice,const link_state_t linkup)1601eef4f27bSRobert Mustacchi bnx_gld_link(um_device_t * const umdevice, const link_state_t linkup)
1602eef4f27bSRobert Mustacchi {
1603eef4f27bSRobert Mustacchi 	mac_link_update(umdevice->os_param.macp, linkup);
1604eef4f27bSRobert Mustacchi }
1605eef4f27bSRobert Mustacchi 
1606eef4f27bSRobert Mustacchi int
bnx_gld_fini(um_device_t * const umdevice)1607eef4f27bSRobert Mustacchi bnx_gld_fini(um_device_t * const umdevice)
1608eef4f27bSRobert Mustacchi {
1609eef4f27bSRobert Mustacchi 	if (umdevice->dev_start != B_FALSE) {
1610eef4f27bSRobert Mustacchi 		cmn_err(CE_WARN,
1611eef4f27bSRobert Mustacchi 		    "%s: Detaching device from GLD that is still started!!!\n",
1612eef4f27bSRobert Mustacchi 		    umdevice->dev_name);
1613eef4f27bSRobert Mustacchi 		return (-1);
1614eef4f27bSRobert Mustacchi 	}
1615eef4f27bSRobert Mustacchi 
1616eef4f27bSRobert Mustacchi 	if (mac_unregister(umdevice->os_param.macp)) {
1617eef4f27bSRobert Mustacchi 		cmn_err(CE_WARN,
1618eef4f27bSRobert Mustacchi 		    "%s: Failed to unregister with the GLD.\n",
1619eef4f27bSRobert Mustacchi 		    umdevice->dev_name);
1620eef4f27bSRobert Mustacchi 		return (-1);
1621eef4f27bSRobert Mustacchi 	}
1622eef4f27bSRobert Mustacchi 
1623eef4f27bSRobert Mustacchi 	rw_destroy(&umdevice->os_param.gld_snd_mutex);
1624eef4f27bSRobert Mustacchi 	mutex_destroy(&umdevice->os_param.gld_mutex);
1625eef4f27bSRobert Mustacchi 
1626eef4f27bSRobert Mustacchi 	return (0);
1627eef4f27bSRobert Mustacchi }
1628