xref: /illumos-gate/usr/src/uts/common/io/qede/qede_gld.c (revision 14b24e2b)
1*14b24e2bSVaishali Kulkarni /*
2*14b24e2bSVaishali Kulkarni * CDDL HEADER START
3*14b24e2bSVaishali Kulkarni *
4*14b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the
5*14b24e2bSVaishali Kulkarni * Common Development and Distribution License, v.1,  (the "License").
6*14b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License.
7*14b24e2bSVaishali Kulkarni *
8*14b24e2bSVaishali Kulkarni * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*14b24e2bSVaishali Kulkarni * or http://opensource.org/licenses/CDDL-1.0.
10*14b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions
11*14b24e2bSVaishali Kulkarni * and limitations under the License.
12*14b24e2bSVaishali Kulkarni *
13*14b24e2bSVaishali Kulkarni * When distributing Covered Code, include this CDDL HEADER in each
14*14b24e2bSVaishali Kulkarni * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*14b24e2bSVaishali Kulkarni * If applicable, add the following below this CDDL HEADER, with the
16*14b24e2bSVaishali Kulkarni * fields enclosed by brackets "[]" replaced with your own identifying
17*14b24e2bSVaishali Kulkarni * information: Portions Copyright [yyyy] [name of copyright owner]
18*14b24e2bSVaishali Kulkarni *
19*14b24e2bSVaishali Kulkarni * CDDL HEADER END
20*14b24e2bSVaishali Kulkarni */
21*14b24e2bSVaishali Kulkarni 
22*14b24e2bSVaishali Kulkarni /*
23*14b24e2bSVaishali Kulkarni * Copyright 2014-2017 Cavium, Inc.
24*14b24e2bSVaishali Kulkarni * The contents of this file are subject to the terms of the Common Development
25*14b24e2bSVaishali Kulkarni * and Distribution License, v.1,  (the "License").
26*14b24e2bSVaishali Kulkarni 
27*14b24e2bSVaishali Kulkarni * You may not use this file except in compliance with the License.
28*14b24e2bSVaishali Kulkarni 
29*14b24e2bSVaishali Kulkarni * You can obtain a copy of the License at available
30*14b24e2bSVaishali Kulkarni * at http://opensource.org/licenses/CDDL-1.0
31*14b24e2bSVaishali Kulkarni 
32*14b24e2bSVaishali Kulkarni * See the License for the specific language governing permissions and
33*14b24e2bSVaishali Kulkarni * limitations under the License.
34*14b24e2bSVaishali Kulkarni */
35*14b24e2bSVaishali Kulkarni 
36*14b24e2bSVaishali Kulkarni 
37*14b24e2bSVaishali Kulkarni #include "qede.h"
38*14b24e2bSVaishali Kulkarni 
39*14b24e2bSVaishali Kulkarni #define	FP_LOCK(ptr)	\
40*14b24e2bSVaishali Kulkarni mutex_enter(&ptr->fp_lock);
41*14b24e2bSVaishali Kulkarni #define	FP_UNLOCK(ptr)	\
42*14b24e2bSVaishali Kulkarni mutex_exit(&ptr->fp_lock);
43*14b24e2bSVaishali Kulkarni 
44*14b24e2bSVaishali Kulkarni int
45*14b24e2bSVaishali Kulkarni qede_ucst_find(qede_t *qede, const uint8_t *mac_addr)
46*14b24e2bSVaishali Kulkarni {
47*14b24e2bSVaishali Kulkarni 	int slot;
48*14b24e2bSVaishali Kulkarni 
49*14b24e2bSVaishali Kulkarni 	for(slot = 0; slot < qede->ucst_total; slot++) {
50*14b24e2bSVaishali Kulkarni 		if (bcmp(qede->ucst_mac[slot].mac_addr.ether_addr_octet,
51*14b24e2bSVaishali Kulkarni 		    mac_addr, ETHERADDRL) == 0) {
52*14b24e2bSVaishali Kulkarni 			return (slot);
53*14b24e2bSVaishali Kulkarni 		}
54*14b24e2bSVaishali Kulkarni 	}
55*14b24e2bSVaishali Kulkarni 	return (-1);
56*14b24e2bSVaishali Kulkarni 
57*14b24e2bSVaishali Kulkarni }
58*14b24e2bSVaishali Kulkarni 
59*14b24e2bSVaishali Kulkarni static int
60*14b24e2bSVaishali Kulkarni qede_set_mac_addr(qede_t *qede, uint8_t *mac_addr, uint8_t fl)
61*14b24e2bSVaishali Kulkarni {
62*14b24e2bSVaishali Kulkarni 	struct ecore_filter_ucast params;
63*14b24e2bSVaishali Kulkarni 
64*14b24e2bSVaishali Kulkarni 	memset(&params, 0, sizeof (params));
65*14b24e2bSVaishali Kulkarni 
66*14b24e2bSVaishali Kulkarni 	params.opcode = fl;
67*14b24e2bSVaishali Kulkarni 	params.type = ECORE_FILTER_MAC;
68*14b24e2bSVaishali Kulkarni 	params.is_rx_filter = true;
69*14b24e2bSVaishali Kulkarni 	params.is_tx_filter = true;
70*14b24e2bSVaishali Kulkarni 	COPY_ETH_ADDRESS(mac_addr, params.mac);
71*14b24e2bSVaishali Kulkarni 
72*14b24e2bSVaishali Kulkarni 	return (ecore_filter_ucast_cmd(&qede->edev,
73*14b24e2bSVaishali Kulkarni 	    &params, ECORE_SPQ_MODE_EBLOCK, NULL));
74*14b24e2bSVaishali Kulkarni 
75*14b24e2bSVaishali Kulkarni 
76*14b24e2bSVaishali Kulkarni }
77*14b24e2bSVaishali Kulkarni static int
78*14b24e2bSVaishali Kulkarni qede_add_macaddr(qede_t *qede, uint8_t *mac_addr)
79*14b24e2bSVaishali Kulkarni {
80*14b24e2bSVaishali Kulkarni 	int i, ret = 0;
81*14b24e2bSVaishali Kulkarni 
82*14b24e2bSVaishali Kulkarni 	i = qede_ucst_find(qede, mac_addr);
83*14b24e2bSVaishali Kulkarni 	if (i != -1) {
84*14b24e2bSVaishali Kulkarni 		/* LINTED E_ARGUMENT_MISMATCH */
85*14b24e2bSVaishali Kulkarni 		qede_info(qede, "mac addr already added %d\n",
86*14b24e2bSVaishali Kulkarni 		    qede->ucst_avail);
87*14b24e2bSVaishali Kulkarni 		return (0);
88*14b24e2bSVaishali Kulkarni 	}
89*14b24e2bSVaishali Kulkarni 	if (qede->ucst_avail == 0) {
90*14b24e2bSVaishali Kulkarni 		qede_info(qede, "add macaddr ignored \n");
91*14b24e2bSVaishali Kulkarni 		return (ENOSPC);
92*14b24e2bSVaishali Kulkarni 	}
93*14b24e2bSVaishali Kulkarni 	for (i = 0; i < qede->ucst_total; i++) {
94*14b24e2bSVaishali Kulkarni 		if (qede->ucst_mac[i].set == 0) {
95*14b24e2bSVaishali Kulkarni 			break;
96*14b24e2bSVaishali Kulkarni 		}
97*14b24e2bSVaishali Kulkarni 	}
98*14b24e2bSVaishali Kulkarni 	if (i >= qede->ucst_total) {
99*14b24e2bSVaishali Kulkarni 		qede_info(qede, "add macaddr ignored no space");
100*14b24e2bSVaishali Kulkarni 		return (ENOSPC);
101*14b24e2bSVaishali Kulkarni 	}
102*14b24e2bSVaishali Kulkarni 	ret = qede_set_mac_addr(qede, (uint8_t *)mac_addr, ECORE_FILTER_ADD);
103*14b24e2bSVaishali Kulkarni 	if (ret == 0) {
104*14b24e2bSVaishali Kulkarni 		bcopy(mac_addr,
105*14b24e2bSVaishali Kulkarni 		    qede->ucst_mac[i].mac_addr.ether_addr_octet,
106*14b24e2bSVaishali Kulkarni 		    ETHERADDRL);
107*14b24e2bSVaishali Kulkarni 		qede->ucst_mac[i].set = 1;
108*14b24e2bSVaishali Kulkarni 		qede->ucst_avail--;
109*14b24e2bSVaishali Kulkarni 		/* LINTED E_ARGUMENT_MISMATCH */
110*14b24e2bSVaishali Kulkarni 		qede_info(qede,  " add macaddr passed for addr "
111*14b24e2bSVaishali Kulkarni 		    "%02x:%02x:%02x:%02x:%02x:%02x",
112*14b24e2bSVaishali Kulkarni 		    mac_addr[0], mac_addr[1],
113*14b24e2bSVaishali Kulkarni 		    mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
114*14b24e2bSVaishali Kulkarni 	} else {
115*14b24e2bSVaishali Kulkarni 		/* LINTED E_ARGUMENT_MISMATCH */
116*14b24e2bSVaishali Kulkarni 		qede_info(qede,  "add macaddr failed for addr "
117*14b24e2bSVaishali Kulkarni 		    "%02x:%02x:%02x:%02x:%02x:%02x",
118*14b24e2bSVaishali Kulkarni 		    mac_addr[0], mac_addr[1],
119*14b24e2bSVaishali Kulkarni 		    mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
120*14b24e2bSVaishali Kulkarni 
121*14b24e2bSVaishali Kulkarni 	}
122*14b24e2bSVaishali Kulkarni 	if (qede->ucst_avail == (qede->ucst_total -1)) {
123*14b24e2bSVaishali Kulkarni 			u8 bcast_addr[] =
124*14b24e2bSVaishali Kulkarni 			{
125*14b24e2bSVaishali Kulkarni 				0xff, 0xff, 0xff, 0xff, 0xff,
126*14b24e2bSVaishali Kulkarni 				0xff
127*14b24e2bSVaishali Kulkarni 			};
128*14b24e2bSVaishali Kulkarni 			for (i = 0; i < qede->ucst_total; i++) {
129*14b24e2bSVaishali Kulkarni 				if (qede->ucst_mac[i].set == 0)
130*14b24e2bSVaishali Kulkarni 					break;
131*14b24e2bSVaishali Kulkarni 			}
132*14b24e2bSVaishali Kulkarni 			ret = qede_set_mac_addr(qede,
133*14b24e2bSVaishali Kulkarni 			    (uint8_t *)bcast_addr, ECORE_FILTER_ADD);
134*14b24e2bSVaishali Kulkarni 			if (ret == 0) {
135*14b24e2bSVaishali Kulkarni 				bcopy(bcast_addr,
136*14b24e2bSVaishali Kulkarni 				    qede->ucst_mac[i].mac_addr.ether_addr_octet,
137*14b24e2bSVaishali Kulkarni 				    ETHERADDRL);
138*14b24e2bSVaishali Kulkarni 				qede->ucst_mac[i].set = 1;
139*14b24e2bSVaishali Kulkarni 				qede->ucst_avail--;
140*14b24e2bSVaishali Kulkarni 			} else {
141*14b24e2bSVaishali Kulkarni 
142*14b24e2bSVaishali Kulkarni 			/* LINTED E_ARGUMENT_MISMATCH */
143*14b24e2bSVaishali Kulkarni 			qede_info(qede,  "add macaddr failed for addr "
144*14b24e2bSVaishali Kulkarni 			    "%02x:%02x:%02x:%02x:%02x:%02x",
145*14b24e2bSVaishali Kulkarni 		            mac_addr[0], mac_addr[1],
146*14b24e2bSVaishali Kulkarni 		            mac_addr[2], mac_addr[3], mac_addr[4],
147*14b24e2bSVaishali Kulkarni 			    mac_addr[5]);
148*14b24e2bSVaishali Kulkarni 		       }
149*14b24e2bSVaishali Kulkarni 
150*14b24e2bSVaishali Kulkarni 		}
151*14b24e2bSVaishali Kulkarni 
152*14b24e2bSVaishali Kulkarni 	return (ret);
153*14b24e2bSVaishali Kulkarni 
154*14b24e2bSVaishali Kulkarni }
155*14b24e2bSVaishali Kulkarni 
156*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS
157*14b24e2bSVaishali Kulkarni static int
158*14b24e2bSVaishali Kulkarni qede_add_mac_addr(void *arg, const uint8_t *mac_addr, const uint64_t flags)
159*14b24e2bSVaishali Kulkarni #else
160*14b24e2bSVaishali Kulkarni static int
161*14b24e2bSVaishali Kulkarni qede_add_mac_addr(void *arg, const uint8_t *mac_addr)
162*14b24e2bSVaishali Kulkarni #endif
163*14b24e2bSVaishali Kulkarni {
164*14b24e2bSVaishali Kulkarni 	qede_mac_group_t *rx_group = (qede_mac_group_t *)arg;
165*14b24e2bSVaishali Kulkarni 	qede_t *qede = rx_group->qede;
166*14b24e2bSVaishali Kulkarni 	int ret = DDI_SUCCESS;
167*14b24e2bSVaishali Kulkarni 
168*14b24e2bSVaishali Kulkarni 	/* LINTED E_ARGUMENT_MISMATCH */
169*14b24e2bSVaishali Kulkarni 	qede_info(qede, " mac addr :" MAC_STRING,  MACTOSTR(mac_addr));
170*14b24e2bSVaishali Kulkarni 
171*14b24e2bSVaishali Kulkarni 	mutex_enter(&qede->gld_lock);
172*14b24e2bSVaishali Kulkarni 	if (qede->qede_state == QEDE_STATE_SUSPENDED) {
173*14b24e2bSVaishali Kulkarni 		mutex_exit(&qede->gld_lock);
174*14b24e2bSVaishali Kulkarni 		return (ECANCELED);
175*14b24e2bSVaishali Kulkarni 	}
176*14b24e2bSVaishali Kulkarni 	ret = qede_add_macaddr(qede, (uint8_t *)mac_addr);
177*14b24e2bSVaishali Kulkarni 
178*14b24e2bSVaishali Kulkarni 	mutex_exit(&qede->gld_lock);
179*14b24e2bSVaishali Kulkarni 
180*14b24e2bSVaishali Kulkarni 
181*14b24e2bSVaishali Kulkarni 	return (ret);
182*14b24e2bSVaishali Kulkarni }
183*14b24e2bSVaishali Kulkarni 
184*14b24e2bSVaishali Kulkarni static int
185*14b24e2bSVaishali Kulkarni qede_rem_macaddr(qede_t *qede, uint8_t *mac_addr)
186*14b24e2bSVaishali Kulkarni {
187*14b24e2bSVaishali Kulkarni 	int ret = 0;
188*14b24e2bSVaishali Kulkarni 	int i;
189*14b24e2bSVaishali Kulkarni 
190*14b24e2bSVaishali Kulkarni 	i = qede_ucst_find(qede, mac_addr);
191*14b24e2bSVaishali Kulkarni 	if (i == -1) {
192*14b24e2bSVaishali Kulkarni 		/* LINTED E_ARGUMENT_MISMATCH */
193*14b24e2bSVaishali Kulkarni 		qede_info(qede,
194*14b24e2bSVaishali Kulkarni 		    "mac addr not there to remove",
195*14b24e2bSVaishali Kulkarni 		    MAC_STRING, MACTOSTR(mac_addr));
196*14b24e2bSVaishali Kulkarni 		return (0);
197*14b24e2bSVaishali Kulkarni 	}
198*14b24e2bSVaishali Kulkarni 	if (qede->ucst_mac[i].set == 0) {
199*14b24e2bSVaishali Kulkarni 	       	return (EINVAL);
200*14b24e2bSVaishali Kulkarni 	}
201*14b24e2bSVaishali Kulkarni 	ret = qede_set_mac_addr(qede, (uint8_t *)mac_addr, ECORE_FILTER_REMOVE);
202*14b24e2bSVaishali Kulkarni 	if (ret == 0) {
203*14b24e2bSVaishali Kulkarni 		bzero(qede->ucst_mac[i].mac_addr.ether_addr_octet,ETHERADDRL);
204*14b24e2bSVaishali Kulkarni 		qede->ucst_mac[i].set = 0;
205*14b24e2bSVaishali Kulkarni 		qede->ucst_avail++;
206*14b24e2bSVaishali Kulkarni 	} else {
207*14b24e2bSVaishali Kulkarni 		/* LINTED E_ARGUMENT_MISMATCH */
208*14b24e2bSVaishali Kulkarni 		qede_info(qede, "mac addr remove failed",
209*14b24e2bSVaishali Kulkarni 		    MAC_STRING, MACTOSTR(mac_addr));
210*14b24e2bSVaishali Kulkarni 	}
211*14b24e2bSVaishali Kulkarni 	return (ret);
212*14b24e2bSVaishali Kulkarni 
213*14b24e2bSVaishali Kulkarni }
214*14b24e2bSVaishali Kulkarni 
215*14b24e2bSVaishali Kulkarni 
216*14b24e2bSVaishali Kulkarni static int
217*14b24e2bSVaishali Kulkarni qede_rem_mac_addr(void *arg, const uint8_t *mac_addr)
218*14b24e2bSVaishali Kulkarni {
219*14b24e2bSVaishali Kulkarni 	qede_mac_group_t *rx_group = (qede_mac_group_t *)arg;
220*14b24e2bSVaishali Kulkarni 	qede_t *qede = rx_group->qede;
221*14b24e2bSVaishali Kulkarni 	int ret = DDI_SUCCESS;
222*14b24e2bSVaishali Kulkarni 
223*14b24e2bSVaishali Kulkarni 	/* LINTED E_ARGUMENT_MISMATCH */
224*14b24e2bSVaishali Kulkarni 	qede_info(qede, "mac addr remove:" MAC_STRING, MACTOSTR(mac_addr));
225*14b24e2bSVaishali Kulkarni 	mutex_enter(&qede->gld_lock);
226*14b24e2bSVaishali Kulkarni 	if (qede->qede_state == QEDE_STATE_SUSPENDED) {
227*14b24e2bSVaishali Kulkarni 		mutex_exit(&qede->gld_lock);
228*14b24e2bSVaishali Kulkarni 		return (ECANCELED);
229*14b24e2bSVaishali Kulkarni 	}
230*14b24e2bSVaishali Kulkarni 	ret = qede_rem_macaddr(qede, (uint8_t *)mac_addr);
231*14b24e2bSVaishali Kulkarni 	mutex_exit(&qede->gld_lock);
232*14b24e2bSVaishali Kulkarni 	return (ret);
233*14b24e2bSVaishali Kulkarni }
234*14b24e2bSVaishali Kulkarni 
235*14b24e2bSVaishali Kulkarni 
236*14b24e2bSVaishali Kulkarni static int
237*14b24e2bSVaishali Kulkarni qede_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
238*14b24e2bSVaishali Kulkarni {
239*14b24e2bSVaishali Kulkarni 	int ret = 0;
240*14b24e2bSVaishali Kulkarni 
241*14b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)rh;
242*14b24e2bSVaishali Kulkarni 	qede_tx_ring_t *tx_ring = fp->tx_ring[0];
243*14b24e2bSVaishali Kulkarni 	qede_t *qede = fp->qede;
244*14b24e2bSVaishali Kulkarni 
245*14b24e2bSVaishali Kulkarni 
246*14b24e2bSVaishali Kulkarni 	if (qede->qede_state == QEDE_STATE_SUSPENDED)
247*14b24e2bSVaishali Kulkarni 		return (ECANCELED);
248*14b24e2bSVaishali Kulkarni 
249*14b24e2bSVaishali Kulkarni 	switch (stat) {
250*14b24e2bSVaishali Kulkarni 	case MAC_STAT_OBYTES:
251*14b24e2bSVaishali Kulkarni 		*val = tx_ring->tx_byte_count;
252*14b24e2bSVaishali Kulkarni 		break;
253*14b24e2bSVaishali Kulkarni 
254*14b24e2bSVaishali Kulkarni 	case MAC_STAT_OPACKETS:
255*14b24e2bSVaishali Kulkarni 		*val = tx_ring->tx_pkt_count;
256*14b24e2bSVaishali Kulkarni 		break;
257*14b24e2bSVaishali Kulkarni 
258*14b24e2bSVaishali Kulkarni 	default:
259*14b24e2bSVaishali Kulkarni 		*val = 0;
260*14b24e2bSVaishali Kulkarni 		ret = ENOTSUP;
261*14b24e2bSVaishali Kulkarni 	}
262*14b24e2bSVaishali Kulkarni 
263*14b24e2bSVaishali Kulkarni 	return (ret);
264*14b24e2bSVaishali Kulkarni }
265*14b24e2bSVaishali Kulkarni 
266*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS
267*14b24e2bSVaishali Kulkarni static mblk_t *
268*14b24e2bSVaishali Kulkarni qede_rx_ring_poll(void *arg, int poll_bytes, int poll_pkts)
269*14b24e2bSVaishali Kulkarni {
270*14b24e2bSVaishali Kulkarni #else
271*14b24e2bSVaishali Kulkarni static mblk_t *
272*14b24e2bSVaishali Kulkarni qede_rx_ring_poll(void *arg, int poll_bytes)
273*14b24e2bSVaishali Kulkarni {
274*14b24e2bSVaishali Kulkarni 	/* XXX pick a value at the moment */
275*14b24e2bSVaishali Kulkarni 	int poll_pkts = 100;
276*14b24e2bSVaishali Kulkarni #endif
277*14b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)arg;
278*14b24e2bSVaishali Kulkarni 	mblk_t *mp = NULL;
279*14b24e2bSVaishali Kulkarni 	int work_done = 0;
280*14b24e2bSVaishali Kulkarni 	qede_t *qede = fp->qede;
281*14b24e2bSVaishali Kulkarni 
282*14b24e2bSVaishali Kulkarni 	if (poll_bytes == 0) {
283*14b24e2bSVaishali Kulkarni 		return (NULL);
284*14b24e2bSVaishali Kulkarni 	}
285*14b24e2bSVaishali Kulkarni 
286*14b24e2bSVaishali Kulkarni 	mutex_enter(&fp->fp_lock);
287*14b24e2bSVaishali Kulkarni 	qede->intrSbPollCnt[fp->vect_info->vect_index]++;
288*14b24e2bSVaishali Kulkarni 
289*14b24e2bSVaishali Kulkarni 	mp = qede_process_fastpath(fp, poll_bytes, poll_pkts, &work_done);
290*14b24e2bSVaishali Kulkarni 	if (mp != NULL) {
291*14b24e2bSVaishali Kulkarni 		fp->rx_ring->rx_poll_cnt++;
292*14b24e2bSVaishali Kulkarni 	} else if ((mp == NULL) && (work_done == 0)) {
293*14b24e2bSVaishali Kulkarni 		qede->intrSbPollNoChangeCnt[fp->vect_info->vect_index]++;
294*14b24e2bSVaishali Kulkarni 	}
295*14b24e2bSVaishali Kulkarni 
296*14b24e2bSVaishali Kulkarni 	mutex_exit(&fp->fp_lock);
297*14b24e2bSVaishali Kulkarni 	return (mp);
298*14b24e2bSVaishali Kulkarni }
299*14b24e2bSVaishali Kulkarni 
300*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS
301*14b24e2bSVaishali Kulkarni static int
302*14b24e2bSVaishali Kulkarni qede_rx_ring_intr_enable(mac_ring_driver_t rh)
303*14b24e2bSVaishali Kulkarni #else
304*14b24e2bSVaishali Kulkarni static int
305*14b24e2bSVaishali Kulkarni qede_rx_ring_intr_enable(mac_intr_handle_t rh)
306*14b24e2bSVaishali Kulkarni #endif
307*14b24e2bSVaishali Kulkarni {
308*14b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)rh;
309*14b24e2bSVaishali Kulkarni 
310*14b24e2bSVaishali Kulkarni 	mutex_enter(&fp->qede->drv_lock);
311*14b24e2bSVaishali Kulkarni 	if (!fp->sb_phys && (fp->sb_dma_handle == NULL)) {
312*14b24e2bSVaishali Kulkarni 		mutex_exit(&fp->qede->drv_lock);
313*14b24e2bSVaishali Kulkarni 		return (DDI_FAILURE);
314*14b24e2bSVaishali Kulkarni 	}
315*14b24e2bSVaishali Kulkarni 
316*14b24e2bSVaishali Kulkarni 	fp->rx_ring->intrEnableCnt++;
317*14b24e2bSVaishali Kulkarni 	qede_enable_hw_intr(fp);
318*14b24e2bSVaishali Kulkarni 	fp->disabled_by_poll = 0;
319*14b24e2bSVaishali Kulkarni 	mutex_exit(&fp->qede->drv_lock);
320*14b24e2bSVaishali Kulkarni 
321*14b24e2bSVaishali Kulkarni 	return (DDI_SUCCESS);
322*14b24e2bSVaishali Kulkarni }
323*14b24e2bSVaishali Kulkarni 
324*14b24e2bSVaishali Kulkarni #ifndef	ILLUMOS
325*14b24e2bSVaishali Kulkarni static int
326*14b24e2bSVaishali Kulkarni qede_rx_ring_intr_disable(mac_ring_driver_t rh)
327*14b24e2bSVaishali Kulkarni #else
328*14b24e2bSVaishali Kulkarni static int
329*14b24e2bSVaishali Kulkarni qede_rx_ring_intr_disable(mac_intr_handle_t rh)
330*14b24e2bSVaishali Kulkarni #endif
331*14b24e2bSVaishali Kulkarni {
332*14b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)rh;
333*14b24e2bSVaishali Kulkarni 
334*14b24e2bSVaishali Kulkarni 	mutex_enter(&fp->qede->drv_lock);
335*14b24e2bSVaishali Kulkarni 	if (!fp->sb_phys && (fp->sb_dma_handle == NULL)) {
336*14b24e2bSVaishali Kulkarni 		mutex_exit(&fp->qede->drv_lock);
337*14b24e2bSVaishali Kulkarni 		return (DDI_FAILURE);
338*14b24e2bSVaishali Kulkarni 	}
339*14b24e2bSVaishali Kulkarni 	fp->rx_ring->intrDisableCnt++;
340*14b24e2bSVaishali Kulkarni 	qede_disable_hw_intr(fp);
341*14b24e2bSVaishali Kulkarni 	fp->disabled_by_poll = 1;
342*14b24e2bSVaishali Kulkarni 	mutex_exit(&fp->qede->drv_lock);
343*14b24e2bSVaishali Kulkarni 	return (DDI_SUCCESS);
344*14b24e2bSVaishali Kulkarni }
345*14b24e2bSVaishali Kulkarni 
346*14b24e2bSVaishali Kulkarni static int
347*14b24e2bSVaishali Kulkarni qede_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
348*14b24e2bSVaishali Kulkarni {
349*14b24e2bSVaishali Kulkarni 
350*14b24e2bSVaishali Kulkarni 	int ret = 0;
351*14b24e2bSVaishali Kulkarni 
352*14b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)rh;
353*14b24e2bSVaishali Kulkarni 	qede_t *qede = fp->qede;
354*14b24e2bSVaishali Kulkarni 	qede_rx_ring_t *rx_ring = fp->rx_ring;
355*14b24e2bSVaishali Kulkarni 
356*14b24e2bSVaishali Kulkarni 	if (qede->qede_state == QEDE_STATE_SUSPENDED) {
357*14b24e2bSVaishali Kulkarni 		return (ECANCELED);
358*14b24e2bSVaishali Kulkarni 	}
359*14b24e2bSVaishali Kulkarni 
360*14b24e2bSVaishali Kulkarni 	switch (stat) {
361*14b24e2bSVaishali Kulkarni 	case MAC_STAT_RBYTES:
362*14b24e2bSVaishali Kulkarni 		*val = rx_ring->rx_byte_cnt;
363*14b24e2bSVaishali Kulkarni 		break;
364*14b24e2bSVaishali Kulkarni 	case MAC_STAT_IPACKETS:
365*14b24e2bSVaishali Kulkarni 		*val = rx_ring->rx_pkt_cnt;
366*14b24e2bSVaishali Kulkarni 		break;
367*14b24e2bSVaishali Kulkarni 	default:
368*14b24e2bSVaishali Kulkarni 		*val = 0;
369*14b24e2bSVaishali Kulkarni 		ret = ENOTSUP;
370*14b24e2bSVaishali Kulkarni 		break;
371*14b24e2bSVaishali Kulkarni 	}
372*14b24e2bSVaishali Kulkarni 
373*14b24e2bSVaishali Kulkarni 	return (ret);
374*14b24e2bSVaishali Kulkarni }
375*14b24e2bSVaishali Kulkarni 
376*14b24e2bSVaishali Kulkarni static int
377*14b24e2bSVaishali Kulkarni qede_get_global_ring_index(qede_t *qede, int gindex, int rindex)
378*14b24e2bSVaishali Kulkarni {
379*14b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp;
380*14b24e2bSVaishali Kulkarni 	qede_rx_ring_t *rx_ring;
381*14b24e2bSVaishali Kulkarni 	int i = 0;
382*14b24e2bSVaishali Kulkarni 
383*14b24e2bSVaishali Kulkarni 	for (i = 0; i < qede->num_fp; i++) {
384*14b24e2bSVaishali Kulkarni 		fp = &qede->fp_array[i];
385*14b24e2bSVaishali Kulkarni 		rx_ring = fp->rx_ring;
386*14b24e2bSVaishali Kulkarni 
387*14b24e2bSVaishali Kulkarni 		if (rx_ring->group_index == gindex) {
388*14b24e2bSVaishali Kulkarni 			rindex--;
389*14b24e2bSVaishali Kulkarni 		}
390*14b24e2bSVaishali Kulkarni 		if (rindex < 0) {
391*14b24e2bSVaishali Kulkarni 			return (i);
392*14b24e2bSVaishali Kulkarni 		}
393*14b24e2bSVaishali Kulkarni 	}
394*14b24e2bSVaishali Kulkarni 
395*14b24e2bSVaishali Kulkarni 	return (-1);
396*14b24e2bSVaishali Kulkarni }
397*14b24e2bSVaishali Kulkarni 
398*14b24e2bSVaishali Kulkarni static void
399*14b24e2bSVaishali Kulkarni qede_rx_ring_stop(mac_ring_driver_t rh)
400*14b24e2bSVaishali Kulkarni {
401*14b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)rh;
402*14b24e2bSVaishali Kulkarni 	qede_rx_ring_t *rx_ring = fp->rx_ring;
403*14b24e2bSVaishali Kulkarni 
404*14b24e2bSVaishali Kulkarni 	qede_print("!%s(%d): called", __func__,fp->qede->instance);
405*14b24e2bSVaishali Kulkarni 	mutex_enter(&fp->fp_lock);
406*14b24e2bSVaishali Kulkarni 	rx_ring->mac_ring_started = B_FALSE;
407*14b24e2bSVaishali Kulkarni 	mutex_exit(&fp->fp_lock);
408*14b24e2bSVaishali Kulkarni }
409*14b24e2bSVaishali Kulkarni 
410*14b24e2bSVaishali Kulkarni static int
411*14b24e2bSVaishali Kulkarni qede_rx_ring_start(mac_ring_driver_t rh, u64 mr_gen_num)
412*14b24e2bSVaishali Kulkarni {
413*14b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = (qede_fastpath_t *)rh;
414*14b24e2bSVaishali Kulkarni 	qede_rx_ring_t *rx_ring = fp->rx_ring;
415*14b24e2bSVaishali Kulkarni 
416*14b24e2bSVaishali Kulkarni 	qede_print("!%s(%d): called", __func__,fp->qede->instance);
417*14b24e2bSVaishali Kulkarni 	mutex_enter(&fp->fp_lock);
418*14b24e2bSVaishali Kulkarni 	rx_ring->mr_gen_num = mr_gen_num;
419*14b24e2bSVaishali Kulkarni 	rx_ring->mac_ring_started = B_TRUE;
420*14b24e2bSVaishali Kulkarni         rx_ring->intrDisableCnt = 0;
421*14b24e2bSVaishali Kulkarni 	rx_ring->intrEnableCnt  = 0;
422*14b24e2bSVaishali Kulkarni 	fp->disabled_by_poll = 0;
423*14b24e2bSVaishali Kulkarni 
424*14b24e2bSVaishali Kulkarni 	mutex_exit(&fp->fp_lock);
425*14b24e2bSVaishali Kulkarni 
426*14b24e2bSVaishali Kulkarni 	return (DDI_SUCCESS);
427*14b24e2bSVaishali Kulkarni }
428*14b24e2bSVaishali Kulkarni 
429*14b24e2bSVaishali Kulkarni /* Callback function from mac layer to register rings */
430*14b24e2bSVaishali Kulkarni void
431*14b24e2bSVaishali Kulkarni qede_fill_ring(void *arg, mac_ring_type_t rtype, const int group_index,
432*14b24e2bSVaishali Kulkarni     const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh)
433*14b24e2bSVaishali Kulkarni {
434*14b24e2bSVaishali Kulkarni 	qede_t *qede = (qede_t *)arg;
435*14b24e2bSVaishali Kulkarni 	mac_intr_t *mintr = &infop->mri_intr;
436*14b24e2bSVaishali Kulkarni 
437*14b24e2bSVaishali Kulkarni 	switch (rtype) {
438*14b24e2bSVaishali Kulkarni 	case MAC_RING_TYPE_RX: {
439*14b24e2bSVaishali Kulkarni 		/*
440*14b24e2bSVaishali Kulkarni 		 * Index passed as a param is the ring index within the
441*14b24e2bSVaishali Kulkarni 		 * given group index. If multiple groups are supported
442*14b24e2bSVaishali Kulkarni 		 * then need to search into all groups to find out the
443*14b24e2bSVaishali Kulkarni 		 * global ring index for the passed group relative
444*14b24e2bSVaishali Kulkarni 		 * ring index
445*14b24e2bSVaishali Kulkarni 		 */
446*14b24e2bSVaishali Kulkarni 		int global_ring_index = qede_get_global_ring_index(qede,
447*14b24e2bSVaishali Kulkarni 		    group_index, ring_index);
448*14b24e2bSVaishali Kulkarni 		qede_fastpath_t *fp;
449*14b24e2bSVaishali Kulkarni 		qede_rx_ring_t *rx_ring;
450*14b24e2bSVaishali Kulkarni 		int i;
451*14b24e2bSVaishali Kulkarni 
452*14b24e2bSVaishali Kulkarni 		/*
453*14b24e2bSVaishali Kulkarni 		 * global_ring_index < 0 means group index passed
454*14b24e2bSVaishali Kulkarni 		 * was registered by our driver
455*14b24e2bSVaishali Kulkarni 		 */
456*14b24e2bSVaishali Kulkarni 		ASSERT(global_ring_index >= 0);
457*14b24e2bSVaishali Kulkarni 
458*14b24e2bSVaishali Kulkarni 		if (rh == NULL) {
459*14b24e2bSVaishali Kulkarni 			cmn_err(CE_WARN, "!rx ring(%d) ring handle NULL",
460*14b24e2bSVaishali Kulkarni 			    global_ring_index);
461*14b24e2bSVaishali Kulkarni 		}
462*14b24e2bSVaishali Kulkarni 
463*14b24e2bSVaishali Kulkarni 		fp = &qede->fp_array[global_ring_index];
464*14b24e2bSVaishali Kulkarni 		rx_ring = fp->rx_ring;
465*14b24e2bSVaishali Kulkarni 		fp->qede = qede;
466*14b24e2bSVaishali Kulkarni 
467*14b24e2bSVaishali Kulkarni 		rx_ring->mac_ring_handle = rh;
468*14b24e2bSVaishali Kulkarni 
469*14b24e2bSVaishali Kulkarni 		qede_info(qede, "rx_ring %d mac_ring_handle %p",
470*14b24e2bSVaishali Kulkarni 		    rx_ring->rss_id, rh);
471*14b24e2bSVaishali Kulkarni 
472*14b24e2bSVaishali Kulkarni 		/* mri_driver passed as arg to mac_ring* callbacks */
473*14b24e2bSVaishali Kulkarni 		infop->mri_driver = (mac_ring_driver_t)fp;
474*14b24e2bSVaishali Kulkarni 		/*
475*14b24e2bSVaishali Kulkarni 		 * mri_start callback will supply a mac rings generation
476*14b24e2bSVaishali Kulkarni 		 * number which is needed while indicating packets
477*14b24e2bSVaishali Kulkarni 		 * upstream via mac_ring_rx() call
478*14b24e2bSVaishali Kulkarni 		 */
479*14b24e2bSVaishali Kulkarni 		infop->mri_start = qede_rx_ring_start;
480*14b24e2bSVaishali Kulkarni 		infop->mri_stop = qede_rx_ring_stop;
481*14b24e2bSVaishali Kulkarni 		infop->mri_poll = qede_rx_ring_poll;
482*14b24e2bSVaishali Kulkarni 		infop->mri_stat = qede_rx_ring_stat;
483*14b24e2bSVaishali Kulkarni 
484*14b24e2bSVaishali Kulkarni 		mintr->mi_handle = (mac_intr_handle_t)fp;
485*14b24e2bSVaishali Kulkarni 		mintr->mi_enable = qede_rx_ring_intr_enable;
486*14b24e2bSVaishali Kulkarni 		mintr->mi_disable = qede_rx_ring_intr_disable;
487*14b24e2bSVaishali Kulkarni 		if (qede->intr_ctx.intr_type_in_use &
488*14b24e2bSVaishali Kulkarni 		    (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) {
489*14b24e2bSVaishali Kulkarni 			mintr->mi_ddi_handle =
490*14b24e2bSVaishali Kulkarni 			    qede->intr_ctx.
491*14b24e2bSVaishali Kulkarni 			    intr_hdl_array[global_ring_index + qede->num_hwfns];
492*14b24e2bSVaishali Kulkarni 		}
493*14b24e2bSVaishali Kulkarni 		break;
494*14b24e2bSVaishali Kulkarni 	}
495*14b24e2bSVaishali Kulkarni 	case MAC_RING_TYPE_TX: {
496*14b24e2bSVaishali Kulkarni 		qede_fastpath_t *fp;
497*14b24e2bSVaishali Kulkarni 		qede_tx_ring_t *tx_ring;
498*14b24e2bSVaishali Kulkarni 		int i, tc;
499*14b24e2bSVaishali Kulkarni 
500*14b24e2bSVaishali Kulkarni 		ASSERT(ring_index < qede->num_fp);
501*14b24e2bSVaishali Kulkarni 
502*14b24e2bSVaishali Kulkarni 		fp = &qede->fp_array[ring_index];
503*14b24e2bSVaishali Kulkarni 		fp->qede = qede;
504*14b24e2bSVaishali Kulkarni 		tx_ring = fp->tx_ring[0];
505*14b24e2bSVaishali Kulkarni 		tx_ring->mac_ring_handle = rh;
506*14b24e2bSVaishali Kulkarni 		qede_info(qede, "tx_ring %d mac_ring_handle %p",
507*14b24e2bSVaishali Kulkarni 		    tx_ring->tx_queue_index, rh);
508*14b24e2bSVaishali Kulkarni 		infop->mri_driver = (mac_ring_driver_t)fp;
509*14b24e2bSVaishali Kulkarni 		infop->mri_start = NULL;
510*14b24e2bSVaishali Kulkarni 		infop->mri_stop = NULL;
511*14b24e2bSVaishali Kulkarni 		infop->mri_tx = qede_ring_tx;
512*14b24e2bSVaishali Kulkarni 		infop->mri_stat = qede_tx_ring_stat;
513*14b24e2bSVaishali Kulkarni 		if (qede->intr_ctx.intr_type_in_use &
514*14b24e2bSVaishali Kulkarni 		    (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) {
515*14b24e2bSVaishali Kulkarni 			mintr->mi_ddi_handle =
516*14b24e2bSVaishali Kulkarni 			    qede->intr_ctx.
517*14b24e2bSVaishali Kulkarni 			    intr_hdl_array[ring_index + qede->num_hwfns];
518*14b24e2bSVaishali Kulkarni 		}
519*14b24e2bSVaishali Kulkarni 		break;
520*14b24e2bSVaishali Kulkarni 	}
521*14b24e2bSVaishali Kulkarni 	default:
522*14b24e2bSVaishali Kulkarni 		break;
523*14b24e2bSVaishali Kulkarni 	}
524*14b24e2bSVaishali Kulkarni }
525*14b24e2bSVaishali Kulkarni 
526*14b24e2bSVaishali Kulkarni /*
527*14b24e2bSVaishali Kulkarni  * Callback function from mac layer to register group
528*14b24e2bSVaishali Kulkarni  */
529*14b24e2bSVaishali Kulkarni void
530*14b24e2bSVaishali Kulkarni qede_fill_group(void *arg, mac_ring_type_t rtype, const int index,
531*14b24e2bSVaishali Kulkarni     mac_group_info_t *infop, mac_group_handle_t gh)
532*14b24e2bSVaishali Kulkarni {
533*14b24e2bSVaishali Kulkarni 	qede_t *qede = (qede_t *)arg;
534*14b24e2bSVaishali Kulkarni 
535*14b24e2bSVaishali Kulkarni 	switch (rtype) {
536*14b24e2bSVaishali Kulkarni 	case MAC_RING_TYPE_RX: {
537*14b24e2bSVaishali Kulkarni 		qede_mac_group_t *rx_group;
538*14b24e2bSVaishali Kulkarni 
539*14b24e2bSVaishali Kulkarni 		rx_group = &qede->rx_groups[index];
540*14b24e2bSVaishali Kulkarni 		rx_group->group_handle = gh;
541*14b24e2bSVaishali Kulkarni 		rx_group->group_index = index;
542*14b24e2bSVaishali Kulkarni 		rx_group->qede = qede;
543*14b24e2bSVaishali Kulkarni 		infop->mgi_driver = (mac_group_driver_t)rx_group;
544*14b24e2bSVaishali Kulkarni 		infop->mgi_start = NULL;
545*14b24e2bSVaishali Kulkarni 		infop->mgi_stop = NULL;
546*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS
547*14b24e2bSVaishali Kulkarni 		infop->mgi_addvlan = NULL;
548*14b24e2bSVaishali Kulkarni 		infop->mgi_remvlan = NULL;
549*14b24e2bSVaishali Kulkarni 		infop->mgi_getsriov_info = NULL;
550*14b24e2bSVaishali Kulkarni 		infop->mgi_setmtu = NULL;
551*14b24e2bSVaishali Kulkarni #endif
552*14b24e2bSVaishali Kulkarni 		infop->mgi_addmac = qede_add_mac_addr;
553*14b24e2bSVaishali Kulkarni 		infop->mgi_remmac = qede_rem_mac_addr;
554*14b24e2bSVaishali Kulkarni 		infop->mgi_count =  qede->num_fp;
555*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS
556*14b24e2bSVaishali Kulkarni 		if (index == 0) {
557*14b24e2bSVaishali Kulkarni 			infop->mgi_flags = MAC_GROUP_DEFAULT;
558*14b24e2bSVaishali Kulkarni 		}
559*14b24e2bSVaishali Kulkarni #endif
560*14b24e2bSVaishali Kulkarni 
561*14b24e2bSVaishali Kulkarni 		break;
562*14b24e2bSVaishali Kulkarni 	}
563*14b24e2bSVaishali Kulkarni 	case MAC_RING_TYPE_TX: {
564*14b24e2bSVaishali Kulkarni 		qede_mac_group_t *tx_group;
565*14b24e2bSVaishali Kulkarni 
566*14b24e2bSVaishali Kulkarni 		tx_group = &qede->tx_groups[index];
567*14b24e2bSVaishali Kulkarni 		tx_group->group_handle = gh;
568*14b24e2bSVaishali Kulkarni 		tx_group->group_index = index;
569*14b24e2bSVaishali Kulkarni 		tx_group->qede = qede;
570*14b24e2bSVaishali Kulkarni 
571*14b24e2bSVaishali Kulkarni 		infop->mgi_driver = (mac_group_driver_t)tx_group;
572*14b24e2bSVaishali Kulkarni 		infop->mgi_start = NULL;
573*14b24e2bSVaishali Kulkarni 		infop->mgi_stop = NULL;
574*14b24e2bSVaishali Kulkarni 		infop->mgi_addmac = NULL;
575*14b24e2bSVaishali Kulkarni 		infop->mgi_remmac = NULL;
576*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS
577*14b24e2bSVaishali Kulkarni 		infop->mgi_addvlan = NULL;
578*14b24e2bSVaishali Kulkarni 		infop->mgi_remvlan = NULL;
579*14b24e2bSVaishali Kulkarni 		infop->mgi_setmtu = NULL;
580*14b24e2bSVaishali Kulkarni 		infop->mgi_getsriov_info = NULL;
581*14b24e2bSVaishali Kulkarni #endif
582*14b24e2bSVaishali Kulkarni 
583*14b24e2bSVaishali Kulkarni 		infop->mgi_count = qede->num_fp;
584*14b24e2bSVaishali Kulkarni 
585*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS
586*14b24e2bSVaishali Kulkarni 		if (index == 0) {
587*14b24e2bSVaishali Kulkarni 			infop->mgi_flags = MAC_GROUP_DEFAULT;
588*14b24e2bSVaishali Kulkarni 		}
589*14b24e2bSVaishali Kulkarni #endif
590*14b24e2bSVaishali Kulkarni 		break;
591*14b24e2bSVaishali Kulkarni 	}
592*14b24e2bSVaishali Kulkarni 	default:
593*14b24e2bSVaishali Kulkarni 		break;
594*14b24e2bSVaishali Kulkarni 	}
595*14b24e2bSVaishali Kulkarni }
596*14b24e2bSVaishali Kulkarni 
597*14b24e2bSVaishali Kulkarni #ifdef ILLUMOS
598*14b24e2bSVaishali Kulkarni static int
599*14b24e2bSVaishali Kulkarni qede_transceiver_info(void *arg, uint_t id, mac_transceiver_info_t *infop)
600*14b24e2bSVaishali Kulkarni {
601*14b24e2bSVaishali Kulkarni         qede_t *qede = arg;
602*14b24e2bSVaishali Kulkarni         struct ecore_dev *edev = &qede->edev;
603*14b24e2bSVaishali Kulkarni         struct ecore_hwfn *hwfn;
604*14b24e2bSVaishali Kulkarni         struct ecore_ptt *ptt;
605*14b24e2bSVaishali Kulkarni         uint32_t transceiver_state;
606*14b24e2bSVaishali Kulkarni 
607*14b24e2bSVaishali Kulkarni         if (id >= edev->num_hwfns || arg == NULL || infop == NULL)
608*14b24e2bSVaishali Kulkarni                 return (EINVAL);
609*14b24e2bSVaishali Kulkarni 
610*14b24e2bSVaishali Kulkarni         hwfn = &edev->hwfns[id];
611*14b24e2bSVaishali Kulkarni         ptt = ecore_ptt_acquire(hwfn);
612*14b24e2bSVaishali Kulkarni         if (ptt == NULL) {
613*14b24e2bSVaishali Kulkarni                 return (EIO);
614*14b24e2bSVaishali Kulkarni         }
615*14b24e2bSVaishali Kulkarni         /*
616*14b24e2bSVaishali Kulkarni          * Use the underlying raw API to get this information. While the
617*14b24e2bSVaishali Kulkarni          * ecore_phy routines have some ways of getting to this information, it
618*14b24e2bSVaishali Kulkarni          * ends up writing the raw data as ASCII characters which doesn't help
619*14b24e2bSVaishali Kulkarni          * us one bit.
620*14b24e2bSVaishali Kulkarni          */
621*14b24e2bSVaishali Kulkarni         transceiver_state = ecore_rd(hwfn, ptt, hwfn->mcp_info->port_addr +
622*14b24e2bSVaishali Kulkarni             OFFSETOF(struct public_port, transceiver_data));
623*14b24e2bSVaishali Kulkarni         transceiver_state = GET_FIELD(transceiver_state, ETH_TRANSCEIVER_STATE);
624*14b24e2bSVaishali Kulkarni         ecore_ptt_release(hwfn, ptt);
625*14b24e2bSVaishali Kulkarni 
626*14b24e2bSVaishali Kulkarni         if ((transceiver_state & ETH_TRANSCEIVER_STATE_PRESENT) != 0) {
627*14b24e2bSVaishali Kulkarni                 mac_transceiver_info_set_present(infop, B_TRUE);
628*14b24e2bSVaishali Kulkarni                 /*
629*14b24e2bSVaishali Kulkarni                  * Based on our testing, the ETH_TRANSCEIVER_STATE_VALID flag is
630*14b24e2bSVaishali Kulkarni                  * not set, so we cannot rely on it. Instead, we have found that
631*14b24e2bSVaishali Kulkarni                  * the ETH_TRANSCEIVER_STATE_UPDATING will be set when we cannot
632*14b24e2bSVaishali Kulkarni                  * use the transceiver.
633*14b24e2bSVaishali Kulkarni                  */
634*14b24e2bSVaishali Kulkarni                 if ((transceiver_state & ETH_TRANSCEIVER_STATE_UPDATING) != 0) {
635*14b24e2bSVaishali Kulkarni                         mac_transceiver_info_set_usable(infop, B_FALSE);
636*14b24e2bSVaishali Kulkarni                 } else {
637*14b24e2bSVaishali Kulkarni                         mac_transceiver_info_set_usable(infop, B_TRUE);
638*14b24e2bSVaishali Kulkarni                 }
639*14b24e2bSVaishali Kulkarni         } else {
640*14b24e2bSVaishali Kulkarni                 mac_transceiver_info_set_present(infop, B_FALSE);
641*14b24e2bSVaishali Kulkarni                 mac_transceiver_info_set_usable(infop, B_FALSE);
642*14b24e2bSVaishali Kulkarni         }
643*14b24e2bSVaishali Kulkarni 
644*14b24e2bSVaishali Kulkarni         return (0);
645*14b24e2bSVaishali Kulkarni }
646*14b24e2bSVaishali Kulkarni 
647*14b24e2bSVaishali Kulkarni static int
648*14b24e2bSVaishali Kulkarni qede_transceiver_read(void *arg, uint_t id, uint_t page, void *buf,
649*14b24e2bSVaishali Kulkarni     size_t nbytes, off_t offset, size_t *nread)
650*14b24e2bSVaishali Kulkarni {
651*14b24e2bSVaishali Kulkarni         qede_t *qede = arg;
652*14b24e2bSVaishali Kulkarni         struct ecore_dev *edev = &qede->edev;
653*14b24e2bSVaishali Kulkarni         struct ecore_hwfn *hwfn;
654*14b24e2bSVaishali Kulkarni         uint32_t port, lane;
655*14b24e2bSVaishali Kulkarni         struct ecore_ptt *ptt;
656*14b24e2bSVaishali Kulkarni         enum _ecore_status_t ret;
657*14b24e2bSVaishali Kulkarni 
658*14b24e2bSVaishali Kulkarni         if (id >= edev->num_hwfns || buf == NULL || nbytes == 0 || nread == NULL ||
659*14b24e2bSVaishali Kulkarni             (page != 0xa0 && page != 0xa2) || offset < 0)
660*14b24e2bSVaishali Kulkarni                 return (EINVAL);
661*14b24e2bSVaishali Kulkarni 
662*14b24e2bSVaishali Kulkarni         /*
663*14b24e2bSVaishali Kulkarni          * Both supported pages have a length of 256 bytes, ensure nothing asks
664*14b24e2bSVaishali Kulkarni          * us to go beyond that.
665*14b24e2bSVaishali Kulkarni          */
666*14b24e2bSVaishali Kulkarni         if (nbytes > 256 || offset >= 256 || (offset + nbytes > 256)) {
667*14b24e2bSVaishali Kulkarni                return (EINVAL);
668*14b24e2bSVaishali Kulkarni         }
669*14b24e2bSVaishali Kulkarni 
670*14b24e2bSVaishali Kulkarni         hwfn = &edev->hwfns[id];
671*14b24e2bSVaishali Kulkarni         ptt = ecore_ptt_acquire(hwfn);
672*14b24e2bSVaishali Kulkarni         if (ptt == NULL) {
673*14b24e2bSVaishali Kulkarni                 return (EIO);
674*14b24e2bSVaishali Kulkarni         }
675*14b24e2bSVaishali Kulkarni 
676*14b24e2bSVaishali Kulkarni         ret = ecore_mcp_phy_sfp_read(hwfn, ptt, hwfn->port_id, page, offset,
677*14b24e2bSVaishali Kulkarni             nbytes, buf);
678*14b24e2bSVaishali Kulkarni         ecore_ptt_release(hwfn, ptt);
679*14b24e2bSVaishali Kulkarni         if (ret != ECORE_SUCCESS) {
680*14b24e2bSVaishali Kulkarni                 return (EIO);
681*14b24e2bSVaishali Kulkarni         }
682*14b24e2bSVaishali Kulkarni         *nread = nbytes;
683*14b24e2bSVaishali Kulkarni         return (0);
684*14b24e2bSVaishali Kulkarni }
685*14b24e2bSVaishali Kulkarni #endif /* ILLUMOS */
686*14b24e2bSVaishali Kulkarni 
687*14b24e2bSVaishali Kulkarni 
688*14b24e2bSVaishali Kulkarni static int
689*14b24e2bSVaishali Kulkarni qede_mac_stats(void *     arg,
690*14b24e2bSVaishali Kulkarni                         uint_t     stat,
691*14b24e2bSVaishali Kulkarni                         uint64_t * value)
692*14b24e2bSVaishali Kulkarni {
693*14b24e2bSVaishali Kulkarni 	qede_t * qede = (qede_t *)arg;
694*14b24e2bSVaishali Kulkarni 	struct ecore_eth_stats vstats;
695*14b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
696*14b24e2bSVaishali Kulkarni 	struct qede_link_cfg lnkcfg;
697*14b24e2bSVaishali Kulkarni 	int rc = 0;
698*14b24e2bSVaishali Kulkarni 	qede_fastpath_t *fp = &qede->fp_array[0];
699*14b24e2bSVaishali Kulkarni 	qede_rx_ring_t *rx_ring;
700*14b24e2bSVaishali Kulkarni 	qede_tx_ring_t *tx_ring;
701*14b24e2bSVaishali Kulkarni 
702*14b24e2bSVaishali Kulkarni 	if ((qede == NULL) || (value == NULL)) {
703*14b24e2bSVaishali Kulkarni 		return EINVAL;
704*14b24e2bSVaishali Kulkarni 	}
705*14b24e2bSVaishali Kulkarni 
706*14b24e2bSVaishali Kulkarni 
707*14b24e2bSVaishali Kulkarni 	mutex_enter(&qede->gld_lock);
708*14b24e2bSVaishali Kulkarni 
709*14b24e2bSVaishali Kulkarni 	if(qede->qede_state != QEDE_STATE_STARTED) {
710*14b24e2bSVaishali Kulkarni 		mutex_exit(&qede->gld_lock);
711*14b24e2bSVaishali Kulkarni 		return EAGAIN;
712*14b24e2bSVaishali Kulkarni 	}
713*14b24e2bSVaishali Kulkarni 
714*14b24e2bSVaishali Kulkarni 	*value = 0;
715*14b24e2bSVaishali Kulkarni 
716*14b24e2bSVaishali Kulkarni 	memset(&vstats, 0, sizeof(struct ecore_eth_stats));
717*14b24e2bSVaishali Kulkarni 	ecore_get_vport_stats(edev, &vstats);
718*14b24e2bSVaishali Kulkarni 
719*14b24e2bSVaishali Kulkarni 
720*14b24e2bSVaishali Kulkarni         memset(&qede->curcfg, 0, sizeof(struct qede_link_cfg));
721*14b24e2bSVaishali Kulkarni         qede_get_link_info(&edev->hwfns[0], &qede->curcfg);
722*14b24e2bSVaishali Kulkarni 
723*14b24e2bSVaishali Kulkarni 
724*14b24e2bSVaishali Kulkarni 
725*14b24e2bSVaishali Kulkarni 	switch (stat)
726*14b24e2bSVaishali Kulkarni 	{
727*14b24e2bSVaishali Kulkarni 	case MAC_STAT_IFSPEED:
728*14b24e2bSVaishali Kulkarni 		*value = (qede->props.link_speed * 1000000ULL);
729*14b24e2bSVaishali Kulkarni 		break;
730*14b24e2bSVaishali Kulkarni 	case MAC_STAT_MULTIRCV:
731*14b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_mcast_pkts;
732*14b24e2bSVaishali Kulkarni 		break;
733*14b24e2bSVaishali Kulkarni 	case MAC_STAT_BRDCSTRCV:
734*14b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_bcast_pkts;
735*14b24e2bSVaishali Kulkarni 		break;
736*14b24e2bSVaishali Kulkarni 	case MAC_STAT_MULTIXMT:
737*14b24e2bSVaishali Kulkarni 		*value = vstats.common.tx_mcast_pkts;
738*14b24e2bSVaishali Kulkarni 		break;
739*14b24e2bSVaishali Kulkarni 	case MAC_STAT_BRDCSTXMT:
740*14b24e2bSVaishali Kulkarni 		*value = vstats.common.tx_bcast_pkts;
741*14b24e2bSVaishali Kulkarni 		break;
742*14b24e2bSVaishali Kulkarni 	case MAC_STAT_NORCVBUF:
743*14b24e2bSVaishali Kulkarni 		*value = vstats.common.no_buff_discards;
744*14b24e2bSVaishali Kulkarni 		break;
745*14b24e2bSVaishali Kulkarni 	case MAC_STAT_NOXMTBUF:
746*14b24e2bSVaishali Kulkarni 		*value = 0;
747*14b24e2bSVaishali Kulkarni 		break;
748*14b24e2bSVaishali Kulkarni 	case MAC_STAT_IERRORS:
749*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_MACRCV_ERRORS:
750*14b24e2bSVaishali Kulkarni 		*value = vstats.common.mac_filter_discards +
751*14b24e2bSVaishali Kulkarni 		    vstats.common.packet_too_big_discard +
752*14b24e2bSVaishali Kulkarni 		    vstats.common.rx_crc_errors;
753*14b24e2bSVaishali Kulkarni 		break;
754*14b24e2bSVaishali Kulkarni 
755*14b24e2bSVaishali Kulkarni 	case MAC_STAT_OERRORS:
756*14b24e2bSVaishali Kulkarni 		break;
757*14b24e2bSVaishali Kulkarni 
758*14b24e2bSVaishali Kulkarni 	case MAC_STAT_COLLISIONS:
759*14b24e2bSVaishali Kulkarni 		*value = vstats.bb.tx_total_collisions;
760*14b24e2bSVaishali Kulkarni 		break;
761*14b24e2bSVaishali Kulkarni 
762*14b24e2bSVaishali Kulkarni 	case MAC_STAT_RBYTES:
763*14b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_ucast_bytes +
764*14b24e2bSVaishali Kulkarni 		    vstats.common.rx_mcast_bytes +
765*14b24e2bSVaishali Kulkarni 		    vstats.common.rx_bcast_bytes;
766*14b24e2bSVaishali Kulkarni 		break;
767*14b24e2bSVaishali Kulkarni 
768*14b24e2bSVaishali Kulkarni 	case MAC_STAT_IPACKETS:
769*14b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_ucast_pkts +
770*14b24e2bSVaishali Kulkarni 		    vstats.common.rx_mcast_pkts +
771*14b24e2bSVaishali Kulkarni 		    vstats.common.rx_bcast_pkts;
772*14b24e2bSVaishali Kulkarni 		break;
773*14b24e2bSVaishali Kulkarni 
774*14b24e2bSVaishali Kulkarni 	case MAC_STAT_OBYTES:
775*14b24e2bSVaishali Kulkarni 		*value = vstats.common.tx_ucast_bytes +
776*14b24e2bSVaishali Kulkarni 		    vstats.common.tx_mcast_bytes +
777*14b24e2bSVaishali Kulkarni 		    vstats.common.tx_bcast_bytes;
778*14b24e2bSVaishali Kulkarni 		break;
779*14b24e2bSVaishali Kulkarni 
780*14b24e2bSVaishali Kulkarni 	case MAC_STAT_OPACKETS:
781*14b24e2bSVaishali Kulkarni 		*value = vstats.common.tx_ucast_pkts +
782*14b24e2bSVaishali Kulkarni 		    vstats.common.tx_mcast_pkts +
783*14b24e2bSVaishali Kulkarni 		    vstats.common.tx_bcast_pkts;
784*14b24e2bSVaishali Kulkarni 		break;
785*14b24e2bSVaishali Kulkarni 
786*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_ALIGN_ERRORS:
787*14b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_align_errors;
788*14b24e2bSVaishali Kulkarni 		break;
789*14b24e2bSVaishali Kulkarni 
790*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_FCS_ERRORS:
791*14b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_crc_errors;
792*14b24e2bSVaishali Kulkarni 		break;
793*14b24e2bSVaishali Kulkarni 
794*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_FIRST_COLLISIONS:
795*14b24e2bSVaishali Kulkarni 		break;
796*14b24e2bSVaishali Kulkarni 
797*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_MULTI_COLLISIONS:
798*14b24e2bSVaishali Kulkarni 		break;
799*14b24e2bSVaishali Kulkarni 
800*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_DEFER_XMTS:
801*14b24e2bSVaishali Kulkarni 		break;
802*14b24e2bSVaishali Kulkarni 
803*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_TX_LATE_COLLISIONS:
804*14b24e2bSVaishali Kulkarni 		break;
805*14b24e2bSVaishali Kulkarni 
806*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_EX_COLLISIONS:
807*14b24e2bSVaishali Kulkarni 		break;
808*14b24e2bSVaishali Kulkarni 
809*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_MACXMT_ERRORS:
810*14b24e2bSVaishali Kulkarni 		*value = 0;
811*14b24e2bSVaishali Kulkarni 		break;
812*14b24e2bSVaishali Kulkarni 
813*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_CARRIER_ERRORS:
814*14b24e2bSVaishali Kulkarni 		break;
815*14b24e2bSVaishali Kulkarni 
816*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_TOOLONG_ERRORS:
817*14b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_oversize_packets;
818*14b24e2bSVaishali Kulkarni 		break;
819*14b24e2bSVaishali Kulkarni 
820*14b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1)
821*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_TOOSHORT_ERRORS:
822*14b24e2bSVaishali Kulkarni 		*value = vstats.common.rx_undersize_packets;
823*14b24e2bSVaishali Kulkarni 		break;
824*14b24e2bSVaishali Kulkarni #endif
825*14b24e2bSVaishali Kulkarni 
826*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_XCVR_ADDR:
827*14b24e2bSVaishali Kulkarni         	*value = 0;
828*14b24e2bSVaishali Kulkarni         	break;
829*14b24e2bSVaishali Kulkarni 
830*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_XCVR_ID:
831*14b24e2bSVaishali Kulkarni         	*value = 0;
832*14b24e2bSVaishali Kulkarni         	break;
833*14b24e2bSVaishali Kulkarni 
834*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_XCVR_INUSE:
835*14b24e2bSVaishali Kulkarni 		switch (qede->props.link_speed) {
836*14b24e2bSVaishali Kulkarni 		default:
837*14b24e2bSVaishali Kulkarni 			*value = XCVR_UNDEFINED;
838*14b24e2bSVaishali Kulkarni 		}
839*14b24e2bSVaishali Kulkarni 		break;
840*14b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1)
841*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_10GFDX:
842*14b24e2bSVaishali Kulkarni 		*value = 0;
843*14b24e2bSVaishali Kulkarni 		break;
844*14b24e2bSVaishali Kulkarni #endif
845*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_100FDX:
846*14b24e2bSVaishali Kulkarni         	*value = 0;
847*14b24e2bSVaishali Kulkarni         	break;
848*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_100HDX:
849*14b24e2bSVaishali Kulkarni         	*value = 0;
850*14b24e2bSVaishali Kulkarni         	break;
851*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_ASMPAUSE:
852*14b24e2bSVaishali Kulkarni 		*value = 1;
853*14b24e2bSVaishali Kulkarni 		break;
854*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_PAUSE:
855*14b24e2bSVaishali Kulkarni 		*value = 1;
856*14b24e2bSVaishali Kulkarni 		break;
857*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_AUTONEG:
858*14b24e2bSVaishali Kulkarni 		*value = 1;
859*14b24e2bSVaishali Kulkarni 		break;
860*14b24e2bSVaishali Kulkarni 
861*14b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1)
862*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_CAP_REMFAULT:
863*14b24e2bSVaishali Kulkarni 		*value = 0;
864*14b24e2bSVaishali Kulkarni 		break;
865*14b24e2bSVaishali Kulkarni #endif
866*14b24e2bSVaishali Kulkarni 
867*14b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1)
868*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_ADV_CAP_10GFDX:
869*14b24e2bSVaishali Kulkarni 		*value = 0;
870*14b24e2bSVaishali Kulkarni 		break;
871*14b24e2bSVaishali Kulkarni #endif
872*14b24e2bSVaishali Kulkarni     case ETHER_STAT_ADV_CAP_ASMPAUSE:
873*14b24e2bSVaishali Kulkarni 		*value = 1;
874*14b24e2bSVaishali Kulkarni 		break;
875*14b24e2bSVaishali Kulkarni 
876*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_ADV_CAP_PAUSE:
877*14b24e2bSVaishali Kulkarni 		*value = 1;
878*14b24e2bSVaishali Kulkarni 		break;
879*14b24e2bSVaishali Kulkarni 
880*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_ADV_CAP_AUTONEG:
881*14b24e2bSVaishali Kulkarni 		*value = qede->curcfg.adv_capab.autoneg;
882*14b24e2bSVaishali Kulkarni 		break;
883*14b24e2bSVaishali Kulkarni 
884*14b24e2bSVaishali Kulkarni #if (MAC_VERSION > 1)
885*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_ADV_REMFAULT:
886*14b24e2bSVaishali Kulkarni 		*value = 0;
887*14b24e2bSVaishali Kulkarni 		break;
888*14b24e2bSVaishali Kulkarni #endif
889*14b24e2bSVaishali Kulkarni 
890*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_LINK_AUTONEG:
891*14b24e2bSVaishali Kulkarni 		*value	= qede->curcfg.autoneg;
892*14b24e2bSVaishali Kulkarni 		break;
893*14b24e2bSVaishali Kulkarni 
894*14b24e2bSVaishali Kulkarni 	case ETHER_STAT_LINK_DUPLEX:
895*14b24e2bSVaishali Kulkarni 		*value = (qede->props.link_duplex == DUPLEX_FULL) ?
896*14b24e2bSVaishali Kulkarni 				    LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
897*14b24e2bSVaishali Kulkarni 		break;
898*14b24e2bSVaishali Kulkarni         /*
899*14b24e2bSVaishali Kulkarni          * Supported speeds. These indicate what hardware is capable of.
900*14b24e2bSVaishali Kulkarni          */
901*14b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_1000HDX:
902*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_1000hdx;
903*14b24e2bSVaishali Kulkarni                 break;
904*14b24e2bSVaishali Kulkarni 
905*14b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_1000FDX:
906*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_1000fdx;
907*14b24e2bSVaishali Kulkarni                 break;
908*14b24e2bSVaishali Kulkarni 
909*14b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_10GFDX:
910*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_10000fdx;
911*14b24e2bSVaishali Kulkarni                 break;
912*14b24e2bSVaishali Kulkarni 
913*14b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_25GFDX:
914*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_25000fdx;
915*14b24e2bSVaishali Kulkarni                 break;
916*14b24e2bSVaishali Kulkarni 
917*14b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_40GFDX:
918*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_40000fdx;
919*14b24e2bSVaishali Kulkarni                 break;
920*14b24e2bSVaishali Kulkarni 
921*14b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_50GFDX:
922*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_50000fdx;
923*14b24e2bSVaishali Kulkarni                 break;
924*14b24e2bSVaishali Kulkarni 
925*14b24e2bSVaishali Kulkarni         case ETHER_STAT_CAP_100GFDX:
926*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.supp_capab.param_100000fdx;
927*14b24e2bSVaishali Kulkarni                 break;
928*14b24e2bSVaishali Kulkarni 
929*14b24e2bSVaishali Kulkarni         /*
930*14b24e2bSVaishali Kulkarni          * Advertised speeds. These indicate what hardware is currently sending.
931*14b24e2bSVaishali Kulkarni          */
932*14b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_1000HDX:
933*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_1000hdx;
934*14b24e2bSVaishali Kulkarni                 break;
935*14b24e2bSVaishali Kulkarni 
936*14b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_1000FDX:
937*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_1000fdx;
938*14b24e2bSVaishali Kulkarni                 break;
939*14b24e2bSVaishali Kulkarni 
940*14b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_10GFDX:
941*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_10000fdx;
942*14b24e2bSVaishali Kulkarni                 break;
943*14b24e2bSVaishali Kulkarni 
944*14b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_25GFDX:
945*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_25000fdx;
946*14b24e2bSVaishali Kulkarni                 break;
947*14b24e2bSVaishali Kulkarni 
948*14b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_40GFDX:
949*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_40000fdx;
950*14b24e2bSVaishali Kulkarni                 break;
951*14b24e2bSVaishali Kulkarni 
952*14b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_50GFDX:
953*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_50000fdx;
954*14b24e2bSVaishali Kulkarni                 break;
955*14b24e2bSVaishali Kulkarni 
956*14b24e2bSVaishali Kulkarni         case ETHER_STAT_ADV_CAP_100GFDX:
957*14b24e2bSVaishali Kulkarni                 *value = qede->curcfg.adv_capab.param_100000fdx;
958*14b24e2bSVaishali Kulkarni                 break;
959*14b24e2bSVaishali Kulkarni 
960*14b24e2bSVaishali Kulkarni 	default:
961*14b24e2bSVaishali Kulkarni 		rc = ENOTSUP;
962*14b24e2bSVaishali Kulkarni 	}
963*14b24e2bSVaishali Kulkarni 
964*14b24e2bSVaishali Kulkarni 	mutex_exit(&qede->gld_lock);
965*14b24e2bSVaishali Kulkarni 	return (rc);
966*14b24e2bSVaishali Kulkarni }
967*14b24e2bSVaishali Kulkarni 
968*14b24e2bSVaishali Kulkarni /* (flag) TRUE = on, FALSE = off */
969*14b24e2bSVaishali Kulkarni static int
970*14b24e2bSVaishali Kulkarni qede_mac_promiscuous(void *arg,
971*14b24e2bSVaishali Kulkarni     boolean_t on)
972*14b24e2bSVaishali Kulkarni {
973*14b24e2bSVaishali Kulkarni     	qede_t *qede = (qede_t *)arg;
974*14b24e2bSVaishali Kulkarni 	qede_print("!%s(%d): called", __func__,qede->instance);
975*14b24e2bSVaishali Kulkarni 	int ret = DDI_SUCCESS;
976*14b24e2bSVaishali Kulkarni 	enum qede_filter_rx_mode_type mode;
977*14b24e2bSVaishali Kulkarni 
978*14b24e2bSVaishali Kulkarni 	mutex_enter(&qede->drv_lock);
979*14b24e2bSVaishali Kulkarni 
980*14b24e2bSVaishali Kulkarni 	if (qede->qede_state == QEDE_STATE_SUSPENDED) {
981*14b24e2bSVaishali Kulkarni 		ret = ECANCELED;
982*14b24e2bSVaishali Kulkarni 		goto exit;
983*14b24e2bSVaishali Kulkarni 	}
984*14b24e2bSVaishali Kulkarni 
985*14b24e2bSVaishali Kulkarni 	if (on) {
986*14b24e2bSVaishali Kulkarni 		qede_info(qede, "Entering promiscuous mode");
987*14b24e2bSVaishali Kulkarni 		mode = QEDE_FILTER_RX_MODE_PROMISC;
988*14b24e2bSVaishali Kulkarni 		qede->params.promisc_fl = B_TRUE;
989*14b24e2bSVaishali Kulkarni 	} else {
990*14b24e2bSVaishali Kulkarni 		qede_info(qede, "Leaving promiscuous mode");
991*14b24e2bSVaishali Kulkarni 		if(qede->params.multi_promisc_fl == B_TRUE) {
992*14b24e2bSVaishali Kulkarni 			mode = QEDE_FILTER_RX_MODE_MULTI_PROMISC;
993*14b24e2bSVaishali Kulkarni 		} else {
994*14b24e2bSVaishali Kulkarni 			 mode = QEDE_FILTER_RX_MODE_REGULAR;
995*14b24e2bSVaishali Kulkarni 		}
996*14b24e2bSVaishali Kulkarni 		qede->params.promisc_fl = B_FALSE;
997*14b24e2bSVaishali Kulkarni 	}
998*14b24e2bSVaishali Kulkarni 
999*14b24e2bSVaishali Kulkarni 	ret = qede_set_filter_rx_mode(qede, mode);
1000*14b24e2bSVaishali Kulkarni 
1001*14b24e2bSVaishali Kulkarni exit:
1002*14b24e2bSVaishali Kulkarni 	mutex_exit(&qede->drv_lock);
1003*14b24e2bSVaishali Kulkarni     	return (ret);
1004*14b24e2bSVaishali Kulkarni }
1005*14b24e2bSVaishali Kulkarni 
1006*14b24e2bSVaishali Kulkarni int qede_set_rx_mac_mcast(qede_t *qede, enum ecore_filter_opcode opcode,
1007*14b24e2bSVaishali Kulkarni 			  uint8_t *mac, int mc_cnt)
1008*14b24e2bSVaishali Kulkarni {
1009*14b24e2bSVaishali Kulkarni 	struct ecore_filter_mcast cmd;
1010*14b24e2bSVaishali Kulkarni 	int i;
1011*14b24e2bSVaishali Kulkarni 	memset(&cmd, 0, sizeof(cmd));
1012*14b24e2bSVaishali Kulkarni 	cmd.opcode = opcode;
1013*14b24e2bSVaishali Kulkarni 	cmd.num_mc_addrs = mc_cnt;
1014*14b24e2bSVaishali Kulkarni 
1015*14b24e2bSVaishali Kulkarni         for (i = 0; i < mc_cnt; i++, mac += ETH_ALLEN) {
1016*14b24e2bSVaishali Kulkarni 		COPY_ETH_ADDRESS(mac, cmd.mac[i]);
1017*14b24e2bSVaishali Kulkarni         }
1018*14b24e2bSVaishali Kulkarni 
1019*14b24e2bSVaishali Kulkarni 
1020*14b24e2bSVaishali Kulkarni         return (ecore_filter_mcast_cmd(&qede->edev, &cmd,
1021*14b24e2bSVaishali Kulkarni 	    ECORE_SPQ_MODE_CB, NULL));
1022*14b24e2bSVaishali Kulkarni 
1023*14b24e2bSVaishali Kulkarni }
1024*14b24e2bSVaishali Kulkarni 
1025*14b24e2bSVaishali Kulkarni int
1026*14b24e2bSVaishali Kulkarni qede_set_filter_rx_mode(qede_t * qede, enum qede_filter_rx_mode_type type)
1027*14b24e2bSVaishali Kulkarni {
1028*14b24e2bSVaishali Kulkarni 	struct ecore_filter_accept_flags flg;
1029*14b24e2bSVaishali Kulkarni 
1030*14b24e2bSVaishali Kulkarni 	memset(&flg, 0, sizeof(flg));
1031*14b24e2bSVaishali Kulkarni 
1032*14b24e2bSVaishali Kulkarni 	flg.update_rx_mode_config      = 1;
1033*14b24e2bSVaishali Kulkarni 	flg.update_tx_mode_config      = 1;
1034*14b24e2bSVaishali Kulkarni 	flg.rx_accept_filter           = ECORE_ACCEPT_UCAST_MATCHED |
1035*14b24e2bSVaishali Kulkarni 	    ECORE_ACCEPT_MCAST_MATCHED | ECORE_ACCEPT_BCAST;
1036*14b24e2bSVaishali Kulkarni 	flg.tx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED |
1037*14b24e2bSVaishali Kulkarni 	    ECORE_ACCEPT_MCAST_MATCHED | ECORE_ACCEPT_BCAST;
1038*14b24e2bSVaishali Kulkarni 
1039*14b24e2bSVaishali Kulkarni 	if (type == QEDE_FILTER_RX_MODE_PROMISC)
1040*14b24e2bSVaishali Kulkarni 		flg.rx_accept_filter |= ECORE_ACCEPT_UCAST_UNMATCHED |
1041*14b24e2bSVaishali Kulkarni 		    ECORE_ACCEPT_MCAST_UNMATCHED;
1042*14b24e2bSVaishali Kulkarni 	else if (type == QEDE_FILTER_RX_MODE_MULTI_PROMISC)
1043*14b24e2bSVaishali Kulkarni 		flg.rx_accept_filter |= ECORE_ACCEPT_MCAST_UNMATCHED;
1044*14b24e2bSVaishali Kulkarni 	qede_info(qede, "rx_mode rx_filter=0x%x tx_filter=0x%x type=0x%x\n",
1045*14b24e2bSVaishali Kulkarni 	    flg.rx_accept_filter, flg.tx_accept_filter, type);
1046*14b24e2bSVaishali Kulkarni 	return (ecore_filter_accept_cmd(&qede->edev, 0, flg,
1047*14b24e2bSVaishali Kulkarni 			0, /* update_accept_any_vlan */
1048*14b24e2bSVaishali Kulkarni 			0, /* accept_any_vlan */
1049*14b24e2bSVaishali Kulkarni 			ECORE_SPQ_MODE_CB, NULL));
1050*14b24e2bSVaishali Kulkarni }
1051*14b24e2bSVaishali Kulkarni 
1052*14b24e2bSVaishali Kulkarni int
1053*14b24e2bSVaishali Kulkarni qede_multicast(qede_t *qede, boolean_t flag, const uint8_t *ptr_mcaddr)
1054*14b24e2bSVaishali Kulkarni {
1055*14b24e2bSVaishali Kulkarni 	int i, ret = DDI_SUCCESS;
1056*14b24e2bSVaishali Kulkarni 	qede_mcast_list_entry_t *ptr_mlist;
1057*14b24e2bSVaishali Kulkarni 	qede_mcast_list_entry_t *ptr_entry;
1058*14b24e2bSVaishali Kulkarni 	int mc_cnt;
1059*14b24e2bSVaishali Kulkarni 	unsigned char *mc_macs, *tmpmc;
1060*14b24e2bSVaishali Kulkarni 	size_t size;
1061*14b24e2bSVaishali Kulkarni 	boolean_t mcmac_exists = B_FALSE;
1062*14b24e2bSVaishali Kulkarni 	enum qede_filter_rx_mode_type mode;
1063*14b24e2bSVaishali Kulkarni 
1064*14b24e2bSVaishali Kulkarni 	if (!ptr_mcaddr)  {
1065*14b24e2bSVaishali Kulkarni 		cmn_err(CE_NOTE, "Removing all multicast");
1066*14b24e2bSVaishali Kulkarni 	} else  {
1067*14b24e2bSVaishali Kulkarni 		cmn_err(CE_NOTE,
1068*14b24e2bSVaishali Kulkarni 		    "qede=%p %s multicast: %02x:%02x:%02x:%02x:%02x:%02x",
1069*14b24e2bSVaishali Kulkarni 		    qede, (flag) ? "Adding" : "Removing", ptr_mcaddr[0],
1070*14b24e2bSVaishali Kulkarni 		    ptr_mcaddr[1],ptr_mcaddr[2],ptr_mcaddr[3],ptr_mcaddr[4],
1071*14b24e2bSVaishali Kulkarni 		    ptr_mcaddr[5]);
1072*14b24e2bSVaishali Kulkarni 	}
1073*14b24e2bSVaishali Kulkarni 
1074*14b24e2bSVaishali Kulkarni 
1075*14b24e2bSVaishali Kulkarni 	if (flag && (ptr_mcaddr == NULL)) {
1076*14b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN, "ERROR: Multicast address not specified");
1077*14b24e2bSVaishali Kulkarni 		return EINVAL;
1078*14b24e2bSVaishali Kulkarni 	}
1079*14b24e2bSVaishali Kulkarni 
1080*14b24e2bSVaishali Kulkarni 
1081*14b24e2bSVaishali Kulkarni 	/* exceeds addition of mcaddr above limit */
1082*14b24e2bSVaishali Kulkarni 	if (flag && (qede->mc_cnt >= MAX_MC_SOFT_LIMIT)) {
1083*14b24e2bSVaishali Kulkarni 		qede_info(qede, "Cannot add more than MAX_MC_SOFT_LIMIT");
1084*14b24e2bSVaishali Kulkarni 		return ENOENT;
1085*14b24e2bSVaishali Kulkarni 	}
1086*14b24e2bSVaishali Kulkarni 
1087*14b24e2bSVaishali Kulkarni 	size = MAX_MC_SOFT_LIMIT * ETH_ALLEN;
1088*14b24e2bSVaishali Kulkarni 
1089*14b24e2bSVaishali Kulkarni 	mc_macs = kmem_zalloc(size, KM_NOSLEEP);
1090*14b24e2bSVaishali Kulkarni 	if (!mc_macs) {
1091*14b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN, "ERROR: Failed to allocate for mc_macs");
1092*14b24e2bSVaishali Kulkarni 		return EINVAL;
1093*14b24e2bSVaishali Kulkarni 	}
1094*14b24e2bSVaishali Kulkarni 
1095*14b24e2bSVaishali Kulkarni 	tmpmc = mc_macs;
1096*14b24e2bSVaishali Kulkarni 
1097*14b24e2bSVaishali Kulkarni         /* remove all multicast - as flag not set and mcaddr not specified*/
1098*14b24e2bSVaishali Kulkarni         if (!flag && (ptr_mcaddr == NULL)) {
1099*14b24e2bSVaishali Kulkarni                 QEDE_LIST_FOR_EACH_ENTRY(ptr_entry,
1100*14b24e2bSVaishali Kulkarni 		    &qede->mclist.head, qede_mcast_list_entry_t, mclist_entry)
1101*14b24e2bSVaishali Kulkarni                 {
1102*14b24e2bSVaishali Kulkarni                         if (ptr_entry != NULL) {
1103*14b24e2bSVaishali Kulkarni                         QEDE_LIST_REMOVE(&ptr_entry->mclist_entry,
1104*14b24e2bSVaishali Kulkarni 			    &qede->mclist.head);
1105*14b24e2bSVaishali Kulkarni                         kmem_free(ptr_entry,
1106*14b24e2bSVaishali Kulkarni 			    sizeof (qede_mcast_list_entry_t) + ETH_ALLEN);
1107*14b24e2bSVaishali Kulkarni                         }
1108*14b24e2bSVaishali Kulkarni                 }
1109*14b24e2bSVaishali Kulkarni 
1110*14b24e2bSVaishali Kulkarni                 ret = qede_set_rx_mac_mcast(qede,
1111*14b24e2bSVaishali Kulkarni 		    ECORE_FILTER_REMOVE, mc_macs, 1);
1112*14b24e2bSVaishali Kulkarni                 qede->mc_cnt = 0;
1113*14b24e2bSVaishali Kulkarni                 goto exit;
1114*14b24e2bSVaishali Kulkarni         }
1115*14b24e2bSVaishali Kulkarni 
1116*14b24e2bSVaishali Kulkarni         QEDE_LIST_FOR_EACH_ENTRY(ptr_entry,
1117*14b24e2bSVaishali Kulkarni 	    &qede->mclist.head, qede_mcast_list_entry_t, mclist_entry)
1118*14b24e2bSVaishali Kulkarni         {
1119*14b24e2bSVaishali Kulkarni                 if ((ptr_entry != NULL) &&
1120*14b24e2bSVaishali Kulkarni 		    IS_ETH_ADDRESS_EQUAL(ptr_mcaddr, ptr_entry->mac)) {
1121*14b24e2bSVaishali Kulkarni                         mcmac_exists = B_TRUE;
1122*14b24e2bSVaishali Kulkarni                         break;
1123*14b24e2bSVaishali Kulkarni                 }
1124*14b24e2bSVaishali Kulkarni         }
1125*14b24e2bSVaishali Kulkarni         if (flag && mcmac_exists) {
1126*14b24e2bSVaishali Kulkarni                 ret = DDI_SUCCESS;
1127*14b24e2bSVaishali Kulkarni                 goto exit;
1128*14b24e2bSVaishali Kulkarni         } else if (!flag && !mcmac_exists) {
1129*14b24e2bSVaishali Kulkarni                 ret = DDI_SUCCESS;
1130*14b24e2bSVaishali Kulkarni                 goto exit;
1131*14b24e2bSVaishali Kulkarni         }
1132*14b24e2bSVaishali Kulkarni 
1133*14b24e2bSVaishali Kulkarni        if (flag) {
1134*14b24e2bSVaishali Kulkarni                 ptr_entry = kmem_zalloc((sizeof (qede_mcast_list_entry_t) +
1135*14b24e2bSVaishali Kulkarni 		    ETH_ALLEN), KM_NOSLEEP);
1136*14b24e2bSVaishali Kulkarni                 ptr_entry->mac = (uint8_t *)ptr_entry +
1137*14b24e2bSVaishali Kulkarni 		    sizeof (qede_mcast_list_entry_t);
1138*14b24e2bSVaishali Kulkarni                 COPY_ETH_ADDRESS(ptr_mcaddr, ptr_entry->mac);
1139*14b24e2bSVaishali Kulkarni                 QEDE_LIST_ADD(&ptr_entry->mclist_entry, &qede->mclist.head);
1140*14b24e2bSVaishali Kulkarni         } else {
1141*14b24e2bSVaishali Kulkarni                 QEDE_LIST_REMOVE(&ptr_entry->mclist_entry, &qede->mclist.head);
1142*14b24e2bSVaishali Kulkarni                 kmem_free(ptr_entry, sizeof(qede_mcast_list_entry_t) +
1143*14b24e2bSVaishali Kulkarni 		    ETH_ALLEN);
1144*14b24e2bSVaishali Kulkarni         }
1145*14b24e2bSVaishali Kulkarni 
1146*14b24e2bSVaishali Kulkarni 	mc_cnt = 0;
1147*14b24e2bSVaishali Kulkarni         QEDE_LIST_FOR_EACH_ENTRY(ptr_entry, &qede->mclist.head,
1148*14b24e2bSVaishali Kulkarni 	    qede_mcast_list_entry_t, mclist_entry) {
1149*14b24e2bSVaishali Kulkarni                 COPY_ETH_ADDRESS(ptr_entry->mac, tmpmc);
1150*14b24e2bSVaishali Kulkarni                 tmpmc += ETH_ALLEN;
1151*14b24e2bSVaishali Kulkarni                 mc_cnt++;
1152*14b24e2bSVaishali Kulkarni         }
1153*14b24e2bSVaishali Kulkarni         qede->mc_cnt = mc_cnt;
1154*14b24e2bSVaishali Kulkarni         if (mc_cnt <=64) {
1155*14b24e2bSVaishali Kulkarni                 ret = qede_set_rx_mac_mcast(qede, ECORE_FILTER_ADD,
1156*14b24e2bSVaishali Kulkarni 		    (unsigned char *)mc_macs, mc_cnt);
1157*14b24e2bSVaishali Kulkarni                 if ((qede->params.multi_promisc_fl == B_TRUE) &&
1158*14b24e2bSVaishali Kulkarni 		    (qede->params.promisc_fl == B_FALSE)) {
1159*14b24e2bSVaishali Kulkarni                         mode = QEDE_FILTER_RX_MODE_REGULAR;
1160*14b24e2bSVaishali Kulkarni                         ret = qede_set_filter_rx_mode(qede, mode);
1161*14b24e2bSVaishali Kulkarni                 }
1162*14b24e2bSVaishali Kulkarni                 qede->params.multi_promisc_fl = B_FALSE;
1163*14b24e2bSVaishali Kulkarni         } else {
1164*14b24e2bSVaishali Kulkarni                 if ((qede->params.multi_promisc_fl == B_FALSE) &&
1165*14b24e2bSVaishali Kulkarni 		    (qede->params.promisc_fl = B_FALSE)) {
1166*14b24e2bSVaishali Kulkarni                         ret = qede_set_filter_rx_mode(qede,
1167*14b24e2bSVaishali Kulkarni 			    QEDE_FILTER_RX_MODE_MULTI_PROMISC);
1168*14b24e2bSVaishali Kulkarni                 }
1169*14b24e2bSVaishali Kulkarni                 qede->params.multi_promisc_fl = B_TRUE;
1170*14b24e2bSVaishali Kulkarni                 qede_info(qede, "mode is MULTI_PROMISC");
1171*14b24e2bSVaishali Kulkarni         }
1172*14b24e2bSVaishali Kulkarni exit:
1173*14b24e2bSVaishali Kulkarni kmem_free(mc_macs, size);
1174*14b24e2bSVaishali Kulkarni qede_info(qede, "multicast ret %d mc_cnt %d\n", ret, qede->mc_cnt);
1175*14b24e2bSVaishali Kulkarni return (ret);
1176*14b24e2bSVaishali Kulkarni }
1177*14b24e2bSVaishali Kulkarni 
1178*14b24e2bSVaishali Kulkarni /*
1179*14b24e2bSVaishali Kulkarni  * This function is used to enable or disable multicast packet reception for
1180*14b24e2bSVaishali Kulkarni  * particular multicast addresses.
1181*14b24e2bSVaishali Kulkarni  * (flag) TRUE = add, FALSE = remove
1182*14b24e2bSVaishali Kulkarni  */
1183*14b24e2bSVaishali Kulkarni static int
1184*14b24e2bSVaishali Kulkarni qede_mac_multicast(void *arg,
1185*14b24e2bSVaishali Kulkarni     boolean_t       flag,
1186*14b24e2bSVaishali Kulkarni     const uint8_t * mcast_addr)
1187*14b24e2bSVaishali Kulkarni {
1188*14b24e2bSVaishali Kulkarni 	qede_t *qede = (qede_t *)arg;
1189*14b24e2bSVaishali Kulkarni 	int ret = DDI_SUCCESS;
1190*14b24e2bSVaishali Kulkarni 
1191*14b24e2bSVaishali Kulkarni 
1192*14b24e2bSVaishali Kulkarni 	mutex_enter(&qede->gld_lock);
1193*14b24e2bSVaishali Kulkarni 	if(qede->qede_state != QEDE_STATE_STARTED) {
1194*14b24e2bSVaishali Kulkarni 		mutex_exit(&qede->gld_lock);
1195*14b24e2bSVaishali Kulkarni 		return (EAGAIN);
1196*14b24e2bSVaishali Kulkarni 	}
1197*14b24e2bSVaishali Kulkarni 	ret = qede_multicast(qede, flag, mcast_addr);
1198*14b24e2bSVaishali Kulkarni 
1199*14b24e2bSVaishali Kulkarni 	mutex_exit(&qede->gld_lock);
1200*14b24e2bSVaishali Kulkarni 
1201*14b24e2bSVaishali Kulkarni     return (ret);
1202*14b24e2bSVaishali Kulkarni }
1203*14b24e2bSVaishali Kulkarni int
1204*14b24e2bSVaishali Kulkarni qede_clear_filters(qede_t *qede)
1205*14b24e2bSVaishali Kulkarni {
1206*14b24e2bSVaishali Kulkarni 	int ret = 0;
1207*14b24e2bSVaishali Kulkarni 	int i;
1208*14b24e2bSVaishali Kulkarni 	if ((qede->params.promisc_fl == B_TRUE) ||
1209*14b24e2bSVaishali Kulkarni 	    (qede->params.multi_promisc_fl == B_TRUE)) {
1210*14b24e2bSVaishali Kulkarni 		ret = qede_set_filter_rx_mode(qede,
1211*14b24e2bSVaishali Kulkarni 		    QEDE_FILTER_RX_MODE_REGULAR);
1212*14b24e2bSVaishali Kulkarni 		if (ret) {
1213*14b24e2bSVaishali Kulkarni 			qede_info(qede,
1214*14b24e2bSVaishali Kulkarni 			    "qede_clear_filters failed to set rx_mode");
1215*14b24e2bSVaishali Kulkarni 		}
1216*14b24e2bSVaishali Kulkarni 	}
1217*14b24e2bSVaishali Kulkarni 	for (i=0; i < qede->ucst_total; i++)
1218*14b24e2bSVaishali Kulkarni 	{
1219*14b24e2bSVaishali Kulkarni 		if (qede->ucst_mac[i].set) {
1220*14b24e2bSVaishali Kulkarni 			qede_rem_macaddr(qede,
1221*14b24e2bSVaishali Kulkarni 			    qede->ucst_mac[i].mac_addr.ether_addr_octet);
1222*14b24e2bSVaishali Kulkarni 		}
1223*14b24e2bSVaishali Kulkarni 	}
1224*14b24e2bSVaishali Kulkarni 	qede_multicast(qede, B_FALSE, NULL);
1225*14b24e2bSVaishali Kulkarni 	return (ret);
1226*14b24e2bSVaishali Kulkarni }
1227*14b24e2bSVaishali Kulkarni 
1228*14b24e2bSVaishali Kulkarni 
1229*14b24e2bSVaishali Kulkarni #ifdef  NO_CROSSBOW
1230*14b24e2bSVaishali Kulkarni static int
1231*14b24e2bSVaishali Kulkarni qede_mac_unicast(void *arg,
1232*14b24e2bSVaishali Kulkarni     const uint8_t * mac_addr)
1233*14b24e2bSVaishali Kulkarni {
1234*14b24e2bSVaishali Kulkarni     qede_t *qede = (qede_t *)arg;
1235*14b24e2bSVaishali Kulkarni     return 0;
1236*14b24e2bSVaishali Kulkarni }
1237*14b24e2bSVaishali Kulkarni 
1238*14b24e2bSVaishali Kulkarni 
1239*14b24e2bSVaishali Kulkarni static mblk_t *
1240*14b24e2bSVaishali Kulkarni qede_mac_tx(void *arg,
1241*14b24e2bSVaishali Kulkarni     mblk_t * mblk)
1242*14b24e2bSVaishali Kulkarni {
1243*14b24e2bSVaishali Kulkarni     qede_t *qede = (qede_t *)arg;
1244*14b24e2bSVaishali Kulkarni     qede_fastpath_t *fp = &qede->fp_array[0];
1245*14b24e2bSVaishali Kulkarni 
1246*14b24e2bSVaishali Kulkarni     mblk = qede_ring_tx((void *)fp, mblk);
1247*14b24e2bSVaishali Kulkarni 
1248*14b24e2bSVaishali Kulkarni     return (mblk);
1249*14b24e2bSVaishali Kulkarni }
1250*14b24e2bSVaishali Kulkarni #endif  /* NO_CROSSBOW */
1251*14b24e2bSVaishali Kulkarni 
1252*14b24e2bSVaishali Kulkarni 
1253*14b24e2bSVaishali Kulkarni static lb_property_t loopmodes[] = {
1254*14b24e2bSVaishali Kulkarni 	{ normal,       "normal",       QEDE_LOOP_NONE                },
1255*14b24e2bSVaishali Kulkarni 	{ internal,     "internal",     QEDE_LOOP_INTERNAL            },
1256*14b24e2bSVaishali Kulkarni 	{ external,     "external",     QEDE_LOOP_EXTERNAL            },
1257*14b24e2bSVaishali Kulkarni };
1258*14b24e2bSVaishali Kulkarni 
1259*14b24e2bSVaishali Kulkarni /*
1260*14b24e2bSVaishali Kulkarni  * Set Loopback mode
1261*14b24e2bSVaishali Kulkarni  */
1262*14b24e2bSVaishali Kulkarni 
1263*14b24e2bSVaishali Kulkarni static enum ioc_reply
1264*14b24e2bSVaishali Kulkarni qede_set_loopback_mode(qede_t *qede, uint32_t mode)
1265*14b24e2bSVaishali Kulkarni {
1266*14b24e2bSVaishali Kulkarni 	int ret, i = 0;
1267*14b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
1268*14b24e2bSVaishali Kulkarni 	struct ecore_hwfn *hwfn;
1269*14b24e2bSVaishali Kulkarni 	struct ecore_ptt *ptt = NULL;
1270*14b24e2bSVaishali Kulkarni 	struct ecore_mcp_link_params *link_params;
1271*14b24e2bSVaishali Kulkarni 
1272*14b24e2bSVaishali Kulkarni 	hwfn = &edev->hwfns[0];
1273*14b24e2bSVaishali Kulkarni 	link_params = ecore_mcp_get_link_params(hwfn);
1274*14b24e2bSVaishali Kulkarni 	ptt = ecore_ptt_acquire(hwfn);
1275*14b24e2bSVaishali Kulkarni 
1276*14b24e2bSVaishali Kulkarni 	switch(mode) {
1277*14b24e2bSVaishali Kulkarni 	default:
1278*14b24e2bSVaishali Kulkarni 		qede_info(qede, "unknown loopback mode !!");
1279*14b24e2bSVaishali Kulkarni 		ecore_ptt_release(hwfn, ptt);
1280*14b24e2bSVaishali Kulkarni 		return IOC_INVAL;
1281*14b24e2bSVaishali Kulkarni 
1282*14b24e2bSVaishali Kulkarni 	case QEDE_LOOP_NONE:
1283*14b24e2bSVaishali Kulkarni 		ecore_mcp_set_link(hwfn, ptt, 0);
1284*14b24e2bSVaishali Kulkarni 
1285*14b24e2bSVaishali Kulkarni 		while (qede->params.link_state && i < 5000) {
1286*14b24e2bSVaishali Kulkarni 			OSAL_MSLEEP(1);
1287*14b24e2bSVaishali Kulkarni 			i++;
1288*14b24e2bSVaishali Kulkarni 		}
1289*14b24e2bSVaishali Kulkarni 		i = 0;
1290*14b24e2bSVaishali Kulkarni 
1291*14b24e2bSVaishali Kulkarni 		link_params->loopback_mode = ETH_LOOPBACK_NONE;
1292*14b24e2bSVaishali Kulkarni 		qede->loop_back_mode = QEDE_LOOP_NONE;
1293*14b24e2bSVaishali Kulkarni 		ret = ecore_mcp_set_link(hwfn, ptt, 1);
1294*14b24e2bSVaishali Kulkarni 		ecore_ptt_release(hwfn, ptt);
1295*14b24e2bSVaishali Kulkarni 
1296*14b24e2bSVaishali Kulkarni 		while (!qede->params.link_state && i < 5000) {
1297*14b24e2bSVaishali Kulkarni 			OSAL_MSLEEP(1);
1298*14b24e2bSVaishali Kulkarni 			i++;
1299*14b24e2bSVaishali Kulkarni 		}
1300*14b24e2bSVaishali Kulkarni 		return IOC_REPLY;
1301*14b24e2bSVaishali Kulkarni 
1302*14b24e2bSVaishali Kulkarni 	case QEDE_LOOP_INTERNAL:
1303*14b24e2bSVaishali Kulkarni 		qede_print("!%s(%d) : loopback mode (INTERNAL) is set!",
1304*14b24e2bSVaishali Kulkarni 		    __func__, qede->instance);
1305*14b24e2bSVaishali Kulkarni 		    ecore_mcp_set_link(hwfn, ptt, 0);
1306*14b24e2bSVaishali Kulkarni 
1307*14b24e2bSVaishali Kulkarni 		while(qede->params.link_state && i < 5000) {
1308*14b24e2bSVaishali Kulkarni 			OSAL_MSLEEP(1);
1309*14b24e2bSVaishali Kulkarni 			i++;
1310*14b24e2bSVaishali Kulkarni 		}
1311*14b24e2bSVaishali Kulkarni 		i = 0;
1312*14b24e2bSVaishali Kulkarni 		link_params->loopback_mode = ETH_LOOPBACK_INT_PHY;
1313*14b24e2bSVaishali Kulkarni 		qede->loop_back_mode = QEDE_LOOP_INTERNAL;
1314*14b24e2bSVaishali Kulkarni 		ret = ecore_mcp_set_link(hwfn, ptt, 1);
1315*14b24e2bSVaishali Kulkarni 		ecore_ptt_release(hwfn, ptt);
1316*14b24e2bSVaishali Kulkarni 
1317*14b24e2bSVaishali Kulkarni 		while(!qede->params.link_state && i < 5000) {
1318*14b24e2bSVaishali Kulkarni 			OSAL_MSLEEP(1);
1319*14b24e2bSVaishali Kulkarni 			i++;
1320*14b24e2bSVaishali Kulkarni 		}
1321*14b24e2bSVaishali Kulkarni 		return IOC_REPLY;
1322*14b24e2bSVaishali Kulkarni 
1323*14b24e2bSVaishali Kulkarni 	case QEDE_LOOP_EXTERNAL:
1324*14b24e2bSVaishali Kulkarni 		qede_print("!%s(%d) : External loopback mode is not supported",
1325*14b24e2bSVaishali Kulkarni 		    __func__, qede->instance);
1326*14b24e2bSVaishali Kulkarni 		ecore_ptt_release(hwfn, ptt);
1327*14b24e2bSVaishali Kulkarni 		return IOC_INVAL;
1328*14b24e2bSVaishali Kulkarni 	}
1329*14b24e2bSVaishali Kulkarni }
1330*14b24e2bSVaishali Kulkarni 
1331*14b24e2bSVaishali Kulkarni static int
1332*14b24e2bSVaishali Kulkarni qede_ioctl_pcicfg_rd(qede_t *qede, u32 addr, void *data,
1333*14b24e2bSVaishali Kulkarni     int len)
1334*14b24e2bSVaishali Kulkarni {
1335*14b24e2bSVaishali Kulkarni 	u32 crb, actual_crb;
1336*14b24e2bSVaishali Kulkarni 	uint32_t ret = 0;
1337*14b24e2bSVaishali Kulkarni 	int cap_offset = 0, cap_id = 0, next_cap = 0;
1338*14b24e2bSVaishali Kulkarni 	ddi_acc_handle_t pci_cfg_handle  = qede->pci_cfg_handle;
1339*14b24e2bSVaishali Kulkarni 	qede_ioctl_data_t * data1 = (qede_ioctl_data_t *) data;
1340*14b24e2bSVaishali Kulkarni 
1341*14b24e2bSVaishali Kulkarni 	cap_offset = pci_config_get8(pci_cfg_handle, PCI_CONF_CAP_PTR);
1342*14b24e2bSVaishali Kulkarni 	while (cap_offset != 0) {
1343*14b24e2bSVaishali Kulkarni                 /* Check for an invalid PCI read. */
1344*14b24e2bSVaishali Kulkarni                 if (cap_offset == PCI_EINVAL8) {
1345*14b24e2bSVaishali Kulkarni                         return DDI_FAILURE;
1346*14b24e2bSVaishali Kulkarni                 }
1347*14b24e2bSVaishali Kulkarni 		cap_id = pci_config_get8(pci_cfg_handle, cap_offset);
1348*14b24e2bSVaishali Kulkarni 		if (cap_id == PCI_CAP_ID_PCI_E) {
1349*14b24e2bSVaishali Kulkarni 			/* PCIe expr capab struct found */
1350*14b24e2bSVaishali Kulkarni 			break;
1351*14b24e2bSVaishali Kulkarni 		} else {
1352*14b24e2bSVaishali Kulkarni 			next_cap = pci_config_get8(pci_cfg_handle,
1353*14b24e2bSVaishali Kulkarni 			    cap_offset + 1);
1354*14b24e2bSVaishali Kulkarni 			cap_offset = next_cap;
1355*14b24e2bSVaishali Kulkarni 		}
1356*14b24e2bSVaishali Kulkarni 	}
1357*14b24e2bSVaishali Kulkarni 
1358*14b24e2bSVaishali Kulkarni 	switch (len) {
1359*14b24e2bSVaishali Kulkarni 	case 1:
1360*14b24e2bSVaishali Kulkarni 		ret = pci_config_get8(qede->pci_cfg_handle, addr);
1361*14b24e2bSVaishali Kulkarni 		(void) memcpy(data, &ret, sizeof(uint8_t));
1362*14b24e2bSVaishali Kulkarni 		break;
1363*14b24e2bSVaishali Kulkarni 	case 2:
1364*14b24e2bSVaishali Kulkarni 		ret = pci_config_get16(qede->pci_cfg_handle, addr);
1365*14b24e2bSVaishali Kulkarni 		(void) memcpy(data, &ret, sizeof(uint16_t));
1366*14b24e2bSVaishali Kulkarni 		break;
1367*14b24e2bSVaishali Kulkarni 	case 4:
1368*14b24e2bSVaishali Kulkarni 		ret = pci_config_get32(qede->pci_cfg_handle, addr);
1369*14b24e2bSVaishali Kulkarni 		(void) memcpy(data, &ret, sizeof(uint32_t));
1370*14b24e2bSVaishali Kulkarni 		break;
1371*14b24e2bSVaishali Kulkarni 	default:
1372*14b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN, "bad length for pci config read\n");
1373*14b24e2bSVaishali Kulkarni 		return (1);
1374*14b24e2bSVaishali Kulkarni 	}
1375*14b24e2bSVaishali Kulkarni 	return (0);
1376*14b24e2bSVaishali Kulkarni }
1377*14b24e2bSVaishali Kulkarni 
1378*14b24e2bSVaishali Kulkarni static int
1379*14b24e2bSVaishali Kulkarni qede_ioctl_pcicfg_wr(qede_t *qede, u32 addr, void *data,
1380*14b24e2bSVaishali Kulkarni     int len)
1381*14b24e2bSVaishali Kulkarni {
1382*14b24e2bSVaishali Kulkarni 	uint16_t ret = 0;
1383*14b24e2bSVaishali Kulkarni 	int cap_offset = 0, cap_id = 0, next_cap = 0;
1384*14b24e2bSVaishali Kulkarni 	qede_ioctl_data_t * data1 = (qede_ioctl_data_t *) data;
1385*14b24e2bSVaishali Kulkarni 	ddi_acc_handle_t pci_cfg_handle  = qede->pci_cfg_handle;
1386*14b24e2bSVaishali Kulkarni #if 1
1387*14b24e2bSVaishali Kulkarni 	cap_offset = pci_config_get8(pci_cfg_handle, PCI_CONF_CAP_PTR);
1388*14b24e2bSVaishali Kulkarni 	while (cap_offset != 0) {
1389*14b24e2bSVaishali Kulkarni 		cap_id = pci_config_get8(pci_cfg_handle, cap_offset);
1390*14b24e2bSVaishali Kulkarni 		if (cap_id == PCI_CAP_ID_PCI_E) {
1391*14b24e2bSVaishali Kulkarni 			/* PCIe expr capab struct found */
1392*14b24e2bSVaishali Kulkarni 			break;
1393*14b24e2bSVaishali Kulkarni 		} else {
1394*14b24e2bSVaishali Kulkarni 			next_cap = pci_config_get8(pci_cfg_handle,
1395*14b24e2bSVaishali Kulkarni 			    cap_offset + 1);
1396*14b24e2bSVaishali Kulkarni 			cap_offset = next_cap;
1397*14b24e2bSVaishali Kulkarni 		}
1398*14b24e2bSVaishali Kulkarni 	}
1399*14b24e2bSVaishali Kulkarni #endif
1400*14b24e2bSVaishali Kulkarni 
1401*14b24e2bSVaishali Kulkarni 	switch(len) {
1402*14b24e2bSVaishali Kulkarni 	case 1:
1403*14b24e2bSVaishali Kulkarni 		pci_config_put8(qede->pci_cfg_handle, addr,
1404*14b24e2bSVaishali Kulkarni 		    *(char *)&(data));
1405*14b24e2bSVaishali Kulkarni 		break;
1406*14b24e2bSVaishali Kulkarni 	case 2:
1407*14b24e2bSVaishali Kulkarni 		ret = pci_config_get16(qede->pci_cfg_handle, addr);
1408*14b24e2bSVaishali Kulkarni 		ret = ret | *(uint16_t *)data1->uabc;
1409*14b24e2bSVaishali Kulkarni 
1410*14b24e2bSVaishali Kulkarni 		pci_config_put16(qede->pci_cfg_handle, addr,
1411*14b24e2bSVaishali Kulkarni 		    ret);
1412*14b24e2bSVaishali Kulkarni 		break;
1413*14b24e2bSVaishali Kulkarni 	case 4:
1414*14b24e2bSVaishali Kulkarni 		pci_config_put32(qede->pci_cfg_handle, addr, *(uint32_t *)data1->uabc);
1415*14b24e2bSVaishali Kulkarni 		break;
1416*14b24e2bSVaishali Kulkarni 
1417*14b24e2bSVaishali Kulkarni 	default:
1418*14b24e2bSVaishali Kulkarni 		return (1);
1419*14b24e2bSVaishali Kulkarni 	}
1420*14b24e2bSVaishali Kulkarni 	return (0);
1421*14b24e2bSVaishali Kulkarni }
1422*14b24e2bSVaishali Kulkarni 
1423*14b24e2bSVaishali Kulkarni static int
1424*14b24e2bSVaishali Kulkarni qede_ioctl_rd_wr_reg(qede_t *qede, void *data)
1425*14b24e2bSVaishali Kulkarni {
1426*14b24e2bSVaishali Kulkarni 	struct ecore_hwfn *p_hwfn;
1427*14b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
1428*14b24e2bSVaishali Kulkarni 	struct ecore_ptt *ptt;
1429*14b24e2bSVaishali Kulkarni 	qede_ioctl_data_t *data1 = (qede_ioctl_data_t *)data;
1430*14b24e2bSVaishali Kulkarni 	uint32_t ret = 0;
1431*14b24e2bSVaishali Kulkarni 	uint8_t cmd = (uint8_t) data1->unused1;
1432*14b24e2bSVaishali Kulkarni 	uint32_t addr = data1->off;
1433*14b24e2bSVaishali Kulkarni 	uint32_t val = *(uint32_t *)&data1->uabc[1];
1434*14b24e2bSVaishali Kulkarni 	uint32_t hwfn_index = *(uint32_t *)&data1->uabc[5];
1435*14b24e2bSVaishali Kulkarni 	uint32_t *reg_addr;
1436*14b24e2bSVaishali Kulkarni 
1437*14b24e2bSVaishali Kulkarni 	if (hwfn_index > qede->num_hwfns) {
1438*14b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN, "invalid hwfn index from application\n");
1439*14b24e2bSVaishali Kulkarni 		return (EINVAL);
1440*14b24e2bSVaishali Kulkarni 	}
1441*14b24e2bSVaishali Kulkarni 	p_hwfn = &edev->hwfns[hwfn_index];
1442*14b24e2bSVaishali Kulkarni 
1443*14b24e2bSVaishali Kulkarni 	switch(cmd) {
1444*14b24e2bSVaishali Kulkarni 	case QEDE_REG_READ:
1445*14b24e2bSVaishali Kulkarni 		ret = ecore_rd(p_hwfn, p_hwfn->p_main_ptt, addr);
1446*14b24e2bSVaishali Kulkarni 		(void) memcpy(data1->uabc, &ret, sizeof(uint32_t));
1447*14b24e2bSVaishali Kulkarni 		break;
1448*14b24e2bSVaishali Kulkarni 
1449*14b24e2bSVaishali Kulkarni 	case QEDE_REG_WRITE:
1450*14b24e2bSVaishali Kulkarni 		ecore_wr(p_hwfn, p_hwfn->p_main_ptt, addr, val);
1451*14b24e2bSVaishali Kulkarni 		break;
1452*14b24e2bSVaishali Kulkarni 
1453*14b24e2bSVaishali Kulkarni 	default:
1454*14b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN,
1455*14b24e2bSVaishali Kulkarni 		    "wrong command in register read/write from application\n");
1456*14b24e2bSVaishali Kulkarni 		break;
1457*14b24e2bSVaishali Kulkarni 	}
1458*14b24e2bSVaishali Kulkarni 	return (ret);
1459*14b24e2bSVaishali Kulkarni }
1460*14b24e2bSVaishali Kulkarni 
1461*14b24e2bSVaishali Kulkarni static int
1462*14b24e2bSVaishali Kulkarni qede_ioctl_rd_wr_nvram(qede_t *qede, mblk_t *mp)
1463*14b24e2bSVaishali Kulkarni {
1464*14b24e2bSVaishali Kulkarni 	qede_nvram_data_t *data1 = (qede_nvram_data_t *)(mp->b_cont->b_rptr);
1465*14b24e2bSVaishali Kulkarni 	qede_nvram_data_t *data2, *next_data;
1466*14b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
1467*14b24e2bSVaishali Kulkarni 	uint32_t ret = 0, hdr_size = 24, bytes_to_copy, copy_len = 0;
1468*14b24e2bSVaishali Kulkarni 	uint32_t copy_len1 = 0;
1469*14b24e2bSVaishali Kulkarni 	uint32_t addr = data1->off;
1470*14b24e2bSVaishali Kulkarni 	uint32_t size = data1->size, i, buf_size;
1471*14b24e2bSVaishali Kulkarni 	uint8_t cmd, cmd2;
1472*14b24e2bSVaishali Kulkarni 	uint8_t *buf, *tmp_buf;
1473*14b24e2bSVaishali Kulkarni 	mblk_t *mp1;
1474*14b24e2bSVaishali Kulkarni 
1475*14b24e2bSVaishali Kulkarni 	cmd = (uint8_t)data1->unused1;
1476*14b24e2bSVaishali Kulkarni 
1477*14b24e2bSVaishali Kulkarni 	switch(cmd) {
1478*14b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_READ:
1479*14b24e2bSVaishali Kulkarni 		buf = kmem_zalloc(size, GFP_KERNEL);
1480*14b24e2bSVaishali Kulkarni 		if(buf == NULL) {
1481*14b24e2bSVaishali Kulkarni 			cmn_err(CE_WARN, "memory allocation failed"
1482*14b24e2bSVaishali Kulkarni 			" in nvram read ioctl\n");
1483*14b24e2bSVaishali Kulkarni 			return (DDI_FAILURE);
1484*14b24e2bSVaishali Kulkarni 		}
1485*14b24e2bSVaishali Kulkarni 		ret = ecore_mcp_nvm_read(edev, addr, buf, data1->size);
1486*14b24e2bSVaishali Kulkarni 
1487*14b24e2bSVaishali Kulkarni 		copy_len = (MBLKL(mp->b_cont)) - hdr_size;
1488*14b24e2bSVaishali Kulkarni 		if(copy_len > size) {
1489*14b24e2bSVaishali Kulkarni 			(void) memcpy(data1->uabc, buf, size);
1490*14b24e2bSVaishali Kulkarni 			kmem_free(buf, size);
1491*14b24e2bSVaishali Kulkarni 			//OSAL_FREE(edev, buf);
1492*14b24e2bSVaishali Kulkarni 			ret = 0;
1493*14b24e2bSVaishali Kulkarni 			break;
1494*14b24e2bSVaishali Kulkarni 		}
1495*14b24e2bSVaishali Kulkarni 		(void) memcpy(data1->uabc, buf, copy_len);
1496*14b24e2bSVaishali Kulkarni 		bytes_to_copy = size - copy_len;
1497*14b24e2bSVaishali Kulkarni 		tmp_buf = ((uint8_t *)buf) + copy_len;
1498*14b24e2bSVaishali Kulkarni 		copy_len1 = copy_len;
1499*14b24e2bSVaishali Kulkarni 		mp1 = mp->b_cont;
1500*14b24e2bSVaishali Kulkarni 		mp1 = mp1->b_cont;
1501*14b24e2bSVaishali Kulkarni 
1502*14b24e2bSVaishali Kulkarni 		while (mp1) {
1503*14b24e2bSVaishali Kulkarni 			copy_len = MBLKL(mp1);
1504*14b24e2bSVaishali Kulkarni 			if(mp1->b_cont == NULL) {
1505*14b24e2bSVaishali Kulkarni 				copy_len = MBLKL(mp1) - 4;
1506*14b24e2bSVaishali Kulkarni 			}
1507*14b24e2bSVaishali Kulkarni 			data2 = (qede_nvram_data_t *)mp1->b_rptr;
1508*14b24e2bSVaishali Kulkarni 			if (copy_len > bytes_to_copy) {
1509*14b24e2bSVaishali Kulkarni 				(void) memcpy(data2->uabc, tmp_buf,
1510*14b24e2bSVaishali Kulkarni 				    bytes_to_copy);
1511*14b24e2bSVaishali Kulkarni 				kmem_free(buf, size);
1512*14b24e2bSVaishali Kulkarni 				//OSAL_FREE(edev, buf);
1513*14b24e2bSVaishali Kulkarni 				break;
1514*14b24e2bSVaishali Kulkarni 			}
1515*14b24e2bSVaishali Kulkarni 			(void) memcpy(data2->uabc, tmp_buf, copy_len);
1516*14b24e2bSVaishali Kulkarni 			tmp_buf = tmp_buf + copy_len;
1517*14b24e2bSVaishali Kulkarni 			copy_len += copy_len;
1518*14b24e2bSVaishali Kulkarni 			mp1 = mp1->b_cont;
1519*14b24e2bSVaishali Kulkarni 			bytes_to_copy = bytes_to_copy - copy_len;
1520*14b24e2bSVaishali Kulkarni 		}
1521*14b24e2bSVaishali Kulkarni 
1522*14b24e2bSVaishali Kulkarni 		kmem_free(buf, size);
1523*14b24e2bSVaishali Kulkarni 		//OSAL_FREE(edev, buf);
1524*14b24e2bSVaishali Kulkarni 		break;
1525*14b24e2bSVaishali Kulkarni 
1526*14b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_WRITE:
1527*14b24e2bSVaishali Kulkarni 		cmd2 = (uint8_t )data1->cmd2;
1528*14b24e2bSVaishali Kulkarni 		size = data1->size;
1529*14b24e2bSVaishali Kulkarni 		addr = data1->off;
1530*14b24e2bSVaishali Kulkarni 		buf_size =  size; //data1->buf_size;
1531*14b24e2bSVaishali Kulkarni 		//buf_size =  data1->buf_size;
1532*14b24e2bSVaishali Kulkarni 		ret = 0;
1533*14b24e2bSVaishali Kulkarni 
1534*14b24e2bSVaishali Kulkarni 		switch(cmd2){
1535*14b24e2bSVaishali Kulkarni 		case START_NVM_WRITE:
1536*14b24e2bSVaishali Kulkarni 			buf = kmem_zalloc(size, GFP_KERNEL);
1537*14b24e2bSVaishali Kulkarni 			//buf = qede->reserved_buf;
1538*14b24e2bSVaishali Kulkarni 			qede->nvm_buf_size = data1->size;
1539*14b24e2bSVaishali Kulkarni 			if(buf == NULL) {
1540*14b24e2bSVaishali Kulkarni 				cmn_err(CE_WARN,
1541*14b24e2bSVaishali Kulkarni 				"memory allocation failed in START_NVM_WRITE\n");
1542*14b24e2bSVaishali Kulkarni 				return DDI_FAILURE;
1543*14b24e2bSVaishali Kulkarni 			}
1544*14b24e2bSVaishali Kulkarni 			qede->nvm_buf_start = buf;
1545*14b24e2bSVaishali Kulkarni 			cmn_err(CE_NOTE,
1546*14b24e2bSVaishali Kulkarni 			    "buf = %p, size = %x\n", qede->nvm_buf_start, size);
1547*14b24e2bSVaishali Kulkarni 			qede->nvm_buf = buf;
1548*14b24e2bSVaishali Kulkarni 			qede->copy_len = 0;
1549*14b24e2bSVaishali Kulkarni 			//tmp_buf = buf + addr;
1550*14b24e2bSVaishali Kulkarni 			ret = 0;
1551*14b24e2bSVaishali Kulkarni 			break;
1552*14b24e2bSVaishali Kulkarni 
1553*14b24e2bSVaishali Kulkarni 		case ACCUMULATE_NVM_BUF:
1554*14b24e2bSVaishali Kulkarni 			tmp_buf = qede->nvm_buf;
1555*14b24e2bSVaishali Kulkarni 			copy_len = MBLKL(mp->b_cont) - hdr_size;
1556*14b24e2bSVaishali Kulkarni 			if(copy_len > buf_size) {
1557*14b24e2bSVaishali Kulkarni 			 	if (buf_size < qede->nvm_buf_size) {
1558*14b24e2bSVaishali Kulkarni 				(void) memcpy(tmp_buf, data1->uabc, buf_size);
1559*14b24e2bSVaishali Kulkarni 					qede->copy_len = qede->copy_len +
1560*14b24e2bSVaishali Kulkarni 					    buf_size;
1561*14b24e2bSVaishali Kulkarni 				} else {
1562*14b24e2bSVaishali Kulkarni 					(void) memcpy(tmp_buf,
1563*14b24e2bSVaishali Kulkarni 					    data1->uabc, qede->nvm_buf_size);
1564*14b24e2bSVaishali Kulkarni 					qede->copy_len =
1565*14b24e2bSVaishali Kulkarni 					    qede->copy_len + qede->nvm_buf_size;
1566*14b24e2bSVaishali Kulkarni 				}
1567*14b24e2bSVaishali Kulkarni 				tmp_buf = tmp_buf + buf_size;
1568*14b24e2bSVaishali Kulkarni 				qede->nvm_buf = tmp_buf;
1569*14b24e2bSVaishali Kulkarni 				//qede->copy_len = qede->copy_len + buf_size;
1570*14b24e2bSVaishali Kulkarni 				cmn_err(CE_NOTE,
1571*14b24e2bSVaishali Kulkarni 				    "buf_size from app = %x\n", copy_len);
1572*14b24e2bSVaishali Kulkarni 				ret = 0;
1573*14b24e2bSVaishali Kulkarni 				break;
1574*14b24e2bSVaishali Kulkarni 			}
1575*14b24e2bSVaishali Kulkarni 			(void) memcpy(tmp_buf, data1->uabc, copy_len);
1576*14b24e2bSVaishali Kulkarni 			tmp_buf = tmp_buf + copy_len;
1577*14b24e2bSVaishali Kulkarni 			bytes_to_copy = buf_size - copy_len;
1578*14b24e2bSVaishali Kulkarni 			mp1 = mp->b_cont;
1579*14b24e2bSVaishali Kulkarni 			mp1 = mp1->b_cont;
1580*14b24e2bSVaishali Kulkarni 			copy_len1 = copy_len;
1581*14b24e2bSVaishali Kulkarni 
1582*14b24e2bSVaishali Kulkarni 			while (mp1) {
1583*14b24e2bSVaishali Kulkarni 				copy_len = MBLKL(mp1);
1584*14b24e2bSVaishali Kulkarni 				if (mp1->b_cont == NULL) {
1585*14b24e2bSVaishali Kulkarni 					copy_len = MBLKL(mp1) - 4;
1586*14b24e2bSVaishali Kulkarni 				}
1587*14b24e2bSVaishali Kulkarni 				next_data = (qede_nvram_data_t *) mp1->b_rptr;
1588*14b24e2bSVaishali Kulkarni 				if (copy_len > bytes_to_copy){
1589*14b24e2bSVaishali Kulkarni 					(void) memcpy(tmp_buf, next_data->uabc,
1590*14b24e2bSVaishali Kulkarni 					    bytes_to_copy);
1591*14b24e2bSVaishali Kulkarni 					qede->copy_len = qede->copy_len +
1592*14b24e2bSVaishali Kulkarni 					    bytes_to_copy;
1593*14b24e2bSVaishali Kulkarni 					ret = 0;
1594*14b24e2bSVaishali Kulkarni 					break;
1595*14b24e2bSVaishali Kulkarni 				}
1596*14b24e2bSVaishali Kulkarni 				(void) memcpy(tmp_buf, next_data->uabc,
1597*14b24e2bSVaishali Kulkarni 				    copy_len);
1598*14b24e2bSVaishali Kulkarni 				qede->copy_len = qede->copy_len + copy_len;
1599*14b24e2bSVaishali Kulkarni 				tmp_buf = tmp_buf + copy_len;
1600*14b24e2bSVaishali Kulkarni 				copy_len = copy_len1 + copy_len;
1601*14b24e2bSVaishali Kulkarni 				bytes_to_copy = bytes_to_copy - copy_len;
1602*14b24e2bSVaishali Kulkarni 				mp1 = mp1->b_cont;
1603*14b24e2bSVaishali Kulkarni 			}
1604*14b24e2bSVaishali Kulkarni 			qede->nvm_buf = tmp_buf;
1605*14b24e2bSVaishali Kulkarni 			ret = 0;
1606*14b24e2bSVaishali Kulkarni 			break;
1607*14b24e2bSVaishali Kulkarni 
1608*14b24e2bSVaishali Kulkarni 		case STOP_NVM_WRITE:
1609*14b24e2bSVaishali Kulkarni 			//qede->nvm_buf = tmp_buf;
1610*14b24e2bSVaishali Kulkarni 			ret = 0;
1611*14b24e2bSVaishali Kulkarni 			break;
1612*14b24e2bSVaishali Kulkarni 		case READ_BUF:
1613*14b24e2bSVaishali Kulkarni 			tmp_buf = (uint8_t *)qede->nvm_buf_start;
1614*14b24e2bSVaishali Kulkarni 			for(i = 0; i < size ; i++){
1615*14b24e2bSVaishali Kulkarni 				cmn_err(CE_NOTE,
1616*14b24e2bSVaishali Kulkarni 				    "buff (%d) : %d\n", i, *tmp_buf);
1617*14b24e2bSVaishali Kulkarni 				tmp_buf ++;
1618*14b24e2bSVaishali Kulkarni 			}
1619*14b24e2bSVaishali Kulkarni 			ret = 0;
1620*14b24e2bSVaishali Kulkarni 			break;
1621*14b24e2bSVaishali Kulkarni 		}
1622*14b24e2bSVaishali Kulkarni 		break;
1623*14b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_PUT_FILE_DATA:
1624*14b24e2bSVaishali Kulkarni 		tmp_buf = qede->nvm_buf_start;
1625*14b24e2bSVaishali Kulkarni 		ret = ecore_mcp_nvm_write(edev, ECORE_PUT_FILE_DATA,
1626*14b24e2bSVaishali Kulkarni 			  addr, tmp_buf, size);
1627*14b24e2bSVaishali Kulkarni 		kmem_free(qede->nvm_buf_start, size);
1628*14b24e2bSVaishali Kulkarni 		//OSAL_FREE(edev, tmp_buf);
1629*14b24e2bSVaishali Kulkarni 		cmn_err(CE_NOTE, "total size = %x, copied size = %x\n",
1630*14b24e2bSVaishali Kulkarni 		    qede->nvm_buf_size, qede->copy_len);
1631*14b24e2bSVaishali Kulkarni 		tmp_buf = NULL;
1632*14b24e2bSVaishali Kulkarni 		qede->nvm_buf = NULL;
1633*14b24e2bSVaishali Kulkarni 		qede->nvm_buf_start = NULL;
1634*14b24e2bSVaishali Kulkarni 		ret = 0;
1635*14b24e2bSVaishali Kulkarni 		break;
1636*14b24e2bSVaishali Kulkarni 
1637*14b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_SET_SECURE_MODE:
1638*14b24e2bSVaishali Kulkarni 		ret = ecore_mcp_nvm_set_secure_mode(edev, addr);
1639*14b24e2bSVaishali Kulkarni 		break;
1640*14b24e2bSVaishali Kulkarni 
1641*14b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_DEL_FILE:
1642*14b24e2bSVaishali Kulkarni 		ret = ecore_mcp_nvm_del_file(edev, addr);
1643*14b24e2bSVaishali Kulkarni 		break;
1644*14b24e2bSVaishali Kulkarni 
1645*14b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_PUT_FILE_BEGIN:
1646*14b24e2bSVaishali Kulkarni 		ret = ecore_mcp_nvm_put_file_begin(edev, addr);
1647*14b24e2bSVaishali Kulkarni 		break;
1648*14b24e2bSVaishali Kulkarni 
1649*14b24e2bSVaishali Kulkarni 	case QEDE_NVRAM_CMD_GET_NVRAM_RESP:
1650*14b24e2bSVaishali Kulkarni 		buf = kmem_zalloc(size, KM_SLEEP);
1651*14b24e2bSVaishali Kulkarni 		ret = ecore_mcp_nvm_resp(edev, buf);
1652*14b24e2bSVaishali Kulkarni 		(void)memcpy(data1->uabc, buf, size);
1653*14b24e2bSVaishali Kulkarni 		kmem_free(buf, size);
1654*14b24e2bSVaishali Kulkarni 		break;
1655*14b24e2bSVaishali Kulkarni 
1656*14b24e2bSVaishali Kulkarni 	default:
1657*14b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN,
1658*14b24e2bSVaishali Kulkarni 		    "wrong command in NVRAM read/write from application\n");
1659*14b24e2bSVaishali Kulkarni 		break;
1660*14b24e2bSVaishali Kulkarni 	}
1661*14b24e2bSVaishali Kulkarni 	return (DDI_SUCCESS);
1662*14b24e2bSVaishali Kulkarni }
1663*14b24e2bSVaishali Kulkarni 
1664*14b24e2bSVaishali Kulkarni static int
1665*14b24e2bSVaishali Kulkarni qede_get_func_info(qede_t *qede, void *data)
1666*14b24e2bSVaishali Kulkarni {
1667*14b24e2bSVaishali Kulkarni 	qede_link_output_t link_op;
1668*14b24e2bSVaishali Kulkarni 	qede_func_info_t func_info;
1669*14b24e2bSVaishali Kulkarni 	qede_ioctl_data_t *data1 = (qede_ioctl_data_t *)data;
1670*14b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
1671*14b24e2bSVaishali Kulkarni 	struct ecore_hwfn *hwfn;
1672*14b24e2bSVaishali Kulkarni 	struct ecore_mcp_link_params params;
1673*14b24e2bSVaishali Kulkarni 	struct ecore_mcp_link_state link;
1674*14b24e2bSVaishali Kulkarni 
1675*14b24e2bSVaishali Kulkarni 	hwfn = &edev->hwfns[0];
1676*14b24e2bSVaishali Kulkarni 
1677*14b24e2bSVaishali Kulkarni 	if(hwfn == NULL){
1678*14b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN, "(%s) : cannot acquire hwfn\n",
1679*14b24e2bSVaishali Kulkarni 		    __func__);
1680*14b24e2bSVaishali Kulkarni 		return (DDI_FAILURE);
1681*14b24e2bSVaishali Kulkarni 	}
1682*14b24e2bSVaishali Kulkarni 	memcpy(&params, &hwfn->mcp_info->link_input, sizeof(params));
1683*14b24e2bSVaishali Kulkarni 	memcpy(&link, &hwfn->mcp_info->link_output, sizeof(link));
1684*14b24e2bSVaishali Kulkarni 
1685*14b24e2bSVaishali Kulkarni 	if(link.link_up) {
1686*14b24e2bSVaishali Kulkarni 		link_op.link_up = true;
1687*14b24e2bSVaishali Kulkarni 	}
1688*14b24e2bSVaishali Kulkarni 
1689*14b24e2bSVaishali Kulkarni 	link_op.supported_caps = SUPPORTED_FIBRE;
1690*14b24e2bSVaishali Kulkarni 	if(params.speed.autoneg) {
1691*14b24e2bSVaishali Kulkarni 		link_op.supported_caps |= SUPPORTED_Autoneg;
1692*14b24e2bSVaishali Kulkarni 	}
1693*14b24e2bSVaishali Kulkarni 
1694*14b24e2bSVaishali Kulkarni 	if(params.pause.autoneg ||
1695*14b24e2bSVaishali Kulkarni 	    (params.pause.forced_rx && params.pause.forced_tx)) {
1696*14b24e2bSVaishali Kulkarni 		link_op.supported_caps |= SUPPORTED_Asym_Pause;
1697*14b24e2bSVaishali Kulkarni 	}
1698*14b24e2bSVaishali Kulkarni 
1699*14b24e2bSVaishali Kulkarni 	if (params.pause.autoneg || params.pause.forced_rx ||
1700*14b24e2bSVaishali Kulkarni 	     params.pause.forced_tx) {
1701*14b24e2bSVaishali Kulkarni 		link_op.supported_caps |= SUPPORTED_Pause;
1702*14b24e2bSVaishali Kulkarni 	}
1703*14b24e2bSVaishali Kulkarni 
1704*14b24e2bSVaishali Kulkarni 	if (params.speed.advertised_speeds &
1705*14b24e2bSVaishali Kulkarni 	    NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) {
1706*14b24e2bSVaishali Kulkarni 		link_op.supported_caps |= SUPPORTED_1000baseT_Half |
1707*14b24e2bSVaishali Kulkarni 	    	    SUPPORTED_1000baseT_Full;
1708*14b24e2bSVaishali Kulkarni 	}
1709*14b24e2bSVaishali Kulkarni 
1710*14b24e2bSVaishali Kulkarni 	if (params.speed.advertised_speeds &
1711*14b24e2bSVaishali Kulkarni 	    NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) {
1712*14b24e2bSVaishali Kulkarni 		link_op.supported_caps |= SUPPORTED_10000baseKR_Full;
1713*14b24e2bSVaishali Kulkarni 	}
1714*14b24e2bSVaishali Kulkarni 
1715*14b24e2bSVaishali Kulkarni 	if (params.speed.advertised_speeds &
1716*14b24e2bSVaishali Kulkarni 	    NVM_CFG1_PORT_DRV_LINK_SPEED_40G) {
1717*14b24e2bSVaishali Kulkarni 		link_op.supported_caps |= SUPPORTED_40000baseLR4_Full;
1718*14b24e2bSVaishali Kulkarni 	}
1719*14b24e2bSVaishali Kulkarni 
1720*14b24e2bSVaishali Kulkarni 	link_op.advertised_caps = link_op.supported_caps;
1721*14b24e2bSVaishali Kulkarni 
1722*14b24e2bSVaishali Kulkarni 	if(link.link_up) {
1723*14b24e2bSVaishali Kulkarni 		link_op.speed = link.speed;
1724*14b24e2bSVaishali Kulkarni 	} else {
1725*14b24e2bSVaishali Kulkarni 		link_op.speed = 0;
1726*14b24e2bSVaishali Kulkarni 	}
1727*14b24e2bSVaishali Kulkarni 
1728*14b24e2bSVaishali Kulkarni 	link_op.duplex = DUPLEX_FULL;
1729*14b24e2bSVaishali Kulkarni 	link_op.port = PORT_FIBRE;
1730*14b24e2bSVaishali Kulkarni 
1731*14b24e2bSVaishali Kulkarni 	link_op.autoneg = params.speed.autoneg;
1732*14b24e2bSVaishali Kulkarni 
1733*14b24e2bSVaishali Kulkarni 	/* Link partner capabilities */
1734*14b24e2bSVaishali Kulkarni 	if (link.partner_adv_speed &
1735*14b24e2bSVaishali Kulkarni 	    ECORE_LINK_PARTNER_SPEED_1G_HD) {
1736*14b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_1000baseT_Half;
1737*14b24e2bSVaishali Kulkarni 	}
1738*14b24e2bSVaishali Kulkarni 
1739*14b24e2bSVaishali Kulkarni 	if (link.partner_adv_speed &
1740*14b24e2bSVaishali Kulkarni 	    ECORE_LINK_PARTNER_SPEED_1G_FD) {
1741*14b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_1000baseT_Full;
1742*14b24e2bSVaishali Kulkarni 	}
1743*14b24e2bSVaishali Kulkarni 
1744*14b24e2bSVaishali Kulkarni 	if (link.partner_adv_speed &
1745*14b24e2bSVaishali Kulkarni 	    ECORE_LINK_PARTNER_SPEED_10G) {
1746*14b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_10000baseKR_Full;
1747*14b24e2bSVaishali Kulkarni 	}
1748*14b24e2bSVaishali Kulkarni 
1749*14b24e2bSVaishali Kulkarni 	if (link.partner_adv_speed &
1750*14b24e2bSVaishali Kulkarni 	    ECORE_LINK_PARTNER_SPEED_20G) {
1751*14b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_20000baseKR2_Full;
1752*14b24e2bSVaishali Kulkarni 	}
1753*14b24e2bSVaishali Kulkarni 
1754*14b24e2bSVaishali Kulkarni 	if (link.partner_adv_speed &
1755*14b24e2bSVaishali Kulkarni 	    ECORE_LINK_PARTNER_SPEED_40G) {
1756*14b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_40000baseLR4_Full;
1757*14b24e2bSVaishali Kulkarni 	}
1758*14b24e2bSVaishali Kulkarni 
1759*14b24e2bSVaishali Kulkarni 	if (link.an_complete) {
1760*14b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_Autoneg;
1761*14b24e2bSVaishali Kulkarni 	}
1762*14b24e2bSVaishali Kulkarni 
1763*14b24e2bSVaishali Kulkarni 	if (link.partner_adv_pause) {
1764*14b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_Pause;
1765*14b24e2bSVaishali Kulkarni 	}
1766*14b24e2bSVaishali Kulkarni 
1767*14b24e2bSVaishali Kulkarni 	if (link.partner_adv_pause == ECORE_LINK_PARTNER_ASYMMETRIC_PAUSE ||
1768*14b24e2bSVaishali Kulkarni 	    link.partner_adv_pause == ECORE_LINK_PARTNER_BOTH_PAUSE) {
1769*14b24e2bSVaishali Kulkarni 		link_op.lp_caps |= SUPPORTED_Asym_Pause;
1770*14b24e2bSVaishali Kulkarni 	}
1771*14b24e2bSVaishali Kulkarni 
1772*14b24e2bSVaishali Kulkarni 	func_info.supported = link_op.supported_caps;
1773*14b24e2bSVaishali Kulkarni 	func_info.advertising = link_op.advertised_caps;
1774*14b24e2bSVaishali Kulkarni 	func_info.speed = link_op.speed;
1775*14b24e2bSVaishali Kulkarni 	func_info.duplex = link_op.duplex;
1776*14b24e2bSVaishali Kulkarni 	func_info.port = qede->pci_func & 0x1;
1777*14b24e2bSVaishali Kulkarni 	func_info.autoneg = link_op.autoneg;
1778*14b24e2bSVaishali Kulkarni 
1779*14b24e2bSVaishali Kulkarni 	(void) memcpy(data1->uabc, &func_info, sizeof(qede_func_info_t));
1780*14b24e2bSVaishali Kulkarni 
1781*14b24e2bSVaishali Kulkarni 	return (0);
1782*14b24e2bSVaishali Kulkarni }
1783*14b24e2bSVaishali Kulkarni 
1784*14b24e2bSVaishali Kulkarni static int
1785*14b24e2bSVaishali Kulkarni qede_do_ioctl(qede_t *qede, queue_t *q, mblk_t *mp)
1786*14b24e2bSVaishali Kulkarni {
1787*14b24e2bSVaishali Kulkarni 	qede_ioctl_data_t *up_data;
1788*14b24e2bSVaishali Kulkarni 	qede_driver_info_t driver_info;
1789*14b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
1790*14b24e2bSVaishali Kulkarni 	struct ecore_hwfn *hwfn;
1791*14b24e2bSVaishali Kulkarni 	struct ecore_ptt *ptt = NULL;
1792*14b24e2bSVaishali Kulkarni 	struct mcp_file_att attrib;
1793*14b24e2bSVaishali Kulkarni 	uint32_t flash_size;
1794*14b24e2bSVaishali Kulkarni 	uint32_t mcp_resp, mcp_param, txn_size;
1795*14b24e2bSVaishali Kulkarni 	uint32_t cmd, size, ret = 0;
1796*14b24e2bSVaishali Kulkarni 	uint64_t off;
1797*14b24e2bSVaishali Kulkarni 	int * up_data1;
1798*14b24e2bSVaishali Kulkarni 	void * ptr;
1799*14b24e2bSVaishali Kulkarni 	mblk_t *mp1 = mp;
1800*14b24e2bSVaishali Kulkarni 	char mac_addr[32];
1801*14b24e2bSVaishali Kulkarni 
1802*14b24e2bSVaishali Kulkarni 	up_data = (qede_ioctl_data_t *)(mp->b_cont->b_rptr);
1803*14b24e2bSVaishali Kulkarni 
1804*14b24e2bSVaishali Kulkarni 	cmd = up_data->cmd;
1805*14b24e2bSVaishali Kulkarni 	off = up_data->off;
1806*14b24e2bSVaishali Kulkarni 	size = up_data->size;
1807*14b24e2bSVaishali Kulkarni 
1808*14b24e2bSVaishali Kulkarni 	switch (cmd) {
1809*14b24e2bSVaishali Kulkarni 	case QEDE_DRV_INFO:
1810*14b24e2bSVaishali Kulkarni 		hwfn = &edev->hwfns[0];
1811*14b24e2bSVaishali Kulkarni 		ptt = ecore_ptt_acquire(hwfn);
1812*14b24e2bSVaishali Kulkarni 
1813*14b24e2bSVaishali Kulkarni 		snprintf(driver_info.drv_name, MAX_QEDE_NAME_LEN, "%s", "qede");
1814*14b24e2bSVaishali Kulkarni 		snprintf(driver_info.drv_version, QEDE_STR_SIZE,
1815*14b24e2bSVaishali Kulkarni 		    "v:%s", qede->version);
1816*14b24e2bSVaishali Kulkarni 		snprintf(driver_info.mfw_version, QEDE_STR_SIZE,
1817*14b24e2bSVaishali Kulkarni 		    "%s", qede->versionMFW);
1818*14b24e2bSVaishali Kulkarni 		snprintf(driver_info.stormfw_version, QEDE_STR_SIZE,
1819*14b24e2bSVaishali Kulkarni 		    "%s", qede->versionFW);
1820*14b24e2bSVaishali Kulkarni 		snprintf(driver_info.bus_info, QEDE_STR_SIZE,
1821*14b24e2bSVaishali Kulkarni 		    "%s", qede->bus_dev_func);
1822*14b24e2bSVaishali Kulkarni 
1823*14b24e2bSVaishali Kulkarni 
1824*14b24e2bSVaishali Kulkarni 		/*
1825*14b24e2bSVaishali Kulkarni 		 * calling ecore_mcp_nvm_rd_cmd to find the flash length, i
1826*14b24e2bSVaishali Kulkarni 		 * 0x08 is equivalent of NVM_TYPE_MFW_TRACE1
1827*14b24e2bSVaishali Kulkarni 		 */
1828*14b24e2bSVaishali Kulkarni 		ecore_mcp_get_flash_size(hwfn, ptt, &flash_size);
1829*14b24e2bSVaishali Kulkarni 		driver_info.eeprom_dump_len = flash_size;
1830*14b24e2bSVaishali Kulkarni 		(void) memcpy(up_data->uabc, &driver_info,
1831*14b24e2bSVaishali Kulkarni 		    sizeof (qede_driver_info_t));
1832*14b24e2bSVaishali Kulkarni 		up_data->size = sizeof (qede_driver_info_t);
1833*14b24e2bSVaishali Kulkarni 
1834*14b24e2bSVaishali Kulkarni 		ecore_ptt_release(hwfn, ptt);
1835*14b24e2bSVaishali Kulkarni 		break;
1836*14b24e2bSVaishali Kulkarni 
1837*14b24e2bSVaishali Kulkarni 	case QEDE_RD_PCICFG:
1838*14b24e2bSVaishali Kulkarni 		ret = qede_ioctl_pcicfg_rd(qede, off, up_data->uabc, size);
1839*14b24e2bSVaishali Kulkarni 		break;
1840*14b24e2bSVaishali Kulkarni 
1841*14b24e2bSVaishali Kulkarni 	case QEDE_WR_PCICFG:
1842*14b24e2bSVaishali Kulkarni 		ret = qede_ioctl_pcicfg_wr(qede, off, up_data, size);
1843*14b24e2bSVaishali Kulkarni 		break;
1844*14b24e2bSVaishali Kulkarni 
1845*14b24e2bSVaishali Kulkarni 	case QEDE_RW_REG:
1846*14b24e2bSVaishali Kulkarni 		ret = qede_ioctl_rd_wr_reg(qede, (void *)up_data);
1847*14b24e2bSVaishali Kulkarni 	       	break;
1848*14b24e2bSVaishali Kulkarni 
1849*14b24e2bSVaishali Kulkarni 	case QEDE_RW_NVRAM:
1850*14b24e2bSVaishali Kulkarni 		ret = qede_ioctl_rd_wr_nvram(qede, mp1);
1851*14b24e2bSVaishali Kulkarni 		break;
1852*14b24e2bSVaishali Kulkarni 
1853*14b24e2bSVaishali Kulkarni 	case QEDE_FUNC_INFO:
1854*14b24e2bSVaishali Kulkarni 		ret = qede_get_func_info(qede, (void *)up_data);
1855*14b24e2bSVaishali Kulkarni 		break;
1856*14b24e2bSVaishali Kulkarni 
1857*14b24e2bSVaishali Kulkarni 	case QEDE_MAC_ADDR:
1858*14b24e2bSVaishali Kulkarni 		snprintf(mac_addr, sizeof(mac_addr),
1859*14b24e2bSVaishali Kulkarni 			"%02x:%02x:%02x:%02x:%02x:%02x",
1860*14b24e2bSVaishali Kulkarni 			qede->ether_addr[0], qede->ether_addr[1],
1861*14b24e2bSVaishali Kulkarni 			qede->ether_addr[2], qede->ether_addr[3],
1862*14b24e2bSVaishali Kulkarni 			qede->ether_addr[4], qede->ether_addr[5]);
1863*14b24e2bSVaishali Kulkarni 		(void) memcpy(up_data->uabc, &mac_addr, sizeof(mac_addr));
1864*14b24e2bSVaishali Kulkarni 		break;
1865*14b24e2bSVaishali Kulkarni 
1866*14b24e2bSVaishali Kulkarni 	}
1867*14b24e2bSVaishali Kulkarni 	//if (cmd == QEDE_RW_NVRAM) {
1868*14b24e2bSVaishali Kulkarni 	//	miocack (q, mp, (sizeof(qede_ioctl_data_t)), 0);
1869*14b24e2bSVaishali Kulkarni 	//	return IOC_REPLY;
1870*14b24e2bSVaishali Kulkarni 	//}
1871*14b24e2bSVaishali Kulkarni 	miocack (q, mp, (sizeof(qede_ioctl_data_t)), ret);
1872*14b24e2bSVaishali Kulkarni 	//miocack (q, mp, 0, ret);
1873*14b24e2bSVaishali Kulkarni 	return (IOC_REPLY);
1874*14b24e2bSVaishali Kulkarni }
1875*14b24e2bSVaishali Kulkarni 
1876*14b24e2bSVaishali Kulkarni static void
1877*14b24e2bSVaishali Kulkarni qede_ioctl(qede_t *qede, int cmd, queue_t *q, mblk_t *mp)
1878*14b24e2bSVaishali Kulkarni {
1879*14b24e2bSVaishali Kulkarni 	void *ptr;
1880*14b24e2bSVaishali Kulkarni 
1881*14b24e2bSVaishali Kulkarni 	switch(cmd) {
1882*14b24e2bSVaishali Kulkarni 	case QEDE_CMD:
1883*14b24e2bSVaishali Kulkarni 		(void) qede_do_ioctl(qede, q, mp);
1884*14b24e2bSVaishali Kulkarni 		break;
1885*14b24e2bSVaishali Kulkarni 	default :
1886*14b24e2bSVaishali Kulkarni 		cmn_err(CE_WARN, "qede ioctl command %x not supported\n", cmd);
1887*14b24e2bSVaishali Kulkarni 		break;
1888*14b24e2bSVaishali Kulkarni 	}
1889*14b24e2bSVaishali Kulkarni 	return;
1890*14b24e2bSVaishali Kulkarni }
1891*14b24e2bSVaishali Kulkarni enum ioc_reply
1892*14b24e2bSVaishali Kulkarni qede_loopback_ioctl(qede_t *qede, queue_t *wq, mblk_t *mp,
1893*14b24e2bSVaishali Kulkarni     struct iocblk *iocp)
1894*14b24e2bSVaishali Kulkarni {
1895*14b24e2bSVaishali Kulkarni 	lb_info_sz_t *lb_info_size;
1896*14b24e2bSVaishali Kulkarni 	lb_property_t *lb_prop;
1897*14b24e2bSVaishali Kulkarni 	uint32_t *lb_mode;
1898*14b24e2bSVaishali Kulkarni 	int cmd;
1899*14b24e2bSVaishali Kulkarni 
1900*14b24e2bSVaishali Kulkarni 	/*
1901*14b24e2bSVaishali Kulkarni 	 * Validate format of ioctl
1902*14b24e2bSVaishali Kulkarni 	 */
1903*14b24e2bSVaishali Kulkarni 	if(mp->b_cont == NULL) {
1904*14b24e2bSVaishali Kulkarni 		return IOC_INVAL;
1905*14b24e2bSVaishali Kulkarni 	}
1906*14b24e2bSVaishali Kulkarni 
1907*14b24e2bSVaishali Kulkarni 	cmd = iocp->ioc_cmd;
1908*14b24e2bSVaishali Kulkarni 
1909*14b24e2bSVaishali Kulkarni 	switch(cmd) {
1910*14b24e2bSVaishali Kulkarni 	default:
1911*14b24e2bSVaishali Kulkarni 		qede_print("!%s(%d): unknown ioctl command %x\n",
1912*14b24e2bSVaishali Kulkarni 		    __func__, qede->instance, cmd);
1913*14b24e2bSVaishali Kulkarni 		return IOC_INVAL;
1914*14b24e2bSVaishali Kulkarni 	case LB_GET_INFO_SIZE:
1915*14b24e2bSVaishali Kulkarni 		if (iocp->ioc_count != sizeof(lb_info_sz_t)) {
1916*14b24e2bSVaishali Kulkarni 			qede_info(qede, "error: ioc_count %d, sizeof %d",
1917*14b24e2bSVaishali Kulkarni 			    iocp->ioc_count,  sizeof(lb_info_sz_t));
1918*14b24e2bSVaishali Kulkarni 			return IOC_INVAL;
1919*14b24e2bSVaishali Kulkarni 		}
1920*14b24e2bSVaishali Kulkarni 		lb_info_size = (void *)mp->b_cont->b_rptr;
1921*14b24e2bSVaishali Kulkarni 		*lb_info_size = sizeof(loopmodes);
1922*14b24e2bSVaishali Kulkarni 		return IOC_REPLY;
1923*14b24e2bSVaishali Kulkarni 	case LB_GET_INFO:
1924*14b24e2bSVaishali Kulkarni 		if (iocp->ioc_count != sizeof (loopmodes)) {
1925*14b24e2bSVaishali Kulkarni 			qede_info(qede, "error: iocp->ioc_count %d, sizepof %d",
1926*14b24e2bSVaishali Kulkarni 			    iocp->ioc_count,  sizeof (loopmodes));
1927*14b24e2bSVaishali Kulkarni 			return (IOC_INVAL);
1928*14b24e2bSVaishali Kulkarni 		}
1929*14b24e2bSVaishali Kulkarni 		lb_prop = (void *)mp->b_cont->b_rptr;
1930*14b24e2bSVaishali Kulkarni 		bcopy(loopmodes, lb_prop, sizeof (loopmodes));
1931*14b24e2bSVaishali Kulkarni 		return IOC_REPLY;
1932*14b24e2bSVaishali Kulkarni 	case LB_GET_MODE:
1933*14b24e2bSVaishali Kulkarni 		if (iocp->ioc_count != sizeof (uint32_t)) {
1934*14b24e2bSVaishali Kulkarni 			qede_info(qede, "iocp->ioc_count %d, sizeof : %d\n",
1935*14b24e2bSVaishali Kulkarni 			    iocp->ioc_count, sizeof (uint32_t));
1936*14b24e2bSVaishali Kulkarni 			return (IOC_INVAL);
1937*14b24e2bSVaishali Kulkarni 		}
1938*14b24e2bSVaishali Kulkarni 		lb_mode = (void *)mp->b_cont->b_rptr;
1939*14b24e2bSVaishali Kulkarni 		*lb_mode = qede->loop_back_mode;
1940*14b24e2bSVaishali Kulkarni 		return IOC_REPLY;
1941*14b24e2bSVaishali Kulkarni 	case LB_SET_MODE:
1942*14b24e2bSVaishali Kulkarni 		if (iocp->ioc_count != sizeof (uint32_t)) {
1943*14b24e2bSVaishali Kulkarni 			qede_info(qede, "iocp->ioc_count %d, sizeof : %d\n",
1944*14b24e2bSVaishali Kulkarni 			    iocp->ioc_count, sizeof (uint32_t));
1945*14b24e2bSVaishali Kulkarni 			return (IOC_INVAL);
1946*14b24e2bSVaishali Kulkarni 		}
1947*14b24e2bSVaishali Kulkarni 		lb_mode = (void *)mp->b_cont->b_rptr;
1948*14b24e2bSVaishali Kulkarni 		return (qede_set_loopback_mode(qede,*lb_mode));
1949*14b24e2bSVaishali Kulkarni 	}
1950*14b24e2bSVaishali Kulkarni }
1951*14b24e2bSVaishali Kulkarni 
1952*14b24e2bSVaishali Kulkarni static void
1953*14b24e2bSVaishali Kulkarni qede_mac_ioctl(void *    arg,
1954*14b24e2bSVaishali Kulkarni                queue_t * wq,
1955*14b24e2bSVaishali Kulkarni                mblk_t *  mp)
1956*14b24e2bSVaishali Kulkarni {
1957*14b24e2bSVaishali Kulkarni 	int err, cmd;
1958*14b24e2bSVaishali Kulkarni     	qede_t * qede = (qede_t *)arg;
1959*14b24e2bSVaishali Kulkarni     	struct iocblk *iocp = (struct iocblk *) (uintptr_t)mp->b_rptr;
1960*14b24e2bSVaishali Kulkarni     	enum ioc_reply status = IOC_DONE;
1961*14b24e2bSVaishali Kulkarni     	boolean_t need_privilege = B_TRUE;
1962*14b24e2bSVaishali Kulkarni 
1963*14b24e2bSVaishali Kulkarni 	iocp->ioc_error = 0;
1964*14b24e2bSVaishali Kulkarni 	cmd = iocp->ioc_cmd;
1965*14b24e2bSVaishali Kulkarni 
1966*14b24e2bSVaishali Kulkarni 	mutex_enter(&qede->drv_lock);
1967*14b24e2bSVaishali Kulkarni 	if ((qede->qede_state == QEDE_STATE_SUSPENDING) ||
1968*14b24e2bSVaishali Kulkarni 	   (qede->qede_state == QEDE_STATE_SUSPENDED)) {
1969*14b24e2bSVaishali Kulkarni 		mutex_exit(&qede->drv_lock);
1970*14b24e2bSVaishali Kulkarni 		miocnak(wq, mp, 0, EINVAL);
1971*14b24e2bSVaishali Kulkarni 		return;
1972*14b24e2bSVaishali Kulkarni 	}
1973*14b24e2bSVaishali Kulkarni 
1974*14b24e2bSVaishali Kulkarni 	switch(cmd) {
1975*14b24e2bSVaishali Kulkarni 		case QEDE_CMD:
1976*14b24e2bSVaishali Kulkarni 			break;
1977*14b24e2bSVaishali Kulkarni 		case LB_GET_INFO_SIZE:
1978*14b24e2bSVaishali Kulkarni 		case LB_GET_INFO:
1979*14b24e2bSVaishali Kulkarni 		case LB_GET_MODE:
1980*14b24e2bSVaishali Kulkarni 			need_privilege = B_FALSE;
1981*14b24e2bSVaishali Kulkarni 		case LB_SET_MODE:
1982*14b24e2bSVaishali Kulkarni 			break;
1983*14b24e2bSVaishali Kulkarni 		default:
1984*14b24e2bSVaishali Kulkarni 			qede_print("!%s(%d) unknown ioctl command %x\n",
1985*14b24e2bSVaishali Kulkarni 			    __func__, qede->instance, cmd);
1986*14b24e2bSVaishali Kulkarni 			miocnak(wq, mp, 0, EINVAL);
1987*14b24e2bSVaishali Kulkarni 			mutex_exit(&qede->drv_lock);
1988*14b24e2bSVaishali Kulkarni 			return;
1989*14b24e2bSVaishali Kulkarni 	}
1990*14b24e2bSVaishali Kulkarni 
1991*14b24e2bSVaishali Kulkarni 	if(need_privilege) {
1992*14b24e2bSVaishali Kulkarni 		err = secpolicy_net_config(iocp->ioc_cr, B_FALSE);
1993*14b24e2bSVaishali Kulkarni 		if(err){
1994*14b24e2bSVaishali Kulkarni 			qede_info(qede, "secpolicy() failed");
1995*14b24e2bSVaishali Kulkarni 			miocnak(wq, mp, 0, err);
1996*14b24e2bSVaishali Kulkarni 		       	mutex_exit(&qede->drv_lock);
1997*14b24e2bSVaishali Kulkarni 			return;
1998*14b24e2bSVaishali Kulkarni 		}
1999*14b24e2bSVaishali Kulkarni 	}
2000*14b24e2bSVaishali Kulkarni 
2001*14b24e2bSVaishali Kulkarni 	switch (cmd) {
2002*14b24e2bSVaishali Kulkarni 		default:
2003*14b24e2bSVaishali Kulkarni 			qede_print("!%s(%d) : unknown ioctl command %x\n",
2004*14b24e2bSVaishali Kulkarni 			    __func__, qede->instance, cmd);
2005*14b24e2bSVaishali Kulkarni 			status = IOC_INVAL;
2006*14b24e2bSVaishali Kulkarni 			mutex_exit(&qede->drv_lock);
2007*14b24e2bSVaishali Kulkarni 			return;
2008*14b24e2bSVaishali Kulkarni 		case LB_GET_INFO_SIZE:
2009*14b24e2bSVaishali Kulkarni 		case LB_GET_INFO:
2010*14b24e2bSVaishali Kulkarni 		case LB_GET_MODE:
2011*14b24e2bSVaishali Kulkarni 		case LB_SET_MODE:
2012*14b24e2bSVaishali Kulkarni 			status = qede_loopback_ioctl(qede, wq, mp, iocp);
2013*14b24e2bSVaishali Kulkarni 			break;
2014*14b24e2bSVaishali Kulkarni 		case QEDE_CMD:
2015*14b24e2bSVaishali Kulkarni 			qede_ioctl(qede, cmd, wq, mp);
2016*14b24e2bSVaishali Kulkarni 			status = IOC_DONE;
2017*14b24e2bSVaishali Kulkarni 			break;
2018*14b24e2bSVaishali Kulkarni 	}
2019*14b24e2bSVaishali Kulkarni 
2020*14b24e2bSVaishali Kulkarni 	switch(status){
2021*14b24e2bSVaishali Kulkarni 		default:
2022*14b24e2bSVaishali Kulkarni 			qede_print("!%s(%d) : invalid status from ioctl",
2023*14b24e2bSVaishali Kulkarni 			    __func__,qede->instance);
2024*14b24e2bSVaishali Kulkarni 			break;
2025*14b24e2bSVaishali Kulkarni 		case IOC_DONE:
2026*14b24e2bSVaishali Kulkarni 			/*
2027*14b24e2bSVaishali Kulkarni 			 * OK, Reply already sent
2028*14b24e2bSVaishali Kulkarni 			 */
2029*14b24e2bSVaishali Kulkarni 
2030*14b24e2bSVaishali Kulkarni 			break;
2031*14b24e2bSVaishali Kulkarni 		case IOC_REPLY:
2032*14b24e2bSVaishali Kulkarni 			mp->b_datap->db_type = iocp->ioc_error == 0 ?
2033*14b24e2bSVaishali Kulkarni 				M_IOCACK : M_IOCNAK;
2034*14b24e2bSVaishali Kulkarni 			qreply(wq, mp);
2035*14b24e2bSVaishali Kulkarni 			break;
2036*14b24e2bSVaishali Kulkarni 		case IOC_INVAL:
2037*14b24e2bSVaishali Kulkarni 			mutex_exit(&qede->drv_lock);
2038*14b24e2bSVaishali Kulkarni 			//miocack(wq, mp, 0, 0);
2039*14b24e2bSVaishali Kulkarni 			miocnak(wq, mp, 0, iocp->ioc_error == 0 ?
2040*14b24e2bSVaishali Kulkarni 			    EINVAL : iocp->ioc_error);
2041*14b24e2bSVaishali Kulkarni 			return;
2042*14b24e2bSVaishali Kulkarni 	}
2043*14b24e2bSVaishali Kulkarni 	mutex_exit(&qede->drv_lock);
2044*14b24e2bSVaishali Kulkarni }
2045*14b24e2bSVaishali Kulkarni 
2046*14b24e2bSVaishali Kulkarni extern ddi_dma_attr_t qede_buf2k_dma_attr_txbuf;
2047*14b24e2bSVaishali Kulkarni extern ddi_dma_attr_t qede_dma_attr_rxbuf;
2048*14b24e2bSVaishali Kulkarni extern ddi_dma_attr_t qede_dma_attr_desc;
2049*14b24e2bSVaishali Kulkarni 
2050*14b24e2bSVaishali Kulkarni static boolean_t
2051*14b24e2bSVaishali Kulkarni qede_mac_get_capability(void *arg,
2052*14b24e2bSVaishali Kulkarni 	mac_capab_t capability,
2053*14b24e2bSVaishali Kulkarni 	void *      cap_data)
2054*14b24e2bSVaishali Kulkarni {
2055*14b24e2bSVaishali Kulkarni  	qede_t * qede = (qede_t *)arg;
2056*14b24e2bSVaishali Kulkarni 	uint32_t *txflags = cap_data;
2057*14b24e2bSVaishali Kulkarni 	boolean_t ret = B_FALSE;
2058*14b24e2bSVaishali Kulkarni 
2059*14b24e2bSVaishali Kulkarni 	switch (capability) {
2060*14b24e2bSVaishali Kulkarni 	case MAC_CAPAB_HCKSUM: {
2061*14b24e2bSVaishali Kulkarni 		u32 *tx_flags = cap_data;
2062*14b24e2bSVaishali Kulkarni 		/*
2063*14b24e2bSVaishali Kulkarni 		 * Check if checksum is enabled on
2064*14b24e2bSVaishali Kulkarni 		 * tx and advertise the cksum capab
2065*14b24e2bSVaishali Kulkarni 		 * to mac layer accordingly. On Rx
2066*14b24e2bSVaishali Kulkarni 		 * side checksummed packets are
2067*14b24e2bSVaishali Kulkarni 		 * reveiced anyway
2068*14b24e2bSVaishali Kulkarni 		 */
2069*14b24e2bSVaishali Kulkarni 		qede_info(qede, "%s tx checksum offload",
2070*14b24e2bSVaishali Kulkarni 		    (qede->checksum == DEFAULT_CKSUM_OFFLOAD) ?
2071*14b24e2bSVaishali Kulkarni 		    "Enabling":
2072*14b24e2bSVaishali Kulkarni 		    "Disabling");
2073*14b24e2bSVaishali Kulkarni 
2074*14b24e2bSVaishali Kulkarni 		if (qede->checksum != DEFAULT_CKSUM_OFFLOAD) {
2075*14b24e2bSVaishali Kulkarni 			ret = B_FALSE;
2076*14b24e2bSVaishali Kulkarni 			break;
2077*14b24e2bSVaishali Kulkarni 		}
2078*14b24e2bSVaishali Kulkarni                 /*
2079*14b24e2bSVaishali Kulkarni                  * Hardware does not support ICMPv6 checksumming. Right now the
2080*14b24e2bSVaishali Kulkarni                  * GLDv3 doesn't provide us a way to specify that we don't
2081*14b24e2bSVaishali Kulkarni                  * support that. As such, we cannot indicate
2082*14b24e2bSVaishali Kulkarni                  * HCKSUM_INET_FULL_V6.
2083*14b24e2bSVaishali Kulkarni                  */
2084*14b24e2bSVaishali Kulkarni 
2085*14b24e2bSVaishali Kulkarni 		*tx_flags = HCKSUM_INET_FULL_V4 |
2086*14b24e2bSVaishali Kulkarni 		    HCKSUM_IPHDRCKSUM;
2087*14b24e2bSVaishali Kulkarni 		ret = B_TRUE;
2088*14b24e2bSVaishali Kulkarni 		break;
2089*14b24e2bSVaishali Kulkarni 	}
2090*14b24e2bSVaishali Kulkarni 	case MAC_CAPAB_LSO: {
2091*14b24e2bSVaishali Kulkarni 		mac_capab_lso_t *cap_lso = (mac_capab_lso_t *)cap_data;
2092*14b24e2bSVaishali Kulkarni 
2093*14b24e2bSVaishali Kulkarni 		qede_info(qede, "%s large segmentation offload",
2094*14b24e2bSVaishali Kulkarni 		    qede->lso_enable ? "Enabling": "Disabling");
2095*14b24e2bSVaishali Kulkarni 		if (qede->lso_enable) {
2096*14b24e2bSVaishali Kulkarni 			cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4;
2097*14b24e2bSVaishali Kulkarni 			cap_lso->lso_basic_tcp_ipv4.lso_max = QEDE_LSO_MAXLEN;
2098*14b24e2bSVaishali Kulkarni 			ret = B_TRUE;
2099*14b24e2bSVaishali Kulkarni 		}
2100*14b24e2bSVaishali Kulkarni 		break;
2101*14b24e2bSVaishali Kulkarni 	}
2102*14b24e2bSVaishali Kulkarni 	case MAC_CAPAB_RINGS: {
2103*14b24e2bSVaishali Kulkarni #ifndef NO_CROSSBOW
2104*14b24e2bSVaishali Kulkarni 		mac_capab_rings_t *cap_rings = cap_data;
2105*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS
2106*14b24e2bSVaishali Kulkarni 		cap_rings->mr_version = MAC_RINGS_VERSION_1;
2107*14b24e2bSVaishali Kulkarni #endif
2108*14b24e2bSVaishali Kulkarni 
2109*14b24e2bSVaishali Kulkarni 		switch (cap_rings->mr_type) {
2110*14b24e2bSVaishali Kulkarni 		case MAC_RING_TYPE_RX:
2111*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS
2112*14b24e2bSVaishali Kulkarni 			cap_rings->mr_flags = MAC_RINGS_VLAN_TRANSPARENT;
2113*14b24e2bSVaishali Kulkarni #endif
2114*14b24e2bSVaishali Kulkarni 			cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
2115*14b24e2bSVaishali Kulkarni 			//cap_rings->mr_rnum = 1; /* qede variable */
2116*14b24e2bSVaishali Kulkarni 			cap_rings->mr_rnum = qede->num_fp; /* qede variable */
2117*14b24e2bSVaishali Kulkarni 			cap_rings->mr_gnum = 1;
2118*14b24e2bSVaishali Kulkarni 			cap_rings->mr_rget = qede_fill_ring;
2119*14b24e2bSVaishali Kulkarni 			cap_rings->mr_gget = qede_fill_group;
2120*14b24e2bSVaishali Kulkarni 			cap_rings->mr_gaddring = NULL;
2121*14b24e2bSVaishali Kulkarni 			cap_rings->mr_gremring = NULL;
2122*14b24e2bSVaishali Kulkarni #ifndef	ILLUMOS
2123*14b24e2bSVaishali Kulkarni 			cap_rings->mr_ggetringtc = NULL;
2124*14b24e2bSVaishali Kulkarni #endif
2125*14b24e2bSVaishali Kulkarni 			ret = B_TRUE;
2126*14b24e2bSVaishali Kulkarni 			break;
2127*14b24e2bSVaishali Kulkarni 		case MAC_RING_TYPE_TX:
2128*14b24e2bSVaishali Kulkarni #ifndef ILLUMOS
2129*14b24e2bSVaishali Kulkarni 			cap_rings->mr_flags = MAC_RINGS_VLAN_TRANSPARENT;
2130*14b24e2bSVaishali Kulkarni #endif
2131*14b24e2bSVaishali Kulkarni 			cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
2132*14b24e2bSVaishali Kulkarni 			//cap_rings->mr_rnum = 1;
2133*14b24e2bSVaishali Kulkarni 			cap_rings->mr_rnum = qede->num_fp;
2134*14b24e2bSVaishali Kulkarni 			cap_rings->mr_gnum = 0;
2135*14b24e2bSVaishali Kulkarni 			cap_rings->mr_rget = qede_fill_ring;
2136*14b24e2bSVaishali Kulkarni 			cap_rings->mr_gget = qede_fill_group;
2137*14b24e2bSVaishali Kulkarni 			cap_rings->mr_gaddring = NULL;
2138*14b24e2bSVaishali Kulkarni 			cap_rings->mr_gremring = NULL;
2139*14b24e2bSVaishali Kulkarni #ifndef	ILLUMOS
2140*14b24e2bSVaishali Kulkarni 			cap_rings->mr_ggetringtc = NULL;
2141*14b24e2bSVaishali Kulkarni #endif
2142*14b24e2bSVaishali Kulkarni 			ret = B_TRUE;
2143*14b24e2bSVaishali Kulkarni 			break;
2144*14b24e2bSVaishali Kulkarni 		default:
2145*14b24e2bSVaishali Kulkarni 			ret = B_FALSE;
2146*14b24e2bSVaishali Kulkarni 			break;
2147*14b24e2bSVaishali Kulkarni 		}
2148*14b24e2bSVaishali Kulkarni #endif
2149*14b24e2bSVaishali Kulkarni 		break; /* CASE MAC_CAPAB_RINGS */
2150*14b24e2bSVaishali Kulkarni 	}
2151*14b24e2bSVaishali Kulkarni #ifdef ILLUMOS
2152*14b24e2bSVaishali Kulkarni         case MAC_CAPAB_TRANSCEIVER: {
2153*14b24e2bSVaishali Kulkarni                 mac_capab_transceiver_t *mct = cap_data;
2154*14b24e2bSVaishali Kulkarni 
2155*14b24e2bSVaishali Kulkarni                 mct->mct_flags = 0;
2156*14b24e2bSVaishali Kulkarni                 mct->mct_ntransceivers = qede->edev.num_hwfns;
2157*14b24e2bSVaishali Kulkarni                 mct->mct_info = qede_transceiver_info;
2158*14b24e2bSVaishali Kulkarni                 mct->mct_read = qede_transceiver_read;
2159*14b24e2bSVaishali Kulkarni 
2160*14b24e2bSVaishali Kulkarni                 ret = B_TRUE;
2161*14b24e2bSVaishali Kulkarni                 break;
2162*14b24e2bSVaishali Kulkarni         }
2163*14b24e2bSVaishali Kulkarni #endif
2164*14b24e2bSVaishali Kulkarni 	default:
2165*14b24e2bSVaishali Kulkarni 		break;
2166*14b24e2bSVaishali Kulkarni 	}
2167*14b24e2bSVaishali Kulkarni 
2168*14b24e2bSVaishali Kulkarni     return (ret);
2169*14b24e2bSVaishali Kulkarni }
2170*14b24e2bSVaishali Kulkarni 
2171*14b24e2bSVaishali Kulkarni int
2172*14b24e2bSVaishali Kulkarni qede_configure_link(qede_t *qede, bool op);
2173*14b24e2bSVaishali Kulkarni 
2174*14b24e2bSVaishali Kulkarni static int
2175*14b24e2bSVaishali Kulkarni qede_mac_set_property(void *        arg,
2176*14b24e2bSVaishali Kulkarni                               const char *  pr_name,
2177*14b24e2bSVaishali Kulkarni                               mac_prop_id_t pr_num,
2178*14b24e2bSVaishali Kulkarni                               uint_t        pr_valsize,
2179*14b24e2bSVaishali Kulkarni                               const void *  pr_val)
2180*14b24e2bSVaishali Kulkarni {
2181*14b24e2bSVaishali Kulkarni 	qede_t * qede = (qede_t *)arg;
2182*14b24e2bSVaishali Kulkarni 	struct ecore_mcp_link_params *link_params;
2183*14b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
2184*14b24e2bSVaishali Kulkarni 	struct ecore_hwfn *hwfn;
2185*14b24e2bSVaishali Kulkarni 	int ret_val = 0, i;
2186*14b24e2bSVaishali Kulkarni 	uint32_t option;
2187*14b24e2bSVaishali Kulkarni 
2188*14b24e2bSVaishali Kulkarni 	mutex_enter(&qede->gld_lock);
2189*14b24e2bSVaishali Kulkarni 	switch (pr_num)
2190*14b24e2bSVaishali Kulkarni 	{
2191*14b24e2bSVaishali Kulkarni         case MAC_PROP_MTU:
2192*14b24e2bSVaishali Kulkarni                 bcopy(pr_val, &option, sizeof (option));
2193*14b24e2bSVaishali Kulkarni 
2194*14b24e2bSVaishali Kulkarni                 if(option == qede->mtu) {
2195*14b24e2bSVaishali Kulkarni                         ret_val = 0;
2196*14b24e2bSVaishali Kulkarni                         break;
2197*14b24e2bSVaishali Kulkarni                 }
2198*14b24e2bSVaishali Kulkarni                 if ((option != DEFAULT_JUMBO_MTU) &&
2199*14b24e2bSVaishali Kulkarni                    (option != DEFAULT_MTU)) {
2200*14b24e2bSVaishali Kulkarni                         ret_val = EINVAL;
2201*14b24e2bSVaishali Kulkarni                         break;
2202*14b24e2bSVaishali Kulkarni                 }
2203*14b24e2bSVaishali Kulkarni                 if(qede->qede_state == QEDE_STATE_STARTED) {
2204*14b24e2bSVaishali Kulkarni                         ret_val = EBUSY;
2205*14b24e2bSVaishali Kulkarni                         break;
2206*14b24e2bSVaishali Kulkarni                 }
2207*14b24e2bSVaishali Kulkarni 
2208*14b24e2bSVaishali Kulkarni                 ret_val = mac_maxsdu_update(qede->mac_handle, qede->mtu);
2209*14b24e2bSVaishali Kulkarni                 if (ret_val == 0) {
2210*14b24e2bSVaishali Kulkarni 
2211*14b24e2bSVaishali Kulkarni                         qede->mtu = option;
2212*14b24e2bSVaishali Kulkarni                         if (option == DEFAULT_JUMBO_MTU) {
2213*14b24e2bSVaishali Kulkarni                                 qede->jumbo_enable = B_TRUE;
2214*14b24e2bSVaishali Kulkarni 			} else {
2215*14b24e2bSVaishali Kulkarni 				qede->jumbo_enable = B_FALSE;
2216*14b24e2bSVaishali Kulkarni 			}
2217*14b24e2bSVaishali Kulkarni 
2218*14b24e2bSVaishali Kulkarni                         hwfn = ECORE_LEADING_HWFN(edev);
2219*14b24e2bSVaishali Kulkarni                         hwfn->hw_info.mtu = qede->mtu;
2220*14b24e2bSVaishali Kulkarni                         ret_val = ecore_mcp_ov_update_mtu(hwfn,
2221*14b24e2bSVaishali Kulkarni 			    hwfn->p_main_ptt,
2222*14b24e2bSVaishali Kulkarni 			    hwfn->hw_info.mtu);
2223*14b24e2bSVaishali Kulkarni                         if (ret_val != ECORE_SUCCESS) {
2224*14b24e2bSVaishali Kulkarni                                 qede_print("!%s(%d): MTU change %d option %d"
2225*14b24e2bSVaishali Kulkarni 				    "FAILED",
2226*14b24e2bSVaishali Kulkarni 				    __func__,qede->instance, qede->mtu, option);
2227*14b24e2bSVaishali Kulkarni 				break;
2228*14b24e2bSVaishali Kulkarni 			}
2229*14b24e2bSVaishali Kulkarni                         qede_print("!%s(%d): MTU changed  %d MTU option"
2230*14b24e2bSVaishali Kulkarni 			    " %d hwfn %d",
2231*14b24e2bSVaishali Kulkarni 			    __func__,qede->instance, qede->mtu,
2232*14b24e2bSVaishali Kulkarni 			    option, hwfn->hw_info.mtu);
2233*14b24e2bSVaishali Kulkarni                 }
2234*14b24e2bSVaishali Kulkarni                 break;
2235*14b24e2bSVaishali Kulkarni 
2236*14b24e2bSVaishali Kulkarni 	case MAC_PROP_EN_10GFDX_CAP:
2237*14b24e2bSVaishali Kulkarni 		hwfn = &edev->hwfns[0];
2238*14b24e2bSVaishali Kulkarni 		link_params = ecore_mcp_get_link_params(hwfn);
2239*14b24e2bSVaishali Kulkarni 		if (*(uint8_t *) pr_val) {
2240*14b24e2bSVaishali Kulkarni 			link_params->speed.autoneg = 0;
2241*14b24e2bSVaishali Kulkarni 			link_params->speed.forced_speed = 10000;
2242*14b24e2bSVaishali Kulkarni 			link_params->speed.advertised_speeds =
2243*14b24e2bSVaishali Kulkarni 			    NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
2244*14b24e2bSVaishali Kulkarni 			qede->forced_speed_10G = *(uint8_t *)pr_val;
2245*14b24e2bSVaishali Kulkarni 		}
2246*14b24e2bSVaishali Kulkarni 		else {
2247*14b24e2bSVaishali Kulkarni 			memcpy(link_params,
2248*14b24e2bSVaishali Kulkarni 			    &qede->link_input_params.default_link_params,
2249*14b24e2bSVaishali Kulkarni 			    sizeof (struct ecore_mcp_link_params));
2250*14b24e2bSVaishali Kulkarni 			qede->forced_speed_10G = *(uint8_t *)pr_val;
2251*14b24e2bSVaishali Kulkarni 		}
2252*14b24e2bSVaishali Kulkarni 		if (qede->qede_state == QEDE_STATE_STARTED) {
2253*14b24e2bSVaishali Kulkarni 			qede_configure_link(qede,1);
2254*14b24e2bSVaishali Kulkarni 		} else {
2255*14b24e2bSVaishali Kulkarni 			mutex_exit(&qede->gld_lock);
2256*14b24e2bSVaishali Kulkarni 			return (0);
2257*14b24e2bSVaishali Kulkarni 		}
2258*14b24e2bSVaishali Kulkarni 		break;
2259*14b24e2bSVaishali Kulkarni 	default:
2260*14b24e2bSVaishali Kulkarni 		ret_val = ENOTSUP;
2261*14b24e2bSVaishali Kulkarni 		break;
2262*14b24e2bSVaishali Kulkarni 	}
2263*14b24e2bSVaishali Kulkarni 	mutex_exit(&qede->gld_lock);
2264*14b24e2bSVaishali Kulkarni 	return (ret_val);
2265*14b24e2bSVaishali Kulkarni }
2266*14b24e2bSVaishali Kulkarni 
2267*14b24e2bSVaishali Kulkarni static void
2268*14b24e2bSVaishali Kulkarni qede_mac_stop(void *arg)
2269*14b24e2bSVaishali Kulkarni {
2270*14b24e2bSVaishali Kulkarni     qede_t *qede = (qede_t *)arg;
2271*14b24e2bSVaishali Kulkarni 	int status;
2272*14b24e2bSVaishali Kulkarni 
2273*14b24e2bSVaishali Kulkarni 	qede_print("!%s(%d): called",
2274*14b24e2bSVaishali Kulkarni 	    __func__,qede->instance);
2275*14b24e2bSVaishali Kulkarni 	mutex_enter(&qede->drv_lock);
2276*14b24e2bSVaishali Kulkarni 	status = qede_stop(qede);
2277*14b24e2bSVaishali Kulkarni 	if (status != DDI_SUCCESS) {
2278*14b24e2bSVaishali Kulkarni 		qede_print("!%s(%d): qede_stop "
2279*14b24e2bSVaishali Kulkarni 		    "FAILED",
2280*14b24e2bSVaishali Kulkarni 	        __func__,qede->instance);
2281*14b24e2bSVaishali Kulkarni 	}
2282*14b24e2bSVaishali Kulkarni 
2283*14b24e2bSVaishali Kulkarni 	mac_link_update(qede->mac_handle, LINK_STATE_UNKNOWN);
2284*14b24e2bSVaishali Kulkarni 	mutex_exit(&qede->drv_lock);
2285*14b24e2bSVaishali Kulkarni }
2286*14b24e2bSVaishali Kulkarni 
2287*14b24e2bSVaishali Kulkarni static int
2288*14b24e2bSVaishali Kulkarni qede_mac_start(void *arg)
2289*14b24e2bSVaishali Kulkarni {
2290*14b24e2bSVaishali Kulkarni     	qede_t *qede = (qede_t *)arg;
2291*14b24e2bSVaishali Kulkarni 	int status;
2292*14b24e2bSVaishali Kulkarni 
2293*14b24e2bSVaishali Kulkarni 	qede_print("!%s(%d): called", __func__,qede->instance);
2294*14b24e2bSVaishali Kulkarni 	if (!mutex_tryenter(&qede->drv_lock)) {
2295*14b24e2bSVaishali Kulkarni 		return (EAGAIN);
2296*14b24e2bSVaishali Kulkarni 	}
2297*14b24e2bSVaishali Kulkarni 
2298*14b24e2bSVaishali Kulkarni 	if (qede->qede_state == QEDE_STATE_SUSPENDED) {
2299*14b24e2bSVaishali Kulkarni 		mutex_exit(&qede->drv_lock);
2300*14b24e2bSVaishali Kulkarni 		return (ECANCELED);
2301*14b24e2bSVaishali Kulkarni 	}
2302*14b24e2bSVaishali Kulkarni 
2303*14b24e2bSVaishali Kulkarni 	status = qede_start(qede);
2304*14b24e2bSVaishali Kulkarni 	if (status != DDI_SUCCESS) {
2305*14b24e2bSVaishali Kulkarni 		mutex_exit(&qede->drv_lock);
2306*14b24e2bSVaishali Kulkarni 		return (EIO);
2307*14b24e2bSVaishali Kulkarni 	}
2308*14b24e2bSVaishali Kulkarni 
2309*14b24e2bSVaishali Kulkarni 	mutex_exit(&qede->drv_lock);
2310*14b24e2bSVaishali Kulkarni 
2311*14b24e2bSVaishali Kulkarni #ifdef	DBLK_DMA_PREMAP
2312*14b24e2bSVaishali Kulkarni 	qede->pm_handle = mac_pmh_tx_get(qede->mac_handle);
2313*14b24e2bSVaishali Kulkarni #endif
2314*14b24e2bSVaishali Kulkarni 	return (0);
2315*14b24e2bSVaishali Kulkarni }
2316*14b24e2bSVaishali Kulkarni 
2317*14b24e2bSVaishali Kulkarni static int
2318*14b24e2bSVaishali Kulkarni qede_mac_get_property(void *arg,
2319*14b24e2bSVaishali Kulkarni     const char *pr_name,
2320*14b24e2bSVaishali Kulkarni     mac_prop_id_t pr_num,
2321*14b24e2bSVaishali Kulkarni     uint_t        pr_valsize,
2322*14b24e2bSVaishali Kulkarni     void *pr_val)
2323*14b24e2bSVaishali Kulkarni {
2324*14b24e2bSVaishali Kulkarni 	qede_t *qede = (qede_t *)arg;
2325*14b24e2bSVaishali Kulkarni 	struct ecore_dev *edev = &qede->edev;
2326*14b24e2bSVaishali Kulkarni 	link_state_t    link_state;
2327*14b24e2bSVaishali Kulkarni 	link_duplex_t   link_duplex;
2328*14b24e2bSVaishali Kulkarni 	uint64_t        link_speed;
2329*14b24e2bSVaishali Kulkarni 	link_flowctrl_t link_flowctrl;
2330*14b24e2bSVaishali Kulkarni 	struct qede_link_cfg link_cfg;
2331*14b24e2bSVaishali Kulkarni 	qede_link_cfg_t  *hw_cfg  = &qede->hwinit;
2332*14b24e2bSVaishali Kulkarni 	int ret_val = 0;
2333*14b24e2bSVaishali Kulkarni 
2334*14b24e2bSVaishali Kulkarni 	memset(&link_cfg, 0, sizeof (struct qede_link_cfg));
2335*14b24e2bSVaishali Kulkarni 	qede_get_link_info(&edev->hwfns[0], &link_cfg);
2336*14b24e2bSVaishali Kulkarni 
2337*14b24e2bSVaishali Kulkarni 
2338*14b24e2bSVaishali Kulkarni 
2339*14b24e2bSVaishali Kulkarni 	switch (pr_num)
2340*14b24e2bSVaishali Kulkarni 	{
2341*14b24e2bSVaishali Kulkarni 	case MAC_PROP_MTU:
2342*14b24e2bSVaishali Kulkarni 
2343*14b24e2bSVaishali Kulkarni 		ASSERT(pr_valsize >= sizeof(uint32_t));
2344*14b24e2bSVaishali Kulkarni 		bcopy(&qede->mtu, pr_val, sizeof(uint32_t));
2345*14b24e2bSVaishali Kulkarni 		break;
2346*14b24e2bSVaishali Kulkarni 
2347*14b24e2bSVaishali Kulkarni 	case MAC_PROP_DUPLEX:
2348*14b24e2bSVaishali Kulkarni 
2349*14b24e2bSVaishali Kulkarni 		ASSERT(pr_valsize >= sizeof(link_duplex_t));
2350*14b24e2bSVaishali Kulkarni 		link_duplex = (qede->props.link_duplex) ?
2351*14b24e2bSVaishali Kulkarni 					  LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
2352*14b24e2bSVaishali Kulkarni 		bcopy(&link_duplex, pr_val, sizeof(link_duplex_t));
2353*14b24e2bSVaishali Kulkarni 		break;
2354*14b24e2bSVaishali Kulkarni 
2355*14b24e2bSVaishali Kulkarni 	case MAC_PROP_SPEED:
2356*14b24e2bSVaishali Kulkarni 
2357*14b24e2bSVaishali Kulkarni 		ASSERT(pr_valsize >= sizeof(link_speed));
2358*14b24e2bSVaishali Kulkarni 
2359*14b24e2bSVaishali Kulkarni 		link_speed = (qede->props.link_speed * 1000000ULL);
2360*14b24e2bSVaishali Kulkarni 		bcopy(&link_speed, pr_val, sizeof(link_speed));
2361*14b24e2bSVaishali Kulkarni 	    	break;
2362*14b24e2bSVaishali Kulkarni 
2363*14b24e2bSVaishali Kulkarni 	case MAC_PROP_STATUS:
2364*14b24e2bSVaishali Kulkarni 
2365*14b24e2bSVaishali Kulkarni 		ASSERT(pr_valsize >= sizeof(link_state_t));
2366*14b24e2bSVaishali Kulkarni 
2367*14b24e2bSVaishali Kulkarni 		link_state = (qede->params.link_state) ?
2368*14b24e2bSVaishali Kulkarni 		                        LINK_STATE_UP : LINK_STATE_DOWN;
2369*14b24e2bSVaishali Kulkarni 		bcopy(&link_state, pr_val, sizeof(link_state_t));
2370*14b24e2bSVaishali Kulkarni 		qede_info(qede, "mac_prop_status %d\n", link_state);
2371*14b24e2bSVaishali Kulkarni 		break;
2372*14b24e2bSVaishali Kulkarni 
2373*14b24e2bSVaishali Kulkarni 	case MAC_PROP_AUTONEG:
2374*14b24e2bSVaishali Kulkarni 
2375*14b24e2bSVaishali Kulkarni 		*(uint8_t *)pr_val = link_cfg.autoneg;
2376*14b24e2bSVaishali Kulkarni 		break;
2377*14b24e2bSVaishali Kulkarni 
2378*14b24e2bSVaishali Kulkarni 	case MAC_PROP_FLOWCTRL:
2379*14b24e2bSVaishali Kulkarni 
2380*14b24e2bSVaishali Kulkarni 		ASSERT(pr_valsize >= sizeof(link_flowctrl_t));
2381*14b24e2bSVaishali Kulkarni 
2382*14b24e2bSVaishali Kulkarni /*
2383*14b24e2bSVaishali Kulkarni  * illumos does not have the notion of LINK_FLOWCTRL_AUTO at this time.
2384*14b24e2bSVaishali Kulkarni  */
2385*14b24e2bSVaishali Kulkarni #ifndef	ILLUMOS
2386*14b24e2bSVaishali Kulkarni 		if (link_cfg.pause_cfg & QEDE_LINK_PAUSE_AUTONEG_ENABLE)  {
2387*14b24e2bSVaishali Kulkarni 	            link_flowctrl = LINK_FLOWCTRL_AUTO;
2388*14b24e2bSVaishali Kulkarni 		}
2389*14b24e2bSVaishali Kulkarni #endif
2390*14b24e2bSVaishali Kulkarni 
2391*14b24e2bSVaishali Kulkarni 		if (!(link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) &&
2392*14b24e2bSVaishali Kulkarni 		    !(link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) {
2393*14b24e2bSVaishali Kulkarni 	            link_flowctrl = LINK_FLOWCTRL_NONE;
2394*14b24e2bSVaishali Kulkarni 		}
2395*14b24e2bSVaishali Kulkarni 		if ((link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) &&
2396*14b24e2bSVaishali Kulkarni 		    !(link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) {
2397*14b24e2bSVaishali Kulkarni 	            link_flowctrl = LINK_FLOWCTRL_RX;
2398*14b24e2bSVaishali Kulkarni 	    	}
2399*14b24e2bSVaishali Kulkarni         	if (!(link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) &&
2400*14b24e2bSVaishali Kulkarni 		    (link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) {
2401*14b24e2bSVaishali Kulkarni 	            link_flowctrl = LINK_FLOWCTRL_TX;
2402*14b24e2bSVaishali Kulkarni 		}
2403*14b24e2bSVaishali Kulkarni 		if ((link_cfg.pause_cfg & QEDE_LINK_PAUSE_RX_ENABLE) &&
2404*14b24e2bSVaishali Kulkarni 		    (link_cfg.pause_cfg & QEDE_LINK_PAUSE_TX_ENABLE)) {
2405*14b24e2bSVaishali Kulkarni 	            link_flowctrl = LINK_FLOWCTRL_BI;
2406*14b24e2bSVaishali Kulkarni 		}
2407*14b24e2bSVaishali Kulkarni 
2408*14b24e2bSVaishali Kulkarni         	bcopy(&link_flowctrl, pr_val, sizeof (link_flowctrl_t));
2409*14b24e2bSVaishali Kulkarni         	break;
2410*14b24e2bSVaishali Kulkarni 
2411*14b24e2bSVaishali Kulkarni 	case MAC_PROP_ADV_10GFDX_CAP:
2412*14b24e2bSVaishali Kulkarni 		*(uint8_t *)pr_val = link_cfg.adv_capab.param_10000fdx;
2413*14b24e2bSVaishali Kulkarni 		break;
2414*14b24e2bSVaishali Kulkarni 
2415*14b24e2bSVaishali Kulkarni 	case MAC_PROP_EN_10GFDX_CAP:
2416*14b24e2bSVaishali Kulkarni 		*(uint8_t *)pr_val = qede->forced_speed_10G;
2417*14b24e2bSVaishali Kulkarni 		break;
2418*14b24e2bSVaishali Kulkarni 
2419*14b24e2bSVaishali Kulkarni 	case MAC_PROP_PRIVATE:
2420*14b24e2bSVaishali Kulkarni 	default:
2421*14b24e2bSVaishali Kulkarni 		return (ENOTSUP);
2422*14b24e2bSVaishali Kulkarni 
2423*14b24e2bSVaishali Kulkarni 	}
2424*14b24e2bSVaishali Kulkarni 
2425*14b24e2bSVaishali Kulkarni 	return (0);
2426*14b24e2bSVaishali Kulkarni }
2427*14b24e2bSVaishali Kulkarni 
2428*14b24e2bSVaishali Kulkarni static void
2429*14b24e2bSVaishali Kulkarni qede_mac_property_info(void *arg,
2430*14b24e2bSVaishali Kulkarni     const char *pr_name,
2431*14b24e2bSVaishali Kulkarni     mac_prop_id_t  pr_num,
2432*14b24e2bSVaishali Kulkarni     mac_prop_info_handle_t prh)
2433*14b24e2bSVaishali Kulkarni {
2434*14b24e2bSVaishali Kulkarni 	qede_t *qede = (qede_t *)arg;
2435*14b24e2bSVaishali Kulkarni 	qede_link_props_t *def_cfg = &qede_def_link_props;
2436*14b24e2bSVaishali Kulkarni 	link_flowctrl_t link_flowctrl;
2437*14b24e2bSVaishali Kulkarni 
2438*14b24e2bSVaishali Kulkarni 
2439*14b24e2bSVaishali Kulkarni 	switch (pr_num)
2440*14b24e2bSVaishali Kulkarni 	{
2441*14b24e2bSVaishali Kulkarni 
2442*14b24e2bSVaishali Kulkarni 	case MAC_PROP_STATUS:
2443*14b24e2bSVaishali Kulkarni 	case MAC_PROP_SPEED:
2444*14b24e2bSVaishali Kulkarni 	case MAC_PROP_DUPLEX:
2445*14b24e2bSVaishali Kulkarni 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
2446*14b24e2bSVaishali Kulkarni 		break;
2447*14b24e2bSVaishali Kulkarni 
2448*14b24e2bSVaishali Kulkarni 	case MAC_PROP_MTU:
2449*14b24e2bSVaishali Kulkarni 
2450*14b24e2bSVaishali Kulkarni 		mac_prop_info_set_range_uint32(prh,
2451*14b24e2bSVaishali Kulkarni 		    MIN_MTU,
2452*14b24e2bSVaishali Kulkarni 		    MAX_MTU);
2453*14b24e2bSVaishali Kulkarni 		break;
2454*14b24e2bSVaishali Kulkarni 
2455*14b24e2bSVaishali Kulkarni 	case MAC_PROP_AUTONEG:
2456*14b24e2bSVaishali Kulkarni 
2457*14b24e2bSVaishali Kulkarni 		mac_prop_info_set_default_uint8(prh, def_cfg->autoneg);
2458*14b24e2bSVaishali Kulkarni 		break;
2459*14b24e2bSVaishali Kulkarni 
2460*14b24e2bSVaishali Kulkarni 	case MAC_PROP_FLOWCTRL:
2461*14b24e2bSVaishali Kulkarni 
2462*14b24e2bSVaishali Kulkarni 		if (!def_cfg->pause) {
2463*14b24e2bSVaishali Kulkarni 			link_flowctrl = LINK_FLOWCTRL_NONE;
2464*14b24e2bSVaishali Kulkarni 		} else {
2465*14b24e2bSVaishali Kulkarni 			link_flowctrl = LINK_FLOWCTRL_BI;
2466*14b24e2bSVaishali Kulkarni 		}
2467*14b24e2bSVaishali Kulkarni 
2468*14b24e2bSVaishali Kulkarni 		mac_prop_info_set_default_link_flowctrl(prh, link_flowctrl);
2469*14b24e2bSVaishali Kulkarni 		break;
2470*14b24e2bSVaishali Kulkarni 
2471*14b24e2bSVaishali Kulkarni 	case MAC_PROP_EN_10GFDX_CAP:
2472*14b24e2bSVaishali Kulkarni 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW);
2473*14b24e2bSVaishali Kulkarni 		break;
2474*14b24e2bSVaishali Kulkarni 
2475*14b24e2bSVaishali Kulkarni 	case MAC_PROP_ADV_10GFDX_CAP:
2476*14b24e2bSVaishali Kulkarni 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
2477*14b24e2bSVaishali Kulkarni 		break;
2478*14b24e2bSVaishali Kulkarni 
2479*14b24e2bSVaishali Kulkarni 	default:
2480*14b24e2bSVaishali Kulkarni 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
2481*14b24e2bSVaishali Kulkarni 		break;
2482*14b24e2bSVaishali Kulkarni 
2483*14b24e2bSVaishali Kulkarni     }
2484*14b24e2bSVaishali Kulkarni }
2485*14b24e2bSVaishali Kulkarni 
2486*14b24e2bSVaishali Kulkarni static mac_callbacks_t qede_callbacks =
2487*14b24e2bSVaishali Kulkarni {
2488*14b24e2bSVaishali Kulkarni     (
2489*14b24e2bSVaishali Kulkarni       MC_IOCTL
2490*14b24e2bSVaishali Kulkarni /*    | MC_RESOURCES */
2491*14b24e2bSVaishali Kulkarni     | MC_SETPROP
2492*14b24e2bSVaishali Kulkarni     | MC_GETPROP
2493*14b24e2bSVaishali Kulkarni     | MC_PROPINFO
2494*14b24e2bSVaishali Kulkarni     | MC_GETCAPAB
2495*14b24e2bSVaishali Kulkarni     ),
2496*14b24e2bSVaishali Kulkarni     qede_mac_stats,
2497*14b24e2bSVaishali Kulkarni     qede_mac_start,
2498*14b24e2bSVaishali Kulkarni     qede_mac_stop,
2499*14b24e2bSVaishali Kulkarni     qede_mac_promiscuous,
2500*14b24e2bSVaishali Kulkarni     qede_mac_multicast,
2501*14b24e2bSVaishali Kulkarni     NULL,
2502*14b24e2bSVaishali Kulkarni #ifndef NO_CROSSBOW
2503*14b24e2bSVaishali Kulkarni     NULL,
2504*14b24e2bSVaishali Kulkarni #else
2505*14b24e2bSVaishali Kulkarni     qede_mac_tx,
2506*14b24e2bSVaishali Kulkarni #endif
2507*14b24e2bSVaishali Kulkarni     NULL,	/* qede_mac_resources, */
2508*14b24e2bSVaishali Kulkarni     qede_mac_ioctl,
2509*14b24e2bSVaishali Kulkarni     qede_mac_get_capability,
2510*14b24e2bSVaishali Kulkarni     NULL,
2511*14b24e2bSVaishali Kulkarni     NULL,
2512*14b24e2bSVaishali Kulkarni     qede_mac_set_property,
2513*14b24e2bSVaishali Kulkarni     qede_mac_get_property,
2514*14b24e2bSVaishali Kulkarni #ifdef MC_PROPINFO
2515*14b24e2bSVaishali Kulkarni     qede_mac_property_info
2516*14b24e2bSVaishali Kulkarni #endif
2517*14b24e2bSVaishali Kulkarni };
2518*14b24e2bSVaishali Kulkarni 
2519*14b24e2bSVaishali Kulkarni boolean_t
2520*14b24e2bSVaishali Kulkarni qede_gld_init(qede_t *qede)
2521*14b24e2bSVaishali Kulkarni {
2522*14b24e2bSVaishali Kulkarni 	int status, ret;
2523*14b24e2bSVaishali Kulkarni 	mac_register_t *macp;
2524*14b24e2bSVaishali Kulkarni 
2525*14b24e2bSVaishali Kulkarni 	macp = mac_alloc(MAC_VERSION);
2526*14b24e2bSVaishali Kulkarni 	if (macp == NULL) {
2527*14b24e2bSVaishali Kulkarni 		cmn_err(CE_NOTE, "%s: mac_alloc() failed\n", __func__);
2528*14b24e2bSVaishali Kulkarni 		return (B_FALSE);
2529*14b24e2bSVaishali Kulkarni 	}
2530*14b24e2bSVaishali Kulkarni 
2531*14b24e2bSVaishali Kulkarni  	macp->m_driver = qede;
2532*14b24e2bSVaishali Kulkarni 	macp->m_dip = qede->dip;
2533*14b24e2bSVaishali Kulkarni 	macp->m_instance = qede->instance;
2534*14b24e2bSVaishali Kulkarni 	macp->m_priv_props = NULL;
2535*14b24e2bSVaishali Kulkarni 	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
2536*14b24e2bSVaishali Kulkarni  	macp->m_src_addr = qede->ether_addr;
2537*14b24e2bSVaishali Kulkarni 	macp->m_callbacks = &qede_callbacks;
2538*14b24e2bSVaishali Kulkarni 	macp->m_min_sdu = 0;
2539*14b24e2bSVaishali Kulkarni 	macp->m_max_sdu = qede->mtu;
2540*14b24e2bSVaishali Kulkarni 	macp->m_margin = VLAN_TAGSZ;
2541*14b24e2bSVaishali Kulkarni #ifdef	ILLUMOS
2542*14b24e2bSVaishali Kulkarni 	macp->m_v12n = MAC_VIRT_LEVEL1;
2543*14b24e2bSVaishali Kulkarni #endif
2544*14b24e2bSVaishali Kulkarni 
2545*14b24e2bSVaishali Kulkarni 	status = mac_register(macp, &qede->mac_handle);
2546*14b24e2bSVaishali Kulkarni 	if (status != 0) {
2547*14b24e2bSVaishali Kulkarni 		cmn_err(CE_NOTE, "%s: mac_register() failed\n", __func__);
2548*14b24e2bSVaishali Kulkarni 	}
2549*14b24e2bSVaishali Kulkarni 
2550*14b24e2bSVaishali Kulkarni 	mac_free(macp);
2551*14b24e2bSVaishali Kulkarni 	if (status == 0) {
2552*14b24e2bSVaishali Kulkarni 		return (B_TRUE);
2553*14b24e2bSVaishali Kulkarni 	}
2554*14b24e2bSVaishali Kulkarni 	return (B_FALSE);
2555*14b24e2bSVaishali Kulkarni }
2556*14b24e2bSVaishali Kulkarni 
2557*14b24e2bSVaishali Kulkarni boolean_t qede_gld_fini(qede_t * qede)
2558*14b24e2bSVaishali Kulkarni {
2559*14b24e2bSVaishali Kulkarni     return (B_TRUE);
2560*14b24e2bSVaishali Kulkarni }
2561*14b24e2bSVaishali Kulkarni 
2562*14b24e2bSVaishali Kulkarni 
2563*14b24e2bSVaishali Kulkarni void qede_link_update(qede_t * qede,
2564*14b24e2bSVaishali Kulkarni                  link_state_t  state)
2565*14b24e2bSVaishali Kulkarni {
2566*14b24e2bSVaishali Kulkarni     mac_link_update(qede->mac_handle, state);
2567*14b24e2bSVaishali Kulkarni }
2568*14b24e2bSVaishali Kulkarni 
2569