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;
78214b24e2bSVaishali Kulkarni 
78314b24e2bSVaishali Kulkarni 	case MAC_STAT_OPACKETS:
78414b24e2bSVaishali Kulkarni 		*value = vstats.common.tx_ucast_pkts +
78514b24e2bSVaishali Kulkarni 		    vstats.common.tx_mcast_pkts +
78614b24e2bSVaishali Kulkarni 		    vstats.common.tx_bcast_pkts;
78714b24e2bSVaishali Kulkarni 		break;
78814b24e2bSVaishali Kulkarni 
78914b24e2bSVaishali Kulkarni 	case ETHER_STAT_ALIGN_ERRORS:
79014b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_align_errors;
79114b24e2bSVaishali Kulkarni 		break;
79214b24e2bSVaishali Kulkarni 
79314b24e2bSVaishali Kulkarni 	case ETHER_STAT_FCS_ERRORS:
79414b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_crc_errors;
79514b24e2bSVaishali Kulkarni 		break;
79614b24e2bSVaishali Kulkarni 
79714b24e2bSVaishali Kulkarni 	case ETHER_STAT_FIRST_COLLISIONS:
79814b24e2bSVaishali Kulkarni 		break;
79914b24e2bSVaishali Kulkarni 
80014b24e2bSVaishali Kulkarni 	case ETHER_STAT_MULTI_COLLISIONS:
80114b24e2bSVaishali Kulkarni 		break;
80214b24e2bSVaishali Kulkarni 
80314b24e2bSVaishali Kulkarni 	case ETHER_STAT_DEFER_XMTS:
80414b24e2bSVaishali Kulkarni 		break;
80514b24e2bSVaishali Kulkarni 
80614b24e2bSVaishali Kulkarni 	case ETHER_STAT_TX_LATE_COLLISIONS:
80714b24e2bSVaishali Kulkarni 		break;
80814b24e2bSVaishali Kulkarni 
80914b24e2bSVaishali Kulkarni 	case ETHER_STAT_EX_COLLISIONS:
81014b24e2bSVaishali Kulkarni 		break;
81114b24e2bSVaishali Kulkarni 
81214b24e2bSVaishali Kulkarni 	case ETHER_STAT_MACXMT_ERRORS:
81314b24e2bSVaishali Kulkarni 		*value = 0;
81414b24e2bSVaishali Kulkarni 		break;
81514b24e2bSVaishali Kulkarni 
81614b24e2bSVaishali Kulkarni 	case ETHER_STAT_CARRIER_ERRORS:
81714b24e2bSVaishali Kulkarni 		break;
81814b24e2bSVaishali Kulkarni 
81914b24e2bSVaishali Kulkarni 	case ETHER_STAT_TOOLONG_ERRORS:
82014b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_oversize_packets;
82114b24e2bSVaishali Kulkarni 		break;
82214b24e2bSVaishali Kulkarni 
82314b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1)
82414b24e2bSVaishali Kulkarni 	case ETHER_STAT_TOOSHORT_ERRORS:
82514b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_undersize_packets;
82614b24e2bSVaishali Kulkarni 		break;
82714b24e2bSVaishali Kulkarni #endif
82814b24e2bSVaishali Kulkarni 
82914b24e2bSVaishali Kulkarni 	case ETHER_STAT_XCVR_ADDR:
83014b24e2bSVaishali Kulkarni         	*value = 0;
83114b24e2bSVaishali Kulkarni         	break;
83214b24e2bSVaishali Kulkarni 
83314b24e2bSVaishali Kulkarni 	case ETHER_STAT_XCVR_ID:
83414b24e2bSVaishali Kulkarni         	*value = 0;
83514b24e2bSVaishali Kulkarni         	break;
83614b24e2bSVaishali Kulkarni 
83714b24e2bSVaishali Kulkarni 	case ETHER_STAT_XCVR_INUSE:
83814b24e2bSVaishali Kulkarni 		switch (qede->props.link_speed) {
83914b24e2bSVaishali Kulkarni 		default:
84014b24e2bSVaishali Kulkarni 			*value = XCVR_UNDEFINED;
84114b24e2bSVaishali Kulkarni 		}
84214b24e2bSVaishali Kulkarni 		break;
84314b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1)
84414b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_10GFDX:
84514b24e2bSVaishali Kulkarni 		*value = 0;
84614b24e2bSVaishali Kulkarni 		break;
84714b24e2bSVaishali Kulkarni #endif
84814b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_100FDX:
84914b24e2bSVaishali Kulkarni         	*value = 0;
85014b24e2bSVaishali Kulkarni         	break;
85114b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_100HDX:
85214b24e2bSVaishali Kulkarni         	*value = 0;
85314b24e2bSVaishali Kulkarni         	break;
85414b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_ASMPAUSE:
85514b24e2bSVaishali Kulkarni 		*value = 1;
85614b24e2bSVaishali Kulkarni 		break;
85714b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_PAUSE:
85814b24e2bSVaishali Kulkarni 		*value = 1;
85914b24e2bSVaishali Kulkarni 		break;
86014b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_AUTONEG:
86114b24e2bSVaishali Kulkarni 		*value = 1;
86214b24e2bSVaishali Kulkarni 		break;
86314b24e2bSVaishali Kulkarni 
86414b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1)
86514b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_REMFAULT:
86614b24e2bSVaishali Kulkarni 		*value = 0;
86714b24e2bSVaishali Kulkarni 		break;
86814b24e2bSVaishali Kulkarni #endif
86914b24e2bSVaishali Kulkarni 
87014b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1)
87114b24e2bSVaishali Kulkarni 	case ETHER_STAT_ADV_CAP_10GFDX:
87214b24e2bSVaishali Kulkarni 		*value = 0;
87314b24e2bSVaishali Kulkarni 		break;
87414b24e2bSVaishali Kulkarni #endif
87514b24e2bSVaishali Kulkarni     case ETHER_STAT_ADV_CAP_ASMPAUSE:
87614b24e2bSVaishali Kulkarni 		*value = 1;
87714b24e2bSVaishali Kulkarni 		break;
87814b24e2bSVaishali Kulkarni 
87914b24e2bSVaishali Kulkarni 	case ETHER_STAT_ADV_CAP_PAUSE:
88014b24e2bSVaishali Kulkarni 		*value = 1;
88114b24e2bSVaishali Kulkarni 		break;
88214b24e2bSVaishali Kulkarni 
88314b24e2bSVaishali Kulkarni 	case ETHER_STAT_ADV_CAP_AUTONEG:
88414b24e2bSVaishali Kulkarni 		*value = qede->curcfg.adv_capab.autoneg;
88514b24e2bSVaishali Kulkarni 		break;
88614b24e2bSVaishali Kulkarni 
88714b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1)
88814b24e2bSVaishali Kulkarni 	case ETHER_STAT_ADV_REMFAULT:
88914b24e2bSVaishali Kulkarni 		*value = 0;
89014b24e2bSVaishali Kulkarni 		break;
89114b24e2bSVaishali Kulkarni #endif
89214b24e2bSVaishali Kulkarni 
89314b24e2bSVaishali Kulkarni 	case ETHER_STAT_LINK_AUTONEG:
89414b24e2bSVaishali Kulkarni 		*value	= qede->curcfg.autoneg;
89514b24e2bSVaishali Kulkarni 		break;
89614b24e2bSVaishali Kulkarni 
89714b24e2bSVaishali Kulkarni 	case ETHER_STAT_LINK_DUPLEX:
89814b24e2bSVaishali Kulkarni 		*value = (qede->props.link_duplex == DUPLEX_FULL) ?
89914b24e2bSVaishali Kulkarni 				    LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
90014b24e2bSVaishali Kulkarni 		break;
90114b24e2bSVaishali Kulkarni         /*
90214b24e2bSVaishali Kulkarni          * Supported speeds. These indicate what hardware is capable of.
90314b24e2bSVaishali Kulkarni          */
90414b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_1000HDX:
90514b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_1000hdx;
90614b24e2bSVaishali Kulkarni                 break;
90714b24e2bSVaishali Kulkarni 
90814b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_1000FDX:
90914b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_1000fdx;
91014b24e2bSVaishali Kulkarni                 break;
91114b24e2bSVaishali Kulkarni 
91214b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_10GFDX:
91314b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_10000fdx;
91414b24e2bSVaishali Kulkarni                 break;
91514b24e2bSVaishali Kulkarni 
91614b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_25GFDX:
91714b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_25000fdx;
91814b24e2bSVaishali Kulkarni                 break;
91914b24e2bSVaishali Kulkarni 
92014b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_40GFDX:
92114b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_40000fdx;
92214b24e2bSVaishali Kulkarni                 break;
92314b24e2bSVaishali Kulkarni 
92414b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_50GFDX:
92514b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_50000fdx;
92614b24e2bSVaishali Kulkarni                 break;
92714b24e2bSVaishali Kulkarni 
92814b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_100GFDX:
92914b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_100000fdx;
93014b24e2bSVaishali Kulkarni                 break;
93114b24e2bSVaishali Kulkarni 
93214b24e2bSVaishali Kulkarni         /*
93314b24e2bSVaishali Kulkarni          * Advertised speeds. These indicate what hardware is currently sending.
93414b24e2bSVaishali Kulkarni          */
93514b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_1000HDX:
93614b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_1000hdx;
93714b24e2bSVaishali Kulkarni                 break;
93814b24e2bSVaishali Kulkarni 
93914b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_1000FDX:
94014b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_1000fdx;
94114b24e2bSVaishali Kulkarni                 break;
94214b24e2bSVaishali Kulkarni 
94314b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_10GFDX:
94414b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_10000fdx;
94514b24e2bSVaishali Kulkarni                 break;
94614b24e2bSVaishali Kulkarni 
94714b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_25GFDX:
94814b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_25000fdx;
94914b24e2bSVaishali Kulkarni                 break;
95014b24e2bSVaishali Kulkarni 
95114b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_40GFDX:
95214b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_40000fdx;
95314b24e2bSVaishali Kulkarni                 break;
95414b24e2bSVaishali Kulkarni 
95514b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_50GFDX:
95614b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_50000fdx;
95714b24e2bSVaishali Kulkarni                 break;
95814b24e2bSVaishali Kulkarni 
95914b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_100GFDX:
96014b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_100000fdx;
96114b24e2bSVaishali Kulkarni                 break;
96214b24e2bSVaishali Kulkarni 
96314b24e2bSVaishali Kulkarni 	default:
96414b24e2bSVaishali Kulkarni 		rc = ENOTSUP;
96514b24e2bSVaishali Kulkarni 	}
96614b24e2bSVaishali Kulkarni 
96714b24e2bSVaishali Kulkarni 	mutex_exit(&qede->gld_lock);
96814b24e2bSVaishali Kulkarni 	return (rc);
96914b24e2bSVaishali Kulkarni }
97014b24e2bSVaishali Kulkarni 
97114b24e2bSVaishali Kulkarni /* (flag) TRUE = on, FALSE = off */
97214b24e2bSVaishali Kulkarni static int
97314b24e2bSVaishali Kulkarni qede_mac_promiscuous(void *arg,
97414b24e2bSVaishali Kulkarni     boolean_t on)
97514b24e2bSVaishali Kulkarni {
97614b24e2bSVaishali Kulkarni     	qede_t *qede = (qede_t *)arg;
97714b24e2bSVaishali Kulkarni 	qede_print("!%s(%d): called", __func__,qede->instance);
97814b24e2bSVaishali Kulkarni 	int ret = DDI_SUCCESS;
97914b24e2bSVaishali Kulkarni 	enum qede_filter_rx_mode_type mode;
98014b24e2bSVaishali Kulkarni 
98114b24e2bSVaishali Kulkarni 	mutex_enter(&qede->drv_lock);
98214b24e2bSVaishali Kulkarni 
98314b24e2bSVaishali Kulkarni 	if (qede->qede_state == QEDE_STATE_SUSPENDED) {
98414b24e2bSVaishali Kulkarni 		ret = ECANCELED;
98514b24e2bSVaishali Kulkarni 		goto exit;
98614b24e2bSVaishali Kulkarni 	}
98714b24e2bSVaishali Kulkarni 
98814b24e2bSVaishali Kulkarni 	if (on) {
98914b24e2bSVaishali Kulkarni 		qede_info(qede, "Entering promiscuous mode");
99014b24e2bSVaishali Kulkarni 		mode = QEDE_FILTER_RX_MODE_PROMISC;
99114b24e2bSVaishali Kulkarni 		qede->params.promisc_fl = B_TRUE;
99214b24e2bSVaishali Kulkarni 	} else {
99314b24e2bSVaishali Kulkarni 		qede_info(qede, "Leaving promiscuous mode");
99414b24e2bSVaishali Kulkarni 		if(qede->params.multi_promisc_fl == B_TRUE) {
99514b24e2bSVaishali Kulkarni 			mode = QEDE_FILTER_RX_MODE_MULTI_PROMISC;
99614b24e2bSVaishali Kulkarni 		} else {
99714b24e2bSVaishali Kulkarni 			 mode = QEDE_FILTER_RX_MODE_REGULAR;
99814b24e2bSVaishali Kulkarni 		}
99914b24e2bSVaishali Kulkarni 		qede->params.promisc_fl = B_FALSE;
100014b24e2bSVaishali Kulkarni 	}
100114b24e2bSVaishali Kulkarni 
100214b24e2bSVaishali Kulkarni 	ret = qede_set_filter_rx_mode(qede, mode);
100314b24e2bSVaishali Kulkarni 
100414b24e2bSVaishali Kulkarni exit:
100514b24e2bSVaishali Kulkarni 	mutex_exit(&qede->drv_lock);
100614b24e2bSVaishali Kulkarni     	return (ret);
100714b24e2bSVaishali Kulkarni }
100814b24e2bSVaishali Kulkarni 
100914b24e2bSVaishali Kulkarni int qede_set_rx_mac_mcast(qede_t *qede, enum ecore_filter_opcode opcode,
101014b24e2bSVaishali Kulkarni 			  uint8_t *mac, int mc_cnt)
101114b24e2bSVaishali Kulkarni {
101214b24e2bSVaishali Kulkarni 	struct ecore_filter_mcast cmd;
101314b24e2bSVaishali Kulkarni 	int i;
101414b24e2bSVaishali Kulkarni 	memset(&cmd, 0, sizeof(cmd));
101514b24e2bSVaishali Kulkarni 	cmd.opcode = opcode;
101614b24e2bSVaishali Kulkarni 	cmd.num_mc_addrs = mc_cnt;
101714b24e2bSVaishali Kulkarni 
101814b24e2bSVaishali Kulkarni         for (i = 0; i < mc_cnt; i++, mac += ETH_ALLEN) {
101914b24e2bSVaishali Kulkarni 		COPY_ETH_ADDRESS(mac, cmd.mac[i]);
102014b24e2bSVaishali Kulkarni         }
102114b24e2bSVaishali Kulkarni 
102214b24e2bSVaishali Kulkarni 
102314b24e2bSVaishali Kulkarni         return (ecore_filter_mcast_cmd(&qede->edev, &cmd,
102414b24e2bSVaishali Kulkarni 	    ECORE_SPQ_MODE_CB, NULL));
102514b24e2bSVaishali Kulkarni 
102614b24e2bSVaishali Kulkarni }
102714b24e2bSVaishali Kulkarni 
102814b24e2bSVaishali Kulkarni int
102914b24e2bSVaishali Kulkarni qede_set_filter_rx_mode(qede_t * qede, enum qede_filter_rx_mode_type type)
103014b24e2bSVaishali Kulkarni {
103114b24e2bSVaishali Kulkarni 	struct ecore_filter_accept_flags flg;
103214b24e2bSVaishali Kulkarni 
103314b24e2bSVaishali Kulkarni 	memset(&flg, 0, sizeof(flg));
103414b24e2bSVaishali Kulkarni 
103514b24e2bSVaishali Kulkarni 	flg.update_rx_mode_config      = 1;
103614b24e2bSVaishali Kulkarni 	flg.update_tx_mode_config      = 1;
103714b24e2bSVaishali Kulkarni 	flg.rx_accept_filter           = ECORE_ACCEPT_UCAST_MATCHED |
103814b24e2bSVaishali Kulkarni 	    ECORE_ACCEPT_MCAST_MATCHED | ECORE_ACCEPT_BCAST;
103914b24e2bSVaishali Kulkarni 	flg.tx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED |
104014b24e2bSVaishali Kulkarni 	    ECORE_ACCEPT_MCAST_MATCHED | ECORE_ACCEPT_BCAST;
104114b24e2bSVaishali Kulkarni 
104214b24e2bSVaishali Kulkarni 	if (type == QEDE_FILTER_RX_MODE_PROMISC)
104314b24e2bSVaishali Kulkarni 		flg.rx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED |
104414b24e2bSVaishali Kulkarni 		    ECORE_ACCEPT_MCAST_UNMATCHED;
104514b24e2bSVaishali Kulkarni 	else if (type == QEDE_FILTER_RX_MODE_MULTI_PROMISC)
104614b24e2bSVaishali Kulkarni 		flg.rx_accept_filter |= ECORE_ACCEPT_MCAST_UNMATCHED;
104714b24e2bSVaishali Kulkarni 	qede_info(qede, "rx_mode rx_filter=0x%x tx_filter=0x%x type=0x%x\n",
104814b24e2bSVaishali Kulkarni 	    flg.rx_accept_filter, flg.tx_accept_filter, type);
104914b24e2bSVaishali Kulkarni 	return (ecore_filter_accept_cmd(&qede->edev, 0, flg,
105014b24e2bSVaishali Kulkarni 			0, /* update_accept_any_vlan */
105114b24e2bSVaishali Kulkarni 			0, /* accept_any_vlan */
105214b24e2bSVaishali Kulkarni 			ECORE_SPQ_MODE_CB, NULL));
105314b24e2bSVaishali Kulkarni }
105414b24e2bSVaishali Kulkarni 
105514b24e2bSVaishali Kulkarni int
105614b24e2bSVaishali Kulkarni qede_multicast(qede_t *qede, boolean_t flag, const uint8_t *ptr_mcaddr)
105714b24e2bSVaishali Kulkarni {
105814b24e2bSVaishali Kulkarni 	int i, ret = DDI_SUCCESS;
105914b24e2bSVaishali Kulkarni 	qede_mcast_list_entry_t *ptr_mlist;
106014b24e2bSVaishali Kulkarni 	qede_mcast_list_entry_t *ptr_entry;
106114b24e2bSVaishali Kulkarni 	int mc_cnt;
106214b24e2bSVaishali Kulkarni 	unsigned char *mc_macs, *tmpmc;
106314b24e2bSVaishali Kulkarni 	size_t size;
106414b24e2bSVaishali Kulkarni 	boolean_t mcmac_exists = B_FALSE;
106514b24e2bSVaishali Kulkarni 	enum qede_filter_rx_mode_type mode;
106614b24e2bSVaishali Kulkarni 
106714b24e2bSVaishali Kulkarni 	if (!ptr_mcaddr)  {
106814b24e2bSVaishali Kulkarni 		cmn_err(CE_NOTE, "Removing all multicast");
106914b24e2bSVaishali Kulkarni 	} else  {
107014b24e2bSVaishali Kulkarni 		cmn_err(CE_NOTE,
107114b24e2bSVaishali Kulkarni 		    "qede=%p %s multicast: %02x:%02x:%02x:%02x:%02x:%02x",
107214b24e2bSVaishali Kulkarni 		    qede, (flag) ? "Adding" : "Removing", ptr_mcaddr[0],
107314b24e2bSVaishali Kulkarni 		    ptr_mcaddr[1],ptr_mcaddr[2],ptr_mcaddr[3],ptr_mcaddr[4],
107414b24e2bSVaishali Kulkarni 		    ptr_mcaddr[5]);
107514b24e2bSVaishali Kulkarni 	}
107614b24e2bSVaishali Kulkarni 
107714b24e2bSVaishali Kulkarni 
107814b24e2bSVaishali Kulkarni 	if (flag && (ptr_mcaddr == NULL)) {
107914b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN, "ERROR: Multicast address not specified");
108014b24e2bSVaishali Kulkarni 		return EINVAL;
108114b24e2bSVaishali Kulkarni 	}
108214b24e2bSVaishali Kulkarni 
108314b24e2bSVaishali Kulkarni 
108414b24e2bSVaishali Kulkarni 	/* exceeds addition of mcaddr above limit */
108514b24e2bSVaishali Kulkarni 	if (flag && (qede->mc_cnt >= MAX_MC_SOFT_LIMIT)) {
108614b24e2bSVaishali Kulkarni 		qede_info(qede, "Cannot add more than MAX_MC_SOFT_LIMIT");
108714b24e2bSVaishali Kulkarni 		return ENOENT;
108814b24e2bSVaishali Kulkarni 	}
108914b24e2bSVaishali Kulkarni 
109014b24e2bSVaishali Kulkarni 	size = MAX_MC_SOFT_LIMIT * ETH_ALLEN;
109114b24e2bSVaishali Kulkarni 
109214b24e2bSVaishali Kulkarni 	mc_macs = kmem_zalloc(size, KM_NOSLEEP);
109314b24e2bSVaishali Kulkarni 	if (!mc_macs) {
109414b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN, "ERROR: Failed to allocate for mc_macs");
109514b24e2bSVaishali Kulkarni 		return EINVAL;
109614b24e2bSVaishali Kulkarni 	}
109714b24e2bSVaishali Kulkarni 
109814b24e2bSVaishali Kulkarni 	tmpmc = mc_macs;
109914b24e2bSVaishali Kulkarni 
110014b24e2bSVaishali Kulkarni         /* remove all multicast - as flag not set and mcaddr not specified*/
110114b24e2bSVaishali Kulkarni         if (!flag && (ptr_mcaddr == NULL)) {
110214b24e2bSVaishali Kulkarni                 QEDE_LIST_FOR_EACH_ENTRY(ptr_entry,
110314b24e2bSVaishali Kulkarni 		    &qede->mclist.head, qede_mcast_list_entry_t, mclist_entry)
110414b24e2bSVaishali Kulkarni                 {
110514b24e2bSVaishali Kulkarni                         if (ptr_entry != NULL) {
110614b24e2bSVaishali Kulkarni                         QEDE_LIST_REMOVE(&ptr_entry->mclist_entry,
110714b24e2bSVaishali Kulkarni 			    &qede->mclist.head);
110814b24e2bSVaishali Kulkarni                         kmem_free(ptr_entry,
110914b24e2bSVaishali Kulkarni 			    sizeof (qede_mcast_list_entry_t) + ETH_ALLEN);
111014b24e2bSVaishali Kulkarni                         }
111114b24e2bSVaishali Kulkarni                 }
111214b24e2bSVaishali Kulkarni 
111314b24e2bSVaishali Kulkarni                 ret = qede_set_rx_mac_mcast(qede,
111414b24e2bSVaishali Kulkarni 		    ECORE_FILTER_REMOVE, mc_macs, 1);
111514b24e2bSVaishali Kulkarni                 qede->mc_cnt = 0;
111614b24e2bSVaishali Kulkarni                 goto exit;
111714b24e2bSVaishali Kulkarni         }
111814b24e2bSVaishali Kulkarni 
111914b24e2bSVaishali Kulkarni         QEDE_LIST_FOR_EACH_ENTRY(ptr_entry,
112014b24e2bSVaishali Kulkarni 	    &qede->mclist.head, qede_mcast_list_entry_t, mclist_entry)
112114b24e2bSVaishali Kulkarni         {
112214b24e2bSVaishali Kulkarni                 if ((ptr_entry != NULL) &&
112314b24e2bSVaishali Kulkarni 		    IS_ETH_ADDRESS_EQUAL(ptr_mcaddr, ptr_entry->mac)) {
112414b24e2bSVaishali Kulkarni                         mcmac_exists = B_TRUE;
112514b24e2bSVaishali Kulkarni                         break;
112614b24e2bSVaishali Kulkarni                 }
112714b24e2bSVaishali Kulkarni         }
112814b24e2bSVaishali Kulkarni         if (flag && mcmac_exists) {
112914b24e2bSVaishali Kulkarni                 ret = DDI_SUCCESS;
113014b24e2bSVaishali Kulkarni                 goto exit;
113114b24e2bSVaishali Kulkarni         } else if (!flag && !mcmac_exists) {
113214b24e2bSVaishali Kulkarni                 ret = DDI_SUCCESS;
113314b24e2bSVaishali Kulkarni                 goto exit;
113414b24e2bSVaishali Kulkarni         }
113514b24e2bSVaishali Kulkarni 
113614b24e2bSVaishali Kulkarni        if (flag) {
113714b24e2bSVaishali Kulkarni                 ptr_entry = kmem_zalloc((sizeof (qede_mcast_list_entry_t) +
113814b24e2bSVaishali Kulkarni 		    ETH_ALLEN), KM_NOSLEEP);
113914b24e2bSVaishali Kulkarni                 ptr_entry->mac = (uint8_t *)ptr_entry +
114014b24e2bSVaishali Kulkarni 		    sizeof (qede_mcast_list_entry_t);
114114b24e2bSVaishali Kulkarni                 COPY_ETH_ADDRESS(ptr_mcaddr, ptr_entry->mac);
114214b24e2bSVaishali Kulkarni                 QEDE_LIST_ADD(&ptr_entry->mclist_entry, &qede->mclist.head);
114314b24e2bSVaishali Kulkarni         } else {
114414b24e2bSVaishali Kulkarni                 QEDE_LIST_REMOVE(&ptr_entry->mclist_entry, &qede->mclist.head);
114514b24e2bSVaishali Kulkarni                 kmem_free(ptr_entry, sizeof(qede_mcast_list_entry_t) +
114614b24e2bSVaishali Kulkarni 		    ETH_ALLEN);
114714b24e2bSVaishali Kulkarni         }
114814b24e2bSVaishali Kulkarni 
114914b24e2bSVaishali Kulkarni 	mc_cnt = 0;
115014b24e2bSVaishali Kulkarni         QEDE_LIST_FOR_EACH_ENTRY(ptr_entry, &qede->mclist.head,
115114b24e2bSVaishali Kulkarni 	    qede_mcast_list_entry_t, mclist_entry) {
115214b24e2bSVaishali Kulkarni                 COPY_ETH_ADDRESS(ptr_entry->mac, tmpmc);
115314b24e2bSVaishali Kulkarni                 tmpmc += ETH_ALLEN;
115414b24e2bSVaishali Kulkarni                 mc_cnt++;
115514b24e2bSVaishali Kulkarni         }
115614b24e2bSVaishali Kulkarni         qede->mc_cnt = mc_cnt;
115714b24e2bSVaishali Kulkarni         if (mc_cnt <=64) {
115814b24e2bSVaishali Kulkarni                 ret = qede_set_rx_mac_mcast(qede, ECORE_FILTER_ADD,
115914b24e2bSVaishali Kulkarni 		    (unsigned char *)mc_macs, mc_cnt);
116014b24e2bSVaishali Kulkarni                 if ((qede->params.multi_promisc_fl == B_TRUE) &&
116114b24e2bSVaishali Kulkarni 		    (qede->params.promisc_fl == B_FALSE)) {
116214b24e2bSVaishali Kulkarni                         mode = QEDE_FILTER_RX_MODE_REGULAR;
116314b24e2bSVaishali Kulkarni                         ret = qede_set_filter_rx_mode(qede, mode);
116414b24e2bSVaishali Kulkarni                 }
116514b24e2bSVaishali Kulkarni                 qede->params.multi_promisc_fl = B_FALSE;
116614b24e2bSVaishali Kulkarni         } else {
116714b24e2bSVaishali Kulkarni                 if ((qede->params.multi_promisc_fl == B_FALSE) &&
1168*589d6798SAnand Khoje 		    (qede->params.promisc_fl == B_FALSE)) {
116914b24e2bSVaishali Kulkarni                         ret = qede_set_filter_rx_mode(qede,
117014b24e2bSVaishali Kulkarni 			    QEDE_FILTER_RX_MODE_MULTI_PROMISC);
117114b24e2bSVaishali Kulkarni                 }
117214b24e2bSVaishali Kulkarni                 qede->params.multi_promisc_fl = B_TRUE;
117314b24e2bSVaishali Kulkarni                 qede_info(qede, "mode is MULTI_PROMISC");
117414b24e2bSVaishali Kulkarni         }
117514b24e2bSVaishali Kulkarni exit:
117614b24e2bSVaishali Kulkarni kmem_free(mc_macs, size);
117714b24e2bSVaishali Kulkarni qede_info(qede, "multicast ret %d mc_cnt %d\n", ret, qede->mc_cnt);
117814b24e2bSVaishali Kulkarni return (ret);
117914b24e2bSVaishali Kulkarni }
118014b24e2bSVaishali Kulkarni 
118114b24e2bSVaishali Kulkarni /*
118214b24e2bSVaishali Kulkarni  * This function is used to enable or disable multicast packet reception for
118314b24e2bSVaishali Kulkarni  * particular multicast addresses.
118414b24e2bSVaishali Kulkarni  * (flag) TRUE = add, FALSE = remove
118514b24e2bSVaishali Kulkarni  */
118614b24e2bSVaishali Kulkarni static int
118714b24e2bSVaishali Kulkarni qede_mac_multicast(void *arg,
118814b24e2bSVaishali Kulkarni     boolean_t       flag,
118914b24e2bSVaishali Kulkarni     const uint8_t * mcast_addr)
119014b24e2bSVaishali Kulkarni {
119114b24e2bSVaishali Kulkarni 	qede_t *qede = (qede_t *)arg;
119214b24e2bSVaishali Kulkarni 	int ret = DDI_SUCCESS;
119314b24e2bSVaishali Kulkarni 
119414b24e2bSVaishali Kulkarni 
119514b24e2bSVaishali Kulkarni 	mutex_enter(&qede->gld_lock);
119614b24e2bSVaishali Kulkarni 	if(qede->qede_state != QEDE_STATE_STARTED) {
119714b24e2bSVaishali Kulkarni 		mutex_exit(&qede->gld_lock);
119814b24e2bSVaishali Kulkarni 		return (EAGAIN);
119914b24e2bSVaishali Kulkarni 	}
120014b24e2bSVaishali Kulkarni 	ret = qede_multicast(qede, flag, mcast_addr);
120114b24e2bSVaishali Kulkarni 
120214b24e2bSVaishali Kulkarni 	mutex_exit(&qede->gld_lock);
120314b24e2bSVaishali Kulkarni 
120414b24e2bSVaishali Kulkarni     return (ret);
120514b24e2bSVaishali Kulkarni }
120614b24e2bSVaishali Kulkarni int
120714b24e2bSVaishali Kulkarni qede_clear_filters(qede_t *qede)
120814b24e2bSVaishali Kulkarni {
120914b24e2bSVaishali Kulkarni 	int ret = 0;
121014b24e2bSVaishali Kulkarni 	int i;
121114b24e2bSVaishali Kulkarni 	if ((qede->params.promisc_fl == B_TRUE) ||
121214b24e2bSVaishali Kulkarni 	    (qede->params.multi_promisc_fl == B_TRUE)) {
121314b24e2bSVaishali Kulkarni 		ret = qede_set_filter_rx_mode(qede,
121414b24e2bSVaishali Kulkarni 		    QEDE_FILTER_RX_MODE_REGULAR);
121514b24e2bSVaishali Kulkarni 		if (ret) {
121614b24e2bSVaishali Kulkarni 			qede_info(qede,
121714b24e2bSVaishali Kulkarni 			    "qede_clear_filters failed to set rx_mode");
121814b24e2bSVaishali Kulkarni 		}
121914b24e2bSVaishali Kulkarni 	}
122014b24e2bSVaishali Kulkarni 	for (i=0; i < qede->ucst_total; i++)
122114b24e2bSVaishali Kulkarni 	{
122214b24e2bSVaishali Kulkarni 		if (qede->ucst_mac[i].set) {
122314b24e2bSVaishali Kulkarni 			qede_rem_macaddr(qede,
122414b24e2bSVaishali Kulkarni 			    qede->ucst_mac[i].mac_addr.ether_addr_octet);
122514b24e2bSVaishali Kulkarni 		}
122614b24e2bSVaishali Kulkarni 	}
122714b24e2bSVaishali Kulkarni 	qede_multicast(qede, B_FALSE, NULL);
122814b24e2bSVaishali Kulkarni 	return (ret);
122914b24e2bSVaishali Kulkarni }
123014b24e2bSVaishali Kulkarni 
123114b24e2bSVaishali Kulkarni 
123214b24e2bSVaishali Kulkarni #ifdef  NO_CROSSBOW
123314b24e2bSVaishali Kulkarni static int
123414b24e2bSVaishali Kulkarni qede_mac_unicast(void *arg,
123514b24e2bSVaishali Kulkarni     const uint8_t * mac_addr)
123614b24e2bSVaishali Kulkarni {
123714b24e2bSVaishali Kulkarni     qede_t *qede = (qede_t *)arg;
123814b24e2bSVaishali Kulkarni     return 0;
123914b24e2bSVaishali Kulkarni }
124014b24e2bSVaishali Kulkarni 
124114b24e2bSVaishali Kulkarni 
124214b24e2bSVaishali Kulkarni static mblk_t *
124314b24e2bSVaishali Kulkarni qede_mac_tx(void *arg,
124414b24e2bSVaishali Kulkarni     mblk_t * mblk)
124514b24e2bSVaishali Kulkarni {
124614b24e2bSVaishali Kulkarni     qede_t *qede = (qede_t *)arg;
124714b24e2bSVaishali Kulkarni     qede_fastpath_t *fp = &qede->fp_array[0];
124814b24e2bSVaishali Kulkarni 
124914b24e2bSVaishali Kulkarni     mblk = qede_ring_tx((void *)fp, mblk);
125014b24e2bSVaishali Kulkarni 
125114b24e2bSVaishali Kulkarni     return (mblk);
125214b24e2bSVaishali Kulkarni }
125314b24e2bSVaishali Kulkarni #endif  /* NO_CROSSBOW */
125414b24e2bSVaishali Kulkarni 
125514b24e2bSVaishali Kulkarni 
125614b24e2bSVaishali Kulkarni static lb_property_t loopmodes[] = {
125714b24e2bSVaishali Kulkarni 	{ normal,       "normal",       QEDE_LOOP_NONE                },
125814b24e2bSVaishali Kulkarni 	{ internal,     "internal",     QEDE_LOOP_INTERNAL            },
125914b24e2bSVaishali Kulkarni 	{ external,     "external",     QEDE_LOOP_EXTERNAL            },
126014b24e2bSVaishali Kulkarni };
126114b24e2bSVaishali Kulkarni 
126214b24e2bSVaishali Kulkarni /*
126314b24e2bSVaishali Kulkarni  * Set Loopback mode
126414b24e2bSVaishali Kulkarni  */
126514b24e2bSVaishali Kulkarni 
126614b24e2bSVaishali Kulkarni static enum ioc_reply
126714b24e2bSVaishali Kulkarni qede_set_loopback_mode(qede_t *qede, uint32_t mode)
126814b24e2bSVaishali Kulkarni {
1269b68ddc76SJohn Levon 	int i = 0;
127014b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
127114b24e2bSVaishali Kulkarni 	struct ecore_hwfn *hwfn;
127214b24e2bSVaishali Kulkarni 	struct ecore_ptt *ptt = NULL;
127314b24e2bSVaishali Kulkarni 	struct ecore_mcp_link_params *link_params;
127414b24e2bSVaishali Kulkarni 
127514b24e2bSVaishali Kulkarni 	hwfn = &edev->hwfns[0];
127614b24e2bSVaishali Kulkarni 	link_params = ecore_mcp_get_link_params(hwfn);
127714b24e2bSVaishali Kulkarni 	ptt = ecore_ptt_acquire(hwfn);
127814b24e2bSVaishali Kulkarni 
127914b24e2bSVaishali Kulkarni 	switch(mode) {
128014b24e2bSVaishali Kulkarni 	default:
128114b24e2bSVaishali Kulkarni 		qede_info(qede, "unknown loopback mode !!");
128214b24e2bSVaishali Kulkarni 		ecore_ptt_release(hwfn, ptt);
128314b24e2bSVaishali Kulkarni 		return IOC_INVAL;
128414b24e2bSVaishali Kulkarni 
128514b24e2bSVaishali Kulkarni 	case QEDE_LOOP_NONE:
128614b24e2bSVaishali Kulkarni 		ecore_mcp_set_link(hwfn, ptt, 0);
128714b24e2bSVaishali Kulkarni 
128814b24e2bSVaishali Kulkarni 		while (qede->params.link_state && i < 5000) {
128914b24e2bSVaishali Kulkarni 			OSAL_MSLEEP(1);
129014b24e2bSVaishali Kulkarni 			i++;
129114b24e2bSVaishali Kulkarni 		}
129214b24e2bSVaishali Kulkarni 		i = 0;
129314b24e2bSVaishali Kulkarni 
129414b24e2bSVaishali Kulkarni 		link_params->loopback_mode = ETH_LOOPBACK_NONE;
129514b24e2bSVaishali Kulkarni 		qede->loop_back_mode = QEDE_LOOP_NONE;
1296b68ddc76SJohn Levon 		(void) ecore_mcp_set_link(hwfn, ptt, 1);
129714b24e2bSVaishali Kulkarni 		ecore_ptt_release(hwfn, ptt);
129814b24e2bSVaishali Kulkarni 
129914b24e2bSVaishali Kulkarni 		while (!qede->params.link_state && i < 5000) {
130014b24e2bSVaishali Kulkarni 			OSAL_MSLEEP(1);
130114b24e2bSVaishali Kulkarni 			i++;
130214b24e2bSVaishali Kulkarni 		}
130314b24e2bSVaishali Kulkarni 		return IOC_REPLY;
130414b24e2bSVaishali Kulkarni 
130514b24e2bSVaishali Kulkarni 	case QEDE_LOOP_INTERNAL:
130614b24e2bSVaishali Kulkarni 		qede_print("!%s(%d) : loopback mode (INTERNAL) is set!",
130714b24e2bSVaishali Kulkarni 		    __func__, qede->instance);
130814b24e2bSVaishali Kulkarni 		    ecore_mcp_set_link(hwfn, ptt, 0);
130914b24e2bSVaishali Kulkarni 
131014b24e2bSVaishali Kulkarni 		while(qede->params.link_state && i < 5000) {
131114b24e2bSVaishali Kulkarni 			OSAL_MSLEEP(1);
131214b24e2bSVaishali Kulkarni 			i++;
131314b24e2bSVaishali Kulkarni 		}
131414b24e2bSVaishali Kulkarni 		i = 0;
131514b24e2bSVaishali Kulkarni 		link_params->loopback_mode = ETH_LOOPBACK_INT_PHY;
131614b24e2bSVaishali Kulkarni 		qede->loop_back_mode = QEDE_LOOP_INTERNAL;
1317b68ddc76SJohn Levon 		(void) ecore_mcp_set_link(hwfn, ptt, 1);
131814b24e2bSVaishali Kulkarni 		ecore_ptt_release(hwfn, ptt);
131914b24e2bSVaishali Kulkarni 
132014b24e2bSVaishali Kulkarni 		while(!qede->params.link_state && i < 5000) {
132114b24e2bSVaishali Kulkarni 			OSAL_MSLEEP(1);
132214b24e2bSVaishali Kulkarni 			i++;
132314b24e2bSVaishali Kulkarni 		}
132414b24e2bSVaishali Kulkarni 		return IOC_REPLY;
132514b24e2bSVaishali Kulkarni 
132614b24e2bSVaishali Kulkarni 	case QEDE_LOOP_EXTERNAL:
132714b24e2bSVaishali Kulkarni 		qede_print("!%s(%d) : External loopback mode is not supported",
132814b24e2bSVaishali Kulkarni 		    __func__, qede->instance);
132914b24e2bSVaishali Kulkarni 		ecore_ptt_release(hwfn, ptt);
133014b24e2bSVaishali Kulkarni 		return IOC_INVAL;
133114b24e2bSVaishali Kulkarni 	}
133214b24e2bSVaishali Kulkarni }
133314b24e2bSVaishali Kulkarni 
133414b24e2bSVaishali Kulkarni static int
133514b24e2bSVaishali Kulkarni qede_ioctl_pcicfg_rd(qede_t *qede, u32 addr, void *data,
133614b24e2bSVaishali Kulkarni     int len)
133714b24e2bSVaishali Kulkarni {
133814b24e2bSVaishali Kulkarni 	u32 crb, actual_crb;
133914b24e2bSVaishali Kulkarni 	uint32_t ret = 0;
134014b24e2bSVaishali Kulkarni 	int cap_offset = 0, cap_id = 0, next_cap = 0;
134114b24e2bSVaishali Kulkarni 	ddi_acc_handle_t pci_cfg_handle  = qede->pci_cfg_handle;
134214b24e2bSVaishali Kulkarni 	qede_ioctl_data_t * data1 = (qede_ioctl_data_t *) data;
134314b24e2bSVaishali Kulkarni 
134414b24e2bSVaishali Kulkarni 	cap_offset = pci_config_get8(pci_cfg_handle, PCI_CONF_CAP_PTR);
134514b24e2bSVaishali Kulkarni 	while (cap_offset != 0) {
134614b24e2bSVaishali Kulkarni                 /* Check for an invalid PCI read. */
134714b24e2bSVaishali Kulkarni                 if (cap_offset == PCI_EINVAL8) {
134814b24e2bSVaishali Kulkarni                         return DDI_FAILURE;
134914b24e2bSVaishali Kulkarni                 }
135014b24e2bSVaishali Kulkarni 		cap_id = pci_config_get8(pci_cfg_handle, cap_offset);
135114b24e2bSVaishali Kulkarni 		if (cap_id == PCI_CAP_ID_PCI_E) {
135214b24e2bSVaishali Kulkarni 			/* PCIe expr capab struct found */
135314b24e2bSVaishali Kulkarni 			break;
135414b24e2bSVaishali Kulkarni 		} else {
135514b24e2bSVaishali Kulkarni 			next_cap = pci_config_get8(pci_cfg_handle,
135614b24e2bSVaishali Kulkarni 			    cap_offset + 1);
135714b24e2bSVaishali Kulkarni 			cap_offset = next_cap;
135814b24e2bSVaishali Kulkarni 		}
135914b24e2bSVaishali Kulkarni 	}
136014b24e2bSVaishali Kulkarni 
136114b24e2bSVaishali Kulkarni 	switch (len) {
136214b24e2bSVaishali Kulkarni 	case 1:
136314b24e2bSVaishali Kulkarni 		ret = pci_config_get8(qede->pci_cfg_handle, addr);
136414b24e2bSVaishali Kulkarni 		(void) memcpy(data, &ret, sizeof(uint8_t));
136514b24e2bSVaishali Kulkarni 		break;
136614b24e2bSVaishali Kulkarni 	case 2:
136714b24e2bSVaishali Kulkarni 		ret = pci_config_get16(qede->pci_cfg_handle, addr);
136814b24e2bSVaishali Kulkarni 		(void) memcpy(data, &ret, sizeof(uint16_t));
136914b24e2bSVaishali Kulkarni 		break;
137014b24e2bSVaishali Kulkarni 	case 4:
137114b24e2bSVaishali Kulkarni 		ret = pci_config_get32(qede->pci_cfg_handle, addr);
137214b24e2bSVaishali Kulkarni 		(void) memcpy(data, &ret, sizeof(uint32_t));
137314b24e2bSVaishali Kulkarni 		break;
137414b24e2bSVaishali Kulkarni 	default:
137514b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN, "bad length for pci config read\n");
137614b24e2bSVaishali Kulkarni 		return (1);
137714b24e2bSVaishali Kulkarni 	}
137814b24e2bSVaishali Kulkarni 	return (0);
137914b24e2bSVaishali Kulkarni }
138014b24e2bSVaishali Kulkarni 
138114b24e2bSVaishali Kulkarni static int
138214b24e2bSVaishali Kulkarni qede_ioctl_pcicfg_wr(qede_t *qede, u32 addr, void *data,
138314b24e2bSVaishali Kulkarni     int len)
138414b24e2bSVaishali Kulkarni {
138514b24e2bSVaishali Kulkarni 	uint16_t ret = 0;
138614b24e2bSVaishali Kulkarni 	int cap_offset = 0, cap_id = 0, next_cap = 0;
138714b24e2bSVaishali Kulkarni 	qede_ioctl_data_t * data1 = (qede_ioctl_data_t *) data;
138814b24e2bSVaishali Kulkarni 	ddi_acc_handle_t pci_cfg_handle  = qede->pci_cfg_handle;
138914b24e2bSVaishali Kulkarni #if 1
139014b24e2bSVaishali Kulkarni 	cap_offset = pci_config_get8(pci_cfg_handle, PCI_CONF_CAP_PTR);
139114b24e2bSVaishali Kulkarni 	while (cap_offset != 0) {
139214b24e2bSVaishali Kulkarni 		cap_id = pci_config_get8(pci_cfg_handle, cap_offset);
139314b24e2bSVaishali Kulkarni 		if (cap_id == PCI_CAP_ID_PCI_E) {
139414b24e2bSVaishali Kulkarni 			/* PCIe expr capab struct found */
139514b24e2bSVaishali Kulkarni 			break;
139614b24e2bSVaishali Kulkarni 		} else {
139714b24e2bSVaishali Kulkarni 			next_cap = pci_config_get8(pci_cfg_handle,
139814b24e2bSVaishali Kulkarni 			    cap_offset + 1);
139914b24e2bSVaishali Kulkarni 			cap_offset = next_cap;
140014b24e2bSVaishali Kulkarni 		}
140114b24e2bSVaishali Kulkarni 	}
140214b24e2bSVaishali Kulkarni #endif
140314b24e2bSVaishali Kulkarni 
140414b24e2bSVaishali Kulkarni 	switch(len) {
140514b24e2bSVaishali Kulkarni 	case 1:
140614b24e2bSVaishali Kulkarni 		pci_config_put8(qede->pci_cfg_handle, addr,
140714b24e2bSVaishali Kulkarni 		    *(char *)&(data));
140814b24e2bSVaishali Kulkarni 		break;
140914b24e2bSVaishali Kulkarni 	case 2:
141014b24e2bSVaishali Kulkarni 		ret = pci_config_get16(qede->pci_cfg_handle, addr);
141114b24e2bSVaishali Kulkarni 		ret = ret | *(uint16_t *)data1->uabc;
141214b24e2bSVaishali Kulkarni 
141314b24e2bSVaishali Kulkarni 		pci_config_put16(qede->pci_cfg_handle, addr,
141414b24e2bSVaishali Kulkarni 		    ret);
141514b24e2bSVaishali Kulkarni 		break;
141614b24e2bSVaishali Kulkarni 	case 4:
141714b24e2bSVaishali Kulkarni 		pci_config_put32(qede->pci_cfg_handle, addr, *(uint32_t *)data1->uabc);
141814b24e2bSVaishali Kulkarni 		break;
141914b24e2bSVaishali Kulkarni 
142014b24e2bSVaishali Kulkarni 	default:
142114b24e2bSVaishali Kulkarni 		return (1);
142214b24e2bSVaishali Kulkarni 	}
142314b24e2bSVaishali Kulkarni 	return (0);
142414b24e2bSVaishali Kulkarni }
142514b24e2bSVaishali Kulkarni 
142614b24e2bSVaishali Kulkarni static int
142714b24e2bSVaishali Kulkarni qede_ioctl_rd_wr_reg(qede_t *qede, void *data)
142814b24e2bSVaishali Kulkarni {
142914b24e2bSVaishali Kulkarni 	struct ecore_hwfn *p_hwfn;
143014b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
143114b24e2bSVaishali Kulkarni 	struct ecore_ptt *ptt;
143214b24e2bSVaishali Kulkarni 	qede_ioctl_data_t *data1 = (qede_ioctl_data_t *)data;
143314b24e2bSVaishali Kulkarni 	uint32_t ret = 0;
143414b24e2bSVaishali Kulkarni 	uint8_t cmd = (uint8_t) data1->unused1;
143514b24e2bSVaishali Kulkarni 	uint32_t addr = data1->off;
143614b24e2bSVaishali Kulkarni 	uint32_t val = *(uint32_t *)&data1->uabc[1];
143714b24e2bSVaishali Kulkarni 	uint32_t hwfn_index = *(uint32_t *)&data1->uabc[5];
143814b24e2bSVaishali Kulkarni 	uint32_t *reg_addr;
143914b24e2bSVaishali Kulkarni 
144014b24e2bSVaishali Kulkarni 	if (hwfn_index > qede->num_hwfns) {
144114b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN, "invalid hwfn index from application\n");
144214b24e2bSVaishali Kulkarni 		return (EINVAL);
144314b24e2bSVaishali Kulkarni 	}
144414b24e2bSVaishali Kulkarni 	p_hwfn = &edev->hwfns[hwfn_index];
144514b24e2bSVaishali Kulkarni 
144614b24e2bSVaishali Kulkarni 	switch(cmd) {
144714b24e2bSVaishali Kulkarni 	case QEDE_REG_READ:
144814b24e2bSVaishali Kulkarni 		ret = ecore_rd(p_hwfn, p_hwfn->p_main_ptt, addr);
144914b24e2bSVaishali Kulkarni 		(void) memcpy(data1->uabc, &ret, sizeof(uint32_t));
145014b24e2bSVaishali Kulkarni 		break;
145114b24e2bSVaishali Kulkarni 
145214b24e2bSVaishali Kulkarni 	case QEDE_REG_WRITE:
145314b24e2bSVaishali Kulkarni 		ecore_wr(p_hwfn, p_hwfn->p_main_ptt, addr, val);
145414b24e2bSVaishali Kulkarni 		break;
145514b24e2bSVaishali Kulkarni 
145614b24e2bSVaishali Kulkarni 	default:
145714b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN,
145814b24e2bSVaishali Kulkarni 		    "wrong command in register read/write from application\n");
145914b24e2bSVaishali Kulkarni 		break;
146014b24e2bSVaishali Kulkarni 	}
146114b24e2bSVaishali Kulkarni 	return (ret);
146214b24e2bSVaishali Kulkarni }
146314b24e2bSVaishali Kulkarni 
146414b24e2bSVaishali Kulkarni static int
146514b24e2bSVaishali Kulkarni qede_ioctl_rd_wr_nvram(qede_t *qede, mblk_t *mp)
146614b24e2bSVaishali Kulkarni {
146714b24e2bSVaishali Kulkarni 	qede_nvram_data_t *data1 = (qede_nvram_data_t *)(mp->b_cont->b_rptr);
146814b24e2bSVaishali Kulkarni 	qede_nvram_data_t *data2, *next_data;
146914b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
1470b68ddc76SJohn Levon 	uint32_t hdr_size = 24, bytes_to_copy, copy_len = 0;
147114b24e2bSVaishali Kulkarni 	uint32_t copy_len1 = 0;
147214b24e2bSVaishali Kulkarni 	uint32_t addr = data1->off;
147314b24e2bSVaishali Kulkarni 	uint32_t size = data1->size, i, buf_size;
147414b24e2bSVaishali Kulkarni 	uint8_t cmd, cmd2;
147514b24e2bSVaishali Kulkarni 	uint8_t *buf, *tmp_buf;
147614b24e2bSVaishali Kulkarni 	mblk_t *mp1;
147714b24e2bSVaishali Kulkarni 
147814b24e2bSVaishali Kulkarni 	cmd = (uint8_t)data1->unused1;
147914b24e2bSVaishali Kulkarni 
148014b24e2bSVaishali Kulkarni 	switch(cmd) {
148114b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_READ:
148214b24e2bSVaishali Kulkarni 		buf = kmem_zalloc(size, GFP_KERNEL);
148314b24e2bSVaishali Kulkarni 		if(buf == NULL) {
148414b24e2bSVaishali Kulkarni 			cmn_err(CE_WARN, "memory allocation failed"
148514b24e2bSVaishali Kulkarni 			" in nvram read ioctl\n");
148614b24e2bSVaishali Kulkarni 			return (DDI_FAILURE);
148714b24e2bSVaishali Kulkarni 		}
1488b68ddc76SJohn Levon 		(void) ecore_mcp_nvm_read(edev, addr, buf, data1->size);
148914b24e2bSVaishali Kulkarni 
149014b24e2bSVaishali Kulkarni 		copy_len = (MBLKL(mp->b_cont)) - hdr_size;
149114b24e2bSVaishali Kulkarni 		if(copy_len > size) {
149214b24e2bSVaishali Kulkarni 			(void) memcpy(data1->uabc, buf, size);
149314b24e2bSVaishali Kulkarni 			kmem_free(buf, size);
149414b24e2bSVaishali Kulkarni 			//OSAL_FREE(edev, buf);
149514b24e2bSVaishali Kulkarni 			break;
149614b24e2bSVaishali Kulkarni 		}
149714b24e2bSVaishali Kulkarni 		(void) memcpy(data1->uabc, buf, copy_len);
149814b24e2bSVaishali Kulkarni 		bytes_to_copy = size - copy_len;
149914b24e2bSVaishali Kulkarni 		tmp_buf = ((uint8_t *)buf) + copy_len;
150014b24e2bSVaishali Kulkarni 		copy_len1 = copy_len;
150114b24e2bSVaishali Kulkarni 		mp1 = mp->b_cont;
150214b24e2bSVaishali Kulkarni 		mp1 = mp1->b_cont;
150314b24e2bSVaishali Kulkarni 
150414b24e2bSVaishali Kulkarni 		while (mp1) {
150514b24e2bSVaishali Kulkarni 			copy_len = MBLKL(mp1);
150614b24e2bSVaishali Kulkarni 			if(mp1->b_cont == NULL) {
150714b24e2bSVaishali Kulkarni 				copy_len = MBLKL(mp1) - 4;
150814b24e2bSVaishali Kulkarni 			}
150914b24e2bSVaishali Kulkarni 			data2 = (qede_nvram_data_t *)mp1->b_rptr;
151014b24e2bSVaishali Kulkarni 			if (copy_len > bytes_to_copy) {
151114b24e2bSVaishali Kulkarni 				(void) memcpy(data2->uabc, tmp_buf,
151214b24e2bSVaishali Kulkarni 				    bytes_to_copy);
151314b24e2bSVaishali Kulkarni 				kmem_free(buf, size);
151414b24e2bSVaishali Kulkarni 				//OSAL_FREE(edev, buf);
151514b24e2bSVaishali Kulkarni 				break;
151614b24e2bSVaishali Kulkarni 			}
151714b24e2bSVaishali Kulkarni 			(void) memcpy(data2->uabc, tmp_buf, copy_len);
151814b24e2bSVaishali Kulkarni 			tmp_buf = tmp_buf + copy_len;
151914b24e2bSVaishali Kulkarni 			copy_len += copy_len;
152014b24e2bSVaishali Kulkarni 			mp1 = mp1->b_cont;
152114b24e2bSVaishali Kulkarni 			bytes_to_copy = bytes_to_copy - copy_len;
152214b24e2bSVaishali Kulkarni 		}
152314b24e2bSVaishali Kulkarni 
152414b24e2bSVaishali Kulkarni 		kmem_free(buf, size);
152514b24e2bSVaishali Kulkarni 		//OSAL_FREE(edev, buf);
152614b24e2bSVaishali Kulkarni 		break;
152714b24e2bSVaishali Kulkarni 
152814b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_WRITE:
152914b24e2bSVaishali Kulkarni 		cmd2 = (uint8_t )data1->cmd2;
153014b24e2bSVaishali Kulkarni 		size = data1->size;
153114b24e2bSVaishali Kulkarni 		addr = data1->off;
153214b24e2bSVaishali Kulkarni 		buf_size =  size; //data1->buf_size;
153314b24e2bSVaishali Kulkarni 		//buf_size =  data1->buf_size;
153414b24e2bSVaishali Kulkarni 
153514b24e2bSVaishali Kulkarni 		switch(cmd2){
153614b24e2bSVaishali Kulkarni 		case START_NVM_WRITE:
153714b24e2bSVaishali Kulkarni 			buf = kmem_zalloc(size, GFP_KERNEL);
153814b24e2bSVaishali Kulkarni 			//buf = qede->reserved_buf;
153914b24e2bSVaishali Kulkarni 			qede->nvm_buf_size = data1->size;
154014b24e2bSVaishali Kulkarni 			if(buf == NULL) {
154114b24e2bSVaishali Kulkarni 				cmn_err(CE_WARN,
154214b24e2bSVaishali Kulkarni 				"memory allocation failed in START_NVM_WRITE\n");
154314b24e2bSVaishali Kulkarni 				return DDI_FAILURE;
154414b24e2bSVaishali Kulkarni 			}
154514b24e2bSVaishali Kulkarni 			qede->nvm_buf_start = buf;
154614b24e2bSVaishali Kulkarni 			cmn_err(CE_NOTE,
154714b24e2bSVaishali Kulkarni 			    "buf = %p, size = %x\n", qede->nvm_buf_start, size);
154814b24e2bSVaishali Kulkarni 			qede->nvm_buf = buf;
154914b24e2bSVaishali Kulkarni 			qede->copy_len = 0;
155014b24e2bSVaishali Kulkarni 			//tmp_buf = buf + addr;
155114b24e2bSVaishali Kulkarni 			break;
155214b24e2bSVaishali Kulkarni 
155314b24e2bSVaishali Kulkarni 		case ACCUMULATE_NVM_BUF:
155414b24e2bSVaishali Kulkarni 			tmp_buf = qede->nvm_buf;
155514b24e2bSVaishali Kulkarni 			copy_len = MBLKL(mp->b_cont) - hdr_size;
155614b24e2bSVaishali Kulkarni 			if(copy_len > buf_size) {
155714b24e2bSVaishali Kulkarni 			 	if (buf_size < qede->nvm_buf_size) {
155814b24e2bSVaishali Kulkarni 				(void) memcpy(tmp_buf, data1->uabc, buf_size);
155914b24e2bSVaishali Kulkarni 					qede->copy_len = qede->copy_len +
156014b24e2bSVaishali Kulkarni 					    buf_size;
156114b24e2bSVaishali Kulkarni 				} else {
156214b24e2bSVaishali Kulkarni 					(void) memcpy(tmp_buf,
156314b24e2bSVaishali Kulkarni 					    data1->uabc, qede->nvm_buf_size);
156414b24e2bSVaishali Kulkarni 					qede->copy_len =
156514b24e2bSVaishali Kulkarni 					    qede->copy_len + qede->nvm_buf_size;
156614b24e2bSVaishali Kulkarni 				}
156714b24e2bSVaishali Kulkarni 				tmp_buf = tmp_buf + buf_size;
156814b24e2bSVaishali Kulkarni 				qede->nvm_buf = tmp_buf;
156914b24e2bSVaishali Kulkarni 				//qede->copy_len = qede->copy_len + buf_size;
157014b24e2bSVaishali Kulkarni 				cmn_err(CE_NOTE,
157114b24e2bSVaishali Kulkarni 				    "buf_size from app = %x\n", copy_len);
157214b24e2bSVaishali Kulkarni 				break;
157314b24e2bSVaishali Kulkarni 			}
157414b24e2bSVaishali Kulkarni 			(void) memcpy(tmp_buf, data1->uabc, copy_len);
157514b24e2bSVaishali Kulkarni 			tmp_buf = tmp_buf + copy_len;
157614b24e2bSVaishali Kulkarni 			bytes_to_copy = buf_size - copy_len;
157714b24e2bSVaishali Kulkarni 			mp1 = mp->b_cont;
157814b24e2bSVaishali Kulkarni 			mp1 = mp1->b_cont;
157914b24e2bSVaishali Kulkarni 			copy_len1 = copy_len;
158014b24e2bSVaishali Kulkarni 
158114b24e2bSVaishali Kulkarni 			while (mp1) {
158214b24e2bSVaishali Kulkarni 				copy_len = MBLKL(mp1);
158314b24e2bSVaishali Kulkarni 				if (mp1->b_cont == NULL) {
158414b24e2bSVaishali Kulkarni 					copy_len = MBLKL(mp1) - 4;
158514b24e2bSVaishali Kulkarni 				}
158614b24e2bSVaishali Kulkarni 				next_data = (qede_nvram_data_t *) mp1->b_rptr;
158714b24e2bSVaishali Kulkarni 				if (copy_len > bytes_to_copy){
158814b24e2bSVaishali Kulkarni 					(void) memcpy(tmp_buf, next_data->uabc,
158914b24e2bSVaishali Kulkarni 					    bytes_to_copy);
159014b24e2bSVaishali Kulkarni 					qede->copy_len = qede->copy_len +
159114b24e2bSVaishali Kulkarni 					    bytes_to_copy;
159214b24e2bSVaishali Kulkarni 					break;
159314b24e2bSVaishali Kulkarni 				}
159414b24e2bSVaishali Kulkarni 				(void) memcpy(tmp_buf, next_data->uabc,
159514b24e2bSVaishali Kulkarni 				    copy_len);
159614b24e2bSVaishali Kulkarni 				qede->copy_len = qede->copy_len + copy_len;
159714b24e2bSVaishali Kulkarni 				tmp_buf = tmp_buf + copy_len;
159814b24e2bSVaishali Kulkarni 				copy_len = copy_len1 + copy_len;
159914b24e2bSVaishali Kulkarni 				bytes_to_copy = bytes_to_copy - copy_len;
160014b24e2bSVaishali Kulkarni 				mp1 = mp1->b_cont;
160114b24e2bSVaishali Kulkarni 			}
160214b24e2bSVaishali Kulkarni 			qede->nvm_buf = tmp_buf;
160314b24e2bSVaishali Kulkarni 			break;
160414b24e2bSVaishali Kulkarni 
160514b24e2bSVaishali Kulkarni 		case STOP_NVM_WRITE:
160614b24e2bSVaishali Kulkarni 			//qede->nvm_buf = tmp_buf;
160714b24e2bSVaishali Kulkarni 			break;
160814b24e2bSVaishali Kulkarni 		case READ_BUF:
160914b24e2bSVaishali Kulkarni 			tmp_buf = (uint8_t *)qede->nvm_buf_start;
161014b24e2bSVaishali Kulkarni 			for(i = 0; i < size ; i++){
161114b24e2bSVaishali Kulkarni 				cmn_err(CE_NOTE,
161214b24e2bSVaishali Kulkarni 				    "buff (%d) : %d\n", i, *tmp_buf);
161314b24e2bSVaishali Kulkarni 				tmp_buf ++;
161414b24e2bSVaishali Kulkarni 			}
161514b24e2bSVaishali Kulkarni 			break;
161614b24e2bSVaishali Kulkarni 		}
161714b24e2bSVaishali Kulkarni 		break;
161814b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_PUT_FILE_DATA:
161914b24e2bSVaishali Kulkarni 		tmp_buf = qede->nvm_buf_start;
1620b68ddc76SJohn Levon 		(void) ecore_mcp_nvm_write(edev, ECORE_PUT_FILE_DATA,
162114b24e2bSVaishali Kulkarni 			  addr, tmp_buf, size);
162214b24e2bSVaishali Kulkarni 		kmem_free(qede->nvm_buf_start, size);
162314b24e2bSVaishali Kulkarni 		//OSAL_FREE(edev, tmp_buf);
162414b24e2bSVaishali Kulkarni 		cmn_err(CE_NOTE, "total size = %x, copied size = %x\n",
162514b24e2bSVaishali Kulkarni 		    qede->nvm_buf_size, qede->copy_len);
162614b24e2bSVaishali Kulkarni 		tmp_buf = NULL;
162714b24e2bSVaishali Kulkarni 		qede->nvm_buf = NULL;
162814b24e2bSVaishali Kulkarni 		qede->nvm_buf_start = NULL;
162914b24e2bSVaishali Kulkarni 		break;
163014b24e2bSVaishali Kulkarni 
163114b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_SET_SECURE_MODE:
1632b68ddc76SJohn Levon 		(void) ecore_mcp_nvm_set_secure_mode(edev, addr);
163314b24e2bSVaishali Kulkarni 		break;
163414b24e2bSVaishali Kulkarni 
163514b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_DEL_FILE:
1636b68ddc76SJohn Levon 		(void) ecore_mcp_nvm_del_file(edev, addr);
163714b24e2bSVaishali Kulkarni 		break;
163814b24e2bSVaishali Kulkarni 
163914b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_PUT_FILE_BEGIN:
1640b68ddc76SJohn Levon 		(void) ecore_mcp_nvm_put_file_begin(edev, addr);
164114b24e2bSVaishali Kulkarni 		break;
164214b24e2bSVaishali Kulkarni 
164314b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_GET_NVRAM_RESP:
164414b24e2bSVaishali Kulkarni 		buf = kmem_zalloc(size, KM_SLEEP);
1645b68ddc76SJohn Levon 		(void) ecore_mcp_nvm_resp(edev, buf);
164614b24e2bSVaishali Kulkarni 		(void)memcpy(data1->uabc, buf, size);
164714b24e2bSVaishali Kulkarni 		kmem_free(buf, size);
164814b24e2bSVaishali Kulkarni 		break;
164914b24e2bSVaishali Kulkarni 
165014b24e2bSVaishali Kulkarni 	default:
165114b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN,
165214b24e2bSVaishali Kulkarni 		    "wrong command in NVRAM read/write from application\n");
165314b24e2bSVaishali Kulkarni 		break;
165414b24e2bSVaishali Kulkarni 	}
165514b24e2bSVaishali Kulkarni 	return (DDI_SUCCESS);
165614b24e2bSVaishali Kulkarni }
165714b24e2bSVaishali Kulkarni 
165814b24e2bSVaishali Kulkarni static int
165914b24e2bSVaishali Kulkarni qede_get_func_info(qede_t *qede, void *data)
166014b24e2bSVaishali Kulkarni {
166114b24e2bSVaishali Kulkarni 	qede_link_output_t link_op;
166214b24e2bSVaishali Kulkarni 	qede_func_info_t func_info;
166314b24e2bSVaishali Kulkarni 	qede_ioctl_data_t *data1 = (qede_ioctl_data_t *)data;
166414b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
166514b24e2bSVaishali Kulkarni 	struct ecore_hwfn *hwfn;
166614b24e2bSVaishali Kulkarni 	struct ecore_mcp_link_params params;
166714b24e2bSVaishali Kulkarni 	struct ecore_mcp_link_state link;
166814b24e2bSVaishali Kulkarni 
166914b24e2bSVaishali Kulkarni 	hwfn = &edev->hwfns[0];
167014b24e2bSVaishali Kulkarni 
167114b24e2bSVaishali Kulkarni 	if(hwfn == NULL){
167214b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN, "(%s) : cannot acquire hwfn\n",
167314b24e2bSVaishali Kulkarni 		    __func__);
167414b24e2bSVaishali Kulkarni 		return (DDI_FAILURE);
167514b24e2bSVaishali Kulkarni 	}
167614b24e2bSVaishali Kulkarni 	memcpy(&params, &hwfn->mcp_info->link_input, sizeof(params));
167714b24e2bSVaishali Kulkarni 	memcpy(&link, &hwfn->mcp_info->link_output, sizeof(link));
167814b24e2bSVaishali Kulkarni 
167914b24e2bSVaishali Kulkarni 	if(link.link_up) {
168014b24e2bSVaishali Kulkarni 		link_op.link_up = true;
168114b24e2bSVaishali Kulkarni 	}
168214b24e2bSVaishali Kulkarni 
168314b24e2bSVaishali Kulkarni 	link_op.supported_caps = SUPPORTED_FIBRE;
168414b24e2bSVaishali Kulkarni 	if(params.speed.autoneg) {
168514b24e2bSVaishali Kulkarni 		link_op.supported_caps |= SUPPORTED_Autoneg;
168614b24e2bSVaishali Kulkarni 	}
168714b24e2bSVaishali Kulkarni 
168814b24e2bSVaishali Kulkarni 	if(params.pause.autoneg ||
168914b24e2bSVaishali Kulkarni 	    (params.pause.forced_rx && params.pause.forced_tx)) {
169014b24e2bSVaishali Kulkarni 		link_op.supported_caps |= SUPPORTED_Asym_Pause;
169114b24e2bSVaishali Kulkarni 	}
169214b24e2bSVaishali Kulkarni 
169314b24e2bSVaishali Kulkarni 	if (params.pause.autoneg || params.pause.forced_rx ||
169414b24e2bSVaishali Kulkarni 	     params.pause.forced_tx) {
169514b24e2bSVaishali Kulkarni 		link_op.supported_caps |= SUPPORTED_Pause;
169614b24e2bSVaishali Kulkarni 	}
169714b24e2bSVaishali Kulkarni 
169814b24e2bSVaishali Kulkarni 	if (params.speed.advertised_speeds &
169914b24e2bSVaishali Kulkarni 	    NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) {
170014b24e2bSVaishali Kulkarni 		link_op.supported_caps |= SUPPORTED_1000baseT_Half |
170114b24e2bSVaishali Kulkarni 	    	    SUPPORTED_1000baseT_Full;
170214b24e2bSVaishali Kulkarni 	}
170314b24e2bSVaishali Kulkarni 
170414b24e2bSVaishali Kulkarni 	if (params.speed.advertised_speeds &
170514b24e2bSVaishali Kulkarni 	    NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) {
170614b24e2bSVaishali Kulkarni 		link_op.supported_caps |= SUPPORTED_10000baseKR_Full;
170714b24e2bSVaishali Kulkarni 	}
170814b24e2bSVaishali Kulkarni 
170914b24e2bSVaishali Kulkarni 	if (params.speed.advertised_speeds &
171014b24e2bSVaishali Kulkarni 	    NVM_CFG1_PORT_DRV_LINK_SPEED_40G) {
171114b24e2bSVaishali Kulkarni 		link_op.supported_caps |= SUPPORTED_40000baseLR4_Full;
171214b24e2bSVaishali Kulkarni 	}
171314b24e2bSVaishali Kulkarni 
171414b24e2bSVaishali Kulkarni 	link_op.advertised_caps = link_op.supported_caps;
171514b24e2bSVaishali Kulkarni 
171614b24e2bSVaishali Kulkarni 	if(link.link_up) {
171714b24e2bSVaishali Kulkarni 		link_op.speed = link.speed;
171814b24e2bSVaishali Kulkarni 	} else {
171914b24e2bSVaishali Kulkarni 		link_op.speed = 0;
172014b24e2bSVaishali Kulkarni 	}
172114b24e2bSVaishali Kulkarni 
172214b24e2bSVaishali Kulkarni 	link_op.duplex = DUPLEX_FULL;
172314b24e2bSVaishali Kulkarni 	link_op.port = PORT_FIBRE;
172414b24e2bSVaishali Kulkarni 
172514b24e2bSVaishali Kulkarni 	link_op.autoneg = params.speed.autoneg;
172614b24e2bSVaishali Kulkarni 
172714b24e2bSVaishali Kulkarni 	/* Link partner capabilities */
172814b24e2bSVaishali Kulkarni 	if (link.partner_adv_speed &
172914b24e2bSVaishali Kulkarni 	    ECORE_LINK_PARTNER_SPEED_1G_HD) {
173014b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_1000baseT_Half;
173114b24e2bSVaishali Kulkarni 	}
173214b24e2bSVaishali Kulkarni 
173314b24e2bSVaishali Kulkarni 	if (link.partner_adv_speed &
173414b24e2bSVaishali Kulkarni 	    ECORE_LINK_PARTNER_SPEED_1G_FD) {
173514b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_1000baseT_Full;
173614b24e2bSVaishali Kulkarni 	}
173714b24e2bSVaishali Kulkarni 
173814b24e2bSVaishali Kulkarni 	if (link.partner_adv_speed &
173914b24e2bSVaishali Kulkarni 	    ECORE_LINK_PARTNER_SPEED_10G) {
174014b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_10000baseKR_Full;
174114b24e2bSVaishali Kulkarni 	}
174214b24e2bSVaishali Kulkarni 
174314b24e2bSVaishali Kulkarni 	if (link.partner_adv_speed &
174414b24e2bSVaishali Kulkarni 	    ECORE_LINK_PARTNER_SPEED_20G) {
174514b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_20000baseKR2_Full;
174614b24e2bSVaishali Kulkarni 	}
174714b24e2bSVaishali Kulkarni 
174814b24e2bSVaishali Kulkarni 	if (link.partner_adv_speed &
174914b24e2bSVaishali Kulkarni 	    ECORE_LINK_PARTNER_SPEED_40G) {
175014b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_40000baseLR4_Full;
175114b24e2bSVaishali Kulkarni 	}
175214b24e2bSVaishali Kulkarni 
175314b24e2bSVaishali Kulkarni 	if (link.an_complete) {
175414b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_Autoneg;
175514b24e2bSVaishali Kulkarni 	}
175614b24e2bSVaishali Kulkarni 
175714b24e2bSVaishali Kulkarni 	if (link.partner_adv_pause) {
175814b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_Pause;
175914b24e2bSVaishali Kulkarni 	}
176014b24e2bSVaishali Kulkarni 
176114b24e2bSVaishali Kulkarni 	if (link.partner_adv_pause == ECORE_LINK_PARTNER_ASYMMETRIC_PAUSE ||
176214b24e2bSVaishali Kulkarni 	    link.partner_adv_pause == ECORE_LINK_PARTNER_BOTH_PAUSE) {
176314b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_Asym_Pause;
176414b24e2bSVaishali Kulkarni 	}
176514b24e2bSVaishali Kulkarni 
176614b24e2bSVaishali Kulkarni 	func_info.supported = link_op.supported_caps;
176714b24e2bSVaishali Kulkarni 	func_info.advertising = link_op.advertised_caps;
176814b24e2bSVaishali Kulkarni 	func_info.speed = link_op.speed;
176914b24e2bSVaishali Kulkarni 	func_info.duplex = link_op.duplex;
177014b24e2bSVaishali Kulkarni 	func_info.port = qede->pci_func & 0x1;
177114b24e2bSVaishali Kulkarni 	func_info.autoneg = link_op.autoneg;
177214b24e2bSVaishali Kulkarni 
177314b24e2bSVaishali Kulkarni 	(void) memcpy(data1->uabc, &func_info, sizeof(qede_func_info_t));
177414b24e2bSVaishali Kulkarni 
177514b24e2bSVaishali Kulkarni 	return (0);
177614b24e2bSVaishali Kulkarni }
177714b24e2bSVaishali Kulkarni 
177814b24e2bSVaishali Kulkarni static int
177914b24e2bSVaishali Kulkarni qede_do_ioctl(qede_t *qede, queue_t *q, mblk_t *mp)
178014b24e2bSVaishali Kulkarni {
178114b24e2bSVaishali Kulkarni 	qede_ioctl_data_t *up_data;
178214b24e2bSVaishali Kulkarni 	qede_driver_info_t driver_info;
178314b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
178414b24e2bSVaishali Kulkarni 	struct ecore_hwfn *hwfn;
178514b24e2bSVaishali Kulkarni 	struct ecore_ptt *ptt = NULL;
178614b24e2bSVaishali Kulkarni 	struct mcp_file_att attrib;
178714b24e2bSVaishali Kulkarni 	uint32_t flash_size;
178814b24e2bSVaishali Kulkarni 	uint32_t mcp_resp, mcp_param, txn_size;
178914b24e2bSVaishali Kulkarni 	uint32_t cmd, size, ret = 0;
179014b24e2bSVaishali Kulkarni 	uint64_t off;
179114b24e2bSVaishali Kulkarni 	int * up_data1;
179214b24e2bSVaishali Kulkarni 	void * ptr;
179314b24e2bSVaishali Kulkarni 	mblk_t *mp1 = mp;
179414b24e2bSVaishali Kulkarni 	char mac_addr[32];
179514b24e2bSVaishali Kulkarni 
179614b24e2bSVaishali Kulkarni 	up_data = (qede_ioctl_data_t *)(mp->b_cont->b_rptr);
179714b24e2bSVaishali Kulkarni 
179814b24e2bSVaishali Kulkarni 	cmd = up_data->cmd;
179914b24e2bSVaishali Kulkarni 	off = up_data->off;
180014b24e2bSVaishali Kulkarni 	size = up_data->size;
180114b24e2bSVaishali Kulkarni 
180214b24e2bSVaishali Kulkarni 	switch (cmd) {
180314b24e2bSVaishali Kulkarni 	case QEDE_DRV_INFO:
180414b24e2bSVaishali Kulkarni 		hwfn = &edev->hwfns[0];
180514b24e2bSVaishali Kulkarni 		ptt = ecore_ptt_acquire(hwfn);
180614b24e2bSVaishali Kulkarni 
180714b24e2bSVaishali Kulkarni 		snprintf(driver_info.drv_name, MAX_QEDE_NAME_LEN, "%s", "qede");
180814b24e2bSVaishali Kulkarni 		snprintf(driver_info.drv_version, QEDE_STR_SIZE,
180914b24e2bSVaishali Kulkarni 		    "v:%s", qede->version);
181014b24e2bSVaishali Kulkarni 		snprintf(driver_info.mfw_version, QEDE_STR_SIZE,
181114b24e2bSVaishali Kulkarni 		    "%s", qede->versionMFW);
181214b24e2bSVaishali Kulkarni 		snprintf(driver_info.stormfw_version, QEDE_STR_SIZE,
181314b24e2bSVaishali Kulkarni 		    "%s", qede->versionFW);
181414b24e2bSVaishali Kulkarni 		snprintf(driver_info.bus_info, QEDE_STR_SIZE,
181514b24e2bSVaishali Kulkarni 		    "%s", qede->bus_dev_func);
181614b24e2bSVaishali Kulkarni 
181714b24e2bSVaishali Kulkarni 
181814b24e2bSVaishali Kulkarni 		/*
181914b24e2bSVaishali Kulkarni 		 * calling ecore_mcp_nvm_rd_cmd to find the flash length, i
182014b24e2bSVaishali Kulkarni 		 * 0x08 is equivalent of NVM_TYPE_MFW_TRACE1
182114b24e2bSVaishali Kulkarni 		 */
182214b24e2bSVaishali Kulkarni 		ecore_mcp_get_flash_size(hwfn, ptt, &flash_size);
182314b24e2bSVaishali Kulkarni 		driver_info.eeprom_dump_len = flash_size;
182414b24e2bSVaishali Kulkarni 		(void) memcpy(up_data->uabc, &driver_info,
182514b24e2bSVaishali Kulkarni 		    sizeof (qede_driver_info_t));
182614b24e2bSVaishali Kulkarni 		up_data->size = sizeof (qede_driver_info_t);
182714b24e2bSVaishali Kulkarni 
182814b24e2bSVaishali Kulkarni 		ecore_ptt_release(hwfn, ptt);
182914b24e2bSVaishali Kulkarni 		break;
183014b24e2bSVaishali Kulkarni 
183114b24e2bSVaishali Kulkarni 	case QEDE_RD_PCICFG:
183214b24e2bSVaishali Kulkarni 		ret = qede_ioctl_pcicfg_rd(qede, off, up_data->uabc, size);
183314b24e2bSVaishali Kulkarni 		break;
183414b24e2bSVaishali Kulkarni 
183514b24e2bSVaishali Kulkarni 	case QEDE_WR_PCICFG:
183614b24e2bSVaishali Kulkarni 		ret = qede_ioctl_pcicfg_wr(qede, off, up_data, size);
183714b24e2bSVaishali Kulkarni 		break;
183814b24e2bSVaishali Kulkarni 
183914b24e2bSVaishali Kulkarni 	case QEDE_RW_REG:
184014b24e2bSVaishali Kulkarni 		ret = qede_ioctl_rd_wr_reg(qede, (void *)up_data);
184114b24e2bSVaishali Kulkarni 	       	break;
184214b24e2bSVaishali Kulkarni 
184314b24e2bSVaishali Kulkarni 	case QEDE_RW_NVRAM:
184414b24e2bSVaishali Kulkarni 		ret = qede_ioctl_rd_wr_nvram(qede, mp1);
184514b24e2bSVaishali Kulkarni 		break;
184614b24e2bSVaishali Kulkarni 
184714b24e2bSVaishali Kulkarni 	case QEDE_FUNC_INFO:
184814b24e2bSVaishali Kulkarni 		ret = qede_get_func_info(qede, (void *)up_data);
184914b24e2bSVaishali Kulkarni 		break;
185014b24e2bSVaishali Kulkarni 
185114b24e2bSVaishali Kulkarni 	case QEDE_MAC_ADDR:
185214b24e2bSVaishali Kulkarni 		snprintf(mac_addr, sizeof(mac_addr),
185314b24e2bSVaishali Kulkarni 			"%02x:%02x:%02x:%02x:%02x:%02x",
185414b24e2bSVaishali Kulkarni 			qede->ether_addr[0], qede->ether_addr[1],
185514b24e2bSVaishali Kulkarni 			qede->ether_addr[2], qede->ether_addr[3],
185614b24e2bSVaishali Kulkarni 			qede->ether_addr[4], qede->ether_addr[5]);
185714b24e2bSVaishali Kulkarni 		(void) memcpy(up_data->uabc, &mac_addr, sizeof(mac_addr));
185814b24e2bSVaishali Kulkarni 		break;
185914b24e2bSVaishali Kulkarni 
186014b24e2bSVaishali Kulkarni 	}
186114b24e2bSVaishali Kulkarni 	//if (cmd == QEDE_RW_NVRAM) {
186214b24e2bSVaishali Kulkarni 	//	miocack (q, mp, (sizeof(qede_ioctl_data_t)), 0);
186314b24e2bSVaishali Kulkarni 	//	return IOC_REPLY;
186414b24e2bSVaishali Kulkarni 	//}
186514b24e2bSVaishali Kulkarni 	miocack (q, mp, (sizeof(qede_ioctl_data_t)), ret);
186614b24e2bSVaishali Kulkarni 	//miocack (q, mp, 0, ret);
186714b24e2bSVaishali Kulkarni 	return (IOC_REPLY);
186814b24e2bSVaishali Kulkarni }
186914b24e2bSVaishali Kulkarni 
187014b24e2bSVaishali Kulkarni static void
187114b24e2bSVaishali Kulkarni qede_ioctl(qede_t *qede, int cmd, queue_t *q, mblk_t *mp)
187214b24e2bSVaishali Kulkarni {
187314b24e2bSVaishali Kulkarni 	void *ptr;
187414b24e2bSVaishali Kulkarni 
187514b24e2bSVaishali Kulkarni 	switch(cmd) {
187614b24e2bSVaishali Kulkarni 	case QEDE_CMD:
187714b24e2bSVaishali Kulkarni 		(void) qede_do_ioctl(qede, q, mp);
187814b24e2bSVaishali Kulkarni 		break;
187914b24e2bSVaishali Kulkarni 	default :
188014b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN, "qede ioctl command %x not supported\n", cmd);
188114b24e2bSVaishali Kulkarni 		break;
188214b24e2bSVaishali Kulkarni 	}
188314b24e2bSVaishali Kulkarni 	return;
188414b24e2bSVaishali Kulkarni }
188514b24e2bSVaishali Kulkarni enum ioc_reply
188614b24e2bSVaishali Kulkarni qede_loopback_ioctl(qede_t *qede, queue_t *wq, mblk_t *mp,
188714b24e2bSVaishali Kulkarni     struct iocblk *iocp)
188814b24e2bSVaishali Kulkarni {
188914b24e2bSVaishali Kulkarni 	lb_info_sz_t *lb_info_size;
189014b24e2bSVaishali Kulkarni 	lb_property_t *lb_prop;
189114b24e2bSVaishali Kulkarni 	uint32_t *lb_mode;
189214b24e2bSVaishali Kulkarni 	int cmd;
189314b24e2bSVaishali Kulkarni 
189414b24e2bSVaishali Kulkarni 	/*
189514b24e2bSVaishali Kulkarni 	 * Validate format of ioctl
189614b24e2bSVaishali Kulkarni 	 */
189714b24e2bSVaishali Kulkarni 	if(mp->b_cont == NULL) {
189814b24e2bSVaishali Kulkarni 		return IOC_INVAL;
189914b24e2bSVaishali Kulkarni 	}
190014b24e2bSVaishali Kulkarni 
190114b24e2bSVaishali Kulkarni 	cmd = iocp->ioc_cmd;
190214b24e2bSVaishali Kulkarni 
190314b24e2bSVaishali Kulkarni 	switch(cmd) {
190414b24e2bSVaishali Kulkarni 	default:
190514b24e2bSVaishali Kulkarni 		qede_print("!%s(%d): unknown ioctl command %x\n",
190614b24e2bSVaishali Kulkarni 		    __func__, qede->instance, cmd);
190714b24e2bSVaishali Kulkarni 		return IOC_INVAL;
190814b24e2bSVaishali Kulkarni 	case LB_GET_INFO_SIZE:
190914b24e2bSVaishali Kulkarni 		if (iocp->ioc_count != sizeof(lb_info_sz_t)) {
191014b24e2bSVaishali Kulkarni 			qede_info(qede, "error: ioc_count %d, sizeof %d",
191114b24e2bSVaishali Kulkarni 			    iocp->ioc_count,  sizeof(lb_info_sz_t));
191214b24e2bSVaishali Kulkarni 			return IOC_INVAL;
191314b24e2bSVaishali Kulkarni 		}
191414b24e2bSVaishali Kulkarni 		lb_info_size = (void *)mp->b_cont->b_rptr;
191514b24e2bSVaishali Kulkarni 		*lb_info_size = sizeof(loopmodes);
191614b24e2bSVaishali Kulkarni 		return IOC_REPLY;
191714b24e2bSVaishali Kulkarni 	case LB_GET_INFO:
191814b24e2bSVaishali Kulkarni 		if (iocp->ioc_count != sizeof (loopmodes)) {
191914b24e2bSVaishali Kulkarni 			qede_info(qede, "error: iocp->ioc_count %d, sizepof %d",
192014b24e2bSVaishali Kulkarni 			    iocp->ioc_count,  sizeof (loopmodes));
192114b24e2bSVaishali Kulkarni 			return (IOC_INVAL);
192214b24e2bSVaishali Kulkarni 		}
192314b24e2bSVaishali Kulkarni 		lb_prop = (void *)mp->b_cont->b_rptr;
192414b24e2bSVaishali Kulkarni 		bcopy(loopmodes, lb_prop, sizeof (loopmodes));
192514b24e2bSVaishali Kulkarni 		return IOC_REPLY;
192614b24e2bSVaishali Kulkarni 	case LB_GET_MODE:
192714b24e2bSVaishali Kulkarni 		if (iocp->ioc_count != sizeof (uint32_t)) {
192814b24e2bSVaishali Kulkarni 			qede_info(qede, "iocp->ioc_count %d, sizeof : %d\n",
192914b24e2bSVaishali Kulkarni 			    iocp->ioc_count, sizeof (uint32_t));
193014b24e2bSVaishali Kulkarni 			return (IOC_INVAL);
193114b24e2bSVaishali Kulkarni 		}
193214b24e2bSVaishali Kulkarni 		lb_mode = (void *)mp->b_cont->b_rptr;
193314b24e2bSVaishali Kulkarni 		*lb_mode = qede->loop_back_mode;
193414b24e2bSVaishali Kulkarni 		return IOC_REPLY;
193514b24e2bSVaishali Kulkarni 	case LB_SET_MODE:
193614b24e2bSVaishali Kulkarni 		if (iocp->ioc_count != sizeof (uint32_t)) {
193714b24e2bSVaishali Kulkarni 			qede_info(qede, "iocp->ioc_count %d, sizeof : %d\n",
193814b24e2bSVaishali Kulkarni 			    iocp->ioc_count, sizeof (uint32_t));
193914b24e2bSVaishali Kulkarni 			return (IOC_INVAL);
194014b24e2bSVaishali Kulkarni 		}
194114b24e2bSVaishali Kulkarni 		lb_mode = (void *)mp->b_cont->b_rptr;
194214b24e2bSVaishali Kulkarni 		return (qede_set_loopback_mode(qede,*lb_mode));
194314b24e2bSVaishali Kulkarni 	}
194414b24e2bSVaishali Kulkarni }
194514b24e2bSVaishali Kulkarni 
194614b24e2bSVaishali Kulkarni static void
194714b24e2bSVaishali Kulkarni qede_mac_ioctl(void *    arg,
194814b24e2bSVaishali Kulkarni                queue_t * wq,
194914b24e2bSVaishali Kulkarni                mblk_t *  mp)
195014b24e2bSVaishali Kulkarni {
195114b24e2bSVaishali Kulkarni 	int err, cmd;
195214b24e2bSVaishali Kulkarni     	qede_t * qede = (qede_t *)arg;
195314b24e2bSVaishali Kulkarni     	struct iocblk *iocp = (struct iocblk *) (uintptr_t)mp->b_rptr;
195414b24e2bSVaishali Kulkarni     	enum ioc_reply status = IOC_DONE;
195514b24e2bSVaishali Kulkarni     	boolean_t need_privilege = B_TRUE;
195614b24e2bSVaishali Kulkarni 
195714b24e2bSVaishali Kulkarni 	iocp->ioc_error = 0;
195814b24e2bSVaishali Kulkarni 	cmd = iocp->ioc_cmd;
195914b24e2bSVaishali Kulkarni 
196014b24e2bSVaishali Kulkarni 	mutex_enter(&qede->drv_lock);
196114b24e2bSVaishali Kulkarni 	if ((qede->qede_state == QEDE_STATE_SUSPENDING) ||
196214b24e2bSVaishali Kulkarni 	   (qede->qede_state == QEDE_STATE_SUSPENDED)) {
196314b24e2bSVaishali Kulkarni 		mutex_exit(&qede->drv_lock);
196414b24e2bSVaishali Kulkarni 		miocnak(wq, mp, 0, EINVAL);
196514b24e2bSVaishali Kulkarni 		return;
196614b24e2bSVaishali Kulkarni 	}
196714b24e2bSVaishali Kulkarni 
196814b24e2bSVaishali Kulkarni 	switch(cmd) {
196914b24e2bSVaishali Kulkarni 		case QEDE_CMD:
197014b24e2bSVaishali Kulkarni 			break;
197114b24e2bSVaishali Kulkarni 		case LB_GET_INFO_SIZE:
197214b24e2bSVaishali Kulkarni 		case LB_GET_INFO:
197314b24e2bSVaishali Kulkarni 		case LB_GET_MODE:
197414b24e2bSVaishali Kulkarni 			need_privilege = B_FALSE;
197514b24e2bSVaishali Kulkarni 		case LB_SET_MODE:
197614b24e2bSVaishali Kulkarni 			break;
197714b24e2bSVaishali Kulkarni 		default:
197814b24e2bSVaishali Kulkarni 			qede_print("!%s(%d) unknown ioctl command %x\n",
197914b24e2bSVaishali Kulkarni 			    __func__, qede->instance, cmd);
198014b24e2bSVaishali Kulkarni 			miocnak(wq, mp, 0, EINVAL);
198114b24e2bSVaishali Kulkarni 			mutex_exit(&qede->drv_lock);
198214b24e2bSVaishali Kulkarni 			return;
198314b24e2bSVaishali Kulkarni 	}
198414b24e2bSVaishali Kulkarni 
198514b24e2bSVaishali Kulkarni 	if(need_privilege) {
198614b24e2bSVaishali Kulkarni 		err = secpolicy_net_config(iocp->ioc_cr, B_FALSE);
198714b24e2bSVaishali Kulkarni 		if(err){
198814b24e2bSVaishali Kulkarni 			qede_info(qede, "secpolicy() failed");
198914b24e2bSVaishali Kulkarni 			miocnak(wq, mp, 0, err);
199014b24e2bSVaishali Kulkarni 		       	mutex_exit(&qede->drv_lock);
199114b24e2bSVaishali Kulkarni 			return;
199214b24e2bSVaishali Kulkarni 		}
199314b24e2bSVaishali Kulkarni 	}
199414b24e2bSVaishali Kulkarni 
199514b24e2bSVaishali Kulkarni 	switch (cmd) {
199614b24e2bSVaishali Kulkarni 		default:
199714b24e2bSVaishali Kulkarni 			qede_print("!%s(%d) : unknown ioctl command %x\n",
199814b24e2bSVaishali Kulkarni 			    __func__, qede->instance, cmd);
199914b24e2bSVaishali Kulkarni 			status = IOC_INVAL;
200014b24e2bSVaishali Kulkarni 			mutex_exit(&qede->drv_lock);
200114b24e2bSVaishali Kulkarni 			return;
200214b24e2bSVaishali Kulkarni 		case LB_GET_INFO_SIZE:
200314b24e2bSVaishali Kulkarni 		case LB_GET_INFO:
200414b24e2bSVaishali Kulkarni 		case LB_GET_MODE:
200514b24e2bSVaishali Kulkarni 		case LB_SET_MODE:
200614b24e2bSVaishali Kulkarni 			status = qede_loopback_ioctl(qede, wq, mp, iocp);
200714b24e2bSVaishali Kulkarni 			break;
200814b24e2bSVaishali Kulkarni 		case QEDE_CMD:
200914b24e2bSVaishali Kulkarni 			qede_ioctl(qede, cmd, wq, mp);
201014b24e2bSVaishali Kulkarni 			status = IOC_DONE;
201114b24e2bSVaishali Kulkarni 			break;
201214b24e2bSVaishali Kulkarni 	}
201314b24e2bSVaishali Kulkarni 
201414b24e2bSVaishali Kulkarni 	switch(status){
201514b24e2bSVaishali Kulkarni 		default:
201614b24e2bSVaishali Kulkarni 			qede_print("!%s(%d) : invalid status from ioctl",
201714b24e2bSVaishali Kulkarni 			    __func__,qede->instance);
201814b24e2bSVaishali Kulkarni 			break;
201914b24e2bSVaishali Kulkarni 		case IOC_DONE:
202014b24e2bSVaishali Kulkarni 			/*
202114b24e2bSVaishali Kulkarni 			 * OK, Reply already sent
202214b24e2bSVaishali Kulkarni 			 */
202314b24e2bSVaishali Kulkarni 
202414b24e2bSVaishali Kulkarni 			break;
202514b24e2bSVaishali Kulkarni 		case IOC_REPLY:
202614b24e2bSVaishali Kulkarni 			mp->b_datap->db_type = iocp->ioc_error == 0 ?
202714b24e2bSVaishali Kulkarni 				M_IOCACK : M_IOCNAK;
202814b24e2bSVaishali Kulkarni 			qreply(wq, mp);
202914b24e2bSVaishali Kulkarni 			break;
203014b24e2bSVaishali Kulkarni 		case IOC_INVAL:
203114b24e2bSVaishali Kulkarni 			mutex_exit(&qede->drv_lock);
203214b24e2bSVaishali Kulkarni 			//miocack(wq, mp, 0, 0);
203314b24e2bSVaishali Kulkarni 			miocnak(wq, mp, 0, iocp->ioc_error == 0 ?
203414b24e2bSVaishali Kulkarni 			    EINVAL : iocp->ioc_error);
203514b24e2bSVaishali Kulkarni 			return;
203614b24e2bSVaishali Kulkarni 	}
203714b24e2bSVaishali Kulkarni 	mutex_exit(&qede->drv_lock);
203814b24e2bSVaishali Kulkarni }
203914b24e2bSVaishali Kulkarni 
204014b24e2bSVaishali Kulkarni extern ddi_dma_attr_t qede_buf2k_dma_attr_txbuf;
204114b24e2bSVaishali Kulkarni extern ddi_dma_attr_t qede_dma_attr_rxbuf;
204214b24e2bSVaishali Kulkarni extern ddi_dma_attr_t qede_dma_attr_desc;
204314b24e2bSVaishali Kulkarni 
204414b24e2bSVaishali Kulkarni static boolean_t
204514b24e2bSVaishali Kulkarni qede_mac_get_capability(void *arg,
204614b24e2bSVaishali Kulkarni 	mac_capab_t capability,
204714b24e2bSVaishali Kulkarni 	void *      cap_data)
204814b24e2bSVaishali Kulkarni {
204914b24e2bSVaishali Kulkarni  	qede_t * qede = (qede_t *)arg;
205014b24e2bSVaishali Kulkarni 	uint32_t *txflags = cap_data;
205114b24e2bSVaishali Kulkarni 	boolean_t ret = B_FALSE;
205214b24e2bSVaishali Kulkarni 
205314b24e2bSVaishali Kulkarni 	switch (capability) {
205414b24e2bSVaishali Kulkarni 	case MAC_CAPAB_HCKSUM: {
205514b24e2bSVaishali Kulkarni 		u32 *tx_flags = cap_data;
205614b24e2bSVaishali Kulkarni 		/*
205714b24e2bSVaishali Kulkarni 		 * Check if checksum is enabled on
205814b24e2bSVaishali Kulkarni 		 * tx and advertise the cksum capab
205914b24e2bSVaishali Kulkarni 		 * to mac layer accordingly. On Rx
206014b24e2bSVaishali Kulkarni 		 * side checksummed packets are
206114b24e2bSVaishali Kulkarni 		 * reveiced anyway
206214b24e2bSVaishali Kulkarni 		 */
206314b24e2bSVaishali Kulkarni 		qede_info(qede, "%s tx checksum offload",
206414b24e2bSVaishali Kulkarni 		    (qede->checksum == DEFAULT_CKSUM_OFFLOAD) ?
206514b24e2bSVaishali Kulkarni 		    "Enabling":
206614b24e2bSVaishali Kulkarni 		    "Disabling");
206714b24e2bSVaishali Kulkarni 
206814b24e2bSVaishali Kulkarni 		if (qede->checksum != DEFAULT_CKSUM_OFFLOAD) {
206914b24e2bSVaishali Kulkarni 			ret = B_FALSE;
207014b24e2bSVaishali Kulkarni 			break;
207114b24e2bSVaishali Kulkarni 		}
207214b24e2bSVaishali Kulkarni                 /*
207314b24e2bSVaishali Kulkarni                  * Hardware does not support ICMPv6 checksumming. Right now the
207414b24e2bSVaishali Kulkarni                  * GLDv3 doesn't provide us a way to specify that we don't
207514b24e2bSVaishali Kulkarni                  * support that. As such, we cannot indicate
207614b24e2bSVaishali Kulkarni                  * HCKSUM_INET_FULL_V6.
207714b24e2bSVaishali Kulkarni                  */
207814b24e2bSVaishali Kulkarni 
207914b24e2bSVaishali Kulkarni 		*tx_flags = HCKSUM_INET_FULL_V4 |
208014b24e2bSVaishali Kulkarni 		    HCKSUM_IPHDRCKSUM;
208114b24e2bSVaishali Kulkarni 		ret = B_TRUE;
208214b24e2bSVaishali Kulkarni 		break;
208314b24e2bSVaishali Kulkarni 	}
208414b24e2bSVaishali Kulkarni 	case MAC_CAPAB_LSO: {
208514b24e2bSVaishali Kulkarni 		mac_capab_lso_t *cap_lso = (mac_capab_lso_t *)cap_data;
208614b24e2bSVaishali Kulkarni 
208714b24e2bSVaishali Kulkarni 		qede_info(qede, "%s large segmentation offload",
208814b24e2bSVaishali Kulkarni 		    qede->lso_enable ? "Enabling": "Disabling");
208914b24e2bSVaishali Kulkarni 		if (qede->lso_enable) {
209014b24e2bSVaishali Kulkarni 			cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4;
209114b24e2bSVaishali Kulkarni 			cap_lso->lso_basic_tcp_ipv4.lso_max = QEDE_LSO_MAXLEN;
209214b24e2bSVaishali Kulkarni 			ret = B_TRUE;
209314b24e2bSVaishali Kulkarni 		}
209414b24e2bSVaishali Kulkarni 		break;
209514b24e2bSVaishali Kulkarni 	}
209614b24e2bSVaishali Kulkarni 	case MAC_CAPAB_RINGS: {
209714b24e2bSVaishali Kulkarni #ifndef NO_CROSSBOW
209814b24e2bSVaishali Kulkarni 		mac_capab_rings_t *cap_rings = cap_data;
209914b24e2bSVaishali Kulkarni #ifndef ILLUMOS
210014b24e2bSVaishali Kulkarni 		cap_rings->mr_version = MAC_RINGS_VERSION_1;
210114b24e2bSVaishali Kulkarni #endif
210214b24e2bSVaishali Kulkarni 
210314b24e2bSVaishali Kulkarni 		switch (cap_rings->mr_type) {
210414b24e2bSVaishali Kulkarni 		case MAC_RING_TYPE_RX:
210514b24e2bSVaishali Kulkarni #ifndef ILLUMOS
210614b24e2bSVaishali Kulkarni 			cap_rings->mr_flags = MAC_RINGS_VLAN_TRANSPARENT;
210714b24e2bSVaishali Kulkarni #endif
210814b24e2bSVaishali Kulkarni 			cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
210914b24e2bSVaishali Kulkarni 			//cap_rings->mr_rnum = 1; /* qede variable */
211014b24e2bSVaishali Kulkarni 			cap_rings->mr_rnum = qede->num_fp; /* qede variable */
211114b24e2bSVaishali Kulkarni 			cap_rings->mr_gnum = 1;
211214b24e2bSVaishali Kulkarni 			cap_rings->mr_rget = qede_fill_ring;
211314b24e2bSVaishali Kulkarni 			cap_rings->mr_gget = qede_fill_group;
211414b24e2bSVaishali Kulkarni 			cap_rings->mr_gaddring = NULL;
211514b24e2bSVaishali Kulkarni 			cap_rings->mr_gremring = NULL;
211614b24e2bSVaishali Kulkarni #ifndef	ILLUMOS
211714b24e2bSVaishali Kulkarni 			cap_rings->mr_ggetringtc = NULL;
211814b24e2bSVaishali Kulkarni #endif
211914b24e2bSVaishali Kulkarni 			ret = B_TRUE;
212014b24e2bSVaishali Kulkarni 			break;
212114b24e2bSVaishali Kulkarni 		case MAC_RING_TYPE_TX:
212214b24e2bSVaishali Kulkarni #ifndef ILLUMOS
212314b24e2bSVaishali Kulkarni 			cap_rings->mr_flags = MAC_RINGS_VLAN_TRANSPARENT;
212414b24e2bSVaishali Kulkarni #endif
212514b24e2bSVaishali Kulkarni 			cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
212614b24e2bSVaishali Kulkarni 			//cap_rings->mr_rnum = 1;
212714b24e2bSVaishali Kulkarni 			cap_rings->mr_rnum = qede->num_fp;
212814b24e2bSVaishali Kulkarni 			cap_rings->mr_gnum = 0;
212914b24e2bSVaishali Kulkarni 			cap_rings->mr_rget = qede_fill_ring;
213014b24e2bSVaishali Kulkarni 			cap_rings->mr_gget = qede_fill_group;
213114b24e2bSVaishali Kulkarni 			cap_rings->mr_gaddring = NULL;
213214b24e2bSVaishali Kulkarni 			cap_rings->mr_gremring = NULL;
213314b24e2bSVaishali Kulkarni #ifndef	ILLUMOS
213414b24e2bSVaishali Kulkarni 			cap_rings->mr_ggetringtc = NULL;
213514b24e2bSVaishali Kulkarni #endif
213614b24e2bSVaishali Kulkarni 			ret = B_TRUE;
213714b24e2bSVaishali Kulkarni 			break;
213814b24e2bSVaishali Kulkarni 		default:
213914b24e2bSVaishali Kulkarni 			ret = B_FALSE;
214014b24e2bSVaishali Kulkarni 			break;
214114b24e2bSVaishali Kulkarni 		}
214214b24e2bSVaishali Kulkarni #endif
214314b24e2bSVaishali Kulkarni 		break; /* CASE MAC_CAPAB_RINGS */
214414b24e2bSVaishali Kulkarni 	}
214514b24e2bSVaishali Kulkarni #ifdef ILLUMOS
214614b24e2bSVaishali Kulkarni         case MAC_CAPAB_TRANSCEIVER: {
214714b24e2bSVaishali Kulkarni                 mac_capab_transceiver_t *mct = cap_data;
214814b24e2bSVaishali Kulkarni 
214914b24e2bSVaishali Kulkarni                 mct->mct_flags = 0;
215014b24e2bSVaishali Kulkarni                 mct->mct_ntransceivers = qede->edev.num_hwfns;
215114b24e2bSVaishali Kulkarni                 mct->mct_info = qede_transceiver_info;
215214b24e2bSVaishali Kulkarni                 mct->mct_read = qede_transceiver_read;
215314b24e2bSVaishali Kulkarni 
215414b24e2bSVaishali Kulkarni                 ret = B_TRUE;
215514b24e2bSVaishali Kulkarni                 break;
215614b24e2bSVaishali Kulkarni         }
215714b24e2bSVaishali Kulkarni #endif
215814b24e2bSVaishali Kulkarni 	default:
215914b24e2bSVaishali Kulkarni 		break;
216014b24e2bSVaishali Kulkarni 	}
216114b24e2bSVaishali Kulkarni 
216214b24e2bSVaishali Kulkarni     return (ret);
216314b24e2bSVaishali Kulkarni }
216414b24e2bSVaishali Kulkarni 
216514b24e2bSVaishali Kulkarni int
216614b24e2bSVaishali Kulkarni qede_configure_link(qede_t *qede, bool op);
216714b24e2bSVaishali Kulkarni 
216814b24e2bSVaishali Kulkarni static int
216914b24e2bSVaishali Kulkarni qede_mac_set_property(void *        arg,
217014b24e2bSVaishali Kulkarni                               const char *  pr_name,
217114b24e2bSVaishali Kulkarni                               mac_prop_id_t pr_num,
217214b24e2bSVaishali Kulkarni                               uint_t        pr_valsize,
217314b24e2bSVaishali Kulkarni                               const void *  pr_val)
217414b24e2bSVaishali Kulkarni {
217514b24e2bSVaishali Kulkarni 	qede_t * qede = (qede_t *)arg;
217614b24e2bSVaishali Kulkarni 	struct ecore_mcp_link_params *link_params;
217714b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
217814b24e2bSVaishali Kulkarni 	struct ecore_hwfn *hwfn;
217914b24e2bSVaishali Kulkarni 	int ret_val = 0, i;
218014b24e2bSVaishali Kulkarni 	uint32_t option;
218114b24e2bSVaishali Kulkarni 
218214b24e2bSVaishali Kulkarni 	mutex_enter(&qede->gld_lock);
218314b24e2bSVaishali Kulkarni 	switch (pr_num)
218414b24e2bSVaishali Kulkarni 	{
218514b24e2bSVaishali Kulkarni         case MAC_PROP_MTU:
218614b24e2bSVaishali Kulkarni                 bcopy(pr_val, &option, sizeof (option));
218714b24e2bSVaishali Kulkarni 
218814b24e2bSVaishali Kulkarni                 if(option == qede->mtu) {
218914b24e2bSVaishali Kulkarni                         ret_val = 0;
219014b24e2bSVaishali Kulkarni                         break;
219114b24e2bSVaishali Kulkarni                 }
219214b24e2bSVaishali Kulkarni                 if ((option != DEFAULT_JUMBO_MTU) &&
219314b24e2bSVaishali Kulkarni                    (option != DEFAULT_MTU)) {
219414b24e2bSVaishali Kulkarni                         ret_val = EINVAL;
219514b24e2bSVaishali Kulkarni                         break;
219614b24e2bSVaishali Kulkarni                 }
219714b24e2bSVaishali Kulkarni                 if(qede->qede_state == QEDE_STATE_STARTED) {
219814b24e2bSVaishali Kulkarni                         ret_val = EBUSY;
219914b24e2bSVaishali Kulkarni                         break;
220014b24e2bSVaishali Kulkarni                 }
220114b24e2bSVaishali Kulkarni 
220214b24e2bSVaishali Kulkarni                 ret_val = mac_maxsdu_update(qede->mac_handle, qede->mtu);
220314b24e2bSVaishali Kulkarni                 if (ret_val == 0) {
220414b24e2bSVaishali Kulkarni 
220514b24e2bSVaishali Kulkarni                         qede->mtu = option;
220614b24e2bSVaishali Kulkarni                         if (option == DEFAULT_JUMBO_MTU) {
220714b24e2bSVaishali Kulkarni                                 qede->jumbo_enable = B_TRUE;
220814b24e2bSVaishali Kulkarni 			} else {
220914b24e2bSVaishali Kulkarni 				qede->jumbo_enable = B_FALSE;
221014b24e2bSVaishali Kulkarni 			}
221114b24e2bSVaishali Kulkarni 
221214b24e2bSVaishali Kulkarni                         hwfn = ECORE_LEADING_HWFN(edev);
221314b24e2bSVaishali Kulkarni                         hwfn->hw_info.mtu = qede->mtu;
221414b24e2bSVaishali Kulkarni                         ret_val = ecore_mcp_ov_update_mtu(hwfn,
221514b24e2bSVaishali Kulkarni 			    hwfn->p_main_ptt,
221614b24e2bSVaishali Kulkarni 			    hwfn->hw_info.mtu);
221714b24e2bSVaishali Kulkarni                         if (ret_val != ECORE_SUCCESS) {
221814b24e2bSVaishali Kulkarni                                 qede_print("!%s(%d): MTU change %d option %d"
221914b24e2bSVaishali Kulkarni 				    "FAILED",
222014b24e2bSVaishali Kulkarni 				    __func__,qede->instance, qede->mtu, option);
222114b24e2bSVaishali Kulkarni 				break;
222214b24e2bSVaishali Kulkarni 			}
222314b24e2bSVaishali Kulkarni                         qede_print("!%s(%d): MTU changed  %d MTU option"
222414b24e2bSVaishali Kulkarni 			    " %d hwfn %d",
222514b24e2bSVaishali Kulkarni 			    __func__,qede->instance, qede->mtu,
222614b24e2bSVaishali Kulkarni 			    option, hwfn->hw_info.mtu);
222714b24e2bSVaishali Kulkarni                 }
222814b24e2bSVaishali Kulkarni                 break;
222914b24e2bSVaishali Kulkarni 
223014b24e2bSVaishali Kulkarni 	case MAC_PROP_EN_10GFDX_CAP:
223114b24e2bSVaishali Kulkarni 		hwfn = &edev->hwfns[0];
223214b24e2bSVaishali Kulkarni 		link_params = ecore_mcp_get_link_params(hwfn);
223314b24e2bSVaishali Kulkarni 		if (*(uint8_t *) pr_val) {
223414b24e2bSVaishali Kulkarni 			link_params->speed.autoneg = 0;
223514b24e2bSVaishali Kulkarni 			link_params->speed.forced_speed = 10000;
223614b24e2bSVaishali Kulkarni 			link_params->speed.advertised_speeds =
223714b24e2bSVaishali Kulkarni 			    NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
223814b24e2bSVaishali Kulkarni 			qede->forced_speed_10G = *(uint8_t *)pr_val;
223914b24e2bSVaishali Kulkarni 		}
224014b24e2bSVaishali Kulkarni 		else {
224114b24e2bSVaishali Kulkarni 			memcpy(link_params,
224214b24e2bSVaishali Kulkarni 			    &qede->link_input_params.default_link_params,
224314b24e2bSVaishali Kulkarni 			    sizeof (struct ecore_mcp_link_params));
224414b24e2bSVaishali Kulkarni 			qede->forced_speed_10G = *(uint8_t *)pr_val;
224514b24e2bSVaishali Kulkarni 		}
224614b24e2bSVaishali Kulkarni 		if (qede->qede_state == QEDE_STATE_STARTED) {
224714b24e2bSVaishali Kulkarni 			qede_configure_link(qede,1);
224814b24e2bSVaishali Kulkarni 		} else {
224914b24e2bSVaishali Kulkarni 			mutex_exit(&qede->gld_lock);
225014b24e2bSVaishali Kulkarni 			return (0);
225114b24e2bSVaishali Kulkarni 		}
225214b24e2bSVaishali Kulkarni 		break;
225314b24e2bSVaishali Kulkarni 	default:
225414b24e2bSVaishali Kulkarni 		ret_val = ENOTSUP;
225514b24e2bSVaishali Kulkarni 		break;
225614b24e2bSVaishali Kulkarni 	}
225714b24e2bSVaishali Kulkarni 	mutex_exit(&qede->gld_lock);
225814b24e2bSVaishali Kulkarni 	return (ret_val);
225914b24e2bSVaishali Kulkarni }
226014b24e2bSVaishali Kulkarni 
226114b24e2bSVaishali Kulkarni static void
226214b24e2bSVaishali Kulkarni qede_mac_stop(void *arg)
226314b24e2bSVaishali Kulkarni {
226414b24e2bSVaishali Kulkarni     qede_t *qede = (qede_t *)arg;
226514b24e2bSVaishali Kulkarni 	int status;
226614b24e2bSVaishali Kulkarni 
226714b24e2bSVaishali Kulkarni 	qede_print("!%s(%d): called",
226814b24e2bSVaishali Kulkarni 	    __func__,qede->instance);
226914b24e2bSVaishali Kulkarni 	mutex_enter(&qede->drv_lock);
227014b24e2bSVaishali Kulkarni 	status = qede_stop(qede);
227114b24e2bSVaishali Kulkarni 	if (status != DDI_SUCCESS) {
227214b24e2bSVaishali Kulkarni 		qede_print("!%s(%d): qede_stop "
227314b24e2bSVaishali Kulkarni 		    "FAILED",
227414b24e2bSVaishali Kulkarni 	        __func__,qede->instance);
227514b24e2bSVaishali Kulkarni 	}
227614b24e2bSVaishali Kulkarni 
227714b24e2bSVaishali Kulkarni 	mac_link_update(qede->mac_handle, LINK_STATE_UNKNOWN);
227814b24e2bSVaishali Kulkarni 	mutex_exit(&qede->drv_lock);
227914b24e2bSVaishali Kulkarni }
228014b24e2bSVaishali Kulkarni 
228114b24e2bSVaishali Kulkarni static int
228214b24e2bSVaishali Kulkarni qede_mac_start(void *arg)
228314b24e2bSVaishali Kulkarni {
228414b24e2bSVaishali Kulkarni     	qede_t *qede = (qede_t *)arg;
228514b24e2bSVaishali Kulkarni 	int status;
228614b24e2bSVaishali Kulkarni 
228714b24e2bSVaishali Kulkarni 	qede_print("!%s(%d): called", __func__,qede->instance);
228814b24e2bSVaishali Kulkarni 	if (!mutex_tryenter(&qede->drv_lock)) {
228914b24e2bSVaishali Kulkarni 		return (EAGAIN);
229014b24e2bSVaishali Kulkarni 	}
229114b24e2bSVaishali Kulkarni 
229214b24e2bSVaishali Kulkarni 	if (qede->qede_state == QEDE_STATE_SUSPENDED) {
229314b24e2bSVaishali Kulkarni 		mutex_exit(&qede->drv_lock);
229414b24e2bSVaishali Kulkarni 		return (ECANCELED);
229514b24e2bSVaishali Kulkarni 	}
229614b24e2bSVaishali Kulkarni 
229714b24e2bSVaishali Kulkarni 	status = qede_start(qede);
229814b24e2bSVaishali Kulkarni 	if (status != DDI_SUCCESS) {
229914b24e2bSVaishali Kulkarni 		mutex_exit(&qede->drv_lock);
230014b24e2bSVaishali Kulkarni 		return (EIO);
230114b24e2bSVaishali Kulkarni 	}
230214b24e2bSVaishali Kulkarni 
230314b24e2bSVaishali Kulkarni 	mutex_exit(&qede->drv_lock);
230414b24e2bSVaishali Kulkarni 
230514b24e2bSVaishali Kulkarni #ifdef	DBLK_DMA_PREMAP
230614b24e2bSVaishali Kulkarni 	qede->pm_handle = mac_pmh_tx_get(qede->mac_handle);
230714b24e2bSVaishali Kulkarni #endif
230814b24e2bSVaishali Kulkarni 	return (0);
230914b24e2bSVaishali Kulkarni }
231014b24e2bSVaishali Kulkarni 
231114b24e2bSVaishali Kulkarni static int
231214b24e2bSVaishali Kulkarni qede_mac_get_property(void *arg,
231314b24e2bSVaishali Kulkarni     const char *pr_name,
231414b24e2bSVaishali Kulkarni     mac_prop_id_t pr_num,
231514b24e2bSVaishali Kulkarni     uint_t        pr_valsize,
231614b24e2bSVaishali Kulkarni     void *pr_val)
231714b24e2bSVaishali Kulkarni {
231814b24e2bSVaishali Kulkarni 	qede_t *qede = (qede_t *)arg;
231914b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
232014b24e2bSVaishali Kulkarni 	link_state_t    link_state;
232114b24e2bSVaishali Kulkarni 	link_duplex_t   link_duplex;
232214b24e2bSVaishali Kulkarni 	uint64_t        link_speed;
232314b24e2bSVaishali Kulkarni 	link_flowctrl_t link_flowctrl;
232414b24e2bSVaishali Kulkarni 	struct qede_link_cfg link_cfg;
232514b24e2bSVaishali Kulkarni 	qede_link_cfg_t  *hw_cfg  = &qede->hwinit;
232614b24e2bSVaishali Kulkarni 	int ret_val = 0;
232714b24e2bSVaishali Kulkarni 
232814b24e2bSVaishali Kulkarni 	memset(&link_cfg, 0, sizeof (struct qede_link_cfg));
232914b24e2bSVaishali Kulkarni 	qede_get_link_info(&edev->hwfns[0], &link_cfg);
233014b24e2bSVaishali Kulkarni 
233114b24e2bSVaishali Kulkarni 
233214b24e2bSVaishali Kulkarni 
233314b24e2bSVaishali Kulkarni 	switch (pr_num)
233414b24e2bSVaishali Kulkarni 	{
233514b24e2bSVaishali Kulkarni 	case MAC_PROP_MTU:
233614b24e2bSVaishali Kulkarni 
233714b24e2bSVaishali Kulkarni 		ASSERT(pr_valsize >= sizeof(uint32_t));
233814b24e2bSVaishali Kulkarni 		bcopy(&qede->mtu, pr_val, sizeof(uint32_t));
233914b24e2bSVaishali Kulkarni 		break;
234014b24e2bSVaishali Kulkarni 
234114b24e2bSVaishali Kulkarni 	case MAC_PROP_DUPLEX:
234214b24e2bSVaishali Kulkarni 
234314b24e2bSVaishali Kulkarni 		ASSERT(pr_valsize >= sizeof(link_duplex_t));
234414b24e2bSVaishali Kulkarni 		link_duplex = (qede->props.link_duplex) ?
234514b24e2bSVaishali Kulkarni 					  LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
234614b24e2bSVaishali Kulkarni 		bcopy(&link_duplex, pr_val, sizeof(link_duplex_t));
234714b24e2bSVaishali Kulkarni 		break;
234814b24e2bSVaishali Kulkarni 
234914b24e2bSVaishali Kulkarni 	case MAC_PROP_SPEED:
235014b24e2bSVaishali Kulkarni 
235114b24e2bSVaishali Kulkarni 		ASSERT(pr_valsize >= sizeof(link_speed));
235214b24e2bSVaishali Kulkarni 
235314b24e2bSVaishali Kulkarni 		link_speed = (qede->props.link_speed * 1000000ULL);
235414b24e2bSVaishali Kulkarni 		bcopy(&link_speed, pr_val, sizeof(link_speed));
235514b24e2bSVaishali Kulkarni 	    	break;
235614b24e2bSVaishali Kulkarni 
235714b24e2bSVaishali Kulkarni 	case MAC_PROP_STATUS:
235814b24e2bSVaishali Kulkarni 
235914b24e2bSVaishali Kulkarni 		ASSERT(pr_valsize >= sizeof(link_state_t));
236014b24e2bSVaishali Kulkarni 
236114b24e2bSVaishali Kulkarni 		link_state = (qede->params.link_state) ?
236214b24e2bSVaishali Kulkarni 		                        LINK_STATE_UP : LINK_STATE_DOWN;
236314b24e2bSVaishali Kulkarni 		bcopy(&link_state, pr_val, sizeof(link_state_t));
236414b24e2bSVaishali Kulkarni 		qede_info(qede, "mac_prop_status %d\n", link_state);
236514b24e2bSVaishali Kulkarni 		break;
236614b24e2bSVaishali Kulkarni 
236714b24e2bSVaishali Kulkarni 	case MAC_PROP_AUTONEG:
236814b24e2bSVaishali Kulkarni 
236914b24e2bSVaishali Kulkarni 		*(uint8_t *)pr_val = link_cfg.autoneg;
237014b24e2bSVaishali Kulkarni 		break;
237114b24e2bSVaishali Kulkarni 
237214b24e2bSVaishali Kulkarni 	case MAC_PROP_FLOWCTRL:
237314b24e2bSVaishali Kulkarni 
237414b24e2bSVaishali Kulkarni 		ASSERT(pr_valsize >= sizeof(link_flowctrl_t));
237514b24e2bSVaishali Kulkarni 
237614b24e2bSVaishali Kulkarni /*
237714b24e2bSVaishali Kulkarni  * illumos does not have the notion of LINK_FLOWCTRL_AUTO at this time.
237814b24e2bSVaishali Kulkarni  */
237914b24e2bSVaishali Kulkarni #ifndef	ILLUMOS
238014b24e2bSVaishali Kulkarni 		if (link_cfg.pause_cfg & QEDE_LINK_PAUSE_AUTONEG_ENABLE)  {
238114b24e2bSVaishali Kulkarni 	            link_flowctrl = LINK_FLOWCTRL_AUTO;
238214b24e2bSVaishali Kulkarni 		}
238314b24e2bSVaishali Kulkarni #endif
238414b24e2bSVaishali Kulkarni 
238514b24e2bSVaishali Kulkarni 		if (!(link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) &&
238614b24e2bSVaishali Kulkarni 		    !(link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) {
238714b24e2bSVaishali Kulkarni 	            link_flowctrl = LINK_FLOWCTRL_NONE;
238814b24e2bSVaishali Kulkarni 		}
238914b24e2bSVaishali Kulkarni 		if ((link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) &&
239014b24e2bSVaishali Kulkarni 		    !(link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) {
239114b24e2bSVaishali Kulkarni 	            link_flowctrl = LINK_FLOWCTRL_RX;
239214b24e2bSVaishali Kulkarni 	    	}
239314b24e2bSVaishali Kulkarni         	if (!(link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) &&
239414b24e2bSVaishali Kulkarni 		    (link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) {
239514b24e2bSVaishali Kulkarni 	            link_flowctrl = LINK_FLOWCTRL_TX;
239614b24e2bSVaishali Kulkarni 		}
239714b24e2bSVaishali Kulkarni 		if ((link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) &&
239814b24e2bSVaishali Kulkarni 		    (link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) {
239914b24e2bSVaishali Kulkarni 	            link_flowctrl = LINK_FLOWCTRL_BI;
240014b24e2bSVaishali Kulkarni 		}
240114b24e2bSVaishali Kulkarni 
240214b24e2bSVaishali Kulkarni         	bcopy(&link_flowctrl, pr_val, sizeof (link_flowctrl_t));
240314b24e2bSVaishali Kulkarni         	break;
240414b24e2bSVaishali Kulkarni 
240514b24e2bSVaishali Kulkarni 	case MAC_PROP_ADV_10GFDX_CAP:
240614b24e2bSVaishali Kulkarni 		*(uint8_t *)pr_val = link_cfg.adv_capab.param_10000fdx;
240714b24e2bSVaishali Kulkarni 		break;
240814b24e2bSVaishali Kulkarni 
240914b24e2bSVaishali Kulkarni 	case MAC_PROP_EN_10GFDX_CAP:
241014b24e2bSVaishali Kulkarni 		*(uint8_t *)pr_val = qede->forced_speed_10G;
241114b24e2bSVaishali Kulkarni 		break;
241214b24e2bSVaishali Kulkarni 
241314b24e2bSVaishali Kulkarni 	case MAC_PROP_PRIVATE:
241414b24e2bSVaishali Kulkarni 	default:
241514b24e2bSVaishali Kulkarni 		return (ENOTSUP);
241614b24e2bSVaishali Kulkarni 
241714b24e2bSVaishali Kulkarni 	}
241814b24e2bSVaishali Kulkarni 
241914b24e2bSVaishali Kulkarni 	return (0);
242014b24e2bSVaishali Kulkarni }
242114b24e2bSVaishali Kulkarni 
242214b24e2bSVaishali Kulkarni static void
242314b24e2bSVaishali Kulkarni qede_mac_property_info(void *arg,
242414b24e2bSVaishali Kulkarni     const char *pr_name,
242514b24e2bSVaishali Kulkarni     mac_prop_id_t  pr_num,
242614b24e2bSVaishali Kulkarni     mac_prop_info_handle_t prh)
242714b24e2bSVaishali Kulkarni {
242814b24e2bSVaishali Kulkarni 	qede_t *qede = (qede_t *)arg;
242914b24e2bSVaishali Kulkarni 	qede_link_props_t *def_cfg = &qede_def_link_props;
243014b24e2bSVaishali Kulkarni 	link_flowctrl_t link_flowctrl;
243114b24e2bSVaishali Kulkarni 
243214b24e2bSVaishali Kulkarni 
243314b24e2bSVaishali Kulkarni 	switch (pr_num)
243414b24e2bSVaishali Kulkarni 	{
243514b24e2bSVaishali Kulkarni 
243614b24e2bSVaishali Kulkarni 	case MAC_PROP_STATUS:
243714b24e2bSVaishali Kulkarni 	case MAC_PROP_SPEED:
243814b24e2bSVaishali Kulkarni 	case MAC_PROP_DUPLEX:
243914b24e2bSVaishali Kulkarni 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
244014b24e2bSVaishali Kulkarni 		break;
244114b24e2bSVaishali Kulkarni 
244214b24e2bSVaishali Kulkarni 	case MAC_PROP_MTU:
244314b24e2bSVaishali Kulkarni 
244414b24e2bSVaishali Kulkarni 		mac_prop_info_set_range_uint32(prh,
244514b24e2bSVaishali Kulkarni 		    MIN_MTU,
244614b24e2bSVaishali Kulkarni 		    MAX_MTU);
244714b24e2bSVaishali Kulkarni 		break;
244814b24e2bSVaishali Kulkarni 
244914b24e2bSVaishali Kulkarni 	case MAC_PROP_AUTONEG:
245014b24e2bSVaishali Kulkarni 
245114b24e2bSVaishali Kulkarni 		mac_prop_info_set_default_uint8(prh, def_cfg->autoneg);
245214b24e2bSVaishali Kulkarni 		break;
245314b24e2bSVaishali Kulkarni 
245414b24e2bSVaishali Kulkarni 	case MAC_PROP_FLOWCTRL:
245514b24e2bSVaishali Kulkarni 
245614b24e2bSVaishali Kulkarni 		if (!def_cfg->pause) {
245714b24e2bSVaishali Kulkarni 			link_flowctrl = LINK_FLOWCTRL_NONE;
245814b24e2bSVaishali Kulkarni 		} else {
245914b24e2bSVaishali Kulkarni 			link_flowctrl = LINK_FLOWCTRL_BI;
246014b24e2bSVaishali Kulkarni 		}
246114b24e2bSVaishali Kulkarni 
246214b24e2bSVaishali Kulkarni 		mac_prop_info_set_default_link_flowctrl(prh, link_flowctrl);
246314b24e2bSVaishali Kulkarni 		break;
246414b24e2bSVaishali Kulkarni 
246514b24e2bSVaishali Kulkarni 	case MAC_PROP_EN_10GFDX_CAP:
246614b24e2bSVaishali Kulkarni 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW);
246714b24e2bSVaishali Kulkarni 		break;
246814b24e2bSVaishali Kulkarni 
246914b24e2bSVaishali Kulkarni 	case MAC_PROP_ADV_10GFDX_CAP:
247014b24e2bSVaishali Kulkarni 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
247114b24e2bSVaishali Kulkarni 		break;
247214b24e2bSVaishali Kulkarni 
247314b24e2bSVaishali Kulkarni 	default:
247414b24e2bSVaishali Kulkarni 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
247514b24e2bSVaishali Kulkarni 		break;
247614b24e2bSVaishali Kulkarni 
247714b24e2bSVaishali Kulkarni     }
247814b24e2bSVaishali Kulkarni }
247914b24e2bSVaishali Kulkarni 
248014b24e2bSVaishali Kulkarni static mac_callbacks_t qede_callbacks =
248114b24e2bSVaishali Kulkarni {
248214b24e2bSVaishali Kulkarni     (
248314b24e2bSVaishali Kulkarni       MC_IOCTL
248414b24e2bSVaishali Kulkarni /*    | MC_RESOURCES */
248514b24e2bSVaishali Kulkarni     | MC_SETPROP
248614b24e2bSVaishali Kulkarni     | MC_GETPROP
248714b24e2bSVaishali Kulkarni     | MC_PROPINFO
248814b24e2bSVaishali Kulkarni     | MC_GETCAPAB
248914b24e2bSVaishali Kulkarni     ),
249014b24e2bSVaishali Kulkarni     qede_mac_stats,
249114b24e2bSVaishali Kulkarni     qede_mac_start,
249214b24e2bSVaishali Kulkarni     qede_mac_stop,
249314b24e2bSVaishali Kulkarni     qede_mac_promiscuous,
249414b24e2bSVaishali Kulkarni     qede_mac_multicast,
249514b24e2bSVaishali Kulkarni     NULL,
249614b24e2bSVaishali Kulkarni #ifndef NO_CROSSBOW
249714b24e2bSVaishali Kulkarni     NULL,
249814b24e2bSVaishali Kulkarni #else
249914b24e2bSVaishali Kulkarni     qede_mac_tx,
250014b24e2bSVaishali Kulkarni #endif
250114b24e2bSVaishali Kulkarni     NULL,	/* qede_mac_resources, */
250214b24e2bSVaishali Kulkarni     qede_mac_ioctl,
250314b24e2bSVaishali Kulkarni     qede_mac_get_capability,
250414b24e2bSVaishali Kulkarni     NULL,
250514b24e2bSVaishali Kulkarni     NULL,
250614b24e2bSVaishali Kulkarni     qede_mac_set_property,
250714b24e2bSVaishali Kulkarni     qede_mac_get_property,
250814b24e2bSVaishali Kulkarni #ifdef MC_PROPINFO
250914b24e2bSVaishali Kulkarni     qede_mac_property_info
251014b24e2bSVaishali Kulkarni #endif
251114b24e2bSVaishali Kulkarni };
251214b24e2bSVaishali Kulkarni 
251314b24e2bSVaishali Kulkarni boolean_t
251414b24e2bSVaishali Kulkarni qede_gld_init(qede_t *qede)
251514b24e2bSVaishali Kulkarni {
251614b24e2bSVaishali Kulkarni 	int status, ret;
251714b24e2bSVaishali Kulkarni 	mac_register_t *macp;
251814b24e2bSVaishali Kulkarni 
251914b24e2bSVaishali Kulkarni 	macp = mac_alloc(MAC_VERSION);
252014b24e2bSVaishali Kulkarni 	if (macp == NULL) {
252114b24e2bSVaishali Kulkarni 		cmn_err(CE_NOTE, "%s: mac_alloc() failed\n", __func__);
252214b24e2bSVaishali Kulkarni 		return (B_FALSE);
252314b24e2bSVaishali Kulkarni 	}
252414b24e2bSVaishali Kulkarni 
252514b24e2bSVaishali Kulkarni  	macp->m_driver = qede;
252614b24e2bSVaishali Kulkarni 	macp->m_dip = qede->dip;
252714b24e2bSVaishali Kulkarni 	macp->m_instance = qede->instance;
252814b24e2bSVaishali Kulkarni 	macp->m_priv_props = NULL;
252914b24e2bSVaishali Kulkarni 	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
253014b24e2bSVaishali Kulkarni  	macp->m_src_addr = qede->ether_addr;
253114b24e2bSVaishali Kulkarni 	macp->m_callbacks = &qede_callbacks;
253214b24e2bSVaishali Kulkarni 	macp->m_min_sdu = 0;
253314b24e2bSVaishali Kulkarni 	macp->m_max_sdu = qede->mtu;
253414b24e2bSVaishali Kulkarni 	macp->m_margin = VLAN_TAGSZ;
253514b24e2bSVaishali Kulkarni #ifdef	ILLUMOS
253614b24e2bSVaishali Kulkarni 	macp->m_v12n = MAC_VIRT_LEVEL1;
253714b24e2bSVaishali Kulkarni #endif
253814b24e2bSVaishali Kulkarni 
253914b24e2bSVaishali Kulkarni 	status = mac_register(macp, &qede->mac_handle);
254014b24e2bSVaishali Kulkarni 	if (status != 0) {
254114b24e2bSVaishali Kulkarni 		cmn_err(CE_NOTE, "%s: mac_register() failed\n", __func__);
254214b24e2bSVaishali Kulkarni 	}
254314b24e2bSVaishali Kulkarni 
254414b24e2bSVaishali Kulkarni 	mac_free(macp);
254514b24e2bSVaishali Kulkarni 	if (status == 0) {
254614b24e2bSVaishali Kulkarni 		return (B_TRUE);
254714b24e2bSVaishali Kulkarni 	}
254814b24e2bSVaishali Kulkarni 	return (B_FALSE);
254914b24e2bSVaishali Kulkarni }
255014b24e2bSVaishali Kulkarni 
255114b24e2bSVaishali Kulkarni boolean_t qede_gld_fini(qede_t * qede)
255214b24e2bSVaishali Kulkarni {
255314b24e2bSVaishali Kulkarni     return (B_TRUE);
255414b24e2bSVaishali Kulkarni }
255514b24e2bSVaishali Kulkarni 
255614b24e2bSVaishali Kulkarni 
255714b24e2bSVaishali Kulkarni void qede_link_update(qede_t * qede,
255814b24e2bSVaishali Kulkarni                  link_state_t  state)
255914b24e2bSVaishali Kulkarni {
256014b24e2bSVaishali Kulkarni     mac_link_update(qede->mac_handle, state);
256114b24e2bSVaishali Kulkarni }
256214b24e2bSVaishali Kulkarni 
2563