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