1*56b2bdd1SGireesh Nagabhushana /*
2*56b2bdd1SGireesh Nagabhushana  * This file and its contents are supplied under the terms of the
3*56b2bdd1SGireesh Nagabhushana  * Common Development and Distribution License ("CDDL"), version 1.0.
4*56b2bdd1SGireesh Nagabhushana  * You may only use this file in accordance with the terms of version
5*56b2bdd1SGireesh Nagabhushana  * 1.0 of the CDDL.
6*56b2bdd1SGireesh Nagabhushana  *
7*56b2bdd1SGireesh Nagabhushana  * A full copy of the text of the CDDL should have accompanied this
8*56b2bdd1SGireesh Nagabhushana  * source. A copy of the CDDL is also available via the Internet at
9*56b2bdd1SGireesh Nagabhushana  * http://www.illumos.org/license/CDDL.
10*56b2bdd1SGireesh Nagabhushana  */
11*56b2bdd1SGireesh Nagabhushana 
12*56b2bdd1SGireesh Nagabhushana /*
13*56b2bdd1SGireesh Nagabhushana  * This file is part of the Chelsio T4 support code.
14*56b2bdd1SGireesh Nagabhushana  *
15*56b2bdd1SGireesh Nagabhushana  * Copyright (C) 2010-2013 Chelsio Communications.  All rights reserved.
16*56b2bdd1SGireesh Nagabhushana  *
17*56b2bdd1SGireesh Nagabhushana  * This program is distributed in the hope that it will be useful, but WITHOUT
18*56b2bdd1SGireesh Nagabhushana  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19*56b2bdd1SGireesh Nagabhushana  * FITNESS FOR A PARTICULAR PURPOSE.  See the LICENSE file included in this
20*56b2bdd1SGireesh Nagabhushana  * release for licensing terms and conditions.
21*56b2bdd1SGireesh Nagabhushana  */
22*56b2bdd1SGireesh Nagabhushana 
23*56b2bdd1SGireesh Nagabhushana #include <sys/ddi.h>
24*56b2bdd1SGireesh Nagabhushana #include <sys/sunddi.h>
25*56b2bdd1SGireesh Nagabhushana #include <sys/dlpi.h>
26*56b2bdd1SGireesh Nagabhushana #include <sys/mac_provider.h>
27*56b2bdd1SGireesh Nagabhushana #include <sys/mac_ether.h>
28*56b2bdd1SGireesh Nagabhushana #include <sys/strsubr.h>
29*56b2bdd1SGireesh Nagabhushana #include <sys/queue.h>
30*56b2bdd1SGireesh Nagabhushana 
31*56b2bdd1SGireesh Nagabhushana #include "common/common.h"
32*56b2bdd1SGireesh Nagabhushana #include "common/t4_regs.h"
33*56b2bdd1SGireesh Nagabhushana 
34*56b2bdd1SGireesh Nagabhushana static int t4_mc_getstat(void *arg, uint_t stat, uint64_t *val);
35*56b2bdd1SGireesh Nagabhushana static int t4_mc_start(void *arg);
36*56b2bdd1SGireesh Nagabhushana static void t4_mc_stop(void *arg);
37*56b2bdd1SGireesh Nagabhushana static int t4_mc_setpromisc(void *arg, boolean_t on);
38*56b2bdd1SGireesh Nagabhushana static int t4_mc_multicst(void *arg, boolean_t add, const uint8_t *mcaddr);
39*56b2bdd1SGireesh Nagabhushana static int t4_mc_unicst(void *arg, const uint8_t *ucaddr);
40*56b2bdd1SGireesh Nagabhushana static mblk_t *t4_mc_tx(void *arg, mblk_t *m);
41*56b2bdd1SGireesh Nagabhushana static boolean_t t4_mc_getcapab(void *arg, mac_capab_t cap, void *data);
42*56b2bdd1SGireesh Nagabhushana static int t4_mc_setprop(void *arg, const char *name, mac_prop_id_t id,
43*56b2bdd1SGireesh Nagabhushana     uint_t size, const void *val);
44*56b2bdd1SGireesh Nagabhushana static int t4_mc_getprop(void *arg, const char *name, mac_prop_id_t id,
45*56b2bdd1SGireesh Nagabhushana     uint_t size, void *val);
46*56b2bdd1SGireesh Nagabhushana static void t4_mc_propinfo(void *arg, const char *name, mac_prop_id_t id,
47*56b2bdd1SGireesh Nagabhushana     mac_prop_info_handle_t ph);
48*56b2bdd1SGireesh Nagabhushana 
49*56b2bdd1SGireesh Nagabhushana static int begin_synchronized_op(struct port_info *pi, int hold, int waitok);
50*56b2bdd1SGireesh Nagabhushana static void end_synchronized_op(struct port_info *pi, int held);
51*56b2bdd1SGireesh Nagabhushana static int t4_init_synchronized(struct port_info *pi);
52*56b2bdd1SGireesh Nagabhushana static int t4_uninit_synchronized(struct port_info *pi);
53*56b2bdd1SGireesh Nagabhushana static void propinfo(struct port_info *pi, const char *name,
54*56b2bdd1SGireesh Nagabhushana     mac_prop_info_handle_t ph);
55*56b2bdd1SGireesh Nagabhushana static int getprop(struct port_info *pi, const char *name, uint_t size,
56*56b2bdd1SGireesh Nagabhushana     void *val);
57*56b2bdd1SGireesh Nagabhushana static int setprop(struct port_info *pi, const char *name, const void *val);
58*56b2bdd1SGireesh Nagabhushana 
59*56b2bdd1SGireesh Nagabhushana mac_callbacks_t t4_m_callbacks = {
60*56b2bdd1SGireesh Nagabhushana 	.mc_callbacks	= MC_GETCAPAB | MC_PROPERTIES,
61*56b2bdd1SGireesh Nagabhushana 	.mc_getstat	= t4_mc_getstat,
62*56b2bdd1SGireesh Nagabhushana 	.mc_start	= t4_mc_start,
63*56b2bdd1SGireesh Nagabhushana 	.mc_stop	= t4_mc_stop,
64*56b2bdd1SGireesh Nagabhushana 	.mc_setpromisc	= t4_mc_setpromisc,
65*56b2bdd1SGireesh Nagabhushana 	.mc_multicst	= t4_mc_multicst,
66*56b2bdd1SGireesh Nagabhushana 	.mc_unicst	= t4_mc_unicst,
67*56b2bdd1SGireesh Nagabhushana 	.mc_tx		= t4_mc_tx,
68*56b2bdd1SGireesh Nagabhushana 	.mc_getcapab	= t4_mc_getcapab,
69*56b2bdd1SGireesh Nagabhushana 	.mc_setprop	= t4_mc_setprop,
70*56b2bdd1SGireesh Nagabhushana 	.mc_getprop	= t4_mc_getprop,
71*56b2bdd1SGireesh Nagabhushana 	.mc_propinfo	= t4_mc_propinfo,
72*56b2bdd1SGireesh Nagabhushana };
73*56b2bdd1SGireesh Nagabhushana 
74*56b2bdd1SGireesh Nagabhushana #define	T4PROP_TMR_IDX "_holdoff_timer_idx"
75*56b2bdd1SGireesh Nagabhushana #define	T4PROP_PKTC_IDX "_holdoff_pktc_idx"
76*56b2bdd1SGireesh Nagabhushana #define	T4PROP_MTU "_mtu"
77*56b2bdd1SGireesh Nagabhushana #define	T4PROP_HW_CSUM	"_hw_csum"
78*56b2bdd1SGireesh Nagabhushana #define	T4PROP_HW_LSO	"_hw_lso"
79*56b2bdd1SGireesh Nagabhushana #define	T4PROP_TX_PAUSE	"_tx_pause"
80*56b2bdd1SGireesh Nagabhushana #define	T4PROP_RX_PAUSE	"_rx_pause"
81*56b2bdd1SGireesh Nagabhushana 
82*56b2bdd1SGireesh Nagabhushana char *t4_priv_props[] = {
83*56b2bdd1SGireesh Nagabhushana 	T4PROP_TMR_IDX,
84*56b2bdd1SGireesh Nagabhushana 	T4PROP_PKTC_IDX,
85*56b2bdd1SGireesh Nagabhushana #if MAC_VERSION == 1
86*56b2bdd1SGireesh Nagabhushana 	/* MAC_VERSION 1 doesn't seem to use MAC_PROP_MTU, hmmmm */
87*56b2bdd1SGireesh Nagabhushana 	T4PROP_MTU,
88*56b2bdd1SGireesh Nagabhushana #endif
89*56b2bdd1SGireesh Nagabhushana 	T4PROP_HW_CSUM,
90*56b2bdd1SGireesh Nagabhushana 	T4PROP_HW_LSO,
91*56b2bdd1SGireesh Nagabhushana 	T4PROP_TX_PAUSE,
92*56b2bdd1SGireesh Nagabhushana 	T4PROP_RX_PAUSE,
93*56b2bdd1SGireesh Nagabhushana 	NULL
94*56b2bdd1SGireesh Nagabhushana };
95*56b2bdd1SGireesh Nagabhushana 
96*56b2bdd1SGireesh Nagabhushana static int
97*56b2bdd1SGireesh Nagabhushana t4_mc_getstat(void *arg, uint_t stat, uint64_t *val)
98*56b2bdd1SGireesh Nagabhushana {
99*56b2bdd1SGireesh Nagabhushana 	struct port_info *pi = arg;
100*56b2bdd1SGireesh Nagabhushana 	struct adapter *sc = pi->adapter;
101*56b2bdd1SGireesh Nagabhushana 	struct link_config *lc = &pi->link_cfg;
102*56b2bdd1SGireesh Nagabhushana 
103*56b2bdd1SGireesh Nagabhushana #define	GET_STAT(name) \
104*56b2bdd1SGireesh Nagabhushana 	t4_read_reg64(sc, PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_##name##_L))
105*56b2bdd1SGireesh Nagabhushana 
106*56b2bdd1SGireesh Nagabhushana 	switch (stat) {
107*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_IFSPEED:
108*56b2bdd1SGireesh Nagabhushana 		if (lc->link_ok != 0) {
109*56b2bdd1SGireesh Nagabhushana 			*val = lc->speed;
110*56b2bdd1SGireesh Nagabhushana 			*val *= 1000000;
111*56b2bdd1SGireesh Nagabhushana 		} else
112*56b2bdd1SGireesh Nagabhushana 			*val = 0;
113*56b2bdd1SGireesh Nagabhushana 		break;
114*56b2bdd1SGireesh Nagabhushana 
115*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_MULTIRCV:
116*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(RX_PORT_MCAST);
117*56b2bdd1SGireesh Nagabhushana 		break;
118*56b2bdd1SGireesh Nagabhushana 
119*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_BRDCSTRCV:
120*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(RX_PORT_BCAST);
121*56b2bdd1SGireesh Nagabhushana 		break;
122*56b2bdd1SGireesh Nagabhushana 
123*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_MULTIXMT:
124*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(TX_PORT_MCAST);
125*56b2bdd1SGireesh Nagabhushana 		break;
126*56b2bdd1SGireesh Nagabhushana 
127*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_BRDCSTXMT:
128*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(TX_PORT_BCAST);
129*56b2bdd1SGireesh Nagabhushana 		break;
130*56b2bdd1SGireesh Nagabhushana 
131*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_NORCVBUF:
132*56b2bdd1SGireesh Nagabhushana 		*val = 0;	/* TODO should come from rxq->nomem */
133*56b2bdd1SGireesh Nagabhushana 		break;
134*56b2bdd1SGireesh Nagabhushana 
135*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_IERRORS:
136*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(RX_PORT_MTU_ERROR) +
137*56b2bdd1SGireesh Nagabhushana 		    GET_STAT(RX_PORT_MTU_CRC_ERROR) +
138*56b2bdd1SGireesh Nagabhushana 		    GET_STAT(RX_PORT_CRC_ERROR) +
139*56b2bdd1SGireesh Nagabhushana 		    GET_STAT(RX_PORT_LEN_ERROR) +
140*56b2bdd1SGireesh Nagabhushana 		    GET_STAT(RX_PORT_SYM_ERROR) +
141*56b2bdd1SGireesh Nagabhushana 		    GET_STAT(RX_PORT_LESS_64B);
142*56b2bdd1SGireesh Nagabhushana 		break;
143*56b2bdd1SGireesh Nagabhushana 
144*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_UNKNOWNS:
145*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
146*56b2bdd1SGireesh Nagabhushana 
147*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_NOXMTBUF:
148*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(TX_PORT_DROP);
149*56b2bdd1SGireesh Nagabhushana 		break;
150*56b2bdd1SGireesh Nagabhushana 
151*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_OERRORS:
152*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(TX_PORT_ERROR);
153*56b2bdd1SGireesh Nagabhushana 		break;
154*56b2bdd1SGireesh Nagabhushana 
155*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_COLLISIONS:
156*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
157*56b2bdd1SGireesh Nagabhushana 
158*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_RBYTES:
159*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(RX_PORT_BYTES);
160*56b2bdd1SGireesh Nagabhushana 		break;
161*56b2bdd1SGireesh Nagabhushana 
162*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_IPACKETS:
163*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(RX_PORT_FRAMES);
164*56b2bdd1SGireesh Nagabhushana 		break;
165*56b2bdd1SGireesh Nagabhushana 
166*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_OBYTES:
167*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(TX_PORT_BYTES);
168*56b2bdd1SGireesh Nagabhushana 		break;
169*56b2bdd1SGireesh Nagabhushana 
170*56b2bdd1SGireesh Nagabhushana 	case MAC_STAT_OPACKETS:
171*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(TX_PORT_FRAMES);
172*56b2bdd1SGireesh Nagabhushana 		break;
173*56b2bdd1SGireesh Nagabhushana 
174*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_ALIGN_ERRORS:
175*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
176*56b2bdd1SGireesh Nagabhushana 
177*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_FCS_ERRORS:
178*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(RX_PORT_CRC_ERROR);
179*56b2bdd1SGireesh Nagabhushana 		break;
180*56b2bdd1SGireesh Nagabhushana 
181*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_FIRST_COLLISIONS:
182*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_MULTI_COLLISIONS:
183*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_SQE_ERRORS:
184*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_DEFER_XMTS:
185*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_TX_LATE_COLLISIONS:
186*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_EX_COLLISIONS:
187*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
188*56b2bdd1SGireesh Nagabhushana 
189*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_MACXMT_ERRORS:
190*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(TX_PORT_ERROR);
191*56b2bdd1SGireesh Nagabhushana 		break;
192*56b2bdd1SGireesh Nagabhushana 
193*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_CARRIER_ERRORS:
194*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
195*56b2bdd1SGireesh Nagabhushana 
196*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_TOOLONG_ERRORS:
197*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(RX_PORT_MTU_ERROR);
198*56b2bdd1SGireesh Nagabhushana 		break;
199*56b2bdd1SGireesh Nagabhushana 
200*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_MACRCV_ERRORS:
201*56b2bdd1SGireesh Nagabhushana 		*val = GET_STAT(RX_PORT_MTU_ERROR) +
202*56b2bdd1SGireesh Nagabhushana 		    GET_STAT(RX_PORT_MTU_CRC_ERROR) +
203*56b2bdd1SGireesh Nagabhushana 		    GET_STAT(RX_PORT_CRC_ERROR) +
204*56b2bdd1SGireesh Nagabhushana 		    GET_STAT(RX_PORT_LEN_ERROR) +
205*56b2bdd1SGireesh Nagabhushana 		    GET_STAT(RX_PORT_SYM_ERROR) +
206*56b2bdd1SGireesh Nagabhushana 		    GET_STAT(RX_PORT_LESS_64B);
207*56b2bdd1SGireesh Nagabhushana 		break;
208*56b2bdd1SGireesh Nagabhushana 
209*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_XCVR_ADDR:
210*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_XCVR_ID:
211*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_XCVR_INUSE:
212*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
213*56b2bdd1SGireesh Nagabhushana 
214*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_CAP_1000FDX:
215*56b2bdd1SGireesh Nagabhushana 		*val = !!(lc->supported & FW_PORT_CAP_SPEED_1G);
216*56b2bdd1SGireesh Nagabhushana 		break;
217*56b2bdd1SGireesh Nagabhushana 
218*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_CAP_1000HDX:
219*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
220*56b2bdd1SGireesh Nagabhushana 
221*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_CAP_100FDX:
222*56b2bdd1SGireesh Nagabhushana 		*val = !!(lc->supported & FW_PORT_CAP_SPEED_100M);
223*56b2bdd1SGireesh Nagabhushana 		break;
224*56b2bdd1SGireesh Nagabhushana 
225*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_CAP_100HDX:
226*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
227*56b2bdd1SGireesh Nagabhushana 
228*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_CAP_10FDX:
229*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_CAP_10HDX:
230*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
231*56b2bdd1SGireesh Nagabhushana 
232*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_CAP_ASMPAUSE:
233*56b2bdd1SGireesh Nagabhushana 		*val = 0;
234*56b2bdd1SGireesh Nagabhushana 		break;
235*56b2bdd1SGireesh Nagabhushana 
236*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_CAP_PAUSE:
237*56b2bdd1SGireesh Nagabhushana 		*val = 1;
238*56b2bdd1SGireesh Nagabhushana 		break;
239*56b2bdd1SGireesh Nagabhushana 
240*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_CAP_AUTONEG:
241*56b2bdd1SGireesh Nagabhushana 		*val = !!(lc->supported & FW_PORT_CAP_ANEG);
242*56b2bdd1SGireesh Nagabhushana 		break;
243*56b2bdd1SGireesh Nagabhushana 
244*56b2bdd1SGireesh Nagabhushana 	/*
245*56b2bdd1SGireesh Nagabhushana 	 * We have set flow control configuration based on tx_pause and rx_pause
246*56b2bdd1SGireesh Nagabhushana 	 * values supported through ndd. Now, we need to translate the settings
247*56b2bdd1SGireesh Nagabhushana 	 * we have in link_config structure to adv_cap_asmpause and
248*56b2bdd1SGireesh Nagabhushana 	 * adv_cap_pause.
249*56b2bdd1SGireesh Nagabhushana 	 *
250*56b2bdd1SGireesh Nagabhushana 	 * There are 4 combinations possible and the translation is as below:
251*56b2bdd1SGireesh Nagabhushana 	 * tx_pause = 0 => We don't send pause frames during Rx congestion
252*56b2bdd1SGireesh Nagabhushana 	 * tx_pause = 1 => We send pause frames during Rx congestion
253*56b2bdd1SGireesh Nagabhushana 	 * rx_pause = 0 => We ignore received pause frames
254*56b2bdd1SGireesh Nagabhushana 	 * rx_pause = 1 => We pause transmission when we receive pause frames
255*56b2bdd1SGireesh Nagabhushana 	 *
256*56b2bdd1SGireesh Nagabhushana 	 * +----------------------------+----------------------------------+
257*56b2bdd1SGireesh Nagabhushana 	 * |  tx_pause	|    rx_pause	| adv_cap_asmpause | adv_cap_pause |
258*56b2bdd1SGireesh Nagabhushana 	 * +-------------------------+-------------------------------------+
259*56b2bdd1SGireesh Nagabhushana 	 * |	0	|	0	|	0	   |	0	   |
260*56b2bdd1SGireesh Nagabhushana 	 * |	0	|	1	|	1	   |	0	   |
261*56b2bdd1SGireesh Nagabhushana 	 * |	1	|	0	|	1	   |	1	   |
262*56b2bdd1SGireesh Nagabhushana 	 * |	1	|	1	|	0	   |	1	   |
263*56b2bdd1SGireesh Nagabhushana 	 * +----------------------------+----------------------------------+
264*56b2bdd1SGireesh Nagabhushana 	 */
265*56b2bdd1SGireesh Nagabhushana 
266*56b2bdd1SGireesh Nagabhushana 	/* Advertised asymmetric pause capability */
267*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
268*56b2bdd1SGireesh Nagabhushana 		*val = (((lc->requested_fc & PAUSE_TX) ? 1 : 0) ^
269*56b2bdd1SGireesh Nagabhushana 		    (lc->requested_fc & PAUSE_RX));
270*56b2bdd1SGireesh Nagabhushana 		break;
271*56b2bdd1SGireesh Nagabhushana 
272*56b2bdd1SGireesh Nagabhushana 	/* Advertised pause capability */
273*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_ADV_CAP_PAUSE:
274*56b2bdd1SGireesh Nagabhushana 		*val = (lc->requested_fc & PAUSE_TX) ? 1 : 0;
275*56b2bdd1SGireesh Nagabhushana 		break;
276*56b2bdd1SGireesh Nagabhushana 
277*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_ADV_CAP_1000FDX:
278*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_ADV_CAP_1000HDX:
279*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_ADV_CAP_100FDX:
280*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_ADV_CAP_100HDX:
281*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_ADV_CAP_10FDX:
282*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_ADV_CAP_10HDX:
283*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_ADV_CAP_AUTONEG:
284*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);	/* TODO */
285*56b2bdd1SGireesh Nagabhushana 
286*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_LP_CAP_1000FDX:
287*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_LP_CAP_1000HDX:
288*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_LP_CAP_100FDX:
289*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_LP_CAP_100HDX:
290*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_LP_CAP_10FDX:
291*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_LP_CAP_10HDX:
292*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_LP_CAP_ASMPAUSE:
293*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_LP_CAP_PAUSE:
294*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_LP_CAP_AUTONEG:
295*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
296*56b2bdd1SGireesh Nagabhushana 
297*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_LINK_ASMPAUSE:
298*56b2bdd1SGireesh Nagabhushana 		*val = 0;
299*56b2bdd1SGireesh Nagabhushana 		break;
300*56b2bdd1SGireesh Nagabhushana 
301*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_LINK_PAUSE:
302*56b2bdd1SGireesh Nagabhushana 		*val = 1;
303*56b2bdd1SGireesh Nagabhushana 		break;
304*56b2bdd1SGireesh Nagabhushana 
305*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_LINK_AUTONEG:
306*56b2bdd1SGireesh Nagabhushana 		*val = lc->autoneg == AUTONEG_ENABLE;
307*56b2bdd1SGireesh Nagabhushana 		break;
308*56b2bdd1SGireesh Nagabhushana 
309*56b2bdd1SGireesh Nagabhushana 	case ETHER_STAT_LINK_DUPLEX:
310*56b2bdd1SGireesh Nagabhushana 		if (lc->link_ok != 0)
311*56b2bdd1SGireesh Nagabhushana 			*val = LINK_DUPLEX_FULL;
312*56b2bdd1SGireesh Nagabhushana 		else
313*56b2bdd1SGireesh Nagabhushana 			*val = LINK_DUPLEX_UNKNOWN;
314*56b2bdd1SGireesh Nagabhushana 		break;
315*56b2bdd1SGireesh Nagabhushana 
316*56b2bdd1SGireesh Nagabhushana 	default:
317*56b2bdd1SGireesh Nagabhushana #ifdef DEBUG
318*56b2bdd1SGireesh Nagabhushana 		cxgb_printf(pi->dip, CE_NOTE, "stat %d not implemented.", stat);
319*56b2bdd1SGireesh Nagabhushana #endif
320*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
321*56b2bdd1SGireesh Nagabhushana 	}
322*56b2bdd1SGireesh Nagabhushana #undef GET_STAT
323*56b2bdd1SGireesh Nagabhushana 
324*56b2bdd1SGireesh Nagabhushana 	return (0);
325*56b2bdd1SGireesh Nagabhushana }
326*56b2bdd1SGireesh Nagabhushana 
327*56b2bdd1SGireesh Nagabhushana static int
328*56b2bdd1SGireesh Nagabhushana t4_mc_start(void *arg)
329*56b2bdd1SGireesh Nagabhushana {
330*56b2bdd1SGireesh Nagabhushana 	struct port_info *pi = arg;
331*56b2bdd1SGireesh Nagabhushana 	int rc;
332*56b2bdd1SGireesh Nagabhushana 
333*56b2bdd1SGireesh Nagabhushana 	rc = begin_synchronized_op(pi, 0, 1);
334*56b2bdd1SGireesh Nagabhushana 	if (rc != 0)
335*56b2bdd1SGireesh Nagabhushana 		return (rc);
336*56b2bdd1SGireesh Nagabhushana 	rc = t4_init_synchronized(pi);
337*56b2bdd1SGireesh Nagabhushana 	end_synchronized_op(pi, 0);
338*56b2bdd1SGireesh Nagabhushana 
339*56b2bdd1SGireesh Nagabhushana 	return (rc);
340*56b2bdd1SGireesh Nagabhushana }
341*56b2bdd1SGireesh Nagabhushana 
342*56b2bdd1SGireesh Nagabhushana static void
343*56b2bdd1SGireesh Nagabhushana t4_mc_stop(void *arg)
344*56b2bdd1SGireesh Nagabhushana {
345*56b2bdd1SGireesh Nagabhushana 	struct port_info *pi = arg;
346*56b2bdd1SGireesh Nagabhushana 
347*56b2bdd1SGireesh Nagabhushana 	while (begin_synchronized_op(pi, 0, 1) != 0)
348*56b2bdd1SGireesh Nagabhushana 		continue;
349*56b2bdd1SGireesh Nagabhushana 	(void) t4_uninit_synchronized(pi);
350*56b2bdd1SGireesh Nagabhushana 	end_synchronized_op(pi, 0);
351*56b2bdd1SGireesh Nagabhushana }
352*56b2bdd1SGireesh Nagabhushana 
353*56b2bdd1SGireesh Nagabhushana static int
354*56b2bdd1SGireesh Nagabhushana t4_mc_setpromisc(void *arg, boolean_t on)
355*56b2bdd1SGireesh Nagabhushana {
356*56b2bdd1SGireesh Nagabhushana 	struct port_info *pi = arg;
357*56b2bdd1SGireesh Nagabhushana 	struct adapter *sc = pi->adapter;
358*56b2bdd1SGireesh Nagabhushana 	int rc;
359*56b2bdd1SGireesh Nagabhushana 
360*56b2bdd1SGireesh Nagabhushana 	rc = begin_synchronized_op(pi, 1, 1);
361*56b2bdd1SGireesh Nagabhushana 	if (rc != 0)
362*56b2bdd1SGireesh Nagabhushana 		return (rc);
363*56b2bdd1SGireesh Nagabhushana 	rc = -t4_set_rxmode(sc, sc->mbox, pi->viid, -1, on ? 1 : 0, -1, -1, -1,
364*56b2bdd1SGireesh Nagabhushana 	    false);
365*56b2bdd1SGireesh Nagabhushana 	end_synchronized_op(pi, 1);
366*56b2bdd1SGireesh Nagabhushana 
367*56b2bdd1SGireesh Nagabhushana 	return (rc);
368*56b2bdd1SGireesh Nagabhushana }
369*56b2bdd1SGireesh Nagabhushana 
370*56b2bdd1SGireesh Nagabhushana /*
371*56b2bdd1SGireesh Nagabhushana  * TODO: Starts failing as soon as the 336 entry table fills up.  Need to use
372*56b2bdd1SGireesh Nagabhushana  * hash in that case.
373*56b2bdd1SGireesh Nagabhushana  */
374*56b2bdd1SGireesh Nagabhushana static int
375*56b2bdd1SGireesh Nagabhushana t4_mc_multicst(void *arg, boolean_t add, const uint8_t *mcaddr)
376*56b2bdd1SGireesh Nagabhushana {
377*56b2bdd1SGireesh Nagabhushana 	struct port_info *pi = arg;
378*56b2bdd1SGireesh Nagabhushana 	struct adapter *sc = pi->adapter;
379*56b2bdd1SGireesh Nagabhushana 	struct fw_vi_mac_cmd c;
380*56b2bdd1SGireesh Nagabhushana 	int len16, rc;
381*56b2bdd1SGireesh Nagabhushana 
382*56b2bdd1SGireesh Nagabhushana 	len16 = howmany(sizeof (c.op_to_viid) + sizeof (c.freemacs_to_len16) +
383*56b2bdd1SGireesh Nagabhushana 	    sizeof (c.u.exact[0]), 16);
384*56b2bdd1SGireesh Nagabhushana 	c.op_to_viid = htonl(V_FW_CMD_OP(FW_VI_MAC_CMD) | F_FW_CMD_REQUEST |
385*56b2bdd1SGireesh Nagabhushana 	    F_FW_CMD_WRITE | V_FW_VI_MAC_CMD_VIID(pi->viid));
386*56b2bdd1SGireesh Nagabhushana 	c.freemacs_to_len16 = htonl(V_FW_CMD_LEN16(len16));
387*56b2bdd1SGireesh Nagabhushana 	c.u.exact[0].valid_to_idx = htons(F_FW_VI_MAC_CMD_VALID |
388*56b2bdd1SGireesh Nagabhushana 	    V_FW_VI_MAC_CMD_IDX(add ? FW_VI_MAC_ADD_MAC :
389*56b2bdd1SGireesh Nagabhushana 	    FW_VI_MAC_MAC_BASED_FREE));
390*56b2bdd1SGireesh Nagabhushana 	bcopy(mcaddr, &c.u.exact[0].macaddr, ETHERADDRL);
391*56b2bdd1SGireesh Nagabhushana 
392*56b2bdd1SGireesh Nagabhushana 	rc = begin_synchronized_op(pi, 1, 1);
393*56b2bdd1SGireesh Nagabhushana 	if (rc != 0)
394*56b2bdd1SGireesh Nagabhushana 		return (rc);
395*56b2bdd1SGireesh Nagabhushana 	rc = -t4_wr_mbox_meat(sc, sc->mbox, &c, len16 * 16, &c, true);
396*56b2bdd1SGireesh Nagabhushana 	end_synchronized_op(pi, 1);
397*56b2bdd1SGireesh Nagabhushana 	if (rc != 0)
398*56b2bdd1SGireesh Nagabhushana 		return (rc);
399*56b2bdd1SGireesh Nagabhushana #ifdef DEBUG
400*56b2bdd1SGireesh Nagabhushana 	/*
401*56b2bdd1SGireesh Nagabhushana 	 * TODO: Firmware doesn't seem to return the correct index on removal
402*56b2bdd1SGireesh Nagabhushana 	 * (it gives back 0x3fd FW_VI_MAC_MAC_BASED_FREE unchanged. Remove this
403*56b2bdd1SGireesh Nagabhushana 	 * code once it is fixed.
404*56b2bdd1SGireesh Nagabhushana 	 */
405*56b2bdd1SGireesh Nagabhushana 	else {
406*56b2bdd1SGireesh Nagabhushana 		uint16_t idx;
407*56b2bdd1SGireesh Nagabhushana 
408*56b2bdd1SGireesh Nagabhushana 		idx = G_FW_VI_MAC_CMD_IDX(ntohs(c.u.exact[0].valid_to_idx));
409*56b2bdd1SGireesh Nagabhushana 		cxgb_printf(pi->dip, CE_NOTE,
410*56b2bdd1SGireesh Nagabhushana 		    "%02x:%02x:%02x:%02x:%02x:%02x %s %d", mcaddr[0],
411*56b2bdd1SGireesh Nagabhushana 		    mcaddr[1], mcaddr[2], mcaddr[3], mcaddr[4], mcaddr[5],
412*56b2bdd1SGireesh Nagabhushana 		    add ? "added at index" : "removed from index", idx);
413*56b2bdd1SGireesh Nagabhushana 	}
414*56b2bdd1SGireesh Nagabhushana #endif
415*56b2bdd1SGireesh Nagabhushana 
416*56b2bdd1SGireesh Nagabhushana 	return (0);
417*56b2bdd1SGireesh Nagabhushana }
418*56b2bdd1SGireesh Nagabhushana 
419*56b2bdd1SGireesh Nagabhushana static int
420*56b2bdd1SGireesh Nagabhushana t4_mc_unicst(void *arg, const uint8_t *ucaddr)
421*56b2bdd1SGireesh Nagabhushana {
422*56b2bdd1SGireesh Nagabhushana 	struct port_info *pi = arg;
423*56b2bdd1SGireesh Nagabhushana 	struct adapter *sc = pi->adapter;
424*56b2bdd1SGireesh Nagabhushana 	int rc;
425*56b2bdd1SGireesh Nagabhushana 
426*56b2bdd1SGireesh Nagabhushana 	rc = begin_synchronized_op(pi, 1, 1);
427*56b2bdd1SGireesh Nagabhushana 	if (rc != 0)
428*56b2bdd1SGireesh Nagabhushana 		return (rc);
429*56b2bdd1SGireesh Nagabhushana 	rc = t4_change_mac(sc, sc->mbox, pi->viid, pi->xact_addr_filt, ucaddr,
430*56b2bdd1SGireesh Nagabhushana 	    true, true);
431*56b2bdd1SGireesh Nagabhushana 	if (rc < 0)
432*56b2bdd1SGireesh Nagabhushana 		rc = -rc;
433*56b2bdd1SGireesh Nagabhushana 	else {
434*56b2bdd1SGireesh Nagabhushana 		/* LINTED: E_CONSTANT_CONDITION */
435*56b2bdd1SGireesh Nagabhushana 		pi->xact_addr_filt = rc;
436*56b2bdd1SGireesh Nagabhushana 		rc = 0;
437*56b2bdd1SGireesh Nagabhushana 	}
438*56b2bdd1SGireesh Nagabhushana 	end_synchronized_op(pi, 1);
439*56b2bdd1SGireesh Nagabhushana 
440*56b2bdd1SGireesh Nagabhushana 	return (rc);
441*56b2bdd1SGireesh Nagabhushana }
442*56b2bdd1SGireesh Nagabhushana 
443*56b2bdd1SGireesh Nagabhushana static mblk_t *
444*56b2bdd1SGireesh Nagabhushana t4_mc_tx(void *arg, mblk_t *m)
445*56b2bdd1SGireesh Nagabhushana {
446*56b2bdd1SGireesh Nagabhushana 	struct port_info *pi = arg;
447*56b2bdd1SGireesh Nagabhushana 	struct adapter *sc = pi->adapter;
448*56b2bdd1SGireesh Nagabhushana 	struct sge_txq *txq = &sc->sge.txq[pi->first_txq];
449*56b2bdd1SGireesh Nagabhushana 
450*56b2bdd1SGireesh Nagabhushana 	return (t4_eth_tx(pi, txq, m));
451*56b2bdd1SGireesh Nagabhushana }
452*56b2bdd1SGireesh Nagabhushana 
453*56b2bdd1SGireesh Nagabhushana static boolean_t
454*56b2bdd1SGireesh Nagabhushana t4_mc_getcapab(void *arg, mac_capab_t cap, void *data)
455*56b2bdd1SGireesh Nagabhushana {
456*56b2bdd1SGireesh Nagabhushana 	struct port_info *pi = arg;
457*56b2bdd1SGireesh Nagabhushana 	boolean_t status = B_TRUE;
458*56b2bdd1SGireesh Nagabhushana 
459*56b2bdd1SGireesh Nagabhushana 	switch (cap) {
460*56b2bdd1SGireesh Nagabhushana 	case MAC_CAPAB_HCKSUM:
461*56b2bdd1SGireesh Nagabhushana 		if (pi->features & CXGBE_HW_CSUM) {
462*56b2bdd1SGireesh Nagabhushana 			uint32_t *d = data;
463*56b2bdd1SGireesh Nagabhushana 			*d = HCKSUM_INET_FULL_V4 | HCKSUM_IPHDRCKSUM;
464*56b2bdd1SGireesh Nagabhushana 		} else
465*56b2bdd1SGireesh Nagabhushana 			status = B_FALSE;
466*56b2bdd1SGireesh Nagabhushana 		break;
467*56b2bdd1SGireesh Nagabhushana 
468*56b2bdd1SGireesh Nagabhushana 	case MAC_CAPAB_LSO:
469*56b2bdd1SGireesh Nagabhushana 		/* Enabling LSO requires Checksum offloading */
470*56b2bdd1SGireesh Nagabhushana 		if (pi->features & CXGBE_HW_LSO &&
471*56b2bdd1SGireesh Nagabhushana 		    pi->features & CXGBE_HW_CSUM) {
472*56b2bdd1SGireesh Nagabhushana 			mac_capab_lso_t *d = data;
473*56b2bdd1SGireesh Nagabhushana 
474*56b2bdd1SGireesh Nagabhushana 			d->lso_flags = LSO_TX_BASIC_TCP_IPV4;
475*56b2bdd1SGireesh Nagabhushana 			d->lso_basic_tcp_ipv4.lso_max = 65535;
476*56b2bdd1SGireesh Nagabhushana 		} else
477*56b2bdd1SGireesh Nagabhushana 			status = B_FALSE;
478*56b2bdd1SGireesh Nagabhushana 		break;
479*56b2bdd1SGireesh Nagabhushana 
480*56b2bdd1SGireesh Nagabhushana 	default:
481*56b2bdd1SGireesh Nagabhushana 		status = B_FALSE; /* cap not supported */
482*56b2bdd1SGireesh Nagabhushana 	}
483*56b2bdd1SGireesh Nagabhushana 
484*56b2bdd1SGireesh Nagabhushana 	return (status);
485*56b2bdd1SGireesh Nagabhushana }
486*56b2bdd1SGireesh Nagabhushana 
487*56b2bdd1SGireesh Nagabhushana /* ARGSUSED */
488*56b2bdd1SGireesh Nagabhushana static int
489*56b2bdd1SGireesh Nagabhushana t4_mc_setprop(void *arg, const char *name, mac_prop_id_t id, uint_t size,
490*56b2bdd1SGireesh Nagabhushana     const void *val)
491*56b2bdd1SGireesh Nagabhushana {
492*56b2bdd1SGireesh Nagabhushana 	struct port_info *pi = arg;
493*56b2bdd1SGireesh Nagabhushana 	struct adapter *sc = pi->adapter;
494*56b2bdd1SGireesh Nagabhushana 	struct link_config lc_copy, *lc = &pi->link_cfg;
495*56b2bdd1SGireesh Nagabhushana 	uint8_t v8 = *(uint8_t *)val;
496*56b2bdd1SGireesh Nagabhushana 	uint32_t v32 = *(uint32_t *)val;
497*56b2bdd1SGireesh Nagabhushana 	int old, new = 0, relink = 0, rx_mode = 0, rc = 0;
498*56b2bdd1SGireesh Nagabhushana 	link_flowctrl_t fc;
499*56b2bdd1SGireesh Nagabhushana 
500*56b2bdd1SGireesh Nagabhushana 	/*
501*56b2bdd1SGireesh Nagabhushana 	 * Save a copy of link_config. This can be used to restore link_config
502*56b2bdd1SGireesh Nagabhushana 	 * if t4_link_start() fails.
503*56b2bdd1SGireesh Nagabhushana 	 */
504*56b2bdd1SGireesh Nagabhushana 	bcopy(lc, &lc_copy, sizeof (struct link_config));
505*56b2bdd1SGireesh Nagabhushana 
506*56b2bdd1SGireesh Nagabhushana 	switch (id) {
507*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_AUTONEG:
508*56b2bdd1SGireesh Nagabhushana 		if (lc->supported & FW_PORT_CAP_ANEG) {
509*56b2bdd1SGireesh Nagabhushana 			old = lc->autoneg;
510*56b2bdd1SGireesh Nagabhushana 			new = v8 ? AUTONEG_ENABLE : AUTONEG_DISABLE;
511*56b2bdd1SGireesh Nagabhushana 			if (old != new) {
512*56b2bdd1SGireesh Nagabhushana 				/* LINTED: E_CONSTANT_CONDITION */
513*56b2bdd1SGireesh Nagabhushana 				lc->autoneg = new;
514*56b2bdd1SGireesh Nagabhushana 				relink = 1;
515*56b2bdd1SGireesh Nagabhushana 				if (new == AUTONEG_DISABLE) {
516*56b2bdd1SGireesh Nagabhushana 					/* Only 100M is available */
517*56b2bdd1SGireesh Nagabhushana 					lc->requested_speed =
518*56b2bdd1SGireesh Nagabhushana 					    FW_PORT_CAP_SPEED_100M;
519*56b2bdd1SGireesh Nagabhushana 					lc->advertising =
520*56b2bdd1SGireesh Nagabhushana 					    FW_PORT_CAP_SPEED_100M;
521*56b2bdd1SGireesh Nagabhushana 				} else {
522*56b2bdd1SGireesh Nagabhushana 					/*
523*56b2bdd1SGireesh Nagabhushana 					 * Advertise autonegotiation capability
524*56b2bdd1SGireesh Nagabhushana 					 * along with supported speeds
525*56b2bdd1SGireesh Nagabhushana 					 */
526*56b2bdd1SGireesh Nagabhushana 					lc->advertising |= (FW_PORT_CAP_ANEG |
527*56b2bdd1SGireesh Nagabhushana 					    (lc->supported &
528*56b2bdd1SGireesh Nagabhushana 					    (FW_PORT_CAP_SPEED_100M |
529*56b2bdd1SGireesh Nagabhushana 					    FW_PORT_CAP_SPEED_1G)));
530*56b2bdd1SGireesh Nagabhushana 					lc->requested_speed = 0;
531*56b2bdd1SGireesh Nagabhushana 				}
532*56b2bdd1SGireesh Nagabhushana 			}
533*56b2bdd1SGireesh Nagabhushana 		} else
534*56b2bdd1SGireesh Nagabhushana 			rc = ENOTSUP;
535*56b2bdd1SGireesh Nagabhushana 		break;
536*56b2bdd1SGireesh Nagabhushana 
537*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_MTU:
538*56b2bdd1SGireesh Nagabhushana 		if (v32 < 46 || v32 > MAX_MTU) {
539*56b2bdd1SGireesh Nagabhushana 			rc = EINVAL;
540*56b2bdd1SGireesh Nagabhushana 		} else if (v32 != pi->mtu) {
541*56b2bdd1SGireesh Nagabhushana 			pi->mtu = v32;
542*56b2bdd1SGireesh Nagabhushana 			(void) mac_maxsdu_update(pi->mh, v32);
543*56b2bdd1SGireesh Nagabhushana 			rx_mode = 1;
544*56b2bdd1SGireesh Nagabhushana 		}
545*56b2bdd1SGireesh Nagabhushana 
546*56b2bdd1SGireesh Nagabhushana 		break;
547*56b2bdd1SGireesh Nagabhushana 
548*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_FLOWCTRL:
549*56b2bdd1SGireesh Nagabhushana 		fc = *(link_flowctrl_t *)val;
550*56b2bdd1SGireesh Nagabhushana 		old = lc->requested_fc & (PAUSE_TX | PAUSE_RX);
551*56b2bdd1SGireesh Nagabhushana 
552*56b2bdd1SGireesh Nagabhushana 		if (fc == LINK_FLOWCTRL_BI)
553*56b2bdd1SGireesh Nagabhushana 			new = (PAUSE_TX | PAUSE_RX);
554*56b2bdd1SGireesh Nagabhushana 		else if (fc == LINK_FLOWCTRL_TX)
555*56b2bdd1SGireesh Nagabhushana 			new = PAUSE_TX;
556*56b2bdd1SGireesh Nagabhushana 		else if (fc == LINK_FLOWCTRL_RX)
557*56b2bdd1SGireesh Nagabhushana 			new = PAUSE_RX;
558*56b2bdd1SGireesh Nagabhushana 
559*56b2bdd1SGireesh Nagabhushana 		if (new != old) {
560*56b2bdd1SGireesh Nagabhushana 			lc->requested_fc &= ~(PAUSE_TX | PAUSE_RX);
561*56b2bdd1SGireesh Nagabhushana 			lc->requested_fc |= new;
562*56b2bdd1SGireesh Nagabhushana 			relink = 1;
563*56b2bdd1SGireesh Nagabhushana 		}
564*56b2bdd1SGireesh Nagabhushana 		break;
565*56b2bdd1SGireesh Nagabhushana 
566*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_EN_10GFDX_CAP:
567*56b2bdd1SGireesh Nagabhushana 		if (lc->supported & FW_PORT_CAP_ANEG && is_10G_port(pi)) {
568*56b2bdd1SGireesh Nagabhushana 			old = lc->advertising & FW_PORT_CAP_SPEED_10G;
569*56b2bdd1SGireesh Nagabhushana 			new = v8 ? FW_PORT_CAP_SPEED_10G : 0;
570*56b2bdd1SGireesh Nagabhushana 			if (new != old) {
571*56b2bdd1SGireesh Nagabhushana 				lc->advertising &= ~FW_PORT_CAP_SPEED_10G;
572*56b2bdd1SGireesh Nagabhushana 				lc->advertising |= new;
573*56b2bdd1SGireesh Nagabhushana 				relink = 1;
574*56b2bdd1SGireesh Nagabhushana 			}
575*56b2bdd1SGireesh Nagabhushana 		} else
576*56b2bdd1SGireesh Nagabhushana 			rc = ENOTSUP;
577*56b2bdd1SGireesh Nagabhushana 
578*56b2bdd1SGireesh Nagabhushana 		break;
579*56b2bdd1SGireesh Nagabhushana 
580*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_EN_1000FDX_CAP:
581*56b2bdd1SGireesh Nagabhushana 		/* Forced 1G */
582*56b2bdd1SGireesh Nagabhushana 		if (lc->autoneg == AUTONEG_ENABLE) {
583*56b2bdd1SGireesh Nagabhushana 			old = lc->advertising & FW_PORT_CAP_SPEED_1G;
584*56b2bdd1SGireesh Nagabhushana 			new = v8 ? FW_PORT_CAP_SPEED_1G : 0;
585*56b2bdd1SGireesh Nagabhushana 
586*56b2bdd1SGireesh Nagabhushana 			if (old != new) {
587*56b2bdd1SGireesh Nagabhushana 				lc->advertising &= ~FW_PORT_CAP_SPEED_1G;
588*56b2bdd1SGireesh Nagabhushana 				lc->advertising |= new;
589*56b2bdd1SGireesh Nagabhushana 				relink = 1;
590*56b2bdd1SGireesh Nagabhushana 			}
591*56b2bdd1SGireesh Nagabhushana 		} else
592*56b2bdd1SGireesh Nagabhushana 			rc = ENOTSUP;
593*56b2bdd1SGireesh Nagabhushana 		break;
594*56b2bdd1SGireesh Nagabhushana 
595*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_EN_100FDX_CAP:
596*56b2bdd1SGireesh Nagabhushana 		/* Forced 100M */
597*56b2bdd1SGireesh Nagabhushana 		if (lc->autoneg == AUTONEG_ENABLE) {
598*56b2bdd1SGireesh Nagabhushana 			old = lc->advertising & FW_PORT_CAP_SPEED_100M;
599*56b2bdd1SGireesh Nagabhushana 			new = v8 ? FW_PORT_CAP_SPEED_100M : 0;
600*56b2bdd1SGireesh Nagabhushana 			if (old != new) {
601*56b2bdd1SGireesh Nagabhushana 				lc->advertising &= ~FW_PORT_CAP_SPEED_100M;
602*56b2bdd1SGireesh Nagabhushana 				lc->advertising |= new;
603*56b2bdd1SGireesh Nagabhushana 				relink = 1;
604*56b2bdd1SGireesh Nagabhushana 			}
605*56b2bdd1SGireesh Nagabhushana 		} else
606*56b2bdd1SGireesh Nagabhushana 			rc = ENOTSUP;
607*56b2bdd1SGireesh Nagabhushana 		break;
608*56b2bdd1SGireesh Nagabhushana 
609*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_PRIVATE:
610*56b2bdd1SGireesh Nagabhushana 		rc = setprop(pi, name, val);
611*56b2bdd1SGireesh Nagabhushana 		break;
612*56b2bdd1SGireesh Nagabhushana 
613*56b2bdd1SGireesh Nagabhushana 	default:
614*56b2bdd1SGireesh Nagabhushana 		rc = ENOTSUP;
615*56b2bdd1SGireesh Nagabhushana 	}
616*56b2bdd1SGireesh Nagabhushana 
617*56b2bdd1SGireesh Nagabhushana 	if (isset(&sc->open_device_map, pi->port_id) != 0) {
618*56b2bdd1SGireesh Nagabhushana 		if (relink != 0) {
619*56b2bdd1SGireesh Nagabhushana 			t4_os_link_changed(pi->adapter, pi->port_id, 0);
620*56b2bdd1SGireesh Nagabhushana 			rc = begin_synchronized_op(pi, 1, 1);
621*56b2bdd1SGireesh Nagabhushana 			if (rc != 0)
622*56b2bdd1SGireesh Nagabhushana 				return (rc);
623*56b2bdd1SGireesh Nagabhushana 			rc = -t4_link_start(sc, sc->mbox, pi->tx_chan,
624*56b2bdd1SGireesh Nagabhushana 			    &pi->link_cfg);
625*56b2bdd1SGireesh Nagabhushana 			end_synchronized_op(pi, 1);
626*56b2bdd1SGireesh Nagabhushana 			if (rc != 0) {
627*56b2bdd1SGireesh Nagabhushana 				cxgb_printf(pi->dip, CE_WARN,
628*56b2bdd1SGireesh Nagabhushana 				    "start_link failed:%d", rc);
629*56b2bdd1SGireesh Nagabhushana 
630*56b2bdd1SGireesh Nagabhushana 				/* Restore link_config */
631*56b2bdd1SGireesh Nagabhushana 				bcopy(&lc_copy, lc,
632*56b2bdd1SGireesh Nagabhushana 				    sizeof (struct link_config));
633*56b2bdd1SGireesh Nagabhushana 			}
634*56b2bdd1SGireesh Nagabhushana 		}
635*56b2bdd1SGireesh Nagabhushana 
636*56b2bdd1SGireesh Nagabhushana 		if (rx_mode != 0) {
637*56b2bdd1SGireesh Nagabhushana 			rc = begin_synchronized_op(pi, 1, 1);
638*56b2bdd1SGireesh Nagabhushana 			if (rc != 0)
639*56b2bdd1SGireesh Nagabhushana 				return (rc);
640*56b2bdd1SGireesh Nagabhushana 			rc = -t4_set_rxmode(sc, sc->mbox, pi->viid, v32, -1,
641*56b2bdd1SGireesh Nagabhushana 			    -1, -1, -1, false);
642*56b2bdd1SGireesh Nagabhushana 			end_synchronized_op(pi, 1);
643*56b2bdd1SGireesh Nagabhushana 			if (rc != 0) {
644*56b2bdd1SGireesh Nagabhushana 				cxgb_printf(pi->dip, CE_WARN,
645*56b2bdd1SGireesh Nagabhushana 				    "set_rxmode failed: %d", rc);
646*56b2bdd1SGireesh Nagabhushana 			}
647*56b2bdd1SGireesh Nagabhushana 		}
648*56b2bdd1SGireesh Nagabhushana 	}
649*56b2bdd1SGireesh Nagabhushana 
650*56b2bdd1SGireesh Nagabhushana 	return (rc);
651*56b2bdd1SGireesh Nagabhushana }
652*56b2bdd1SGireesh Nagabhushana 
653*56b2bdd1SGireesh Nagabhushana static int
654*56b2bdd1SGireesh Nagabhushana t4_mc_getprop(void *arg, const char *name, mac_prop_id_t id, uint_t size,
655*56b2bdd1SGireesh Nagabhushana     void *val)
656*56b2bdd1SGireesh Nagabhushana {
657*56b2bdd1SGireesh Nagabhushana 	struct port_info *pi = arg;
658*56b2bdd1SGireesh Nagabhushana 	struct link_config *lc = &pi->link_cfg;
659*56b2bdd1SGireesh Nagabhushana 	uint8_t *u = val;
660*56b2bdd1SGireesh Nagabhushana 
661*56b2bdd1SGireesh Nagabhushana 	switch (id) {
662*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_DUPLEX:
663*56b2bdd1SGireesh Nagabhushana 		*(link_duplex_t *)val = lc->link_ok ? LINK_DUPLEX_FULL :
664*56b2bdd1SGireesh Nagabhushana 		    LINK_DUPLEX_UNKNOWN;
665*56b2bdd1SGireesh Nagabhushana 		break;
666*56b2bdd1SGireesh Nagabhushana 
667*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_SPEED:
668*56b2bdd1SGireesh Nagabhushana 		if (lc->link_ok != 0) {
669*56b2bdd1SGireesh Nagabhushana 			*(uint64_t *)val = lc->speed;
670*56b2bdd1SGireesh Nagabhushana 			*(uint64_t *)val *= 1000000;
671*56b2bdd1SGireesh Nagabhushana 		} else
672*56b2bdd1SGireesh Nagabhushana 			*(uint64_t *)val = 0;
673*56b2bdd1SGireesh Nagabhushana 		break;
674*56b2bdd1SGireesh Nagabhushana 
675*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_STATUS:
676*56b2bdd1SGireesh Nagabhushana 		*(link_state_t *)val = lc->link_ok ? LINK_STATE_UP :
677*56b2bdd1SGireesh Nagabhushana 		    LINK_STATE_DOWN;
678*56b2bdd1SGireesh Nagabhushana 		break;
679*56b2bdd1SGireesh Nagabhushana 
680*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_AUTONEG:
681*56b2bdd1SGireesh Nagabhushana 		*u = lc->autoneg == AUTONEG_ENABLE;
682*56b2bdd1SGireesh Nagabhushana 		break;
683*56b2bdd1SGireesh Nagabhushana 
684*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_MTU:
685*56b2bdd1SGireesh Nagabhushana 		*(uint32_t *)val = pi->mtu;
686*56b2bdd1SGireesh Nagabhushana 		break;
687*56b2bdd1SGireesh Nagabhushana 
688*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_FLOWCTRL:
689*56b2bdd1SGireesh Nagabhushana 		if ((lc->requested_fc & (PAUSE_TX | PAUSE_RX)) ==
690*56b2bdd1SGireesh Nagabhushana 		    (PAUSE_TX | PAUSE_RX))
691*56b2bdd1SGireesh Nagabhushana 			*(link_flowctrl_t *)val = LINK_FLOWCTRL_BI;
692*56b2bdd1SGireesh Nagabhushana 		else if (lc->requested_fc & PAUSE_TX)
693*56b2bdd1SGireesh Nagabhushana 			*(link_flowctrl_t *)val = LINK_FLOWCTRL_TX;
694*56b2bdd1SGireesh Nagabhushana 		else if (lc->requested_fc & PAUSE_RX)
695*56b2bdd1SGireesh Nagabhushana 			*(link_flowctrl_t *)val = LINK_FLOWCTRL_RX;
696*56b2bdd1SGireesh Nagabhushana 		else
697*56b2bdd1SGireesh Nagabhushana 			*(link_flowctrl_t *)val = LINK_FLOWCTRL_NONE;
698*56b2bdd1SGireesh Nagabhushana 		break;
699*56b2bdd1SGireesh Nagabhushana 
700*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_ADV_10GFDX_CAP:
701*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_EN_10GFDX_CAP:
702*56b2bdd1SGireesh Nagabhushana 		*u = !!(lc->advertising & FW_PORT_CAP_SPEED_10G);
703*56b2bdd1SGireesh Nagabhushana 		break;
704*56b2bdd1SGireesh Nagabhushana 
705*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_ADV_1000FDX_CAP:
706*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_EN_1000FDX_CAP:
707*56b2bdd1SGireesh Nagabhushana 		*u = !!(lc->advertising & FW_PORT_CAP_SPEED_1G);
708*56b2bdd1SGireesh Nagabhushana 		break;
709*56b2bdd1SGireesh Nagabhushana 
710*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_ADV_100FDX_CAP:
711*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_EN_100FDX_CAP:
712*56b2bdd1SGireesh Nagabhushana 		*u = !!(lc->advertising & FW_PORT_CAP_SPEED_100M);
713*56b2bdd1SGireesh Nagabhushana 		break;
714*56b2bdd1SGireesh Nagabhushana 
715*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_PRIVATE:
716*56b2bdd1SGireesh Nagabhushana 		return (getprop(pi, name, size, val));
717*56b2bdd1SGireesh Nagabhushana 
718*56b2bdd1SGireesh Nagabhushana 	default:
719*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
720*56b2bdd1SGireesh Nagabhushana 	}
721*56b2bdd1SGireesh Nagabhushana 
722*56b2bdd1SGireesh Nagabhushana 	return (0);
723*56b2bdd1SGireesh Nagabhushana }
724*56b2bdd1SGireesh Nagabhushana 
725*56b2bdd1SGireesh Nagabhushana static void
726*56b2bdd1SGireesh Nagabhushana t4_mc_propinfo(void *arg, const char *name, mac_prop_id_t id,
727*56b2bdd1SGireesh Nagabhushana     mac_prop_info_handle_t ph)
728*56b2bdd1SGireesh Nagabhushana {
729*56b2bdd1SGireesh Nagabhushana 	struct port_info *pi = arg;
730*56b2bdd1SGireesh Nagabhushana 	struct link_config *lc = &pi->link_cfg;
731*56b2bdd1SGireesh Nagabhushana 
732*56b2bdd1SGireesh Nagabhushana 	switch (id) {
733*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_DUPLEX:
734*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_SPEED:
735*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_STATUS:
736*56b2bdd1SGireesh Nagabhushana 		mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
737*56b2bdd1SGireesh Nagabhushana 		break;
738*56b2bdd1SGireesh Nagabhushana 
739*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_AUTONEG:
740*56b2bdd1SGireesh Nagabhushana 		if (lc->supported & FW_PORT_CAP_ANEG)
741*56b2bdd1SGireesh Nagabhushana 			mac_prop_info_set_default_uint8(ph, 1);
742*56b2bdd1SGireesh Nagabhushana 		else
743*56b2bdd1SGireesh Nagabhushana 			mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
744*56b2bdd1SGireesh Nagabhushana 		break;
745*56b2bdd1SGireesh Nagabhushana 
746*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_MTU:
747*56b2bdd1SGireesh Nagabhushana 		mac_prop_info_set_range_uint32(ph, 46, MAX_MTU);
748*56b2bdd1SGireesh Nagabhushana 		break;
749*56b2bdd1SGireesh Nagabhushana 
750*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_FLOWCTRL:
751*56b2bdd1SGireesh Nagabhushana 		mac_prop_info_set_default_link_flowctrl(ph, LINK_FLOWCTRL_BI);
752*56b2bdd1SGireesh Nagabhushana 		break;
753*56b2bdd1SGireesh Nagabhushana 
754*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_EN_10GFDX_CAP:
755*56b2bdd1SGireesh Nagabhushana 		if (lc->supported & FW_PORT_CAP_ANEG &&
756*56b2bdd1SGireesh Nagabhushana 		    lc->supported & FW_PORT_CAP_SPEED_10G)
757*56b2bdd1SGireesh Nagabhushana 			mac_prop_info_set_default_uint8(ph, 1);
758*56b2bdd1SGireesh Nagabhushana 		else
759*56b2bdd1SGireesh Nagabhushana 			mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
760*56b2bdd1SGireesh Nagabhushana 		break;
761*56b2bdd1SGireesh Nagabhushana 
762*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_EN_1000FDX_CAP:
763*56b2bdd1SGireesh Nagabhushana 		if (lc->supported & FW_PORT_CAP_ANEG &&
764*56b2bdd1SGireesh Nagabhushana 		    lc->supported & FW_PORT_CAP_SPEED_1G)
765*56b2bdd1SGireesh Nagabhushana 			mac_prop_info_set_default_uint8(ph, 1);
766*56b2bdd1SGireesh Nagabhushana 		else
767*56b2bdd1SGireesh Nagabhushana 			mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
768*56b2bdd1SGireesh Nagabhushana 		break;
769*56b2bdd1SGireesh Nagabhushana 
770*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_EN_100FDX_CAP:
771*56b2bdd1SGireesh Nagabhushana 		if (lc->supported & FW_PORT_CAP_ANEG &&
772*56b2bdd1SGireesh Nagabhushana 		    lc->supported & FW_PORT_CAP_SPEED_100M)
773*56b2bdd1SGireesh Nagabhushana 			mac_prop_info_set_default_uint8(ph, 1);
774*56b2bdd1SGireesh Nagabhushana 		else
775*56b2bdd1SGireesh Nagabhushana 			mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
776*56b2bdd1SGireesh Nagabhushana 		break;
777*56b2bdd1SGireesh Nagabhushana 
778*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_ADV_10GFDX_CAP:
779*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_ADV_1000FDX_CAP:
780*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_ADV_100FDX_CAP:
781*56b2bdd1SGireesh Nagabhushana 		mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
782*56b2bdd1SGireesh Nagabhushana 		break;
783*56b2bdd1SGireesh Nagabhushana 
784*56b2bdd1SGireesh Nagabhushana 	case MAC_PROP_PRIVATE:
785*56b2bdd1SGireesh Nagabhushana 		propinfo(pi, name, ph);
786*56b2bdd1SGireesh Nagabhushana 		break;
787*56b2bdd1SGireesh Nagabhushana 
788*56b2bdd1SGireesh Nagabhushana 	default:
789*56b2bdd1SGireesh Nagabhushana 		break;
790*56b2bdd1SGireesh Nagabhushana 	}
791*56b2bdd1SGireesh Nagabhushana }
792*56b2bdd1SGireesh Nagabhushana 
793*56b2bdd1SGireesh Nagabhushana static int
794*56b2bdd1SGireesh Nagabhushana begin_synchronized_op(struct port_info *pi, int hold, int waitok)
795*56b2bdd1SGireesh Nagabhushana {
796*56b2bdd1SGireesh Nagabhushana 	struct adapter *sc = pi->adapter;
797*56b2bdd1SGireesh Nagabhushana 	int rc = 0;
798*56b2bdd1SGireesh Nagabhushana 
799*56b2bdd1SGireesh Nagabhushana 	ADAPTER_LOCK(sc);
800*56b2bdd1SGireesh Nagabhushana 	while (!IS_DOOMED(pi) && IS_BUSY(sc)) {
801*56b2bdd1SGireesh Nagabhushana 		if (!waitok) {
802*56b2bdd1SGireesh Nagabhushana 			rc = EBUSY;
803*56b2bdd1SGireesh Nagabhushana 			goto failed;
804*56b2bdd1SGireesh Nagabhushana 		} else if (cv_wait_sig(&sc->cv, &sc->lock) == 0) {
805*56b2bdd1SGireesh Nagabhushana 			rc = EINTR;
806*56b2bdd1SGireesh Nagabhushana 			goto failed;
807*56b2bdd1SGireesh Nagabhushana 		}
808*56b2bdd1SGireesh Nagabhushana 	}
809*56b2bdd1SGireesh Nagabhushana 	if (IS_DOOMED(pi) != 0) {	/* shouldn't happen on Solaris */
810*56b2bdd1SGireesh Nagabhushana 		rc = ENXIO;
811*56b2bdd1SGireesh Nagabhushana 		goto failed;
812*56b2bdd1SGireesh Nagabhushana 	}
813*56b2bdd1SGireesh Nagabhushana 	ASSERT(!IS_BUSY(sc));
814*56b2bdd1SGireesh Nagabhushana 	/* LINTED: E_CONSTANT_CONDITION */
815*56b2bdd1SGireesh Nagabhushana 	SET_BUSY(sc);
816*56b2bdd1SGireesh Nagabhushana 
817*56b2bdd1SGireesh Nagabhushana 	if (!hold)
818*56b2bdd1SGireesh Nagabhushana 		ADAPTER_UNLOCK(sc);
819*56b2bdd1SGireesh Nagabhushana 
820*56b2bdd1SGireesh Nagabhushana 	return (0);
821*56b2bdd1SGireesh Nagabhushana failed:
822*56b2bdd1SGireesh Nagabhushana 	ADAPTER_UNLOCK(sc);
823*56b2bdd1SGireesh Nagabhushana 	return (rc);
824*56b2bdd1SGireesh Nagabhushana }
825*56b2bdd1SGireesh Nagabhushana 
826*56b2bdd1SGireesh Nagabhushana static void
827*56b2bdd1SGireesh Nagabhushana end_synchronized_op(struct port_info *pi, int held)
828*56b2bdd1SGireesh Nagabhushana {
829*56b2bdd1SGireesh Nagabhushana 	struct adapter *sc = pi->adapter;
830*56b2bdd1SGireesh Nagabhushana 
831*56b2bdd1SGireesh Nagabhushana 	if (!held)
832*56b2bdd1SGireesh Nagabhushana 		ADAPTER_LOCK(sc);
833*56b2bdd1SGireesh Nagabhushana 
834*56b2bdd1SGireesh Nagabhushana 	ADAPTER_LOCK_ASSERT_OWNED(sc);
835*56b2bdd1SGireesh Nagabhushana 	ASSERT(IS_BUSY(sc));
836*56b2bdd1SGireesh Nagabhushana 	/* LINTED: E_CONSTANT_CONDITION */
837*56b2bdd1SGireesh Nagabhushana 	CLR_BUSY(sc);
838*56b2bdd1SGireesh Nagabhushana 	cv_signal(&sc->cv);
839*56b2bdd1SGireesh Nagabhushana 	ADAPTER_UNLOCK(sc);
840*56b2bdd1SGireesh Nagabhushana }
841*56b2bdd1SGireesh Nagabhushana 
842*56b2bdd1SGireesh Nagabhushana static int
843*56b2bdd1SGireesh Nagabhushana t4_init_synchronized(struct port_info *pi)
844*56b2bdd1SGireesh Nagabhushana {
845*56b2bdd1SGireesh Nagabhushana 	struct adapter *sc = pi->adapter;
846*56b2bdd1SGireesh Nagabhushana 	int rc = 0;
847*56b2bdd1SGireesh Nagabhushana 
848*56b2bdd1SGireesh Nagabhushana 	ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
849*56b2bdd1SGireesh Nagabhushana 
850*56b2bdd1SGireesh Nagabhushana 	if (isset(&sc->open_device_map, pi->port_id) != 0)
851*56b2bdd1SGireesh Nagabhushana 		return (0);	/* already running */
852*56b2bdd1SGireesh Nagabhushana 
853*56b2bdd1SGireesh Nagabhushana 	if (!(sc->flags & FULL_INIT_DONE) &&
854*56b2bdd1SGireesh Nagabhushana 	    ((rc = adapter_full_init(sc)) != 0))
855*56b2bdd1SGireesh Nagabhushana 		return (rc);	/* error message displayed already */
856*56b2bdd1SGireesh Nagabhushana 
857*56b2bdd1SGireesh Nagabhushana 	if (!(pi->flags & PORT_INIT_DONE)) {
858*56b2bdd1SGireesh Nagabhushana 		rc = port_full_init(pi);
859*56b2bdd1SGireesh Nagabhushana 		if (rc != 0)
860*56b2bdd1SGireesh Nagabhushana 			return (rc); /* error message displayed already */
861*56b2bdd1SGireesh Nagabhushana 	} else
862*56b2bdd1SGireesh Nagabhushana 		enable_port_queues(pi);
863*56b2bdd1SGireesh Nagabhushana 
864*56b2bdd1SGireesh Nagabhushana 	rc = -t4_set_rxmode(sc, sc->mbox, pi->viid, pi->mtu, 0, 0, 1, 0, false);
865*56b2bdd1SGireesh Nagabhushana 	if (rc != 0) {
866*56b2bdd1SGireesh Nagabhushana 		cxgb_printf(pi->dip, CE_WARN, "set_rxmode failed: %d", rc);
867*56b2bdd1SGireesh Nagabhushana 		goto done;
868*56b2bdd1SGireesh Nagabhushana 	}
869*56b2bdd1SGireesh Nagabhushana 	rc = t4_change_mac(sc, sc->mbox, pi->viid, pi->xact_addr_filt,
870*56b2bdd1SGireesh Nagabhushana 	    pi->hw_addr, true, true);
871*56b2bdd1SGireesh Nagabhushana 	if (rc < 0) {
872*56b2bdd1SGireesh Nagabhushana 		cxgb_printf(pi->dip, CE_WARN, "change_mac failed: %d", rc);
873*56b2bdd1SGireesh Nagabhushana 		rc = -rc;
874*56b2bdd1SGireesh Nagabhushana 		goto done;
875*56b2bdd1SGireesh Nagabhushana 	} else
876*56b2bdd1SGireesh Nagabhushana 		/* LINTED: E_ASSIGN_NARROW_CONV */
877*56b2bdd1SGireesh Nagabhushana 		pi->xact_addr_filt = rc;
878*56b2bdd1SGireesh Nagabhushana 
879*56b2bdd1SGireesh Nagabhushana 	rc = -t4_link_start(sc, sc->mbox, pi->tx_chan, &pi->link_cfg);
880*56b2bdd1SGireesh Nagabhushana 	if (rc != 0) {
881*56b2bdd1SGireesh Nagabhushana 		cxgb_printf(pi->dip, CE_WARN, "start_link failed: %d", rc);
882*56b2bdd1SGireesh Nagabhushana 		goto done;
883*56b2bdd1SGireesh Nagabhushana 	}
884*56b2bdd1SGireesh Nagabhushana 
885*56b2bdd1SGireesh Nagabhushana 	rc = -t4_enable_vi(sc, sc->mbox, pi->viid, true, true);
886*56b2bdd1SGireesh Nagabhushana 	if (rc != 0) {
887*56b2bdd1SGireesh Nagabhushana 		cxgb_printf(pi->dip, CE_WARN, "enable_vi failed: %d", rc);
888*56b2bdd1SGireesh Nagabhushana 		goto done;
889*56b2bdd1SGireesh Nagabhushana 	}
890*56b2bdd1SGireesh Nagabhushana 
891*56b2bdd1SGireesh Nagabhushana 	/* all ok */
892*56b2bdd1SGireesh Nagabhushana 	setbit(&sc->open_device_map, pi->port_id);
893*56b2bdd1SGireesh Nagabhushana done:
894*56b2bdd1SGireesh Nagabhushana 	if (rc != 0)
895*56b2bdd1SGireesh Nagabhushana 		(void) t4_uninit_synchronized(pi);
896*56b2bdd1SGireesh Nagabhushana 
897*56b2bdd1SGireesh Nagabhushana 	return (rc);
898*56b2bdd1SGireesh Nagabhushana }
899*56b2bdd1SGireesh Nagabhushana 
900*56b2bdd1SGireesh Nagabhushana /*
901*56b2bdd1SGireesh Nagabhushana  * Idempotent.
902*56b2bdd1SGireesh Nagabhushana  */
903*56b2bdd1SGireesh Nagabhushana static int
904*56b2bdd1SGireesh Nagabhushana t4_uninit_synchronized(struct port_info *pi)
905*56b2bdd1SGireesh Nagabhushana {
906*56b2bdd1SGireesh Nagabhushana 	struct adapter *sc = pi->adapter;
907*56b2bdd1SGireesh Nagabhushana 	int rc;
908*56b2bdd1SGireesh Nagabhushana 
909*56b2bdd1SGireesh Nagabhushana 	ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
910*56b2bdd1SGireesh Nagabhushana 
911*56b2bdd1SGireesh Nagabhushana 	/*
912*56b2bdd1SGireesh Nagabhushana 	 * Disable the VI so that all its data in either direction is discarded
913*56b2bdd1SGireesh Nagabhushana 	 * by the MPS.  Leave everything else (the queues, interrupts, and 1Hz
914*56b2bdd1SGireesh Nagabhushana 	 * tick) intact as the TP can deliver negative advice or data that it's
915*56b2bdd1SGireesh Nagabhushana 	 * holding in its RAM (for an offloaded connection) even after the VI is
916*56b2bdd1SGireesh Nagabhushana 	 * disabled.
917*56b2bdd1SGireesh Nagabhushana 	 */
918*56b2bdd1SGireesh Nagabhushana 	rc = -t4_enable_vi(sc, sc->mbox, pi->viid, false, false);
919*56b2bdd1SGireesh Nagabhushana 	if (rc != 0) {
920*56b2bdd1SGireesh Nagabhushana 		cxgb_printf(pi->dip, CE_WARN, "disable_vi failed: %d", rc);
921*56b2bdd1SGireesh Nagabhushana 		return (rc);
922*56b2bdd1SGireesh Nagabhushana 	}
923*56b2bdd1SGireesh Nagabhushana 
924*56b2bdd1SGireesh Nagabhushana 	disable_port_queues(pi);
925*56b2bdd1SGireesh Nagabhushana 
926*56b2bdd1SGireesh Nagabhushana 	clrbit(&sc->open_device_map, pi->port_id);
927*56b2bdd1SGireesh Nagabhushana 
928*56b2bdd1SGireesh Nagabhushana 	pi->link_cfg.link_ok = 0;
929*56b2bdd1SGireesh Nagabhushana 	pi->link_cfg.speed = 0;
930*56b2bdd1SGireesh Nagabhushana 	mac_link_update(pi->mh, LINK_STATE_UNKNOWN);
931*56b2bdd1SGireesh Nagabhushana 
932*56b2bdd1SGireesh Nagabhushana 	return (0);
933*56b2bdd1SGireesh Nagabhushana }
934*56b2bdd1SGireesh Nagabhushana 
935*56b2bdd1SGireesh Nagabhushana static void
936*56b2bdd1SGireesh Nagabhushana propinfo(struct port_info *pi, const char *name, mac_prop_info_handle_t ph)
937*56b2bdd1SGireesh Nagabhushana {
938*56b2bdd1SGireesh Nagabhushana 	struct adapter *sc = pi->adapter;
939*56b2bdd1SGireesh Nagabhushana 	struct driver_properties *p = &sc->props;
940*56b2bdd1SGireesh Nagabhushana 	struct link_config *lc = &pi->link_cfg;
941*56b2bdd1SGireesh Nagabhushana 	int v;
942*56b2bdd1SGireesh Nagabhushana 	char str[16];
943*56b2bdd1SGireesh Nagabhushana 
944*56b2bdd1SGireesh Nagabhushana 	if (strcmp(name, T4PROP_TMR_IDX) == 0)
945*56b2bdd1SGireesh Nagabhushana 		v = is_10G_port(pi) ? p->tmr_idx_10g : p->tmr_idx_1g;
946*56b2bdd1SGireesh Nagabhushana 	else if (strcmp(name, T4PROP_PKTC_IDX) == 0)
947*56b2bdd1SGireesh Nagabhushana 		v = is_10G_port(pi) ? p->pktc_idx_10g : p->pktc_idx_1g;
948*56b2bdd1SGireesh Nagabhushana 	else if (strcmp(name, T4PROP_HW_CSUM) == 0)
949*56b2bdd1SGireesh Nagabhushana 		v = (pi->features & CXGBE_HW_CSUM) ? 1 : 0;
950*56b2bdd1SGireesh Nagabhushana 	else if (strcmp(name, T4PROP_HW_LSO) == 0)
951*56b2bdd1SGireesh Nagabhushana 		v = (pi->features & CXGBE_HW_LSO) ? 1 : 0;
952*56b2bdd1SGireesh Nagabhushana 	else if (strcmp(name, T4PROP_TX_PAUSE) == 0)
953*56b2bdd1SGireesh Nagabhushana 		v = (lc->fc & PAUSE_TX) ? 1 : 0;
954*56b2bdd1SGireesh Nagabhushana 	else if (strcmp(name, T4PROP_RX_PAUSE) == 0)
955*56b2bdd1SGireesh Nagabhushana 		v = (lc->fc & PAUSE_RX) ? 1 : 0;
956*56b2bdd1SGireesh Nagabhushana #if MAC_VERSION == 1
957*56b2bdd1SGireesh Nagabhushana 	else if (strcmp(name, T4PROP_MTU) == 0)
958*56b2bdd1SGireesh Nagabhushana 		v = ETHERMTU;
959*56b2bdd1SGireesh Nagabhushana #endif
960*56b2bdd1SGireesh Nagabhushana 	else
961*56b2bdd1SGireesh Nagabhushana 		return;
962*56b2bdd1SGireesh Nagabhushana 
963*56b2bdd1SGireesh Nagabhushana 	(void) snprintf(str, sizeof (str), "%d", v);
964*56b2bdd1SGireesh Nagabhushana 	mac_prop_info_set_default_str(ph, str);
965*56b2bdd1SGireesh Nagabhushana }
966*56b2bdd1SGireesh Nagabhushana 
967*56b2bdd1SGireesh Nagabhushana static int
968*56b2bdd1SGireesh Nagabhushana getprop(struct port_info *pi, const char *name, uint_t size, void *val)
969*56b2bdd1SGireesh Nagabhushana {
970*56b2bdd1SGireesh Nagabhushana 	struct link_config *lc = &pi->link_cfg;
971*56b2bdd1SGireesh Nagabhushana 	int v;
972*56b2bdd1SGireesh Nagabhushana 
973*56b2bdd1SGireesh Nagabhushana 	if (strcmp(name, T4PROP_TMR_IDX) == 0)
974*56b2bdd1SGireesh Nagabhushana 		v = pi->tmr_idx;
975*56b2bdd1SGireesh Nagabhushana 	else if (strcmp(name, T4PROP_PKTC_IDX) == 0)
976*56b2bdd1SGireesh Nagabhushana 		v = pi->pktc_idx;
977*56b2bdd1SGireesh Nagabhushana 	else if (strcmp(name, T4PROP_HW_CSUM) == 0)
978*56b2bdd1SGireesh Nagabhushana 		v = (pi->features & CXGBE_HW_CSUM) ? 1 : 0;
979*56b2bdd1SGireesh Nagabhushana 	else if (strcmp(name, T4PROP_HW_LSO) == 0)
980*56b2bdd1SGireesh Nagabhushana 		v = (pi->features & CXGBE_HW_LSO) ? 1 : 0;
981*56b2bdd1SGireesh Nagabhushana 	else if (strcmp(name, T4PROP_TX_PAUSE) == 0)
982*56b2bdd1SGireesh Nagabhushana 		v = (lc->fc & PAUSE_TX) ? 1 : 0;
983*56b2bdd1SGireesh Nagabhushana 	else if (strcmp(name, T4PROP_RX_PAUSE) == 0)
984*56b2bdd1SGireesh Nagabhushana 		v = (lc->fc & PAUSE_RX) ? 1 : 0;
985*56b2bdd1SGireesh Nagabhushana #if MAC_VERSION == 1
986*56b2bdd1SGireesh Nagabhushana 	else if (strcmp(name, T4PROP_MTU) == 0)
987*56b2bdd1SGireesh Nagabhushana 		v = pi->mtu;
988*56b2bdd1SGireesh Nagabhushana #endif
989*56b2bdd1SGireesh Nagabhushana 	else
990*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
991*56b2bdd1SGireesh Nagabhushana 
992*56b2bdd1SGireesh Nagabhushana 	(void) snprintf(val, size, "%d", v);
993*56b2bdd1SGireesh Nagabhushana 	return (0);
994*56b2bdd1SGireesh Nagabhushana }
995*56b2bdd1SGireesh Nagabhushana 
996*56b2bdd1SGireesh Nagabhushana static int
997*56b2bdd1SGireesh Nagabhushana setprop(struct port_info *pi, const char *name, const void *val)
998*56b2bdd1SGireesh Nagabhushana {
999*56b2bdd1SGireesh Nagabhushana 	struct adapter *sc = pi->adapter;
1000*56b2bdd1SGireesh Nagabhushana 	long v;
1001*56b2bdd1SGireesh Nagabhushana 	int i, rc = 0, relink = 0, rx_mode = 0;
1002*56b2bdd1SGireesh Nagabhushana 	struct sge_rxq *rxq;
1003*56b2bdd1SGireesh Nagabhushana 	struct link_config lc_old, *lc = &pi->link_cfg;
1004*56b2bdd1SGireesh Nagabhushana 
1005*56b2bdd1SGireesh Nagabhushana 	/*
1006*56b2bdd1SGireesh Nagabhushana 	 * Save a copy of link_config. This can be used to restore link_config
1007*56b2bdd1SGireesh Nagabhushana 	 * if t4_link_start() fails.
1008*56b2bdd1SGireesh Nagabhushana 	 */
1009*56b2bdd1SGireesh Nagabhushana 	bcopy(lc, &lc_old, sizeof (struct link_config));
1010*56b2bdd1SGireesh Nagabhushana 
1011*56b2bdd1SGireesh Nagabhushana 	(void) ddi_strtol(val, NULL, 0, &v);
1012*56b2bdd1SGireesh Nagabhushana 
1013*56b2bdd1SGireesh Nagabhushana 	if (strcmp(name, T4PROP_TMR_IDX) == 0) {
1014*56b2bdd1SGireesh Nagabhushana 		if (v < 0 || v >= SGE_NTIMERS)
1015*56b2bdd1SGireesh Nagabhushana 			return (EINVAL);
1016*56b2bdd1SGireesh Nagabhushana 		if (v == pi->tmr_idx)
1017*56b2bdd1SGireesh Nagabhushana 			return (0);
1018*56b2bdd1SGireesh Nagabhushana 
1019*56b2bdd1SGireesh Nagabhushana 		/* LINTED: E_ASSIGN_NARROW_CONV */
1020*56b2bdd1SGireesh Nagabhushana 		pi->tmr_idx = v;
1021*56b2bdd1SGireesh Nagabhushana 		for_each_rxq(pi, i, rxq) {
1022*56b2bdd1SGireesh Nagabhushana 			rxq->iq.intr_params = V_QINTR_TIMER_IDX(v) |
1023*56b2bdd1SGireesh Nagabhushana 			    V_QINTR_CNT_EN(pi->pktc_idx >= 0);
1024*56b2bdd1SGireesh Nagabhushana 		}
1025*56b2bdd1SGireesh Nagabhushana 
1026*56b2bdd1SGireesh Nagabhushana 	} else if (strcmp(name, T4PROP_PKTC_IDX) == 0) {
1027*56b2bdd1SGireesh Nagabhushana 		if (v >= SGE_NCOUNTERS)
1028*56b2bdd1SGireesh Nagabhushana 			return (EINVAL);
1029*56b2bdd1SGireesh Nagabhushana 		if (v == pi->pktc_idx || (v < 0 && pi->pktc_idx == -1))
1030*56b2bdd1SGireesh Nagabhushana 			return (0);
1031*56b2bdd1SGireesh Nagabhushana 
1032*56b2bdd1SGireesh Nagabhushana 		/* LINTED: E_ASSIGN_NARROW_CONV */
1033*56b2bdd1SGireesh Nagabhushana 		pi->pktc_idx = v < 0 ? -1 : v;
1034*56b2bdd1SGireesh Nagabhushana 		for_each_rxq(pi, i, rxq) {
1035*56b2bdd1SGireesh Nagabhushana 			rxq->iq.intr_params = V_QINTR_TIMER_IDX(pi->tmr_idx) |
1036*56b2bdd1SGireesh Nagabhushana 			    /* takes effect right away */
1037*56b2bdd1SGireesh Nagabhushana 			    V_QINTR_CNT_EN(v >= 0);
1038*56b2bdd1SGireesh Nagabhushana 			/* LINTED: E_ASSIGN_NARROW_CONV */
1039*56b2bdd1SGireesh Nagabhushana 			rxq->iq.intr_pktc_idx = v; /* this needs fresh plumb */
1040*56b2bdd1SGireesh Nagabhushana 		}
1041*56b2bdd1SGireesh Nagabhushana 	} else if (strcmp(name, T4PROP_HW_CSUM) == 0) {
1042*56b2bdd1SGireesh Nagabhushana 		if (v != 0 && v != 1)
1043*56b2bdd1SGireesh Nagabhushana 			return (EINVAL);
1044*56b2bdd1SGireesh Nagabhushana 		if (v == 1)
1045*56b2bdd1SGireesh Nagabhushana 			pi->features |= CXGBE_HW_CSUM;
1046*56b2bdd1SGireesh Nagabhushana 		else
1047*56b2bdd1SGireesh Nagabhushana 			pi->features &= ~CXGBE_HW_CSUM;
1048*56b2bdd1SGireesh Nagabhushana 	} else if (strcmp(name, T4PROP_HW_LSO) == 0) {
1049*56b2bdd1SGireesh Nagabhushana 		if (v != 0 && v != 1)
1050*56b2bdd1SGireesh Nagabhushana 			return (EINVAL);
1051*56b2bdd1SGireesh Nagabhushana 		if (v == 1)
1052*56b2bdd1SGireesh Nagabhushana 			pi->features |= CXGBE_HW_LSO;
1053*56b2bdd1SGireesh Nagabhushana 		else
1054*56b2bdd1SGireesh Nagabhushana 			pi->features &= ~CXGBE_HW_LSO;
1055*56b2bdd1SGireesh Nagabhushana 	} else if (strcmp(name, T4PROP_TX_PAUSE) == 0) {
1056*56b2bdd1SGireesh Nagabhushana 		if (v != 0 && v != 1)
1057*56b2bdd1SGireesh Nagabhushana 			return (EINVAL);
1058*56b2bdd1SGireesh Nagabhushana 
1059*56b2bdd1SGireesh Nagabhushana 		if (v != 0)
1060*56b2bdd1SGireesh Nagabhushana 			lc->requested_fc |= PAUSE_TX;
1061*56b2bdd1SGireesh Nagabhushana 		else
1062*56b2bdd1SGireesh Nagabhushana 			lc->requested_fc &= ~PAUSE_TX;
1063*56b2bdd1SGireesh Nagabhushana 
1064*56b2bdd1SGireesh Nagabhushana 		relink = 1;
1065*56b2bdd1SGireesh Nagabhushana 
1066*56b2bdd1SGireesh Nagabhushana 	} else if (strcmp(name, T4PROP_RX_PAUSE) == 0) {
1067*56b2bdd1SGireesh Nagabhushana 		if (v != 0 && v != 1)
1068*56b2bdd1SGireesh Nagabhushana 			return (EINVAL);
1069*56b2bdd1SGireesh Nagabhushana 
1070*56b2bdd1SGireesh Nagabhushana 		if (v != 0)
1071*56b2bdd1SGireesh Nagabhushana 			lc->requested_fc |= PAUSE_RX;
1072*56b2bdd1SGireesh Nagabhushana 		else
1073*56b2bdd1SGireesh Nagabhushana 			lc->requested_fc &= ~PAUSE_RX;
1074*56b2bdd1SGireesh Nagabhushana 
1075*56b2bdd1SGireesh Nagabhushana 		relink = 1;
1076*56b2bdd1SGireesh Nagabhushana 	}
1077*56b2bdd1SGireesh Nagabhushana #if MAC_VERSION == 1
1078*56b2bdd1SGireesh Nagabhushana 	else if (strcmp(name, T4PROP_MTU) == 0) {
1079*56b2bdd1SGireesh Nagabhushana 		if (v < 46 || v > MAX_MTU)
1080*56b2bdd1SGireesh Nagabhushana 			return (EINVAL);
1081*56b2bdd1SGireesh Nagabhushana 		if (v == pi->mtu)
1082*56b2bdd1SGireesh Nagabhushana 			return (0);
1083*56b2bdd1SGireesh Nagabhushana 
1084*56b2bdd1SGireesh Nagabhushana 		pi->mtu = (int)v;
1085*56b2bdd1SGireesh Nagabhushana 		(void) mac_maxsdu_update(pi->mh, v);
1086*56b2bdd1SGireesh Nagabhushana 		rx_mode = 1;
1087*56b2bdd1SGireesh Nagabhushana 	}
1088*56b2bdd1SGireesh Nagabhushana #endif
1089*56b2bdd1SGireesh Nagabhushana 	else
1090*56b2bdd1SGireesh Nagabhushana 		return (ENOTSUP);
1091*56b2bdd1SGireesh Nagabhushana 
1092*56b2bdd1SGireesh Nagabhushana 	if (!(relink || rx_mode))
1093*56b2bdd1SGireesh Nagabhushana 		return (0);
1094*56b2bdd1SGireesh Nagabhushana 
1095*56b2bdd1SGireesh Nagabhushana 	/* If we are here, either relink or rx_mode is 1 */
1096*56b2bdd1SGireesh Nagabhushana 	if (isset(&sc->open_device_map, pi->port_id) != 0) {
1097*56b2bdd1SGireesh Nagabhushana 		if (relink != 0) {
1098*56b2bdd1SGireesh Nagabhushana 			rc = begin_synchronized_op(pi, 1, 1);
1099*56b2bdd1SGireesh Nagabhushana 			if (rc != 0)
1100*56b2bdd1SGireesh Nagabhushana 				return (rc);
1101*56b2bdd1SGireesh Nagabhushana 			rc = -t4_link_start(sc, sc->mbox, pi->tx_chan, lc);
1102*56b2bdd1SGireesh Nagabhushana 			end_synchronized_op(pi, 1);
1103*56b2bdd1SGireesh Nagabhushana 			if (rc != 0) {
1104*56b2bdd1SGireesh Nagabhushana 				cxgb_printf(pi->dip, CE_WARN,
1105*56b2bdd1SGireesh Nagabhushana 				    "start_link failed:%d", rc);
1106*56b2bdd1SGireesh Nagabhushana 				/* Restore link_config */
1107*56b2bdd1SGireesh Nagabhushana 				bcopy(&lc_old, lc, sizeof (struct link_config));
1108*56b2bdd1SGireesh Nagabhushana 			}
1109*56b2bdd1SGireesh Nagabhushana 		} else if (rx_mode != 0) {
1110*56b2bdd1SGireesh Nagabhushana 			rc = begin_synchronized_op(pi, 1, 1);
1111*56b2bdd1SGireesh Nagabhushana 			if (rc != 0)
1112*56b2bdd1SGireesh Nagabhushana 				return (rc);
1113*56b2bdd1SGireesh Nagabhushana 			rc = -t4_set_rxmode(sc, sc->mbox, pi->viid, v, -1, -1,
1114*56b2bdd1SGireesh Nagabhushana 			    -1, -1, false);
1115*56b2bdd1SGireesh Nagabhushana 			end_synchronized_op(pi, 1);
1116*56b2bdd1SGireesh Nagabhushana 			if (rc != 0)  {
1117*56b2bdd1SGireesh Nagabhushana 				cxgb_printf(pi->dip, CE_WARN,
1118*56b2bdd1SGireesh Nagabhushana 				    "set_rxmode failed: %d", rc);
1119*56b2bdd1SGireesh Nagabhushana 			}
1120*56b2bdd1SGireesh Nagabhushana 		}
1121*56b2bdd1SGireesh Nagabhushana 		return (rc);
1122*56b2bdd1SGireesh Nagabhushana 	}
1123*56b2bdd1SGireesh Nagabhushana 
1124*56b2bdd1SGireesh Nagabhushana 	return (0);
1125*56b2bdd1SGireesh Nagabhushana }
1126*56b2bdd1SGireesh Nagabhushana 
1127*56b2bdd1SGireesh Nagabhushana void
1128*56b2bdd1SGireesh Nagabhushana t4_mc_init(struct port_info *pi)
1129*56b2bdd1SGireesh Nagabhushana {
1130*56b2bdd1SGireesh Nagabhushana 	pi->mc = &t4_m_callbacks;
1131*56b2bdd1SGireesh Nagabhushana 	pi->props = t4_priv_props;
1132*56b2bdd1SGireesh Nagabhushana }
1133*56b2bdd1SGireesh Nagabhushana 
1134*56b2bdd1SGireesh Nagabhushana void
1135*56b2bdd1SGireesh Nagabhushana t4_os_link_changed(struct adapter *sc, int idx, int link_stat)
1136*56b2bdd1SGireesh Nagabhushana {
1137*56b2bdd1SGireesh Nagabhushana 	struct port_info *pi = sc->port[idx];
1138*56b2bdd1SGireesh Nagabhushana 
1139*56b2bdd1SGireesh Nagabhushana 	mac_link_update(pi->mh, link_stat ? LINK_STATE_UP : LINK_STATE_DOWN);
1140*56b2bdd1SGireesh Nagabhushana }
1141*56b2bdd1SGireesh Nagabhushana 
1142*56b2bdd1SGireesh Nagabhushana /* ARGSUSED */
1143*56b2bdd1SGireesh Nagabhushana void
1144*56b2bdd1SGireesh Nagabhushana t4_mac_rx(struct port_info *pi, struct sge_rxq *rxq, mblk_t *m)
1145*56b2bdd1SGireesh Nagabhushana {
1146*56b2bdd1SGireesh Nagabhushana 	mac_rx(pi->mh, NULL, m);
1147*56b2bdd1SGireesh Nagabhushana }
1148