xref: /freebsd/sys/dev/qlxge/qls_hw.c (revision f9bc005b8ef3b507a5ecbc2d7fe4411ef70eff38)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2013-2014 Qlogic Corporation
5  * All rights reserved.
6  *
7  *  Redistribution and use in source and binary forms, with or without
8  *  modification, are permitted provided that the following conditions
9  *  are met:
10  *
11  *  1. Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer.
13  *  2. Redistributions in binary form must reproduce the above copyright
14  *     notice, this list of conditions and the following disclaimer in the
15  *     documentation and/or other materials provided with the distribution.
16  *
17  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  *  POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31  * File: qls_hw.c
32  * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
33  * Content: Contains Hardware dependent functions
34  */
35 #include <sys/cdefs.h>
36 #include "qls_os.h"
37 #include <net/rss_config.h>
38 #include "qls_hw.h"
39 #include "qls_def.h"
40 #include "qls_inline.h"
41 #include "qls_ver.h"
42 #include "qls_glbl.h"
43 #include "qls_dbg.h"
44 
45 /*
46  * Static Functions
47  */
48 static int qls_wait_for_mac_proto_idx_ready(qla_host_t *ha, uint32_t op);
49 static int qls_config_unicast_mac_addr(qla_host_t *ha, uint32_t add_mac);
50 static int qls_config_mcast_mac_addr(qla_host_t *ha, uint8_t *mac_addr,
51                 uint32_t add_mac, uint32_t index);
52 
53 static int qls_init_rss(qla_host_t *ha);
54 static int qls_init_comp_queue(qla_host_t *ha, int cid);
55 static int qls_init_work_queue(qla_host_t *ha, int wid);
56 static int qls_init_fw_routing_table(qla_host_t *ha);
57 static int qls_hw_add_all_mcast(qla_host_t *ha);
58 static int qls_hw_add_mcast(qla_host_t *ha, uint8_t *mta);
59 static int qls_hw_del_mcast(qla_host_t *ha, uint8_t *mta);
60 static int qls_wait_for_flash_ready(qla_host_t *ha);
61 
62 static int qls_sem_lock(qla_host_t *ha, uint32_t mask, uint32_t value);
63 static void qls_sem_unlock(qla_host_t *ha, uint32_t mask);
64 
65 static void qls_free_tx_dma(qla_host_t *ha);
66 static int qls_alloc_tx_dma(qla_host_t *ha);
67 static void qls_free_rx_dma(qla_host_t *ha);
68 static int qls_alloc_rx_dma(qla_host_t *ha);
69 static void qls_free_mpi_dma(qla_host_t *ha);
70 static int qls_alloc_mpi_dma(qla_host_t *ha);
71 static void qls_free_rss_dma(qla_host_t *ha);
72 static int qls_alloc_rss_dma(qla_host_t *ha);
73 
74 static int qls_flash_validate(qla_host_t *ha, const char *signature);
75 
76 static int qls_wait_for_proc_addr_ready(qla_host_t *ha);
77 static int qls_proc_addr_rd_reg(qla_host_t *ha, uint32_t addr_module,
78 		uint32_t reg, uint32_t *data);
79 static int qls_proc_addr_wr_reg(qla_host_t *ha, uint32_t addr_module,
80 		uint32_t reg, uint32_t data);
81 
82 static int qls_hw_reset(qla_host_t *ha);
83 
84 /*
85  * MPI Related Functions
86  */
87 static int qls_mbx_cmd(qla_host_t *ha, uint32_t *in_mbx, uint32_t i_count,
88 		uint32_t *out_mbx, uint32_t o_count);
89 static int qls_mbx_set_mgmt_ctrl(qla_host_t *ha, uint32_t t_ctrl);
90 static int qls_mbx_get_mgmt_ctrl(qla_host_t *ha, uint32_t *t_status);
91 static void qls_mbx_get_link_status(qla_host_t *ha);
92 static void qls_mbx_about_fw(qla_host_t *ha);
93 
94 int
95 qls_get_msix_count(qla_host_t *ha)
96 {
97 	return (ha->num_rx_rings);
98 }
99 
100 static int
101 qls_syctl_mpi_dump(SYSCTL_HANDLER_ARGS)
102 {
103         int err = 0, ret;
104         qla_host_t *ha;
105 
106         err = sysctl_handle_int(oidp, &ret, 0, req);
107 
108         if (err || !req->newptr)
109                 return (err);
110 
111         if (ret == 1) {
112                 ha = (qla_host_t *)arg1;
113 		qls_mpi_core_dump(ha);
114         }
115         return (err);
116 }
117 
118 static int
119 qls_syctl_link_status(SYSCTL_HANDLER_ARGS)
120 {
121         int err = 0, ret;
122         qla_host_t *ha;
123 
124         err = sysctl_handle_int(oidp, &ret, 0, req);
125 
126         if (err || !req->newptr)
127                 return (err);
128 
129         if (ret == 1) {
130                 ha = (qla_host_t *)arg1;
131 		qls_mbx_get_link_status(ha);
132 		qls_mbx_about_fw(ha);
133         }
134         return (err);
135 }
136 
137 void
138 qls_hw_add_sysctls(qla_host_t *ha)
139 {
140         device_t	dev;
141 
142         dev = ha->pci_dev;
143 
144 	ha->num_rx_rings = MAX_RX_RINGS; ha->num_tx_rings = MAX_TX_RINGS;
145 
146 	SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
147 		SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
148 		OID_AUTO, "num_rx_rings", CTLFLAG_RD, &ha->num_rx_rings,
149 		ha->num_rx_rings, "Number of Completion Queues");
150 
151         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
152                 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
153                 OID_AUTO, "num_tx_rings", CTLFLAG_RD, &ha->num_tx_rings,
154 		ha->num_tx_rings, "Number of Transmit Rings");
155 
156         SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
157             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
158             OID_AUTO, "mpi_dump",
159 	    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, (void *)ha, 0,
160 	    qls_syctl_mpi_dump, "I", "MPI Dump");
161 
162         SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
163             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
164             OID_AUTO, "link_status",
165 	    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, (void *)ha, 0,
166 	    qls_syctl_link_status, "I", "Link Status");
167 }
168 
169 /*
170  * Name: qls_free_dma
171  * Function: Frees the DMA'able memory allocated in qls_alloc_dma()
172  */
173 void
174 qls_free_dma(qla_host_t *ha)
175 {
176 	qls_free_rss_dma(ha);
177 	qls_free_mpi_dma(ha);
178 	qls_free_tx_dma(ha);
179 	qls_free_rx_dma(ha);
180 	return;
181 }
182 
183 /*
184  * Name: qls_alloc_dma
185  * Function: Allocates DMA'able memory for Tx/Rx Rings, Tx/Rx Contexts.
186  */
187 int
188 qls_alloc_dma(qla_host_t *ha)
189 {
190 	if (qls_alloc_rx_dma(ha))
191 		return (-1);
192 
193 	if (qls_alloc_tx_dma(ha)) {
194 		qls_free_rx_dma(ha);
195 		return (-1);
196 	}
197 
198 	if (qls_alloc_mpi_dma(ha)) {
199 		qls_free_tx_dma(ha);
200 		qls_free_rx_dma(ha);
201 		return (-1);
202 	}
203 
204 	if (qls_alloc_rss_dma(ha)) {
205 		qls_free_mpi_dma(ha);
206 		qls_free_tx_dma(ha);
207 		qls_free_rx_dma(ha);
208 		return (-1);
209 	}
210 
211 	return (0);
212 }
213 
214 static int
215 qls_wait_for_mac_proto_idx_ready(qla_host_t *ha, uint32_t op)
216 {
217 	uint32_t data32;
218 	uint32_t count = 3;
219 
220 	while (count--) {
221 		data32 = READ_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX);
222 
223 		if (data32 & op)
224 			return (0);
225 
226 		QLA_USEC_DELAY(100);
227 	}
228 	ha->qla_initiate_recovery = 1;
229 	return (-1);
230 }
231 
232 /*
233  * Name: qls_config_unicast_mac_addr
234  * Function: binds/unbinds a unicast MAC address to the interface.
235  */
236 static int
237 qls_config_unicast_mac_addr(qla_host_t *ha, uint32_t add_mac)
238 {
239 	int ret = 0;
240 	uint32_t mac_upper = 0;
241 	uint32_t mac_lower = 0;
242 	uint32_t value = 0, index;
243 
244 	if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_MAC_SERDES,
245 		Q81_CTL_SEM_SET_MAC_SERDES)) {
246 		QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
247 		return(-1);
248 	}
249 
250 	if (add_mac) {
251 		mac_upper = (ha->mac_addr[0] << 8) | ha->mac_addr[1];
252 		mac_lower = (ha->mac_addr[2] << 24) | (ha->mac_addr[3] << 16) |
253 				(ha->mac_addr[4] << 8) | ha->mac_addr[5];
254 	}
255 	ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW);
256 	if (ret)
257 		goto qls_config_unicast_mac_addr_exit;
258 
259 	index = 128 * (ha->pci_func & 0x1); /* index */
260 
261 	value = (index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) |
262 		Q81_CTL_MAC_PROTO_AI_TYPE_CAM_MAC;
263 
264 	WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value);
265 	WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, mac_lower);
266 
267 	ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW);
268 	if (ret)
269 		goto qls_config_unicast_mac_addr_exit;
270 
271 	value = (index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) |
272 		Q81_CTL_MAC_PROTO_AI_TYPE_CAM_MAC | 0x1;
273 
274 	WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value);
275 	WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, mac_upper);
276 
277 	ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW);
278 	if (ret)
279 		goto qls_config_unicast_mac_addr_exit;
280 
281 	value = (index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) |
282 		Q81_CTL_MAC_PROTO_AI_TYPE_CAM_MAC | 0x2;
283 
284 	WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value);
285 
286 	value = Q81_CAM_MAC_OFF2_ROUTE_NIC |
287 			((ha->pci_func & 0x1) << Q81_CAM_MAC_OFF2_FUNC_SHIFT) |
288 			(0 << Q81_CAM_MAC_OFF2_CQID_SHIFT);
289 
290 	WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, value);
291 
292 qls_config_unicast_mac_addr_exit:
293 	qls_sem_unlock(ha, Q81_CTL_SEM_MASK_MAC_SERDES);
294 	return (ret);
295 }
296 
297 /*
298  * Name: qls_config_mcast_mac_addr
299  * Function: binds/unbinds a multicast MAC address to the interface.
300  */
301 static int
302 qls_config_mcast_mac_addr(qla_host_t *ha, uint8_t *mac_addr, uint32_t add_mac,
303 	uint32_t index)
304 {
305 	int ret = 0;
306 	uint32_t mac_upper = 0;
307 	uint32_t mac_lower = 0;
308 	uint32_t value = 0;
309 
310 	if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_MAC_SERDES,
311 		Q81_CTL_SEM_SET_MAC_SERDES)) {
312 		QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
313 		return(-1);
314 	}
315 
316 	if (add_mac) {
317 		mac_upper = (mac_addr[0] << 8) | mac_addr[1];
318 		mac_lower = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
319 				(mac_addr[4] << 8) | mac_addr[5];
320 	}
321 	ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW);
322 	if (ret)
323 		goto qls_config_mcast_mac_addr_exit;
324 
325 	value = Q81_CTL_MAC_PROTO_AI_E |
326 			(index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) |
327 			Q81_CTL_MAC_PROTO_AI_TYPE_MCAST ;
328 
329 	WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value);
330 	WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, mac_lower);
331 
332 	ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW);
333 	if (ret)
334 		goto qls_config_mcast_mac_addr_exit;
335 
336 	value = Q81_CTL_MAC_PROTO_AI_E |
337 			(index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) |
338 			Q81_CTL_MAC_PROTO_AI_TYPE_MCAST | 0x1;
339 
340 	WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value);
341 	WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, mac_upper);
342 
343 qls_config_mcast_mac_addr_exit:
344 	qls_sem_unlock(ha, Q81_CTL_SEM_MASK_MAC_SERDES);
345 
346 	return (ret);
347 }
348 
349 /*
350  * Name: qls_set_mac_rcv_mode
351  * Function: Enable/Disable AllMulticast and Promiscuous Modes.
352  */
353 static int
354 qls_wait_for_route_idx_ready(qla_host_t *ha, uint32_t op)
355 {
356 	uint32_t data32;
357 	uint32_t count = 3;
358 
359 	while (count--) {
360 		data32 = READ_REG32(ha, Q81_CTL_ROUTING_INDEX);
361 
362 		if (data32 & op)
363 			return (0);
364 
365 		QLA_USEC_DELAY(100);
366 	}
367 	ha->qla_initiate_recovery = 1;
368 	return (-1);
369 }
370 
371 static int
372 qls_load_route_idx_reg(qla_host_t *ha, uint32_t index, uint32_t data)
373 {
374 	int ret = 0;
375 
376 	ret = qls_wait_for_route_idx_ready(ha, Q81_CTL_RI_MW);
377 
378 	if (ret) {
379 		device_printf(ha->pci_dev, "%s: [0x%08x, 0x%08x] failed\n",
380 			__func__, index, data);
381 		goto qls_load_route_idx_reg_exit;
382 	}
383 
384 	WRITE_REG32(ha, Q81_CTL_ROUTING_INDEX, index);
385 	WRITE_REG32(ha, Q81_CTL_ROUTING_DATA, data);
386 
387 qls_load_route_idx_reg_exit:
388 	return (ret);
389 }
390 
391 static int
392 qls_load_route_idx_reg_locked(qla_host_t *ha, uint32_t index, uint32_t data)
393 {
394 	int ret = 0;
395 
396 	if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG,
397 		Q81_CTL_SEM_SET_RIDX_DATAREG)) {
398 		QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
399 		return(-1);
400 	}
401 
402 	ret = qls_load_route_idx_reg(ha, index, data);
403 
404 	qls_sem_unlock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG);
405 
406 	return (ret);
407 }
408 
409 static int
410 qls_clear_routing_table(qla_host_t *ha)
411 {
412 	int i, ret = 0;
413 
414 	if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG,
415 		Q81_CTL_SEM_SET_RIDX_DATAREG)) {
416 		QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
417 		return(-1);
418 	}
419 
420 	for (i = 0; i < 16; i++) {
421 		ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_TYPE_NICQMASK|
422 			(i << 8) | Q81_CTL_RI_DST_DFLTQ), 0);
423 		if (ret)
424 			break;
425 	}
426 
427 	qls_sem_unlock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG);
428 
429 	return (ret);
430 }
431 
432 int
433 qls_set_promisc(qla_host_t *ha)
434 {
435 	int ret;
436 
437 	ret = qls_load_route_idx_reg_locked(ha,
438 			(Q81_CTL_RI_E | Q81_CTL_RI_TYPE_NICQMASK |
439 			Q81_CTL_RI_IDX_PROMISCUOUS | Q81_CTL_RI_DST_DFLTQ),
440 			Q81_CTL_RD_VALID_PKT);
441 	return (ret);
442 }
443 
444 void
445 qls_reset_promisc(qla_host_t *ha)
446 {
447 	qls_load_route_idx_reg_locked(ha, (Q81_CTL_RI_TYPE_NICQMASK |
448 			Q81_CTL_RI_IDX_PROMISCUOUS | Q81_CTL_RI_DST_DFLTQ), 0);
449 	return;
450 }
451 
452 int
453 qls_set_allmulti(qla_host_t *ha)
454 {
455 	int ret;
456 
457 	ret = qls_load_route_idx_reg_locked(ha,
458 			(Q81_CTL_RI_E | Q81_CTL_RI_TYPE_NICQMASK |
459 			Q81_CTL_RI_IDX_ALLMULTI | Q81_CTL_RI_DST_DFLTQ),
460 			Q81_CTL_RD_MCAST);
461 	return (ret);
462 }
463 
464 void
465 qls_reset_allmulti(qla_host_t *ha)
466 {
467 	qls_load_route_idx_reg_locked(ha, (Q81_CTL_RI_TYPE_NICQMASK |
468 			Q81_CTL_RI_IDX_ALLMULTI | Q81_CTL_RI_DST_DFLTQ), 0);
469 	return;
470 }
471 
472 static int
473 qls_init_fw_routing_table(qla_host_t *ha)
474 {
475 	int ret = 0;
476 
477 	ret = qls_clear_routing_table(ha);
478 	if (ret)
479 		return (-1);
480 
481 	if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG,
482 		Q81_CTL_SEM_SET_RIDX_DATAREG)) {
483 		QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
484 		return(-1);
485 	}
486 
487 	ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_E | Q81_CTL_RI_DST_DROP |
488 			Q81_CTL_RI_TYPE_NICQMASK | Q81_CTL_RI_IDX_ALL_ERROR),
489 			Q81_CTL_RD_ERROR_PKT);
490 	if (ret)
491 		goto qls_init_fw_routing_table_exit;
492 
493 	ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_E | Q81_CTL_RI_DST_DFLTQ |
494 			Q81_CTL_RI_TYPE_NICQMASK | Q81_CTL_RI_IDX_BCAST),
495 			Q81_CTL_RD_BCAST);
496 	if (ret)
497 		goto qls_init_fw_routing_table_exit;
498 
499 	if (ha->num_rx_rings > 1 ) {
500 		ret = qls_load_route_idx_reg(ha,
501 				(Q81_CTL_RI_E | Q81_CTL_RI_DST_RSS |
502 				Q81_CTL_RI_TYPE_NICQMASK |
503 				Q81_CTL_RI_IDX_RSS_MATCH),
504 				Q81_CTL_RD_RSS_MATCH);
505 		if (ret)
506 			goto qls_init_fw_routing_table_exit;
507 	}
508 
509 	ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_E | Q81_CTL_RI_DST_DFLTQ |
510 			Q81_CTL_RI_TYPE_NICQMASK | Q81_CTL_RI_IDX_MCAST_MATCH),
511 			Q81_CTL_RD_MCAST_REG_MATCH);
512 	if (ret)
513 		goto qls_init_fw_routing_table_exit;
514 
515 	ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_E | Q81_CTL_RI_DST_DFLTQ |
516 			Q81_CTL_RI_TYPE_NICQMASK | Q81_CTL_RI_IDX_CAM_HIT),
517 			Q81_CTL_RD_CAM_HIT);
518 	if (ret)
519 		goto qls_init_fw_routing_table_exit;
520 
521 qls_init_fw_routing_table_exit:
522 	qls_sem_unlock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG);
523 	return (ret);
524 }
525 
526 static int
527 qls_tx_tso_chksum(qla_host_t *ha, struct mbuf *mp, q81_tx_tso_t *tx_mac)
528 {
529 #if defined(INET) || defined(INET6)
530         struct ether_vlan_header *eh;
531         struct ip *ip;
532 #if defined(INET6)
533         struct ip6_hdr *ip6;
534 #endif
535 	struct tcphdr *th;
536         uint32_t ehdrlen, ip_hlen;
537 	int ret = 0;
538         uint16_t etype;
539         uint8_t buf[sizeof(struct ip6_hdr)];
540 
541         eh = mtod(mp, struct ether_vlan_header *);
542 
543         if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
544                 ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
545                 etype = ntohs(eh->evl_proto);
546         } else {
547                 ehdrlen = ETHER_HDR_LEN;
548                 etype = ntohs(eh->evl_encap_proto);
549         }
550 
551         switch (etype) {
552 #ifdef INET
553                 case ETHERTYPE_IP:
554                         ip = (struct ip *)(mp->m_data + ehdrlen);
555 
556                         ip_hlen = sizeof (struct ip);
557 
558                         if (mp->m_len < (ehdrlen + ip_hlen)) {
559                                 m_copydata(mp, ehdrlen, sizeof(struct ip), buf);
560                                 ip = (struct ip *)buf;
561                         }
562 			tx_mac->opcode = Q81_IOCB_TX_TSO;
563 			tx_mac->flags |= Q81_TX_TSO_FLAGS_IPV4 ;
564 
565 			tx_mac->phdr_offsets = ehdrlen;
566 
567 			tx_mac->phdr_offsets |= ((ehdrlen + ip_hlen) <<
568 							Q81_TX_TSO_PHDR_SHIFT);
569 
570 			ip->ip_sum = 0;
571 
572 			if (mp->m_pkthdr.csum_flags & CSUM_TSO) {
573 				tx_mac->flags |= Q81_TX_TSO_FLAGS_LSO;
574 
575 				th = (struct tcphdr *)(ip + 1);
576 
577 				th->th_sum = in_pseudo(ip->ip_src.s_addr,
578 						ip->ip_dst.s_addr,
579 						htons(IPPROTO_TCP));
580 				tx_mac->mss = mp->m_pkthdr.tso_segsz;
581 				tx_mac->phdr_length = ip_hlen + ehdrlen +
582 							(th->th_off << 2);
583 				break;
584 			}
585 			tx_mac->vlan_off |= Q81_TX_TSO_VLAN_OFF_IC ;
586 
587                         if (ip->ip_p == IPPROTO_TCP) {
588 				tx_mac->flags |= Q81_TX_TSO_FLAGS_TC;
589                         } else if (ip->ip_p == IPPROTO_UDP) {
590 				tx_mac->flags |= Q81_TX_TSO_FLAGS_UC;
591                         }
592                 break;
593 #endif
594 
595 #ifdef INET6
596                 case ETHERTYPE_IPV6:
597                         ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
598 
599                         ip_hlen = sizeof(struct ip6_hdr);
600 
601                         if (mp->m_len < (ehdrlen + ip_hlen)) {
602                                 m_copydata(mp, ehdrlen, sizeof (struct ip6_hdr),
603                                         buf);
604                                 ip6 = (struct ip6_hdr *)buf;
605                         }
606 
607 			tx_mac->opcode = Q81_IOCB_TX_TSO;
608 			tx_mac->flags |= Q81_TX_TSO_FLAGS_IPV6 ;
609 			tx_mac->vlan_off |= Q81_TX_TSO_VLAN_OFF_IC ;
610 
611 			tx_mac->phdr_offsets = ehdrlen;
612 			tx_mac->phdr_offsets |= ((ehdrlen + ip_hlen) <<
613 							Q81_TX_TSO_PHDR_SHIFT);
614 
615                         if (ip6->ip6_nxt == IPPROTO_TCP) {
616 				tx_mac->flags |= Q81_TX_TSO_FLAGS_TC;
617                         } else if (ip6->ip6_nxt == IPPROTO_UDP) {
618 				tx_mac->flags |= Q81_TX_TSO_FLAGS_UC;
619                         }
620                 break;
621 #endif
622 
623                 default:
624                         ret = -1;
625                 break;
626         }
627 
628         return (ret);
629 #else
630 	return (-1);
631 #endif
632 }
633 
634 #define QLA_TX_MIN_FREE 2
635 int
636 qls_hw_tx_done(qla_host_t *ha, uint32_t txr_idx)
637 {
638 	uint32_t txr_done, txr_next;
639 
640 	txr_done = ha->tx_ring[txr_idx].txr_done;
641 	txr_next = ha->tx_ring[txr_idx].txr_next;
642 
643 	if (txr_done == txr_next) {
644 		ha->tx_ring[txr_idx].txr_free = NUM_TX_DESCRIPTORS;
645 	} else if (txr_done > txr_next) {
646 		ha->tx_ring[txr_idx].txr_free = txr_done - txr_next;
647 	} else {
648 		ha->tx_ring[txr_idx].txr_free = NUM_TX_DESCRIPTORS +
649 			txr_done - txr_next;
650 	}
651 
652 	if (ha->tx_ring[txr_idx].txr_free <= QLA_TX_MIN_FREE)
653 		return (-1);
654 
655 	return (0);
656 }
657 
658 /*
659  * Name: qls_hw_send
660  * Function: Transmits a packet. It first checks if the packet is a
661  *	candidate for Large TCP Segment Offload and then for UDP/TCP checksum
662  *	offload. If either of these creteria are not met, it is transmitted
663  *	as a regular ethernet frame.
664  */
665 int
666 qls_hw_send(qla_host_t *ha, bus_dma_segment_t *segs, int nsegs,
667 	uint32_t txr_next,  struct mbuf *mp, uint32_t txr_idx)
668 {
669         q81_tx_mac_t *tx_mac;
670 	q81_txb_desc_t *tx_desc;
671         uint32_t total_length = 0;
672         uint32_t i;
673         device_t dev;
674 	int ret = 0;
675 
676 	dev = ha->pci_dev;
677 
678         total_length = mp->m_pkthdr.len;
679 
680         if (total_length > QLA_MAX_TSO_FRAME_SIZE) {
681                 device_printf(dev, "%s: total length exceeds maxlen(%d)\n",
682                         __func__, total_length);
683                 return (-1);
684         }
685 
686 	if (ha->tx_ring[txr_idx].txr_free <= (NUM_TX_DESCRIPTORS >> 2)) {
687 		if (qls_hw_tx_done(ha, txr_idx)) {
688 			device_printf(dev, "%s: tx_free[%d] = %d\n",
689 				__func__, txr_idx,
690 				ha->tx_ring[txr_idx].txr_free);
691 			return (-1);
692 		}
693 	}
694 
695 	tx_mac = (q81_tx_mac_t *)&ha->tx_ring[txr_idx].wq_vaddr[txr_next];
696 
697 	bzero(tx_mac, sizeof(q81_tx_mac_t));
698 
699 	if ((mp->m_pkthdr.csum_flags &
700 			(CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO)) != 0) {
701 		ret = qls_tx_tso_chksum(ha, mp, (q81_tx_tso_t *)tx_mac);
702 		if (ret)
703 			return (EINVAL);
704 
705 		if (mp->m_pkthdr.csum_flags & CSUM_TSO)
706 			ha->tx_ring[txr_idx].tx_tso_frames++;
707 		else
708 			ha->tx_ring[txr_idx].tx_frames++;
709 
710 	} else {
711 		tx_mac->opcode = Q81_IOCB_TX_MAC;
712 	}
713 
714 	if (mp->m_flags & M_VLANTAG) {
715 		tx_mac->vlan_tci = mp->m_pkthdr.ether_vtag;
716 		tx_mac->vlan_off |= Q81_TX_MAC_VLAN_OFF_V;
717 
718 		ha->tx_ring[txr_idx].tx_vlan_frames++;
719 	}
720 
721 	tx_mac->frame_length = total_length;
722 
723 	tx_mac->tid_lo = txr_next;
724 
725 	if (nsegs <= MAX_TX_MAC_DESC) {
726 		QL_DPRINT2((dev, "%s: 1 [%d, %d]\n", __func__, total_length,
727 			tx_mac->tid_lo));
728 
729 		for (i = 0; i < nsegs; i++) {
730 			tx_mac->txd[i].baddr = segs->ds_addr;
731 			tx_mac->txd[i].length = segs->ds_len;
732 			segs++;
733 		}
734 		tx_mac->txd[(nsegs - 1)].flags = Q81_RXB_DESC_FLAGS_E;
735 
736 	} else {
737 		QL_DPRINT2((dev, "%s: 2 [%d, %d]\n", __func__, total_length,
738 			tx_mac->tid_lo));
739 
740 		tx_mac->txd[0].baddr =
741 			ha->tx_ring[txr_idx].tx_buf[txr_next].oal_paddr;
742 		tx_mac->txd[0].length =
743 			nsegs * (sizeof(q81_txb_desc_t));
744 		tx_mac->txd[0].flags = Q81_RXB_DESC_FLAGS_C;
745 
746 		tx_desc = ha->tx_ring[txr_idx].tx_buf[txr_next].oal_vaddr;
747 
748 		for (i = 0; i < nsegs; i++) {
749 			tx_desc->baddr = segs->ds_addr;
750 			tx_desc->length = segs->ds_len;
751 
752 			if (i == (nsegs -1))
753 				tx_desc->flags = Q81_RXB_DESC_FLAGS_E;
754 			else
755 				tx_desc->flags = 0;
756 
757 			segs++;
758 			tx_desc++;
759 		}
760 	}
761 	txr_next = (txr_next + 1) & (NUM_TX_DESCRIPTORS - 1);
762 	ha->tx_ring[txr_idx].txr_next = txr_next;
763 
764 	ha->tx_ring[txr_idx].txr_free--;
765 
766 	Q81_WR_WQ_PROD_IDX(txr_idx, txr_next);
767 
768 	return (0);
769 }
770 
771 /*
772  * Name: qls_del_hw_if
773  * Function: Destroys the hardware specific entities corresponding to an
774  *	Ethernet Interface
775  */
776 void
777 qls_del_hw_if(qla_host_t *ha)
778 {
779 	uint32_t value;
780 	int i;
781 	//int  count;
782 
783 	if (ha->hw_init == 0) {
784 		qls_hw_reset(ha);
785 		return;
786 	}
787 
788 	for (i = 0;  i < ha->num_tx_rings; i++) {
789 		Q81_SET_WQ_INVALID(i);
790 	}
791 	for (i = 0;  i < ha->num_rx_rings; i++) {
792 		Q81_SET_CQ_INVALID(i);
793 	}
794 
795 	for (i = 0; i < ha->num_rx_rings; i++) {
796 		Q81_DISABLE_INTR(ha, i); /* MSI-x i */
797 	}
798 
799 	value = (Q81_CTL_INTRE_IHD << Q81_CTL_INTRE_MASK_SHIFT);
800 	WRITE_REG32(ha, Q81_CTL_INTR_ENABLE, value);
801 
802 	value = (Q81_CTL_INTRE_EI << Q81_CTL_INTRE_MASK_SHIFT);
803 	WRITE_REG32(ha, Q81_CTL_INTR_ENABLE, value);
804 	ha->flags.intr_enable = 0;
805 
806 	qls_hw_reset(ha);
807 
808 	return;
809 }
810 
811 /*
812  * Name: qls_init_hw_if
813  * Function: Creates the hardware specific entities corresponding to an
814  *	Ethernet Interface - Transmit and Receive Contexts. Sets the MAC Address
815  *	corresponding to the interface. Enables LRO if allowed.
816  */
817 int
818 qls_init_hw_if(qla_host_t *ha)
819 {
820 	uint32_t	value;
821 	int		ret = 0;
822 	int		i;
823 
824 	QL_DPRINT2((ha->pci_dev, "%s:enter\n", __func__));
825 
826 	ret = qls_hw_reset(ha);
827 	if (ret)
828 		goto qls_init_hw_if_exit;
829 
830 	ha->vm_pgsize = 4096;
831 
832 	/* Enable FAE and EFE bits in System Register */
833 	value = Q81_CTL_SYSTEM_ENABLE_FAE | Q81_CTL_SYSTEM_ENABLE_EFE;
834 	value = (value << Q81_CTL_SYSTEM_MASK_SHIFT) | value;
835 
836 	WRITE_REG32(ha, Q81_CTL_SYSTEM, value);
837 
838 	/* Set Default Completion Queue_ID in NIC Rcv Configuration Register */
839 	value = (Q81_CTL_NIC_RCVC_DCQ_MASK << Q81_CTL_NIC_RCVC_MASK_SHIFT);
840 	WRITE_REG32(ha, Q81_CTL_NIC_RCV_CONFIG, value);
841 
842 	/* Function Specific Control Register - Set Page Size and Enable NIC */
843 	value = Q81_CTL_FUNC_SPECIFIC_FE |
844 		Q81_CTL_FUNC_SPECIFIC_VM_PGSIZE_MASK |
845 		Q81_CTL_FUNC_SPECIFIC_EPC_O |
846 		Q81_CTL_FUNC_SPECIFIC_EPC_I |
847 		Q81_CTL_FUNC_SPECIFIC_EC;
848 	value = (value << Q81_CTL_FUNC_SPECIFIC_MASK_SHIFT) |
849                         Q81_CTL_FUNC_SPECIFIC_FE |
850 			Q81_CTL_FUNC_SPECIFIC_VM_PGSIZE_4K |
851 			Q81_CTL_FUNC_SPECIFIC_EPC_O |
852 			Q81_CTL_FUNC_SPECIFIC_EPC_I |
853 			Q81_CTL_FUNC_SPECIFIC_EC;
854 
855 	WRITE_REG32(ha, Q81_CTL_FUNC_SPECIFIC, value);
856 
857 	/* Interrupt Mask Register */
858 	value = Q81_CTL_INTRM_PI;
859 	value = (value << Q81_CTL_INTRM_MASK_SHIFT) | value;
860 
861 	WRITE_REG32(ha, Q81_CTL_INTR_MASK, value);
862 
863 	/* Initialiatize Completion Queue */
864 	for (i = 0; i < ha->num_rx_rings; i++) {
865 		ret = qls_init_comp_queue(ha, i);
866 		if (ret)
867 			goto qls_init_hw_if_exit;
868 	}
869 
870 	if (ha->num_rx_rings > 1 ) {
871 		ret = qls_init_rss(ha);
872 		if (ret)
873 			goto qls_init_hw_if_exit;
874 	}
875 
876 	/* Initialize Work Queue */
877 
878 	for (i = 0; i < ha->num_tx_rings; i++) {
879 		ret = qls_init_work_queue(ha, i);
880 		if (ret)
881 			goto qls_init_hw_if_exit;
882 	}
883 
884 	if (ret)
885 		goto qls_init_hw_if_exit;
886 
887 	/* Set up CAM RAM with MAC Address */
888 	ret = qls_config_unicast_mac_addr(ha, 1);
889 	if (ret)
890 		goto qls_init_hw_if_exit;
891 
892 	ret = qls_hw_add_all_mcast(ha);
893 	if (ret)
894 		goto qls_init_hw_if_exit;
895 
896 	/* Initialize Firmware Routing Table */
897 	ret = qls_init_fw_routing_table(ha);
898 	if (ret)
899 		goto qls_init_hw_if_exit;
900 
901 	/* Get Chip Revision ID */
902 	ha->rev_id = READ_REG32(ha, Q81_CTL_REV_ID);
903 
904 	/* Enable Global Interrupt */
905 	value = Q81_CTL_INTRE_EI;
906 	value = (value << Q81_CTL_INTRE_MASK_SHIFT) | value;
907 
908 	WRITE_REG32(ha, Q81_CTL_INTR_ENABLE, value);
909 
910 	/* Enable Interrupt Handshake Disable */
911 	value = Q81_CTL_INTRE_IHD;
912 	value = (value << Q81_CTL_INTRE_MASK_SHIFT) | value;
913 
914 	WRITE_REG32(ha, Q81_CTL_INTR_ENABLE, value);
915 
916 	/* Enable Completion Interrupt */
917 
918 	ha->flags.intr_enable = 1;
919 
920 	for (i = 0; i < ha->num_rx_rings; i++) {
921 		Q81_ENABLE_INTR(ha, i); /* MSI-x i */
922 	}
923 
924 	ha->hw_init = 1;
925 
926 	qls_mbx_get_link_status(ha);
927 
928 	QL_DPRINT2((ha->pci_dev, "%s:rxr [0x%08x]\n", __func__,
929 		ha->rx_ring[0].cq_db_offset));
930 	QL_DPRINT2((ha->pci_dev, "%s:txr [0x%08x]\n", __func__,
931 		ha->tx_ring[0].wq_db_offset));
932 
933 	for (i = 0; i < ha->num_rx_rings; i++) {
934 		Q81_WR_CQ_CONS_IDX(i, 0);
935 		Q81_WR_LBQ_PROD_IDX(i, ha->rx_ring[i].lbq_in);
936 		Q81_WR_SBQ_PROD_IDX(i, ha->rx_ring[i].sbq_in);
937 
938 		QL_DPRINT2((ha->pci_dev,
939 			"%s: [wq_idx, cq_idx, lbq_idx, sbq_idx]"
940 			"[0x%08x, 0x%08x, 0x%08x, 0x%08x]\n", __func__,
941 			Q81_RD_WQ_IDX(i), Q81_RD_CQ_IDX(i), Q81_RD_LBQ_IDX(i),
942 			Q81_RD_SBQ_IDX(i)));
943 	}
944 
945 	for (i = 0; i < ha->num_rx_rings; i++) {
946 		Q81_SET_CQ_VALID(i);
947 	}
948 
949 qls_init_hw_if_exit:
950 	QL_DPRINT2((ha->pci_dev, "%s:exit\n", __func__));
951 	return (ret);
952 }
953 
954 static int
955 qls_wait_for_config_reg_bits(qla_host_t *ha, uint32_t bits, uint32_t value)
956 {
957 	uint32_t data32;
958 	uint32_t count = 3;
959 
960 	while (count--) {
961 		data32 = READ_REG32(ha, Q81_CTL_CONFIG);
962 
963 		if ((data32 & bits) == value)
964 			return (0);
965 
966 		QLA_USEC_DELAY(100);
967 	}
968 	ha->qla_initiate_recovery = 1;
969 	device_printf(ha->pci_dev, "%s: failed\n", __func__);
970 	return (-1);
971 }
972 
973 static int
974 qls_init_rss(qla_host_t *ha)
975 {
976 	uint8_t		rss_key[RSS_KEYSIZE];
977 	q81_rss_icb_t	*rss_icb;
978 	int		ret = 0;
979 	int		i;
980 	uint32_t	value;
981 
982 	rss_icb = ha->rss_dma.dma_b;
983 
984 	bzero(rss_icb, sizeof (q81_rss_icb_t));
985 
986 	rss_icb->flags_base_cq_num = Q81_RSS_ICB_FLAGS_L4K |
987 				Q81_RSS_ICB_FLAGS_L6K | Q81_RSS_ICB_FLAGS_LI |
988 				Q81_RSS_ICB_FLAGS_LB | Q81_RSS_ICB_FLAGS_LM |
989 				Q81_RSS_ICB_FLAGS_RT4 | Q81_RSS_ICB_FLAGS_RT6;
990 
991 	rss_icb->mask = 0x3FF;
992 
993 	for (i = 0; i < Q81_RSS_ICB_NUM_INDTBL_ENTRIES; i++) {
994 		rss_icb->cq_id[i] = (i & (ha->num_rx_rings - 1));
995 	}
996 
997 	_Static_assert(sizeof(rss_icb->ipv6_rss_hash_key) == RSS_KEYSIZE,
998 	    "RSS key size mismatch");
999 	_Static_assert(sizeof(rss_icb->ipv4_rss_hash_key) <= RSS_KEYSIZE,
1000 	    "IPv4 RSS key exceeds common key size");
1001 	rss_getkey(rss_key);
1002 	/* The ICB stores each network-order key word in little-endian order. */
1003 	for (i = 0; i < nitems(rss_icb->ipv6_rss_hash_key); i++)
1004 		le32enc(&rss_icb->ipv6_rss_hash_key[i],
1005 		    be32dec(rss_key + i * sizeof(uint32_t)));
1006 	memcpy(rss_icb->ipv4_rss_hash_key, rss_icb->ipv6_rss_hash_key,
1007 	    sizeof(rss_icb->ipv4_rss_hash_key));
1008 
1009 	ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LR, 0);
1010 
1011 	if (ret)
1012 		goto qls_init_rss_exit;
1013 
1014 	ret = qls_sem_lock(ha, Q81_CTL_SEM_MASK_ICB, Q81_CTL_SEM_SET_ICB);
1015 
1016 	if (ret) {
1017 		QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
1018 		goto qls_init_rss_exit;
1019 	}
1020 
1021 	value = (uint32_t)ha->rss_dma.dma_addr;
1022 	WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_LO, value);
1023 
1024 	value = (uint32_t)(ha->rss_dma.dma_addr >> 32);
1025 	WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_HI, value);
1026 
1027 	qls_sem_unlock(ha, Q81_CTL_SEM_MASK_ICB);
1028 
1029 	value = (Q81_CTL_CONFIG_LR << Q81_CTL_CONFIG_MASK_SHIFT) |
1030 			Q81_CTL_CONFIG_LR;
1031 
1032 	WRITE_REG32(ha, Q81_CTL_CONFIG, value);
1033 
1034 	ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LR, 0);
1035 
1036 qls_init_rss_exit:
1037 	return (ret);
1038 }
1039 
1040 static int
1041 qls_init_comp_queue(qla_host_t *ha, int cid)
1042 {
1043 	q81_cq_icb_t	*cq_icb;
1044 	qla_rx_ring_t	*rxr;
1045 	int		ret = 0;
1046 	uint32_t	value;
1047 
1048 	rxr = &ha->rx_ring[cid];
1049 
1050 	rxr->cq_db_offset = ha->vm_pgsize * (128 + cid);
1051 
1052 	cq_icb = rxr->cq_icb_vaddr;
1053 
1054 	bzero(cq_icb, sizeof (q81_cq_icb_t));
1055 
1056 	cq_icb->msix_vector = cid;
1057 	cq_icb->flags = Q81_CQ_ICB_FLAGS_LC |
1058 			Q81_CQ_ICB_FLAGS_LI |
1059 			Q81_CQ_ICB_FLAGS_LL |
1060 			Q81_CQ_ICB_FLAGS_LS |
1061 			Q81_CQ_ICB_FLAGS_LV;
1062 
1063 	cq_icb->length_v = NUM_CQ_ENTRIES;
1064 
1065 	cq_icb->cq_baddr_lo = (rxr->cq_base_paddr & 0xFFFFFFFF);
1066 	cq_icb->cq_baddr_hi = (rxr->cq_base_paddr >> 32) & 0xFFFFFFFF;
1067 
1068 	cq_icb->cqi_addr_lo = (rxr->cqi_paddr & 0xFFFFFFFF);
1069 	cq_icb->cqi_addr_hi = (rxr->cqi_paddr >> 32) & 0xFFFFFFFF;
1070 
1071 	cq_icb->pkt_idelay = 10;
1072 	cq_icb->idelay = 100;
1073 
1074 	cq_icb->lbq_baddr_lo = (rxr->lbq_addr_tbl_paddr & 0xFFFFFFFF);
1075 	cq_icb->lbq_baddr_hi = (rxr->lbq_addr_tbl_paddr >> 32) & 0xFFFFFFFF;
1076 
1077 	cq_icb->lbq_bsize = QLA_LGB_SIZE;
1078 	cq_icb->lbq_length = QLA_NUM_LGB_ENTRIES;
1079 
1080 	cq_icb->sbq_baddr_lo = (rxr->sbq_addr_tbl_paddr & 0xFFFFFFFF);
1081 	cq_icb->sbq_baddr_hi = (rxr->sbq_addr_tbl_paddr >> 32) & 0xFFFFFFFF;
1082 
1083 	cq_icb->sbq_bsize = (uint16_t)ha->msize;
1084 	cq_icb->sbq_length = QLA_NUM_SMB_ENTRIES;
1085 
1086 	QL_DUMP_CQ(ha);
1087 
1088 	ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LCQ, 0);
1089 
1090 	if (ret)
1091 		goto qls_init_comp_queue_exit;
1092 
1093 	ret = qls_sem_lock(ha, Q81_CTL_SEM_MASK_ICB, Q81_CTL_SEM_SET_ICB);
1094 
1095 	if (ret) {
1096 		QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
1097 		goto qls_init_comp_queue_exit;
1098 	}
1099 
1100 	value = (uint32_t)rxr->cq_icb_paddr;
1101 	WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_LO, value);
1102 
1103 	value = (uint32_t)(rxr->cq_icb_paddr >> 32);
1104 	WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_HI, value);
1105 
1106 	qls_sem_unlock(ha, Q81_CTL_SEM_MASK_ICB);
1107 
1108 	value = Q81_CTL_CONFIG_LCQ | Q81_CTL_CONFIG_Q_NUM_MASK;
1109 	value = (value << Q81_CTL_CONFIG_MASK_SHIFT) | Q81_CTL_CONFIG_LCQ;
1110 	value |= (cid << Q81_CTL_CONFIG_Q_NUM_SHIFT);
1111 	WRITE_REG32(ha, Q81_CTL_CONFIG, value);
1112 
1113 	ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LCQ, 0);
1114 
1115 	rxr->cq_next = 0;
1116 	rxr->lbq_next = rxr->lbq_free = 0;
1117 	rxr->sbq_next = rxr->sbq_free = 0;
1118 	rxr->rx_free = rxr->rx_next = 0;
1119 	rxr->lbq_in = (QLA_NUM_LGB_ENTRIES - 1) & ~0xF;
1120 	rxr->sbq_in = (QLA_NUM_SMB_ENTRIES - 1) & ~0xF;
1121 
1122 qls_init_comp_queue_exit:
1123 	return (ret);
1124 }
1125 
1126 static int
1127 qls_init_work_queue(qla_host_t *ha, int wid)
1128 {
1129 	q81_wq_icb_t	*wq_icb;
1130 	qla_tx_ring_t	*txr;
1131 	int		ret = 0;
1132 	uint32_t	value;
1133 
1134 	txr = &ha->tx_ring[wid];
1135 
1136 	txr->wq_db_addr = (struct resource *)((uint8_t *)ha->pci_reg1
1137 						+ (ha->vm_pgsize * wid));
1138 
1139 	txr->wq_db_offset = (ha->vm_pgsize * wid);
1140 
1141 	wq_icb = txr->wq_icb_vaddr;
1142 	bzero(wq_icb, sizeof (q81_wq_icb_t));
1143 
1144 	wq_icb->length_v = NUM_TX_DESCRIPTORS  |
1145 				Q81_WQ_ICB_VALID;
1146 
1147 	wq_icb->flags = Q81_WQ_ICB_FLAGS_LO | Q81_WQ_ICB_FLAGS_LI |
1148 			Q81_WQ_ICB_FLAGS_LB | Q81_WQ_ICB_FLAGS_LC;
1149 
1150 	wq_icb->wqcqid_rss = wid;
1151 
1152 	wq_icb->baddr_lo = txr->wq_paddr & 0xFFFFFFFF;
1153 	wq_icb->baddr_hi = (txr->wq_paddr >> 32)& 0xFFFFFFFF;
1154 
1155 	wq_icb->ci_addr_lo = txr->txr_cons_paddr & 0xFFFFFFFF;
1156 	wq_icb->ci_addr_hi = (txr->txr_cons_paddr >> 32)& 0xFFFFFFFF;
1157 
1158 	ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LRQ, 0);
1159 
1160 	if (ret)
1161 		goto qls_init_wq_exit;
1162 
1163 	ret = qls_sem_lock(ha, Q81_CTL_SEM_MASK_ICB, Q81_CTL_SEM_SET_ICB);
1164 
1165 	if (ret) {
1166 		QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
1167 		goto qls_init_wq_exit;
1168 	}
1169 
1170 	value = (uint32_t)txr->wq_icb_paddr;
1171 	WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_LO, value);
1172 
1173 	value = (uint32_t)(txr->wq_icb_paddr >> 32);
1174 	WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_HI, value);
1175 
1176 	qls_sem_unlock(ha, Q81_CTL_SEM_MASK_ICB);
1177 
1178 	value = Q81_CTL_CONFIG_LRQ | Q81_CTL_CONFIG_Q_NUM_MASK;
1179 	value = (value << Q81_CTL_CONFIG_MASK_SHIFT) | Q81_CTL_CONFIG_LRQ;
1180 	value |= (wid << Q81_CTL_CONFIG_Q_NUM_SHIFT);
1181 	WRITE_REG32(ha, Q81_CTL_CONFIG, value);
1182 
1183 	ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LRQ, 0);
1184 
1185 	txr->txr_free = NUM_TX_DESCRIPTORS;
1186 	txr->txr_next = 0;
1187 	txr->txr_done = 0;
1188 
1189 qls_init_wq_exit:
1190 	return (ret);
1191 }
1192 
1193 static int
1194 qls_hw_add_all_mcast(qla_host_t *ha)
1195 {
1196 	int i, nmcast;
1197 
1198 	nmcast = ha->nmcast;
1199 
1200 	for (i = 0 ; ((i < Q8_MAX_NUM_MULTICAST_ADDRS) && nmcast); i++) {
1201 		if ((ha->mcast[i].addr[0] != 0) ||
1202 			(ha->mcast[i].addr[1] != 0) ||
1203 			(ha->mcast[i].addr[2] != 0) ||
1204 			(ha->mcast[i].addr[3] != 0) ||
1205 			(ha->mcast[i].addr[4] != 0) ||
1206 			(ha->mcast[i].addr[5] != 0)) {
1207 			if (qls_config_mcast_mac_addr(ha, ha->mcast[i].addr,
1208 				1, i)) {
1209                 		device_printf(ha->pci_dev, "%s: failed\n",
1210 					__func__);
1211 				return (-1);
1212 			}
1213 
1214 			nmcast--;
1215 		}
1216 	}
1217 	return 0;
1218 }
1219 
1220 static int
1221 qls_hw_add_mcast(qla_host_t *ha, uint8_t *mta)
1222 {
1223 	int i;
1224 
1225 	for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) {
1226 		if (QL_MAC_CMP(ha->mcast[i].addr, mta) == 0)
1227 			return 0; /* its been already added */
1228 	}
1229 
1230 	for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) {
1231 		if ((ha->mcast[i].addr[0] == 0) &&
1232 			(ha->mcast[i].addr[1] == 0) &&
1233 			(ha->mcast[i].addr[2] == 0) &&
1234 			(ha->mcast[i].addr[3] == 0) &&
1235 			(ha->mcast[i].addr[4] == 0) &&
1236 			(ha->mcast[i].addr[5] == 0)) {
1237 			if (qls_config_mcast_mac_addr(ha, mta, 1, i))
1238 				return (-1);
1239 
1240 			bcopy(mta, ha->mcast[i].addr, Q8_MAC_ADDR_LEN);
1241 			ha->nmcast++;
1242 
1243 			return 0;
1244 		}
1245 	}
1246 	return 0;
1247 }
1248 
1249 static int
1250 qls_hw_del_mcast(qla_host_t *ha, uint8_t *mta)
1251 {
1252 	int i;
1253 
1254 	for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) {
1255 		if (QL_MAC_CMP(ha->mcast[i].addr, mta) == 0) {
1256 			if (qls_config_mcast_mac_addr(ha, mta, 0, i))
1257 				return (-1);
1258 
1259 			ha->mcast[i].addr[0] = 0;
1260 			ha->mcast[i].addr[1] = 0;
1261 			ha->mcast[i].addr[2] = 0;
1262 			ha->mcast[i].addr[3] = 0;
1263 			ha->mcast[i].addr[4] = 0;
1264 			ha->mcast[i].addr[5] = 0;
1265 
1266 			ha->nmcast--;
1267 
1268 			return 0;
1269 		}
1270 	}
1271 	return 0;
1272 }
1273 
1274 /*
1275  * Name: qls_hw_set_multi
1276  * Function: Sets the Multicast Addresses provided the host O.S into the
1277  *	hardware (for the given interface)
1278  */
1279 void
1280 qls_hw_set_multi(qla_host_t *ha, uint8_t *mta, uint32_t mcnt,
1281 	uint32_t add_mac)
1282 {
1283 	int i;
1284 
1285 	for (i = 0; i < mcnt; i++) {
1286 		if (add_mac) {
1287 			if (qls_hw_add_mcast(ha, mta))
1288 				break;
1289 		} else {
1290 			if (qls_hw_del_mcast(ha, mta))
1291 				break;
1292 		}
1293 
1294 		mta += Q8_MAC_ADDR_LEN;
1295 	}
1296 	return;
1297 }
1298 
1299 void
1300 qls_update_link_state(qla_host_t *ha)
1301 {
1302 	uint32_t link_state;
1303 	uint32_t prev_link_state;
1304 
1305 	if (!(if_getdrvflags(ha->ifp) & IFF_DRV_RUNNING)) {
1306 		ha->link_up = 0;
1307 		return;
1308 	}
1309 	link_state = READ_REG32(ha, Q81_CTL_STATUS);
1310 
1311 	prev_link_state =  ha->link_up;
1312 
1313 	if ((ha->pci_func & 0x1) == 0)
1314 		ha->link_up = ((link_state & Q81_CTL_STATUS_PL0)? 1 : 0);
1315 	else
1316 		ha->link_up = ((link_state & Q81_CTL_STATUS_PL1)? 1 : 0);
1317 
1318 	if (prev_link_state !=  ha->link_up) {
1319 		if (ha->link_up) {
1320 			if_link_state_change(ha->ifp, LINK_STATE_UP);
1321 		} else {
1322 			if_link_state_change(ha->ifp, LINK_STATE_DOWN);
1323 		}
1324 	}
1325 	return;
1326 }
1327 
1328 static void
1329 qls_free_tx_ring_dma(qla_host_t *ha, int r_idx)
1330 {
1331 	if (ha->tx_ring[r_idx].flags.wq_dma) {
1332 		qls_free_dmabuf(ha, &ha->tx_ring[r_idx].wq_dma);
1333 		ha->tx_ring[r_idx].flags.wq_dma = 0;
1334 	}
1335 
1336 	if (ha->tx_ring[r_idx].flags.privb_dma) {
1337 		qls_free_dmabuf(ha, &ha->tx_ring[r_idx].privb_dma);
1338 		ha->tx_ring[r_idx].flags.privb_dma = 0;
1339 	}
1340 	return;
1341 }
1342 
1343 static void
1344 qls_free_tx_dma(qla_host_t *ha)
1345 {
1346 	int i, j;
1347 	qla_tx_buf_t *txb;
1348 
1349 	for (i = 0; i < ha->num_tx_rings; i++) {
1350 		qls_free_tx_ring_dma(ha, i);
1351 
1352 		for (j = 0; j < NUM_TX_DESCRIPTORS; j++) {
1353 			txb = &ha->tx_ring[i].tx_buf[j];
1354 
1355 			if (txb->map) {
1356 				bus_dmamap_destroy(ha->tx_tag, txb->map);
1357 			}
1358 		}
1359 	}
1360 
1361         if (ha->tx_tag != NULL) {
1362                 bus_dma_tag_destroy(ha->tx_tag);
1363                 ha->tx_tag = NULL;
1364         }
1365 
1366 	return;
1367 }
1368 
1369 static int
1370 qls_alloc_tx_ring_dma(qla_host_t *ha, int ridx)
1371 {
1372 	int		ret = 0, i;
1373 	uint8_t		*v_addr;
1374 	bus_addr_t	p_addr;
1375 	qla_tx_buf_t	*txb;
1376 	device_t	dev = ha->pci_dev;
1377 
1378 	ha->tx_ring[ridx].wq_dma.alignment = 8;
1379 	ha->tx_ring[ridx].wq_dma.size =
1380 		NUM_TX_DESCRIPTORS * (sizeof (q81_tx_cmd_t));
1381 
1382 	ret = qls_alloc_dmabuf(ha, &ha->tx_ring[ridx].wq_dma);
1383 
1384 	if (ret) {
1385 		device_printf(dev, "%s: [%d] txr failed\n", __func__, ridx);
1386 		goto qls_alloc_tx_ring_dma_exit;
1387 	}
1388 	ha->tx_ring[ridx].flags.wq_dma = 1;
1389 
1390 	ha->tx_ring[ridx].privb_dma.alignment = 8;
1391 	ha->tx_ring[ridx].privb_dma.size = QLA_TX_PRIVATE_BSIZE;
1392 
1393 	ret = qls_alloc_dmabuf(ha, &ha->tx_ring[ridx].privb_dma);
1394 
1395 	if (ret) {
1396 		device_printf(dev, "%s: [%d] oalb failed\n", __func__, ridx);
1397 		goto qls_alloc_tx_ring_dma_exit;
1398 	}
1399 
1400 	ha->tx_ring[ridx].flags.privb_dma = 1;
1401 
1402 	ha->tx_ring[ridx].wq_vaddr = ha->tx_ring[ridx].wq_dma.dma_b;
1403 	ha->tx_ring[ridx].wq_paddr = ha->tx_ring[ridx].wq_dma.dma_addr;
1404 
1405 	v_addr = ha->tx_ring[ridx].privb_dma.dma_b;
1406 	p_addr = ha->tx_ring[ridx].privb_dma.dma_addr;
1407 
1408 	ha->tx_ring[ridx].wq_icb_vaddr = v_addr;
1409 	ha->tx_ring[ridx].wq_icb_paddr = p_addr;
1410 
1411 	ha->tx_ring[ridx].txr_cons_vaddr =
1412 		(uint32_t *)(v_addr + (PAGE_SIZE >> 1));
1413 	ha->tx_ring[ridx].txr_cons_paddr = p_addr + (PAGE_SIZE >> 1);
1414 
1415 	v_addr = v_addr + (PAGE_SIZE >> 1);
1416 	p_addr = p_addr + (PAGE_SIZE >> 1);
1417 
1418 	txb = ha->tx_ring[ridx].tx_buf;
1419 
1420 	for (i = 0; i < NUM_TX_DESCRIPTORS; i++) {
1421 		txb[i].oal_vaddr = v_addr;
1422 		txb[i].oal_paddr = p_addr;
1423 
1424 		v_addr = v_addr + QLA_OAL_BLK_SIZE;
1425 		p_addr = p_addr + QLA_OAL_BLK_SIZE;
1426 	}
1427 
1428 qls_alloc_tx_ring_dma_exit:
1429 	return (ret);
1430 }
1431 
1432 static int
1433 qls_alloc_tx_dma(qla_host_t *ha)
1434 {
1435 	int	i, j;
1436 	int	ret = 0;
1437 	qla_tx_buf_t *txb;
1438 
1439         if (bus_dma_tag_create(NULL,    /* parent */
1440                 1, 0,    /* alignment, bounds */
1441                 BUS_SPACE_MAXADDR,       /* lowaddr */
1442                 BUS_SPACE_MAXADDR,       /* highaddr */
1443                 NULL, NULL,      /* filter, filterarg */
1444                 QLA_MAX_TSO_FRAME_SIZE,     /* maxsize */
1445                 QLA_MAX_SEGMENTS,        /* nsegments */
1446                 PAGE_SIZE,        /* maxsegsize */
1447                 BUS_DMA_ALLOCNOW,        /* flags */
1448                 NULL,    /* lockfunc */
1449                 NULL,    /* lockfuncarg */
1450                 &ha->tx_tag)) {
1451                 device_printf(ha->pci_dev, "%s: tx_tag alloc failed\n",
1452                         __func__);
1453                 return (ENOMEM);
1454         }
1455 
1456 	for (i = 0; i < ha->num_tx_rings; i++) {
1457 		ret = qls_alloc_tx_ring_dma(ha, i);
1458 
1459 		if (ret) {
1460 			qls_free_tx_dma(ha);
1461 			break;
1462 		}
1463 
1464 		for (j = 0; j < NUM_TX_DESCRIPTORS; j++) {
1465 			txb = &ha->tx_ring[i].tx_buf[j];
1466 
1467 			ret = bus_dmamap_create(ha->tx_tag,
1468 				BUS_DMA_NOWAIT, &txb->map);
1469 			if (ret) {
1470 				ha->err_tx_dmamap_create++;
1471 				device_printf(ha->pci_dev,
1472 				"%s: bus_dmamap_create failed[%d, %d, %d]\n",
1473 				__func__, ret, i, j);
1474 
1475 				qls_free_tx_dma(ha);
1476 
1477                 		return (ret);
1478        			}
1479 		}
1480 	}
1481 
1482 	return (ret);
1483 }
1484 
1485 static void
1486 qls_free_rss_dma(qla_host_t *ha)
1487 {
1488 	qls_free_dmabuf(ha, &ha->rss_dma);
1489 	ha->flags.rss_dma = 0;
1490 }
1491 
1492 static int
1493 qls_alloc_rss_dma(qla_host_t *ha)
1494 {
1495 	int ret = 0;
1496 
1497 	ha->rss_dma.alignment = 4;
1498 	ha->rss_dma.size = PAGE_SIZE;
1499 
1500 	ret = qls_alloc_dmabuf(ha, &ha->rss_dma);
1501 
1502 	if (ret)
1503 		device_printf(ha->pci_dev, "%s: failed\n", __func__);
1504 	else
1505 		ha->flags.rss_dma = 1;
1506 
1507 	return (ret);
1508 }
1509 
1510 static void
1511 qls_free_mpi_dma(qla_host_t *ha)
1512 {
1513 	qls_free_dmabuf(ha, &ha->mpi_dma);
1514 	ha->flags.mpi_dma = 0;
1515 }
1516 
1517 static int
1518 qls_alloc_mpi_dma(qla_host_t *ha)
1519 {
1520 	int ret = 0;
1521 
1522 	ha->mpi_dma.alignment = 4;
1523 	ha->mpi_dma.size = (0x4000 * 4);
1524 
1525 	ret = qls_alloc_dmabuf(ha, &ha->mpi_dma);
1526 	if (ret)
1527 		device_printf(ha->pci_dev, "%s: failed\n", __func__);
1528 	else
1529 		ha->flags.mpi_dma = 1;
1530 
1531 	return (ret);
1532 }
1533 
1534 static void
1535 qls_free_rx_ring_dma(qla_host_t *ha, int ridx)
1536 {
1537 	if (ha->rx_ring[ridx].flags.cq_dma) {
1538 		qls_free_dmabuf(ha, &ha->rx_ring[ridx].cq_dma);
1539 		ha->rx_ring[ridx].flags.cq_dma = 0;
1540 	}
1541 
1542 	if (ha->rx_ring[ridx].flags.lbq_dma) {
1543 		qls_free_dmabuf(ha, &ha->rx_ring[ridx].lbq_dma);
1544 		ha->rx_ring[ridx].flags.lbq_dma = 0;
1545 	}
1546 
1547 	if (ha->rx_ring[ridx].flags.sbq_dma) {
1548 		qls_free_dmabuf(ha, &ha->rx_ring[ridx].sbq_dma);
1549 		ha->rx_ring[ridx].flags.sbq_dma = 0;
1550 	}
1551 
1552 	if (ha->rx_ring[ridx].flags.lb_dma) {
1553 		qls_free_dmabuf(ha, &ha->rx_ring[ridx].lb_dma);
1554 		ha->rx_ring[ridx].flags.lb_dma = 0;
1555 	}
1556 	return;
1557 }
1558 
1559 static void
1560 qls_free_rx_dma(qla_host_t *ha)
1561 {
1562 	int i;
1563 
1564 	for (i = 0; i < ha->num_rx_rings; i++) {
1565 		qls_free_rx_ring_dma(ha, i);
1566 	}
1567 
1568         if (ha->rx_tag != NULL) {
1569                 bus_dma_tag_destroy(ha->rx_tag);
1570                 ha->rx_tag = NULL;
1571         }
1572 
1573 	return;
1574 }
1575 
1576 static int
1577 qls_alloc_rx_ring_dma(qla_host_t *ha, int ridx)
1578 {
1579 	int				i, ret = 0;
1580 	uint8_t				*v_addr;
1581 	bus_addr_t			p_addr;
1582 	volatile q81_bq_addr_e_t	*bq_e;
1583 	device_t			dev = ha->pci_dev;
1584 
1585 	ha->rx_ring[ridx].cq_dma.alignment = 128;
1586 	ha->rx_ring[ridx].cq_dma.size =
1587 		(NUM_CQ_ENTRIES * (sizeof (q81_cq_e_t))) + PAGE_SIZE;
1588 
1589 	ret = qls_alloc_dmabuf(ha, &ha->rx_ring[ridx].cq_dma);
1590 
1591 	if (ret) {
1592 		device_printf(dev, "%s: [%d] cq failed\n", __func__, ridx);
1593 		goto qls_alloc_rx_ring_dma_exit;
1594 	}
1595 	ha->rx_ring[ridx].flags.cq_dma = 1;
1596 
1597 	ha->rx_ring[ridx].lbq_dma.alignment = 8;
1598 	ha->rx_ring[ridx].lbq_dma.size = QLA_LGBQ_AND_TABLE_SIZE;
1599 
1600 	ret = qls_alloc_dmabuf(ha, &ha->rx_ring[ridx].lbq_dma);
1601 
1602 	if (ret) {
1603 		device_printf(dev, "%s: [%d] lbq failed\n", __func__, ridx);
1604 		goto qls_alloc_rx_ring_dma_exit;
1605 	}
1606 	ha->rx_ring[ridx].flags.lbq_dma = 1;
1607 
1608 	ha->rx_ring[ridx].sbq_dma.alignment = 8;
1609 	ha->rx_ring[ridx].sbq_dma.size = QLA_SMBQ_AND_TABLE_SIZE;
1610 
1611 	ret = qls_alloc_dmabuf(ha, &ha->rx_ring[ridx].sbq_dma);
1612 
1613 	if (ret) {
1614 		device_printf(dev, "%s: [%d] sbq failed\n", __func__, ridx);
1615 		goto qls_alloc_rx_ring_dma_exit;
1616 	}
1617 	ha->rx_ring[ridx].flags.sbq_dma = 1;
1618 
1619 	ha->rx_ring[ridx].lb_dma.alignment = 8;
1620 	ha->rx_ring[ridx].lb_dma.size = (QLA_LGB_SIZE * QLA_NUM_LGB_ENTRIES);
1621 
1622 	ret = qls_alloc_dmabuf(ha, &ha->rx_ring[ridx].lb_dma);
1623 	if (ret) {
1624 		device_printf(dev, "%s: [%d] lb failed\n", __func__, ridx);
1625 		goto qls_alloc_rx_ring_dma_exit;
1626 	}
1627 	ha->rx_ring[ridx].flags.lb_dma = 1;
1628 
1629 	bzero(ha->rx_ring[ridx].cq_dma.dma_b, ha->rx_ring[ridx].cq_dma.size);
1630 	bzero(ha->rx_ring[ridx].lbq_dma.dma_b, ha->rx_ring[ridx].lbq_dma.size);
1631 	bzero(ha->rx_ring[ridx].sbq_dma.dma_b, ha->rx_ring[ridx].sbq_dma.size);
1632 	bzero(ha->rx_ring[ridx].lb_dma.dma_b, ha->rx_ring[ridx].lb_dma.size);
1633 
1634 	/* completion queue */
1635 	ha->rx_ring[ridx].cq_base_vaddr = ha->rx_ring[ridx].cq_dma.dma_b;
1636 	ha->rx_ring[ridx].cq_base_paddr = ha->rx_ring[ridx].cq_dma.dma_addr;
1637 
1638 	v_addr = ha->rx_ring[ridx].cq_dma.dma_b;
1639 	p_addr = ha->rx_ring[ridx].cq_dma.dma_addr;
1640 
1641 	v_addr = v_addr + (NUM_CQ_ENTRIES * (sizeof (q81_cq_e_t)));
1642 	p_addr = p_addr + (NUM_CQ_ENTRIES * (sizeof (q81_cq_e_t)));
1643 
1644 	/* completion queue icb */
1645 	ha->rx_ring[ridx].cq_icb_vaddr = v_addr;
1646 	ha->rx_ring[ridx].cq_icb_paddr = p_addr;
1647 
1648 	v_addr = v_addr + (PAGE_SIZE >> 2);
1649 	p_addr = p_addr + (PAGE_SIZE >> 2);
1650 
1651 	/* completion queue index register */
1652 	ha->rx_ring[ridx].cqi_vaddr = (uint32_t *)v_addr;
1653 	ha->rx_ring[ridx].cqi_paddr = p_addr;
1654 
1655 	v_addr = ha->rx_ring[ridx].lbq_dma.dma_b;
1656 	p_addr = ha->rx_ring[ridx].lbq_dma.dma_addr;
1657 
1658 	/* large buffer queue address table */
1659 	ha->rx_ring[ridx].lbq_addr_tbl_vaddr = v_addr;
1660 	ha->rx_ring[ridx].lbq_addr_tbl_paddr = p_addr;
1661 
1662 	/* large buffer queue */
1663 	ha->rx_ring[ridx].lbq_vaddr = v_addr + PAGE_SIZE;
1664 	ha->rx_ring[ridx].lbq_paddr = p_addr + PAGE_SIZE;
1665 
1666 	v_addr = ha->rx_ring[ridx].sbq_dma.dma_b;
1667 	p_addr = ha->rx_ring[ridx].sbq_dma.dma_addr;
1668 
1669 	/* small buffer queue address table */
1670 	ha->rx_ring[ridx].sbq_addr_tbl_vaddr = v_addr;
1671 	ha->rx_ring[ridx].sbq_addr_tbl_paddr = p_addr;
1672 
1673 	/* small buffer queue */
1674 	ha->rx_ring[ridx].sbq_vaddr = v_addr + PAGE_SIZE;
1675 	ha->rx_ring[ridx].sbq_paddr = p_addr + PAGE_SIZE;
1676 
1677 	ha->rx_ring[ridx].lb_vaddr = ha->rx_ring[ridx].lb_dma.dma_b;
1678 	ha->rx_ring[ridx].lb_paddr = ha->rx_ring[ridx].lb_dma.dma_addr;
1679 
1680 	/* Initialize Large Buffer Queue Table */
1681 
1682 	p_addr = ha->rx_ring[ridx].lbq_paddr;
1683 	bq_e = ha->rx_ring[ridx].lbq_addr_tbl_vaddr;
1684 
1685 	bq_e->addr_lo = p_addr & 0xFFFFFFFF;
1686 	bq_e->addr_hi = (p_addr >> 32) & 0xFFFFFFFF;
1687 
1688 	p_addr = ha->rx_ring[ridx].lb_paddr;
1689 	bq_e = ha->rx_ring[ridx].lbq_vaddr;
1690 
1691 	for (i = 0; i < QLA_NUM_LGB_ENTRIES; i++) {
1692 		bq_e->addr_lo = p_addr & 0xFFFFFFFF;
1693 		bq_e->addr_hi = (p_addr >> 32) & 0xFFFFFFFF;
1694 
1695 		p_addr = p_addr + QLA_LGB_SIZE;
1696 		bq_e++;
1697 	}
1698 
1699 	/* Initialize Small Buffer Queue Table */
1700 
1701 	p_addr = ha->rx_ring[ridx].sbq_paddr;
1702 	bq_e = ha->rx_ring[ridx].sbq_addr_tbl_vaddr;
1703 
1704 	for (i =0; i < (QLA_SBQ_SIZE/QLA_PAGE_SIZE); i++) {
1705 		bq_e->addr_lo = p_addr & 0xFFFFFFFF;
1706 		bq_e->addr_hi = (p_addr >> 32) & 0xFFFFFFFF;
1707 
1708 		p_addr = p_addr + QLA_PAGE_SIZE;
1709 		bq_e++;
1710 	}
1711 
1712 qls_alloc_rx_ring_dma_exit:
1713 	return (ret);
1714 }
1715 
1716 static int
1717 qls_alloc_rx_dma(qla_host_t *ha)
1718 {
1719 	int	i;
1720 	int	ret = 0;
1721 
1722         if (bus_dma_tag_create(NULL,    /* parent */
1723                         1, 0,    /* alignment, bounds */
1724                         BUS_SPACE_MAXADDR,       /* lowaddr */
1725                         BUS_SPACE_MAXADDR,       /* highaddr */
1726                         NULL, NULL,      /* filter, filterarg */
1727                         MJUM9BYTES,     /* maxsize */
1728                         1,        /* nsegments */
1729                         MJUM9BYTES,        /* maxsegsize */
1730                         BUS_DMA_ALLOCNOW,        /* flags */
1731                         NULL,    /* lockfunc */
1732                         NULL,    /* lockfuncarg */
1733                         &ha->rx_tag)) {
1734                 device_printf(ha->pci_dev, "%s: rx_tag alloc failed\n",
1735                         __func__);
1736 
1737                 return (ENOMEM);
1738         }
1739 
1740 	for (i = 0; i < ha->num_rx_rings; i++) {
1741 		ret = qls_alloc_rx_ring_dma(ha, i);
1742 
1743 		if (ret) {
1744 			qls_free_rx_dma(ha);
1745 			break;
1746 		}
1747 	}
1748 
1749 	return (ret);
1750 }
1751 
1752 static int
1753 qls_wait_for_flash_ready(qla_host_t *ha)
1754 {
1755 	uint32_t data32;
1756 	uint32_t count = 3;
1757 
1758 	while (count--) {
1759 		data32 = READ_REG32(ha, Q81_CTL_FLASH_ADDR);
1760 
1761 		if (data32 & Q81_CTL_FLASH_ADDR_ERR)
1762 			goto qls_wait_for_flash_ready_exit;
1763 
1764 		if (data32 & Q81_CTL_FLASH_ADDR_RDY)
1765 			return (0);
1766 
1767 		QLA_USEC_DELAY(100);
1768 	}
1769 
1770 qls_wait_for_flash_ready_exit:
1771 	QL_DPRINT1((ha->pci_dev, "%s: failed\n", __func__));
1772 
1773 	return (-1);
1774 }
1775 
1776 /*
1777  * Name: qls_rd_flash32
1778  * Function: Read Flash Memory
1779  */
1780 int
1781 qls_rd_flash32(qla_host_t *ha, uint32_t addr, uint32_t *data)
1782 {
1783 	int ret;
1784 
1785 	ret = qls_wait_for_flash_ready(ha);
1786 
1787 	if (ret)
1788 		return (ret);
1789 
1790 	WRITE_REG32(ha, Q81_CTL_FLASH_ADDR, (addr | Q81_CTL_FLASH_ADDR_R));
1791 
1792 	ret = qls_wait_for_flash_ready(ha);
1793 
1794 	if (ret)
1795 		return (ret);
1796 
1797 	*data = READ_REG32(ha, Q81_CTL_FLASH_DATA);
1798 
1799 	return 0;
1800 }
1801 
1802 static int
1803 qls_flash_validate(qla_host_t *ha, const char *signature)
1804 {
1805 	uint16_t csum16 = 0;
1806 	uint16_t *data16;
1807 	int i;
1808 
1809 	if (bcmp(ha->flash.id, signature, 4)) {
1810 		QL_DPRINT1((ha->pci_dev, "%s: invalid signature "
1811 			"%x:%x:%x:%x %s\n", __func__, ha->flash.id[0],
1812 			ha->flash.id[1], ha->flash.id[2], ha->flash.id[3],
1813 			signature));
1814 		return(-1);
1815 	}
1816 
1817 	data16 = (uint16_t *)&ha->flash;
1818 
1819 	for (i = 0; i < (sizeof (q81_flash_t) >> 1); i++) {
1820 		csum16 += *data16++;
1821 	}
1822 
1823 	if (csum16) {
1824 		QL_DPRINT1((ha->pci_dev, "%s: invalid checksum\n", __func__));
1825 		return(-1);
1826 	}
1827 	return(0);
1828 }
1829 
1830 int
1831 qls_rd_nic_params(qla_host_t *ha)
1832 {
1833 	int		i, ret = 0;
1834 	uint32_t	faddr;
1835 	uint32_t	*qflash;
1836 
1837 	if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_FLASH, Q81_CTL_SEM_SET_FLASH)) {
1838 		QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
1839 		return(-1);
1840 	}
1841 
1842 	if ((ha->pci_func & 0x1) == 0)
1843 		faddr = Q81_F0_FLASH_OFFSET >> 2;
1844 	else
1845 		faddr = Q81_F1_FLASH_OFFSET >> 2;
1846 
1847 	qflash = (uint32_t *)&ha->flash;
1848 
1849 	for (i = 0; i < (sizeof(q81_flash_t) >> 2) ; i++) {
1850 		ret = qls_rd_flash32(ha, faddr, qflash);
1851 
1852 		if (ret)
1853 			goto qls_rd_flash_data_exit;
1854 
1855 		faddr++;
1856 		qflash++;
1857 	}
1858 
1859 	QL_DUMP_BUFFER8(ha, __func__, (&ha->flash), (sizeof (q81_flash_t)));
1860 
1861 	ret = qls_flash_validate(ha, Q81_FLASH_ID);
1862 
1863 	if (ret)
1864 		goto qls_rd_flash_data_exit;
1865 
1866 	bcopy(ha->flash.mac_addr0, ha->mac_addr, ETHER_ADDR_LEN);
1867 
1868 	QL_DPRINT1((ha->pci_dev, "%s: mac %02x:%02x:%02x:%02x:%02x:%02x\n",
1869 		__func__, ha->mac_addr[0],  ha->mac_addr[1], ha->mac_addr[2],
1870 		ha->mac_addr[3], ha->mac_addr[4],  ha->mac_addr[5]));
1871 
1872 qls_rd_flash_data_exit:
1873 
1874 	qls_sem_unlock(ha, Q81_CTL_SEM_MASK_FLASH);
1875 
1876 	return(ret);
1877 }
1878 
1879 static int
1880 qls_sem_lock(qla_host_t *ha, uint32_t mask, uint32_t value)
1881 {
1882 	uint32_t count = 30;
1883 	uint32_t data;
1884 
1885 	while (count--) {
1886 		WRITE_REG32(ha, Q81_CTL_SEMAPHORE, (mask|value));
1887 
1888 		data = READ_REG32(ha, Q81_CTL_SEMAPHORE);
1889 
1890 		if (data & value) {
1891 			return (0);
1892 		} else {
1893 			QLA_USEC_DELAY(100);
1894 		}
1895 	}
1896 	ha->qla_initiate_recovery = 1;
1897 	return (-1);
1898 }
1899 
1900 static void
1901 qls_sem_unlock(qla_host_t *ha, uint32_t mask)
1902 {
1903 	WRITE_REG32(ha, Q81_CTL_SEMAPHORE, mask);
1904 }
1905 
1906 static int
1907 qls_wait_for_proc_addr_ready(qla_host_t *ha)
1908 {
1909 	uint32_t data32;
1910 	uint32_t count = 3;
1911 
1912 	while (count--) {
1913 		data32 = READ_REG32(ha, Q81_CTL_PROC_ADDR);
1914 
1915 		if (data32 & Q81_CTL_PROC_ADDR_ERR)
1916 			goto qls_wait_for_proc_addr_ready_exit;
1917 
1918 		if (data32 & Q81_CTL_PROC_ADDR_RDY)
1919 			return (0);
1920 
1921 		QLA_USEC_DELAY(100);
1922 	}
1923 
1924 qls_wait_for_proc_addr_ready_exit:
1925 	QL_DPRINT1((ha->pci_dev, "%s: failed\n", __func__));
1926 
1927 	ha->qla_initiate_recovery = 1;
1928 	return (-1);
1929 }
1930 
1931 static int
1932 qls_proc_addr_rd_reg(qla_host_t *ha, uint32_t addr_module, uint32_t reg,
1933 	uint32_t *data)
1934 {
1935 	int ret;
1936 	uint32_t value;
1937 
1938 	ret = qls_wait_for_proc_addr_ready(ha);
1939 
1940 	if (ret)
1941 		goto qls_proc_addr_rd_reg_exit;
1942 
1943 	value = addr_module | reg | Q81_CTL_PROC_ADDR_READ;
1944 
1945 	WRITE_REG32(ha, Q81_CTL_PROC_ADDR, value);
1946 
1947 	ret = qls_wait_for_proc_addr_ready(ha);
1948 
1949 	if (ret)
1950 		goto qls_proc_addr_rd_reg_exit;
1951 
1952 	*data = READ_REG32(ha, Q81_CTL_PROC_DATA);
1953 
1954 qls_proc_addr_rd_reg_exit:
1955 	return (ret);
1956 }
1957 
1958 static int
1959 qls_proc_addr_wr_reg(qla_host_t *ha, uint32_t addr_module, uint32_t reg,
1960 	uint32_t data)
1961 {
1962 	int ret;
1963 	uint32_t value;
1964 
1965 	ret = qls_wait_for_proc_addr_ready(ha);
1966 
1967 	if (ret)
1968 		goto qls_proc_addr_wr_reg_exit;
1969 
1970 	WRITE_REG32(ha, Q81_CTL_PROC_DATA, data);
1971 
1972 	value = addr_module | reg;
1973 
1974 	WRITE_REG32(ha, Q81_CTL_PROC_ADDR, value);
1975 
1976 	ret = qls_wait_for_proc_addr_ready(ha);
1977 
1978 qls_proc_addr_wr_reg_exit:
1979 	return (ret);
1980 }
1981 
1982 static int
1983 qls_hw_nic_reset(qla_host_t *ha)
1984 {
1985 	int		count;
1986 	uint32_t	data;
1987 	device_t	dev = ha->pci_dev;
1988 
1989 	ha->hw_init = 0;
1990 
1991 	data = (Q81_CTL_RESET_FUNC << Q81_CTL_RESET_MASK_SHIFT) |
1992 			Q81_CTL_RESET_FUNC;
1993 	WRITE_REG32(ha, Q81_CTL_RESET, data);
1994 
1995 	count = 10;
1996 	while (count--) {
1997 		data = READ_REG32(ha, Q81_CTL_RESET);
1998 		if ((data & Q81_CTL_RESET_FUNC) == 0)
1999 			break;
2000 		QLA_USEC_DELAY(10);
2001 	}
2002 	if (count == 0) {
2003 		device_printf(dev, "%s: Bit 15 not cleared after Reset\n",
2004 			__func__);
2005 		return (-1);
2006 	}
2007 	return (0);
2008 }
2009 
2010 static int
2011 qls_hw_reset(qla_host_t *ha)
2012 {
2013 	device_t	dev = ha->pci_dev;
2014 	int		ret;
2015 	int		count;
2016 	uint32_t	data;
2017 
2018 	QL_DPRINT2((ha->pci_dev, "%s:enter[%d]\n", __func__, ha->hw_init));
2019 
2020 	if (ha->hw_init == 0) {
2021 		ret = qls_hw_nic_reset(ha);
2022 		goto qls_hw_reset_exit;
2023 	}
2024 
2025 	ret = qls_clear_routing_table(ha);
2026 	if (ret)
2027 		goto qls_hw_reset_exit;
2028 
2029 	ret = qls_mbx_set_mgmt_ctrl(ha, Q81_MBX_SET_MGMT_CTL_STOP);
2030 	if (ret)
2031 		goto qls_hw_reset_exit;
2032 
2033 	/*
2034 	 * Wait for FIFO to empty
2035 	 */
2036 	count = 5;
2037 	while (count--) {
2038 		data = READ_REG32(ha, Q81_CTL_STATUS);
2039 		if (data & Q81_CTL_STATUS_NFE)
2040 			break;
2041 		qls_mdelay(__func__, 100);
2042 	}
2043 	if (count == 0) {
2044 		device_printf(dev, "%s: NFE bit not set\n", __func__);
2045 		goto qls_hw_reset_exit;
2046 	}
2047 
2048 	count = 5;
2049 	while (count--) {
2050 		(void)qls_mbx_get_mgmt_ctrl(ha, &data);
2051 
2052 		if ((data & Q81_MBX_GET_MGMT_CTL_FIFO_EMPTY) &&
2053 			(data & Q81_MBX_GET_MGMT_CTL_SET_MGMT))
2054 			break;
2055 		qls_mdelay(__func__, 100);
2056 	}
2057 	if (count == 0)
2058 		goto qls_hw_reset_exit;
2059 
2060 	/*
2061 	 * Reset the NIC function
2062 	 */
2063 	ret = qls_hw_nic_reset(ha);
2064 	if (ret)
2065 		goto qls_hw_reset_exit;
2066 
2067 	ret = qls_mbx_set_mgmt_ctrl(ha, Q81_MBX_SET_MGMT_CTL_RESUME);
2068 
2069 qls_hw_reset_exit:
2070 	if (ret)
2071 		device_printf(dev, "%s: failed\n", __func__);
2072 
2073 	return (ret);
2074 }
2075 
2076 /*
2077  * MPI Related Functions
2078  */
2079 int
2080 qls_mpi_risc_rd_reg(qla_host_t *ha, uint32_t reg, uint32_t *data)
2081 {
2082 	int ret;
2083 
2084 	ret = qls_proc_addr_rd_reg(ha, Q81_CTL_PROC_ADDR_MPI_RISC,
2085 			reg, data);
2086 	return (ret);
2087 }
2088 
2089 int
2090 qls_mpi_risc_wr_reg(qla_host_t *ha, uint32_t reg, uint32_t data)
2091 {
2092 	int ret;
2093 
2094 	ret = qls_proc_addr_wr_reg(ha, Q81_CTL_PROC_ADDR_MPI_RISC,
2095 			reg, data);
2096 	return (ret);
2097 }
2098 
2099 int
2100 qls_mbx_rd_reg(qla_host_t *ha, uint32_t reg, uint32_t *data)
2101 {
2102 	int ret;
2103 
2104 	if ((ha->pci_func & 0x1) == 0)
2105 		reg += Q81_FUNC0_MBX_OUT_REG0;
2106 	else
2107 		reg += Q81_FUNC1_MBX_OUT_REG0;
2108 
2109 	ret = qls_mpi_risc_rd_reg(ha, reg, data);
2110 
2111 	return (ret);
2112 }
2113 
2114 int
2115 qls_mbx_wr_reg(qla_host_t *ha, uint32_t reg, uint32_t data)
2116 {
2117 	int ret;
2118 
2119 	if ((ha->pci_func & 0x1) == 0)
2120 		reg += Q81_FUNC0_MBX_IN_REG0;
2121 	else
2122 		reg += Q81_FUNC1_MBX_IN_REG0;
2123 
2124 	ret = qls_mpi_risc_wr_reg(ha, reg, data);
2125 
2126 	return (ret);
2127 }
2128 
2129 static int
2130 qls_mbx_cmd(qla_host_t *ha, uint32_t *in_mbx, uint32_t i_count,
2131 	uint32_t *out_mbx, uint32_t o_count)
2132 {
2133 	int i, ret = -1;
2134 	uint32_t data32;
2135 	uint32_t count = 50;
2136 
2137 	QL_DPRINT2((ha->pci_dev, "%s: enter[0x%08x 0x%08x 0x%08x]\n",
2138 		__func__, *in_mbx, *(in_mbx + 1), *(in_mbx + 2)));
2139 
2140 	data32 = READ_REG32(ha, Q81_CTL_HOST_CMD_STATUS);
2141 
2142 	if (data32 & Q81_CTL_HCS_HTR_INTR) {
2143 		device_printf(ha->pci_dev, "%s: cmd_status[0x%08x]\n",
2144 			__func__, data32);
2145 		goto qls_mbx_cmd_exit;
2146 	}
2147 
2148 	if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_PROC_ADDR_NIC_RCV,
2149 		Q81_CTL_SEM_SET_PROC_ADDR_NIC_RCV)) {
2150 		device_printf(ha->pci_dev, "%s: semlock failed\n", __func__);
2151 		goto qls_mbx_cmd_exit;
2152 	}
2153 
2154 	ha->mbx_done = 0;
2155 
2156 	for (i = 0; i < i_count; i++) {
2157 		ret = qls_mbx_wr_reg(ha, i, *in_mbx);
2158 
2159 		if (ret) {
2160 			device_printf(ha->pci_dev,
2161 				"%s: mbx_wr[%d, 0x%08x] failed\n", __func__,
2162 				i, *in_mbx);
2163 			qls_sem_unlock(ha, Q81_CTL_SEM_MASK_PROC_ADDR_NIC_RCV);
2164 			goto qls_mbx_cmd_exit;
2165 		}
2166 
2167 		in_mbx++;
2168 	}
2169 	WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS, Q81_CTL_HCS_CMD_SET_HTR_INTR);
2170 
2171 	qls_sem_unlock(ha, Q81_CTL_SEM_MASK_PROC_ADDR_NIC_RCV);
2172 
2173 	ret = -1;
2174 	ha->mbx_done = 0;
2175 
2176 	while (count--) {
2177 		if (ha->flags.intr_enable == 0) {
2178 			data32 = READ_REG32(ha, Q81_CTL_STATUS);
2179 
2180 			if (!(data32 & Q81_CTL_STATUS_PI)) {
2181 				qls_mdelay(__func__, 100);
2182 				continue;
2183 			}
2184 
2185 			ret = qls_mbx_rd_reg(ha, 0, &data32);
2186 
2187 			if (ret == 0 ) {
2188 				if ((data32 & 0xF000) == 0x4000) {
2189 					out_mbx[0] = data32;
2190 
2191 					for (i = 1; i < o_count; i++) {
2192 						ret = qls_mbx_rd_reg(ha, i,
2193 								&data32);
2194 						if (ret) {
2195 							device_printf(
2196 								ha->pci_dev,
2197 								"%s: mbx_rd[%d]"
2198 								" failed\n",
2199 								__func__, i);
2200 							break;
2201 						}
2202 						out_mbx[i] = data32;
2203 					}
2204 					break;
2205 				} else if ((data32 & 0xF000) == 0x8000) {
2206 					count = 50;
2207 					WRITE_REG32(ha,\
2208 						Q81_CTL_HOST_CMD_STATUS,\
2209 						Q81_CTL_HCS_CMD_CLR_RTH_INTR);
2210 				}
2211 			}
2212 		} else {
2213 			if (ha->mbx_done) {
2214 				for (i = 1; i < o_count; i++) {
2215 					out_mbx[i] = ha->mbox[i];
2216 				}
2217 				ret = 0;
2218 				break;
2219 			}
2220 		}
2221 		qls_mdelay(__func__, 1000);
2222 	}
2223 
2224 qls_mbx_cmd_exit:
2225 
2226 	if (ha->flags.intr_enable == 0) {
2227 		WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS,\
2228 			Q81_CTL_HCS_CMD_CLR_RTH_INTR);
2229 	}
2230 
2231 	if (ret) {
2232 		ha->qla_initiate_recovery = 1;
2233 	}
2234 
2235 	QL_DPRINT2((ha->pci_dev, "%s: exit[%d]\n", __func__, ret));
2236 	return (ret);
2237 }
2238 
2239 static int
2240 qls_mbx_set_mgmt_ctrl(qla_host_t *ha, uint32_t t_ctrl)
2241 {
2242 	uint32_t *mbox;
2243 	device_t dev = ha->pci_dev;
2244 
2245 	mbox = ha->mbox;
2246 	bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS));
2247 
2248 	mbox[0] = Q81_MBX_SET_MGMT_CTL;
2249 	mbox[1] = t_ctrl;
2250 
2251 	if (qls_mbx_cmd(ha, mbox, 2, mbox, 1)) {
2252 		device_printf(dev, "%s failed\n", __func__);
2253 		return (-1);
2254 	}
2255 
2256 	if ((mbox[0] == Q81_MBX_CMD_COMPLETE) ||
2257 		((t_ctrl == Q81_MBX_SET_MGMT_CTL_STOP) &&
2258 			(mbox[0] == Q81_MBX_CMD_ERROR))){
2259 		return (0);
2260 	}
2261 	device_printf(dev, "%s failed [0x%08x]\n", __func__, mbox[0]);
2262 	return (-1);
2263 
2264 }
2265 
2266 static int
2267 qls_mbx_get_mgmt_ctrl(qla_host_t *ha, uint32_t *t_status)
2268 {
2269 	uint32_t *mbox;
2270 	device_t dev = ha->pci_dev;
2271 
2272 	*t_status = 0;
2273 
2274 	mbox = ha->mbox;
2275 	bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS));
2276 
2277 	mbox[0] = Q81_MBX_GET_MGMT_CTL;
2278 
2279 	if (qls_mbx_cmd(ha, mbox, 1, mbox, 2)) {
2280 		device_printf(dev, "%s failed\n", __func__);
2281 		return (-1);
2282 	}
2283 
2284 	*t_status = mbox[1];
2285 
2286 	return (0);
2287 }
2288 
2289 static void
2290 qls_mbx_get_link_status(qla_host_t *ha)
2291 {
2292 	uint32_t *mbox;
2293 	device_t dev = ha->pci_dev;
2294 
2295 	mbox = ha->mbox;
2296 	bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS));
2297 
2298 	mbox[0] = Q81_MBX_GET_LNK_STATUS;
2299 
2300 	if (qls_mbx_cmd(ha, mbox, 1, mbox, 6)) {
2301 		device_printf(dev, "%s failed\n", __func__);
2302 		return;
2303 	}
2304 
2305 	ha->link_status			= mbox[1];
2306 	ha->link_down_info		= mbox[2];
2307 	ha->link_hw_info		= mbox[3];
2308 	ha->link_dcbx_counters		= mbox[4];
2309 	ha->link_change_counters	= mbox[5];
2310 
2311 	device_printf(dev, "%s 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
2312 		__func__, mbox[0],mbox[1],mbox[2],mbox[3],mbox[4],mbox[5]);
2313 
2314 	return;
2315 }
2316 
2317 static void
2318 qls_mbx_about_fw(qla_host_t *ha)
2319 {
2320 	uint32_t *mbox;
2321 	device_t dev = ha->pci_dev;
2322 
2323 	mbox = ha->mbox;
2324 	bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS));
2325 
2326 	mbox[0] = Q81_MBX_ABOUT_FW;
2327 
2328 	if (qls_mbx_cmd(ha, mbox, 1, mbox, 6)) {
2329 		device_printf(dev, "%s failed\n", __func__);
2330 		return;
2331 	}
2332 
2333 	device_printf(dev, "%s 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
2334 		__func__, mbox[0],mbox[1],mbox[2],mbox[3],mbox[4],mbox[5]);
2335 }
2336 
2337 int
2338 qls_mbx_dump_risc_ram(qla_host_t *ha, void *buf, uint32_t r_addr,
2339 	uint32_t r_size)
2340 {
2341 	bus_addr_t b_paddr;
2342 	uint32_t *mbox;
2343 	device_t dev = ha->pci_dev;
2344 
2345 	mbox = ha->mbox;
2346 	bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS));
2347 
2348 	bzero(ha->mpi_dma.dma_b,(r_size << 2));
2349 	b_paddr = ha->mpi_dma.dma_addr;
2350 
2351 	mbox[0] = Q81_MBX_DUMP_RISC_RAM;
2352 	mbox[1] = r_addr & 0xFFFF;
2353 	mbox[2] = ((uint32_t)(b_paddr >> 16)) & 0xFFFF;
2354 	mbox[3] = ((uint32_t)b_paddr) & 0xFFFF;
2355 	mbox[4] = (r_size >> 16) & 0xFFFF;
2356 	mbox[5] = r_size & 0xFFFF;
2357 	mbox[6] = ((uint32_t)(b_paddr >> 48)) & 0xFFFF;
2358 	mbox[7] = ((uint32_t)(b_paddr >> 32)) & 0xFFFF;
2359 	mbox[8] = (r_addr >> 16) & 0xFFFF;
2360 
2361 	bus_dmamap_sync(ha->mpi_dma.dma_tag, ha->mpi_dma.dma_map,
2362 		BUS_DMASYNC_PREREAD);
2363 
2364 	if (qls_mbx_cmd(ha, mbox, 9, mbox, 1)) {
2365 		device_printf(dev, "%s failed\n", __func__);
2366 		return (-1);
2367 	}
2368         if (mbox[0] != 0x4000) {
2369                 device_printf(ha->pci_dev, "%s: failed!\n", __func__);
2370 		return (-1);
2371         } else {
2372                 bus_dmamap_sync(ha->mpi_dma.dma_tag, ha->mpi_dma.dma_map,
2373                         BUS_DMASYNC_POSTREAD);
2374                 bcopy(ha->mpi_dma.dma_b, buf, (r_size << 2));
2375         }
2376 
2377 	return (0);
2378 }
2379 
2380 int
2381 qls_mpi_reset(qla_host_t *ha)
2382 {
2383 	int		count;
2384 	uint32_t	data;
2385 	device_t	dev = ha->pci_dev;
2386 
2387 	WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS,\
2388 		Q81_CTL_HCS_CMD_SET_RISC_RESET);
2389 
2390 	count = 10;
2391 	while (count--) {
2392 		data = READ_REG32(ha, Q81_CTL_HOST_CMD_STATUS);
2393 		if (data & Q81_CTL_HCS_RISC_RESET) {
2394 			WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS,\
2395 				Q81_CTL_HCS_CMD_CLR_RISC_RESET);
2396 			break;
2397 		}
2398 		qls_mdelay(__func__, 10);
2399 	}
2400 	if (count == 0) {
2401 		device_printf(dev, "%s: failed\n", __func__);
2402 		return (-1);
2403 	}
2404 	return (0);
2405 }
2406