xref: /freebsd/sys/dev/qlxgb/qla_hw.c (revision 716fd348)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2011-2012 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: qla_hw.c
32  * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
33  * Content: Contains Hardware dependent functions
34  */
35 
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
38 
39 #include "qla_os.h"
40 #include "qla_reg.h"
41 #include "qla_hw.h"
42 #include "qla_def.h"
43 #include "qla_inline.h"
44 #include "qla_ver.h"
45 #include "qla_glbl.h"
46 #include "qla_dbg.h"
47 
48 static uint32_t sysctl_num_rds_rings = 2;
49 static uint32_t sysctl_num_sds_rings = 4;
50 
51 /*
52  * Static Functions
53  */
54 
55 static void qla_init_cntxt_regions(qla_host_t *ha);
56 static int qla_issue_cmd(qla_host_t *ha, qla_cdrp_t *cdrp);
57 static int qla_fw_cmd(qla_host_t *ha, void *fw_cmd, uint32_t size);
58 static int qla_config_mac_addr(qla_host_t *ha, uint8_t *mac_addr,
59 		uint16_t cntxt_id, uint32_t add_multi);
60 static void qla_del_rcv_cntxt(qla_host_t *ha);
61 static int qla_init_rcv_cntxt(qla_host_t *ha);
62 static void qla_del_xmt_cntxt(qla_host_t *ha);
63 static int qla_init_xmt_cntxt(qla_host_t *ha);
64 static int qla_get_max_rds(qla_host_t *ha);
65 static int qla_get_max_sds(qla_host_t *ha);
66 static int qla_get_max_rules(qla_host_t *ha);
67 static int qla_get_max_rcv_cntxts(qla_host_t *ha);
68 static int qla_get_max_tx_cntxts(qla_host_t *ha);
69 static int qla_get_max_mtu(qla_host_t *ha);
70 static int qla_get_max_lro(qla_host_t *ha);
71 static int qla_get_flow_control(qla_host_t *ha);
72 static void qla_hw_tx_done_locked(qla_host_t *ha);
73 
74 int
75 qla_get_msix_count(qla_host_t *ha)
76 {
77 	return (sysctl_num_sds_rings);
78 }
79 
80 /*
81  * Name: qla_hw_add_sysctls
82  * Function: Add P3Plus specific sysctls
83  */
84 void
85 qla_hw_add_sysctls(qla_host_t *ha)
86 {
87         device_t	dev;
88 
89         dev = ha->pci_dev;
90 
91         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
92                 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
93                 OID_AUTO, "num_rds_rings", CTLFLAG_RD, &sysctl_num_rds_rings,
94 		sysctl_num_rds_rings, "Number of Rcv Descriptor Rings");
95 
96         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
97                 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
98                 OID_AUTO, "num_sds_rings", CTLFLAG_RD, &sysctl_num_sds_rings,
99 		sysctl_num_sds_rings, "Number of Status Descriptor Rings");
100 }
101 
102 /*
103  * Name: qla_free_dma
104  * Function: Frees the DMA'able memory allocated in qla_alloc_dma()
105  */
106 void
107 qla_free_dma(qla_host_t *ha)
108 {
109 	uint32_t i;
110 
111         if (ha->hw.dma_buf.flags.context) {
112 		qla_free_dmabuf(ha, &ha->hw.dma_buf.context);
113         	ha->hw.dma_buf.flags.context = 0;
114 	}
115 
116         if (ha->hw.dma_buf.flags.sds_ring) {
117 		for (i = 0; i < ha->hw.num_sds_rings; i++)
118 			qla_free_dmabuf(ha, &ha->hw.dma_buf.sds_ring[i]);
119         	ha->hw.dma_buf.flags.sds_ring = 0;
120 	}
121 
122         if (ha->hw.dma_buf.flags.rds_ring) {
123 		for (i = 0; i < ha->hw.num_rds_rings; i++)
124 			qla_free_dmabuf(ha, &ha->hw.dma_buf.rds_ring[i]);
125         	ha->hw.dma_buf.flags.rds_ring = 0;
126 	}
127 
128         if (ha->hw.dma_buf.flags.tx_ring) {
129 		qla_free_dmabuf(ha, &ha->hw.dma_buf.tx_ring);
130         	ha->hw.dma_buf.flags.tx_ring = 0;
131 	}
132 }
133 
134 /*
135  * Name: qla_alloc_dma
136  * Function: Allocates DMA'able memory for Tx/Rx Rings, Tx/Rx Contexts.
137  */
138 int
139 qla_alloc_dma(qla_host_t *ha)
140 {
141         device_t                dev;
142 	uint32_t		i, j, size;
143 
144         dev = ha->pci_dev;
145 
146         QL_DPRINT2((dev, "%s: enter\n", __func__));
147 
148 	ha->hw.num_rds_rings = (uint16_t)sysctl_num_rds_rings;
149 	ha->hw.num_sds_rings = (uint16_t)sysctl_num_sds_rings;
150 
151 	/*
152 	 * Allocate Transmit Ring
153 	 */
154 
155 	ha->hw.dma_buf.tx_ring.alignment = 8;
156 	ha->hw.dma_buf.tx_ring.size =
157 		(sizeof(q80_tx_cmd_t)) * NUM_TX_DESCRIPTORS;
158 
159         if (qla_alloc_dmabuf(ha, &ha->hw.dma_buf.tx_ring)) {
160                 device_printf(dev, "%s: tx ring alloc failed\n", __func__);
161                 goto qla_alloc_dma_exit;
162         }
163         ha->hw.dma_buf.flags.tx_ring = 1;
164 
165 	QL_DPRINT2((dev, "%s: tx_ring phys %p virt %p\n",
166 		__func__, (void *)(ha->hw.dma_buf.tx_ring.dma_addr),
167 		ha->hw.dma_buf.tx_ring.dma_b));
168 	/*
169 	 * Allocate Receive Descriptor Rings
170 	 */
171 
172 	for (i = 0; i < ha->hw.num_rds_rings; i++) {
173 		ha->hw.dma_buf.rds_ring[i].alignment = 8;
174 
175 		if (i == RDS_RING_INDEX_NORMAL) {
176 			ha->hw.dma_buf.rds_ring[i].size =
177 				(sizeof(q80_recv_desc_t)) * NUM_RX_DESCRIPTORS;
178 		} else if (i == RDS_RING_INDEX_JUMBO) {
179 			ha->hw.dma_buf.rds_ring[i].size =
180 				(sizeof(q80_recv_desc_t)) *
181 					NUM_RX_JUMBO_DESCRIPTORS;
182 		} else
183 			break;
184 
185 		if (qla_alloc_dmabuf(ha, &ha->hw.dma_buf.rds_ring[i])) {
186 			QL_DPRINT4((dev, "%s: rds ring alloc failed\n",
187 				__func__));
188 
189 			for (j = 0; j < i; j++)
190 				qla_free_dmabuf(ha,
191 					&ha->hw.dma_buf.rds_ring[j]);
192 
193 			goto qla_alloc_dma_exit;
194 		}
195 		QL_DPRINT4((dev, "%s: rx_ring[%d] phys %p virt %p\n",
196 			__func__, i,
197 			(void *)(ha->hw.dma_buf.rds_ring[i].dma_addr),
198 			ha->hw.dma_buf.rds_ring[i].dma_b));
199 	}
200 	ha->hw.dma_buf.flags.rds_ring = 1;
201 
202 	/*
203 	 * Allocate Status Descriptor Rings
204 	 */
205 
206 	for (i = 0; i < ha->hw.num_sds_rings; i++) {
207 		ha->hw.dma_buf.sds_ring[i].alignment = 8;
208 		ha->hw.dma_buf.sds_ring[i].size =
209 			(sizeof(q80_stat_desc_t)) * NUM_STATUS_DESCRIPTORS;
210 
211 		if (qla_alloc_dmabuf(ha, &ha->hw.dma_buf.sds_ring[i])) {
212 			device_printf(dev, "%s: sds ring alloc failed\n",
213 				__func__);
214 
215 			for (j = 0; j < i; j++)
216 				qla_free_dmabuf(ha,
217 					&ha->hw.dma_buf.sds_ring[j]);
218 
219 			goto qla_alloc_dma_exit;
220 		}
221 		QL_DPRINT4((dev, "%s: sds_ring[%d] phys %p virt %p\n",
222 			__func__, i,
223 			(void *)(ha->hw.dma_buf.sds_ring[i].dma_addr),
224 			ha->hw.dma_buf.sds_ring[i].dma_b));
225 	}
226 	ha->hw.dma_buf.flags.sds_ring = 1;
227 
228 	/*
229 	 * Allocate Context Area
230 	 */
231 	size = QL_ALIGN((sizeof (q80_tx_cntxt_req_t)), QL_BUFFER_ALIGN);
232 
233 	size += QL_ALIGN((sizeof (q80_tx_cntxt_rsp_t)), QL_BUFFER_ALIGN);
234 
235 	size += QL_ALIGN((sizeof (q80_rcv_cntxt_req_t)), QL_BUFFER_ALIGN);
236 
237 	size += QL_ALIGN((sizeof (q80_rcv_cntxt_rsp_t)), QL_BUFFER_ALIGN);
238 
239 	size += sizeof (uint32_t); /* for tx consumer index */
240 
241 	size = QL_ALIGN(size, PAGE_SIZE);
242 
243 	ha->hw.dma_buf.context.alignment = 8;
244 	ha->hw.dma_buf.context.size = size;
245 
246         if (qla_alloc_dmabuf(ha, &ha->hw.dma_buf.context)) {
247                 device_printf(dev, "%s: context alloc failed\n", __func__);
248                 goto qla_alloc_dma_exit;
249         }
250         ha->hw.dma_buf.flags.context = 1;
251 	QL_DPRINT2((dev, "%s: context phys %p virt %p\n",
252 		__func__, (void *)(ha->hw.dma_buf.context.dma_addr),
253 		ha->hw.dma_buf.context.dma_b));
254 
255 	qla_init_cntxt_regions(ha);
256 
257 	return 0;
258 
259 qla_alloc_dma_exit:
260 	qla_free_dma(ha);
261 	return -1;
262 }
263 
264 /*
265  * Name: qla_init_cntxt_regions
266  * Function: Initializes Tx/Rx Contexts.
267  */
268 static void
269 qla_init_cntxt_regions(qla_host_t *ha)
270 {
271 	qla_hw_t		*hw;
272 	q80_tx_cntxt_req_t	*tx_cntxt_req;
273 	q80_rcv_cntxt_req_t	*rx_cntxt_req;
274 	bus_addr_t		phys_addr;
275 	uint32_t		i;
276 	uint32_t		size;
277 
278 	hw = &ha->hw;
279 
280 	hw->tx_ring_base = hw->dma_buf.tx_ring.dma_b;
281 
282 	for (i = 0; i < ha->hw.num_sds_rings; i++)
283 		hw->sds[i].sds_ring_base =
284 			(q80_stat_desc_t *)hw->dma_buf.sds_ring[i].dma_b;
285 
286 	phys_addr = hw->dma_buf.context.dma_addr;
287 
288 	memset((void *)hw->dma_buf.context.dma_b, 0,
289 		ha->hw.dma_buf.context.size);
290 
291 	hw->tx_cntxt_req	=
292 		(q80_tx_cntxt_req_t *)hw->dma_buf.context.dma_b;
293 	hw->tx_cntxt_req_paddr	= phys_addr;
294 
295 	size = QL_ALIGN((sizeof (q80_tx_cntxt_req_t)), QL_BUFFER_ALIGN);
296 
297 	hw->tx_cntxt_rsp	=
298 		(q80_tx_cntxt_rsp_t *)((uint8_t *)hw->tx_cntxt_req + size);
299 	hw->tx_cntxt_rsp_paddr	= hw->tx_cntxt_req_paddr + size;
300 
301 	size = QL_ALIGN((sizeof (q80_tx_cntxt_rsp_t)), QL_BUFFER_ALIGN);
302 
303 	hw->rx_cntxt_req =
304 		(q80_rcv_cntxt_req_t *)((uint8_t *)hw->tx_cntxt_rsp + size);
305 	hw->rx_cntxt_req_paddr = hw->tx_cntxt_rsp_paddr + size;
306 
307 	size = QL_ALIGN((sizeof (q80_rcv_cntxt_req_t)), QL_BUFFER_ALIGN);
308 
309 	hw->rx_cntxt_rsp =
310 		(q80_rcv_cntxt_rsp_t *)((uint8_t *)hw->rx_cntxt_req + size);
311 	hw->rx_cntxt_rsp_paddr = hw->rx_cntxt_req_paddr + size;
312 
313 	size = QL_ALIGN((sizeof (q80_rcv_cntxt_rsp_t)), QL_BUFFER_ALIGN);
314 
315 	hw->tx_cons = (uint32_t *)((uint8_t *)hw->rx_cntxt_rsp + size);
316 	hw->tx_cons_paddr = hw->rx_cntxt_rsp_paddr + size;
317 
318 	/*
319 	 * Initialize the Transmit Context Request so that we don't need to
320 	 * do it every time we need to create a context
321 	 */
322 	tx_cntxt_req = hw->tx_cntxt_req;
323 
324 	tx_cntxt_req->rsp_dma_addr = qla_host_to_le64(hw->tx_cntxt_rsp_paddr);
325 
326 	tx_cntxt_req->cmd_cons_dma_addr = qla_host_to_le64(hw->tx_cons_paddr);
327 
328 	tx_cntxt_req->caps[0] = qla_host_to_le32((CNTXT_CAP0_BASEFW |
329 					CNTXT_CAP0_LEGACY_MN | CNTXT_CAP0_LSO));
330 
331 	tx_cntxt_req->intr_mode = qla_host_to_le32(CNTXT_INTR_MODE_SHARED);
332 
333 	tx_cntxt_req->phys_addr =
334 		qla_host_to_le64(hw->dma_buf.tx_ring.dma_addr);
335 
336 	tx_cntxt_req->num_entries = qla_host_to_le32(NUM_TX_DESCRIPTORS);
337 
338 	/*
339 	 * Initialize the Receive Context Request
340 	 */
341 
342 	rx_cntxt_req = hw->rx_cntxt_req;
343 
344 	rx_cntxt_req->rx_req.rsp_dma_addr =
345 		qla_host_to_le64(hw->rx_cntxt_rsp_paddr);
346 
347 	rx_cntxt_req->rx_req.caps[0] = qla_host_to_le32(CNTXT_CAP0_BASEFW |
348 						CNTXT_CAP0_LEGACY_MN |
349 						CNTXT_CAP0_JUMBO |
350 						CNTXT_CAP0_LRO|
351 						CNTXT_CAP0_HW_LRO);
352 
353 	rx_cntxt_req->rx_req.intr_mode =
354 		qla_host_to_le32(CNTXT_INTR_MODE_SHARED);
355 
356 	rx_cntxt_req->rx_req.rds_intr_mode =
357 		qla_host_to_le32(CNTXT_INTR_MODE_UNIQUE);
358 
359 	rx_cntxt_req->rx_req.rds_ring_offset = 0;
360 	rx_cntxt_req->rx_req.sds_ring_offset = qla_host_to_le32(
361 		(hw->num_rds_rings * sizeof(q80_rq_rds_ring_t)));
362 	rx_cntxt_req->rx_req.num_rds_rings =
363 		qla_host_to_le16(hw->num_rds_rings);
364 	rx_cntxt_req->rx_req.num_sds_rings =
365 		qla_host_to_le16(hw->num_sds_rings);
366 
367 	for (i = 0; i < hw->num_rds_rings; i++) {
368 		rx_cntxt_req->rds_req[i].phys_addr =
369 			qla_host_to_le64(hw->dma_buf.rds_ring[i].dma_addr);
370 
371 		if (i == RDS_RING_INDEX_NORMAL) {
372 			rx_cntxt_req->rds_req[i].buf_size =
373 				qla_host_to_le64(MCLBYTES);
374 			rx_cntxt_req->rds_req[i].size =
375 				qla_host_to_le32(NUM_RX_DESCRIPTORS);
376 		} else {
377 			rx_cntxt_req->rds_req[i].buf_size =
378 				qla_host_to_le64(MJUM9BYTES);
379 			rx_cntxt_req->rds_req[i].size =
380 				qla_host_to_le32(NUM_RX_JUMBO_DESCRIPTORS);
381 		}
382 	}
383 
384 	for (i = 0; i < hw->num_sds_rings; i++) {
385 		rx_cntxt_req->sds_req[i].phys_addr =
386 			qla_host_to_le64(hw->dma_buf.sds_ring[i].dma_addr);
387 		rx_cntxt_req->sds_req[i].size =
388 			qla_host_to_le32(NUM_STATUS_DESCRIPTORS);
389 		rx_cntxt_req->sds_req[i].msi_index = qla_host_to_le16(i);
390 	}
391 
392 	QL_DPRINT2((ha->pci_dev, "%s: tx_cntxt_req = %p paddr %p\n",
393 		__func__, hw->tx_cntxt_req, (void *)hw->tx_cntxt_req_paddr));
394 	QL_DPRINT2((ha->pci_dev, "%s: tx_cntxt_rsp = %p paddr %p\n",
395 		__func__, hw->tx_cntxt_rsp, (void *)hw->tx_cntxt_rsp_paddr));
396 	QL_DPRINT2((ha->pci_dev, "%s: rx_cntxt_req = %p paddr %p\n",
397 		__func__, hw->rx_cntxt_req, (void *)hw->rx_cntxt_req_paddr));
398 	QL_DPRINT2((ha->pci_dev, "%s: rx_cntxt_rsp = %p paddr %p\n",
399 		__func__, hw->rx_cntxt_rsp, (void *)hw->rx_cntxt_rsp_paddr));
400 	QL_DPRINT2((ha->pci_dev, "%s: tx_cons      = %p paddr %p\n",
401 		__func__, hw->tx_cons, (void *)hw->tx_cons_paddr));
402 }
403 
404 /*
405  * Name: qla_issue_cmd
406  * Function: Issues commands on the CDRP interface and returns responses.
407  */
408 static int
409 qla_issue_cmd(qla_host_t *ha, qla_cdrp_t *cdrp)
410 {
411 	int	ret = 0;
412 	uint32_t signature;
413 	uint32_t count = 400; /* 4 seconds or 400 10ms intervals */
414 	uint32_t data;
415 	device_t dev;
416 
417 	dev = ha->pci_dev;
418 
419 	signature = 0xcafe0000 | 0x0100 | ha->pci_func;
420 
421 	ret = qla_sem_lock(ha, Q8_SEM5_LOCK, 0, (uint32_t)ha->pci_func);
422 
423 	if (ret) {
424 		device_printf(dev, "%s: SEM5_LOCK lock failed\n", __func__);
425 		return (ret);
426 	}
427 
428 	WRITE_OFFSET32(ha, Q8_NX_CDRP_SIGNATURE, signature);
429 
430 	WRITE_OFFSET32(ha, Q8_NX_CDRP_ARG1, (cdrp->cmd_arg1));
431 	WRITE_OFFSET32(ha, Q8_NX_CDRP_ARG2, (cdrp->cmd_arg2));
432 	WRITE_OFFSET32(ha, Q8_NX_CDRP_ARG3, (cdrp->cmd_arg3));
433 
434 	WRITE_OFFSET32(ha, Q8_NX_CDRP_CMD_RSP, cdrp->cmd);
435 
436 	while (count) {
437 		qla_mdelay(__func__, 10);
438 
439 		data = READ_REG32(ha, Q8_NX_CDRP_CMD_RSP);
440 
441 		if ((!(data & 0x80000000)))
442 			break;
443 		count--;
444 	}
445 	if ((!count) || (data != 1))
446 		ret = -1;
447 
448 	cdrp->rsp = READ_REG32(ha, Q8_NX_CDRP_CMD_RSP);
449 	cdrp->rsp_arg1 = READ_REG32(ha, Q8_NX_CDRP_ARG1);
450 	cdrp->rsp_arg2 = READ_REG32(ha, Q8_NX_CDRP_ARG2);
451 	cdrp->rsp_arg3 = READ_REG32(ha, Q8_NX_CDRP_ARG3);
452 
453 	qla_sem_unlock(ha, Q8_SEM5_UNLOCK);
454 
455 	if (ret) {
456 		device_printf(dev, "%s: "
457 			"cmd[0x%08x] = 0x%08x\n"
458 			"\tsig[0x%08x] = 0x%08x\n"
459 			"\targ1[0x%08x] = 0x%08x\n"
460 			"\targ2[0x%08x] = 0x%08x\n"
461 			"\targ3[0x%08x] = 0x%08x\n",
462 			__func__, Q8_NX_CDRP_CMD_RSP, cdrp->cmd,
463 			Q8_NX_CDRP_SIGNATURE, signature,
464 			Q8_NX_CDRP_ARG1, cdrp->cmd_arg1,
465 			Q8_NX_CDRP_ARG2, cdrp->cmd_arg2,
466 			Q8_NX_CDRP_ARG3, cdrp->cmd_arg3);
467 
468 		device_printf(dev, "%s: exit (ret = 0x%x)\n"
469 			"\t\t rsp = 0x%08x\n"
470 			"\t\t arg1 = 0x%08x\n"
471 			"\t\t arg2 = 0x%08x\n"
472 			"\t\t arg3 = 0x%08x\n",
473 			__func__, ret, cdrp->rsp,
474 			cdrp->rsp_arg1, cdrp->rsp_arg2, cdrp->rsp_arg3);
475 	}
476 
477 	return (ret);
478 }
479 
480 #define QLA_TX_MIN_FREE	2
481 
482 /*
483  * Name: qla_fw_cmd
484  * Function: Issues firmware control commands on the Tx Ring.
485  */
486 static int
487 qla_fw_cmd(qla_host_t *ha, void *fw_cmd, uint32_t size)
488 {
489 	device_t dev;
490         q80_tx_cmd_t *tx_cmd;
491         qla_hw_t *hw = &ha->hw;
492 	int count = 100;
493 
494 	dev = ha->pci_dev;
495 
496 	QLA_TX_LOCK(ha);
497 
498         if (hw->txr_free <= QLA_TX_MIN_FREE) {
499 		while (count--) {
500 			qla_hw_tx_done_locked(ha);
501 			if (hw->txr_free > QLA_TX_MIN_FREE)
502 				break;
503 
504 			QLA_TX_UNLOCK(ha);
505 			qla_mdelay(__func__, 10);
506 			QLA_TX_LOCK(ha);
507 		}
508         	if (hw->txr_free <= QLA_TX_MIN_FREE) {
509 			QLA_TX_UNLOCK(ha);
510 			device_printf(dev, "%s: xmit queue full\n", __func__);
511                 	return (-1);
512 		}
513         }
514         tx_cmd = &hw->tx_ring_base[hw->txr_next];
515 
516         bzero((void *)tx_cmd, sizeof(q80_tx_cmd_t));
517 
518 	bcopy(fw_cmd, tx_cmd, size);
519 
520 	hw->txr_next = (hw->txr_next + 1) & (NUM_TX_DESCRIPTORS - 1);
521 	hw->txr_free--;
522 
523 	QL_UPDATE_TX_PRODUCER_INDEX(ha, hw->txr_next);
524 
525 	QLA_TX_UNLOCK(ha);
526 
527 	return (0);
528 }
529 
530 /*
531  * Name: qla_config_rss
532  * Function: Configure RSS for the context/interface.
533  */
534 const uint64_t rss_key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
535 			0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
536 			0x255b0ec26d5a56daULL };
537 
538 static int
539 qla_config_rss(qla_host_t *ha, uint16_t cntxt_id)
540 {
541 	qla_fw_cds_config_rss_t rss_config;
542 	int ret, i;
543 
544 	bzero(&rss_config, sizeof(qla_fw_cds_config_rss_t));
545 
546 	rss_config.hdr.cmd = Q8_FWCD_CNTRL_REQ;
547 	rss_config.hdr.opcode = Q8_FWCD_OPCODE_CONFIG_RSS;
548 	rss_config.hdr.cntxt_id = cntxt_id;
549 
550 	rss_config.hash_type = (Q8_FWCD_RSS_HASH_TYPE_IPV4_TCP_IP |
551 					Q8_FWCD_RSS_HASH_TYPE_IPV6_TCP_IP);
552 	rss_config.flags = Q8_FWCD_RSS_FLAGS_ENABLE_RSS;
553 
554 	rss_config.ind_tbl_mask = 0x7;
555 
556 	for (i = 0; i < 5; i++)
557 		rss_config.rss_key[i] = rss_key[i];
558 
559 	ret = qla_fw_cmd(ha, &rss_config, sizeof(qla_fw_cds_config_rss_t));
560 
561 	return ret;
562 }
563 
564 /*
565  * Name: qla_config_intr_coalesce
566  * Function: Configure Interrupt Coalescing.
567  */
568 static int
569 qla_config_intr_coalesce(qla_host_t *ha, uint16_t cntxt_id, int tenable)
570 {
571 	qla_fw_cds_config_intr_coalesc_t intr_coalesce;
572 	int ret;
573 
574 	bzero(&intr_coalesce, sizeof(qla_fw_cds_config_intr_coalesc_t));
575 
576 	intr_coalesce.hdr.cmd = Q8_FWCD_CNTRL_REQ;
577 	intr_coalesce.hdr.opcode = Q8_FWCD_OPCODE_CONFIG_INTR_COALESCING;
578 	intr_coalesce.hdr.cntxt_id = cntxt_id;
579 
580 	intr_coalesce.flags = 0x04;
581 	intr_coalesce.max_rcv_pkts = 256;
582 	intr_coalesce.max_rcv_usecs = 3;
583 	intr_coalesce.max_snd_pkts = 64;
584 	intr_coalesce.max_snd_usecs = 4;
585 
586 	if (tenable) {
587 		intr_coalesce.usecs_to = 1000; /* 1 millisecond */
588 		intr_coalesce.timer_type = Q8_FWCMD_INTR_COALESC_TIMER_PERIODIC;
589 		intr_coalesce.sds_ring_bitmask =
590 			Q8_FWCMD_INTR_COALESC_SDS_RING_0;
591 	}
592 
593 	ret = qla_fw_cmd(ha, &intr_coalesce,
594 			sizeof(qla_fw_cds_config_intr_coalesc_t));
595 
596 	return ret;
597 }
598 
599 /*
600  * Name: qla_config_mac_addr
601  * Function: binds a MAC address to the context/interface.
602  *	Can be unicast, multicast or broadcast.
603  */
604 static int
605 qla_config_mac_addr(qla_host_t *ha, uint8_t *mac_addr, uint16_t cntxt_id,
606 	uint32_t add_multi)
607 {
608 	qla_fw_cds_config_mac_addr_t mac_config;
609 	int ret;
610 
611 //	device_printf(ha->pci_dev,
612 //		"%s: mac_addr %02x:%02x:%02x:%02x:%02x:%02x\n", __func__,
613 //		mac_addr[0], mac_addr[1], mac_addr[2],
614 //		mac_addr[3], mac_addr[4], mac_addr[5]);
615 
616 	bzero(&mac_config, sizeof(qla_fw_cds_config_mac_addr_t));
617 
618 	mac_config.hdr.cmd = Q8_FWCD_CNTRL_REQ;
619 	mac_config.hdr.opcode = Q8_FWCD_OPCODE_CONFIG_MAC_ADDR;
620 	mac_config.hdr.cntxt_id = cntxt_id;
621 
622 	if (add_multi)
623 		mac_config.cmd = Q8_FWCD_ADD_MAC_ADDR;
624 	else
625 		mac_config.cmd = Q8_FWCD_DEL_MAC_ADDR;
626 	bcopy(mac_addr, mac_config.mac_addr,6);
627 
628 	ret = qla_fw_cmd(ha, &mac_config, sizeof(qla_fw_cds_config_mac_addr_t));
629 
630 	return ret;
631 }
632 
633 /*
634  * Name: qla_set_mac_rcv_mode
635  * Function: Enable/Disable AllMulticast and Promiscuous Modes.
636  */
637 static int
638 qla_set_mac_rcv_mode(qla_host_t *ha, uint16_t cntxt_id, uint32_t mode)
639 {
640 	qla_set_mac_rcv_mode_t rcv_mode;
641 	int ret;
642 
643 	bzero(&rcv_mode, sizeof(qla_set_mac_rcv_mode_t));
644 
645 	rcv_mode.hdr.cmd = Q8_FWCD_CNTRL_REQ;
646 	rcv_mode.hdr.opcode = Q8_FWCD_OPCODE_CONFIG_MAC_RCV_MODE;
647 	rcv_mode.hdr.cntxt_id = cntxt_id;
648 
649 	rcv_mode.mode = mode;
650 
651 	ret = qla_fw_cmd(ha, &rcv_mode, sizeof(qla_set_mac_rcv_mode_t));
652 
653 	return ret;
654 }
655 
656 void
657 qla_set_promisc(qla_host_t *ha)
658 {
659 	(void)qla_set_mac_rcv_mode(ha,
660 		(ha->hw.rx_cntxt_rsp)->rx_rsp.cntxt_id,
661 		Q8_MAC_RCV_ENABLE_PROMISCUOUS);
662 }
663 
664 void
665 qla_set_allmulti(qla_host_t *ha)
666 {
667 	(void)qla_set_mac_rcv_mode(ha,
668 		(ha->hw.rx_cntxt_rsp)->rx_rsp.cntxt_id,
669 		Q8_MAC_RCV_ENABLE_ALLMULTI);
670 }
671 
672 void
673 qla_reset_promisc_allmulti(qla_host_t *ha)
674 {
675 	(void)qla_set_mac_rcv_mode(ha,
676 		(ha->hw.rx_cntxt_rsp)->rx_rsp.cntxt_id,
677 		Q8_MAC_RCV_RESET_PROMISC_ALLMULTI);
678 }
679 
680 /*
681  * Name: qla_config_ipv4_addr
682  * Function: Configures the Destination IP Addr for LRO.
683  */
684 void
685 qla_config_ipv4_addr(qla_host_t *ha, uint32_t ipv4_addr)
686 {
687 	qla_config_ipv4_t ip_conf;
688 
689 	bzero(&ip_conf, sizeof(qla_config_ipv4_t));
690 
691 	ip_conf.hdr.cmd = Q8_FWCD_CNTRL_REQ;
692 	ip_conf.hdr.opcode = Q8_FWCD_OPCODE_CONFIG_IPADDR;
693 	ip_conf.hdr.cntxt_id = (ha->hw.rx_cntxt_rsp)->rx_rsp.cntxt_id;
694 
695 	ip_conf.cmd = (uint64_t)Q8_CONFIG_CMD_IP_ENABLE;
696 	ip_conf.ipv4_addr = (uint64_t)ipv4_addr;
697 
698 	(void)qla_fw_cmd(ha, &ip_conf, sizeof(qla_config_ipv4_t));
699 
700 	return;
701 }
702 
703 /*
704  * Name: qla_tx_tso
705  * Function: Checks if the packet to be transmitted is a candidate for
706  *	Large TCP Segment Offload. If yes, the appropriate fields in the Tx
707  *	Ring Structure are plugged in.
708  */
709 static int
710 qla_tx_tso(qla_host_t *ha, struct mbuf *mp, q80_tx_cmd_t *tx_cmd, uint8_t *hdr)
711 {
712 	struct ether_vlan_header *eh;
713 	struct ip *ip = NULL;
714 	struct tcphdr *th = NULL;
715 	uint32_t ehdrlen,  hdrlen = 0, ip_hlen, tcp_hlen, tcp_opt_off;
716 	uint16_t etype, opcode, offload = 1;
717 	uint8_t *tcp_opt;
718 	device_t dev;
719 
720 	dev = ha->pci_dev;
721 
722 	eh = mtod(mp, struct ether_vlan_header *);
723 
724 	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
725 		ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
726 		etype = ntohs(eh->evl_proto);
727 	} else {
728 		ehdrlen = ETHER_HDR_LEN;
729 		etype = ntohs(eh->evl_encap_proto);
730 	}
731 
732 	switch (etype) {
733 		case ETHERTYPE_IP:
734 
735 			tcp_opt_off = ehdrlen + sizeof(struct ip) +
736 					sizeof(struct tcphdr);
737 
738 			if (mp->m_len < tcp_opt_off) {
739 				m_copydata(mp, 0, tcp_opt_off, hdr);
740 				ip = (struct ip *)hdr;
741 			} else {
742 				ip = (struct ip *)(mp->m_data + ehdrlen);
743 			}
744 
745 			ip_hlen = ip->ip_hl << 2;
746 			opcode = Q8_TX_CMD_OP_XMT_TCP_LSO;
747 
748 			if ((ip->ip_p != IPPROTO_TCP) ||
749 				(ip_hlen != sizeof (struct ip))) {
750 				offload = 0;
751 			} else {
752 				th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
753 			}
754 		break;
755 
756 		default:
757 			QL_DPRINT8((dev, "%s: type!=ip\n", __func__));
758 			offload = 0;
759 		break;
760 	}
761 
762 	if (!offload)
763 		return (-1);
764 
765 	tcp_hlen = th->th_off << 2;
766 
767 	hdrlen = ehdrlen + ip_hlen + tcp_hlen;
768 
769 	if (mp->m_len < hdrlen) {
770 		if (mp->m_len < tcp_opt_off) {
771 			if (tcp_hlen > sizeof(struct tcphdr)) {
772 				m_copydata(mp, tcp_opt_off,
773 					(tcp_hlen - sizeof(struct tcphdr)),
774 					&hdr[tcp_opt_off]);
775 			}
776 		} else {
777 			m_copydata(mp, 0, hdrlen, hdr);
778 		}
779 	}
780 
781 	if ((mp->m_pkthdr.csum_flags & CSUM_TSO) == 0) {
782 		/* If TCP options are preset only time stamp option is supported */
783 		if ((tcp_hlen - sizeof(struct tcphdr)) != 10)
784 			return -1;
785 		else {
786 			if (mp->m_len < hdrlen) {
787 				tcp_opt = &hdr[tcp_opt_off];
788 			} else {
789 				tcp_opt = (uint8_t *)(mp->m_data + tcp_opt_off);
790 			}
791 
792 			if ((*tcp_opt != 0x01) || (*(tcp_opt + 1) != 0x01) ||
793 				(*(tcp_opt + 2) != 0x08) ||
794 				(*(tcp_opt + 3) != 10)) {
795 				return -1;
796 			}
797 		}
798 
799 		tx_cmd->mss = ha->max_frame_size - ETHER_CRC_LEN - hdrlen;
800 	} else {
801 		tx_cmd->mss = mp->m_pkthdr.tso_segsz;
802 	}
803 
804 	tx_cmd->flags_opcode = opcode ;
805 	tx_cmd->tcp_hdr_off = ip_hlen + ehdrlen;
806 	tx_cmd->ip_hdr_off = ehdrlen;
807 	tx_cmd->mss = mp->m_pkthdr.tso_segsz;
808 	tx_cmd->total_hdr_len = hdrlen;
809 
810 	/* Check for Multicast least significant bit of MSB == 1 */
811 	if (eh->evl_dhost[0] & 0x01) {
812 		tx_cmd->flags_opcode = Q8_TX_CMD_FLAGS_MULTICAST;
813 	}
814 
815 	if (mp->m_len < hdrlen) {
816 		return (1);
817 	}
818 
819 	return (0);
820 }
821 
822 /*
823  * Name: qla_tx_chksum
824  * Function: Checks if the packet to be transmitted is a candidate for
825  *	TCP/UDP Checksum offload. If yes, the appropriate fields in the Tx
826  *	Ring Structure are plugged in.
827  */
828 static int
829 qla_tx_chksum(qla_host_t *ha, struct mbuf *mp, q80_tx_cmd_t *tx_cmd)
830 {
831 	struct ether_vlan_header *eh;
832 	struct ip *ip;
833 	struct ip6_hdr *ip6;
834 	uint32_t ehdrlen, ip_hlen;
835 	uint16_t etype, opcode, offload = 1;
836 	device_t dev;
837 
838 	dev = ha->pci_dev;
839 
840 	if ((mp->m_pkthdr.csum_flags & (CSUM_TCP|CSUM_UDP)) == 0)
841 		return (-1);
842 
843 	eh = mtod(mp, struct ether_vlan_header *);
844 
845 	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
846 		ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
847 		etype = ntohs(eh->evl_proto);
848 	} else {
849 		ehdrlen = ETHER_HDR_LEN;
850 		etype = ntohs(eh->evl_encap_proto);
851 	}
852 
853 
854 	switch (etype) {
855 		case ETHERTYPE_IP:
856 			ip = (struct ip *)(mp->m_data + ehdrlen);
857 
858 			ip_hlen = sizeof (struct ip);
859 
860 			if (mp->m_len < (ehdrlen + ip_hlen)) {
861 				device_printf(dev, "%s: ipv4 mlen\n", __func__);
862 				offload = 0;
863 				break;
864 			}
865 
866 			if (ip->ip_p == IPPROTO_TCP)
867 				opcode = Q8_TX_CMD_OP_XMT_TCP_CHKSUM;
868 			else if (ip->ip_p == IPPROTO_UDP)
869 				opcode = Q8_TX_CMD_OP_XMT_UDP_CHKSUM;
870 			else {
871 				device_printf(dev, "%s: ipv4\n", __func__);
872 				offload = 0;
873 			}
874 		break;
875 
876 		case ETHERTYPE_IPV6:
877 			ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
878 
879 			ip_hlen = sizeof(struct ip6_hdr);
880 
881 			if (mp->m_len < (ehdrlen + ip_hlen)) {
882 				device_printf(dev, "%s: ipv6 mlen\n", __func__);
883 				offload = 0;
884 				break;
885 			}
886 
887 			if (ip6->ip6_nxt == IPPROTO_TCP)
888 				opcode = Q8_TX_CMD_OP_XMT_TCP_CHKSUM_IPV6;
889 			else if (ip6->ip6_nxt == IPPROTO_UDP)
890 				opcode = Q8_TX_CMD_OP_XMT_UDP_CHKSUM_IPV6;
891 			else {
892 				device_printf(dev, "%s: ipv6\n", __func__);
893 				offload = 0;
894 			}
895 		break;
896 
897 		default:
898 			offload = 0;
899 		break;
900 	}
901 	if (!offload)
902 		return (-1);
903 
904 	tx_cmd->flags_opcode = opcode;
905 
906 	tx_cmd->tcp_hdr_off = ip_hlen + ehdrlen;
907 
908 	return (0);
909 }
910 
911 /*
912  * Name: qla_hw_send
913  * Function: Transmits a packet. It first checks if the packet is a
914  *	candidate for Large TCP Segment Offload and then for UDP/TCP checksum
915  *	offload. If either of these creteria are not met, it is transmitted
916  *	as a regular ethernet frame.
917  */
918 int
919 qla_hw_send(qla_host_t *ha, bus_dma_segment_t *segs, int nsegs,
920 	uint32_t *tx_idx,  struct mbuf *mp)
921 {
922 	struct ether_vlan_header *eh;
923 	qla_hw_t *hw = &ha->hw;
924 	q80_tx_cmd_t *tx_cmd, tso_cmd;
925 	bus_dma_segment_t *c_seg;
926 	uint32_t num_tx_cmds, hdr_len = 0;
927 	uint32_t total_length = 0, bytes, tx_cmd_count = 0;
928 	device_t dev;
929 	int i, ret;
930 	uint8_t *src = NULL, *dst = NULL;
931 
932 	dev = ha->pci_dev;
933 
934 	/*
935 	 * Always make sure there is atleast one empty slot in the tx_ring
936 	 * tx_ring is considered full when there only one entry available
937 	 */
938         num_tx_cmds = (nsegs + (Q8_TX_CMD_MAX_SEGMENTS - 1)) >> 2;
939 
940 	total_length = mp->m_pkthdr.len;
941 	if (total_length > QLA_MAX_TSO_FRAME_SIZE) {
942 		device_printf(dev, "%s: total length exceeds maxlen(%d)\n",
943 			__func__, total_length);
944 		return (-1);
945 	}
946 	eh = mtod(mp, struct ether_vlan_header *);
947 
948 	if ((mp->m_pkthdr.len > ha->max_frame_size)||(nsegs > Q8_TX_MAX_SEGMENTS)) {
949 		bzero((void *)&tso_cmd, sizeof(q80_tx_cmd_t));
950 
951 		src = ha->hw.frame_hdr;
952 		ret = qla_tx_tso(ha, mp, &tso_cmd, src);
953 
954 		if (!(ret & ~1)) {
955 			/* find the additional tx_cmd descriptors required */
956 
957 			hdr_len = tso_cmd.total_hdr_len;
958 
959 			bytes = sizeof(q80_tx_cmd_t) - Q8_TX_CMD_TSO_ALIGN;
960 			bytes = QL_MIN(bytes, hdr_len);
961 
962 			num_tx_cmds++;
963 			hdr_len -= bytes;
964 
965 			while (hdr_len) {
966 				bytes = QL_MIN((sizeof(q80_tx_cmd_t)), hdr_len);
967 				hdr_len -= bytes;
968 				num_tx_cmds++;
969 			}
970 			hdr_len = tso_cmd.total_hdr_len;
971 
972 			if (ret == 0)
973 				src = (uint8_t *)eh;
974 		}
975 	}
976 
977 	if (hw->txr_free <= (num_tx_cmds + QLA_TX_MIN_FREE)) {
978 		qla_hw_tx_done_locked(ha);
979 		if (hw->txr_free <= (num_tx_cmds + QLA_TX_MIN_FREE)) {
980         		QL_DPRINT8((dev, "%s: (hw->txr_free <= "
981 				"(num_tx_cmds + QLA_TX_MIN_FREE))\n",
982 				__func__));
983 			return (-1);
984 		}
985 	}
986 
987 	*tx_idx = hw->txr_next;
988 
989         tx_cmd = &hw->tx_ring_base[hw->txr_next];
990 
991 	if (hdr_len == 0) {
992 		if ((nsegs > Q8_TX_MAX_SEGMENTS) ||
993 			(mp->m_pkthdr.len > ha->max_frame_size)){
994         		device_printf(dev,
995 				"%s: (nsegs[%d, %d, 0x%b] > Q8_TX_MAX_SEGMENTS)\n",
996 				__func__, nsegs, mp->m_pkthdr.len,
997 				(int)mp->m_pkthdr.csum_flags, CSUM_BITS);
998 			qla_dump_buf8(ha, "qla_hw_send: wrong pkt",
999 				mtod(mp, char *), mp->m_len);
1000 			return (EINVAL);
1001 		}
1002 		bzero((void *)tx_cmd, sizeof(q80_tx_cmd_t));
1003 		if (qla_tx_chksum(ha, mp, tx_cmd) != 0)
1004         		tx_cmd->flags_opcode = Q8_TX_CMD_OP_XMT_ETHER;
1005 	} else {
1006 		bcopy(&tso_cmd, tx_cmd, sizeof(q80_tx_cmd_t));
1007 	}
1008 
1009 	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN))
1010         	tx_cmd->flags_opcode |= Q8_TX_CMD_FLAGS_VLAN_TAGGED;
1011 	else if (mp->m_flags & M_VLANTAG) {
1012         	tx_cmd->flags_opcode |= (Q8_TX_CMD_FLAGS_VLAN_TAGGED |
1013 						Q8_TX_CMD_FLAGS_HW_VLAN_ID);
1014 		tx_cmd->vlan_tci = mp->m_pkthdr.ether_vtag;
1015 	}
1016 
1017         tx_cmd->n_bufs = (uint8_t)nsegs;
1018         tx_cmd->data_len_lo = (uint8_t)(total_length & 0xFF);
1019         tx_cmd->data_len_hi = qla_host_to_le16(((uint16_t)(total_length >> 8)));
1020 	tx_cmd->port_cntxtid = Q8_TX_CMD_PORT_CNXTID(ha->pci_func);
1021 
1022 	c_seg = segs;
1023 
1024 	while (1) {
1025 		for (i = 0; ((i < Q8_TX_CMD_MAX_SEGMENTS) && nsegs); i++) {
1026 			switch (i) {
1027 			case 0:
1028 				tx_cmd->buf1_addr = c_seg->ds_addr;
1029 				tx_cmd->buf1_len = c_seg->ds_len;
1030 				break;
1031 
1032 			case 1:
1033 				tx_cmd->buf2_addr = c_seg->ds_addr;
1034 				tx_cmd->buf2_len = c_seg->ds_len;
1035 				break;
1036 
1037 			case 2:
1038 				tx_cmd->buf3_addr = c_seg->ds_addr;
1039 				tx_cmd->buf3_len = c_seg->ds_len;
1040 				break;
1041 
1042 			case 3:
1043 				tx_cmd->buf4_addr = c_seg->ds_addr;
1044 				tx_cmd->buf4_len = c_seg->ds_len;
1045 				break;
1046 			}
1047 
1048 			c_seg++;
1049 			nsegs--;
1050 		}
1051 
1052 		hw->txr_next = (hw->txr_next + 1) & (NUM_TX_DESCRIPTORS - 1);
1053 		tx_cmd_count++;
1054 
1055 		if (!nsegs)
1056 			break;
1057 
1058         	tx_cmd = &hw->tx_ring_base[hw->txr_next];
1059 		bzero((void *)tx_cmd, sizeof(q80_tx_cmd_t));
1060 	}
1061 
1062 	if (hdr_len) {
1063 		/* TSO : Copy the header in the following tx cmd descriptors */
1064 
1065 		tx_cmd = &hw->tx_ring_base[hw->txr_next];
1066 		bzero((void *)tx_cmd, sizeof(q80_tx_cmd_t));
1067 
1068 		bytes = sizeof(q80_tx_cmd_t) - Q8_TX_CMD_TSO_ALIGN;
1069 		bytes = QL_MIN(bytes, hdr_len);
1070 
1071 		dst = (uint8_t *)tx_cmd + Q8_TX_CMD_TSO_ALIGN;
1072 
1073 		if (mp->m_flags & M_VLANTAG) {
1074 			/* first copy the src/dst MAC addresses */
1075 			bcopy(src, dst, (ETHER_ADDR_LEN * 2));
1076 			dst += (ETHER_ADDR_LEN * 2);
1077 			src += (ETHER_ADDR_LEN * 2);
1078 
1079 			hdr_len -= (ETHER_ADDR_LEN * 2);
1080 
1081 			*((uint16_t *)dst) = htons(ETHERTYPE_VLAN);
1082 			dst += 2;
1083 			*((uint16_t *)dst) = mp->m_pkthdr.ether_vtag;
1084 			dst += 2;
1085 
1086 			bytes -= ((ETHER_ADDR_LEN * 2) + 4);
1087 
1088 			bcopy(src, dst, bytes);
1089 			src += bytes;
1090 			hdr_len -= bytes;
1091 		} else {
1092 			bcopy(src, dst, bytes);
1093 			src += bytes;
1094 			hdr_len -= bytes;
1095 		}
1096 
1097 		hw->txr_next = (hw->txr_next + 1) & (NUM_TX_DESCRIPTORS - 1);
1098 		tx_cmd_count++;
1099 
1100 		while (hdr_len) {
1101 			tx_cmd = &hw->tx_ring_base[hw->txr_next];
1102 			bzero((void *)tx_cmd, sizeof(q80_tx_cmd_t));
1103 
1104 			bytes = QL_MIN((sizeof(q80_tx_cmd_t)), hdr_len);
1105 
1106 			bcopy(src, tx_cmd, bytes);
1107 			src += bytes;
1108 			hdr_len -= bytes;
1109 			hw->txr_next =
1110 				(hw->txr_next + 1) & (NUM_TX_DESCRIPTORS - 1);
1111 			tx_cmd_count++;
1112 		}
1113 	}
1114 
1115 	hw->txr_free = hw->txr_free - tx_cmd_count;
1116 
1117 	QL_UPDATE_TX_PRODUCER_INDEX(ha, hw->txr_next);
1118        	QL_DPRINT8((dev, "%s: return\n", __func__));
1119 	return (0);
1120 }
1121 
1122 /*
1123  * Name: qla_del_hw_if
1124  * Function: Destroys the hardware specific entities corresponding to an
1125  *	Ethernet Interface
1126  */
1127 void
1128 qla_del_hw_if(qla_host_t *ha)
1129 {
1130 	int	i;
1131 
1132 	for (i = 0; i < ha->hw.num_sds_rings; i++)
1133 		QL_DISABLE_INTERRUPTS(ha, i);
1134 
1135 	qla_del_rcv_cntxt(ha);
1136 	qla_del_xmt_cntxt(ha);
1137 
1138 	ha->hw.flags.lro = 0;
1139 }
1140 
1141 /*
1142  * Name: qla_init_hw_if
1143  * Function: Creates the hardware specific entities corresponding to an
1144  *	Ethernet Interface - Transmit and Receive Contexts. Sets the MAC Address
1145  *	corresponding to the interface. Enables LRO if allowed.
1146  */
1147 int
1148 qla_init_hw_if(qla_host_t *ha)
1149 {
1150 	int		i;
1151 	uint8_t		bcast_mac[6];
1152 
1153 	qla_get_hw_caps(ha);
1154 
1155 	for (i = 0; i < ha->hw.num_sds_rings; i++) {
1156 		bzero(ha->hw.dma_buf.sds_ring[i].dma_b,
1157 			ha->hw.dma_buf.sds_ring[i].size);
1158 	}
1159 	/*
1160 	 * Create Receive Context
1161 	 */
1162 	if (qla_init_rcv_cntxt(ha)) {
1163 		return (-1);
1164 	}
1165 
1166 	ha->hw.rx_next = NUM_RX_DESCRIPTORS - 2;
1167 	ha->hw.rxj_next = NUM_RX_JUMBO_DESCRIPTORS - 2;
1168 	ha->hw.rx_in = ha->hw.rxj_in = 0;
1169 
1170 	/* Update the RDS Producer Indices */
1171 	QL_UPDATE_RDS_PRODUCER_INDEX(ha, 0, ha->hw.rx_next);
1172 	QL_UPDATE_RDS_PRODUCER_INDEX(ha, 1, ha->hw.rxj_next);
1173 
1174 	/*
1175 	 * Create Transmit Context
1176 	 */
1177 	if (qla_init_xmt_cntxt(ha)) {
1178 		qla_del_rcv_cntxt(ha);
1179 		return (-1);
1180 	}
1181 
1182 	qla_config_mac_addr(ha, ha->hw.mac_addr,
1183 		(ha->hw.rx_cntxt_rsp)->rx_rsp.cntxt_id, 1);
1184 
1185 	bcast_mac[0] = 0xFF; bcast_mac[1] = 0xFF; bcast_mac[2] = 0xFF;
1186 	bcast_mac[3] = 0xFF; bcast_mac[4] = 0xFF; bcast_mac[5] = 0xFF;
1187 	qla_config_mac_addr(ha, bcast_mac,
1188 		(ha->hw.rx_cntxt_rsp)->rx_rsp.cntxt_id, 1);
1189 
1190 	qla_config_rss(ha, (ha->hw.rx_cntxt_rsp)->rx_rsp.cntxt_id);
1191 
1192 	qla_config_intr_coalesce(ha, (ha->hw.rx_cntxt_rsp)->rx_rsp.cntxt_id, 0);
1193 
1194 	for (i = 0; i < ha->hw.num_sds_rings; i++)
1195 		QL_ENABLE_INTERRUPTS(ha, i);
1196 
1197 	return (0);
1198 }
1199 
1200 /*
1201  * Name: qla_init_rcv_cntxt
1202  * Function: Creates the Receive Context.
1203  */
1204 static int
1205 qla_init_rcv_cntxt(qla_host_t *ha)
1206 {
1207 	device_t		dev;
1208 	qla_cdrp_t		cdrp;
1209 	q80_rcv_cntxt_rsp_t	*rsp;
1210 	q80_stat_desc_t		*sdesc;
1211 	bus_addr_t		phys_addr;
1212 	int			i, j;
1213         qla_hw_t		*hw = &ha->hw;
1214 
1215 	dev = ha->pci_dev;
1216 
1217 	/*
1218 	 * Create Receive Context
1219 	 */
1220 
1221 	for (i = 0; i < hw->num_sds_rings; i++) {
1222 		sdesc = (q80_stat_desc_t *)&hw->sds[i].sds_ring_base[0];
1223 		for (j = 0; j < NUM_STATUS_DESCRIPTORS; j++) {
1224 			sdesc->data[0] =
1225 				Q8_STAT_DESC_SET_OWNER(Q8_STAT_DESC_OWNER_FW);
1226 		}
1227 	}
1228 
1229 	phys_addr = ha->hw.rx_cntxt_req_paddr;
1230 
1231 	bzero(&cdrp, sizeof(qla_cdrp_t));
1232 
1233 	cdrp.cmd = Q8_CMD_CREATE_RX_CNTXT;
1234 	cdrp.cmd_arg1 = (uint32_t)(phys_addr >> 32);
1235 	cdrp.cmd_arg2 = (uint32_t)(phys_addr);
1236 	cdrp.cmd_arg3 = (uint32_t)(sizeof (q80_rcv_cntxt_req_t));
1237 
1238 	if (qla_issue_cmd(ha, &cdrp)) {
1239 		device_printf(dev, "%s: Q8_CMD_CREATE_RX_CNTXT failed\n",
1240 			__func__);
1241 		return (-1);
1242 	} else {
1243 		rsp = ha->hw.rx_cntxt_rsp;
1244 
1245 		QL_DPRINT2((dev, "%s: rcv cntxt successful"
1246 			" rds_ring_offset = 0x%08x"
1247 			" sds_ring_offset = 0x%08x"
1248 			" cntxt_state = 0x%08x"
1249 			" funcs_per_port = 0x%08x"
1250 			" num_rds_rings = 0x%04x"
1251 			" num_sds_rings = 0x%04x"
1252 			" cntxt_id = 0x%04x"
1253 			" phys_port = 0x%02x"
1254 			" virt_port = 0x%02x\n",
1255 			__func__,
1256 			rsp->rx_rsp.rds_ring_offset,
1257 			rsp->rx_rsp.sds_ring_offset,
1258 			rsp->rx_rsp.cntxt_state,
1259 			rsp->rx_rsp.funcs_per_port,
1260 			rsp->rx_rsp.num_rds_rings,
1261 			rsp->rx_rsp.num_sds_rings,
1262 			rsp->rx_rsp.cntxt_id,
1263 			rsp->rx_rsp.phys_port,
1264 			rsp->rx_rsp.virt_port));
1265 
1266 		for (i = 0; i < ha->hw.num_rds_rings; i++) {
1267 			QL_DPRINT2((dev,
1268 				"%s: rcv cntxt rds[%i].producer_reg = 0x%08x\n",
1269 				__func__, i, rsp->rds_rsp[i].producer_reg));
1270 		}
1271 		for (i = 0; i < ha->hw.num_sds_rings; i++) {
1272 			QL_DPRINT2((dev,
1273 				"%s: rcv cntxt sds[%i].consumer_reg = 0x%08x"
1274 				" sds[%i].intr_mask_reg = 0x%08x\n",
1275 				__func__, i, rsp->sds_rsp[i].consumer_reg,
1276 				i, rsp->sds_rsp[i].intr_mask_reg));
1277 		}
1278 	}
1279 	ha->hw.flags.init_rx_cnxt = 1;
1280 	return (0);
1281 }
1282 
1283 /*
1284  * Name: qla_del_rcv_cntxt
1285  * Function: Destroys the Receive Context.
1286  */
1287 void
1288 qla_del_rcv_cntxt(qla_host_t *ha)
1289 {
1290 	qla_cdrp_t	cdrp;
1291 	device_t	dev = ha->pci_dev;
1292 
1293 	if (!ha->hw.flags.init_rx_cnxt)
1294 		return;
1295 
1296 	bzero(&cdrp, sizeof(qla_cdrp_t));
1297 
1298 	cdrp.cmd = Q8_CMD_DESTROY_RX_CNTXT;
1299 	cdrp.cmd_arg1 = (uint32_t) (ha->hw.rx_cntxt_rsp)->rx_rsp.cntxt_id;
1300 
1301 	if (qla_issue_cmd(ha, &cdrp)) {
1302 		device_printf(dev, "%s: Q8_CMD_DESTROY_RX_CNTXT failed\n",
1303 			__func__);
1304 	}
1305 	ha->hw.flags.init_rx_cnxt = 0;
1306 }
1307 
1308 /*
1309  * Name: qla_init_xmt_cntxt
1310  * Function: Creates the Transmit Context.
1311  */
1312 static int
1313 qla_init_xmt_cntxt(qla_host_t *ha)
1314 {
1315 	bus_addr_t		phys_addr;
1316 	device_t		dev;
1317 	q80_tx_cntxt_rsp_t	*tx_rsp;
1318 	qla_cdrp_t		cdrp;
1319         qla_hw_t		*hw = &ha->hw;
1320 
1321 	dev = ha->pci_dev;
1322 
1323 	/*
1324 	 * Create Transmit Context
1325 	 */
1326 	phys_addr = ha->hw.tx_cntxt_req_paddr;
1327 	tx_rsp = ha->hw.tx_cntxt_rsp;
1328 
1329 	hw->txr_comp = hw->txr_next = 0;
1330 	*(hw->tx_cons) = 0;
1331 
1332 	bzero(&cdrp, sizeof(qla_cdrp_t));
1333 
1334 	cdrp.cmd = Q8_CMD_CREATE_TX_CNTXT;
1335 	cdrp.cmd_arg1 = (uint32_t)(phys_addr >> 32);
1336 	cdrp.cmd_arg2 = (uint32_t)(phys_addr);
1337 	cdrp.cmd_arg3 = (uint32_t)(sizeof (q80_tx_cntxt_req_t));
1338 
1339 	if (qla_issue_cmd(ha, &cdrp)) {
1340 		device_printf(dev, "%s: Q8_CMD_CREATE_TX_CNTXT failed\n",
1341 			__func__);
1342 		return (-1);
1343 	} else {
1344 		ha->hw.tx_prod_reg = tx_rsp->producer_reg;
1345 
1346 		QL_DPRINT2((dev, "%s: tx cntxt successful"
1347 			" cntxt_state = 0x%08x "
1348 			" cntxt_id = 0x%04x "
1349 			" phys_port_id = 0x%02x "
1350 			" virt_port_id = 0x%02x "
1351 			" producer_reg = 0x%08x "
1352 			" intr_mask_reg = 0x%08x\n",
1353 			__func__, tx_rsp->cntxt_state, tx_rsp->cntxt_id,
1354 			tx_rsp->phys_port_id, tx_rsp->virt_port_id,
1355 			tx_rsp->producer_reg, tx_rsp->intr_mask_reg));
1356 	}
1357 	ha->hw.txr_free = NUM_TX_DESCRIPTORS;
1358 
1359 	ha->hw.flags.init_tx_cnxt = 1;
1360 	return (0);
1361 }
1362 
1363 /*
1364  * Name: qla_del_xmt_cntxt
1365  * Function: Destroys the Transmit Context.
1366  */
1367 static void
1368 qla_del_xmt_cntxt(qla_host_t *ha)
1369 {
1370 	qla_cdrp_t	cdrp;
1371 	device_t	dev = ha->pci_dev;
1372 
1373 	if (!ha->hw.flags.init_tx_cnxt)
1374 		return;
1375 
1376 	bzero(&cdrp, sizeof(qla_cdrp_t));
1377 
1378 	cdrp.cmd = Q8_CMD_DESTROY_TX_CNTXT;
1379 	cdrp.cmd_arg1 = (uint32_t) (ha->hw.tx_cntxt_rsp)->cntxt_id;
1380 
1381 	if (qla_issue_cmd(ha, &cdrp)) {
1382 		device_printf(dev, "%s: Q8_CMD_DESTROY_TX_CNTXT failed\n",
1383 			__func__);
1384 	}
1385 	ha->hw.flags.init_tx_cnxt = 0;
1386 }
1387 
1388 /*
1389  * Name: qla_get_max_rds
1390  * Function: Returns the maximum number of Receive Descriptor Rings per context.
1391  */
1392 static int
1393 qla_get_max_rds(qla_host_t *ha)
1394 {
1395 	qla_cdrp_t	cdrp;
1396 	device_t	dev;
1397 
1398 	dev = ha->pci_dev;
1399 
1400 	bzero(&cdrp, sizeof(qla_cdrp_t));
1401 
1402 	cdrp.cmd = Q8_CMD_RD_MAX_RDS_PER_CNTXT;
1403 
1404 	if (qla_issue_cmd(ha, &cdrp)) {
1405 		device_printf(dev, "%s: Q8_CMD_RD_MAX_RDS_PER_CNTXT failed\n",
1406 			__func__);
1407 		return (-1);
1408 	} else {
1409 		ha->hw.max_rds_per_cntxt = cdrp.rsp_arg1;
1410 		QL_DPRINT2((dev, "%s: max_rds_per_context 0x%08x\n",
1411 			__func__, ha->hw.max_rds_per_cntxt));
1412 	}
1413 	return 0;
1414 }
1415 
1416 /*
1417  * Name: qla_get_max_sds
1418  * Function: Returns the maximum number of Status Descriptor Rings per context.
1419  */
1420 static int
1421 qla_get_max_sds(qla_host_t *ha)
1422 {
1423 	qla_cdrp_t	cdrp;
1424 	device_t	dev;
1425 
1426 	dev = ha->pci_dev;
1427 
1428 	bzero(&cdrp, sizeof(qla_cdrp_t));
1429 
1430 	cdrp.cmd = Q8_CMD_RD_MAX_SDS_PER_CNTXT;
1431 
1432 	if (qla_issue_cmd(ha, &cdrp)) {
1433 		device_printf(dev, "%s: Q8_CMD_RD_MAX_RDS_PER_CNTXT failed\n",
1434 			__func__);
1435 		return (-1);
1436 	} else {
1437 		ha->hw.max_sds_per_cntxt = cdrp.rsp_arg1;
1438 		QL_DPRINT2((dev, "%s: max_sds_per_context 0x%08x\n",
1439 			__func__, ha->hw.max_sds_per_cntxt));
1440 	}
1441 	return 0;
1442 }
1443 
1444 /*
1445  * Name: qla_get_max_rules
1446  * Function: Returns the maximum number of Rules per context.
1447  */
1448 static int
1449 qla_get_max_rules(qla_host_t *ha)
1450 {
1451 	qla_cdrp_t	cdrp;
1452 	device_t	dev;
1453 
1454 	dev = ha->pci_dev;
1455 
1456 	bzero(&cdrp, sizeof(qla_cdrp_t));
1457 
1458 	cdrp.cmd = Q8_CMD_RD_MAX_RULES_PER_CNTXT;
1459 
1460 	if (qla_issue_cmd(ha, &cdrp)) {
1461 		device_printf(dev, "%s: Q8_CMD_RD_MAX_RULES_PER_CNTXT failed\n",
1462 			__func__);
1463 		return (-1);
1464 	} else {
1465 		ha->hw.max_rules_per_cntxt = cdrp.rsp_arg1;
1466 		QL_DPRINT2((dev, "%s: max_rules_per_cntxt 0x%08x\n",
1467 			__func__, ha->hw.max_rules_per_cntxt));
1468 	}
1469 	return 0;
1470 }
1471 
1472 /*
1473  * Name: qla_get_max_rcv_cntxts
1474  * Function: Returns the maximum number of Receive Contexts supported.
1475  */
1476 static int
1477 qla_get_max_rcv_cntxts(qla_host_t *ha)
1478 {
1479 	qla_cdrp_t	cdrp;
1480 	device_t	dev;
1481 
1482 	dev = ha->pci_dev;
1483 
1484 	bzero(&cdrp, sizeof(qla_cdrp_t));
1485 
1486 	cdrp.cmd = Q8_CMD_RD_MAX_RX_CNTXT;
1487 
1488 	if (qla_issue_cmd(ha, &cdrp)) {
1489 		device_printf(dev, "%s: Q8_CMD_RD_MAX_RX_CNTXT failed\n",
1490 			__func__);
1491 		return (-1);
1492 	} else {
1493 		ha->hw.max_rcv_cntxts = cdrp.rsp_arg1;
1494 		QL_DPRINT2((dev, "%s: max_rcv_cntxts 0x%08x\n",
1495 			__func__, ha->hw.max_rcv_cntxts));
1496 	}
1497 	return 0;
1498 }
1499 
1500 /*
1501  * Name: qla_get_max_tx_cntxts
1502  * Function: Returns the maximum number of Transmit Contexts supported.
1503  */
1504 static int
1505 qla_get_max_tx_cntxts(qla_host_t *ha)
1506 {
1507 	qla_cdrp_t	cdrp;
1508 	device_t	dev;
1509 
1510 	dev = ha->pci_dev;
1511 
1512 	bzero(&cdrp, sizeof(qla_cdrp_t));
1513 
1514 	cdrp.cmd = Q8_CMD_RD_MAX_TX_CNTXT;
1515 
1516 	if (qla_issue_cmd(ha, &cdrp)) {
1517 		device_printf(dev, "%s: Q8_CMD_RD_MAX_TX_CNTXT failed\n",
1518 			__func__);
1519 		return (-1);
1520 	} else {
1521 		ha->hw.max_xmt_cntxts = cdrp.rsp_arg1;
1522 		QL_DPRINT2((dev, "%s: max_xmt_cntxts 0x%08x\n",
1523 			__func__, ha->hw.max_xmt_cntxts));
1524 	}
1525 	return 0;
1526 }
1527 
1528 /*
1529  * Name: qla_get_max_mtu
1530  * Function: Returns the MTU supported for a context.
1531  */
1532 static int
1533 qla_get_max_mtu(qla_host_t *ha)
1534 {
1535 	qla_cdrp_t	cdrp;
1536 	device_t	dev;
1537 
1538 	dev = ha->pci_dev;
1539 
1540 	bzero(&cdrp, sizeof(qla_cdrp_t));
1541 
1542 	cdrp.cmd = Q8_CMD_RD_MAX_MTU;
1543 
1544 	if (qla_issue_cmd(ha, &cdrp)) {
1545 		device_printf(dev, "%s: Q8_CMD_RD_MAX_MTU failed\n", __func__);
1546 		return (-1);
1547 	} else {
1548 		ha->hw.max_mtu = cdrp.rsp_arg1;
1549 		QL_DPRINT2((dev, "%s: max_mtu 0x%08x\n", __func__,
1550 			ha->hw.max_mtu));
1551 	}
1552 	return 0;
1553 }
1554 
1555 /*
1556  * Name: qla_set_max_mtu
1557  * Function:
1558  *	Sets the maximum transfer unit size for the specified rcv context.
1559  */
1560 int
1561 qla_set_max_mtu(qla_host_t *ha, uint32_t mtu, uint16_t cntxt_id)
1562 {
1563 	qla_cdrp_t	cdrp;
1564 	device_t	dev;
1565 
1566 	dev = ha->pci_dev;
1567 
1568 	bzero(&cdrp, sizeof(qla_cdrp_t));
1569 
1570 	cdrp.cmd = Q8_CMD_SET_MTU;
1571 	cdrp.cmd_arg1 = (uint32_t)cntxt_id;
1572 	cdrp.cmd_arg2 = mtu;
1573 
1574 	if (qla_issue_cmd(ha, &cdrp)) {
1575 		device_printf(dev, "%s: Q8_CMD_RD_MAX_MTU failed\n", __func__);
1576 		return (-1);
1577 	} else {
1578 		ha->hw.max_mtu = cdrp.rsp_arg1;
1579 	}
1580 	return 0;
1581 }
1582 
1583 /*
1584  * Name: qla_get_max_lro
1585  * Function: Returns the maximum number of TCP Connection which can be supported
1586  *	with LRO.
1587  */
1588 static int
1589 qla_get_max_lro(qla_host_t *ha)
1590 {
1591 	qla_cdrp_t	cdrp;
1592 	device_t	dev;
1593 
1594 	dev = ha->pci_dev;
1595 
1596 	bzero(&cdrp, sizeof(qla_cdrp_t));
1597 
1598 	cdrp.cmd = Q8_CMD_RD_MAX_LRO;
1599 
1600 	if (qla_issue_cmd(ha, &cdrp)) {
1601 		device_printf(dev, "%s: Q8_CMD_RD_MAX_LRO failed\n", __func__);
1602 		return (-1);
1603 	} else {
1604 		ha->hw.max_lro = cdrp.rsp_arg1;
1605 		QL_DPRINT2((dev, "%s: max_lro 0x%08x\n", __func__,
1606 			ha->hw.max_lro));
1607 	}
1608 	return 0;
1609 }
1610 
1611 /*
1612  * Name: qla_get_flow_control
1613  * Function: Returns the Receive/Transmit Flow Control (PAUSE) settings for
1614  *	PCI function.
1615  */
1616 static int
1617 qla_get_flow_control(qla_host_t *ha)
1618 {
1619 	qla_cdrp_t	cdrp;
1620 	device_t	dev;
1621 
1622 	dev = ha->pci_dev;
1623 
1624 	bzero(&cdrp, sizeof(qla_cdrp_t));
1625 
1626 	cdrp.cmd = Q8_CMD_GET_FLOW_CNTRL;
1627 
1628 	if (qla_issue_cmd(ha, &cdrp)) {
1629 		device_printf(dev, "%s: Q8_CMD_GET_FLOW_CNTRL failed\n",
1630 			__func__);
1631 		return (-1);
1632 	} else {
1633 		QL_DPRINT2((dev, "%s: flow control 0x%08x\n", __func__,
1634 			cdrp.rsp_arg1));
1635 	}
1636 	return 0;
1637 }
1638 
1639 /*
1640  * Name: qla_get_flow_control
1641  * Function: Retrieves hardware capabilities
1642  */
1643 void
1644 qla_get_hw_caps(qla_host_t *ha)
1645 {
1646 	//qla_read_mac_addr(ha);
1647 	qla_get_max_rds(ha);
1648 	qla_get_max_sds(ha);
1649 	qla_get_max_rules(ha);
1650 	qla_get_max_rcv_cntxts(ha);
1651 	qla_get_max_tx_cntxts(ha);
1652 	qla_get_max_mtu(ha);
1653 	qla_get_max_lro(ha);
1654 	qla_get_flow_control(ha);
1655 	return;
1656 }
1657 
1658 /*
1659  * Name: qla_hw_set_multi
1660  * Function: Sets the Multicast Addresses provided the host O.S into the
1661  *	hardware (for the given interface)
1662  */
1663 void
1664 qla_hw_set_multi(qla_host_t *ha, uint8_t *mta, uint32_t mcnt,
1665 	uint32_t add_multi)
1666 {
1667 	q80_rcv_cntxt_rsp_t	*rsp;
1668 	int i;
1669 
1670 	rsp = ha->hw.rx_cntxt_rsp;
1671 	for (i = 0; i < mcnt; i++) {
1672 		qla_config_mac_addr(ha, mta, rsp->rx_rsp.cntxt_id, add_multi);
1673 		mta += Q8_MAC_ADDR_LEN;
1674 	}
1675 	return;
1676 }
1677 
1678 /*
1679  * Name: qla_hw_tx_done_locked
1680  * Function: Handle Transmit Completions
1681  */
1682 static void
1683 qla_hw_tx_done_locked(qla_host_t *ha)
1684 {
1685 	qla_tx_buf_t *txb;
1686         qla_hw_t *hw = &ha->hw;
1687 	uint32_t comp_idx, comp_count = 0;
1688 
1689 	/* retrieve index of last entry in tx ring completed */
1690 	comp_idx = qla_le32_to_host(*(hw->tx_cons));
1691 
1692 	while (comp_idx != hw->txr_comp) {
1693 		txb = &ha->tx_buf[hw->txr_comp];
1694 
1695 		hw->txr_comp++;
1696 		if (hw->txr_comp == NUM_TX_DESCRIPTORS)
1697 			hw->txr_comp = 0;
1698 
1699 		comp_count++;
1700 
1701 		if (txb->m_head) {
1702 			bus_dmamap_sync(ha->tx_tag, txb->map,
1703 				BUS_DMASYNC_POSTWRITE);
1704 			bus_dmamap_unload(ha->tx_tag, txb->map);
1705 			bus_dmamap_destroy(ha->tx_tag, txb->map);
1706 			m_freem(txb->m_head);
1707 
1708 			txb->map = (bus_dmamap_t)0;
1709 			txb->m_head = NULL;
1710 		}
1711 	}
1712 
1713 	hw->txr_free += comp_count;
1714 
1715        	QL_DPRINT8((ha->pci_dev, "%s: return [c,f, p, pn][%d, %d, %d, %d]\n", __func__,
1716 		hw->txr_comp, hw->txr_free, hw->txr_next, READ_REG32(ha, (ha->hw.tx_prod_reg + 0x1b2000))));
1717 
1718 	return;
1719 }
1720 
1721 /*
1722  * Name: qla_hw_tx_done
1723  * Function: Handle Transmit Completions
1724  */
1725 void
1726 qla_hw_tx_done(qla_host_t *ha)
1727 {
1728 	if (!mtx_trylock(&ha->tx_lock)) {
1729        		QL_DPRINT8((ha->pci_dev,
1730 			"%s: !mtx_trylock(&ha->tx_lock)\n", __func__));
1731 		return;
1732 	}
1733 	qla_hw_tx_done_locked(ha);
1734 
1735 	if (ha->hw.txr_free > free_pkt_thres)
1736 		ha->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1737 
1738 	mtx_unlock(&ha->tx_lock);
1739 	return;
1740 }
1741 
1742 void
1743 qla_update_link_state(qla_host_t *ha)
1744 {
1745 	uint32_t link_state;
1746 	uint32_t prev_link_state;
1747 
1748 	if (!(ha->ifp->if_drv_flags & IFF_DRV_RUNNING)) {
1749 		ha->hw.flags.link_up = 0;
1750 		return;
1751 	}
1752 	link_state = READ_REG32(ha, Q8_LINK_STATE);
1753 
1754 	prev_link_state =  ha->hw.flags.link_up;
1755 
1756 	if (ha->pci_func == 0)
1757 		ha->hw.flags.link_up = (((link_state & 0xF) == 1)? 1 : 0);
1758 	else
1759 		ha->hw.flags.link_up = ((((link_state >> 4)& 0xF) == 1)? 1 : 0);
1760 
1761 	if (prev_link_state !=  ha->hw.flags.link_up) {
1762 		if (ha->hw.flags.link_up) {
1763 			if_link_state_change(ha->ifp, LINK_STATE_UP);
1764 		} else {
1765 			if_link_state_change(ha->ifp, LINK_STATE_DOWN);
1766 		}
1767 	}
1768 }
1769 
1770 int
1771 qla_config_lro(qla_host_t *ha)
1772 {
1773 #if defined(INET) || defined(INET6)
1774 	int i;
1775         qla_hw_t *hw = &ha->hw;
1776 	struct lro_ctrl *lro;
1777 
1778 	for (i = 0; i < hw->num_sds_rings; i++) {
1779 		lro = &hw->sds[i].lro;
1780 		if (tcp_lro_init(lro)) {
1781 			device_printf(ha->pci_dev, "%s: tcp_lro_init failed\n",
1782 				__func__);
1783 			return (-1);
1784 		}
1785 		lro->ifp = ha->ifp;
1786 	}
1787 	ha->flags.lro_init = 1;
1788 
1789 	QL_DPRINT2((ha->pci_dev, "%s: LRO initialized\n", __func__));
1790 #endif
1791 	return (0);
1792 }
1793 
1794 void
1795 qla_free_lro(qla_host_t *ha)
1796 {
1797 #if defined(INET) || defined(INET6)
1798 	int i;
1799         qla_hw_t *hw = &ha->hw;
1800 	struct lro_ctrl *lro;
1801 
1802 	if (!ha->flags.lro_init)
1803 		return;
1804 
1805 	for (i = 0; i < hw->num_sds_rings; i++) {
1806 		lro = &hw->sds[i].lro;
1807 		tcp_lro_free(lro);
1808 	}
1809 	ha->flags.lro_init = 0;
1810 #endif
1811 }
1812 
1813 void
1814 qla_hw_stop_rcv(qla_host_t *ha)
1815 {
1816 	int i, done, count = 100;
1817 
1818 	while (count--) {
1819 		done = 1;
1820 		for (i = 0; i < ha->hw.num_sds_rings; i++) {
1821 			if (ha->hw.sds[i].rcv_active)
1822 				done = 0;
1823 		}
1824 		if (done)
1825 			break;
1826 		else
1827 			qla_mdelay(__func__, 10);
1828 	}
1829 }
1830