xref: /illumos-gate/usr/src/uts/common/io/qede/qede_gld.c (revision 589d6798)
114b24e2bSVaishali Kulkarni /*
214b24e2bSVaishali Kulkarni * CDDL HEADER START
314b24e2bSVaishali Kulkarni *
414b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the
514b24e2bSVaishali Kulkarni * Common Development and Distribution License, v.1,  (the "License").
614b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License.
714b24e2bSVaishali Kulkarni *
814b24e2bSVaishali Kulkarni * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
914b24e2bSVaishali Kulkarni * or http://opensource.org/licenses/CDDL-1.0.
1014b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions
1114b24e2bSVaishali Kulkarni * and limitations under the License.
1214b24e2bSVaishali Kulkarni *
1314b24e2bSVaishali Kulkarni * When distributing Covered Code, include this CDDL HEADER in each
1414b24e2bSVaishali Kulkarni * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1514b24e2bSVaishali Kulkarni * If applicable, add the following below this CDDL HEADER, with the
1614b24e2bSVaishali Kulkarni * fields enclosed by brackets "[]" replaced with your own identifying
1714b24e2bSVaishali Kulkarni * information: Portions Copyright [yyyy] [name of copyright owner]
1814b24e2bSVaishali Kulkarni *
1914b24e2bSVaishali Kulkarni * CDDL HEADER END
2014b24e2bSVaishali Kulkarni */
2114b24e2bSVaishali Kulkarni 
2214b24e2bSVaishali Kulkarni /*
2314b24e2bSVaishali Kulkarni * Copyright 2014-2017 Cavium, Inc.
2414b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the Common Development
2514b24e2bSVaishali Kulkarni * and Distribution License, v.1,  (the "License").
2614b24e2bSVaishali Kulkarni 
2714b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License.
2814b24e2bSVaishali Kulkarni 
2914b24e2bSVaishali Kulkarni * You can obtain a copy of the License at available
3014b24e2bSVaishali Kulkarni * at http://opensource.org/licenses/CDDL-1.0
3114b24e2bSVaishali Kulkarni 
3214b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions and
3314b24e2bSVaishali Kulkarni * limitations under the License.
3414b24e2bSVaishali Kulkarni */
3514b24e2bSVaishali Kulkarni 
36b68ddc76SJohn Levon /*
37b68ddc76SJohn Levon  * Copyright 2018 Joyent, Inc.
38b68ddc76SJohn Levon  */
3914b24e2bSVaishali Kulkarni 
4014b24e2bSVaishali Kulkarni #include "qede.h"
4114b24e2bSVaishali Kulkarni 
4214b24e2bSVaishali Kulkarni #define	FP_LOCK(ptr)	\
4314b24e2bSVaishali Kulkarni mutex_enter(&ptr->fp_lock);
4414b24e2bSVaishali Kulkarni #define	FP_UNLOCK(ptr)	\
4514b24e2bSVaishali Kulkarni mutex_exit(&ptr->fp_lock);
4614b24e2bSVaishali Kulkarni 
4714b24e2bSVaishali Kulkarni int
qede_ucst_find(qede_t * qede,const uint8_t * mac_addr)4814b24e2bSVaishali Kulkarni qede_ucst_find(qede_t *qede, const uint8_t *mac_addr)
4914b24e2bSVaishali Kulkarni {
5014b24e2bSVaishali Kulkarni 	int slot;
5114b24e2bSVaishali Kulkarni 
5214b24e2bSVaishali Kulkarni 	for(slot = 0; slot < qede->ucst_total; slot++) {
5314b24e2bSVaishali Kulkarni 		if (bcmp(qede->ucst_mac[slot].mac_addr.ether_addr_octet,
5414b24e2bSVaishali Kulkarni 		    mac_addr, ETHERADDRL) == 0) {
5514b24e2bSVaishali Kulkarni 			return (slot);
5614b24e2bSVaishali Kulkarni 		}
5714b24e2bSVaishali Kulkarni 	}
5814b24e2bSVaishali Kulkarni 	return (-1);
5914b24e2bSVaishali Kulkarni 
6014b24e2bSVaishali Kulkarni }
6114b24e2bSVaishali Kulkarni 
6214b24e2bSVaishali Kulkarni static int
qede_set_mac_addr(qede_t * qede,uint8_t * mac_addr,uint8_t fl)6314b24e2bSVaishali Kulkarni qede_set_mac_addr(qede_t *qede, uint8_t *mac_addr, uint8_t fl)
6414b24e2bSVaishali Kulkarni {
6514b24e2bSVaishali Kulkarni 	struct ecore_filter_ucast params;
6614b24e2bSVaishali Kulkarni 
6714b24e2bSVaishali Kulkarni 	memset(&params, 0, sizeof (params));
6814b24e2bSVaishali Kulkarni 
6914b24e2bSVaishali Kulkarni 	params.opcode = fl;
7014b24e2bSVaishali Kulkarni 	params.type = ECORE_FILTER_MAC;
7114b24e2bSVaishali Kulkarni 	params.is_rx_filter = true;
7214b24e2bSVaishali Kulkarni 	params.is_tx_filter = true;
7314b24e2bSVaishali Kulkarni 	COPY_ETH_ADDRESS(mac_addr, params.mac);
7414b24e2bSVaishali Kulkarni 
7514b24e2bSVaishali Kulkarni 	return (ecore_filter_ucast_cmd(&qede->edev,
7614b24e2bSVaishali Kulkarni 	    &params, ECORE_SPQ_MODE_EBLOCK, NULL));
7714b24e2bSVaishali Kulkarni 
7814b24e2bSVaishali Kulkarni 
7914b24e2bSVaishali Kulkarni }
8014b24e2bSVaishali Kulkarni static int
qede_add_macaddr(qede_t * qede,uint8_t * mac_addr)8114b24e2bSVaishali Kulkarni qede_add_macaddr(qede_t *qede, uint8_t *mac_addr)
8214b24e2bSVaishali Kulkarni {
8314b24e2bSVaishali Kulkarni 	int i, ret = 0;
8414b24e2bSVaishali Kulkarni 
8514b24e2bSVaishali Kulkarni 	i = qede_ucst_find(qede, mac_addr);
8614b24e2bSVaishali Kulkarni 	if (i != -1) {
8714b24e2bSVaishali Kulkarni 		/* LINTED E_ARGUMENT_MISMATCH */
8814b24e2bSVaishali Kulkarni 		qede_info(qede, "mac addr already added %d\n",
8914b24e2bSVaishali Kulkarni 		    qede->ucst_avail);
9014b24e2bSVaishali Kulkarni 		return (0);
9114b24e2bSVaishali Kulkarni 	}
9214b24e2bSVaishali Kulkarni 	if (qede->ucst_avail == 0) {
9314b24e2bSVaishali Kulkarni 		qede_info(qede, "add macaddr ignored \n");
9414b24e2bSVaishali Kulkarni 		return (ENOSPC);
9514b24e2bSVaishali Kulkarni 	}
9614b24e2bSVaishali Kulkarni 	for (i = 0; i < qede->ucst_total; i++) {
9714b24e2bSVaishali Kulkarni 		if (qede->ucst_mac[i].set == 0) {
9814b24e2bSVaishali Kulkarni 			break;
9914b24e2bSVaishali Kulkarni 		}
10014b24e2bSVaishali Kulkarni 	}
10114b24e2bSVaishali Kulkarni 	if (i >= qede->ucst_total) {
10214b24e2bSVaishali Kulkarni 		qede_info(qede, "add macaddr ignored no space");
10314b24e2bSVaishali Kulkarni 		return (ENOSPC);
10414b24e2bSVaishali Kulkarni 	}
10514b24e2bSVaishali Kulkarni 	ret = qede_set_mac_addr(qede, (uint8_t *)mac_addr, ECORE_FILTER_ADD);
10614b24e2bSVaishali Kulkarni 	if (ret == 0) {
10714b24e2bSVaishali Kulkarni 		bcopy(mac_addr,
10814b24e2bSVaishali Kulkarni 		    qede->ucst_mac[i].mac_addr.ether_addr_octet,
10914b24e2bSVaishali Kulkarni 		    ETHERADDRL);
11014b24e2bSVaishali Kulkarni 		qede->ucst_mac[i].set = 1;
11114b24e2bSVaishali Kulkarni 		qede->ucst_avail--;
11214b24e2bSVaishali Kulkarni 		/* LINTED E_ARGUMENT_MISMATCH */
11314b24e2bSVaishali Kulkarni 		qede_info(qede,  " add macaddr passed for addr "
11414b24e2bSVaishali Kulkarni 		    "%02x:%02x:%02x:%02x:%02x:%02x",
11514b24e2bSVaishali Kulkarni 		    mac_addr[0], mac_addr[1],
11614b24e2bSVaishali Kulkarni 		    mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
11714b24e2bSVaishali Kulkarni 	} else {
11814b24e2bSVaishali Kulkarni 		/* LINTED E_ARGUMENT_MISMATCH */
11914b24e2bSVaishali Kulkarni 		qede_info(qede,  "add macaddr failed for addr "
12014b24e2bSVaishali Kulkarni 		    "%02x:%02x:%02x:%02x:%02x:%02x",
12114b24e2bSVaishali Kulkarni 		    mac_addr[0], mac_addr[1],
12214b24e2bSVaishali Kulkarni 		    mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
12314b24e2bSVaishali Kulkarni 
12414b24e2bSVaishali Kulkarni 	}
12514b24e2bSVaishali Kulkarni 	if (qede->ucst_avail == (qede->ucst_total -1)) {
12614b24e2bSVaishali Kulkarni 			u8 bcast_addr[] =
12714b24e2bSVaishali Kulkarni 			{
12814b24e2bSVaishali Kulkarni 				0xff, 0xff, 0xff, 0xff, 0xff,
12914b24e2bSVaishali Kulkarni 				0xff
13014b24e2bSVaishali Kulkarni 			};
13114b24e2bSVaishali Kulkarni 			for (i = 0; i < qede->ucst_total; i++) {
13214b24e2bSVaishali Kulkarni 				if (qede->ucst_mac[i].set == 0)
13314b24e2bSVaishali Kulkarni 					break;
13414b24e2bSVaishali Kulkarni 			}
13514b24e2bSVaishali Kulkarni 			ret = qede_set_mac_addr(qede,
13614b24e2bSVaishali Kulkarni 			    (uint8_t *)bcast_addr, ECORE_FILTER_ADD);
13714b24e2bSVaishali Kulkarni 			if (ret == 0) {
13814b24e2bSVaishali Kulkarni 				bcopy(bcast_addr,
13914b24e2bSVaishali Kulkarni 				    qede->ucst_mac[i].mac_addr.ether_addr_octet,
14014b24e2bSVaishali Kulkarni 				    ETHERADDRL);
14114b24e2bSVaishali Kulkarni 				qede->ucst_mac[i].set = 1;
14214b24e2bSVaishali Kulkarni 				qede->ucst_avail--;
14314b24e2bSVaishali Kulkarni 			} else {
14414b24e2bSVaishali Kulkarni 
14514b24e2bSVaishali Kulkarni 			/* LINTED E_ARGUMENT_MISMATCH */
14614b24e2bSVaishali Kulkarni 			qede_info(qede,  "add macaddr failed for addr "
14714b24e2bSVaishali Kulkarni 			    "%02x:%02x:%02x:%02x:%02x:%02x",
14814b24e2bSVaishali Kulkarni 		            mac_addr[0], mac_addr[1],
14914b24e2bSVaishali Kulkarni 		            mac_addr[2], mac_addr[3], mac_addr[4],
15014b24e2bSVaishali Kulkarni 			    mac_addr[5]);
15114b24e2bSVaishali Kulkarni 		       }
15214b24e2bSVaishali Kulkarni 
15314b24e2bSVaishali Kulkarni 		}
15414b24e2bSVaishali Kulkarni 
15514b24e2bSVaishali Kulkarni 	return (ret);
15614b24e2bSVaishali Kulkarni 
15714b24e2bSVaishali Kulkarni }
15814b24e2bSVaishali Kulkarni 
15914b24e2bSVaishali Kulkarni #ifndef ILLUMOS
16014b24e2bSVaishali Kulkarni static int
qede_add_mac_addr(void * arg,const uint8_t * mac_addr,const uint64_t flags)16114b24e2bSVaishali Kulkarni qede_add_mac_addr(void *arg, const uint8_t *mac_addr, const uint64_t flags)
16214b24e2bSVaishali Kulkarni #else
16314b24e2bSVaishali Kulkarni static int
16414b24e2bSVaishali Kulkarni qede_add_mac_addr(void *arg, const uint8_t *mac_addr)
16514b24e2bSVaishali Kulkarni #endif
16614b24e2bSVaishali Kulkarni {
16714b24e2bSVaishali Kulkarni 	qede_mac_group_t *rx_group = (qede_mac_group_t *)arg;
16814b24e2bSVaishali Kulkarni 	qede_t *qede = rx_group->qede;
16914b24e2bSVaishali Kulkarni 	int ret = DDI_SUCCESS;
17014b24e2bSVaishali Kulkarni 
17114b24e2bSVaishali Kulkarni 	/* LINTED E_ARGUMENT_MISMATCH */
17214b24e2bSVaishali Kulkarni 	qede_info(qede, " mac addr :" MAC_STRING,  MACTOSTR(mac_addr));
17314b24e2bSVaishali Kulkarni 
17414b24e2bSVaishali Kulkarni 	mutex_enter(&qede->gld_lock);
17514b24e2bSVaishali Kulkarni 	if (qede->qede_state == QEDE_STATE_SUSPENDED) {
17614b24e2bSVaishali Kulkarni 		mutex_exit(&qede->gld_lock);
17714b24e2bSVaishali Kulkarni 		return (ECANCELED);
17814b24e2bSVaishali Kulkarni 	}
17914b24e2bSVaishali Kulkarni 	ret = qede_add_macaddr(qede, (uint8_t *)mac_addr);
18014b24e2bSVaishali Kulkarni 
18114b24e2bSVaishali Kulkarni 	mutex_exit(&qede->gld_lock);
18214b24e2bSVaishali Kulkarni 
18314b24e2bSVaishali Kulkarni 
18414b24e2bSVaishali Kulkarni 	return (ret);
18514b24e2bSVaishali Kulkarni }
18614b24e2bSVaishali Kulkarni 
18714b24e2bSVaishali Kulkarni static int
qede_rem_macaddr(qede_t * qede,uint8_t * mac_addr)18814b24e2bSVaishali Kulkarni qede_rem_macaddr(qede_t *qede, uint8_t *mac_addr)
18914b24e2bSVaishali Kulkarni {
19014b24e2bSVaishali Kulkarni 	int ret = 0;
19114b24e2bSVaishali Kulkarni 	int i;
19214b24e2bSVaishali Kulkarni 
19314b24e2bSVaishali Kulkarni 	i = qede_ucst_find(qede, mac_addr);
19414b24e2bSVaishali Kulkarni 	if (i == -1) {
19514b24e2bSVaishali Kulkarni 		/* LINTED E_ARGUMENT_MISMATCH */
19614b24e2bSVaishali Kulkarni 		qede_info(qede,
19714b24e2bSVaishali Kulkarni 		    "mac addr not there to remove",
19814b24e2bSVaishali Kulkarni 		    MAC_STRING, MACTOSTR(mac_addr));
19914b24e2bSVaishali Kulkarni 		return (0);
20014b24e2bSVaishali Kulkarni 	}
20114b24e2bSVaishali Kulkarni 	if (qede->ucst_mac[i].set == 0) {
20214b24e2bSVaishali Kulkarni 	       	return (EINVAL);
20314b24e2bSVaishali Kulkarni 	}
20414b24e2bSVaishali Kulkarni 	ret = qede_set_mac_addr(qede, (uint8_t *)mac_addr, ECORE_FILTER_REMOVE);
20514b24e2bSVaishali Kulkarni 	if (ret == 0) {
20614b24e2bSVaishali Kulkarni 		bzero(qede->ucst_mac[i].mac_addr.ether_addr_octet,ETHERADDRL);
20714b24e2bSVaishali Kulkarni 		qede->ucst_mac[i].set = 0;
20814b24e2bSVaishali Kulkarni 		qede->ucst_avail++;
20914b24e2bSVaishali Kulkarni 	} else {
21014b24e2bSVaishali Kulkarni 		/* LINTED E_ARGUMENT_MISMATCH */
21114b24e2bSVaishali Kulkarni 		qede_info(qede, "mac addr remove failed",
21214b24e2bSVaishali Kulkarni 		    MAC_STRING, MACTOSTR(mac_addr));
21314b24e2bSVaishali Kulkarni 	}
21414b24e2bSVaishali Kulkarni 	return (ret);
21514b24e2bSVaishali Kulkarni 
21614b24e2bSVaishali Kulkarni }
21714b24e2bSVaishali Kulkarni 
21814b24e2bSVaishali Kulkarni 
21914b24e2bSVaishali Kulkarni static int
qede_rem_mac_addr(void * arg,const uint8_t * mac_addr)22014b24e2bSVaishali Kulkarni qede_rem_mac_addr(void *arg, const uint8_t *mac_addr)
22114b24e2bSVaishali Kulkarni {
22214b24e2bSVaishali Kulkarni 	qede_mac_group_t *rx_group = (qede_mac_group_t *)arg;
22314b24e2bSVaishali Kulkarni 	qede_t *qede = rx_group->qede;
22414b24e2bSVaishali Kulkarni 	int ret = DDI_SUCCESS;
22514b24e2bSVaishali Kulkarni 
22614b24e2bSVaishali Kulkarni 	/* LINTED E_ARGUMENT_MISMATCH */
22714b24e2bSVaishali Kulkarni 	qede_info(qede, "mac addr remove:" MAC_STRING, MACTOSTR(mac_addr));
22814b24e2bSVaishali Kulkarni 	mutex_enter(&qede->gld_lock);
22914b24e2bSVaishali Kulkarni 	if (qede->qede_state == QEDE_STATE_SUSPENDED) {
23014b24e2bSVaishali Kulkarni 		mutex_exit(&qede->gld_lock);
23114b24e2bSVaishali Kulkarni 		return (ECANCELED);
23214b24e2bSVaishali Kulkarni 	}
23314b24e2bSVaishali Kulkarni 	ret = qede_rem_macaddr(qede, (uint8_t *)mac_addr);
23414b24e2bSVaishali Kulkarni 	mutex_exit(&qede->gld_lock);
23514b24e2bSVaishali Kulkarni 	return (ret);
23614b24e2bSVaishali Kulkarni }
23714b24e2bSVaishali Kulkarni 
23814b24e2bSVaishali Kulkarni 
23914b24e2bSVaishali Kulkarni static int
qede_tx_ring_stat(mac_ring_driver_t rh,uint_t stat,uint64_t * val)24014b24e2bSVaishali Kulkarni qede_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
24114b24e2bSVaishali Kulkarni {
24214b24e2bSVaishali Kulkarni 	int ret = 0;
24314b24e2bSVaishali Kulkarni 
24414b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)rh;
24514b24e2bSVaishali Kulkarni 	qede_tx_ring_t *tx_ring = fp->tx_ring[0];
24614b24e2bSVaishali Kulkarni 	qede_t *qede = fp->qede;
24714b24e2bSVaishali Kulkarni 
24814b24e2bSVaishali Kulkarni 
24914b24e2bSVaishali Kulkarni 	if (qede->qede_state == QEDE_STATE_SUSPENDED)
25014b24e2bSVaishali Kulkarni 		return (ECANCELED);
25114b24e2bSVaishali Kulkarni 
25214b24e2bSVaishali Kulkarni 	switch (stat) {
25314b24e2bSVaishali Kulkarni 	case MAC_STAT_OBYTES:
25414b24e2bSVaishali Kulkarni 		*val = tx_ring->tx_byte_count;
25514b24e2bSVaishali Kulkarni 		break;
25614b24e2bSVaishali Kulkarni 
25714b24e2bSVaishali Kulkarni 	case MAC_STAT_OPACKETS:
25814b24e2bSVaishali Kulkarni 		*val = tx_ring->tx_pkt_count;
25914b24e2bSVaishali Kulkarni 		break;
26014b24e2bSVaishali Kulkarni 
26114b24e2bSVaishali Kulkarni 	default:
26214b24e2bSVaishali Kulkarni 		*val = 0;
26314b24e2bSVaishali Kulkarni 		ret = ENOTSUP;
26414b24e2bSVaishali Kulkarni 	}
26514b24e2bSVaishali Kulkarni 
26614b24e2bSVaishali Kulkarni 	return (ret);
26714b24e2bSVaishali Kulkarni }
26814b24e2bSVaishali Kulkarni 
26914b24e2bSVaishali Kulkarni #ifndef ILLUMOS
27014b24e2bSVaishali Kulkarni static mblk_t *
qede_rx_ring_poll(void * arg,int poll_bytes,int poll_pkts)27114b24e2bSVaishali Kulkarni qede_rx_ring_poll(void *arg, int poll_bytes, int poll_pkts)
27214b24e2bSVaishali Kulkarni {
27314b24e2bSVaishali Kulkarni #else
27414b24e2bSVaishali Kulkarni static mblk_t *
27514b24e2bSVaishali Kulkarni qede_rx_ring_poll(void *arg, int poll_bytes)
27614b24e2bSVaishali Kulkarni {
27714b24e2bSVaishali Kulkarni 	/* XXX pick a value at the moment */
27814b24e2bSVaishali Kulkarni 	int poll_pkts = 100;
27914b24e2bSVaishali Kulkarni #endif
28014b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)arg;
28114b24e2bSVaishali Kulkarni 	mblk_t *mp = NULL;
28214b24e2bSVaishali Kulkarni 	int work_done = 0;
28314b24e2bSVaishali Kulkarni 	qede_t *qede = fp->qede;
28414b24e2bSVaishali Kulkarni 
28514b24e2bSVaishali Kulkarni 	if (poll_bytes == 0) {
28614b24e2bSVaishali Kulkarni 		return (NULL);
28714b24e2bSVaishali Kulkarni 	}
28814b24e2bSVaishali Kulkarni 
28914b24e2bSVaishali Kulkarni 	mutex_enter(&fp->fp_lock);
29014b24e2bSVaishali Kulkarni 	qede->intrSbPollCnt[fp->vect_info->vect_index]++;
29114b24e2bSVaishali Kulkarni 
29214b24e2bSVaishali Kulkarni 	mp = qede_process_fastpath(fp, poll_bytes, poll_pkts, &work_done);
29314b24e2bSVaishali Kulkarni 	if (mp != NULL) {
29414b24e2bSVaishali Kulkarni 		fp->rx_ring->rx_poll_cnt++;
29514b24e2bSVaishali Kulkarni 	} else if ((mp == NULL) && (work_done == 0)) {
29614b24e2bSVaishali Kulkarni 		qede->intrSbPollNoChangeCnt[fp->vect_info->vect_index]++;
29714b24e2bSVaishali Kulkarni 	}
29814b24e2bSVaishali Kulkarni 
29914b24e2bSVaishali Kulkarni 	mutex_exit(&fp->fp_lock);
30014b24e2bSVaishali Kulkarni 	return (mp);
30114b24e2bSVaishali Kulkarni }
30214b24e2bSVaishali Kulkarni 
30314b24e2bSVaishali Kulkarni #ifndef ILLUMOS
30414b24e2bSVaishali Kulkarni static int
30514b24e2bSVaishali Kulkarni qede_rx_ring_intr_enable(mac_ring_driver_t rh)
30614b24e2bSVaishali Kulkarni #else
30714b24e2bSVaishali Kulkarni static int
30814b24e2bSVaishali Kulkarni qede_rx_ring_intr_enable(mac_intr_handle_t rh)
30914b24e2bSVaishali Kulkarni #endif
31014b24e2bSVaishali Kulkarni {
31114b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)rh;
31214b24e2bSVaishali Kulkarni 
31314b24e2bSVaishali Kulkarni 	mutex_enter(&fp->qede->drv_lock);
31414b24e2bSVaishali Kulkarni 	if (!fp->sb_phys && (fp->sb_dma_handle == NULL)) {
31514b24e2bSVaishali Kulkarni 		mutex_exit(&fp->qede->drv_lock);
31614b24e2bSVaishali Kulkarni 		return (DDI_FAILURE);
31714b24e2bSVaishali Kulkarni 	}
31814b24e2bSVaishali Kulkarni 
31914b24e2bSVaishali Kulkarni 	fp->rx_ring->intrEnableCnt++;
32014b24e2bSVaishali Kulkarni 	qede_enable_hw_intr(fp);
32114b24e2bSVaishali Kulkarni 	fp->disabled_by_poll = 0;
32214b24e2bSVaishali Kulkarni 	mutex_exit(&fp->qede->drv_lock);
32314b24e2bSVaishali Kulkarni 
32414b24e2bSVaishali Kulkarni 	return (DDI_SUCCESS);
32514b24e2bSVaishali Kulkarni }
32614b24e2bSVaishali Kulkarni 
32714b24e2bSVaishali Kulkarni #ifndef	ILLUMOS
32814b24e2bSVaishali Kulkarni static int
32914b24e2bSVaishali Kulkarni qede_rx_ring_intr_disable(mac_ring_driver_t rh)
33014b24e2bSVaishali Kulkarni #else
33114b24e2bSVaishali Kulkarni static int
33214b24e2bSVaishali Kulkarni qede_rx_ring_intr_disable(mac_intr_handle_t rh)
33314b24e2bSVaishali Kulkarni #endif
33414b24e2bSVaishali Kulkarni {
33514b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)rh;
33614b24e2bSVaishali Kulkarni 
33714b24e2bSVaishali Kulkarni 	mutex_enter(&fp->qede->drv_lock);
33814b24e2bSVaishali Kulkarni 	if (!fp->sb_phys && (fp->sb_dma_handle == NULL)) {
33914b24e2bSVaishali Kulkarni 		mutex_exit(&fp->qede->drv_lock);
34014b24e2bSVaishali Kulkarni 		return (DDI_FAILURE);
34114b24e2bSVaishali Kulkarni 	}
34214b24e2bSVaishali Kulkarni 	fp->rx_ring->intrDisableCnt++;
34314b24e2bSVaishali Kulkarni 	qede_disable_hw_intr(fp);
34414b24e2bSVaishali Kulkarni 	fp->disabled_by_poll = 1;
34514b24e2bSVaishali Kulkarni 	mutex_exit(&fp->qede->drv_lock);
34614b24e2bSVaishali Kulkarni 	return (DDI_SUCCESS);
34714b24e2bSVaishali Kulkarni }
34814b24e2bSVaishali Kulkarni 
34914b24e2bSVaishali Kulkarni static int
35014b24e2bSVaishali Kulkarni qede_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
35114b24e2bSVaishali Kulkarni {
35214b24e2bSVaishali Kulkarni 
35314b24e2bSVaishali Kulkarni 	int ret = 0;
35414b24e2bSVaishali Kulkarni 
35514b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)rh;
35614b24e2bSVaishali Kulkarni 	qede_t *qede = fp->qede;
35714b24e2bSVaishali Kulkarni 	qede_rx_ring_t *rx_ring = fp->rx_ring;
35814b24e2bSVaishali Kulkarni 
35914b24e2bSVaishali Kulkarni 	if (qede->qede_state == QEDE_STATE_SUSPENDED) {
36014b24e2bSVaishali Kulkarni 		return (ECANCELED);
36114b24e2bSVaishali Kulkarni 	}
36214b24e2bSVaishali Kulkarni 
36314b24e2bSVaishali Kulkarni 	switch (stat) {
36414b24e2bSVaishali Kulkarni 	case MAC_STAT_RBYTES:
36514b24e2bSVaishali Kulkarni 		*val = rx_ring->rx_byte_cnt;
36614b24e2bSVaishali Kulkarni 		break;
36714b24e2bSVaishali Kulkarni 	case MAC_STAT_IPACKETS:
36814b24e2bSVaishali Kulkarni 		*val = rx_ring->rx_pkt_cnt;
36914b24e2bSVaishali Kulkarni 		break;
37014b24e2bSVaishali Kulkarni 	default:
37114b24e2bSVaishali Kulkarni 		*val = 0;
37214b24e2bSVaishali Kulkarni 		ret = ENOTSUP;
37314b24e2bSVaishali Kulkarni 		break;
37414b24e2bSVaishali Kulkarni 	}
37514b24e2bSVaishali Kulkarni 
37614b24e2bSVaishali Kulkarni 	return (ret);
37714b24e2bSVaishali Kulkarni }
37814b24e2bSVaishali Kulkarni 
37914b24e2bSVaishali Kulkarni static int
38014b24e2bSVaishali Kulkarni qede_get_global_ring_index(qede_t *qede, int gindex, int rindex)
38114b24e2bSVaishali Kulkarni {
38214b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp;
38314b24e2bSVaishali Kulkarni 	qede_rx_ring_t *rx_ring;
38414b24e2bSVaishali Kulkarni 	int i = 0;
38514b24e2bSVaishali Kulkarni 
38614b24e2bSVaishali Kulkarni 	for (i = 0; i < qede->num_fp; i++) {
38714b24e2bSVaishali Kulkarni 		fp = &qede->fp_array[i];
38814b24e2bSVaishali Kulkarni 		rx_ring = fp->rx_ring;
38914b24e2bSVaishali Kulkarni 
39014b24e2bSVaishali Kulkarni 		if (rx_ring->group_index == gindex) {
39114b24e2bSVaishali Kulkarni 			rindex--;
39214b24e2bSVaishali Kulkarni 		}
39314b24e2bSVaishali Kulkarni 		if (rindex < 0) {
39414b24e2bSVaishali Kulkarni 			return (i);
39514b24e2bSVaishali Kulkarni 		}
39614b24e2bSVaishali Kulkarni 	}
39714b24e2bSVaishali Kulkarni 
39814b24e2bSVaishali Kulkarni 	return (-1);
39914b24e2bSVaishali Kulkarni }
40014b24e2bSVaishali Kulkarni 
40114b24e2bSVaishali Kulkarni static void
40214b24e2bSVaishali Kulkarni qede_rx_ring_stop(mac_ring_driver_t rh)
40314b24e2bSVaishali Kulkarni {
40414b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)rh;
40514b24e2bSVaishali Kulkarni 	qede_rx_ring_t *rx_ring = fp->rx_ring;
40614b24e2bSVaishali Kulkarni 
40714b24e2bSVaishali Kulkarni 	qede_print("!%s(%d): called", __func__,fp->qede->instance);
40814b24e2bSVaishali Kulkarni 	mutex_enter(&fp->fp_lock);
40914b24e2bSVaishali Kulkarni 	rx_ring->mac_ring_started = B_FALSE;
41014b24e2bSVaishali Kulkarni 	mutex_exit(&fp->fp_lock);
41114b24e2bSVaishali Kulkarni }
41214b24e2bSVaishali Kulkarni 
41314b24e2bSVaishali Kulkarni static int
41414b24e2bSVaishali Kulkarni qede_rx_ring_start(mac_ring_driver_t rh, u64 mr_gen_num)
41514b24e2bSVaishali Kulkarni {
41614b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)rh;
41714b24e2bSVaishali Kulkarni 	qede_rx_ring_t *rx_ring = fp->rx_ring;
41814b24e2bSVaishali Kulkarni 
41914b24e2bSVaishali Kulkarni 	qede_print("!%s(%d): called", __func__,fp->qede->instance);
42014b24e2bSVaishali Kulkarni 	mutex_enter(&fp->fp_lock);
42114b24e2bSVaishali Kulkarni 	rx_ring->mr_gen_num = mr_gen_num;
42214b24e2bSVaishali Kulkarni 	rx_ring->mac_ring_started = B_TRUE;
42314b24e2bSVaishali Kulkarni         rx_ring->intrDisableCnt = 0;
42414b24e2bSVaishali Kulkarni 	rx_ring->intrEnableCnt  = 0;
42514b24e2bSVaishali Kulkarni 	fp->disabled_by_poll = 0;
42614b24e2bSVaishali Kulkarni 
42714b24e2bSVaishali Kulkarni 	mutex_exit(&fp->fp_lock);
42814b24e2bSVaishali Kulkarni 
42914b24e2bSVaishali Kulkarni 	return (DDI_SUCCESS);
43014b24e2bSVaishali Kulkarni }
43114b24e2bSVaishali Kulkarni 
43214b24e2bSVaishali Kulkarni /* Callback function from mac layer to register rings */
43314b24e2bSVaishali Kulkarni void
43414b24e2bSVaishali Kulkarni qede_fill_ring(void *arg, mac_ring_type_t rtype, const int group_index,
43514b24e2bSVaishali Kulkarni     const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh)
43614b24e2bSVaishali Kulkarni {
43714b24e2bSVaishali Kulkarni 	qede_t *qede = (qede_t *)arg;
43814b24e2bSVaishali Kulkarni 	mac_intr_t *mintr = &infop->mri_intr;
43914b24e2bSVaishali Kulkarni 
44014b24e2bSVaishali Kulkarni 	switch (rtype) {
44114b24e2bSVaishali Kulkarni 	case MAC_RING_TYPE_RX: {
44214b24e2bSVaishali Kulkarni 		/*
44314b24e2bSVaishali Kulkarni 		 * Index passed as a param is the ring index within the
44414b24e2bSVaishali Kulkarni 		 * given group index. If multiple groups are supported
44514b24e2bSVaishali Kulkarni 		 * then need to search into all groups to find out the
44614b24e2bSVaishali Kulkarni 		 * global ring index for the passed group relative
44714b24e2bSVaishali Kulkarni 		 * ring index
44814b24e2bSVaishali Kulkarni 		 */
44914b24e2bSVaishali Kulkarni 		int global_ring_index = qede_get_global_ring_index(qede,
45014b24e2bSVaishali Kulkarni 		    group_index, ring_index);
45114b24e2bSVaishali Kulkarni 		qede_fastpath_t *fp;
45214b24e2bSVaishali Kulkarni 		qede_rx_ring_t *rx_ring;
45314b24e2bSVaishali Kulkarni 		int i;
45414b24e2bSVaishali Kulkarni 
45514b24e2bSVaishali Kulkarni 		/*
45614b24e2bSVaishali Kulkarni 		 * global_ring_index < 0 means group index passed
45714b24e2bSVaishali Kulkarni 		 * was registered by our driver
45814b24e2bSVaishali Kulkarni 		 */
45914b24e2bSVaishali Kulkarni 		ASSERT(global_ring_index >= 0);
46014b24e2bSVaishali Kulkarni 
46114b24e2bSVaishali Kulkarni 		if (rh == NULL) {
46214b24e2bSVaishali Kulkarni 			cmn_err(CE_WARN, "!rx ring(%d) ring handle NULL",
46314b24e2bSVaishali Kulkarni 			    global_ring_index);
46414b24e2bSVaishali Kulkarni 		}
46514b24e2bSVaishali Kulkarni 
46614b24e2bSVaishali Kulkarni 		fp = &qede->fp_array[global_ring_index];
46714b24e2bSVaishali Kulkarni 		rx_ring = fp->rx_ring;
46814b24e2bSVaishali Kulkarni 		fp->qede = qede;
46914b24e2bSVaishali Kulkarni 
47014b24e2bSVaishali Kulkarni 		rx_ring->mac_ring_handle = rh;
47114b24e2bSVaishali Kulkarni 
47214b24e2bSVaishali Kulkarni 		qede_info(qede, "rx_ring %d mac_ring_handle %p",
47314b24e2bSVaishali Kulkarni 		    rx_ring->rss_id, rh);
47414b24e2bSVaishali Kulkarni 
47514b24e2bSVaishali Kulkarni 		/* mri_driver passed as arg to mac_ring* callbacks */
47614b24e2bSVaishali Kulkarni 		infop->mri_driver = (mac_ring_driver_t)fp;
47714b24e2bSVaishali Kulkarni 		/*
47814b24e2bSVaishali Kulkarni 		 * mri_start callback will supply a mac rings generation
47914b24e2bSVaishali Kulkarni 		 * number which is needed while indicating packets
48014b24e2bSVaishali Kulkarni 		 * upstream via mac_ring_rx() call
48114b24e2bSVaishali Kulkarni 		 */
48214b24e2bSVaishali Kulkarni 		infop->mri_start = qede_rx_ring_start;
48314b24e2bSVaishali Kulkarni 		infop->mri_stop = qede_rx_ring_stop;
48414b24e2bSVaishali Kulkarni 		infop->mri_poll = qede_rx_ring_poll;
48514b24e2bSVaishali Kulkarni 		infop->mri_stat = qede_rx_ring_stat;
48614b24e2bSVaishali Kulkarni 
48714b24e2bSVaishali Kulkarni 		mintr->mi_handle = (mac_intr_handle_t)fp;
48814b24e2bSVaishali Kulkarni 		mintr->mi_enable = qede_rx_ring_intr_enable;
48914b24e2bSVaishali Kulkarni 		mintr->mi_disable = qede_rx_ring_intr_disable;
49014b24e2bSVaishali Kulkarni 		if (qede->intr_ctx.intr_type_in_use &
49114b24e2bSVaishali Kulkarni 		    (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) {
49214b24e2bSVaishali Kulkarni 			mintr->mi_ddi_handle =
49314b24e2bSVaishali Kulkarni 			    qede->intr_ctx.
49414b24e2bSVaishali Kulkarni 			    intr_hdl_array[global_ring_index + qede->num_hwfns];
49514b24e2bSVaishali Kulkarni 		}
49614b24e2bSVaishali Kulkarni 		break;
49714b24e2bSVaishali Kulkarni 	}
49814b24e2bSVaishali Kulkarni 	case MAC_RING_TYPE_TX: {
49914b24e2bSVaishali Kulkarni 		qede_fastpath_t *fp;
50014b24e2bSVaishali Kulkarni 		qede_tx_ring_t *tx_ring;
50114b24e2bSVaishali Kulkarni 		int i, tc;
50214b24e2bSVaishali Kulkarni 
50314b24e2bSVaishali Kulkarni 		ASSERT(ring_index < qede->num_fp);
50414b24e2bSVaishali Kulkarni 
50514b24e2bSVaishali Kulkarni 		fp = &qede->fp_array[ring_index];
50614b24e2bSVaishali Kulkarni 		fp->qede = qede;
50714b24e2bSVaishali Kulkarni 		tx_ring = fp->tx_ring[0];
50814b24e2bSVaishali Kulkarni 		tx_ring->mac_ring_handle = rh;
50914b24e2bSVaishali Kulkarni 		qede_info(qede, "tx_ring %d mac_ring_handle %p",
51014b24e2bSVaishali Kulkarni 		    tx_ring->tx_queue_index, rh);
51114b24e2bSVaishali Kulkarni 		infop->mri_driver = (mac_ring_driver_t)fp;
51214b24e2bSVaishali Kulkarni 		infop->mri_start = NULL;
51314b24e2bSVaishali Kulkarni 		infop->mri_stop = NULL;
51414b24e2bSVaishali Kulkarni 		infop->mri_tx = qede_ring_tx;
51514b24e2bSVaishali Kulkarni 		infop->mri_stat = qede_tx_ring_stat;
51614b24e2bSVaishali Kulkarni 		if (qede->intr_ctx.intr_type_in_use &
51714b24e2bSVaishali Kulkarni 		    (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) {
51814b24e2bSVaishali Kulkarni 			mintr->mi_ddi_handle =
51914b24e2bSVaishali Kulkarni 			    qede->intr_ctx.
52014b24e2bSVaishali Kulkarni 			    intr_hdl_array[ring_index + qede->num_hwfns];
52114b24e2bSVaishali Kulkarni 		}
52214b24e2bSVaishali Kulkarni 		break;
52314b24e2bSVaishali Kulkarni 	}
52414b24e2bSVaishali Kulkarni 	default:
52514b24e2bSVaishali Kulkarni 		break;
52614b24e2bSVaishali Kulkarni 	}
52714b24e2bSVaishali Kulkarni }
52814b24e2bSVaishali Kulkarni 
52914b24e2bSVaishali Kulkarni /*
53014b24e2bSVaishali Kulkarni  * Callback function from mac layer to register group
53114b24e2bSVaishali Kulkarni  */
53214b24e2bSVaishali Kulkarni void
53314b24e2bSVaishali Kulkarni qede_fill_group(void *arg, mac_ring_type_t rtype, const int index,
53414b24e2bSVaishali Kulkarni     mac_group_info_t *infop, mac_group_handle_t gh)
53514b24e2bSVaishali Kulkarni {
53614b24e2bSVaishali Kulkarni 	qede_t *qede = (qede_t *)arg;
53714b24e2bSVaishali Kulkarni 
53814b24e2bSVaishali Kulkarni 	switch (rtype) {
53914b24e2bSVaishali Kulkarni 	case MAC_RING_TYPE_RX: {
54014b24e2bSVaishali Kulkarni 		qede_mac_group_t *rx_group;
54114b24e2bSVaishali Kulkarni 
54214b24e2bSVaishali Kulkarni 		rx_group = &qede->rx_groups[index];
54314b24e2bSVaishali Kulkarni 		rx_group->group_handle = gh;
54414b24e2bSVaishali Kulkarni 		rx_group->group_index = index;
54514b24e2bSVaishali Kulkarni 		rx_group->qede = qede;
54614b24e2bSVaishali Kulkarni 		infop->mgi_driver = (mac_group_driver_t)rx_group;
54714b24e2bSVaishali Kulkarni 		infop->mgi_start = NULL;
54814b24e2bSVaishali Kulkarni 		infop->mgi_stop = NULL;
54914b24e2bSVaishali Kulkarni #ifndef ILLUMOS
55014b24e2bSVaishali Kulkarni 		infop->mgi_addvlan = NULL;
55114b24e2bSVaishali Kulkarni 		infop->mgi_remvlan = NULL;
55214b24e2bSVaishali Kulkarni 		infop->mgi_getsriov_info = NULL;
55314b24e2bSVaishali Kulkarni 		infop->mgi_setmtu = NULL;
55414b24e2bSVaishali Kulkarni #endif
55514b24e2bSVaishali Kulkarni 		infop->mgi_addmac = qede_add_mac_addr;
55614b24e2bSVaishali Kulkarni 		infop->mgi_remmac = qede_rem_mac_addr;
55714b24e2bSVaishali Kulkarni 		infop->mgi_count =  qede->num_fp;
55814b24e2bSVaishali Kulkarni #ifndef ILLUMOS
55914b24e2bSVaishali Kulkarni 		if (index == 0) {
56014b24e2bSVaishali Kulkarni 			infop->mgi_flags = MAC_GROUP_DEFAULT;
56114b24e2bSVaishali Kulkarni 		}
56214b24e2bSVaishali Kulkarni #endif
56314b24e2bSVaishali Kulkarni 
56414b24e2bSVaishali Kulkarni 		break;
56514b24e2bSVaishali Kulkarni 	}
56614b24e2bSVaishali Kulkarni 	case MAC_RING_TYPE_TX: {
56714b24e2bSVaishali Kulkarni 		qede_mac_group_t *tx_group;
56814b24e2bSVaishali Kulkarni 
56914b24e2bSVaishali Kulkarni 		tx_group = &qede->tx_groups[index];
57014b24e2bSVaishali Kulkarni 		tx_group->group_handle = gh;
57114b24e2bSVaishali Kulkarni 		tx_group->group_index = index;
57214b24e2bSVaishali Kulkarni 		tx_group->qede = qede;
57314b24e2bSVaishali Kulkarni 
57414b24e2bSVaishali Kulkarni 		infop->mgi_driver = (mac_group_driver_t)tx_group;
57514b24e2bSVaishali Kulkarni 		infop->mgi_start = NULL;
57614b24e2bSVaishali Kulkarni 		infop->mgi_stop = NULL;
57714b24e2bSVaishali Kulkarni 		infop->mgi_addmac = NULL;
57814b24e2bSVaishali Kulkarni 		infop->mgi_remmac = NULL;
57914b24e2bSVaishali Kulkarni #ifndef ILLUMOS
58014b24e2bSVaishali Kulkarni 		infop->mgi_addvlan = NULL;
58114b24e2bSVaishali Kulkarni 		infop->mgi_remvlan = NULL;
58214b24e2bSVaishali Kulkarni 		infop->mgi_setmtu = NULL;
58314b24e2bSVaishali Kulkarni 		infop->mgi_getsriov_info = NULL;
58414b24e2bSVaishali Kulkarni #endif
58514b24e2bSVaishali Kulkarni 
58614b24e2bSVaishali Kulkarni 		infop->mgi_count = qede->num_fp;
58714b24e2bSVaishali Kulkarni 
58814b24e2bSVaishali Kulkarni #ifndef ILLUMOS
58914b24e2bSVaishali Kulkarni 		if (index == 0) {
59014b24e2bSVaishali Kulkarni 			infop->mgi_flags = MAC_GROUP_DEFAULT;
59114b24e2bSVaishali Kulkarni 		}
59214b24e2bSVaishali Kulkarni #endif
59314b24e2bSVaishali Kulkarni 		break;
59414b24e2bSVaishali Kulkarni 	}
59514b24e2bSVaishali Kulkarni 	default:
59614b24e2bSVaishali Kulkarni 		break;
59714b24e2bSVaishali Kulkarni 	}
59814b24e2bSVaishali Kulkarni }
59914b24e2bSVaishali Kulkarni 
60014b24e2bSVaishali Kulkarni #ifdef ILLUMOS
60114b24e2bSVaishali Kulkarni static int
60214b24e2bSVaishali Kulkarni qede_transceiver_info(void *arg, uint_t id, mac_transceiver_info_t *infop)
60314b24e2bSVaishali Kulkarni {
60414b24e2bSVaishali Kulkarni         qede_t *qede = arg;
60514b24e2bSVaishali Kulkarni         struct ecore_dev *edev = &qede->edev;
60614b24e2bSVaishali Kulkarni         struct ecore_hwfn *hwfn;
60714b24e2bSVaishali Kulkarni         struct ecore_ptt *ptt;
60814b24e2bSVaishali Kulkarni         uint32_t transceiver_state;
60914b24e2bSVaishali Kulkarni 
61014b24e2bSVaishali Kulkarni         if (id >= edev->num_hwfns || arg == NULL || infop == NULL)
61114b24e2bSVaishali Kulkarni                 return (EINVAL);
61214b24e2bSVaishali Kulkarni 
61314b24e2bSVaishali Kulkarni         hwfn = &edev->hwfns[id];
61414b24e2bSVaishali Kulkarni         ptt = ecore_ptt_acquire(hwfn);
61514b24e2bSVaishali Kulkarni         if (ptt == NULL) {
61614b24e2bSVaishali Kulkarni                 return (EIO);
61714b24e2bSVaishali Kulkarni         }
61814b24e2bSVaishali Kulkarni         /*
61914b24e2bSVaishali Kulkarni          * Use the underlying raw API to get this information. While the
62014b24e2bSVaishali Kulkarni          * ecore_phy routines have some ways of getting to this information, it
62114b24e2bSVaishali Kulkarni          * ends up writing the raw data as ASCII characters which doesn't help
62214b24e2bSVaishali Kulkarni          * us one bit.
62314b24e2bSVaishali Kulkarni          */
62414b24e2bSVaishali Kulkarni         transceiver_state = ecore_rd(hwfn, ptt, hwfn->mcp_info->port_addr +
62504443fdeSToomas Soome             offsetof(struct public_port, transceiver_data));
62614b24e2bSVaishali Kulkarni         transceiver_state = GET_FIELD(transceiver_state, ETH_TRANSCEIVER_STATE);
62714b24e2bSVaishali Kulkarni         ecore_ptt_release(hwfn, ptt);
62814b24e2bSVaishali Kulkarni 
62914b24e2bSVaishali Kulkarni         if ((transceiver_state & ETH_TRANSCEIVER_STATE_PRESENT) != 0) {
63014b24e2bSVaishali Kulkarni                 mac_transceiver_info_set_present(infop, B_TRUE);
63114b24e2bSVaishali Kulkarni                 /*
63214b24e2bSVaishali Kulkarni                  * Based on our testing, the ETH_TRANSCEIVER_STATE_VALID flag is
63314b24e2bSVaishali Kulkarni                  * not set, so we cannot rely on it. Instead, we have found that
63414b24e2bSVaishali Kulkarni                  * the ETH_TRANSCEIVER_STATE_UPDATING will be set when we cannot
63514b24e2bSVaishali Kulkarni                  * use the transceiver.
63614b24e2bSVaishali Kulkarni                  */
63714b24e2bSVaishali Kulkarni                 if ((transceiver_state & ETH_TRANSCEIVER_STATE_UPDATING) != 0) {
63814b24e2bSVaishali Kulkarni                         mac_transceiver_info_set_usable(infop, B_FALSE);
63914b24e2bSVaishali Kulkarni                 } else {
64014b24e2bSVaishali Kulkarni                         mac_transceiver_info_set_usable(infop, B_TRUE);
64114b24e2bSVaishali Kulkarni                 }
64214b24e2bSVaishali Kulkarni         } else {
64314b24e2bSVaishali Kulkarni                 mac_transceiver_info_set_present(infop, B_FALSE);
64414b24e2bSVaishali Kulkarni                 mac_transceiver_info_set_usable(infop, B_FALSE);
64514b24e2bSVaishali Kulkarni         }
64614b24e2bSVaishali Kulkarni 
64714b24e2bSVaishali Kulkarni         return (0);
64814b24e2bSVaishali Kulkarni }
64914b24e2bSVaishali Kulkarni 
65014b24e2bSVaishali Kulkarni static int
65114b24e2bSVaishali Kulkarni qede_transceiver_read(void *arg, uint_t id, uint_t page, void *buf,
65214b24e2bSVaishali Kulkarni     size_t nbytes, off_t offset, size_t *nread)
65314b24e2bSVaishali Kulkarni {
65414b24e2bSVaishali Kulkarni         qede_t *qede = arg;
65514b24e2bSVaishali Kulkarni         struct ecore_dev *edev = &qede->edev;
65614b24e2bSVaishali Kulkarni         struct ecore_hwfn *hwfn;
65714b24e2bSVaishali Kulkarni         uint32_t port, lane;
65814b24e2bSVaishali Kulkarni         struct ecore_ptt *ptt;
65914b24e2bSVaishali Kulkarni         enum _ecore_status_t ret;
66014b24e2bSVaishali Kulkarni 
66114b24e2bSVaishali Kulkarni         if (id >= edev->num_hwfns || buf == NULL || nbytes == 0 || nread == NULL ||
66214b24e2bSVaishali Kulkarni             (page != 0xa0 && page != 0xa2) || offset < 0)
66314b24e2bSVaishali Kulkarni                 return (EINVAL);
66414b24e2bSVaishali Kulkarni 
66514b24e2bSVaishali Kulkarni         /*
66614b24e2bSVaishali Kulkarni          * Both supported pages have a length of 256 bytes, ensure nothing asks
66714b24e2bSVaishali Kulkarni          * us to go beyond that.
66814b24e2bSVaishali Kulkarni          */
66914b24e2bSVaishali Kulkarni         if (nbytes > 256 || offset >= 256 || (offset + nbytes > 256)) {
67014b24e2bSVaishali Kulkarni                return (EINVAL);
67114b24e2bSVaishali Kulkarni         }
67214b24e2bSVaishali Kulkarni 
67314b24e2bSVaishali Kulkarni         hwfn = &edev->hwfns[id];
67414b24e2bSVaishali Kulkarni         ptt = ecore_ptt_acquire(hwfn);
67514b24e2bSVaishali Kulkarni         if (ptt == NULL) {
67614b24e2bSVaishali Kulkarni                 return (EIO);
67714b24e2bSVaishali Kulkarni         }
67814b24e2bSVaishali Kulkarni 
67914b24e2bSVaishali Kulkarni         ret = ecore_mcp_phy_sfp_read(hwfn, ptt, hwfn->port_id, page, offset,
68014b24e2bSVaishali Kulkarni             nbytes, buf);
68114b24e2bSVaishali Kulkarni         ecore_ptt_release(hwfn, ptt);
68214b24e2bSVaishali Kulkarni         if (ret != ECORE_SUCCESS) {
68314b24e2bSVaishali Kulkarni                 return (EIO);
68414b24e2bSVaishali Kulkarni         }
68514b24e2bSVaishali Kulkarni         *nread = nbytes;
68614b24e2bSVaishali Kulkarni         return (0);
68714b24e2bSVaishali Kulkarni }
68814b24e2bSVaishali Kulkarni #endif /* ILLUMOS */
68914b24e2bSVaishali Kulkarni 
69014b24e2bSVaishali Kulkarni 
69114b24e2bSVaishali Kulkarni static int
69214b24e2bSVaishali Kulkarni qede_mac_stats(void *     arg,
69314b24e2bSVaishali Kulkarni                         uint_t     stat,
69414b24e2bSVaishali Kulkarni                         uint64_t * value)
69514b24e2bSVaishali Kulkarni {
69614b24e2bSVaishali Kulkarni 	qede_t * qede = (qede_t *)arg;
69714b24e2bSVaishali Kulkarni 	struct ecore_eth_stats vstats;
69814b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
69914b24e2bSVaishali Kulkarni 	struct qede_link_cfg lnkcfg;
70014b24e2bSVaishali Kulkarni 	int rc = 0;
70114b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = &qede->fp_array[0];
70214b24e2bSVaishali Kulkarni 	qede_rx_ring_t *rx_ring;
70314b24e2bSVaishali Kulkarni 	qede_tx_ring_t *tx_ring;
70414b24e2bSVaishali Kulkarni 
70514b24e2bSVaishali Kulkarni 	if ((qede == NULL) || (value == NULL)) {
70614b24e2bSVaishali Kulkarni 		return EINVAL;
70714b24e2bSVaishali Kulkarni 	}
70814b24e2bSVaishali Kulkarni 
70914b24e2bSVaishali Kulkarni 
71014b24e2bSVaishali Kulkarni 	mutex_enter(&qede->gld_lock);
71114b24e2bSVaishali Kulkarni 
71214b24e2bSVaishali Kulkarni 	if(qede->qede_state != QEDE_STATE_STARTED) {
71314b24e2bSVaishali Kulkarni 		mutex_exit(&qede->gld_lock);
71414b24e2bSVaishali Kulkarni 		return EAGAIN;
71514b24e2bSVaishali Kulkarni 	}
71614b24e2bSVaishali Kulkarni 
71714b24e2bSVaishali Kulkarni 	*value = 0;
71814b24e2bSVaishali Kulkarni 
71914b24e2bSVaishali Kulkarni 	memset(&vstats, 0, sizeof(struct ecore_eth_stats));
72014b24e2bSVaishali Kulkarni 	ecore_get_vport_stats(edev, &vstats);
72114b24e2bSVaishali Kulkarni 
72214b24e2bSVaishali Kulkarni 
72314b24e2bSVaishali Kulkarni         memset(&qede->curcfg, 0, sizeof(struct qede_link_cfg));
72414b24e2bSVaishali Kulkarni         qede_get_link_info(&edev->hwfns[0], &qede->curcfg);
72514b24e2bSVaishali Kulkarni 
72614b24e2bSVaishali Kulkarni 
72714b24e2bSVaishali Kulkarni 
72814b24e2bSVaishali Kulkarni 	switch (stat)
72914b24e2bSVaishali Kulkarni 	{
73014b24e2bSVaishali Kulkarni 	case MAC_STAT_IFSPEED:
73114b24e2bSVaishali Kulkarni 		*value = (qede->props.link_speed * 1000000ULL);
73214b24e2bSVaishali Kulkarni 		break;
73314b24e2bSVaishali Kulkarni 	case MAC_STAT_MULTIRCV:
73414b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_mcast_pkts;
73514b24e2bSVaishali Kulkarni 		break;
73614b24e2bSVaishali Kulkarni 	case MAC_STAT_BRDCSTRCV:
73714b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_bcast_pkts;
73814b24e2bSVaishali Kulkarni 		break;
73914b24e2bSVaishali Kulkarni 	case MAC_STAT_MULTIXMT:
74014b24e2bSVaishali Kulkarni 		*value = vstats.common.tx_mcast_pkts;
74114b24e2bSVaishali Kulkarni 		break;
74214b24e2bSVaishali Kulkarni 	case MAC_STAT_BRDCSTXMT:
74314b24e2bSVaishali Kulkarni 		*value = vstats.common.tx_bcast_pkts;
74414b24e2bSVaishali Kulkarni 		break;
74514b24e2bSVaishali Kulkarni 	case MAC_STAT_NORCVBUF:
74614b24e2bSVaishali Kulkarni 		*value = vstats.common.no_buff_discards;
74714b24e2bSVaishali Kulkarni 		break;
74814b24e2bSVaishali Kulkarni 	case MAC_STAT_NOXMTBUF:
74914b24e2bSVaishali Kulkarni 		*value = 0;
75014b24e2bSVaishali Kulkarni 		break;
75114b24e2bSVaishali Kulkarni 	case MAC_STAT_IERRORS:
75214b24e2bSVaishali Kulkarni 	case ETHER_STAT_MACRCV_ERRORS:
75314b24e2bSVaishali Kulkarni 		*value = vstats.common.mac_filter_discards +
75414b24e2bSVaishali Kulkarni 		    vstats.common.packet_too_big_discard +
75514b24e2bSVaishali Kulkarni 		    vstats.common.rx_crc_errors;
75614b24e2bSVaishali Kulkarni 		break;
75714b24e2bSVaishali Kulkarni 
75814b24e2bSVaishali Kulkarni 	case MAC_STAT_OERRORS:
75914b24e2bSVaishali Kulkarni 		break;
76014b24e2bSVaishali Kulkarni 
76114b24e2bSVaishali Kulkarni 	case MAC_STAT_COLLISIONS:
76214b24e2bSVaishali Kulkarni 		*value = vstats.bb.tx_total_collisions;
76314b24e2bSVaishali Kulkarni 		break;
76414b24e2bSVaishali Kulkarni 
76514b24e2bSVaishali Kulkarni 	case MAC_STAT_RBYTES:
76614b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_ucast_bytes +
76714b24e2bSVaishali Kulkarni 		    vstats.common.rx_mcast_bytes +
76814b24e2bSVaishali Kulkarni 		    vstats.common.rx_bcast_bytes;
76914b24e2bSVaishali Kulkarni 		break;
77014b24e2bSVaishali Kulkarni 
77114b24e2bSVaishali Kulkarni 	case MAC_STAT_IPACKETS:
77214b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_ucast_pkts +
77314b24e2bSVaishali Kulkarni 		    vstats.common.rx_mcast_pkts +
77414b24e2bSVaishali Kulkarni 		    vstats.common.rx_bcast_pkts;
77514b24e2bSVaishali Kulkarni 		break;
77614b24e2bSVaishali Kulkarni 
77714b24e2bSVaishali Kulkarni 	case MAC_STAT_OBYTES:
77814b24e2bSVaishali Kulkarni 		*value = vstats.common.tx_ucast_bytes +
77914b24e2bSVaishali Kulkarni 		    vstats.common.tx_mcast_bytes +
78014b24e2bSVaishali Kulkarni 		    vstats.common.tx_bcast_bytes;
78114b24e2bSVaishali Kulkarni 		break;
78214b2