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
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.
13 * This file is part of the Chelsio T4 support code.
15 * Copyright (C) 2010-2013 Chelsio Communications. All rights reserved.
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.
24 #include <sys/sunddi.h>
26 #include <sys/mac_provider.h>
27 #include <sys/mac_ether.h>
28 #include <sys/strsubr.h>
29 #include <sys/queue.h>
31 #include "common/common.h"
32 #include "common/t4_regs.h"
34 static int t4_mc_getstat(void *arg
, uint_t stat
, uint64_t *val
);
35 static int t4_mc_start(void *arg
);
36 static void t4_mc_stop(void *arg
);
37 static int t4_mc_setpromisc(void *arg
, boolean_t on
);
38 static int t4_mc_multicst(void *arg
, boolean_t add
, const uint8_t *mcaddr
);
39 static int t4_mc_unicst(void *arg
, const uint8_t *ucaddr
);
40 static boolean_t
t4_mc_getcapab(void *arg
, mac_capab_t cap
, void *data
);
41 static int t4_mc_setprop(void *arg
, const char *name
, mac_prop_id_t id
,
42 uint_t size
, const void *val
);
43 static int t4_mc_getprop(void *arg
, const char *name
, mac_prop_id_t id
,
44 uint_t size
, void *val
);
45 static void t4_mc_propinfo(void *arg
, const char *name
, mac_prop_id_t id
,
46 mac_prop_info_handle_t ph
);
48 static int begin_synchronized_op(struct port_info
*pi
, int hold
, int waitok
);
49 static void end_synchronized_op(struct port_info
*pi
, int held
);
50 static int t4_init_synchronized(struct port_info
*pi
);
51 static int t4_uninit_synchronized(struct port_info
*pi
);
52 static void propinfo(struct port_info
*pi
, const char *name
,
53 mac_prop_info_handle_t ph
);
54 static int getprop(struct port_info
*pi
, const char *name
, uint_t size
,
56 static int setprop(struct port_info
*pi
, const char *name
, const void *val
);
58 mac_callbacks_t t4_m_callbacks
= {
59 .mc_callbacks
= MC_GETCAPAB
| MC_PROPERTIES
,
60 .mc_getstat
= t4_mc_getstat
,
61 .mc_start
= t4_mc_start
,
62 .mc_stop
= t4_mc_stop
,
63 .mc_setpromisc
= t4_mc_setpromisc
,
64 .mc_multicst
= t4_mc_multicst
,
65 .mc_unicst
= t4_mc_unicst
,
67 .mc_getcapab
= t4_mc_getcapab
,
68 .mc_setprop
= t4_mc_setprop
,
69 .mc_getprop
= t4_mc_getprop
,
70 .mc_propinfo
= t4_mc_propinfo
,
73 /* I couldn't comeup with a better idea of not redefine
74 * another strcture and instead somehow reuse the earlier
75 * above structure and modify its members.
77 mac_callbacks_t t4_m_ring_callbacks
= {
78 .mc_callbacks
= MC_GETCAPAB
| MC_PROPERTIES
,
79 .mc_getstat
= t4_mc_getstat
,
80 .mc_start
= t4_mc_start
,
81 .mc_stop
= t4_mc_stop
,
82 .mc_setpromisc
=t4_mc_setpromisc
,
83 .mc_multicst
= t4_mc_multicst
,
84 .mc_unicst
= NULL
, /* t4_addmac */
85 .mc_tx
= NULL
, /* t4_eth_tx */
86 .mc_getcapab
= t4_mc_getcapab
,
87 .mc_setprop
= t4_mc_setprop
,
88 .mc_getprop
= t4_mc_getprop
,
89 .mc_propinfo
= t4_mc_propinfo
,
92 #define T4PROP_TMR_IDX "_holdoff_timer_idx"
93 #define T4PROP_PKTC_IDX "_holdoff_pktc_idx"
94 #define T4PROP_MTU "_mtu"
95 #define T4PROP_HW_CSUM "_hw_csum"
96 #define T4PROP_HW_LSO "_hw_lso"
97 #define T4PROP_TX_PAUSE "_tx_pause"
98 #define T4PROP_RX_PAUSE "_rx_pause"
100 char *t4_priv_props
[] = {
104 /* MAC_VERSION 1 doesn't seem to use MAC_PROP_MTU, hmmmm */
115 t4_mc_getstat(void *arg
, uint_t stat
, uint64_t *val
)
117 struct port_info
*pi
= arg
;
118 struct adapter
*sc
= pi
->adapter
;
119 struct link_config
*lc
= &pi
->link_cfg
;
121 #define GET_STAT(name) \
122 t4_read_reg64(sc, PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_##name##_L))
125 case MAC_STAT_IFSPEED
:
126 if (lc
->link_ok
!= 0) {
133 case MAC_STAT_MULTIRCV
:
134 *val
= GET_STAT(RX_PORT_MCAST
);
137 case MAC_STAT_BRDCSTRCV
:
138 *val
= GET_STAT(RX_PORT_BCAST
);
141 case MAC_STAT_MULTIXMT
:
142 *val
= GET_STAT(TX_PORT_MCAST
);
145 case MAC_STAT_BRDCSTXMT
:
146 *val
= GET_STAT(TX_PORT_BCAST
);
149 case MAC_STAT_NORCVBUF
:
150 *val
= 0; /* TODO should come from rxq->nomem */
153 case MAC_STAT_IERRORS
:
154 *val
= GET_STAT(RX_PORT_MTU_ERROR
) +
155 GET_STAT(RX_PORT_MTU_CRC_ERROR
) +
156 GET_STAT(RX_PORT_CRC_ERROR
) +
157 GET_STAT(RX_PORT_LEN_ERROR
) +
158 GET_STAT(RX_PORT_SYM_ERROR
) +
159 GET_STAT(RX_PORT_LESS_64B
);
162 case MAC_STAT_UNKNOWNS
:
165 case MAC_STAT_NOXMTBUF
:
166 *val
= GET_STAT(TX_PORT_DROP
);
169 case MAC_STAT_OERRORS
:
170 *val
= GET_STAT(TX_PORT_ERROR
);
173 case MAC_STAT_COLLISIONS
:
176 case MAC_STAT_RBYTES
:
177 *val
= GET_STAT(RX_PORT_BYTES
);
180 case MAC_STAT_IPACKETS
:
181 *val
= GET_STAT(RX_PORT_FRAMES
);
184 case MAC_STAT_OBYTES
:
185 *val
= GET_STAT(TX_PORT_BYTES
);
188 case MAC_STAT_OPACKETS
:
189 *val
= GET_STAT(TX_PORT_FRAMES
);
192 case ETHER_STAT_ALIGN_ERRORS
:
195 case ETHER_STAT_FCS_ERRORS
:
196 *val
= GET_STAT(RX_PORT_CRC_ERROR
);
199 case ETHER_STAT_FIRST_COLLISIONS
:
200 case ETHER_STAT_MULTI_COLLISIONS
:
201 case ETHER_STAT_SQE_ERRORS
:
202 case ETHER_STAT_DEFER_XMTS
:
203 case ETHER_STAT_TX_LATE_COLLISIONS
:
204 case ETHER_STAT_EX_COLLISIONS
:
207 case ETHER_STAT_MACXMT_ERRORS
:
208 *val
= GET_STAT(TX_PORT_ERROR
);
211 case ETHER_STAT_CARRIER_ERRORS
:
214 case ETHER_STAT_TOOLONG_ERRORS
:
215 *val
= GET_STAT(RX_PORT_MTU_ERROR
);
218 case ETHER_STAT_MACRCV_ERRORS
:
219 *val
= GET_STAT(RX_PORT_MTU_ERROR
) +
220 GET_STAT(RX_PORT_MTU_CRC_ERROR
) +
221 GET_STAT(RX_PORT_CRC_ERROR
) +
222 GET_STAT(RX_PORT_LEN_ERROR
) +
223 GET_STAT(RX_PORT_SYM_ERROR
) +
224 GET_STAT(RX_PORT_LESS_64B
);
227 case ETHER_STAT_XCVR_ADDR
:
228 case ETHER_STAT_XCVR_ID
:
229 case ETHER_STAT_XCVR_INUSE
:
232 case ETHER_STAT_CAP_100GFDX
:
233 *val
= !!(lc
->supported
& FW_PORT_CAP_SPEED_100G
);
236 case ETHER_STAT_CAP_40GFDX
:
237 *val
= !!(lc
->supported
& FW_PORT_CAP_SPEED_40G
);
240 case ETHER_STAT_CAP_25GFDX
:
241 *val
= !!(lc
->supported
& FW_PORT_CAP_SPEED_25G
);
244 case ETHER_STAT_CAP_10GFDX
:
245 *val
= !!(lc
->supported
& FW_PORT_CAP_SPEED_10G
);
248 case ETHER_STAT_CAP_1000FDX
:
249 *val
= !!(lc
->supported
& FW_PORT_CAP_SPEED_1G
);
252 case ETHER_STAT_CAP_1000HDX
:
255 case ETHER_STAT_CAP_100FDX
:
256 *val
= !!(lc
->supported
& FW_PORT_CAP_SPEED_100M
);
259 case ETHER_STAT_CAP_100HDX
:
262 case ETHER_STAT_CAP_10FDX
:
263 case ETHER_STAT_CAP_10HDX
:
266 case ETHER_STAT_CAP_ASMPAUSE
:
270 case ETHER_STAT_CAP_PAUSE
:
274 case ETHER_STAT_CAP_AUTONEG
:
275 *val
= !!(lc
->supported
& FW_PORT_CAP_ANEG
);
279 * We have set flow control configuration based on tx_pause and rx_pause
280 * values supported through ndd. Now, we need to translate the settings
281 * we have in link_config structure to adv_cap_asmpause and
284 * There are 4 combinations possible and the translation is as below:
285 * tx_pause = 0 => We don't send pause frames during Rx congestion
286 * tx_pause = 1 => We send pause frames during Rx congestion
287 * rx_pause = 0 => We ignore received pause frames
288 * rx_pause = 1 => We pause transmission when we receive pause frames
290 * +----------------------------+----------------------------------+
291 * | tx_pause | rx_pause | adv_cap_asmpause | adv_cap_pause |
292 * +-------------------------+-------------------------------------+
297 * +----------------------------+----------------------------------+
300 /* Advertised asymmetric pause capability */
301 case ETHER_STAT_ADV_CAP_ASMPAUSE
:
302 *val
= (((lc
->requested_fc
& PAUSE_TX
) ? 1 : 0) ^
303 (lc
->requested_fc
& PAUSE_RX
));
306 /* Advertised pause capability */
307 case ETHER_STAT_ADV_CAP_PAUSE
:
308 *val
= (lc
->requested_fc
& PAUSE_TX
) ? 1 : 0;
311 case ETHER_STAT_ADV_CAP_100GFDX
:
312 *val
= !!(lc
->advertising
& FW_PORT_CAP_SPEED_100G
);
315 case ETHER_STAT_ADV_CAP_40GFDX
:
316 *val
= !!(lc
->advertising
& FW_PORT_CAP_SPEED_40G
);
319 case ETHER_STAT_ADV_CAP_25GFDX
:
320 *val
= !!(lc
->advertising
& FW_PORT_CAP_SPEED_25G
);
323 case ETHER_STAT_ADV_CAP_10GFDX
:
324 *val
= !!(lc
->advertising
& FW_PORT_CAP_SPEED_10G
);
327 case ETHER_STAT_ADV_CAP_1000FDX
:
328 *val
= !!(lc
->advertising
& FW_PORT_CAP_SPEED_1G
);
331 case ETHER_STAT_ADV_CAP_AUTONEG
:
332 *val
= !!(lc
->advertising
& FW_PORT_CAP_ANEG
);
335 case ETHER_STAT_ADV_CAP_1000HDX
:
336 case ETHER_STAT_ADV_CAP_100FDX
:
337 case ETHER_STAT_ADV_CAP_100HDX
:
338 case ETHER_STAT_ADV_CAP_10FDX
:
339 case ETHER_STAT_ADV_CAP_10HDX
:
340 return (ENOTSUP
); /* TODO */
343 case ETHER_STAT_LP_CAP_100GFDX
:
344 *val
= !!(lc
->lp_advertising
& FW_PORT_CAP_SPEED_100G
);
347 case ETHER_STAT_LP_CAP_40GFDX
:
348 *val
= !!(lc
->lp_advertising
& FW_PORT_CAP_SPEED_40G
);
351 case ETHER_STAT_LP_CAP_25GFDX
:
352 *val
= !!(lc
->lp_advertising
& FW_PORT_CAP_SPEED_25G
);
355 case ETHER_STAT_LP_CAP_10GFDX
:
356 *val
= !!(lc
->lp_advertising
& FW_PORT_CAP_SPEED_10G
);
359 case ETHER_STAT_LP_CAP_1000FDX
:
360 *val
= !!(lc
->lp_advertising
& FW_PORT_CAP_SPEED_1G
);
363 case ETHER_STAT_LP_CAP_AUTONEG
:
364 *val
= !!(lc
->lp_advertising
& FW_PORT_CAP_ANEG
);
367 case ETHER_STAT_LP_CAP_1000HDX
:
368 case ETHER_STAT_LP_CAP_100FDX
:
369 case ETHER_STAT_LP_CAP_100HDX
:
370 case ETHER_STAT_LP_CAP_10FDX
:
371 case ETHER_STAT_LP_CAP_10HDX
:
372 case ETHER_STAT_LP_CAP_ASMPAUSE
:
373 case ETHER_STAT_LP_CAP_PAUSE
:
376 case ETHER_STAT_LINK_ASMPAUSE
:
380 case ETHER_STAT_LINK_PAUSE
:
384 case ETHER_STAT_LINK_AUTONEG
:
385 *val
= lc
->autoneg
== AUTONEG_ENABLE
;
388 case ETHER_STAT_LINK_DUPLEX
:
389 if (lc
->link_ok
!= 0)
390 *val
= LINK_DUPLEX_FULL
;
392 *val
= LINK_DUPLEX_UNKNOWN
;
397 cxgb_printf(pi
->dip
, CE_NOTE
, "stat %d not implemented.", stat
);
407 t4_mc_start(void *arg
)
409 struct port_info
*pi
= arg
;
412 rc
= begin_synchronized_op(pi
, 0, 1);
415 rc
= t4_init_synchronized(pi
);
416 end_synchronized_op(pi
, 0);
422 t4_mc_stop(void *arg
)
424 struct port_info
*pi
= arg
;
426 while (begin_synchronized_op(pi
, 0, 1) != 0)
428 (void) t4_uninit_synchronized(pi
);
429 end_synchronized_op(pi
, 0);
433 t4_mc_setpromisc(void *arg
, boolean_t on
)
435 struct port_info
*pi
= arg
;
436 struct adapter
*sc
= pi
->adapter
;
439 rc
= begin_synchronized_op(pi
, 1, 1);
442 rc
= -t4_set_rxmode(sc
, sc
->mbox
, pi
->viid
, -1, on
? 1 : 0, -1, -1, -1,
444 end_synchronized_op(pi
, 1);
450 * TODO: Starts failing as soon as the 336 entry table fills up. Need to use
454 t4_mc_multicst(void *arg
, boolean_t add
, const uint8_t *mcaddr
)
456 struct port_info
*pi
= arg
;
457 struct adapter
*sc
= pi
->adapter
;
458 struct fw_vi_mac_cmd c
;
461 len16
= howmany(sizeof (c
.op_to_viid
) + sizeof (c
.freemacs_to_len16
) +
462 sizeof (c
.u
.exact
[0]), 16);
463 c
.op_to_viid
= htonl(V_FW_CMD_OP(FW_VI_MAC_CMD
) | F_FW_CMD_REQUEST
|
464 F_FW_CMD_WRITE
| V_FW_VI_MAC_CMD_VIID(pi
->viid
));
465 c
.freemacs_to_len16
= htonl(V_FW_CMD_LEN16(len16
));
466 c
.u
.exact
[0].valid_to_idx
= htons(F_FW_VI_MAC_CMD_VALID
|
467 V_FW_VI_MAC_CMD_IDX(add
? FW_VI_MAC_ADD_MAC
:
468 FW_VI_MAC_MAC_BASED_FREE
));
469 bcopy(mcaddr
, &c
.u
.exact
[0].macaddr
, ETHERADDRL
);
471 rc
= begin_synchronized_op(pi
, 1, 1);
474 rc
= -t4_wr_mbox_meat(sc
, sc
->mbox
, &c
, len16
* 16, &c
, true);
475 end_synchronized_op(pi
, 1);
480 * TODO: Firmware doesn't seem to return the correct index on removal
481 * (it gives back 0x3fd FW_VI_MAC_MAC_BASED_FREE unchanged. Remove this
482 * code once it is fixed.
487 idx
= G_FW_VI_MAC_CMD_IDX(ntohs(c
.u
.exact
[0].valid_to_idx
));
488 cxgb_printf(pi
->dip
, CE_NOTE
,
489 "%02x:%02x:%02x:%02x:%02x:%02x %s %d", mcaddr
[0],
490 mcaddr
[1], mcaddr
[2], mcaddr
[3], mcaddr
[4], mcaddr
[5],
491 add
? "added at index" : "removed from index", idx
);
499 t4_mc_unicst(void *arg
, const uint8_t *ucaddr
)
501 struct port_info
*pi
= arg
;
502 struct adapter
*sc
= pi
->adapter
;
508 rc
= begin_synchronized_op(pi
, 1, 1);
512 /* We will support adding only one mac address */
513 if (pi
->adapter
->props
.multi_rings
&& pi
->macaddr_cnt
) {
514 end_synchronized_op(pi
, 1);
517 rc
= t4_change_mac(sc
, sc
->mbox
, pi
->viid
, pi
->xact_addr_filt
, ucaddr
,
523 pi
->xact_addr_filt
= rc
;
526 end_synchronized_op(pi
, 1);
532 t4_addmac(void *arg
, const uint8_t *ucaddr
)
534 return (t4_mc_unicst(arg
, ucaddr
));
538 t4_remmac(void *arg
, const uint8_t *mac_addr
)
540 struct port_info
*pi
= arg
;
543 rc
= begin_synchronized_op(pi
, 1, 1);
548 end_synchronized_op(pi
, 1);
554 * Callback funtion for MAC layer to register all groups.
557 t4_fill_group(void *arg
, mac_ring_type_t rtype
, const int rg_index
,
558 mac_group_info_t
*infop
, mac_group_handle_t gh
)
560 struct port_info
*pi
= arg
;
563 case MAC_RING_TYPE_RX
: {
564 infop
->mgi_driver
= (mac_group_driver_t
)arg
;
565 infop
->mgi_start
= NULL
;
566 infop
->mgi_stop
= NULL
;
567 infop
->mgi_addmac
= t4_addmac
;
568 infop
->mgi_remmac
= t4_remmac
;
569 infop
->mgi_count
= pi
->nrxq
;
572 case MAC_RING_TYPE_TX
:
580 t4_ring_start(mac_ring_driver_t rh
, uint64_t mr_gen_num
)
582 struct sge_rxq
*rxq
= (struct sge_rxq
*)rh
;
585 rxq
->ring_gen_num
= mr_gen_num
;
591 * Enable interrupt on the specificed rx ring.
594 t4_ring_intr_enable(mac_intr_handle_t intrh
)
596 struct sge_rxq
*rxq
= (struct sge_rxq
*)intrh
;
597 struct adapter
*sc
= rxq
->port
->adapter
;
603 iq
->state
= IQS_IDLE
;
604 t4_write_reg(sc
, MYPF_REG(A_SGE_PF_GTS
),
605 V_SEINTARM(iq
->intr_params
) | V_INGRESSQID(iq
->cntxt_id
));
611 * Disable interrupt on the specificed rx ring.
614 t4_ring_intr_disable(mac_intr_handle_t intrh
)
616 struct sge_rxq
*rxq
= (struct sge_rxq
*)intrh
;
619 /* Nothing to be done here wrt interrupt, as it
620 * will not fire, until we write back to
621 * A_SGE_PF_GTS.SEIntArm in t4_ring_intr_enable.
627 iq
->state
= IQS_BUSY
;
633 t4_poll_ring(void *arg
, int n_bytes
)
635 struct sge_rxq
*rxq
= (struct sge_rxq
*)arg
;
638 ASSERT(n_bytes
>= 0);
643 mp
= t4_ring_rx(rxq
, n_bytes
);
650 * Retrieve a value for one of the statistics for a particular rx ring
653 t4_rx_stat(mac_ring_driver_t rh
, uint_t stat
, uint64_t *val
)
655 struct sge_rxq
*rxq
= (struct sge_rxq
*)rh
;
658 case MAC_STAT_RBYTES
:
662 case MAC_STAT_IPACKETS
:
675 * Retrieve a value for one of the statistics for a particular tx ring
678 t4_tx_stat(mac_ring_driver_t rh
, uint_t stat
, uint64_t *val
)
680 struct sge_txq
*txq
= (struct sge_txq
*)rh
;
683 case MAC_STAT_RBYTES
:
687 case MAC_STAT_IPACKETS
:
700 * Callback funtion for MAC layer to register all rings
701 * for given ring_group, noted by group_index.
702 * Since we have only one group, ring index becomes
706 t4_fill_ring(void *arg
, mac_ring_type_t rtype
, const int group_index
,
707 const int ring_index
, mac_ring_info_t
*infop
, mac_ring_handle_t rh
)
709 struct port_info
*pi
= arg
;
713 case MAC_RING_TYPE_RX
: {
716 rxq
= &pi
->adapter
->sge
.rxq
[pi
->first_rxq
+ ring_index
];
717 rxq
->ring_handle
= rh
;
719 infop
->mri_driver
= (mac_ring_driver_t
)rxq
;
720 infop
->mri_start
= t4_ring_start
;
721 infop
->mri_stop
= NULL
;
722 infop
->mri_poll
= t4_poll_ring
;
723 infop
->mri_stat
= t4_rx_stat
;
725 mintr
= &infop
->mri_intr
;
726 mintr
->mi_handle
= (mac_intr_handle_t
)rxq
;
727 mintr
->mi_enable
= t4_ring_intr_enable
;
728 mintr
->mi_disable
= t4_ring_intr_disable
;
732 case MAC_RING_TYPE_TX
: {
733 struct sge_txq
*txq
= &pi
->adapter
->sge
.txq
[pi
->first_txq
+ ring_index
];
734 txq
->ring_handle
= rh
;
735 infop
->mri_driver
= (mac_ring_driver_t
)txq
;
736 infop
->mri_start
= NULL
;
737 infop
->mri_stop
= NULL
;
738 infop
->mri_tx
= t4_eth_tx
;
739 infop
->mri_stat
= t4_tx_stat
;
749 t4_mc_tx(void *arg
, mblk_t
*m
)
751 struct port_info
*pi
= arg
;
752 struct adapter
*sc
= pi
->adapter
;
753 struct sge_txq
*txq
= &sc
->sge
.txq
[pi
->first_txq
];
755 return (t4_eth_tx(txq
, m
));
759 t4_mc_transceiver_info(void *arg
, uint_t id
, mac_transceiver_info_t
*infop
)
761 struct port_info
*pi
= arg
;
763 if (id
!= 0 || infop
== NULL
)
766 switch (pi
->mod_type
) {
767 case FW_PORT_MOD_TYPE_NONE
:
768 mac_transceiver_info_set_present(infop
, B_FALSE
);
770 case FW_PORT_MOD_TYPE_NOTSUPPORTED
:
771 mac_transceiver_info_set_present(infop
, B_TRUE
);
772 mac_transceiver_info_set_usable(infop
, B_FALSE
);
775 mac_transceiver_info_set_present(infop
, B_TRUE
);
776 mac_transceiver_info_set_usable(infop
, B_TRUE
);
784 t4_mc_transceiver_read(void *arg
, uint_t id
, uint_t page
, void *bp
,
785 size_t nbytes
, off_t offset
, size_t *nread
)
787 struct port_info
*pi
= arg
;
788 struct adapter
*sc
= pi
->adapter
;
791 /* LINTED: E_FUNC_VAR_UNUSED */
792 struct fw_ldst_cmd ldst __unused
;
794 if (id
!= 0 || bp
== NULL
|| nbytes
== 0 || nread
== NULL
||
795 (page
!= 0xa0 && page
!= 0xa2) || offset
< 0)
798 if (nbytes
> 256 || offset
>= 256 || (offset
+ nbytes
> 256))
801 rc
= begin_synchronized_op(pi
, 0, 1);
806 * Firmware has a maximum size that we can read. Don't read more than it
809 maxread
= sizeof (ldst
.u
.i2c
.data
);
810 for (i
= 0; i
< nbytes
; i
+= maxread
) {
811 size_t toread
= MIN(maxread
, nbytes
- i
);
812 rc
= -t4_i2c_rd(sc
, sc
->mbox
, pi
->port_id
, page
, offset
, toread
,
817 bp
= (void *)((uintptr_t)bp
+ toread
);
819 end_synchronized_op(pi
, 0);
826 t4_mc_getcapab(void *arg
, mac_capab_t cap
, void *data
)
828 struct port_info
*pi
= arg
;
829 boolean_t status
= B_TRUE
;
830 mac_capab_transceiver_t
*mct
;
833 case MAC_CAPAB_HCKSUM
:
834 if (pi
->features
& CXGBE_HW_CSUM
) {
836 *d
= HCKSUM_INET_FULL_V4
| HCKSUM_IPHDRCKSUM
;
842 /* Enabling LSO requires Checksum offloading */
843 if (pi
->features
& CXGBE_HW_LSO
&&
844 pi
->features
& CXGBE_HW_CSUM
) {
845 mac_capab_lso_t
*d
= data
;
847 d
->lso_flags
= LSO_TX_BASIC_TCP_IPV4
;
848 d
->lso_basic_tcp_ipv4
.lso_max
= 65535;
853 case MAC_CAPAB_RINGS
: {
854 mac_capab_rings_t
*cap_rings
= data
;
856 if (!pi
->adapter
->props
.multi_rings
) {
860 switch (cap_rings
->mr_type
) {
861 case MAC_RING_TYPE_RX
:
862 cap_rings
->mr_group_type
= MAC_GROUP_TYPE_STATIC
;
863 cap_rings
->mr_rnum
= pi
->nrxq
;
864 cap_rings
->mr_gnum
= 1;
865 cap_rings
->mr_rget
= t4_fill_ring
;
866 cap_rings
->mr_gget
= t4_fill_group
;
867 cap_rings
->mr_gaddring
= NULL
;
868 cap_rings
->mr_gremring
= NULL
;
870 case MAC_RING_TYPE_TX
:
871 cap_rings
->mr_group_type
= MAC_GROUP_TYPE_STATIC
;
872 cap_rings
->mr_rnum
= pi
->ntxq
;
873 cap_rings
->mr_gnum
= 0;
874 cap_rings
->mr_rget
= t4_fill_ring
;
875 cap_rings
->mr_gget
= NULL
;
881 case MAC_CAPAB_TRANSCEIVER
:
885 mct
->mct_ntransceivers
= 1;
886 mct
->mct_info
= t4_mc_transceiver_info
;
887 mct
->mct_read
= t4_mc_transceiver_read
;
891 status
= B_FALSE
; /* cap not supported */
899 t4_mc_setprop(void *arg
, const char *name
, mac_prop_id_t id
, uint_t size
,
902 struct port_info
*pi
= arg
;
903 struct adapter
*sc
= pi
->adapter
;
904 struct link_config lc_copy
, *lc
= &pi
->link_cfg
;
905 uint8_t v8
= *(uint8_t *)val
;
906 uint32_t v32
= *(uint32_t *)val
;
907 int old
, new = 0, relink
= 0, rx_mode
= 0, rc
= 0;
911 * Save a copy of link_config. This can be used to restore link_config
912 * if t4_link_l1cfg() fails.
914 bcopy(lc
, &lc_copy
, sizeof (struct link_config
));
917 case MAC_PROP_AUTONEG
:
918 if (lc
->supported
& FW_PORT_CAP_ANEG
) {
920 new = v8
? AUTONEG_ENABLE
: AUTONEG_DISABLE
;
922 /* LINTED: E_CONSTANT_CONDITION */
925 if (new == AUTONEG_DISABLE
) {
926 /* Only 100M is available */
927 lc
->requested_speed
=
928 FW_PORT_CAP_SPEED_100M
;
930 FW_PORT_CAP_SPEED_100M
;
933 * Advertise autonegotiation capability
934 * along with supported speeds
936 lc
->advertising
|= (FW_PORT_CAP_ANEG
|
938 (FW_PORT_CAP_SPEED_100M
|
939 FW_PORT_CAP_SPEED_1G
)));
940 lc
->requested_speed
= 0;
948 if (v32
< 46 || v32
> MAX_MTU
) {
950 } else if (v32
!= pi
->mtu
) {
952 (void) mac_maxsdu_update(pi
->mh
, v32
);
958 case MAC_PROP_FLOWCTRL
:
959 fc
= *(link_flowctrl_t
*)val
;
960 old
= lc
->requested_fc
& (PAUSE_TX
| PAUSE_RX
);
962 if (fc
== LINK_FLOWCTRL_BI
)
963 new = (PAUSE_TX
| PAUSE_RX
);
964 else if (fc
== LINK_FLOWCTRL_TX
)
966 else if (fc
== LINK_FLOWCTRL_RX
)
970 lc
->requested_fc
&= ~(PAUSE_TX
| PAUSE_RX
);
971 lc
->requested_fc
|= new;
976 case MAC_PROP_EN_10GFDX_CAP
:
977 if (lc
->supported
& FW_PORT_CAP_ANEG
&& is_10G_port(pi
)) {
978 old
= lc
->advertising
& FW_PORT_CAP_SPEED_10G
;
979 new = v8
? FW_PORT_CAP_SPEED_10G
: 0;
981 lc
->advertising
&= ~FW_PORT_CAP_SPEED_10G
;
982 lc
->advertising
|= new;
990 case MAC_PROP_EN_1000FDX_CAP
:
992 if (lc
->autoneg
== AUTONEG_ENABLE
) {
993 old
= lc
->advertising
& FW_PORT_CAP_SPEED_1G
;
994 new = v8
? FW_PORT_CAP_SPEED_1G
: 0;
997 lc
->advertising
&= ~FW_PORT_CAP_SPEED_1G
;
998 lc
->advertising
|= new;
1005 case MAC_PROP_EN_100FDX_CAP
:
1007 if (lc
->autoneg
== AUTONEG_ENABLE
) {
1008 old
= lc
->advertising
& FW_PORT_CAP_SPEED_100M
;
1009 new = v8
? FW_PORT_CAP_SPEED_100M
: 0;
1011 lc
->advertising
&= ~FW_PORT_CAP_SPEED_100M
;
1012 lc
->advertising
|= new;
1019 case MAC_PROP_PRIVATE
:
1020 rc
= setprop(pi
, name
, val
);
1027 if (isset(&sc
->open_device_map
, pi
->port_id
) != 0) {
1029 t4_os_link_changed(pi
->adapter
, pi
->port_id
, 0);
1030 rc
= begin_synchronized_op(pi
, 1, 1);
1033 rc
= -t4_link_l1cfg(sc
, sc
->mbox
, pi
->tx_chan
,
1035 end_synchronized_op(pi
, 1);
1037 cxgb_printf(pi
->dip
, CE_WARN
,
1038 "start_link failed:%d", rc
);
1040 /* Restore link_config */
1042 sizeof (struct link_config
));
1047 rc
= begin_synchronized_op(pi
, 1, 1);
1050 rc
= -t4_set_rxmode(sc
, sc
->mbox
, pi
->viid
, v32
, -1,
1052 end_synchronized_op(pi
, 1);
1054 cxgb_printf(pi
->dip
, CE_WARN
,
1055 "set_rxmode failed: %d", rc
);
1064 t4_mc_getprop(void *arg
, const char *name
, mac_prop_id_t id
, uint_t size
,
1067 struct port_info
*pi
= arg
;
1068 struct link_config
*lc
= &pi
->link_cfg
;
1072 case MAC_PROP_DUPLEX
:
1073 *(link_duplex_t
*)val
= lc
->link_ok
? LINK_DUPLEX_FULL
:
1074 LINK_DUPLEX_UNKNOWN
;
1077 case MAC_PROP_SPEED
:
1078 if (lc
->link_ok
!= 0) {
1079 *(uint64_t *)val
= lc
->speed
;
1080 *(uint64_t *)val
*= 1000000;
1082 *(uint64_t *)val
= 0;
1085 case MAC_PROP_STATUS
:
1086 *(link_state_t
*)val
= lc
->link_ok
? LINK_STATE_UP
:
1090 case MAC_PROP_AUTONEG
:
1091 *u
= lc
->autoneg
== AUTONEG_ENABLE
;
1095 *(uint32_t *)val
= pi
->mtu
;
1098 case MAC_PROP_FLOWCTRL
:
1099 if ((lc
->requested_fc
& (PAUSE_TX
| PAUSE_RX
)) ==
1100 (PAUSE_TX
| PAUSE_RX
))
1101 *(link_flowctrl_t
*)val
= LINK_FLOWCTRL_BI
;
1102 else if (lc
->requested_fc
& PAUSE_TX
)
1103 *(link_flowctrl_t
*)val
= LINK_FLOWCTRL_TX
;
1104 else if (lc
->requested_fc
& PAUSE_RX
)
1105 *(link_flowctrl_t
*)val
= LINK_FLOWCTRL_RX
;
1107 *(link_flowctrl_t
*)val
= LINK_FLOWCTRL_NONE
;
1110 case MAC_PROP_ADV_100GFDX_CAP
:
1111 case MAC_PROP_EN_100GFDX_CAP
:
1112 *u
= !!(lc
->advertising
& FW_PORT_CAP_SPEED_100G
);
1115 case MAC_PROP_ADV_40GFDX_CAP
:
1116 case MAC_PROP_EN_40GFDX_CAP
:
1117 *u
= !!(lc
->advertising
& FW_PORT_CAP_SPEED_40G
);
1120 case MAC_PROP_ADV_25GFDX_CAP
:
1121 case MAC_PROP_EN_25GFDX_CAP
:
1122 *u
= !!(lc
->advertising
& FW_PORT_CAP_SPEED_25G
);
1125 case MAC_PROP_ADV_10GFDX_CAP
:
1126 case MAC_PROP_EN_10GFDX_CAP
:
1127 *u
= !!(lc
->advertising
& FW_PORT_CAP_SPEED_10G
);
1130 case MAC_PROP_ADV_1000FDX_CAP
:
1131 case MAC_PROP_EN_1000FDX_CAP
:
1132 *u
= !!(lc
->advertising
& FW_PORT_CAP_SPEED_1G
);
1135 case MAC_PROP_ADV_100FDX_CAP
:
1136 case MAC_PROP_EN_100FDX_CAP
:
1137 *u
= !!(lc
->advertising
& FW_PORT_CAP_SPEED_100M
);
1140 case MAC_PROP_PRIVATE
:
1141 return (getprop(pi
, name
, size
, val
));
1151 t4_mc_propinfo(void *arg
, const char *name
, mac_prop_id_t id
,
1152 mac_prop_info_handle_t ph
)
1154 struct port_info
*pi
= arg
;
1155 struct link_config
*lc
= &pi
->link_cfg
;
1158 case MAC_PROP_DUPLEX
:
1159 case MAC_PROP_SPEED
:
1160 case MAC_PROP_STATUS
:
1161 mac_prop_info_set_perm(ph
, MAC_PROP_PERM_READ
);
1164 case MAC_PROP_AUTONEG
:
1165 if (lc
->supported
& FW_PORT_CAP_ANEG
)
1166 mac_prop_info_set_default_uint8(ph
, 1);
1168 mac_prop_info_set_perm(ph
, MAC_PROP_PERM_READ
);
1172 mac_prop_info_set_range_uint32(ph
, 46, MAX_MTU
);
1175 case MAC_PROP_FLOWCTRL
:
1176 mac_prop_info_set_default_link_flowctrl(ph
, LINK_FLOWCTRL_BI
);
1179 case MAC_PROP_EN_10GFDX_CAP
:
1180 if (lc
->supported
& FW_PORT_CAP_ANEG
&&
1181 lc
->supported
& FW_PORT_CAP_SPEED_10G
)
1182 mac_prop_info_set_default_uint8(ph
, 1);
1184 mac_prop_info_set_perm(ph
, MAC_PROP_PERM_READ
);
1187 case MAC_PROP_EN_1000FDX_CAP
:
1188 if (lc
->supported
& FW_PORT_CAP_ANEG
&&
1189 lc
->supported
& FW_PORT_CAP_SPEED_1G
)
1190 mac_prop_info_set_default_uint8(ph
, 1);
1192 mac_prop_info_set_perm(ph
, MAC_PROP_PERM_READ
);
1195 case MAC_PROP_EN_100FDX_CAP
:
1196 if (lc
->supported
& FW_PORT_CAP_ANEG
&&
1197 lc
->supported
& FW_PORT_CAP_SPEED_100M
)
1198 mac_prop_info_set_default_uint8(ph
, 1);
1200 mac_prop_info_set_perm(ph
, MAC_PROP_PERM_READ
);
1203 case MAC_PROP_ADV_10GFDX_CAP
:
1204 case MAC_PROP_ADV_1000FDX_CAP
:
1205 case MAC_PROP_ADV_100FDX_CAP
:
1206 mac_prop_info_set_perm(ph
, MAC_PROP_PERM_READ
);
1209 case MAC_PROP_PRIVATE
:
1210 propinfo(pi
, name
, ph
);
1219 begin_synchronized_op(struct port_info
*pi
, int hold
, int waitok
)
1221 struct adapter
*sc
= pi
->adapter
;
1225 while (!IS_DOOMED(pi
) && IS_BUSY(sc
)) {
1229 } else if (cv_wait_sig(&sc
->cv
, &sc
->lock
) == 0) {
1234 if (IS_DOOMED(pi
) != 0) { /* shouldn't happen on Solaris */
1238 ASSERT(!IS_BUSY(sc
));
1239 /* LINTED: E_CONSTANT_CONDITION */
1252 end_synchronized_op(struct port_info
*pi
, int held
)
1254 struct adapter
*sc
= pi
->adapter
;
1259 ADAPTER_LOCK_ASSERT_OWNED(sc
);
1260 ASSERT(IS_BUSY(sc
));
1261 /* LINTED: E_CONSTANT_CONDITION */
1268 t4_init_synchronized(struct port_info
*pi
)
1270 struct adapter
*sc
= pi
->adapter
;
1273 ADAPTER_LOCK_ASSERT_NOTOWNED(sc
);
1275 if (isset(&sc
->open_device_map
, pi
->port_id
) != 0)
1276 return (0); /* already running */
1278 if (!(sc
->flags
& FULL_INIT_DONE
) &&
1279 ((rc
= adapter_full_init(sc
)) != 0))
1280 return (rc
); /* error message displayed already */
1282 if (!(pi
->flags
& PORT_INIT_DONE
)) {
1283 rc
= port_full_init(pi
);
1285 return (rc
); /* error message displayed already */
1287 enable_port_queues(pi
);
1289 rc
= -t4_set_rxmode(sc
, sc
->mbox
, pi
->viid
, pi
->mtu
, 0, 0, 1, 0, false);
1291 cxgb_printf(pi
->dip
, CE_WARN
, "set_rxmode failed: %d", rc
);
1294 rc
= t4_change_mac(sc
, sc
->mbox
, pi
->viid
, pi
->xact_addr_filt
,
1295 pi
->hw_addr
, true, true);
1297 cxgb_printf(pi
->dip
, CE_WARN
, "change_mac failed: %d", rc
);
1301 /* LINTED: E_ASSIGN_NARROW_CONV */
1302 pi
->xact_addr_filt
= rc
;
1304 rc
= -t4_link_l1cfg(sc
, sc
->mbox
, pi
->tx_chan
, &pi
->link_cfg
);
1306 cxgb_printf(pi
->dip
, CE_WARN
, "start_link failed: %d", rc
);
1310 rc
= -t4_enable_vi(sc
, sc
->mbox
, pi
->viid
, true, true);
1312 cxgb_printf(pi
->dip
, CE_WARN
, "enable_vi failed: %d", rc
);
1317 setbit(&sc
->open_device_map
, pi
->port_id
);
1320 (void) t4_uninit_synchronized(pi
);
1329 t4_uninit_synchronized(struct port_info
*pi
)
1331 struct adapter
*sc
= pi
->adapter
;
1334 ADAPTER_LOCK_ASSERT_NOTOWNED(sc
);
1337 * Disable the VI so that all its data in either direction is discarded
1338 * by the MPS. Leave everything else (the queues, interrupts, and 1Hz
1339 * tick) intact as the TP can deliver negative advice or data that it's
1340 * holding in its RAM (for an offloaded connection) even after the VI is
1343 rc
= -t4_enable_vi(sc
, sc
->mbox
, pi
->viid
, false, false);
1345 cxgb_printf(pi
->dip
, CE_WARN
, "disable_vi failed: %d", rc
);
1349 disable_port_queues(pi
);
1351 clrbit(&sc
->open_device_map
, pi
->port_id
);
1353 pi
->link_cfg
.link_ok
= 0;
1354 pi
->link_cfg
.speed
= 0;
1355 mac_link_update(pi
->mh
, LINK_STATE_UNKNOWN
);
1361 propinfo(struct port_info
*pi
, const char *name
, mac_prop_info_handle_t ph
)
1363 struct adapter
*sc
= pi
->adapter
;
1364 struct driver_properties
*p
= &sc
->props
;
1365 struct link_config
*lc
= &pi
->link_cfg
;
1369 if (strcmp(name
, T4PROP_TMR_IDX
) == 0)
1370 v
= is_10G_port(pi
) ? p
->tmr_idx_10g
: p
->tmr_idx_1g
;
1371 else if (strcmp(name
, T4PROP_PKTC_IDX
) == 0)
1372 v
= is_10G_port(pi
) ? p
->pktc_idx_10g
: p
->pktc_idx_1g
;
1373 else if (strcmp(name
, T4PROP_HW_CSUM
) == 0)
1374 v
= (pi
->features
& CXGBE_HW_CSUM
) ? 1 : 0;
1375 else if (strcmp(name
, T4PROP_HW_LSO
) == 0)
1376 v
= (pi
->features
& CXGBE_HW_LSO
) ? 1 : 0;
1377 else if (strcmp(name
, T4PROP_TX_PAUSE
) == 0)
1378 v
= (lc
->fc
& PAUSE_TX
) ? 1 : 0;
1379 else if (strcmp(name
, T4PROP_RX_PAUSE
) == 0)
1380 v
= (lc
->fc
& PAUSE_RX
) ? 1 : 0;
1381 #if MAC_VERSION == 1
1382 else if (strcmp(name
, T4PROP_MTU
) == 0)
1388 (void) snprintf(str
, sizeof (str
), "%d", v
);
1389 mac_prop_info_set_default_str(ph
, str
);
1393 getprop(struct port_info
*pi
, const char *name
, uint_t size
, void *val
)
1395 struct link_config
*lc
= &pi
->link_cfg
;
1398 if (strcmp(name
, T4PROP_TMR_IDX
) == 0)
1400 else if (strcmp(name
, T4PROP_PKTC_IDX
) == 0)
1402 else if (strcmp(name
, T4PROP_HW_CSUM
) == 0)
1403 v
= (pi
->features
& CXGBE_HW_CSUM
) ? 1 : 0;
1404 else if (strcmp(name
, T4PROP_HW_LSO
) == 0)
1405 v
= (pi
->features
& CXGBE_HW_LSO
) ? 1 : 0;
1406 else if (strcmp(name
, T4PROP_TX_PAUSE
) == 0)
1407 v
= (lc
->fc
& PAUSE_TX
) ? 1 : 0;
1408 else if (strcmp(name
, T4PROP_RX_PAUSE
) == 0)
1409 v
= (lc
->fc
& PAUSE_RX
) ? 1 : 0;
1410 #if MAC_VERSION == 1
1411 else if (strcmp(name
, T4PROP_MTU
) == 0)
1417 (void) snprintf(val
, size
, "%d", v
);
1422 setprop(struct port_info
*pi
, const char *name
, const void *val
)
1424 struct adapter
*sc
= pi
->adapter
;
1426 int i
, rc
= 0, relink
= 0, rx_mode
= 0;
1427 struct sge_rxq
*rxq
;
1428 struct link_config lc_old
, *lc
= &pi
->link_cfg
;
1431 * Save a copy of link_config. This can be used to restore link_config
1432 * if t4_link_l1cfg() fails.
1434 bcopy(lc
, &lc_old
, sizeof (struct link_config
));
1436 (void) ddi_strtol(val
, NULL
, 0, &v
);
1438 if (strcmp(name
, T4PROP_TMR_IDX
) == 0) {
1439 if (v
< 0 || v
>= SGE_NTIMERS
)
1441 if (v
== pi
->tmr_idx
)
1444 /* LINTED: E_ASSIGN_NARROW_CONV */
1446 for_each_rxq(pi
, i
, rxq
) {
1447 rxq
->iq
.intr_params
= V_QINTR_TIMER_IDX(v
) |
1448 V_QINTR_CNT_EN(pi
->pktc_idx
>= 0);
1451 } else if (strcmp(name
, T4PROP_PKTC_IDX
) == 0) {
1452 if (v
>= SGE_NCOUNTERS
)
1454 if (v
== pi
->pktc_idx
|| (v
< 0 && pi
->pktc_idx
== -1))
1457 /* LINTED: E_ASSIGN_NARROW_CONV */
1458 pi
->pktc_idx
= v
< 0 ? -1 : v
;
1459 for_each_rxq(pi
, i
, rxq
) {
1460 rxq
->iq
.intr_params
= V_QINTR_TIMER_IDX(pi
->tmr_idx
) |
1461 /* takes effect right away */
1462 V_QINTR_CNT_EN(v
>= 0);
1463 /* LINTED: E_ASSIGN_NARROW_CONV */
1464 rxq
->iq
.intr_pktc_idx
= v
; /* this needs fresh plumb */
1466 } else if (strcmp(name
, T4PROP_HW_CSUM
) == 0) {
1467 if (v
!= 0 && v
!= 1)
1470 pi
->features
|= CXGBE_HW_CSUM
;
1472 pi
->features
&= ~CXGBE_HW_CSUM
;
1473 } else if (strcmp(name
, T4PROP_HW_LSO
) == 0) {
1474 if (v
!= 0 && v
!= 1)
1477 pi
->features
|= CXGBE_HW_LSO
;
1479 pi
->features
&= ~CXGBE_HW_LSO
;
1480 } else if (strcmp(name
, T4PROP_TX_PAUSE
) == 0) {
1481 if (v
!= 0 && v
!= 1)
1485 lc
->requested_fc
|= PAUSE_TX
;
1487 lc
->requested_fc
&= ~PAUSE_TX
;
1491 } else if (strcmp(name
, T4PROP_RX_PAUSE
) == 0) {
1492 if (v
!= 0 && v
!= 1)
1496 lc
->requested_fc
|= PAUSE_RX
;
1498 lc
->requested_fc
&= ~PAUSE_RX
;
1502 #if MAC_VERSION == 1
1503 else if (strcmp(name
, T4PROP_MTU
) == 0) {
1504 if (v
< 46 || v
> MAX_MTU
)
1510 (void) mac_maxsdu_update(pi
->mh
, v
);
1517 if (!(relink
|| rx_mode
))
1520 /* If we are here, either relink or rx_mode is 1 */
1521 if (isset(&sc
->open_device_map
, pi
->port_id
) != 0) {
1523 rc
= begin_synchronized_op(pi
, 1, 1);
1526 rc
= -t4_link_l1cfg(sc
, sc
->mbox
, pi
->tx_chan
, lc
);
1527 end_synchronized_op(pi
, 1);
1529 cxgb_printf(pi
->dip
, CE_WARN
,
1530 "start_link failed:%d", rc
);
1531 /* Restore link_config */
1532 bcopy(&lc_old
, lc
, sizeof (struct link_config
));
1534 } else if (rx_mode
!= 0) {
1535 rc
= begin_synchronized_op(pi
, 1, 1);
1538 rc
= -t4_set_rxmode(sc
, sc
->mbox
, pi
->viid
, v
, -1, -1,
1540 end_synchronized_op(pi
, 1);
1542 cxgb_printf(pi
->dip
, CE_WARN
,
1543 "set_rxmode failed: %d", rc
);
1553 t4_mc_init(struct port_info
*pi
)
1555 pi
->props
= t4_priv_props
;
1559 t4_mc_cb_init(struct port_info
*pi
)
1561 if (pi
->adapter
->props
.multi_rings
)
1562 pi
->mc
= &t4_m_ring_callbacks
;
1564 pi
->mc
= &t4_m_callbacks
;
1568 t4_os_link_changed(struct adapter
*sc
, int idx
, int link_stat
)
1570 struct port_info
*pi
= sc
->port
[idx
];
1572 mac_link_update(pi
->mh
, link_stat
? LINK_STATE_UP
: LINK_STATE_DOWN
);
1577 t4_mac_rx(struct port_info
*pi
, struct sge_rxq
*rxq
, mblk_t
*m
)
1579 mac_rx(pi
->mh
, NULL
, m
);
1583 t4_mac_tx_update(struct port_info
*pi
, struct sge_txq
*txq
)
1585 if (pi
->adapter
->props
.multi_rings
)
1586 mac_tx_ring_update(pi
->mh
, txq
->ring_handle
);
1588 mac_tx_update(pi
->mh
);