xref: /illumos-gate/usr/src/uts/common/io/cxgbe/t4nex/t4_mac.c (revision d35eb49b13b481dcf2e0b66df3d6b2fad04f3572)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source. A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * This file is part of the Chelsio T4 support code.
14  *
15  * Copyright (C) 2010-2013 Chelsio Communications.  All rights reserved.
16  *
17  * This program is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE.  See the LICENSE file included in this
20  * release for licensing terms and conditions.
21  */
22 
23 /*
24  * Copyright 2020 RackTop Systems, Inc.
25  * Copyright 2025 Oxide Computer Company
26  */
27 
28 #include <sys/ddi.h>
29 #include <sys/sunddi.h>
30 #include <sys/dlpi.h>
31 #include <sys/mac_provider.h>
32 #include <sys/mac_ether.h>
33 #include <sys/strsubr.h>
34 #include <sys/queue.h>
35 
36 #include "common/common.h"
37 #include "common/t4_regs.h"
38 
39 static int t4_mc_getstat(void *arg, uint_t stat, uint64_t *val);
40 static int t4_mc_start(void *arg);
41 static void t4_mc_stop(void *arg);
42 static int t4_mc_setpromisc(void *arg, boolean_t on);
43 static int t4_mc_multicst(void *arg, boolean_t add, const uint8_t *mcaddr);
44 static int t4_mc_unicst(void *arg, const uint8_t *ucaddr);
45 static boolean_t t4_mc_getcapab(void *arg, mac_capab_t cap, void *data);
46 static int t4_mc_setprop(void *arg, const char *name, mac_prop_id_t id,
47     uint_t size, const void *val);
48 static int t4_mc_getprop(void *arg, const char *name, mac_prop_id_t id,
49     uint_t size, void *val);
50 static void t4_mc_propinfo(void *arg, const char *name, mac_prop_id_t id,
51     mac_prop_info_handle_t ph);
52 
53 static int t4_init_synchronized(struct port_info *pi);
54 static int t4_uninit_synchronized(struct port_info *pi);
55 static void t4_propinfo_priv(struct port_info *, const char *,
56     mac_prop_info_handle_t);
57 static int t4_getprop_priv(struct port_info *, const char *, uint_t, void *);
58 static int t4_setprop_priv(struct port_info *, const char *, const void *);
59 
60 mac_callbacks_t t4_m_callbacks = {
61 	.mc_callbacks	= MC_GETCAPAB | MC_PROPERTIES,
62 	.mc_getstat	= t4_mc_getstat,
63 	.mc_start	= t4_mc_start,
64 	.mc_stop	= t4_mc_stop,
65 	.mc_setpromisc	= t4_mc_setpromisc,
66 	.mc_multicst	= t4_mc_multicst,
67 	.mc_unicst	= t4_mc_unicst,
68 	.mc_tx		= t4_mc_tx,
69 	.mc_getcapab	= t4_mc_getcapab,
70 	.mc_setprop	= t4_mc_setprop,
71 	.mc_getprop	= t4_mc_getprop,
72 	.mc_propinfo	= t4_mc_propinfo,
73 };
74 
75 mac_callbacks_t t4_m_ring_callbacks = {
76 	.mc_callbacks	= MC_GETCAPAB | MC_PROPERTIES,
77 	.mc_getstat	= t4_mc_getstat,
78 	.mc_start	= t4_mc_start,
79 	.mc_stop	= t4_mc_stop,
80 	.mc_setpromisc	= t4_mc_setpromisc,
81 	.mc_multicst	= t4_mc_multicst,
82 	.mc_unicst	= NULL, /* t4_addmac */
83 	.mc_tx		= NULL, /* t4_eth_tx */
84 	.mc_getcapab	= t4_mc_getcapab,
85 	.mc_setprop	= t4_mc_setprop,
86 	.mc_getprop	= t4_mc_getprop,
87 	.mc_propinfo	= t4_mc_propinfo,
88 };
89 
90 typedef enum t4_prop_id {
91 	T4PROP_FW_TMR,
92 	T4PROP_FW_PKTC,
93 	T4PROP_RX_TMR,
94 	T4PROP_RX_PKTC,
95 	T4PROP_TX_TMR,
96 	T4PROP_HW_CSUM,
97 	T4PROP_HW_LSO,
98 	T4PROP_RX_PAUSE,
99 	T4PROP_TX_PAUSE,
100 } t4_prop_id_t;
101 
102 typedef struct t4_priv_prop {
103 	const char	*tpp_name;
104 	t4_prop_id_t	tpp_id;
105 	bool		tpp_is_bool;
106 } t4_priv_prop_t;
107 
108 static const t4_priv_prop_t t4_priv_props[] = {
109 	/*
110 	 * Because there is a single FWQ for the entire NIC, all ports will be
111 	 * impacted by changes to these properties.
112 	 */
113 	{ "_fw_coalesce_timer_us", T4PROP_FW_TMR },
114 	{ "_fw_coalesce_count", T4PROP_FW_PKTC },
115 
116 	{ "_rx_coalesce_timer_us", T4PROP_RX_TMR },
117 	{ "_rx_coalesce_count", T4PROP_RX_PKTC },
118 	{ "_tx_reclaim_timer_us", T4PROP_TX_TMR },
119 	{ "_hw_csum", T4PROP_HW_CSUM, true },
120 	{ "_hw_lso", T4PROP_HW_LSO, true },
121 	{ "_rx_pause", T4PROP_RX_PAUSE, true },
122 	{ "_tx_pause", T4PROP_TX_PAUSE, true },
123 };
124 
125 static const t4_priv_prop_t *
t4_priv_prop_match(const char * name)126 t4_priv_prop_match(const char *name)
127 {
128 	for (uint_t i = 0; i < ARRAY_SIZE(t4_priv_props); i++) {
129 		const t4_priv_prop_t *prop = &t4_priv_props[i];
130 		if (strcmp(prop->tpp_name, name) == 0) {
131 			return (prop);
132 		}
133 	}
134 	return (NULL);
135 }
136 
137 static bool
t4_priv_prop_supported(struct port_info * pi,const t4_priv_prop_t * prop)138 t4_priv_prop_supported(struct port_info *pi, const t4_priv_prop_t *prop)
139 {
140 	struct adapter *sc = pi->adapter;
141 
142 	switch (prop->tpp_id) {
143 	case T4PROP_TX_TMR:
144 		return ((sc->flags & TAF_DBQ_TIMER) != 0);
145 
146 	default:
147 		return (true);
148 	}
149 }
150 
151 const char **
t4_get_priv_props(struct port_info * pi,size_t * alloc_sz)152 t4_get_priv_props(struct port_info *pi, size_t *alloc_sz)
153 {
154 	/*
155 	 * Just alloc for all possible options, skipping those which are not
156 	 * supported (and appending extra NULLs).
157 	 */
158 	const size_t sz = (ARRAY_SIZE(t4_priv_props) + 1) * sizeof (char *);
159 	const char **out = kmem_zalloc(sz, KM_SLEEP);
160 
161 	uint_t filled = 0;
162 	for (uint_t i = 0; i < ARRAY_SIZE(t4_priv_props); i++) {
163 		if (t4_priv_prop_supported(pi, &t4_priv_props[i])) {
164 			out[filled++] = t4_priv_props[i].tpp_name;
165 		}
166 	}
167 
168 	*alloc_sz = sz;
169 	return (out);
170 }
171 
172 /*
173  * To determine the actual Ethernet mode that we're in we need to look at the
174  * port type. That will tell us whether we're using a BASE-T PHY, have an
175  * external SFP connection whose module type we also need to use to qualify
176  * this, and then the link speed itself. Combining that tuple we can then get
177  * the current media.
178  *
179  * Our tables below assume we have gotten it down so the last thing we need to
180  * consider is a single speed. If port types end up supporting the same class of
181  * transceiver at a given speed, then this will need to be changed to use
182  * additional information to disambiguate that (which will require additional
183  * logic from the firmware).
184  */
185 typedef struct {
186 	fw_port_cap32_t tmm_speed;
187 	mac_ether_media_t tmm_ether;
188 } t4nex_media_map_t;
189 
190 static const t4nex_media_map_t t4nex_map_baset[] = {
191 	/*
192 	 * We're assuming that the 100 Mb/s mode is 100BASE-TX. It's hard to say
193 	 * for certain what the phy would have done, but given the rest of the
194 	 * market, that seems the most likely one.
195 	 */
196 	{ FW_PORT_CAP32_SPEED_100M, ETHER_MEDIA_100BASE_TX },
197 	{ FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_T },
198 	{ FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_T }
199 };
200 
201 static const t4nex_media_map_t t4nex_map_kx[] = {
202 	{ FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_KX },
203 	{ FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_KX4 }
204 };
205 
206 static const t4nex_media_map_t t4nex_map_cx[] = {
207 	{ FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_CX4 }
208 };
209 
210 static const t4nex_media_map_t t4nex_map_kr[] = {
211 	{ FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_KX },
212 	{ FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_KR },
213 	{ FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_KR },
214 	{ FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_KR4 },
215 	{ FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_KR2 },
216 	{ FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_KR4 },
217 };
218 
219 static const t4nex_media_map_t t4nex_map_lr[] = {
220 	{ FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_LX },
221 	{ FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_LR },
222 	{ FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_LR },
223 	{ FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_LR4 },
224 	{ FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_LR2 },
225 	{ FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_LR4 },
226 };
227 
228 static const t4nex_media_map_t t4nex_map_sr[] = {
229 	{ FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_SX },
230 	{ FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_SR },
231 	{ FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_SR },
232 	{ FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_SR4 },
233 	{ FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_SR2 },
234 	{ FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_SR4 },
235 };
236 
237 static const t4nex_media_map_t t4nex_map_er[] = {
238 	{ FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_ER },
239 	{ FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_ER },
240 	{ FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_ER4 },
241 	{ FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_ER4 },
242 };
243 
244 static const t4nex_media_map_t t4nex_map_cr[] = {
245 	{ FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_CX },
246 	{ FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_CR },
247 	{ FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_CR },
248 	{ FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_CR4 },
249 	{ FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_CR2 },
250 	{ FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_CR4 },
251 };
252 
253 static const t4nex_media_map_t t4nex_map_acc[] = {
254 	{ FW_PORT_CAP32_SPEED_1G, ETHER_MEDIA_1000BASE_CX },
255 	{ FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_ACC },
256 	{ FW_PORT_CAP32_SPEED_25G, ETHER_MEDIA_25GBASE_ACC },
257 	{ FW_PORT_CAP32_SPEED_40G, ETHER_MEDIA_40GBASE_ACC4 },
258 	{ FW_PORT_CAP32_SPEED_50G, ETHER_MEDIA_50GBASE_ACC2 },
259 	{ FW_PORT_CAP32_SPEED_100G, ETHER_MEDIA_100GBASE_ACC4 },
260 };
261 
262 static const t4nex_media_map_t t4nex_map_lrm[] = {
263 	{ FW_PORT_CAP32_SPEED_10G, ETHER_MEDIA_10GBASE_LRM },
264 };
265 
266 static mac_ether_media_t
t4_port_to_media(struct port_info * pi)267 t4_port_to_media(struct port_info *pi)
268 {
269 	fw_port_cap32_t speed;
270 	struct link_config *lc = &pi->link_cfg;
271 	const t4nex_media_map_t *map = NULL;
272 	size_t count = 0;
273 
274 	if (lc->link_ok != 0) {
275 		speed = t4_link_fwcap_to_fwspeed(lc->link_caps);
276 	} else {
277 		return (ETHER_MEDIA_UNKNOWN);
278 	}
279 
280 	switch (pi->port_type) {
281 	case FW_PORT_TYPE_FIBER_XFI:
282 	case FW_PORT_TYPE_FIBER_XAUI:
283 	case FW_PORT_TYPE_SFP:
284 	case FW_PORT_TYPE_QSFP_10G:
285 	case FW_PORT_TYPE_QSA:
286 	case FW_PORT_TYPE_QSFP:
287 	case FW_PORT_TYPE_CR4_QSFP:
288 	case FW_PORT_TYPE_CR_QSFP:
289 	case FW_PORT_TYPE_CR2_QSFP:
290 	case FW_PORT_TYPE_SFP28:
291 		switch (pi->mod_type) {
292 		case FW_PORT_MOD_TYPE_LR:
293 			map = t4nex_map_lr;
294 			count = ARRAY_SIZE(t4nex_map_lr);
295 			break;
296 		case FW_PORT_MOD_TYPE_SR:
297 			map = t4nex_map_sr;
298 			count = ARRAY_SIZE(t4nex_map_sr);
299 			break;
300 		case FW_PORT_MOD_TYPE_ER:
301 			map = t4nex_map_er;
302 			count = ARRAY_SIZE(t4nex_map_er);
303 			break;
304 		case FW_PORT_MOD_TYPE_TWINAX_PASSIVE:
305 			map = t4nex_map_cr;
306 			count = ARRAY_SIZE(t4nex_map_cr);
307 			break;
308 		case FW_PORT_MOD_TYPE_TWINAX_ACTIVE:
309 			map = t4nex_map_acc;
310 			count = ARRAY_SIZE(t4nex_map_acc);
311 			break;
312 		case FW_PORT_MOD_TYPE_LRM:
313 			map = t4nex_map_lrm;
314 			count = ARRAY_SIZE(t4nex_map_lrm);
315 			break;
316 		case FW_PORT_MOD_TYPE_ERROR:
317 		case FW_PORT_MOD_TYPE_UNKNOWN:
318 		case FW_PORT_MOD_TYPE_NOTSUPPORTED:
319 		case FW_PORT_MOD_TYPE_NONE:
320 		case FW_PORT_MOD_TYPE_NA:
321 		default:
322 			break;
323 		}
324 		break;
325 	case FW_PORT_TYPE_KX4:
326 	case FW_PORT_TYPE_KX:
327 		map = t4nex_map_kx;
328 		count = ARRAY_SIZE(t4nex_map_kx);
329 		break;
330 	case FW_PORT_TYPE_CX4:
331 		map = t4nex_map_cx;
332 		count = ARRAY_SIZE(t4nex_map_cx);
333 		break;
334 	case FW_PORT_TYPE_KR:
335 	case FW_PORT_TYPE_BP_AP:
336 	case FW_PORT_TYPE_BP4_AP:
337 	case FW_PORT_TYPE_BP40_BA:
338 	case FW_PORT_TYPE_KR4_100G:
339 	case FW_PORT_TYPE_KR_SFP28:
340 	case FW_PORT_TYPE_KR_XLAUI:
341 		map = t4nex_map_kr;
342 		count = ARRAY_SIZE(t4nex_map_kr);
343 		break;
344 	case FW_PORT_TYPE_BT_SGMII:
345 	case FW_PORT_TYPE_BT_XFI:
346 	case FW_PORT_TYPE_BT_XAUI:
347 		map = t4nex_map_baset;
348 		count = ARRAY_SIZE(t4nex_map_baset);
349 		break;
350 	case FW_PORT_TYPE_NONE:
351 	default:
352 		break;
353 	}
354 
355 	for (size_t i = 0; i < count; i++) {
356 		if (map[i].tmm_speed == speed) {
357 			return (map[i].tmm_ether);
358 		}
359 	}
360 
361 	/*
362 	 * At this point we return unknown as we already checked for a down link
363 	 * earlier.
364 	 */
365 	return (ETHER_MEDIA_UNKNOWN);
366 }
367 
368 static int
t4_mc_getstat(void * arg,uint_t stat,uint64_t * val)369 t4_mc_getstat(void *arg, uint_t stat, uint64_t *val)
370 {
371 	struct port_info *pi = arg;
372 	struct adapter *sc = pi->adapter;
373 	struct link_config *lc = &pi->link_cfg;
374 
375 #define	GET_STAT(name) \
376 	t4_read_reg64(sc, PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_##name##_L))
377 
378 	switch (stat) {
379 	case MAC_STAT_IFSPEED:
380 		if (lc->link_ok != 0) {
381 			*val = t4_link_fwcap_to_speed(lc->link_caps);
382 			*val *= 1000000;
383 		} else
384 			*val = 0;
385 		break;
386 
387 	case MAC_STAT_MULTIRCV:
388 		*val = GET_STAT(RX_PORT_MCAST);
389 		break;
390 
391 	case MAC_STAT_BRDCSTRCV:
392 		*val = GET_STAT(RX_PORT_BCAST);
393 		break;
394 
395 	case MAC_STAT_MULTIXMT:
396 		*val = GET_STAT(TX_PORT_MCAST);
397 		break;
398 
399 	case MAC_STAT_BRDCSTXMT:
400 		*val = GET_STAT(TX_PORT_BCAST);
401 		break;
402 
403 	case MAC_STAT_NORCVBUF:
404 		*val = 0;	/* TODO should come from rxq->nomem */
405 		break;
406 
407 	case MAC_STAT_IERRORS:
408 		*val = GET_STAT(RX_PORT_MTU_ERROR) +
409 		    GET_STAT(RX_PORT_MTU_CRC_ERROR) +
410 		    GET_STAT(RX_PORT_CRC_ERROR) +
411 		    GET_STAT(RX_PORT_LEN_ERROR) +
412 		    GET_STAT(RX_PORT_SYM_ERROR) +
413 		    GET_STAT(RX_PORT_LESS_64B);
414 		break;
415 
416 	case MAC_STAT_UNKNOWNS:
417 		return (ENOTSUP);
418 
419 	case MAC_STAT_NOXMTBUF:
420 		*val = GET_STAT(TX_PORT_DROP);
421 		break;
422 
423 	case MAC_STAT_OERRORS:
424 		*val = GET_STAT(TX_PORT_ERROR);
425 		break;
426 
427 	case MAC_STAT_COLLISIONS:
428 		return (ENOTSUP);
429 
430 	case MAC_STAT_RBYTES:
431 		*val = GET_STAT(RX_PORT_BYTES);
432 		break;
433 
434 	case MAC_STAT_IPACKETS:
435 		*val = GET_STAT(RX_PORT_FRAMES);
436 		break;
437 
438 	case MAC_STAT_OBYTES:
439 		*val = GET_STAT(TX_PORT_BYTES);
440 		break;
441 
442 	case MAC_STAT_OPACKETS:
443 		*val = GET_STAT(TX_PORT_FRAMES);
444 		break;
445 
446 	case ETHER_STAT_ALIGN_ERRORS:
447 		return (ENOTSUP);
448 
449 	case ETHER_STAT_FCS_ERRORS:
450 		*val = GET_STAT(RX_PORT_CRC_ERROR);
451 		break;
452 
453 	case ETHER_STAT_FIRST_COLLISIONS:
454 	case ETHER_STAT_MULTI_COLLISIONS:
455 	case ETHER_STAT_SQE_ERRORS:
456 	case ETHER_STAT_DEFER_XMTS:
457 	case ETHER_STAT_TX_LATE_COLLISIONS:
458 	case ETHER_STAT_EX_COLLISIONS:
459 		return (ENOTSUP);
460 
461 	case ETHER_STAT_MACXMT_ERRORS:
462 		*val = GET_STAT(TX_PORT_ERROR);
463 		break;
464 
465 	case ETHER_STAT_CARRIER_ERRORS:
466 		return (ENOTSUP);
467 
468 	case ETHER_STAT_TOOLONG_ERRORS:
469 		*val = GET_STAT(RX_PORT_MTU_ERROR);
470 		break;
471 
472 	case ETHER_STAT_MACRCV_ERRORS:
473 		*val = GET_STAT(RX_PORT_MTU_ERROR) +
474 		    GET_STAT(RX_PORT_MTU_CRC_ERROR) +
475 		    GET_STAT(RX_PORT_CRC_ERROR) +
476 		    GET_STAT(RX_PORT_LEN_ERROR) +
477 		    GET_STAT(RX_PORT_SYM_ERROR) +
478 		    GET_STAT(RX_PORT_LESS_64B);
479 		break;
480 
481 	case ETHER_STAT_XCVR_ADDR:
482 	case ETHER_STAT_XCVR_ID:
483 		return (ENOTSUP);
484 	case ETHER_STAT_XCVR_INUSE:
485 		*val = t4_port_to_media(pi);
486 		break;
487 
488 	case ETHER_STAT_CAP_100GFDX:
489 		*val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_100G);
490 		break;
491 
492 	case ETHER_STAT_CAP_50GFDX:
493 		*val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_50G);
494 		break;
495 
496 	case ETHER_STAT_CAP_40GFDX:
497 		*val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_40G);
498 		break;
499 
500 	case ETHER_STAT_CAP_25GFDX:
501 		*val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_25G);
502 		break;
503 
504 	case ETHER_STAT_CAP_10GFDX:
505 		*val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_10G);
506 		break;
507 
508 	case ETHER_STAT_CAP_1000FDX:
509 		*val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_1G);
510 		break;
511 
512 	case ETHER_STAT_CAP_100FDX:
513 		*val = !!(lc->pcaps & FW_PORT_CAP32_SPEED_100M);
514 		break;
515 
516 	case ETHER_STAT_CAP_1000HDX:
517 	case ETHER_STAT_CAP_100HDX:
518 	case ETHER_STAT_CAP_10FDX:
519 	case ETHER_STAT_CAP_10HDX:
520 		return (ENOTSUP);
521 
522 	case ETHER_STAT_CAP_ASMPAUSE:
523 		*val = !!(lc->pcaps & FW_PORT_CAP32_FC_RX);
524 		break;
525 
526 	case ETHER_STAT_CAP_PAUSE:
527 		*val = !!(lc->pcaps & FW_PORT_CAP32_FC_TX);
528 		break;
529 
530 	case ETHER_STAT_CAP_AUTONEG:
531 		*val = !!(lc->pcaps & FW_PORT_CAP32_ANEG);
532 		break;
533 
534 	/*
535 	 * We have set flow control configuration based on tx_pause and rx_pause
536 	 * values supported through ndd. Now, we need to translate the settings
537 	 * we have in link_config structure to adv_cap_asmpause and
538 	 * adv_cap_pause.
539 	 *
540 	 * There are 4 combinations possible and the translation is as below:
541 	 * tx_pause = 0 => We don't send pause frames during Rx congestion
542 	 * tx_pause = 1 => We send pause frames during Rx congestion
543 	 * rx_pause = 0 => We ignore received pause frames
544 	 * rx_pause = 1 => We pause transmission when we receive pause frames
545 	 *
546 	 * +----------------------------+----------------------------------+
547 	 * |  tx_pause	|    rx_pause	| adv_cap_asmpause | adv_cap_pause |
548 	 * +-------------------------+-------------------------------------+
549 	 * |	0	|	0	|	0	   |	0	   |
550 	 * |	0	|	1	|	1	   |	0	   |
551 	 * |	1	|	0	|	1	   |	1	   |
552 	 * |	1	|	1	|	0	   |	1	   |
553 	 * +----------------------------+----------------------------------+
554 	 */
555 
556 	/* Advertised asymmetric pause capability */
557 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
558 		if (lc->pcaps & FW_PORT_CAP32_802_3_ASM_DIR)
559 			*val = !!(lc->admin_caps & FW_PORT_CAP32_802_3_ASM_DIR);
560 		else
561 			*val = (!!(lc->admin_caps & FW_PORT_CAP32_FC_TX)) ^
562 			    (!!(lc->admin_caps & FW_PORT_CAP32_FC_RX));
563 		break;
564 
565 	/* Advertised pause capability */
566 	case ETHER_STAT_ADV_CAP_PAUSE:
567 		if (lc->pcaps & FW_PORT_CAP32_802_3_PAUSE)
568 			*val = !!(lc->admin_caps & FW_PORT_CAP32_802_3_PAUSE);
569 		else
570 			*val = !!(lc->admin_caps & FW_PORT_CAP32_FC_TX);
571 		break;
572 
573 	case ETHER_STAT_ADV_CAP_100GFDX:
574 		*val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_100G);
575 		break;
576 
577 	case ETHER_STAT_ADV_CAP_50GFDX:
578 		*val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_50G);
579 		break;
580 
581 	case ETHER_STAT_ADV_CAP_40GFDX:
582 		*val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_40G);
583 		break;
584 
585 	case ETHER_STAT_ADV_CAP_25GFDX:
586 		*val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_25G);
587 		break;
588 
589 	case ETHER_STAT_ADV_CAP_10GFDX:
590 		*val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_10G);
591 		break;
592 
593 	case ETHER_STAT_ADV_CAP_1000FDX:
594 		*val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_1G);
595 		break;
596 
597 	case ETHER_STAT_ADV_CAP_100FDX:
598 		*val = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_100M);
599 		break;
600 
601 	case ETHER_STAT_ADV_CAP_AUTONEG:
602 		*val = !!(lc->admin_caps & FW_PORT_CAP32_ANEG);
603 		break;
604 
605 	case ETHER_STAT_ADV_CAP_1000HDX:
606 	case ETHER_STAT_ADV_CAP_100HDX:
607 	case ETHER_STAT_ADV_CAP_10FDX:
608 	case ETHER_STAT_ADV_CAP_10HDX:
609 		return (ENOTSUP);	/* TODO */
610 
611 	case ETHER_STAT_LP_CAP_ASMPAUSE:
612 		if (!(lc->acaps & FW_PORT_CAP32_ANEG))
613 			return (ENOTSUP);
614 
615 		if (lc->pcaps & FW_PORT_CAP32_802_3_ASM_DIR)
616 			*val = !!(lc->lpacaps & FW_PORT_CAP32_802_3_ASM_DIR);
617 		else
618 			*val = (!!(lc->lpacaps & FW_PORT_CAP32_FC_TX)) ^
619 			    (!!(lc->lpacaps & FW_PORT_CAP32_FC_RX));
620 		break;
621 
622 	case ETHER_STAT_LP_CAP_PAUSE:
623 		if (!(lc->acaps & FW_PORT_CAP32_ANEG))
624 			return (ENOTSUP);
625 
626 		if (lc->pcaps & FW_PORT_CAP32_802_3_PAUSE)
627 			*val = !!(lc->lpacaps & FW_PORT_CAP32_802_3_PAUSE);
628 		else
629 			*val = !!(lc->lpacaps & FW_PORT_CAP32_FC_TX);
630 		break;
631 
632 	case ETHER_STAT_LP_CAP_100GFDX:
633 		if (!(lc->acaps & FW_PORT_CAP32_ANEG))
634 			return (ENOTSUP);
635 
636 		*val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_100G);
637 		break;
638 
639 	case ETHER_STAT_LP_CAP_50GFDX:
640 		if (!(lc->acaps & FW_PORT_CAP32_ANEG))
641 			return (ENOTSUP);
642 
643 		*val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_50G);
644 		break;
645 
646 	case ETHER_STAT_LP_CAP_40GFDX:
647 		if (!(lc->acaps & FW_PORT_CAP32_ANEG))
648 			return (ENOTSUP);
649 
650 		*val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_40G);
651 		break;
652 
653 	case ETHER_STAT_LP_CAP_25GFDX:
654 		if (!(lc->acaps & FW_PORT_CAP32_ANEG))
655 			return (ENOTSUP);
656 
657 		*val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_25G);
658 		break;
659 
660 	case ETHER_STAT_LP_CAP_10GFDX:
661 		if (!(lc->acaps & FW_PORT_CAP32_ANEG))
662 			return (ENOTSUP);
663 
664 		*val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_10G);
665 		break;
666 
667 	case ETHER_STAT_LP_CAP_1000FDX:
668 		if (!(lc->acaps & FW_PORT_CAP32_ANEG))
669 			return (ENOTSUP);
670 
671 		*val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_1G);
672 		break;
673 
674 	case ETHER_STAT_LP_CAP_100FDX:
675 		if (!(lc->acaps & FW_PORT_CAP32_ANEG))
676 			return (ENOTSUP);
677 
678 		*val = !!(lc->lpacaps & FW_PORT_CAP32_SPEED_100M);
679 		break;
680 
681 	case ETHER_STAT_LP_CAP_AUTONEG:
682 		if (!(lc->acaps & FW_PORT_CAP32_ANEG))
683 			return (ENOTSUP);
684 
685 		*val = !!(lc->lpacaps & FW_PORT_CAP32_ANEG);
686 		break;
687 
688 	case ETHER_STAT_LP_CAP_1000HDX:
689 	case ETHER_STAT_LP_CAP_100HDX:
690 	case ETHER_STAT_LP_CAP_10FDX:
691 	case ETHER_STAT_LP_CAP_10HDX:
692 		return (ENOTSUP);
693 
694 	case ETHER_STAT_LINK_ASMPAUSE:
695 		*val = (!!(lc->link_caps & FW_PORT_CAP32_FC_TX)) ^
696 		    (!!(lc->link_caps & FW_PORT_CAP32_FC_RX));
697 		break;
698 
699 	case ETHER_STAT_LINK_PAUSE:
700 		*val = !!(lc->link_caps & FW_PORT_CAP32_FC_TX);
701 		break;
702 
703 	case ETHER_STAT_LINK_AUTONEG:
704 		*val = !!(lc->link_caps & FW_PORT_CAP32_ANEG);
705 		break;
706 
707 	case ETHER_STAT_LINK_DUPLEX:
708 		if (lc->link_ok != 0)
709 			*val = LINK_DUPLEX_FULL;
710 		else
711 			*val = LINK_DUPLEX_UNKNOWN;
712 		break;
713 
714 	default:
715 		return (ENOTSUP);
716 	}
717 #undef GET_STAT
718 
719 	return (0);
720 }
721 
722 static int
t4_mc_start(void * arg)723 t4_mc_start(void *arg)
724 {
725 	struct port_info *pi = arg;
726 
727 	ADAPTER_LOCK(pi->adapter);
728 	const int rc = t4_init_synchronized(pi);
729 	ADAPTER_UNLOCK(pi->adapter);
730 
731 	return (rc);
732 }
733 
734 static void
t4_mc_stop(void * arg)735 t4_mc_stop(void *arg)
736 {
737 	struct port_info *pi = arg;
738 
739 	ADAPTER_LOCK(pi->adapter);
740 	(void) t4_uninit_synchronized(pi);
741 	ADAPTER_UNLOCK(pi->adapter);
742 }
743 
744 static int
t4_mc_setpromisc(void * arg,boolean_t on)745 t4_mc_setpromisc(void *arg, boolean_t on)
746 {
747 	struct port_info *pi = arg;
748 	struct adapter *sc = pi->adapter;
749 	int rc;
750 
751 	ADAPTER_LOCK(sc);
752 	rc = -t4_set_rxmode(sc, sc->mbox, pi->viid, -1, on ? 1 : 0, -1, -1, -1,
753 	    false);
754 	ADAPTER_UNLOCK(sc);
755 
756 	return (rc);
757 }
758 
759 /*
760  * TODO: Starts failing as soon as the 336 entry table fills up.  Need to use
761  * hash in that case.
762  */
763 static int
t4_mc_multicst(void * arg,boolean_t add,const uint8_t * mcaddr)764 t4_mc_multicst(void *arg, boolean_t add, const uint8_t *mcaddr)
765 {
766 	struct port_info *pi = arg;
767 	struct adapter *sc = pi->adapter;
768 	struct fw_vi_mac_cmd c;
769 	int len16, rc;
770 
771 	len16 = howmany(sizeof (c.op_to_viid) + sizeof (c.freemacs_to_len16) +
772 	    sizeof (c.u.exact[0]), 16);
773 	c.op_to_viid = htonl(V_FW_CMD_OP(FW_VI_MAC_CMD) | F_FW_CMD_REQUEST |
774 	    F_FW_CMD_WRITE | V_FW_VI_MAC_CMD_VIID(pi->viid));
775 	c.freemacs_to_len16 = htonl(V_FW_CMD_LEN16(len16));
776 	c.u.exact[0].valid_to_idx = htons(F_FW_VI_MAC_CMD_VALID |
777 	    V_FW_VI_MAC_CMD_IDX(add ? FW_VI_MAC_ADD_MAC :
778 	    FW_VI_MAC_MAC_BASED_FREE));
779 	bcopy(mcaddr, &c.u.exact[0].macaddr, ETHERADDRL);
780 
781 	ADAPTER_LOCK(sc);
782 	rc = -t4_wr_mbox_meat(sc, sc->mbox, &c, len16 * 16, &c, true);
783 	ADAPTER_UNLOCK(sc);
784 	if (rc != 0)
785 		return (rc);
786 #ifdef DEBUG
787 	/*
788 	 * TODO: Firmware doesn't seem to return the correct index on removal
789 	 * (it gives back 0x3fd FW_VI_MAC_MAC_BASED_FREE unchanged. Remove this
790 	 * code once it is fixed.
791 	 */
792 	else {
793 		uint16_t idx;
794 
795 		idx = G_FW_VI_MAC_CMD_IDX(ntohs(c.u.exact[0].valid_to_idx));
796 		cxgb_printf(pi->dip, CE_NOTE,
797 		    "%02x:%02x:%02x:%02x:%02x:%02x %s %d", mcaddr[0],
798 		    mcaddr[1], mcaddr[2], mcaddr[3], mcaddr[4], mcaddr[5],
799 		    add ? "added at index" : "removed from index", idx);
800 	}
801 #endif
802 
803 	return (0);
804 }
805 
806 int
t4_mc_unicst(void * arg,const uint8_t * ucaddr)807 t4_mc_unicst(void *arg, const uint8_t *ucaddr)
808 {
809 	struct port_info *pi = arg;
810 	struct adapter *sc = pi->adapter;
811 	int rc;
812 
813 	if (ucaddr == NULL)
814 		return (EINVAL);
815 
816 	ADAPTER_LOCK(sc);
817 
818 	/* We will support adding only one mac address */
819 	if (pi->adapter->props.multi_rings && pi->macaddr_cnt) {
820 		ADAPTER_UNLOCK(sc);
821 		return (ENOSPC);
822 	}
823 	rc = t4_change_mac(sc, sc->mbox, pi->viid, pi->xact_addr_filt, ucaddr,
824 	    true, &pi->smt_idx);
825 	if (rc < 0) {
826 		rc = -rc;
827 	} else {
828 		pi->macaddr_cnt++;
829 		pi->xact_addr_filt = rc;
830 		rc = 0;
831 	}
832 	ADAPTER_UNLOCK(sc);
833 
834 	return (rc);
835 }
836 
837 int
t4_addmac(void * arg,const uint8_t * ucaddr)838 t4_addmac(void *arg, const uint8_t *ucaddr)
839 {
840 	return (t4_mc_unicst(arg, ucaddr));
841 }
842 
843 static int
t4_remmac(void * arg,const uint8_t * mac_addr)844 t4_remmac(void *arg, const uint8_t *mac_addr)
845 {
846 	struct port_info *pi = arg;
847 
848 	ADAPTER_LOCK(pi->adapter);
849 	pi->macaddr_cnt--;
850 	ADAPTER_UNLOCK(pi->adapter);
851 
852 	return (0);
853 }
854 
855 /*
856  * Callback funtion for MAC layer to register all groups.
857  */
858 void
t4_fill_group(void * arg,mac_ring_type_t rtype,const int rg_index,mac_group_info_t * infop,mac_group_handle_t gh)859 t4_fill_group(void *arg, mac_ring_type_t rtype, const int rg_index,
860     mac_group_info_t *infop, mac_group_handle_t gh)
861 {
862 	struct port_info *pi = arg;
863 
864 	switch (rtype) {
865 	case MAC_RING_TYPE_RX: {
866 		infop->mgi_driver = (mac_group_driver_t)arg;
867 		infop->mgi_start = NULL;
868 		infop->mgi_stop = NULL;
869 		infop->mgi_addmac = t4_addmac;
870 		infop->mgi_remmac = t4_remmac;
871 		infop->mgi_count = pi->nrxq;
872 		break;
873 	}
874 	case MAC_RING_TYPE_TX:
875 	default:
876 		ASSERT(0);
877 		break;
878 	}
879 }
880 
881 static int
t4_ring_start(mac_ring_driver_t rh,uint64_t mr_gen_num)882 t4_ring_start(mac_ring_driver_t rh, uint64_t mr_gen_num)
883 {
884 	struct sge_rxq *rxq = (struct sge_rxq *)rh;
885 
886 	RXQ_LOCK(rxq);
887 	rxq->ring_gen_num = mr_gen_num;
888 	RXQ_UNLOCK(rxq);
889 	return (0);
890 }
891 
892 /*
893  * Enable interrupt on the specificed rx ring.
894  */
895 int
t4_ring_intr_enable(mac_intr_handle_t intrh)896 t4_ring_intr_enable(mac_intr_handle_t intrh)
897 {
898 	struct sge_rxq *rxq = (struct sge_rxq *)intrh;
899 	struct sge_iq *iq = &rxq->iq;
900 
901 	RXQ_LOCK(rxq);
902 	iq->polling = 0;
903 	iq->state = IQS_IDLE;
904 	t4_iq_gts_update(iq, iq->intr_params, 0);
905 	RXQ_UNLOCK(rxq);
906 	return (0);
907 }
908 
909 /*
910  * Disable interrupt on the specificed rx ring.
911  */
912 int
t4_ring_intr_disable(mac_intr_handle_t intrh)913 t4_ring_intr_disable(mac_intr_handle_t intrh)
914 {
915 	struct sge_rxq *rxq = (struct sge_rxq *)intrh;
916 	struct sge_iq *iq;
917 
918 	/*
919 	 * Nothing to be done here WRT the interrupt, as it will not fire until
920 	 * re-enabled through the t4_iq_gts_update() in t4_ring_intr_enable().
921 	 */
922 
923 	iq = &rxq->iq;
924 	RXQ_LOCK(rxq);
925 	iq->polling = 1;
926 	iq->state = IQS_BUSY;
927 	RXQ_UNLOCK(rxq);
928 
929 	return (0);
930 }
931 
932 mblk_t *
t4_poll_ring(void * arg,int n_bytes)933 t4_poll_ring(void *arg, int n_bytes)
934 {
935 	struct sge_rxq *rxq = (struct sge_rxq *)arg;
936 	mblk_t *mp = NULL;
937 
938 	ASSERT(n_bytes >= 0);
939 	if (n_bytes == 0)
940 		return (NULL);
941 
942 	RXQ_LOCK(rxq);
943 	mp = t4_ring_rx(rxq, n_bytes);
944 	RXQ_UNLOCK(rxq);
945 
946 	return (mp);
947 }
948 
949 /*
950  * Retrieve a value for one of the statistics for a particular rx ring
951  */
952 int
t4_rx_stat(mac_ring_driver_t rh,uint_t stat,uint64_t * val)953 t4_rx_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
954 {
955 	struct sge_rxq *rxq = (struct sge_rxq *)rh;
956 
957 	switch (stat) {
958 	case MAC_STAT_RBYTES:
959 		*val = rxq->rxbytes;
960 		break;
961 
962 	case MAC_STAT_IPACKETS:
963 		*val = rxq->rxpkts;
964 		break;
965 
966 	default:
967 		*val = 0;
968 		return (ENOTSUP);
969 	}
970 
971 	return (0);
972 }
973 
974 /*
975  * Retrieve a value for one of the statistics for a particular tx ring
976  */
977 int
t4_tx_stat(mac_ring_driver_t rh,uint_t stat,uint64_t * val)978 t4_tx_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
979 {
980 	struct sge_txq *txq = (struct sge_txq *)rh;
981 
982 	switch (stat) {
983 	case MAC_STAT_RBYTES:
984 		*val = txq->txbytes;
985 		break;
986 
987 	case MAC_STAT_IPACKETS:
988 		*val = txq->txpkts;
989 		break;
990 
991 	default:
992 		*val = 0;
993 		return (ENOTSUP);
994 	}
995 
996 	return (0);
997 }
998 
999 /*
1000  * Callback funtion for MAC layer to register all rings
1001  * for given ring_group, noted by group_index.
1002  * Since we have only one group, ring index becomes
1003  * absolute index.
1004  */
1005 void
t4_fill_ring(void * arg,mac_ring_type_t rtype,const int group_index,const int ring_index,mac_ring_info_t * infop,mac_ring_handle_t rh)1006 t4_fill_ring(void *arg, mac_ring_type_t rtype, const int group_index,
1007     const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh)
1008 {
1009 	struct port_info *pi = arg;
1010 	mac_intr_t *mintr;
1011 
1012 	switch (rtype) {
1013 	case MAC_RING_TYPE_RX: {
1014 		struct sge_rxq *rxq;
1015 
1016 		rxq = &pi->adapter->sge.rxq[pi->first_rxq + ring_index];
1017 		rxq->ring_handle = rh;
1018 
1019 		infop->mri_driver = (mac_ring_driver_t)rxq;
1020 		infop->mri_start = t4_ring_start;
1021 		infop->mri_stop = NULL;
1022 		infop->mri_poll = t4_poll_ring;
1023 		infop->mri_stat = t4_rx_stat;
1024 
1025 		mintr = &infop->mri_intr;
1026 		mintr->mi_handle = (mac_intr_handle_t)rxq;
1027 		mintr->mi_enable = t4_ring_intr_enable;
1028 		mintr->mi_disable = t4_ring_intr_disable;
1029 
1030 		break;
1031 	}
1032 	case MAC_RING_TYPE_TX: {
1033 		struct sge_txq *txq =
1034 		    &pi->adapter->sge.txq[pi->first_txq + ring_index];
1035 		txq->ring_handle = rh;
1036 		infop->mri_driver = (mac_ring_driver_t)txq;
1037 		infop->mri_start = NULL;
1038 		infop->mri_stop = NULL;
1039 		infop->mri_tx = t4_eth_tx;
1040 		infop->mri_stat = t4_tx_stat;
1041 		break;
1042 	}
1043 	default:
1044 		ASSERT(0);
1045 		break;
1046 	}
1047 }
1048 
1049 mblk_t *
t4_mc_tx(void * arg,mblk_t * m)1050 t4_mc_tx(void *arg, mblk_t *m)
1051 {
1052 	struct port_info *pi = arg;
1053 	struct adapter *sc = pi->adapter;
1054 	struct sge_txq *txq = &sc->sge.txq[pi->first_txq];
1055 
1056 	return (t4_eth_tx(txq, m));
1057 }
1058 
1059 static int
t4_mc_transceiver_info(void * arg,uint_t id,mac_transceiver_info_t * infop)1060 t4_mc_transceiver_info(void *arg, uint_t id, mac_transceiver_info_t *infop)
1061 {
1062 	struct port_info *pi = arg;
1063 
1064 	if (id != 0 || infop == NULL)
1065 		return (EINVAL);
1066 
1067 	switch (pi->mod_type) {
1068 	case FW_PORT_MOD_TYPE_NONE:
1069 		mac_transceiver_info_set_present(infop, B_FALSE);
1070 		break;
1071 	case FW_PORT_MOD_TYPE_NOTSUPPORTED:
1072 		mac_transceiver_info_set_present(infop, B_TRUE);
1073 		mac_transceiver_info_set_usable(infop, B_FALSE);
1074 		break;
1075 	default:
1076 		mac_transceiver_info_set_present(infop, B_TRUE);
1077 		mac_transceiver_info_set_usable(infop, B_TRUE);
1078 		break;
1079 	}
1080 
1081 	return (0);
1082 }
1083 
1084 static int
t4_mc_transceiver_read(void * arg,uint_t id,uint_t page,void * bp,size_t nbytes,off_t offset,size_t * nread)1085 t4_mc_transceiver_read(void *arg, uint_t id, uint_t page, void *bp,
1086     size_t nbytes, off_t offset, size_t *nread)
1087 {
1088 	struct port_info *pi = arg;
1089 	struct adapter *sc = pi->adapter;
1090 	int rc;
1091 
1092 	if (id != 0 || bp == NULL || nbytes == 0 || nread == NULL ||
1093 	    (page != 0xa0 && page != 0xa2) || offset < 0)
1094 		return (EINVAL);
1095 
1096 	if (nbytes > 256 || offset >= 256 || (offset + nbytes > 256))
1097 		return (EINVAL);
1098 
1099 	ADAPTER_LOCK(sc);
1100 	/*
1101 	 * Firmware has a maximum size that we can read. Don't read more than it
1102 	 * allows.
1103 	 */
1104 	const size_t maxread = sizeof (((struct fw_ldst_cmd *)0)->u.i2c.data);
1105 	for (size_t i = 0; i < nbytes; i += maxread) {
1106 		size_t toread = MIN(maxread, nbytes - i);
1107 		rc = -t4_i2c_rd(sc, sc->mbox, pi->port_id, page, offset, toread,
1108 		    bp);
1109 		if (rc != 0)
1110 			break;
1111 		offset += toread;
1112 		bp = (void *)((uintptr_t)bp + toread);
1113 	}
1114 	ADAPTER_UNLOCK(sc);
1115 
1116 	if (rc == 0)
1117 		*nread = nbytes;
1118 	return (rc);
1119 }
1120 
1121 static int
t4_port_led_set(void * arg,mac_led_mode_t mode,uint_t flags)1122 t4_port_led_set(void *arg, mac_led_mode_t mode, uint_t flags)
1123 {
1124 	struct port_info *pi = arg;
1125 	struct adapter *sc = pi->adapter;
1126 	int val, rc;
1127 
1128 	if (flags != 0)
1129 		return (EINVAL);
1130 
1131 	switch (mode) {
1132 	case MAC_LED_DEFAULT:
1133 		val = 0;
1134 		break;
1135 	case MAC_LED_IDENT:
1136 		val = 0xffff;
1137 		break;
1138 
1139 	default:
1140 		return (ENOTSUP);
1141 	}
1142 
1143 	ADAPTER_LOCK(sc);
1144 	rc = -t4_identify_port(sc, sc->mbox, pi->viid, val);
1145 	ADAPTER_UNLOCK(sc);
1146 
1147 	return (rc);
1148 }
1149 
1150 static boolean_t
t4_mc_getcapab(void * arg,mac_capab_t cap,void * data)1151 t4_mc_getcapab(void *arg, mac_capab_t cap, void *data)
1152 {
1153 	struct port_info *pi = arg;
1154 	boolean_t status = B_TRUE;
1155 	mac_capab_transceiver_t *mct;
1156 	mac_capab_led_t *mcl;
1157 
1158 	switch (cap) {
1159 	case MAC_CAPAB_HCKSUM:
1160 		if (pi->features & CXGBE_HW_CSUM) {
1161 			uint32_t *d = data;
1162 			*d = HCKSUM_INET_FULL_V4 | HCKSUM_IPHDRCKSUM |
1163 			    HCKSUM_INET_FULL_V6;
1164 		} else
1165 			status = B_FALSE;
1166 		break;
1167 
1168 	case MAC_CAPAB_LSO:
1169 		/* Enabling LSO requires Checksum offloading */
1170 		if (pi->features & CXGBE_HW_LSO &&
1171 		    pi->features & CXGBE_HW_CSUM) {
1172 			mac_capab_lso_t *d = data;
1173 
1174 			d->lso_flags = LSO_TX_BASIC_TCP_IPV4 |
1175 			    LSO_TX_BASIC_TCP_IPV6;
1176 			d->lso_basic_tcp_ipv4.lso_max = 65535;
1177 			d->lso_basic_tcp_ipv6.lso_max = 65535;
1178 		} else
1179 			status = B_FALSE;
1180 		break;
1181 
1182 	case MAC_CAPAB_RINGS: {
1183 		mac_capab_rings_t *cap_rings = data;
1184 
1185 		if (!pi->adapter->props.multi_rings) {
1186 			status = B_FALSE;
1187 			break;
1188 		}
1189 		switch (cap_rings->mr_type) {
1190 		case MAC_RING_TYPE_RX:
1191 			cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
1192 			cap_rings->mr_rnum = pi->nrxq;
1193 			cap_rings->mr_gnum = 1;
1194 			cap_rings->mr_rget = t4_fill_ring;
1195 			cap_rings->mr_gget = t4_fill_group;
1196 			cap_rings->mr_gaddring = NULL;
1197 			cap_rings->mr_gremring = NULL;
1198 			break;
1199 		case MAC_RING_TYPE_TX:
1200 			cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
1201 			cap_rings->mr_rnum = pi->ntxq;
1202 			cap_rings->mr_gnum = 0;
1203 			cap_rings->mr_rget = t4_fill_ring;
1204 			cap_rings->mr_gget = NULL;
1205 			break;
1206 		}
1207 		break;
1208 	}
1209 
1210 	case MAC_CAPAB_TRANSCEIVER:
1211 		mct = data;
1212 
1213 		mct->mct_flags = 0;
1214 		mct->mct_ntransceivers = 1;
1215 		mct->mct_info = t4_mc_transceiver_info;
1216 		mct->mct_read = t4_mc_transceiver_read;
1217 		break;
1218 	case MAC_CAPAB_LED:
1219 		mcl = data;
1220 		mcl->mcl_flags = 0;
1221 		mcl->mcl_modes = MAC_LED_DEFAULT | MAC_LED_IDENT;
1222 		mcl->mcl_set = t4_port_led_set;
1223 		break;
1224 
1225 	default:
1226 		status = B_FALSE; /* cap not supported */
1227 	}
1228 
1229 	return (status);
1230 }
1231 
1232 static void
t4_mac_link_caps_to_flowctrl(fw_port_cap32_t caps,link_flowctrl_t * fc)1233 t4_mac_link_caps_to_flowctrl(fw_port_cap32_t caps, link_flowctrl_t *fc)
1234 {
1235 	u8 pause_tx = 0, pause_rx = 0;
1236 
1237 	if (caps & FW_PORT_CAP32_FC_TX)
1238 		pause_tx = 1;
1239 
1240 	if (caps & FW_PORT_CAP32_FC_RX)
1241 		pause_rx = 1;
1242 
1243 	if (pause_rx & pause_tx)
1244 		*fc = LINK_FLOWCTRL_BI;
1245 	else if (pause_tx)
1246 		*fc = LINK_FLOWCTRL_TX;
1247 	else if (pause_rx)
1248 		*fc = LINK_FLOWCTRL_RX;
1249 	else
1250 		*fc = LINK_FLOWCTRL_NONE;
1251 }
1252 
1253 static int
t4_mac_flowctrl_to_link_caps(struct port_info * pi,link_flowctrl_t fc,fw_port_cap32_t * new_caps)1254 t4_mac_flowctrl_to_link_caps(struct port_info *pi, link_flowctrl_t fc,
1255     fw_port_cap32_t *new_caps)
1256 {
1257 	cc_pause_t pause = 0;
1258 
1259 	switch (fc) {
1260 	case LINK_FLOWCTRL_BI:
1261 		pause |= PAUSE_TX | PAUSE_RX;
1262 		break;
1263 	case LINK_FLOWCTRL_TX:
1264 		pause |= PAUSE_TX;
1265 		break;
1266 	case LINK_FLOWCTRL_RX:
1267 		pause |= PAUSE_RX;
1268 		break;
1269 	default:
1270 		break;
1271 	}
1272 
1273 	if (pi->link_cfg.admin_caps & FW_PORT_CAP32_ANEG)
1274 		pause |= PAUSE_AUTONEG;
1275 
1276 	return (t4_link_set_pause(pi, pause, new_caps));
1277 }
1278 
1279 static link_fec_t
t4_mac_port_caps_to_fec_cap(fw_port_cap32_t caps)1280 t4_mac_port_caps_to_fec_cap(fw_port_cap32_t caps)
1281 {
1282 	link_fec_t link_fec = 0;
1283 
1284 	if (caps & FW_PORT_CAP32_FEC_RS)
1285 		link_fec |= LINK_FEC_RS;
1286 
1287 	if (caps & FW_PORT_CAP32_FEC_BASER_RS)
1288 		link_fec |= LINK_FEC_BASE_R;
1289 
1290 	if (caps & FW_PORT_CAP32_FEC_NO_FEC)
1291 		link_fec |= LINK_FEC_NONE;
1292 
1293 	if ((link_fec & (link_fec - 1)) &&
1294 	    !(caps & FW_PORT_CAP32_FORCE_FEC))
1295 		return (LINK_FEC_AUTO);
1296 
1297 	return (link_fec);
1298 }
1299 
1300 static void
t4_mac_admin_caps_to_fec_cap(fw_port_cap32_t caps,link_fec_t * fec)1301 t4_mac_admin_caps_to_fec_cap(fw_port_cap32_t caps, link_fec_t *fec)
1302 {
1303 	*fec = t4_mac_port_caps_to_fec_cap(caps);
1304 }
1305 
1306 static void
t4_mac_link_caps_to_fec_cap(fw_port_cap32_t caps,link_fec_t * fec)1307 t4_mac_link_caps_to_fec_cap(fw_port_cap32_t caps, link_fec_t *fec)
1308 {
1309 	link_fec_t link_fec;
1310 
1311 	caps &= ~FW_PORT_CAP32_FEC_NO_FEC;
1312 	link_fec = t4_mac_port_caps_to_fec_cap(caps);
1313 	*fec = link_fec ? link_fec : LINK_FEC_NONE;
1314 }
1315 
1316 static int
t4_mac_fec_cap_to_link_caps(struct port_info * pi,link_fec_t v,fw_port_cap32_t * new_caps)1317 t4_mac_fec_cap_to_link_caps(struct port_info *pi, link_fec_t v,
1318     fw_port_cap32_t *new_caps)
1319 {
1320 	cc_fec_t fec = 0;
1321 
1322 	if (v == LINK_FEC_AUTO) {
1323 		fec = FEC_AUTO;
1324 		goto out;
1325 	}
1326 
1327 	if (v & LINK_FEC_NONE) {
1328 		v &= ~LINK_FEC_NONE;
1329 		fec |= FEC_NONE;
1330 	}
1331 
1332 	if (v & LINK_FEC_RS) {
1333 		v &= ~LINK_FEC_RS;
1334 		fec |= FEC_RS;
1335 	}
1336 
1337 	if (v & LINK_FEC_BASE_R) {
1338 		v &= ~LINK_FEC_BASE_R;
1339 		fec |= FEC_BASER_RS;
1340 	}
1341 
1342 	if (v != 0)
1343 		return (-1);
1344 
1345 	ASSERT3S(fec, !=, 0);
1346 
1347 	fec |= FEC_FORCE;
1348 
1349 out:
1350 	return (t4_link_set_fec(pi, fec, new_caps));
1351 }
1352 
1353 /* ARGSUSED */
1354 static int
t4_mc_setprop(void * arg,const char * name,mac_prop_id_t id,uint_t size,const void * val)1355 t4_mc_setprop(void *arg, const char *name, mac_prop_id_t id, uint_t size,
1356     const void *val)
1357 {
1358 	struct port_info *pi = arg;
1359 	struct adapter *sc = pi->adapter;
1360 	struct link_config *lc = &pi->link_cfg;
1361 	fw_port_cap32_t new_caps = lc->admin_caps;
1362 	int relink = 0, rx_mode = 0, rc = 0;
1363 	uint32_t v32 = *(uint32_t *)val;
1364 	uint8_t v8 = *(uint8_t *)val;
1365 
1366 	switch (id) {
1367 	case MAC_PROP_AUTONEG:
1368 		rc = t4_link_set_autoneg(pi, v8, &new_caps);
1369 		relink = 1;
1370 		break;
1371 
1372 	case MAC_PROP_MTU:
1373 		if (v32 < 46 || v32 > MAX_MTU) {
1374 			rc = EINVAL;
1375 		} else if (v32 != pi->mtu) {
1376 			pi->mtu = v32;
1377 			(void) mac_maxsdu_update(pi->mh, v32);
1378 			rx_mode = 1;
1379 		}
1380 		break;
1381 
1382 	case MAC_PROP_FLOWCTRL:
1383 		rc = t4_mac_flowctrl_to_link_caps(pi,
1384 		    *(const link_flowctrl_t *)val, &new_caps);
1385 		relink = 1;
1386 		break;
1387 
1388 	case MAC_PROP_EN_FEC_CAP:
1389 		rc = t4_mac_fec_cap_to_link_caps(pi,
1390 		    *(const link_fec_t *)val, &new_caps);
1391 		relink = 1;
1392 		break;
1393 
1394 	case MAC_PROP_EN_100GFDX_CAP:
1395 		rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_100G, v8,
1396 		    &new_caps);
1397 		relink = 1;
1398 		break;
1399 
1400 	case MAC_PROP_EN_50GFDX_CAP:
1401 		rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_50G, v8,
1402 		    &new_caps);
1403 		relink = 1;
1404 		break;
1405 
1406 	case MAC_PROP_EN_40GFDX_CAP:
1407 		rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_40G, v8,
1408 		    &new_caps);
1409 		relink = 1;
1410 		break;
1411 
1412 	case MAC_PROP_EN_25GFDX_CAP:
1413 		rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_25G, v8,
1414 		    &new_caps);
1415 		relink = 1;
1416 		break;
1417 
1418 	case MAC_PROP_EN_10GFDX_CAP:
1419 		rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_10G, v8,
1420 		    &new_caps);
1421 		relink = 1;
1422 		break;
1423 
1424 	case MAC_PROP_EN_1000FDX_CAP:
1425 		rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_1G, v8,
1426 		    &new_caps);
1427 		relink = 1;
1428 		break;
1429 
1430 	case MAC_PROP_EN_100FDX_CAP:
1431 		rc = t4_link_set_speed(pi, FW_PORT_CAP32_SPEED_100M, v8,
1432 		    &new_caps);
1433 		relink = 1;
1434 		break;
1435 
1436 	case MAC_PROP_PRIVATE:
1437 		return (t4_setprop_priv(pi, name, val));
1438 
1439 	default:
1440 		rc = ENOTSUP;
1441 		break;
1442 	}
1443 
1444 	if (rc != 0)
1445 		return (rc);
1446 
1447 	if ((pi->flags & TPF_OPEN) != 0) {
1448 		if (relink != 0) {
1449 			ADAPTER_LOCK(sc);
1450 			rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc,
1451 			    new_caps);
1452 			ADAPTER_UNLOCK(sc);
1453 			if (rc != 0) {
1454 				cxgb_printf(pi->dip, CE_WARN,
1455 				    "%s link config failed: %d", __func__, rc);
1456 				return (rc);
1457 			}
1458 		}
1459 
1460 		if (rx_mode != 0) {
1461 			ADAPTER_LOCK(sc);
1462 			rc = -t4_set_rxmode(sc, sc->mbox, pi->viid, v32, -1,
1463 			    -1, -1, -1, false);
1464 			ADAPTER_UNLOCK(sc);
1465 			if (rc != 0) {
1466 				cxgb_printf(pi->dip, CE_WARN,
1467 				    "set_rxmode failed: %d", rc);
1468 				return (rc);
1469 			}
1470 		}
1471 	}
1472 
1473 	if (relink != 0)
1474 		lc->admin_caps = new_caps;
1475 
1476 	return (0);
1477 }
1478 
1479 static int
t4_mc_getprop(void * arg,const char * name,mac_prop_id_t id,uint_t size,void * val)1480 t4_mc_getprop(void *arg, const char *name, mac_prop_id_t id, uint_t size,
1481     void *val)
1482 {
1483 	struct port_info *pi = arg;
1484 	struct link_config *lc = &pi->link_cfg;
1485 	uint8_t *u = val;
1486 	int rc = 0;
1487 
1488 	switch (id) {
1489 	case MAC_PROP_DUPLEX:
1490 		*(link_duplex_t *)val = lc->link_ok ? LINK_DUPLEX_FULL :
1491 		    LINK_DUPLEX_UNKNOWN;
1492 		break;
1493 
1494 	case MAC_PROP_SPEED:
1495 		if (lc->link_ok != 0) {
1496 			*(uint64_t *)val =
1497 			    t4_link_fwcap_to_speed(lc->link_caps);
1498 			*(uint64_t *)val *= 1000000;
1499 		} else {
1500 			*(uint64_t *)val = 0;
1501 		}
1502 		break;
1503 
1504 	case MAC_PROP_STATUS:
1505 		*(link_state_t *)val = lc->link_ok ? LINK_STATE_UP :
1506 		    LINK_STATE_DOWN;
1507 		break;
1508 
1509 	case MAC_PROP_MEDIA:
1510 		*(mac_ether_media_t *)val = t4_port_to_media(pi);
1511 		break;
1512 
1513 	case MAC_PROP_AUTONEG:
1514 		*u = !!(lc->link_caps & FW_PORT_CAP32_ANEG);
1515 		break;
1516 
1517 	case MAC_PROP_MTU:
1518 		*(uint32_t *)val = pi->mtu;
1519 		break;
1520 
1521 	case MAC_PROP_FLOWCTRL:
1522 		t4_mac_link_caps_to_flowctrl(lc->link_caps, val);
1523 		break;
1524 
1525 	case MAC_PROP_ADV_FEC_CAP:
1526 		t4_mac_link_caps_to_fec_cap(lc->link_caps, val);
1527 		break;
1528 
1529 	case MAC_PROP_EN_FEC_CAP:
1530 		t4_mac_admin_caps_to_fec_cap(lc->admin_caps, val);
1531 		break;
1532 
1533 	case MAC_PROP_ADV_100GFDX_CAP:
1534 		*u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_100G);
1535 		break;
1536 
1537 	case MAC_PROP_EN_100GFDX_CAP:
1538 		*u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_100G);
1539 		break;
1540 
1541 	case MAC_PROP_ADV_50GFDX_CAP:
1542 		*u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_50G);
1543 		break;
1544 
1545 	case MAC_PROP_EN_50GFDX_CAP:
1546 		*u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_50G);
1547 		break;
1548 
1549 	case MAC_PROP_ADV_40GFDX_CAP:
1550 		*u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_40G);
1551 		break;
1552 
1553 	case MAC_PROP_EN_40GFDX_CAP:
1554 		*u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_40G);
1555 		break;
1556 
1557 	case MAC_PROP_ADV_25GFDX_CAP:
1558 		*u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_25G);
1559 		break;
1560 
1561 	case MAC_PROP_EN_25GFDX_CAP:
1562 		*u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_25G);
1563 		break;
1564 
1565 	case MAC_PROP_ADV_10GFDX_CAP:
1566 		*u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_10G);
1567 		break;
1568 
1569 	case MAC_PROP_EN_10GFDX_CAP:
1570 		*u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_10G);
1571 		break;
1572 
1573 	case MAC_PROP_ADV_1000FDX_CAP:
1574 		*u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_1G);
1575 		break;
1576 
1577 	case MAC_PROP_EN_1000FDX_CAP:
1578 		*u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_1G);
1579 		break;
1580 
1581 	case MAC_PROP_ADV_100FDX_CAP:
1582 		*u = !!(lc->link_caps & FW_PORT_CAP32_SPEED_100M);
1583 		break;
1584 
1585 	case MAC_PROP_EN_100FDX_CAP:
1586 		*u = !!(lc->admin_caps & FW_PORT_CAP32_SPEED_100M);
1587 		break;
1588 
1589 	case MAC_PROP_PRIVATE:
1590 		return (t4_getprop_priv(pi, name, size, val));
1591 
1592 	default:
1593 		return (ENOTSUP);
1594 	}
1595 
1596 	return (rc);
1597 }
1598 
1599 static void
t4_mc_propinfo(void * arg,const char * name,mac_prop_id_t id,mac_prop_info_handle_t ph)1600 t4_mc_propinfo(void *arg, const char *name, mac_prop_id_t id,
1601     mac_prop_info_handle_t ph)
1602 {
1603 	struct port_info *pi = arg;
1604 	struct link_config *lc = &pi->link_cfg;
1605 
1606 	switch (id) {
1607 	case MAC_PROP_DUPLEX:
1608 	case MAC_PROP_SPEED:
1609 	case MAC_PROP_STATUS:
1610 		mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
1611 		break;
1612 
1613 	case MAC_PROP_AUTONEG:
1614 		if (lc->pcaps & FW_PORT_CAP32_ANEG)
1615 			mac_prop_info_set_default_uint8(ph, 1);
1616 		else
1617 			mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
1618 		break;
1619 
1620 	case MAC_PROP_MTU:
1621 		mac_prop_info_set_range_uint32(ph, 46, MAX_MTU);
1622 		break;
1623 
1624 	case MAC_PROP_FLOWCTRL:
1625 		mac_prop_info_set_default_link_flowctrl(ph, LINK_FLOWCTRL_BI);
1626 		break;
1627 
1628 	case MAC_PROP_EN_FEC_CAP:
1629 		mac_prop_info_set_default_fec(ph, LINK_FEC_AUTO);
1630 		break;
1631 
1632 	case MAC_PROP_ADV_FEC_CAP:
1633 		mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
1634 		mac_prop_info_set_default_fec(ph, LINK_FEC_AUTO);
1635 		break;
1636 
1637 	case MAC_PROP_EN_100GFDX_CAP:
1638 		if (lc->pcaps & FW_PORT_CAP32_SPEED_100G)
1639 			mac_prop_info_set_default_uint8(ph, 1);
1640 		else
1641 			mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
1642 		break;
1643 
1644 	case MAC_PROP_EN_50GFDX_CAP:
1645 		if (lc->pcaps & FW_PORT_CAP32_SPEED_50G)
1646 			mac_prop_info_set_default_uint8(ph, 1);
1647 		else
1648 			mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
1649 		break;
1650 
1651 	case MAC_PROP_EN_40GFDX_CAP:
1652 		if (lc->pcaps & FW_PORT_CAP32_SPEED_40G)
1653 			mac_prop_info_set_default_uint8(ph, 1);
1654 		else
1655 			mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
1656 		break;
1657 
1658 	case MAC_PROP_EN_25GFDX_CAP:
1659 		if (lc->pcaps & FW_PORT_CAP32_SPEED_25G)
1660 			mac_prop_info_set_default_uint8(ph, 1);
1661 		else
1662 			mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
1663 		break;
1664 
1665 	case MAC_PROP_EN_10GFDX_CAP:
1666 		if (lc->pcaps & FW_PORT_CAP32_SPEED_10G)
1667 			mac_prop_info_set_default_uint8(ph, 1);
1668 		else
1669 			mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
1670 		break;
1671 
1672 	case MAC_PROP_EN_1000FDX_CAP:
1673 		if (lc->pcaps & FW_PORT_CAP32_SPEED_1G)
1674 			mac_prop_info_set_default_uint8(ph, 1);
1675 		else
1676 			mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
1677 		break;
1678 
1679 	case MAC_PROP_EN_100FDX_CAP:
1680 		if (lc->pcaps & FW_PORT_CAP32_SPEED_100M)
1681 			mac_prop_info_set_default_uint8(ph, 1);
1682 		else
1683 			mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
1684 		break;
1685 
1686 	case MAC_PROP_ADV_100GFDX_CAP:
1687 	case MAC_PROP_ADV_50GFDX_CAP:
1688 	case MAC_PROP_ADV_40GFDX_CAP:
1689 	case MAC_PROP_ADV_25GFDX_CAP:
1690 	case MAC_PROP_ADV_10GFDX_CAP:
1691 	case MAC_PROP_ADV_1000FDX_CAP:
1692 	case MAC_PROP_ADV_100FDX_CAP:
1693 		mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
1694 		break;
1695 
1696 	case MAC_PROP_PRIVATE:
1697 		t4_propinfo_priv(pi, name, ph);
1698 		break;
1699 
1700 	default:
1701 		break;
1702 	}
1703 }
1704 
1705 static int
t4_init_synchronized(struct port_info * pi)1706 t4_init_synchronized(struct port_info *pi)
1707 {
1708 	struct adapter *sc = pi->adapter;
1709 	int rc = 0;
1710 
1711 	ADAPTER_LOCK_ASSERT_OWNED(pi->adapter);
1712 	ASSERT(sc->flags & TAF_INIT_DONE);
1713 
1714 	PORT_LOCK(pi);
1715 
1716 	if ((pi->flags & TPF_OPEN) != 0) {
1717 		PORT_UNLOCK(pi);
1718 		return (0);	/* already running */
1719 	}
1720 
1721 	if (!(pi->flags & TPF_INIT_DONE)) {
1722 		rc = t4_port_full_init(pi);
1723 		if (rc != 0) {
1724 			PORT_UNLOCK(pi);
1725 			return (rc); /* error message displayed already */
1726 		}
1727 	} else {
1728 		t4_port_queues_enable(pi);
1729 	}
1730 
1731 	rc = -t4_set_rxmode(sc, sc->mbox, pi->viid, pi->mtu, 0, 0, 1, 0, false);
1732 	if (rc != 0) {
1733 		cxgb_printf(pi->dip, CE_WARN, "set_rxmode failed: %d", rc);
1734 		goto done;
1735 	}
1736 	rc = t4_change_mac(sc, sc->mbox, pi->viid, pi->xact_addr_filt,
1737 	    pi->hw_addr, true, &pi->smt_idx);
1738 	if (rc < 0) {
1739 		cxgb_printf(pi->dip, CE_WARN, "change_mac failed: %d", rc);
1740 		rc = -rc;
1741 		goto done;
1742 	} else {
1743 		pi->xact_addr_filt = rc;
1744 	}
1745 
1746 	rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, &pi->link_cfg,
1747 	    pi->link_cfg.admin_caps);
1748 	if (rc != 0) {
1749 		cxgb_printf(pi->dip, CE_WARN, "start_link failed: %d", rc);
1750 		goto done;
1751 	}
1752 
1753 	rc = -t4_enable_vi(sc, sc->mbox, pi->viid, true, true);
1754 	if (rc != 0) {
1755 		cxgb_printf(pi->dip, CE_WARN, "enable_vi failed: %d", rc);
1756 		goto done;
1757 	}
1758 
1759 	/* all ok */
1760 	pi->flags |= TPF_OPEN;
1761 done:
1762 	PORT_UNLOCK(pi);
1763 	if (rc != 0)
1764 		(void) t4_uninit_synchronized(pi);
1765 
1766 	return (rc);
1767 }
1768 
1769 /*
1770  * Idempotent.
1771  */
1772 static int
t4_uninit_synchronized(struct port_info * pi)1773 t4_uninit_synchronized(struct port_info *pi)
1774 {
1775 	struct adapter *sc = pi->adapter;
1776 	int rc;
1777 
1778 	ADAPTER_LOCK_ASSERT_OWNED(pi->adapter);
1779 
1780 	PORT_LOCK(pi);
1781 	/*
1782 	 * Disable the VI so that all its data in either direction is discarded
1783 	 * by the MPS.  Leave everything else (the queues, interrupts, and 1Hz
1784 	 * tick) intact as the TP can deliver negative advice or data that it's
1785 	 * holding in its RAM (for an offloaded connection) even after the VI is
1786 	 * disabled.
1787 	 */
1788 	rc = -t4_enable_vi(sc, sc->mbox, pi->viid, false, false);
1789 	if (rc != 0) {
1790 		cxgb_printf(pi->dip, CE_WARN, "disable_vi failed: %d", rc);
1791 		PORT_UNLOCK(pi);
1792 		return (rc);
1793 	}
1794 
1795 	t4_port_queues_disable(pi);
1796 
1797 	pi->flags &= ~TPF_OPEN;
1798 	pi->link_cfg.link_ok = 0;
1799 	PORT_UNLOCK(pi);
1800 
1801 	mac_link_update(pi->mh, LINK_STATE_UNKNOWN);
1802 
1803 	return (0);
1804 }
1805 
1806 static uint_t
t4_convert_holdoff_timer(struct adapter * sc,uint_t idx)1807 t4_convert_holdoff_timer(struct adapter *sc, uint_t idx)
1808 {
1809 	ASSERT(idx < SGE_NTIMERS);
1810 	return (sc->props.holdoff_timer_us[idx]);
1811 }
1812 
1813 static int
t4_convert_holdoff_pktcnt(struct adapter * sc,int idx)1814 t4_convert_holdoff_pktcnt(struct adapter *sc, int idx)
1815 {
1816 	if (idx < 0) {
1817 		return (-1);
1818 	} else {
1819 		ASSERT(idx < SGE_NCOUNTERS);
1820 		return (sc->props.holdoff_pktcnt[idx]);
1821 	}
1822 }
1823 
1824 static uint_t
t4_convert_dbq_timer(struct adapter * sc,uint_t idx)1825 t4_convert_dbq_timer(struct adapter *sc, uint_t idx)
1826 {
1827 	ASSERT(idx < SGE_NDBQTIMERS);
1828 	return (sc->sge.dbq_timers[idx]);
1829 }
1830 
1831 static void
t4_propinfo_priv(struct port_info * pi,const char * name,mac_prop_info_handle_t ph)1832 t4_propinfo_priv(struct port_info *pi, const char *name,
1833     mac_prop_info_handle_t ph)
1834 {
1835 	struct adapter *sc = pi->adapter;
1836 	struct driver_properties *dp = &sc->props;
1837 	struct link_config *lc = &pi->link_cfg;
1838 
1839 	const t4_priv_prop_t *prop = t4_priv_prop_match(name);
1840 	if (prop == NULL || !t4_priv_prop_supported(pi, prop)) {
1841 		return;
1842 	}
1843 
1844 	int v = 0;
1845 	switch (prop->tpp_id) {
1846 	case T4PROP_FW_TMR:
1847 		v = t4_convert_holdoff_timer(sc, sc->props.fwq_tmr_idx);
1848 		break;
1849 	case T4PROP_FW_PKTC:
1850 		v = t4_convert_holdoff_pktcnt(sc, sc->props.fwq_pktc_idx);
1851 		break;
1852 	case T4PROP_RX_TMR:
1853 		v = t4_convert_holdoff_timer(sc, t4_port_is_10xg(pi) ?
1854 		    dp->tmr_idx_10g : dp->tmr_idx_1g);
1855 		break;
1856 	case T4PROP_RX_PKTC:
1857 		v = t4_convert_holdoff_pktcnt(sc, t4_port_is_10xg(pi) ?
1858 		    dp->pktc_idx_10g : dp->pktc_idx_1g);
1859 		break;
1860 	case T4PROP_TX_TMR:
1861 		v = t4_convert_dbq_timer(sc, dp->dbq_timer_idx);
1862 		break;
1863 	case T4PROP_HW_CSUM:
1864 		v = (pi->features & CXGBE_HW_CSUM) ? 1 : 0;
1865 		break;
1866 	case T4PROP_HW_LSO:
1867 		v = (pi->features & CXGBE_HW_LSO) ? 1 : 0;
1868 		break;
1869 	case T4PROP_TX_PAUSE:
1870 		v = (lc->pcaps & FW_PORT_CAP32_FC_TX) ? 1 : 0;
1871 		break;
1872 	case T4PROP_RX_PAUSE:
1873 		v = (lc->pcaps & FW_PORT_CAP32_FC_RX) ? 1 : 0;
1874 		break;
1875 	default:
1876 		return;
1877 	}
1878 
1879 	char str[16];
1880 	(void) snprintf(str, sizeof (str), "%d", v);
1881 	mac_prop_info_set_default_str(ph, str);
1882 }
1883 
1884 static int
t4_getprop_priv(struct port_info * pi,const char * name,uint_t size,void * val)1885 t4_getprop_priv(struct port_info *pi, const char *name, uint_t size, void *val)
1886 {
1887 	struct adapter *sc = pi->adapter;
1888 	struct link_config *lc = &pi->link_cfg;
1889 
1890 	const t4_priv_prop_t *prop = t4_priv_prop_match(name);
1891 	if (prop == NULL || !t4_priv_prop_supported(pi, prop)) {
1892 		return (ENOTSUP);
1893 	}
1894 
1895 	PORT_LOCK(pi);
1896 	int v = 0;
1897 	switch (prop->tpp_id) {
1898 	case T4PROP_FW_TMR:
1899 		v = t4_convert_holdoff_timer(sc, sc->sge.fwq_tmr_idx);
1900 		break;
1901 	case T4PROP_FW_PKTC:
1902 		v = t4_convert_holdoff_pktcnt(sc, sc->sge.fwq_pktc_idx);
1903 		break;
1904 	case T4PROP_RX_TMR:
1905 		v = t4_convert_holdoff_timer(sc, pi->tmr_idx);
1906 		break;
1907 	case T4PROP_RX_PKTC:
1908 		v = t4_convert_holdoff_pktcnt(sc, pi->pktc_idx);
1909 		break;
1910 	case T4PROP_TX_TMR:
1911 		v = t4_convert_dbq_timer(sc, pi->dbq_timer_idx);
1912 		break;
1913 	case T4PROP_HW_CSUM:
1914 		v = (pi->features & CXGBE_HW_CSUM) ? 1 : 0;
1915 		break;
1916 	case T4PROP_HW_LSO:
1917 		v = (pi->features & CXGBE_HW_LSO) ? 1 : 0;
1918 		break;
1919 	case T4PROP_TX_PAUSE:
1920 		v = (lc->link_caps & FW_PORT_CAP32_FC_TX) ? 1 : 0;
1921 		break;
1922 	case T4PROP_RX_PAUSE:
1923 		v = (lc->link_caps & FW_PORT_CAP32_FC_RX) ? 1 : 0;
1924 		break;
1925 	default:
1926 		PORT_UNLOCK(pi);
1927 		return (ENOTSUP);
1928 	}
1929 	PORT_UNLOCK(pi);
1930 
1931 	(void) snprintf(val, size, "%d", v);
1932 	return (0);
1933 }
1934 
1935 #define	ABS_DELTA(left, right)		\
1936 	(((left) > (right)) ? (left) - (right) : (right) - (left))
1937 
1938 uint8_t
t4_choose_holdoff_timer(struct adapter * sc,uint_t target_us)1939 t4_choose_holdoff_timer(struct adapter *sc, uint_t target_us)
1940 {
1941 	const uint_t *timer_us = sc->props.holdoff_timer_us;
1942 
1943 	uint_t delta = UINT_MAX;
1944 	uint_t chosen_idx = 0;
1945 	for (uint_t i = 0; i < SGE_NTIMERS; i++) {
1946 		const uint_t next_delta = ABS_DELTA(target_us, timer_us[i]);
1947 
1948 		if (next_delta < delta) {
1949 			chosen_idx = i;
1950 			delta = next_delta;
1951 		}
1952 	}
1953 
1954 	ASSERT3U(chosen_idx, <, SGE_NTIMERS);
1955 	return (chosen_idx);
1956 }
1957 
1958 int8_t
t4_choose_holdoff_pktcnt(struct adapter * sc,int target_cnt)1959 t4_choose_holdoff_pktcnt(struct adapter *sc, int target_cnt)
1960 {
1961 	const uint_t *pkt_cnt = sc->props.holdoff_pktcnt;
1962 
1963 	if (target_cnt <= 0) {
1964 		/* -1 is sentinel value for do-not-use */
1965 		return (-1);
1966 	}
1967 
1968 	uint_t delta = UINT_MAX;
1969 	uint_t chosen_idx = 0;
1970 	for (uint_t i = 0; i < SGE_NCOUNTERS; i++) {
1971 		const uint_t next_delta = ABS_DELTA(target_cnt, pkt_cnt[i]);
1972 
1973 		if (next_delta < delta) {
1974 			chosen_idx = i;
1975 			delta = next_delta;
1976 		}
1977 	}
1978 
1979 	ASSERT3U(chosen_idx, <, SGE_NCOUNTERS);
1980 	return (chosen_idx);
1981 }
1982 
1983 uint_t
t4_choose_dbq_timer(struct adapter * sc,uint_t target_us)1984 t4_choose_dbq_timer(struct adapter *sc, uint_t target_us)
1985 {
1986 	const uint16_t *dbq_us = sc->sge.dbq_timers;
1987 
1988 	uint_t delta = UINT_MAX;
1989 	uint_t chosen_idx = 0;
1990 	for (uint_t i = 0; i < SGE_NDBQTIMERS; i++) {
1991 		const uint_t next_delta = ABS_DELTA(target_us, dbq_us[i]);
1992 
1993 		if (next_delta < delta) {
1994 			chosen_idx = i;
1995 			delta = next_delta;
1996 		}
1997 	}
1998 
1999 	ASSERT3U(chosen_idx, <, SGE_NDBQTIMERS);
2000 	return (chosen_idx);
2001 }
2002 
2003 
2004 static int
t4_setprop_priv(struct port_info * pi,const char * name,const void * val)2005 t4_setprop_priv(struct port_info *pi, const char *name, const void *val)
2006 {
2007 	struct adapter *sc = pi->adapter;
2008 	long v;
2009 
2010 	const t4_priv_prop_t *prop = t4_priv_prop_match(name);
2011 	if (prop == NULL || !t4_priv_prop_supported(pi, prop)) {
2012 		return (ENOTSUP);
2013 	}
2014 
2015 	(void) ddi_strtol(val, NULL, 0, &v);
2016 	if (prop->tpp_is_bool && v != 0 && v != 1) {
2017 		return (EINVAL);
2018 	}
2019 	const bool vbool = (v != 0);
2020 
2021 	/* XXX: this needs better locking to deal with adapter init */
2022 
2023 	bool update_rx_intr_cfg = false;
2024 	bool update_link_cfg = false;
2025 	struct link_config *lc = &pi->link_cfg;
2026 	fw_port_cap32_t new_caps = lc->admin_caps;
2027 	cc_pause_t fc = 0;
2028 
2029 	switch (prop->tpp_id) {
2030 	case T4PROP_FW_TMR: {
2031 		struct sge_iq *fwq = &sc->sge.fwq;
2032 		const uint8_t idx = t4_choose_holdoff_timer(sc, MAX(0, v));
2033 
2034 		IQ_LOCK(fwq);
2035 		sc->sge.fwq_tmr_idx = idx;
2036 		t4_iq_update_intr_cfg(fwq, sc->sge.fwq_tmr_idx,
2037 		    sc->sge.fwq_pktc_idx);
2038 		IQ_UNLOCK(fwq);
2039 		break;
2040 	}
2041 	case T4PROP_FW_PKTC: {
2042 		struct sge_iq *fwq = &sc->sge.fwq;
2043 		const int8_t idx = t4_choose_holdoff_pktcnt(sc, (int)v);
2044 
2045 		IQ_LOCK(fwq);
2046 		sc->sge.fwq_pktc_idx = idx;
2047 		t4_iq_update_intr_cfg(fwq, sc->sge.fwq_tmr_idx,
2048 		    sc->sge.fwq_pktc_idx);
2049 		IQ_UNLOCK(fwq);
2050 		break;
2051 	}
2052 	case T4PROP_RX_TMR: {
2053 		const uint8_t idx = t4_choose_holdoff_timer(sc, MAX(0, v));
2054 		if (idx != pi->tmr_idx) {
2055 			pi->tmr_idx = idx;
2056 			update_rx_intr_cfg = true;
2057 		}
2058 		break;
2059 	}
2060 	case T4PROP_RX_PKTC: {
2061 		const int8_t idx = t4_choose_holdoff_pktcnt(sc, (int)v);
2062 		if (idx != pi->pktc_idx) {
2063 			pi->pktc_idx = idx;
2064 			update_rx_intr_cfg = true;
2065 		}
2066 		break;
2067 	}
2068 	case T4PROP_TX_TMR: {
2069 		ASSERT(sc->flags & TAF_DBQ_TIMER);
2070 		if (v <= 0) {
2071 			return (EINVAL);
2072 		}
2073 		const uint_t idx = t4_choose_dbq_timer(sc, (uint_t)v);
2074 		PORT_LOCK(pi);
2075 		if ((pi->flags & TPF_OPEN) != 0 &&
2076 		    idx != pi->dbq_timer_idx) {
2077 			pi->dbq_timer_idx = idx;
2078 
2079 			int i;
2080 			struct sge_txq *txq;
2081 			for_each_txq(pi, i, txq) {
2082 				struct sge_eq *eq = &txq->eq;
2083 
2084 				EQ_LOCK(eq);
2085 				t4_eq_update_dbq_timer(eq, pi);
2086 				EQ_UNLOCK(eq);
2087 			}
2088 		}
2089 		PORT_UNLOCK(pi);
2090 		return (0);
2091 	}
2092 	case T4PROP_HW_CSUM:
2093 		if (vbool)
2094 			pi->features |= CXGBE_HW_CSUM;
2095 		else
2096 			pi->features &= ~CXGBE_HW_CSUM;
2097 		break;
2098 	case T4PROP_HW_LSO:
2099 		if (vbool)
2100 			pi->features |= CXGBE_HW_LSO;
2101 		else
2102 			pi->features &= ~CXGBE_HW_LSO;
2103 		break;
2104 	case T4PROP_TX_PAUSE:
2105 	case T4PROP_RX_PAUSE:
2106 		if (new_caps & FW_PORT_CAP32_FC_TX) {
2107 			if (prop->tpp_id == T4PROP_TX_PAUSE) {
2108 				fc |= vbool ? PAUSE_TX : 0;
2109 			} else {
2110 				fc |= PAUSE_TX;
2111 			}
2112 		}
2113 		if (new_caps & FW_PORT_CAP32_FC_RX) {
2114 			if (prop->tpp_id == T4PROP_RX_PAUSE) {
2115 				fc |= vbool ? PAUSE_RX : 0;
2116 			} else {
2117 				fc |= PAUSE_RX;
2118 			}
2119 		}
2120 		if (new_caps & FW_PORT_CAP32_ANEG) {
2121 			fc |= PAUSE_AUTONEG;
2122 		}
2123 		update_link_cfg = true;
2124 		break;
2125 	default:
2126 		return (ENOTSUP);
2127 	}
2128 
2129 	if (update_rx_intr_cfg) {
2130 		struct sge_rxq *rxq;
2131 		int i;
2132 
2133 		PORT_LOCK(pi);
2134 		if ((pi->flags & TPF_OPEN) != 0) {
2135 			for_each_rxq(pi, i, rxq) {
2136 				struct sge_iq *iq = &rxq->iq;
2137 
2138 				IQ_LOCK(iq);
2139 				t4_iq_update_intr_cfg(iq, pi->tmr_idx,
2140 				    pi->pktc_idx);
2141 				IQ_UNLOCK(iq);
2142 			}
2143 		}
2144 		PORT_UNLOCK(pi);
2145 	}
2146 	if (update_link_cfg) {
2147 		int rc = 0;
2148 
2149 		ADAPTER_LOCK(pi->adapter);
2150 		PORT_LOCK(pi);
2151 		t4_link_set_pause(pi, fc, &new_caps);
2152 		if ((pi->flags & TPF_OPEN) != 0) {
2153 			rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc,
2154 			    new_caps);
2155 			if (rc != 0) {
2156 				cxgb_printf(pi->dip, CE_WARN,
2157 				    "%s link config failed: %d",
2158 				    __func__, rc);
2159 			}
2160 		}
2161 
2162 		if (rc == 0) {
2163 			lc->admin_caps = new_caps;
2164 		}
2165 		PORT_UNLOCK(pi);
2166 		ADAPTER_UNLOCK(pi->adapter);
2167 		return (rc);
2168 	}
2169 
2170 	return (0);
2171 }
2172 
2173 void
t4_mc_cb_init(struct port_info * pi)2174 t4_mc_cb_init(struct port_info *pi)
2175 {
2176 	if (pi->adapter->props.multi_rings)
2177 		pi->mc = &t4_m_ring_callbacks;
2178 	else
2179 		pi->mc = &t4_m_callbacks;
2180 }
2181 
2182 void
t4_os_link_changed(struct adapter * sc,int idx,int link_stat)2183 t4_os_link_changed(struct adapter *sc, int idx, int link_stat)
2184 {
2185 	struct port_info *pi = sc->port[idx];
2186 
2187 	mac_link_update(pi->mh, link_stat ? LINK_STATE_UP : LINK_STATE_DOWN);
2188 }
2189 
2190 /* ARGSUSED */
2191 void
t4_mac_rx(struct port_info * pi,struct sge_rxq * rxq,mblk_t * m)2192 t4_mac_rx(struct port_info *pi, struct sge_rxq *rxq, mblk_t *m)
2193 {
2194 	mac_rx(pi->mh, NULL, m);
2195 }
2196 
2197 void
t4_mac_tx_update(struct port_info * pi,struct sge_txq * txq)2198 t4_mac_tx_update(struct port_info *pi, struct sge_txq *txq)
2199 {
2200 	if (pi->adapter->props.multi_rings)
2201 		mac_tx_ring_update(pi->mh, txq->ring_handle);
2202 	else
2203 		mac_tx_update(pi->mh);
2204 }
2205