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