xref: /illumos-gate/usr/src/uts/common/io/bnx/bnxcfg.c (revision eef4f27b)
1*eef4f27bSRobert Mustacchi /*
2*eef4f27bSRobert Mustacchi  * Copyright 2014-2017 Cavium, Inc.
3*eef4f27bSRobert Mustacchi  * The contents of this file are subject to the terms of the Common Development
4*eef4f27bSRobert Mustacchi  * and Distribution License, v.1,  (the "License").
5*eef4f27bSRobert Mustacchi  *
6*eef4f27bSRobert Mustacchi  * You may not use this file except in compliance with the License.
7*eef4f27bSRobert Mustacchi  *
8*eef4f27bSRobert Mustacchi  * You can obtain a copy of the License at available
9*eef4f27bSRobert Mustacchi  * at http://opensource.org/licenses/CDDL-1.0
10*eef4f27bSRobert Mustacchi  *
11*eef4f27bSRobert Mustacchi  * See the License for the specific language governing permissions and
12*eef4f27bSRobert Mustacchi  * limitations under the License.
13*eef4f27bSRobert Mustacchi  */
14*eef4f27bSRobert Mustacchi 
15*eef4f27bSRobert Mustacchi /*
16*eef4f27bSRobert Mustacchi  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
17*eef4f27bSRobert Mustacchi  * Copyright (c) 2019, Joyent, Inc.
18*eef4f27bSRobert Mustacchi  */
19*eef4f27bSRobert Mustacchi 
20*eef4f27bSRobert Mustacchi #include "bnxcfg.h"
21*eef4f27bSRobert Mustacchi 
22*eef4f27bSRobert Mustacchi const bnx_lnk_cfg_t bnx_copper_config = {
23*eef4f27bSRobert Mustacchi 	B_TRUE,  /* link_autoneg   */
24*eef4f27bSRobert Mustacchi 	B_FALSE, /* param_2500fdx  */
25*eef4f27bSRobert Mustacchi 	B_TRUE,  /* param_1000fdx  */
26*eef4f27bSRobert Mustacchi 	B_TRUE,  /* param_1000hdx  */
27*eef4f27bSRobert Mustacchi 	B_TRUE,  /* param_100fdx   */
28*eef4f27bSRobert Mustacchi 	B_TRUE,  /* param_100hdx   */
29*eef4f27bSRobert Mustacchi 	B_TRUE,  /* param_10fdx    */
30*eef4f27bSRobert Mustacchi 	B_TRUE,  /* param_10hdx    */
31*eef4f27bSRobert Mustacchi 	B_TRUE,  /* param_tx_pause */
32*eef4f27bSRobert Mustacchi 	B_TRUE   /* param_rx_pause */
33*eef4f27bSRobert Mustacchi };
34*eef4f27bSRobert Mustacchi 
35*eef4f27bSRobert Mustacchi const bnx_lnk_cfg_t bnx_serdes_config = {
36*eef4f27bSRobert Mustacchi 	B_TRUE,  /* link_autoneg   */
37*eef4f27bSRobert Mustacchi 	B_TRUE,  /* param_2500fdx  */
38*eef4f27bSRobert Mustacchi 	B_TRUE,  /* param_1000fdx  */
39*eef4f27bSRobert Mustacchi 	B_TRUE,  /* param_1000hdx  */
40*eef4f27bSRobert Mustacchi 	B_FALSE, /* param_100fdx   */
41*eef4f27bSRobert Mustacchi 	B_FALSE, /* param_100hdx   */
42*eef4f27bSRobert Mustacchi 	B_FALSE, /* param_10fdx    */
43*eef4f27bSRobert Mustacchi 	B_FALSE, /* param_10hdx    */
44*eef4f27bSRobert Mustacchi 	B_TRUE,  /* param_tx_pause */
45*eef4f27bSRobert Mustacchi 	B_TRUE   /* param_rx_pause */
46*eef4f27bSRobert Mustacchi };
47*eef4f27bSRobert Mustacchi 
48*eef4f27bSRobert Mustacchi static void
bnx_cfg_readbool(dev_info_t * dip,char * paramname,boolean_t * paramval)49*eef4f27bSRobert Mustacchi bnx_cfg_readbool(dev_info_t *dip, char *paramname, boolean_t *paramval)
50*eef4f27bSRobert Mustacchi {
51*eef4f27bSRobert Mustacchi 	int rc;
52*eef4f27bSRobert Mustacchi 	int *option;
53*eef4f27bSRobert Mustacchi 	uint_t num_options;
54*eef4f27bSRobert Mustacchi 
55*eef4f27bSRobert Mustacchi 	if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_NOTPROM, paramname) ==
56*eef4f27bSRobert Mustacchi 	    1) {
57*eef4f27bSRobert Mustacchi 		rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
58*eef4f27bSRobert Mustacchi 		    DDI_PROP_DONTPASS, paramname, &option, &num_options);
59*eef4f27bSRobert Mustacchi 
60*eef4f27bSRobert Mustacchi 		if (rc == DDI_PROP_SUCCESS) {
61*eef4f27bSRobert Mustacchi 			int inst = ddi_get_instance(dip);
62*eef4f27bSRobert Mustacchi 
63*eef4f27bSRobert Mustacchi 			if (num_options >= inst) {
64*eef4f27bSRobert Mustacchi 				if (option[inst] == 1) {
65*eef4f27bSRobert Mustacchi 					*paramval = B_TRUE;
66*eef4f27bSRobert Mustacchi 				} else {
67*eef4f27bSRobert Mustacchi 					*paramval = B_FALSE;
68*eef4f27bSRobert Mustacchi 				}
69*eef4f27bSRobert Mustacchi 			}
70*eef4f27bSRobert Mustacchi 		}
71*eef4f27bSRobert Mustacchi 
72*eef4f27bSRobert Mustacchi 		ddi_prop_free(option);
73*eef4f27bSRobert Mustacchi 	}
74*eef4f27bSRobert Mustacchi } /* bnx_cfg_readbool */
75*eef4f27bSRobert Mustacchi 
76*eef4f27bSRobert Mustacchi static void
bnx_cfg_readint(dev_info_t * dip,char * paramname,int * paramval)77*eef4f27bSRobert Mustacchi bnx_cfg_readint(dev_info_t *dip, char *paramname, int *paramval)
78*eef4f27bSRobert Mustacchi {
79*eef4f27bSRobert Mustacchi 	int rc;
80*eef4f27bSRobert Mustacchi 	int *option;
81*eef4f27bSRobert Mustacchi 	uint_t num_options;
82*eef4f27bSRobert Mustacchi 
83*eef4f27bSRobert Mustacchi 	rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
84*eef4f27bSRobert Mustacchi 	    paramname, &option, &num_options);
85*eef4f27bSRobert Mustacchi 	if (rc == DDI_PROP_SUCCESS) {
86*eef4f27bSRobert Mustacchi 		int inst = ddi_get_instance(dip);
87*eef4f27bSRobert Mustacchi 
88*eef4f27bSRobert Mustacchi 		if (num_options >= inst) {
89*eef4f27bSRobert Mustacchi 			*paramval = option[inst];
90*eef4f27bSRobert Mustacchi 		}
91*eef4f27bSRobert Mustacchi 
92*eef4f27bSRobert Mustacchi 		ddi_prop_free(option);
93*eef4f27bSRobert Mustacchi 	}
94*eef4f27bSRobert Mustacchi } /* bnx_cfg_readint */
95*eef4f27bSRobert Mustacchi 
96*eef4f27bSRobert Mustacchi void
bnx_cfg_msix(um_device_t * const umdevice)97*eef4f27bSRobert Mustacchi bnx_cfg_msix(um_device_t * const umdevice)
98*eef4f27bSRobert Mustacchi {
99*eef4f27bSRobert Mustacchi 	umdevice->dev_var.disableMsix = B_FALSE;
100*eef4f27bSRobert Mustacchi 
101*eef4f27bSRobert Mustacchi 	bnx_cfg_readbool(umdevice->os_param.dip, "disable_msix",
102*eef4f27bSRobert Mustacchi 	    &(umdevice->dev_var.disableMsix));
103*eef4f27bSRobert Mustacchi }
104*eef4f27bSRobert Mustacchi 
105*eef4f27bSRobert Mustacchi void
bnx_cfg_init(um_device_t * const umdevice)106*eef4f27bSRobert Mustacchi bnx_cfg_init(um_device_t *const umdevice)
107*eef4f27bSRobert Mustacchi {
108*eef4f27bSRobert Mustacchi 	int option;
109*eef4f27bSRobert Mustacchi 	lm_medium_t lmmedium;
110*eef4f27bSRobert Mustacchi 	lm_device_t *lmdevice;
111*eef4f27bSRobert Mustacchi 
112*eef4f27bSRobert Mustacchi 	lmdevice = &(umdevice->lm_dev);
113*eef4f27bSRobert Mustacchi 
114*eef4f27bSRobert Mustacchi 	lmmedium = lm_get_medium(lmdevice);
115*eef4f27bSRobert Mustacchi 	if (lmmedium == LM_MEDIUM_TYPE_FIBER) {
116*eef4f27bSRobert Mustacchi 		umdevice->dev_var.isfiber = B_TRUE;
117*eef4f27bSRobert Mustacchi 
118*eef4f27bSRobert Mustacchi 		bcopy(&bnx_serdes_config,
119*eef4f27bSRobert Mustacchi 		    &(umdevice->hwinit.lnkcfg),
120*eef4f27bSRobert Mustacchi 		    sizeof (bnx_serdes_config));
121*eef4f27bSRobert Mustacchi 	} else {
122*eef4f27bSRobert Mustacchi 		umdevice->dev_var.isfiber = B_FALSE;
123*eef4f27bSRobert Mustacchi 
124*eef4f27bSRobert Mustacchi 		bcopy(&bnx_copper_config, &(umdevice->hwinit.lnkcfg),
125*eef4f27bSRobert Mustacchi 		    sizeof (bnx_copper_config));
126*eef4f27bSRobert Mustacchi 	}
127*eef4f27bSRobert Mustacchi 
128*eef4f27bSRobert Mustacchi 	umdevice->hwinit.flow_autoneg = B_TRUE;
129*eef4f27bSRobert Mustacchi 	umdevice->hwinit.wirespeed    = B_TRUE;
130*eef4f27bSRobert Mustacchi 
131*eef4f27bSRobert Mustacchi 	bnx_cfg_readbool(umdevice->os_param.dip, "adv_autoneg_cap",
132*eef4f27bSRobert Mustacchi 	    &(umdevice->hwinit.lnkcfg.link_autoneg));
133*eef4f27bSRobert Mustacchi 
134*eef4f27bSRobert Mustacchi 	bnx_cfg_readbool(umdevice->os_param.dip, "adv_1000fdx_cap",
135*eef4f27bSRobert Mustacchi 	    &(umdevice->hwinit.lnkcfg.param_1000fdx));
136*eef4f27bSRobert Mustacchi 
137*eef4f27bSRobert Mustacchi 	bnx_cfg_readbool(umdevice->os_param.dip, "adv_1000hdx_cap",
138*eef4f27bSRobert Mustacchi 	    &(umdevice->hwinit.lnkcfg.param_1000hdx));
139*eef4f27bSRobert Mustacchi 
140*eef4f27bSRobert Mustacchi 	bnx_cfg_readbool(umdevice->os_param.dip, "tx_pause_cap",
141*eef4f27bSRobert Mustacchi 	    &(umdevice->hwinit.lnkcfg.param_tx_pause));
142*eef4f27bSRobert Mustacchi 
143*eef4f27bSRobert Mustacchi 	bnx_cfg_readbool(umdevice->os_param.dip, "rx_pause_cap",
144*eef4f27bSRobert Mustacchi 	    &(umdevice->hwinit.lnkcfg.param_rx_pause));
145*eef4f27bSRobert Mustacchi 
146*eef4f27bSRobert Mustacchi 	if (umdevice->dev_var.isfiber) {
147*eef4f27bSRobert Mustacchi 		bnx_cfg_readbool(umdevice->os_param.dip, "adv_2500fdx_cap",
148*eef4f27bSRobert Mustacchi 		    &(umdevice->hwinit.lnkcfg.param_2500fdx));
149*eef4f27bSRobert Mustacchi 	} else {
150*eef4f27bSRobert Mustacchi 		bnx_cfg_readbool(umdevice->os_param.dip, "adv_100fdx_cap",
151*eef4f27bSRobert Mustacchi 		    &(umdevice->hwinit.lnkcfg.param_100fdx));
152*eef4f27bSRobert Mustacchi 
153*eef4f27bSRobert Mustacchi 		bnx_cfg_readbool(umdevice->os_param.dip, "adv_100hdx_cap",
154*eef4f27bSRobert Mustacchi 		    &(umdevice->hwinit.lnkcfg.param_100hdx));
155*eef4f27bSRobert Mustacchi 
156*eef4f27bSRobert Mustacchi 		bnx_cfg_readbool(umdevice->os_param.dip, "adv_10fdx_cap",
157*eef4f27bSRobert Mustacchi 		    &(umdevice->hwinit.lnkcfg.param_10fdx));
158*eef4f27bSRobert Mustacchi 
159*eef4f27bSRobert Mustacchi 		bnx_cfg_readbool(umdevice->os_param.dip, "adv_10hdx_cap",
160*eef4f27bSRobert Mustacchi 		    &(umdevice->hwinit.lnkcfg.param_10hdx));
161*eef4f27bSRobert Mustacchi 	}
162*eef4f27bSRobert Mustacchi 
163*eef4f27bSRobert Mustacchi 	bnx_cfg_readbool(umdevice->os_param.dip, "autoneg_flow",
164*eef4f27bSRobert Mustacchi 	    &(umdevice->hwinit.flow_autoneg));
165*eef4f27bSRobert Mustacchi 
166*eef4f27bSRobert Mustacchi 	bnx_cfg_readbool(umdevice->os_param.dip, "wirespeed",
167*eef4f27bSRobert Mustacchi 	    &(umdevice->hwinit.wirespeed));
168*eef4f27bSRobert Mustacchi 
169*eef4f27bSRobert Mustacchi #if 1
170*eef4f27bSRobert Mustacchi 	/* FIXME -- Do we really need "transfer-speed"? */
171*eef4f27bSRobert Mustacchi 	/*
172*eef4f27bSRobert Mustacchi 	 * The link speed may be forced to 10, 100 or 1000 Mbps using
173*eef4f27bSRobert Mustacchi 	 * the property "transfer-speed". This may be done in OBP by
174*eef4f27bSRobert Mustacchi 	 * using the command "apply transfer-speed=<speed> <device>".
175*eef4f27bSRobert Mustacchi 	 * The speed may be 10, 100 or 1000 - any other value will be
176*eef4f27bSRobert Mustacchi 	 * ignored.  Note that this *enables* autonegotiation, but
177*eef4f27bSRobert Mustacchi 	 * restricts it to the speed specified by the property.
178*eef4f27bSRobert Mustacchi 	 */
179*eef4f27bSRobert Mustacchi 	option = 0;
180*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
181*eef4f27bSRobert Mustacchi 	    "transfer-speed", &option);
182*eef4f27bSRobert Mustacchi 	switch (option) {
183*eef4f27bSRobert Mustacchi 		case 1000:
184*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.link_autoneg  = B_TRUE;
185*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_1000fdx = B_TRUE;
186*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_1000hdx = B_TRUE;
187*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_100fdx  = B_FALSE;
188*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_100hdx  = B_FALSE;
189*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_10fdx   = B_FALSE;
190*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_10hdx   = B_FALSE;
191*eef4f27bSRobert Mustacchi 			break;
192*eef4f27bSRobert Mustacchi 
193*eef4f27bSRobert Mustacchi 		case 100:
194*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.link_autoneg  = B_TRUE;
195*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_1000fdx = B_FALSE;
196*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_1000hdx = B_FALSE;
197*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_100fdx  = B_TRUE;
198*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_100hdx  = B_TRUE;
199*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_10fdx   = B_FALSE;
200*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_10hdx   = B_FALSE;
201*eef4f27bSRobert Mustacchi 			break;
202*eef4f27bSRobert Mustacchi 
203*eef4f27bSRobert Mustacchi 		case 10:
204*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.link_autoneg  = B_TRUE;
205*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_1000fdx = B_FALSE;
206*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_1000hdx = B_FALSE;
207*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_100fdx  = B_FALSE;
208*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_100hdx  = B_FALSE;
209*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_10fdx   = B_TRUE;
210*eef4f27bSRobert Mustacchi 			umdevice->hwinit.lnkcfg.param_10hdx   = B_TRUE;
211*eef4f27bSRobert Mustacchi 			break;
212*eef4f27bSRobert Mustacchi 	}
213*eef4f27bSRobert Mustacchi #endif
214*eef4f27bSRobert Mustacchi 
215*eef4f27bSRobert Mustacchi 
216*eef4f27bSRobert Mustacchi 	/* FIXME -- Make the MAC address hwconf configurable. */
217*eef4f27bSRobert Mustacchi 
218*eef4f27bSRobert Mustacchi 	/* Checksum configuration */
219*eef4f27bSRobert Mustacchi 	option = USER_OPTION_CKSUM_DEFAULT;
220*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
221*eef4f27bSRobert Mustacchi 	    "checksum", &option);
222*eef4f27bSRobert Mustacchi 	switch (option) {
223*eef4f27bSRobert Mustacchi 		case USER_OPTION_CKSUM_TX_ONLY:
224*eef4f27bSRobert Mustacchi 			umdevice->dev_var.enabled_oflds = LM_OFFLOAD_TX_IP_CKSUM
225*eef4f27bSRobert Mustacchi 			    | LM_OFFLOAD_TX_TCP_CKSUM
226*eef4f27bSRobert Mustacchi 			    | LM_OFFLOAD_TX_UDP_CKSUM;
227*eef4f27bSRobert Mustacchi 			break;
228*eef4f27bSRobert Mustacchi 
229*eef4f27bSRobert Mustacchi 		case USER_OPTION_CKSUM_RX_ONLY:
230*eef4f27bSRobert Mustacchi 			umdevice->dev_var.enabled_oflds = LM_OFFLOAD_RX_IP_CKSUM
231*eef4f27bSRobert Mustacchi 			    | LM_OFFLOAD_RX_TCP_CKSUM
232*eef4f27bSRobert Mustacchi 			    | LM_OFFLOAD_RX_UDP_CKSUM;
233*eef4f27bSRobert Mustacchi 			break;
234*eef4f27bSRobert Mustacchi 
235*eef4f27bSRobert Mustacchi 		case USER_OPTION_CKSUM_TX_RX:
236*eef4f27bSRobert Mustacchi 			umdevice->dev_var.enabled_oflds = LM_OFFLOAD_TX_IP_CKSUM
237*eef4f27bSRobert Mustacchi 			    | LM_OFFLOAD_RX_IP_CKSUM
238*eef4f27bSRobert Mustacchi 			    | LM_OFFLOAD_TX_TCP_CKSUM
239*eef4f27bSRobert Mustacchi 			    | LM_OFFLOAD_RX_TCP_CKSUM
240*eef4f27bSRobert Mustacchi 			    | LM_OFFLOAD_TX_UDP_CKSUM
241*eef4f27bSRobert Mustacchi 			    | LM_OFFLOAD_RX_UDP_CKSUM;
242*eef4f27bSRobert Mustacchi 			break;
243*eef4f27bSRobert Mustacchi 
244*eef4f27bSRobert Mustacchi 		case USER_OPTION_CKSUM_NONE:
245*eef4f27bSRobert Mustacchi 		default:
246*eef4f27bSRobert Mustacchi 			umdevice->dev_var.enabled_oflds = LM_OFFLOAD_NONE;
247*eef4f27bSRobert Mustacchi 			break;
248*eef4f27bSRobert Mustacchi 	}
249*eef4f27bSRobert Mustacchi 
250*eef4f27bSRobert Mustacchi 	/* Ticks interval between statistics block updates. */
251*eef4f27bSRobert Mustacchi 	option = USER_OPTION_STATSTICKS_DEFAULT;
252*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
253*eef4f27bSRobert Mustacchi 	    USER_OPTION_KEYWORD_STATSTICKS, &option);
254*eef4f27bSRobert Mustacchi 	if (option >= USER_OPTION_STATSTICKS_MIN &&
255*eef4f27bSRobert Mustacchi 	    option <= USER_OPTION_STATSTICKS_MAX) {
256*eef4f27bSRobert Mustacchi 		lmdevice->params.stats_ticks = option;
257*eef4f27bSRobert Mustacchi 	} else {
258*eef4f27bSRobert Mustacchi 		lmdevice->params.stats_ticks = USER_OPTION_STATSTICKS_DEFAULT;
259*eef4f27bSRobert Mustacchi 	}
260*eef4f27bSRobert Mustacchi 
261*eef4f27bSRobert Mustacchi 	/* Tx ticks for interrupt coalescing */
262*eef4f27bSRobert Mustacchi 	option = USER_OPTION_TXTICKS_DEFAULT;
263*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
264*eef4f27bSRobert Mustacchi 	    "tx_coalesce_ticks", &option);
265*eef4f27bSRobert Mustacchi 	if (option >= USER_OPTION_TICKS_MIN &&
266*eef4f27bSRobert Mustacchi 	    option <= USER_OPTION_TICKS_MAX) {
267*eef4f27bSRobert Mustacchi 		lmdevice->params.tx_ticks = option;
268*eef4f27bSRobert Mustacchi 	} else {
269*eef4f27bSRobert Mustacchi 		lmdevice->params.tx_ticks = USER_OPTION_TXTICKS_DEFAULT;
270*eef4f27bSRobert Mustacchi 	}
271*eef4f27bSRobert Mustacchi 
272*eef4f27bSRobert Mustacchi 	/* Interrupt mode Tx ticks for interrupt coalescing */
273*eef4f27bSRobert Mustacchi 	option = USER_OPTION_TXTICKS_INT_DEFAULT;
274*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
275*eef4f27bSRobert Mustacchi 	    "tx_coalesce_ticks_int", &option);
276*eef4f27bSRobert Mustacchi 	if (option >= USER_OPTION_TICKS_MIN &&
277*eef4f27bSRobert Mustacchi 	    option <= USER_OPTION_TICKS_MAX) {
278*eef4f27bSRobert Mustacchi 		lmdevice->params.tx_ticks_int = option;
279*eef4f27bSRobert Mustacchi 	} else {
280*eef4f27bSRobert Mustacchi 		lmdevice->params.tx_ticks_int = USER_OPTION_TXTICKS_INT_DEFAULT;
281*eef4f27bSRobert Mustacchi 	}
282*eef4f27bSRobert Mustacchi 
283*eef4f27bSRobert Mustacchi 	/* Rx ticks for interrupt coalescing */
284*eef4f27bSRobert Mustacchi 	option = USER_OPTION_RXTICKS_DEFAULT;
285*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
286*eef4f27bSRobert Mustacchi 	    "rx_coalesce_ticks", &option);
287*eef4f27bSRobert Mustacchi 	if (option >= USER_OPTION_TICKS_MIN &&
288*eef4f27bSRobert Mustacchi 	    option <= USER_OPTION_TICKS_MAX) {
289*eef4f27bSRobert Mustacchi 		lmdevice->params.rx_ticks = option;
290*eef4f27bSRobert Mustacchi 	} else {
291*eef4f27bSRobert Mustacchi 		lmdevice->params.rx_ticks = USER_OPTION_RXTICKS_DEFAULT;
292*eef4f27bSRobert Mustacchi 	}
293*eef4f27bSRobert Mustacchi 
294*eef4f27bSRobert Mustacchi 	/* Interrupt mode Rx ticks for interrupt coalescing */
295*eef4f27bSRobert Mustacchi 	option = USER_OPTION_RXTICKS_INT_DEFAULT;
296*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
297*eef4f27bSRobert Mustacchi 	    "rx_coalesce_ticks_int", &option);
298*eef4f27bSRobert Mustacchi 	if (option >= USER_OPTION_TICKS_INT_MIN &&
299*eef4f27bSRobert Mustacchi 	    option <= USER_OPTION_TICKS_INT_MAX) {
300*eef4f27bSRobert Mustacchi 		lmdevice->params.rx_ticks_int = option;
301*eef4f27bSRobert Mustacchi 	} else {
302*eef4f27bSRobert Mustacchi 		lmdevice->params.rx_ticks_int = USER_OPTION_RXTICKS_INT_DEFAULT;
303*eef4f27bSRobert Mustacchi 	}
304*eef4f27bSRobert Mustacchi 
305*eef4f27bSRobert Mustacchi 
306*eef4f27bSRobert Mustacchi 	/* Tx frames for interrupt coalescing */
307*eef4f27bSRobert Mustacchi 	option = USER_OPTION_TXFRAMES_DEFAULT;
308*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
309*eef4f27bSRobert Mustacchi 	    "tx_coalesce_frames", &option);
310*eef4f27bSRobert Mustacchi 	if (option >= USER_OPTION_FRAMES_MIN &&
311*eef4f27bSRobert Mustacchi 	    option <= USER_OPTION_FRAMES_MAX) {
312*eef4f27bSRobert Mustacchi 		lmdevice->params.tx_quick_cons_trip = option;
313*eef4f27bSRobert Mustacchi 	} else {
314*eef4f27bSRobert Mustacchi 		lmdevice->params.tx_quick_cons_trip =
315*eef4f27bSRobert Mustacchi 		    USER_OPTION_TXFRAMES_DEFAULT;
316*eef4f27bSRobert Mustacchi 	}
317*eef4f27bSRobert Mustacchi 
318*eef4f27bSRobert Mustacchi 	/* Interrupt mode Tx frames for interrupt coalescing */
319*eef4f27bSRobert Mustacchi 	option = USER_OPTION_TXFRAMES_INT_DEFAULT;
320*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
321*eef4f27bSRobert Mustacchi 	    "tx_coalesce_frames_int", &option);
322*eef4f27bSRobert Mustacchi 	if (option >= USER_OPTION_FRAMES_MIN &&
323*eef4f27bSRobert Mustacchi 	    option <= USER_OPTION_FRAMES_MAX) {
324*eef4f27bSRobert Mustacchi 		lmdevice->params.tx_quick_cons_trip_int = option;
325*eef4f27bSRobert Mustacchi 	} else {
326*eef4f27bSRobert Mustacchi 		lmdevice->params.tx_quick_cons_trip_int =
327*eef4f27bSRobert Mustacchi 		    USER_OPTION_TXFRAMES_INT_DEFAULT;
328*eef4f27bSRobert Mustacchi 	}
329*eef4f27bSRobert Mustacchi 
330*eef4f27bSRobert Mustacchi 	/* Rx frames for interrupt coalescing */
331*eef4f27bSRobert Mustacchi 	option = USER_OPTION_RXFRAMES_DEFAULT;
332*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
333*eef4f27bSRobert Mustacchi 	    "rx_coalesce_frames", &option);
334*eef4f27bSRobert Mustacchi 	if (option >= USER_OPTION_FRAMES_MIN &&
335*eef4f27bSRobert Mustacchi 	    option <= USER_OPTION_FRAMES_MAX) {
336*eef4f27bSRobert Mustacchi 		lmdevice->params.rx_quick_cons_trip = option;
337*eef4f27bSRobert Mustacchi 	} else {
338*eef4f27bSRobert Mustacchi 		lmdevice->params.rx_quick_cons_trip =
339*eef4f27bSRobert Mustacchi 		    USER_OPTION_RXFRAMES_DEFAULT;
340*eef4f27bSRobert Mustacchi 	}
341*eef4f27bSRobert Mustacchi 
342*eef4f27bSRobert Mustacchi 	/* Interrupt mode Rx frames for interrupt coalescing */
343*eef4f27bSRobert Mustacchi 	option = USER_OPTION_RXFRAMES_INT_DEFAULT;
344*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
345*eef4f27bSRobert Mustacchi 	    "rx_coalesce_frames_int", &option);
346*eef4f27bSRobert Mustacchi 	if (option >= USER_OPTION_FRAMES_MIN &&
347*eef4f27bSRobert Mustacchi 	    option <= USER_OPTION_FRAMES_MAX) {
348*eef4f27bSRobert Mustacchi 		lmdevice->params.rx_quick_cons_trip_int = option;
349*eef4f27bSRobert Mustacchi 	} else {
350*eef4f27bSRobert Mustacchi 		lmdevice->params.rx_quick_cons_trip_int =
351*eef4f27bSRobert Mustacchi 		    USER_OPTION_RXFRAMES_INT_DEFAULT;
352*eef4f27bSRobert Mustacchi 	}
353*eef4f27bSRobert Mustacchi 
354*eef4f27bSRobert Mustacchi 
355*eef4f27bSRobert Mustacchi 	option = USER_OPTION_TX_DESC_CNT_DEFAULT;
356*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
357*eef4f27bSRobert Mustacchi 	    "tx_descriptor_count", &option);
358*eef4f27bSRobert Mustacchi 	if (option < USER_OPTION_TX_DESC_CNT_MIN ||
359*eef4f27bSRobert Mustacchi 	    option > USER_OPTION_TX_DESC_CNT_MAX) {
360*eef4f27bSRobert Mustacchi 		option = USER_OPTION_TX_DESC_CNT_DEFAULT;
361*eef4f27bSRobert Mustacchi 	}
362*eef4f27bSRobert Mustacchi 
363*eef4f27bSRobert Mustacchi 	/* FIXME -- tx bd pages assumes 1 pd === 1 bd */
364*eef4f27bSRobert Mustacchi 	_TX_QINFO(umdevice, 0).desc_cnt = option;
365*eef4f27bSRobert Mustacchi 	lmdevice->params.l2_tx_bd_page_cnt[0] = option / MAX_BD_PER_PAGE;
366*eef4f27bSRobert Mustacchi 	if (option % MAX_BD_PER_PAGE) {
367*eef4f27bSRobert Mustacchi 		lmdevice->params.l2_tx_bd_page_cnt[0]++;
368*eef4f27bSRobert Mustacchi 	}
369*eef4f27bSRobert Mustacchi 	if (lmdevice->params.l2_tx_bd_page_cnt[0] > 127) {
370*eef4f27bSRobert Mustacchi 		lmdevice->params.l2_tx_bd_page_cnt[0] = 127;
371*eef4f27bSRobert Mustacchi 	}
372*eef4f27bSRobert Mustacchi 
373*eef4f27bSRobert Mustacchi 
374*eef4f27bSRobert Mustacchi 	option = USER_OPTION_RX_DESC_CNT_DEFAULT;
375*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
376*eef4f27bSRobert Mustacchi 	    "rx_descriptor_count", &option);
377*eef4f27bSRobert Mustacchi 	if (option < USER_OPTION_RX_DESC_CNT_MIN ||
378*eef4f27bSRobert Mustacchi 	    option > USER_OPTION_RX_DESC_CNT_MAX) {
379*eef4f27bSRobert Mustacchi 		option = USER_OPTION_RX_DESC_CNT_DEFAULT;
380*eef4f27bSRobert Mustacchi 	}
381*eef4f27bSRobert Mustacchi 
382*eef4f27bSRobert Mustacchi 	lmdevice->params.l2_rx_desc_cnt[0] = option;
383*eef4f27bSRobert Mustacchi 	option = (option * BNX_RECV_MAX_FRAGS) / MAX_BD_PER_PAGE;
384*eef4f27bSRobert Mustacchi 	lmdevice->params.l2_rx_bd_page_cnt[0] = option;
385*eef4f27bSRobert Mustacchi 	if (option % MAX_BD_PER_PAGE) {
386*eef4f27bSRobert Mustacchi 		lmdevice->params.l2_rx_bd_page_cnt[0]++;
387*eef4f27bSRobert Mustacchi 	}
388*eef4f27bSRobert Mustacchi 
389*eef4f27bSRobert Mustacchi 	option = USER_OPTION_MTU_DEFAULT;
390*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
391*eef4f27bSRobert Mustacchi 	    "mtu", &option);
392*eef4f27bSRobert Mustacchi 	if (option < USER_OPTION_MTU_MIN) {
393*eef4f27bSRobert Mustacchi 		umdevice->dev_var.mtu = USER_OPTION_MTU_MIN;
394*eef4f27bSRobert Mustacchi 	} else if (option > USER_OPTION_MTU_MAX) {
395*eef4f27bSRobert Mustacchi 		umdevice->dev_var.mtu = USER_OPTION_MTU_MAX;
396*eef4f27bSRobert Mustacchi 	} else {
397*eef4f27bSRobert Mustacchi 		umdevice->dev_var.mtu = option;
398*eef4f27bSRobert Mustacchi 	}
399*eef4f27bSRobert Mustacchi 	lmdevice->params.mtu = umdevice->dev_var.mtu +
400*eef4f27bSRobert Mustacchi 	    sizeof (struct ether_header) + VLAN_TAGSZ;
401*eef4f27bSRobert Mustacchi 
402*eef4f27bSRobert Mustacchi 	/* Flag to enable double copy of transmit payload. */
403*eef4f27bSRobert Mustacchi 	option = USER_OPTION_TX_DCOPY_THRESH_DEFAULT;
404*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip,
405*eef4f27bSRobert Mustacchi 	    "tx_copy_thresh", &option);
406*eef4f27bSRobert Mustacchi 	if (option < MIN_ETHERNET_PACKET_SIZE) {
407*eef4f27bSRobert Mustacchi 		option = MIN_ETHERNET_PACKET_SIZE;
408*eef4f27bSRobert Mustacchi 	}
409*eef4f27bSRobert Mustacchi 	umdevice->tx_copy_threshold = option;
410*eef4f27bSRobert Mustacchi 
411*eef4f27bSRobert Mustacchi 	/* Flag to enable double copy of receive packet. */
412*eef4f27bSRobert Mustacchi 	option = USER_OPTION_RX_DCOPY_DEFAULT;
413*eef4f27bSRobert Mustacchi 	bnx_cfg_readint(umdevice->os_param.dip, USER_OPTION_KEYWORD_RX_DCOPY,
414*eef4f27bSRobert Mustacchi 	    &option);
415*eef4f27bSRobert Mustacchi 	if (option) {
416*eef4f27bSRobert Mustacchi 		umdevice->rx_copy_threshold = 0xffffffff;
417*eef4f27bSRobert Mustacchi 	} else {
418*eef4f27bSRobert Mustacchi 		umdevice->rx_copy_threshold = 0;
419*eef4f27bSRobert Mustacchi 	}
420*eef4f27bSRobert Mustacchi } /* bnx_cfg_init */
421*eef4f27bSRobert Mustacchi 
422*eef4f27bSRobert Mustacchi 
423*eef4f27bSRobert Mustacchi void
bnx_cfg_reset(um_device_t * const umdevice)424*eef4f27bSRobert Mustacchi bnx_cfg_reset(um_device_t *const umdevice)
425*eef4f27bSRobert Mustacchi {
426*eef4f27bSRobert Mustacchi 	/* Reset the link status. */
427*eef4f27bSRobert Mustacchi 	umdevice->nddcfg.link_speed = 0;
428*eef4f27bSRobert Mustacchi 	umdevice->nddcfg.link_duplex = B_FALSE;
429*eef4f27bSRobert Mustacchi 	umdevice->nddcfg.link_tx_pause = B_FALSE;
430*eef4f27bSRobert Mustacchi 	umdevice->nddcfg.link_rx_pause = B_FALSE;
431*eef4f27bSRobert Mustacchi 
432*eef4f27bSRobert Mustacchi 	/* Reset the link partner status. */
433*eef4f27bSRobert Mustacchi 	umdevice->remote.link_autoneg   = B_FALSE;
434*eef4f27bSRobert Mustacchi 	umdevice->remote.param_2500fdx  = B_FALSE;
435*eef4f27bSRobert Mustacchi 	umdevice->remote.param_1000fdx  = B_FALSE;
436*eef4f27bSRobert Mustacchi 	umdevice->remote.param_1000hdx  = B_FALSE;
437*eef4f27bSRobert Mustacchi 	umdevice->remote.param_100fdx   = B_FALSE;
438*eef4f27bSRobert Mustacchi 	umdevice->remote.param_100hdx   = B_FALSE;
439*eef4f27bSRobert Mustacchi 	umdevice->remote.param_10fdx    = B_FALSE;
440*eef4f27bSRobert Mustacchi 	umdevice->remote.param_10hdx    = B_FALSE;
441*eef4f27bSRobert Mustacchi 	umdevice->remote.param_tx_pause = B_FALSE;
442*eef4f27bSRobert Mustacchi 	umdevice->remote.param_rx_pause = B_FALSE;
443*eef4f27bSRobert Mustacchi 
444*eef4f27bSRobert Mustacchi 	/* Reset the configuration to the hardware default. */
445*eef4f27bSRobert Mustacchi 	bcopy(&(umdevice->hwinit), &(umdevice->curcfg), sizeof (bnx_phy_cfg_t));
446*eef4f27bSRobert Mustacchi } /* bnx_cfg_reset */
447*eef4f27bSRobert Mustacchi 
448*eef4f27bSRobert Mustacchi 
449*eef4f27bSRobert Mustacchi 
450*eef4f27bSRobert Mustacchi static lm_medium_t
bnx_cfg_map_serdes(um_device_t * const umdevice)451*eef4f27bSRobert Mustacchi bnx_cfg_map_serdes(um_device_t *const umdevice)
452*eef4f27bSRobert Mustacchi {
453*eef4f27bSRobert Mustacchi 	lm_medium_t lmmedium;
454*eef4f27bSRobert Mustacchi 	lm_device_t *lmdevice;
455*eef4f27bSRobert Mustacchi 
456*eef4f27bSRobert Mustacchi 	lmdevice = &(umdevice->lm_dev);
457*eef4f27bSRobert Mustacchi 
458*eef4f27bSRobert Mustacchi 	lmmedium = LM_MEDIUM_TYPE_FIBER;
459*eef4f27bSRobert Mustacchi 
460*eef4f27bSRobert Mustacchi 	if (umdevice->curcfg.lnkcfg.link_autoneg) {
461*eef4f27bSRobert Mustacchi 		if (umdevice->curcfg.lnkcfg.param_2500fdx &&
462*eef4f27bSRobert Mustacchi 		    umdevice->curcfg.lnkcfg.param_1000fdx &&
463*eef4f27bSRobert Mustacchi 		    umdevice->curcfg.lnkcfg.param_1000hdx) {
464*eef4f27bSRobert Mustacchi 			/*
465*eef4f27bSRobert Mustacchi 			 * All autoneg speeds are advertised.
466*eef4f27bSRobert Mustacchi 			 * Don't specify a speed so we get the full range.
467*eef4f27bSRobert Mustacchi 			 */
468*eef4f27bSRobert Mustacchi 			lmmedium |= LM_MEDIUM_SPEED_AUTONEG;
469*eef4f27bSRobert Mustacchi 		} else {
470*eef4f27bSRobert Mustacchi 			lmdevice->params.selective_autoneg =
471*eef4f27bSRobert Mustacchi 			    SELECTIVE_AUTONEG_SINGLE_SPEED;
472*eef4f27bSRobert Mustacchi 
473*eef4f27bSRobert Mustacchi 			if (umdevice->curcfg.lnkcfg.param_2500fdx) {
474*eef4f27bSRobert Mustacchi 				lmmedium |= LM_MEDIUM_SPEED_2500MBPS
475*eef4f27bSRobert Mustacchi 				    | LM_MEDIUM_FULL_DUPLEX;
476*eef4f27bSRobert Mustacchi 			} else if (umdevice->curcfg.lnkcfg.param_1000fdx) {
477*eef4f27bSRobert Mustacchi 				lmmedium |= LM_MEDIUM_SPEED_1000MBPS
478*eef4f27bSRobert Mustacchi 				    | LM_MEDIUM_FULL_DUPLEX;
479*eef4f27bSRobert Mustacchi 			} else if (umdevice->curcfg.lnkcfg.param_1000hdx) {
480*eef4f27bSRobert Mustacchi 				lmmedium |= LM_MEDIUM_SPEED_1000MBPS
481*eef4f27bSRobert Mustacchi 				    | LM_MEDIUM_HALF_DUPLEX;
482*eef4f27bSRobert Mustacchi 			} else {
483*eef4f27bSRobert Mustacchi 				/* Configuration error. */
484*eef4f27bSRobert Mustacchi 				lmdevice->params.selective_autoneg =
485*eef4f27bSRobert Mustacchi 				    SELECTIVE_AUTONEG_OFF;
486*eef4f27bSRobert Mustacchi 				goto error;
487*eef4f27bSRobert Mustacchi 			}
488*eef4f27bSRobert Mustacchi 		}
489*eef4f27bSRobert Mustacchi 
490*eef4f27bSRobert Mustacchi 		/*
491*eef4f27bSRobert Mustacchi 		 * Enable serdes fallback for all but one particular HP
492*eef4f27bSRobert Mustacchi 		 * platform.
493*eef4f27bSRobert Mustacchi 		 */
494*eef4f27bSRobert Mustacchi 		if (CHIP_NUM(lmdevice) == CHIP_NUM_5706 &&
495*eef4f27bSRobert Mustacchi 		    !(lmdevice->hw_info.svid == 0x103c &&
496*eef4f27bSRobert Mustacchi 		    lmdevice->hw_info.ssid == 0x310c)) {
497*eef4f27bSRobert Mustacchi 			if (umdevice->curcfg.lnkcfg.param_2500fdx) {
498*eef4f27bSRobert Mustacchi 				lmmedium |=
499*eef4f27bSRobert Mustacchi 				    LM_MEDIUM_SPEED_AUTONEG_2_5G_FALLBACK;
500*eef4f27bSRobert Mustacchi 			} else {
501*eef4f27bSRobert Mustacchi 				lmmedium |= LM_MEDIUM_SPEED_AUTONEG_1G_FALLBACK;
502*eef4f27bSRobert Mustacchi 			}
503*eef4f27bSRobert Mustacchi 		}
504*eef4f27bSRobert Mustacchi 	} else {
505*eef4f27bSRobert Mustacchi 		if (umdevice->curcfg.lnkcfg.param_2500fdx) {
506*eef4f27bSRobert Mustacchi 			lmmedium |= LM_MEDIUM_SPEED_2500MBPS
507*eef4f27bSRobert Mustacchi 			    | LM_MEDIUM_FULL_DUPLEX;
508*eef4f27bSRobert Mustacchi 		} else if (umdevice->curcfg.lnkcfg.param_1000fdx) {
509*eef4f27bSRobert Mustacchi 			lmmedium |= LM_MEDIUM_SPEED_1000MBPS
510*eef4f27bSRobert Mustacchi 			    | LM_MEDIUM_FULL_DUPLEX;
511*eef4f27bSRobert Mustacchi 		} else {
512*eef4f27bSRobert Mustacchi 			/* Configuration error. */
513*eef4f27bSRobert Mustacchi 			goto error;
514*eef4f27bSRobert Mustacchi 		}
515*eef4f27bSRobert Mustacchi 	}
516*eef4f27bSRobert Mustacchi 
517*eef4f27bSRobert Mustacchi 	return (lmmedium);
518*eef4f27bSRobert Mustacchi 
519*eef4f27bSRobert Mustacchi error:
520*eef4f27bSRobert Mustacchi 	/* Just give them full autoneg with no fallback capabilities. */
521*eef4f27bSRobert Mustacchi 	lmmedium |= LM_MEDIUM_SPEED_AUTONEG;
522*eef4f27bSRobert Mustacchi 
523*eef4f27bSRobert Mustacchi 	return (lmmedium);
524*eef4f27bSRobert Mustacchi } /* bnx_cfg_map_serdes */
525*eef4f27bSRobert Mustacchi 
526*eef4f27bSRobert Mustacchi 
527*eef4f27bSRobert Mustacchi 
528*eef4f27bSRobert Mustacchi static lm_medium_t
bnx_cfg_map_copper(um_device_t * const umdevice)529*eef4f27bSRobert Mustacchi bnx_cfg_map_copper(um_device_t *const umdevice)
530*eef4f27bSRobert Mustacchi {
531*eef4f27bSRobert Mustacchi 	lm_medium_t lmmedium;
532*eef4f27bSRobert Mustacchi 	lm_device_t *lmdevice;
533*eef4f27bSRobert Mustacchi 
534*eef4f27bSRobert Mustacchi 	lmdevice = &(umdevice->lm_dev);
535*eef4f27bSRobert Mustacchi 
536*eef4f27bSRobert Mustacchi 	lmmedium = LM_MEDIUM_TYPE_UTP;
537*eef4f27bSRobert Mustacchi 
538*eef4f27bSRobert Mustacchi 	if (umdevice->curcfg.lnkcfg.link_autoneg) {
539*eef4f27bSRobert Mustacchi 		if (umdevice->curcfg.lnkcfg.param_1000fdx == B_TRUE &&
540*eef4f27bSRobert Mustacchi 		    umdevice->curcfg.lnkcfg.param_1000hdx == B_TRUE &&
541*eef4f27bSRobert Mustacchi 		    umdevice->curcfg.lnkcfg.param_100fdx == B_TRUE &&
542*eef4f27bSRobert Mustacchi 		    umdevice->curcfg.lnkcfg.param_100hdx == B_TRUE &&
543*eef4f27bSRobert Mustacchi 		    umdevice->curcfg.lnkcfg.param_10fdx == B_TRUE &&
544*eef4f27bSRobert Mustacchi 		    umdevice->curcfg.lnkcfg.param_10hdx == B_TRUE) {
545*eef4f27bSRobert Mustacchi 			/*
546*eef4f27bSRobert Mustacchi 			 * All autoneg speeds are advertised.
547*eef4f27bSRobert Mustacchi 			 * Don't specify a speed so we get the full range.
548*eef4f27bSRobert Mustacchi 			 */
549*eef4f27bSRobert Mustacchi 			lmmedium |= LM_MEDIUM_SPEED_AUTONEG;
550*eef4f27bSRobert Mustacchi 		} else {
551*eef4f27bSRobert Mustacchi 			lmdevice->params.selective_autoneg =
552*eef4f27bSRobert Mustacchi 			    SELECTIVE_AUTONEG_SINGLE_SPEED;
553*eef4f27bSRobert Mustacchi 
554*eef4f27bSRobert Mustacchi 			if (umdevice->curcfg.lnkcfg.param_1000fdx) {
555*eef4f27bSRobert Mustacchi 				lmmedium |= LM_MEDIUM_SPEED_1000MBPS
556*eef4f27bSRobert Mustacchi 				    | LM_MEDIUM_FULL_DUPLEX;
557*eef4f27bSRobert Mustacchi 			} else if (umdevice->curcfg.lnkcfg.param_1000hdx) {
558*eef4f27bSRobert Mustacchi 				lmmedium |= LM_MEDIUM_SPEED_1000MBPS
559*eef4f27bSRobert Mustacchi 				    | LM_MEDIUM_HALF_DUPLEX;
560*eef4f27bSRobert Mustacchi 
561*eef4f27bSRobert Mustacchi 				if (umdevice->curcfg.lnkcfg.param_100fdx ==
562*eef4f27bSRobert Mustacchi 				    B_TRUE &&
563*eef4f27bSRobert Mustacchi 				    umdevice->curcfg.lnkcfg.param_100hdx ==
564*eef4f27bSRobert Mustacchi 				    B_TRUE &&
565*eef4f27bSRobert Mustacchi 				    umdevice->curcfg.lnkcfg.param_10fdx ==
566*eef4f27bSRobert Mustacchi 				    B_TRUE &&
567*eef4f27bSRobert Mustacchi 				    umdevice->curcfg.lnkcfg.param_10hdx ==
568*eef4f27bSRobert Mustacchi 				    B_TRUE) {
569*eef4f27bSRobert Mustacchi 					lmdevice->params.selective_autoneg =
570*eef4f27bSRobert Mustacchi 					    SELECTIVE_AUTONEG_ENABLE_SLOWER_SPEEDS;
571*eef4f27bSRobert Mustacchi 				}
572*eef4f27bSRobert Mustacchi 			} else if (umdevice->curcfg.lnkcfg.param_100fdx) {
573*eef4f27bSRobert Mustacchi 				lmmedium |= LM_MEDIUM_SPEED_100MBPS
574*eef4f27bSRobert Mustacchi 				    | LM_MEDIUM_FULL_DUPLEX;
575*eef4f27bSRobert Mustacchi 
576*eef4f27bSRobert Mustacchi 				if (umdevice->curcfg.lnkcfg.param_100hdx ==
577*eef4f27bSRobert Mustacchi 				    B_TRUE &&
578*eef4f27bSRobert Mustacchi 				    umdevice->curcfg.lnkcfg.param_10fdx ==
579*eef4f27bSRobert Mustacchi 				    B_TRUE &&
580*eef4f27bSRobert Mustacchi 				    umdevice->curcfg.lnkcfg.param_10hdx ==
581*eef4f27bSRobert Mustacchi 				    B_TRUE) {
582*eef4f27bSRobert Mustacchi 					lmdevice->params.selective_autoneg =
583*eef4f27bSRobert Mustacchi 					    SELECTIVE_AUTONEG_ENABLE_SLOWER_SPEEDS;
584*eef4f27bSRobert Mustacchi 				}
585*eef4f27bSRobert Mustacchi 			} else if (umdevice->curcfg.lnkcfg.param_100hdx) {
586*eef4f27bSRobert Mustacchi 				lmmedium |= LM_MEDIUM_SPEED_100MBPS
587*eef4f27bSRobert Mustacchi 				    | LM_MEDIUM_HALF_DUPLEX;
588*eef4f27bSRobert Mustacchi 
589*eef4f27bSRobert Mustacchi 				if (umdevice->curcfg.lnkcfg.param_10fdx ==
590*eef4f27bSRobert Mustacchi 				    B_TRUE &&
591*eef4f27bSRobert Mustacchi 				    umdevice->curcfg.lnkcfg.param_10hdx ==
592*eef4f27bSRobert Mustacchi 				    B_TRUE) {
593*eef4f27bSRobert Mustacchi 					lmdevice->params.selective_autoneg =
594*eef4f27bSRobert Mustacchi 					    SELECTIVE_AUTONEG_ENABLE_SLOWER_SPEEDS;
595*eef4f27bSRobert Mustacchi 				}
596*eef4f27bSRobert Mustacchi 			} else if (umdevice->curcfg.lnkcfg.param_10fdx) {
597*eef4f27bSRobert Mustacchi 				lmmedium |= LM_MEDIUM_SPEED_10MBPS
598*eef4f27bSRobert Mustacchi 				    | LM_MEDIUM_FULL_DUPLEX;
599*eef4f27bSRobert Mustacchi 
600*eef4f27bSRobert Mustacchi 				if (umdevice->curcfg.lnkcfg.param_10hdx ==
601*eef4f27bSRobert Mustacchi 				    B_TRUE) {
602*eef4f27bSRobert Mustacchi 					lmdevice->params.selective_autoneg =
603*eef4f27bSRobert Mustacchi 					    SELECTIVE_AUTONEG_ENABLE_SLOWER_SPEEDS;
604*eef4f27bSRobert Mustacchi 				}
605*eef4f27bSRobert Mustacchi 			} else if (umdevice->curcfg.lnkcfg.param_10hdx) {
606*eef4f27bSRobert Mustacchi 				lmmedium |= LM_MEDIUM_SPEED_10MBPS
607*eef4f27bSRobert Mustacchi 				    | LM_MEDIUM_HALF_DUPLEX;
608*eef4f27bSRobert Mustacchi 			} else {
609*eef4f27bSRobert Mustacchi 				/* Configuration error. */
610*eef4f27bSRobert Mustacchi 				lmdevice->params.selective_autoneg =
611*eef4f27bSRobert Mustacchi 				    SELECTIVE_AUTONEG_OFF;
612*eef4f27bSRobert Mustacchi 				goto error;
613*eef4f27bSRobert Mustacchi 			}
614*eef4f27bSRobert Mustacchi 		}
615*eef4f27bSRobert Mustacchi 	} else {
616*eef4f27bSRobert Mustacchi 		/*
617*eef4f27bSRobert Mustacchi 		 * Forced speeds greater than 100Mbps intentionally omitted.
618*eef4f27bSRobert Mustacchi 		 * Forcing speeds greater than 100Mbps on copper media is
619*eef4f27bSRobert Mustacchi 		 * illegal.
620*eef4f27bSRobert Mustacchi 		 */
621*eef4f27bSRobert Mustacchi 		if (umdevice->curcfg.lnkcfg.param_100fdx) {
622*eef4f27bSRobert Mustacchi 			lmmedium |= LM_MEDIUM_SPEED_100MBPS
623*eef4f27bSRobert Mustacchi 			    | LM_MEDIUM_FULL_DUPLEX;
624*eef4f27bSRobert Mustacchi 		} else if (umdevice->curcfg.lnkcfg.param_100hdx) {
625*eef4f27bSRobert Mustacchi 			lmmedium |= LM_MEDIUM_SPEED_100MBPS
626*eef4f27bSRobert Mustacchi 			    | LM_MEDIUM_HALF_DUPLEX;
627*eef4f27bSRobert Mustacchi 		} else if (umdevice->curcfg.lnkcfg.param_10fdx) {
628*eef4f27bSRobert Mustacchi 			lmmedium |= LM_MEDIUM_SPEED_10MBPS
629*eef4f27bSRobert Mustacchi 			    | LM_MEDIUM_FULL_DUPLEX;
630*eef4f27bSRobert Mustacchi 		} else if (umdevice->curcfg.lnkcfg.param_10hdx) {
631*eef4f27bSRobert Mustacchi 			lmmedium |= LM_MEDIUM_SPEED_10MBPS
632*eef4f27bSRobert Mustacchi 			    | LM_MEDIUM_HALF_DUPLEX;
633*eef4f27bSRobert Mustacchi 		} else {
634*eef4f27bSRobert Mustacchi 			/* Configuration error. */
635*eef4f27bSRobert Mustacchi 			goto error;
636*eef4f27bSRobert Mustacchi 		}
637*eef4f27bSRobert Mustacchi 	}
638*eef4f27bSRobert Mustacchi 
639*eef4f27bSRobert Mustacchi 	return (lmmedium);
640*eef4f27bSRobert Mustacchi 
641*eef4f27bSRobert Mustacchi error:
642*eef4f27bSRobert Mustacchi 	/* Just give them full autoneg. */
643*eef4f27bSRobert Mustacchi 	lmmedium |= LM_MEDIUM_SPEED_AUTONEG;
644*eef4f27bSRobert Mustacchi 
645*eef4f27bSRobert Mustacchi 	return (lmmedium);
646*eef4f27bSRobert Mustacchi } /* bnx_cfg_map_copper */
647*eef4f27bSRobert Mustacchi 
648*eef4f27bSRobert Mustacchi 
649*eef4f27bSRobert Mustacchi 
650*eef4f27bSRobert Mustacchi /*
651*eef4f27bSRobert Mustacchi  * Name:	bnx_cfg_map_phy
652*eef4f27bSRobert Mustacchi  *
653*eef4f27bSRobert Mustacchi  * Input:	ptr to device structure
654*eef4f27bSRobert Mustacchi  *
655*eef4f27bSRobert Mustacchi  * Return:	None
656*eef4f27bSRobert Mustacchi  *
657*eef4f27bSRobert Mustacchi  * Description:	This function is translates user configuration parameter,
658*eef4f27bSRobert Mustacchi  *		ones accessible through 'ndd' commands to LM driver settings.
659*eef4f27bSRobert Mustacchi  *		Driver chooses best possible parameters if conflicting ones
660*eef4f27bSRobert Mustacchi  *		are set by the user.
661*eef4f27bSRobert Mustacchi  */
662*eef4f27bSRobert Mustacchi void
bnx_cfg_map_phy(um_device_t * const umdevice)663*eef4f27bSRobert Mustacchi bnx_cfg_map_phy(um_device_t *const umdevice)
664*eef4f27bSRobert Mustacchi {
665*eef4f27bSRobert Mustacchi 	lm_medium_t lmmedium;
666*eef4f27bSRobert Mustacchi 	lm_device_t *lmdevice;
667*eef4f27bSRobert Mustacchi 	lm_flow_control_t flowctrl;
668*eef4f27bSRobert Mustacchi 
669*eef4f27bSRobert Mustacchi 	lmdevice = &(umdevice->lm_dev);
670*eef4f27bSRobert Mustacchi 
671*eef4f27bSRobert Mustacchi 	/* Disable the remote PHY. */
672*eef4f27bSRobert Mustacchi 	lmdevice->params.enable_remote_phy = 0;
673*eef4f27bSRobert Mustacchi 
674*eef4f27bSRobert Mustacchi 	/* Assume selective autonegotiation is turned off. */
675*eef4f27bSRobert Mustacchi 	lmdevice->params.selective_autoneg = SELECTIVE_AUTONEG_OFF;
676*eef4f27bSRobert Mustacchi 
677*eef4f27bSRobert Mustacchi 	/* FIXME -- Clean up configuration parameters. */
678*eef4f27bSRobert Mustacchi 	if (umdevice->dev_var.isfiber) {
679*eef4f27bSRobert Mustacchi 		lmmedium = bnx_cfg_map_serdes(umdevice);
680*eef4f27bSRobert Mustacchi 	} else {
681*eef4f27bSRobert Mustacchi 		lmmedium = bnx_cfg_map_copper(umdevice);
682*eef4f27bSRobert Mustacchi 	}
683*eef4f27bSRobert Mustacchi 
684*eef4f27bSRobert Mustacchi 	lmdevice->params.req_medium = lmmedium;
685*eef4f27bSRobert Mustacchi 
686*eef4f27bSRobert Mustacchi 
687*eef4f27bSRobert Mustacchi 	flowctrl = LM_FLOW_CONTROL_NONE;
688*eef4f27bSRobert Mustacchi 
689*eef4f27bSRobert Mustacchi 	if (umdevice->curcfg.lnkcfg.param_tx_pause) {
690*eef4f27bSRobert Mustacchi 		flowctrl |= LM_FLOW_CONTROL_TRANSMIT_PAUSE;
691*eef4f27bSRobert Mustacchi 	}
692*eef4f27bSRobert Mustacchi 
693*eef4f27bSRobert Mustacchi 	if (umdevice->curcfg.lnkcfg.param_rx_pause) {
694*eef4f27bSRobert Mustacchi 		flowctrl |= LM_FLOW_CONTROL_RECEIVE_PAUSE;
695*eef4f27bSRobert Mustacchi 	}
696*eef4f27bSRobert Mustacchi 
697*eef4f27bSRobert Mustacchi 	if (umdevice->curcfg.flow_autoneg == B_TRUE &&
698*eef4f27bSRobert Mustacchi 	    flowctrl != LM_FLOW_CONTROL_NONE) {
699*eef4f27bSRobert Mustacchi 		/*
700*eef4f27bSRobert Mustacchi 		 * FIXME -- LM Flow control constraint.
701*eef4f27bSRobert Mustacchi 		 * LM_FLOW_CONTROL_AUTO_PAUSE ==
702*eef4f27bSRobert Mustacchi 		 * (LM_FLOW_CONTROL_AUTO_PAUSE |
703*eef4f27bSRobert Mustacchi 		 * LM_FLOW_CONTROL_TRANSMIT_PAUSE |
704*eef4f27bSRobert Mustacchi 		 * LM_FLOW_CONTROL_RECEIVE_PAUSE)
705*eef4f27bSRobert Mustacchi 		 * The LM does not allow us finer selection of what
706*eef4f27bSRobert Mustacchi 		 * pause features to autoneg.
707*eef4f27bSRobert Mustacchi 		 */
708*eef4f27bSRobert Mustacchi 		flowctrl |= LM_FLOW_CONTROL_AUTO_PAUSE;
709*eef4f27bSRobert Mustacchi 	}
710*eef4f27bSRobert Mustacchi 
711*eef4f27bSRobert Mustacchi 	lmdevice->params.flow_ctrl_cap = flowctrl;
712*eef4f27bSRobert Mustacchi 
713*eef4f27bSRobert Mustacchi 	lmdevice->params.wire_speed = umdevice->curcfg.wirespeed;
714*eef4f27bSRobert Mustacchi } /* bnx_cfg_map_phy */
715