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