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