aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid C Somayajulu <davidcs@FreeBSD.org>2013-05-15 17:03:09 +0000
committerDavid C Somayajulu <davidcs@FreeBSD.org>2013-05-15 17:03:09 +0000
commitf10a77bb82dac2ecab9c2ccfa25a920eb77765ef (patch)
tree86503bbdad05dec2946b8f85430c49c6ac0e7028 /sys
parent2afea814ac977b45eca2d17e74f4e664df52d1fd (diff)
downloadsrc-f10a77bb82dac2ecab9c2ccfa25a920eb77765ef.tar.gz
src-f10a77bb82dac2ecab9c2ccfa25a920eb77765ef.zip
Add Qlogic 10Gigabit Ethernet & CNA Adapter Driver Version 3.10.10 for
QLogic 8300 Series Adapters Submitted by: David C Somayajulu (davidcs@freebsd.org) QLogic Corporation Approved by: George Neville-Neil (gnn@freebsd.org)
Notes
Notes: svn path=/head/; revision=250661
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/files.amd647
-rw-r--r--sys/dev/qlxgbe/README.txt102
-rw-r--r--sys/dev/qlxgbe/ql_dbg.c260
-rw-r--r--sys/dev/qlxgbe/ql_dbg.h98
-rw-r--r--sys/dev/qlxgbe/ql_def.h258
-rw-r--r--sys/dev/qlxgbe/ql_glbl.h95
-rw-r--r--sys/dev/qlxgbe/ql_hw.c2847
-rw-r--r--sys/dev/qlxgbe/ql_hw.h1588
-rw-r--r--sys/dev/qlxgbe/ql_inline.h187
-rw-r--r--sys/dev/qlxgbe/ql_ioctl.c246
-rw-r--r--sys/dev/qlxgbe/ql_ioctl.h136
-rw-r--r--sys/dev/qlxgbe/ql_isr.c889
-rw-r--r--sys/dev/qlxgbe/ql_misc.c1304
-rw-r--r--sys/dev/qlxgbe/ql_os.c1703
-rw-r--r--sys/dev/qlxgbe/ql_os.h170
-rw-r--r--sys/dev/qlxgbe/ql_reset.c1409
-rw-r--r--sys/dev/qlxgbe/ql_tmplt.h147
-rw-r--r--sys/dev/qlxgbe/ql_ver.h41
-rw-r--r--sys/modules/Makefile2
-rw-r--r--sys/modules/qlxgbe/Makefile50
20 files changed, 11539 insertions, 0 deletions
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index 2d6db7a9f486..fc5a04fc7be2 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -232,6 +232,13 @@ dev/qlxgb/qla_ioctl.c optional qlxgb pci
dev/qlxgb/qla_isr.c optional qlxgb pci
dev/qlxgb/qla_misc.c optional qlxgb pci
dev/qlxgb/qla_os.c optional qlxgb pci
+dev/qlxgbe/ql_dbg.c optional qlxgbe pci
+dev/qlxgbe/ql_hw.c optional qlxgbe pci
+dev/qlxgbe/ql_ioctl.c optional qlxgbe pci
+dev/qlxgbe/ql_isr.c optional qlxgbe pci
+dev/qlxgbe/ql_misc.c optional qlxgbe pci
+dev/qlxgbe/ql_os.c optional qlxgbe pci
+dev/qlxgbe/ql_reset.c optional qlxgbe pci
dev/sfxge/common/efx_bootcfg.c optional sfxge inet pci
dev/sfxge/common/efx_ev.c optional sfxge inet pci
dev/sfxge/common/efx_filter.c optional sfxge inet pci
diff --git a/sys/dev/qlxgbe/README.txt b/sys/dev/qlxgbe/README.txt
new file mode 100644
index 000000000000..9f1fcd45db74
--- /dev/null
+++ b/sys/dev/qlxgbe/README.txt
@@ -0,0 +1,102 @@
+# $FreeBSD$
+
+ README File
+ QLogic 8300 series Dual Port
+10 Gigabit Ethernet & CNA Adapter Driver for FreeBSD 9.x/10.x
+
+ QLogic Corporation.
+ All rights reserved.
+
+
+Table of Contents
+1. Package Contents
+2. OS Support
+3. Supported Features
+4. Using the Driver
+ 4.1 Installing the driver
+ 4.2 Removing the driver
+5. Driver Parameters
+6. Additional Notes
+7. Contacting Support
+
+1. Package Contents
+ * Documentation
+ - README (this document) version:1.0
+ - Release Notes Version:1.0
+ * Driver (if_qlxgbe.ko)
+ - FreeBSD 9.x/10.x
+ * Firmware: pre-flashed on QLogic adapter;
+
+2. OS Support
+
+The Qlogic 83xx 10Gigabit Ethernet/CNA driver is compatible with the
+following OS platforms:
+ * FreeBSD 9.x/10.x (64-bit) [Intel EM64T, AMD64]
+
+3. Supported Features
+10Gigabit Ethernet NIC/CNA driver supports following features
+
+* Large Segment Offload over TCP IPV4
+* Large Segment Offload over TCP IPV6
+* Receive Side scaling
+* TCP over IPv4 checksum offload
+* UDP over IPv4 checksum offload
+* IPV4 checksum offload
+* TCP over IPv6 checksum offload
+* UDP over IPv6 checksum offload
+* Jumbo frames
+* VLAN Tag
+
+
+4. Using the driver
+
+ 4.1 Installing the driver
+
+ - copy the driver file (if_qlxgbe.ko) into some directory (say qla_driver)
+ - cd <to qla_driver>
+ - kldload -v ./if_qlxgbe.ko
+
+ 4.2 Removing the driver
+
+ - kldunload if_qlxgbe
+
+5. Parameters to set prior to installing the driver
+
+ - Add the following lines to /etc/sysctl.conf and reboot the machine prior
+ to installing the driver
+
+ kern.ipc.nmbjumbo9=262144
+ net.inet.tcp.recvbuf_max=262144
+ net.inet.tcp.recvbuf_inc=16384
+ kern.ipc.nmbclusters=1000000
+ kern.ipc.maxsockbuf=2097152
+ net.inet.tcp.recvspace=131072
+ net.inet.tcp.sendbuf_max=262144
+ net.inet.tcp.sendspace=65536
+
+ - If you do not want to reboot the system please run the following commands
+
+ login or su to root
+
+ sysctl kern.ipc.nmbjumbo9=262144
+ sysctl net.inet.tcp.recvbuf_max=262144
+ sysctl net.inet.tcp.recvbuf_inc=16384
+ sysctl kern.ipc.nmbclusters=1000000
+ sysctl kern.ipc.maxsockbuf=2097152
+ sysctl net.inet.tcp.recvspace=131072
+ sysctl net.inet.tcp.sendbuf_max=262144
+ sysctl net.inet.tcp.sendspace=65536
+
+6. Compile options Makefile if building driver from sources
+ None
+
+7. Contacting Support
+Please feel free to contact your QLogic approved reseller or QLogic
+Technical Support at any phase of integration for assistance. QLogic
+Technical Support can be reached by the following methods:
+Web: http://support.qlogic.com
+E-mail: support@qlogic.com
+(c) Copyright 2013-14. All rights reserved worldwide. QLogic, the QLogic
+logo, and the Powered by QLogic logo are registered trademarks of
+QLogic Corporation. All other brand and product names are trademarks
+or registered trademarks of their respective owners.
diff --git a/sys/dev/qlxgbe/ql_dbg.c b/sys/dev/qlxgbe/ql_dbg.c
new file mode 100644
index 000000000000..867d5109874b
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_dbg.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * File : ql_dbg.c
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "ql_os.h"
+#include "ql_hw.h"
+#include "ql_def.h"
+#include "ql_inline.h"
+#include "ql_ver.h"
+#include "ql_glbl.h"
+#include "ql_dbg.h"
+
+/*
+ * Name: ql_dump_buf32
+ * Function: dumps a buffer as 32 bit words
+ */
+void ql_dump_buf32(qla_host_t *ha, const char *msg, void *dbuf32, uint32_t len32)
+{
+ device_t dev;
+ uint32_t i = 0;
+ uint32_t *buf;
+
+ dev = ha->pci_dev;
+ buf = dbuf32;
+
+ device_printf(dev, "%s: %s dump start\n", __func__, msg);
+
+ while (len32 >= 4) {
+ device_printf(dev,"0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ i, buf[0], buf[1], buf[2], buf[3]);
+ i += 4 * 4;
+ len32 -= 4;
+ buf += 4;
+ }
+ switch (len32) {
+ case 1:
+ device_printf(dev,"0x%08x: 0x%08x\n", i, buf[0]);
+ break;
+ case 2:
+ device_printf(dev,"0x%08x: 0x%08x 0x%08x\n", i, buf[0], buf[1]);
+ break;
+ case 3:
+ device_printf(dev,"0x%08x: 0x%08x 0x%08x 0x%08x\n",
+ i, buf[0], buf[1], buf[2]);
+ break;
+ default:
+ break;
+ }
+ device_printf(dev, "%s: %s dump end\n", __func__, msg);
+}
+
+/*
+ * Name: ql_dump_buf16
+ * Function: dumps a buffer as 16 bit words
+ */
+void ql_dump_buf16(qla_host_t *ha, const char *msg, void *dbuf16, uint32_t len16)
+{
+ device_t dev;
+ uint32_t i = 0;
+ uint16_t *buf;
+
+ dev = ha->pci_dev;
+ buf = dbuf16;
+
+ device_printf(dev, "%s: %s dump start\n", __func__, msg);
+
+ while (len16 >= 8) {
+ device_printf(dev,"0x%08x: 0x%04x 0x%04x 0x%04x 0x%04x"
+ " 0x%04x 0x%04x 0x%04x 0x%04x\n", i, buf[0],
+ buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+ i += 16;
+ len16 -= 8;
+ buf += 8;
+ }
+ switch (len16) {
+ case 1:
+ device_printf(dev,"0x%08x: 0x%04x\n", i, buf[0]);
+ break;
+ case 2:
+ device_printf(dev,"0x%08x: 0x%04x 0x%04x\n", i, buf[0], buf[1]);
+ break;
+ case 3:
+ device_printf(dev,"0x%08x: 0x%04x 0x%04x 0x%04x\n",
+ i, buf[0], buf[1], buf[2]);
+ break;
+ case 4:
+ device_printf(dev,"0x%08x: 0x%04x 0x%04x 0x%04x 0x%04x\n", i,
+ buf[0], buf[1], buf[2], buf[3]);
+ break;
+ case 5:
+ device_printf(dev,"0x%08x:"
+ " 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", i,
+ buf[0], buf[1], buf[2], buf[3], buf[4]);
+ break;
+ case 6:
+ device_printf(dev,"0x%08x:"
+ " 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", i,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+ break;
+ case 7:
+ device_printf(dev,"0x%04x: 0x%04x 0x%04x 0x%04x 0x%04x"
+ " 0x%04x 0x%04x 0x%04x\n", i, buf[0], buf[1],
+ buf[2], buf[3], buf[4], buf[5], buf[6]);
+ break;
+ default:
+ break;
+ }
+ device_printf(dev, "%s: %s dump end\n", __func__, msg);
+}
+
+/*
+ * Name: ql_dump_buf8
+ * Function: dumps a buffer as bytes
+ */
+void ql_dump_buf8(qla_host_t *ha, const char *msg, void *dbuf, uint32_t len)
+{
+ device_t dev;
+ uint32_t i = 0;
+ uint8_t *buf;
+
+ dev = ha->pci_dev;
+ buf = dbuf;
+
+ device_printf(dev, "%s: %s 0x%x dump start\n", __func__, msg, len);
+
+ while (len >= 16) {
+ device_printf(dev,"0x%08x:"
+ " %02x %02x %02x %02x %02x %02x %02x %02x"
+ " %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
+ buf[0], buf[1], buf[2], buf[3],
+ buf[4], buf[5], buf[6], buf[7],
+ buf[8], buf[9], buf[10], buf[11],
+ buf[12], buf[13], buf[14], buf[15]);
+ i += 16;
+ len -= 16;
+ buf += 16;
+ }
+ switch (len) {
+ case 1:
+ device_printf(dev,"0x%08x: %02x\n", i, buf[0]);
+ break;
+ case 2:
+ device_printf(dev,"0x%08x: %02x %02x\n", i, buf[0], buf[1]);
+ break;
+ case 3:
+ device_printf(dev,"0x%08x: %02x %02x %02x\n",
+ i, buf[0], buf[1], buf[2]);
+ break;
+ case 4:
+ device_printf(dev,"0x%08x: %02x %02x %02x %02x\n", i,
+ buf[0], buf[1], buf[2], buf[3]);
+ break;
+ case 5:
+ device_printf(dev,"0x%08x:"
+ " %02x %02x %02x %02x %02x\n", i,
+ buf[0], buf[1], buf[2], buf[3], buf[4]);
+ break;
+ case 6:
+ device_printf(dev,"0x%08x:"
+ " %02x %02x %02x %02x %02x %02x\n", i,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+ break;
+ case 7:
+ device_printf(dev,"0x%08x:"
+ " %02x %02x %02x %02x %02x %02x %02x\n", i,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
+ break;
+ case 8:
+ device_printf(dev,"0x%08x:"
+ " %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
+ buf[7]);
+ break;
+ case 9:
+ device_printf(dev,"0x%08x:"
+ " %02x %02x %02x %02x %02x %02x %02x %02x"
+ " %02x\n", i,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
+ buf[7], buf[8]);
+ break;
+ case 10:
+ device_printf(dev,"0x%08x:"
+ " %02x %02x %02x %02x %02x %02x %02x %02x"
+ " %02x %02x\n", i,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
+ buf[7], buf[8], buf[9]);
+ break;
+ case 11:
+ device_printf(dev,"0x%08x:"
+ " %02x %02x %02x %02x %02x %02x %02x %02x"
+ " %02x %02x %02x\n", i,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
+ buf[7], buf[8], buf[9], buf[10]);
+ break;
+ case 12:
+ device_printf(dev,"0x%08x:"
+ " %02x %02x %02x %02x %02x %02x %02x %02x"
+ " %02x %02x %02x %02x\n", i,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
+ buf[7], buf[8], buf[9], buf[10], buf[11]);
+ break;
+ case 13:
+ device_printf(dev,"0x%08x:"
+ " %02x %02x %02x %02x %02x %02x %02x %02x"
+ " %02x %02x %02x %02x %02x\n", i,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
+ buf[7], buf[8], buf[9], buf[10], buf[11], buf[12]);
+ break;
+ case 14:
+ device_printf(dev,"0x%08x:"
+ " %02x %02x %02x %02x %02x %02x %02x %02x"
+ " %02x %02x %02x %02x %02x %02x\n", i,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
+ buf[7], buf[8], buf[9], buf[10], buf[11], buf[12],
+ buf[13]);
+ break;
+ case 15:
+ device_printf(dev,"0x%08x:"
+ " %02x %02x %02x %02x %02x %02x %02x %02x"
+ " %02x %02x %02x %02x %02x %02x %02x\n", i,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
+ buf[7], buf[8], buf[9], buf[10], buf[11], buf[12],
+ buf[13], buf[14]);
+ break;
+ default:
+ break;
+ }
+
+ device_printf(dev, "%s: %s dump end\n", __func__, msg);
+}
+
diff --git a/sys/dev/qlxgbe/ql_dbg.h b/sys/dev/qlxgbe/ql_dbg.h
new file mode 100644
index 000000000000..29f77b9e4c10
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_dbg.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * File : ql_dbg.h
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ */
+
+#ifndef _QL_DBG_H_
+#define _QL_DBG_H_
+
+extern void ql_dump_buf8(qla_host_t *ha, const char *str, void *dbuf,
+ uint32_t len);
+extern void ql_dump_buf16(qla_host_t *ha, const char *str, void *dbuf,
+ uint32_t len16);
+extern void ql_dump_buf32(qla_host_t *ha, const char *str, void *dbuf,
+ uint32_t len32);
+
+#define INJCT_RX_RXB_INVAL 0x00001
+#define INJCT_RX_MP_NULL 0x00002
+#define INJCT_LRO_RXB_INVAL 0x00003
+#define INJCT_LRO_MP_NULL 0x00004
+#define INJCT_NUM_HNDLE_INVALID 0x00005
+#define INJCT_RDWR_INDREG_FAILURE 0x00006
+#define INJCT_RDWR_OFFCHIPMEM_FAILURE 0x00007
+#define INJCT_MBX_CMD_FAILURE 0x00008
+#define INJCT_HEARTBEAT_FAILURE 0x00009
+#define INJCT_TEMPERATURE_FAILURE 0x0000A
+
+#ifdef QL_DBG
+
+#define QL_DPRINT1(ha, x) if (ha->dbg_level & 0x0001) device_printf x
+#define QL_DPRINT2(ha, x) if (ha->dbg_level & 0x0002) device_printf x
+#define QL_DPRINT4(ha, x) if (ha->dbg_level & 0x0004) device_printf x
+#define QL_DPRINT8(ha, x) if (ha->dbg_level & 0x0008) device_printf x
+#define QL_DPRINT10(ha, x) if (ha->dbg_level & 0x0010) device_printf x
+#define QL_DPRINT20(ha, x) if (ha->dbg_level & 0x0020) device_printf x
+#define QL_DPRINT40(ha, x) if (ha->dbg_level & 0x0040) device_printf x
+#define QL_DPRINT80(ha, x) if (ha->dbg_level & 0x0080) device_printf x
+
+#define QL_DUMP_BUFFER8(h, s, b, n) if (h->dbg_level & 0x08000000)\
+ qla_dump_buf8(h, s, b, n)
+#define QL_DUMP_BUFFER16(h, s, b, n) if (h->dbg_level & 0x08000000)\
+ qla_dump_buf16(h, s, b, n)
+#define QL_DUMP_BUFFER32(h, s, b, n) if (h->dbg_level & 0x08000000)\
+ qla_dump_buf32(h, s, b, n)
+
+#define QL_ASSERT(ha, x, y) if (!x && !ha->err_inject) panic y
+#define QL_ERR_INJECT(ha, val) (ha->err_inject == val)
+
+#else
+
+#define QL_DPRINT1(ha, x)
+#define QL_DPRINT2(ha, x)
+#define QL_DPRINT4(ha, x)
+#define QL_DPRINT8(ha, x)
+#define QL_DPRINT10(ha, x)
+#define QL_DPRINT20(ha, x)
+#define QL_DPRINT40(ha, x)
+#define QL_DPRINT80(ha, x)
+
+#define QL_DUMP_BUFFER8(h, s, b, n)
+#define QL_DUMP_BUFFER16(h, s, b, n)
+#define QL_DUMP_BUFFER32(h, s, b, n)
+
+#define QL_ASSERT(ha, x, y)
+#define QL_ERR_INJECT(ha, val) 0
+
+#endif
+
+
+#endif /* #ifndef _QL_DBG_H_ */
diff --git a/sys/dev/qlxgbe/ql_def.h b/sys/dev/qlxgbe/ql_def.h
new file mode 100644
index 000000000000..f93036731c30
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_def.h
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * File: ql_def.h
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ */
+
+#ifndef _QL_DEF_H_
+#define _QL_DEF_H_
+
+#define BIT_0 (0x1 << 0)
+#define BIT_1 (0x1 << 1)
+#define BIT_2 (0x1 << 2)
+#define BIT_3 (0x1 << 3)
+#define BIT_4 (0x1 << 4)
+#define BIT_5 (0x1 << 5)
+#define BIT_6 (0x1 << 6)
+#define BIT_7 (0x1 << 7)
+#define BIT_8 (0x1 << 8)
+#define BIT_9 (0x1 << 9)
+#define BIT_10 (0x1 << 10)
+#define BIT_11 (0x1 << 11)
+#define BIT_12 (0x1 << 12)
+#define BIT_13 (0x1 << 13)
+#define BIT_14 (0x1 << 14)
+#define BIT_15 (0x1 << 15)
+#define BIT_16 (0x1 << 16)
+#define BIT_17 (0x1 << 17)
+#define BIT_18 (0x1 << 18)
+#define BIT_19 (0x1 << 19)
+#define BIT_20 (0x1 << 20)
+#define BIT_21 (0x1 << 21)
+#define BIT_22 (0x1 << 22)
+#define BIT_23 (0x1 << 23)
+#define BIT_24 (0x1 << 24)
+#define BIT_25 (0x1 << 25)
+#define BIT_26 (0x1 << 26)
+#define BIT_27 (0x1 << 27)
+#define BIT_28 (0x1 << 28)
+#define BIT_29 (0x1 << 29)
+#define BIT_30 (0x1 << 30)
+#define BIT_31 (0x1 << 31)
+
+struct qla_rx_buf {
+ struct mbuf *m_head;
+ bus_dmamap_t map;
+ bus_addr_t paddr;
+ uint32_t handle;
+ void *next;
+};
+typedef struct qla_rx_buf qla_rx_buf_t;
+
+struct qla_rx_ring {
+ qla_rx_buf_t rx_buf[NUM_RX_DESCRIPTORS];
+};
+typedef struct qla_rx_ring qla_rx_ring_t;
+
+struct qla_tx_buf {
+ struct mbuf *m_head;
+ bus_dmamap_t map;
+};
+typedef struct qla_tx_buf qla_tx_buf_t;
+
+#define QLA_MAX_SEGMENTS 62 /* maximum # of segs in a sg list */
+#define QLA_MAX_MTU 9000
+#define QLA_STD_FRAME_SIZE 1514
+#define QLA_MAX_TSO_FRAME_SIZE ((64 * 1024 - 1) + 22)
+
+/* Number of MSIX/MSI Vectors required */
+
+struct qla_ivec {
+ uint32_t sds_idx;
+ void *ha;
+ struct resource *irq;
+ void *handle;
+ int irq_rid;
+};
+
+typedef struct qla_ivec qla_ivec_t;
+
+#define QLA_WATCHDOG_CALLOUT_TICKS 1
+
+typedef struct _qla_tx_ring {
+ qla_tx_buf_t tx_buf[NUM_TX_DESCRIPTORS];
+ uint64_t count;
+} qla_tx_ring_t;
+
+/*
+ * Adapter structure contains the hardware independant information of the
+ * pci function.
+ */
+struct qla_host {
+ volatile struct {
+ volatile uint32_t
+ qla_callout_init :1,
+ qla_watchdog_active :1,
+ qla_watchdog_exit :1,
+ qla_watchdog_pause :1,
+ lro_init :1,
+ stop_rcv :1,
+ parent_tag :1,
+ lock_init :1;
+ } flags;
+
+ volatile uint32_t qla_watchdog_exited;
+ volatile uint32_t qla_watchdog_paused;
+ volatile uint32_t qla_initiate_recovery;
+
+ device_t pci_dev;
+
+ uint16_t watchdog_ticks;
+ uint8_t pci_func;
+ uint8_t resvd;
+
+ /* ioctl related */
+ struct cdev *ioctl_dev;
+
+ /* register mapping */
+ struct resource *pci_reg;
+ int reg_rid;
+ struct resource *pci_reg1;
+ int reg_rid1;
+
+ /* interrupts */
+ struct resource *mbx_irq;
+ void *mbx_handle;
+ int mbx_irq_rid;
+
+ int msix_count;
+
+ qla_ivec_t irq_vec[MAX_SDS_RINGS];
+
+ /* parent dma tag */
+ bus_dma_tag_t parent_tag;
+
+ /* interface to o.s */
+ struct ifnet *ifp;
+
+ struct ifmedia media;
+ uint16_t max_frame_size;
+ uint16_t rsrvd0;
+ int if_flags;
+
+ /* hardware access lock */
+
+ struct mtx hw_lock;
+ volatile uint32_t hw_lock_held;
+
+ /* transmit and receive buffers */
+ uint32_t txr_idx; /* index of the current tx ring */
+ qla_tx_ring_t tx_ring[NUM_TX_RINGS];
+
+ bus_dma_tag_t tx_tag;
+ struct task tx_task;
+ struct taskqueue *tx_tq;
+ struct callout tx_callout;
+ struct mtx tx_lock;
+
+ qla_rx_ring_t rx_ring[MAX_RDS_RINGS];
+ bus_dma_tag_t rx_tag;
+ uint32_t std_replenish;
+
+ qla_rx_buf_t *rxb_free;
+ uint32_t rxb_free_count;
+ volatile uint32_t posting;
+
+ /* stats */
+ uint32_t err_m_getcl;
+ uint32_t err_m_getjcl;
+ uint32_t err_tx_dmamap_create;
+ uint32_t err_tx_dmamap_load;
+ uint32_t err_tx_defrag;
+
+ uint64_t rx_frames;
+ uint64_t rx_bytes;
+
+ uint64_t lro_pkt_count;
+ uint64_t lro_bytes;
+
+ uint64_t ipv4_lro;
+ uint64_t ipv6_lro;
+
+ uint64_t tx_frames;
+ uint64_t tx_bytes;
+ uint64_t tx_tso_frames;
+ uint64_t hw_vlan_tx_frames;
+
+ uint32_t fw_ver_major;
+ uint32_t fw_ver_minor;
+ uint32_t fw_ver_sub;
+ uint32_t fw_ver_build;
+
+ /* hardware specific */
+ qla_hw_t hw;
+
+ /* debug stuff */
+ volatile const char *qla_lock;
+ volatile const char *qla_unlock;
+ uint32_t dbg_level;
+
+ uint8_t fw_ver_str[32];
+
+ /* Error Injection Related */
+ uint32_t err_inject;
+ struct task err_task;
+ struct taskqueue *err_tq;
+
+ /* Peer Device */
+ device_t peer_dev;
+
+ volatile uint32_t msg_from_peer;
+#define QL_PEER_MSG_RESET 0x01
+#define QL_PEER_MSG_ACK 0x02
+
+};
+typedef struct qla_host qla_host_t;
+
+/* note that align has to be a power of 2 */
+#define QL_ALIGN(size, align) (size + (align - 1)) & ~(align - 1);
+#define QL_MIN(x, y) ((x < y) ? x : y)
+
+#define QL_RUNNING(ifp) \
+ ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) == \
+ IFF_DRV_RUNNING)
+
+/* Return 0, if identical, else 1 */
+#define QL_MAC_CMP(mac1, mac2) \
+ ((((*(uint32_t *) mac1) == (*(uint32_t *) mac2) && \
+ (*(uint16_t *)(mac1 + 4)) == (*(uint16_t *)(mac2 + 4)))) ? 0 : 1)
+
+#endif /* #ifndef _QL_DEF_H_ */
diff --git a/sys/dev/qlxgbe/ql_glbl.h b/sys/dev/qlxgbe/ql_glbl.h
new file mode 100644
index 000000000000..3ccb6624337e
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_glbl.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/*
+ * File: ql_glbl.h
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ * Content: Contains prototypes of the exported functions from each file.
+ */
+#ifndef _QL_GLBL_H_
+#define _QL_GLBL_H_
+
+/*
+ * from ql_isr.c
+ */
+extern void ql_mbx_isr(void *arg);
+extern void ql_isr(void *arg);
+
+/*
+ * from ql_os.c
+ */
+extern int ql_alloc_dmabuf(qla_host_t *ha, qla_dma_t *dma_buf);
+extern void ql_free_dmabuf(qla_host_t *ha, qla_dma_t *dma_buf);
+extern int ql_get_mbuf(qla_host_t *ha, qla_rx_buf_t *rxb, struct mbuf *nmp);
+
+/*
+ * from ql_hw.c
+ */
+extern int ql_alloc_dma(qla_host_t *ha);
+extern void ql_free_dma(qla_host_t *ha);
+extern void ql_hw_add_sysctls(qla_host_t *ha);
+extern int ql_hw_send(qla_host_t *ha, bus_dma_segment_t *segs, int nsegs,
+ uint32_t tx_idx, struct mbuf *mp, uint32_t txr_idx);
+extern int ql_init_hw_if(qla_host_t *ha);
+extern int ql_hw_set_multi(qla_host_t *ha, uint8_t *mta, uint32_t mcnt,
+ uint32_t add_multi);
+extern void ql_del_hw_if(qla_host_t *ha);
+extern int ql_set_promisc(qla_host_t *ha);
+extern int ql_set_allmulti(qla_host_t *ha);
+extern void ql_update_link_state(qla_host_t *ha);
+extern void ql_hw_tx_done(qla_host_t *ha);
+extern int ql_set_max_mtu(qla_host_t *ha, uint32_t mtu, uint16_t cntxt_id);
+extern void ql_hw_stop_rcv(qla_host_t *ha);
+extern void ql_get_stats(qla_host_t *ha);
+extern void ql_hw_link_status(qla_host_t *ha);
+extern int ql_hw_check_health(qla_host_t *ha);
+extern void ql_minidump(qla_host_t *ha);
+
+/*
+ * from ql_misc.c
+ */
+extern int ql_init_hw(qla_host_t *ha);
+extern int ql_rdwr_indreg32(qla_host_t *ha, uint32_t addr, uint32_t *val,
+ uint32_t rd);
+extern int ql_rd_flash32(qla_host_t *ha, uint32_t addr, uint32_t *data);
+extern int ql_rdwr_offchip_mem(qla_host_t *ha, uint64_t addr,
+ q80_offchip_mem_val_t *val, uint32_t rd);
+extern void ql_read_mac_addr(qla_host_t *ha);
+extern int ql_erase_flash(qla_host_t *ha, uint32_t off, uint32_t size);
+extern int ql_wr_flash_buffer(qla_host_t *ha, uint32_t off, uint32_t size,
+ void *buf);
+extern int ql_stop_sequence(qla_host_t *ha);
+extern int ql_start_sequence(qla_host_t *ha, uint16_t index);
+
+/*
+ * from ql_ioctl.c
+ */
+extern int ql_make_cdev(qla_host_t *ha);
+extern void ql_del_cdev(qla_host_t *ha);
+
+#endif /* #ifndef_QL_GLBL_H_ */
diff --git a/sys/dev/qlxgbe/ql_hw.c b/sys/dev/qlxgbe/ql_hw.c
new file mode 100644
index 000000000000..1a6e7040c3b3
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_hw.c
@@ -0,0 +1,2847 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * File: ql_hw.c
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ * Content: Contains Hardware dependant functions
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "ql_os.h"
+#include "ql_hw.h"
+#include "ql_def.h"
+#include "ql_inline.h"
+#include "ql_ver.h"
+#include "ql_glbl.h"
+#include "ql_dbg.h"
+
+/*
+ * Static Functions
+ */
+
+static void qla_del_rcv_cntxt(qla_host_t *ha);
+static int qla_init_rcv_cntxt(qla_host_t *ha);
+static void qla_del_xmt_cntxt(qla_host_t *ha);
+static int qla_init_xmt_cntxt(qla_host_t *ha);
+static void qla_hw_tx_done_locked(qla_host_t *ha, uint32_t txr_idx);
+static int qla_mbx_cmd(qla_host_t *ha, uint32_t *h_mbox, uint32_t n_hmbox,
+ uint32_t *fw_mbox, uint32_t n_fwmbox, uint32_t no_pause);
+static int qla_config_intr_cntxt(qla_host_t *ha, uint32_t num_intrs,
+ uint32_t create);
+static int qla_get_nic_partition(qla_host_t *ha);
+static int qla_config_rss(qla_host_t *ha, uint16_t cntxt_id);
+static int qla_config_intr_coalesce(qla_host_t *ha, uint16_t cntxt_id,
+ int tenable);
+static int qla_set_mac_rcv_mode(qla_host_t *ha, uint32_t mode);
+static int qla_link_event_req(qla_host_t *ha, uint16_t cntxt_id);
+
+static int qla_tx_tso(qla_host_t *ha, struct mbuf *mp, q80_tx_cmd_t *tx_cmd,
+ uint8_t *hdr);
+static int qla_hw_add_all_mcast(qla_host_t *ha);
+static int qla_hw_del_all_mcast(qla_host_t *ha);
+static int qla_add_rcv_rings(qla_host_t *ha, uint32_t sds_idx);
+
+static int qla_minidump_init(qla_host_t *ha);
+static void qla_minidump_free(qla_host_t *ha);
+
+
+static int
+qla_sysctl_get_drvr_stats(SYSCTL_HANDLER_ARGS)
+{
+ int err = 0, ret;
+ qla_host_t *ha;
+ uint32_t i;
+
+ err = sysctl_handle_int(oidp, &ret, 0, req);
+
+ if (err || !req->newptr)
+ return (err);
+
+ if (ret == 1) {
+
+ ha = (qla_host_t *)arg1;
+
+ for (i = 0; i < ha->hw.num_sds_rings; i++)
+ device_printf(ha->pci_dev,
+ "%s: sds_ring[%d] = %p\n", __func__,i,
+ (void *)ha->hw.sds[i].intr_count);
+
+ for (i = 0; i < ha->hw.num_tx_rings; i++)
+ device_printf(ha->pci_dev,
+ "%s: tx[%d] = %p\n", __func__,i,
+ (void *)ha->tx_ring[i].count);
+
+ for (i = 0; i < ha->hw.num_rds_rings; i++)
+ device_printf(ha->pci_dev,
+ "%s: rds_ring[%d] = %p\n", __func__,i,
+ (void *)ha->hw.rds[i].count);
+
+ device_printf(ha->pci_dev, "%s: lro_pkt_count = %p\n", __func__,
+ (void *)ha->lro_pkt_count);
+
+ device_printf(ha->pci_dev, "%s: lro_bytes = %p\n", __func__,
+ (void *)ha->lro_bytes);
+ }
+ return (err);
+}
+
+#ifdef QL_DBG
+
+static void
+qla_stop_pegs(qla_host_t *ha)
+{
+ uint32_t val = 1;
+
+ ql_rdwr_indreg32(ha, Q8_CRB_PEG_0, &val, 0);
+ ql_rdwr_indreg32(ha, Q8_CRB_PEG_1, &val, 0);
+ ql_rdwr_indreg32(ha, Q8_CRB_PEG_2, &val, 0);
+ ql_rdwr_indreg32(ha, Q8_CRB_PEG_3, &val, 0);
+ ql_rdwr_indreg32(ha, Q8_CRB_PEG_4, &val, 0);
+ device_printf(ha->pci_dev, "%s PEGS HALTED!!!!!\n", __func__);
+}
+
+static int
+qla_sysctl_stop_pegs(SYSCTL_HANDLER_ARGS)
+{
+ int err, ret = 0;
+ qla_host_t *ha;
+
+ err = sysctl_handle_int(oidp, &ret, 0, req);
+
+
+ if (err || !req->newptr)
+ return (err);
+
+ if (ret == 1) {
+ ha = (qla_host_t *)arg1;
+ (void)QLA_LOCK(ha, __func__, 0);
+ qla_stop_pegs(ha);
+ QLA_UNLOCK(ha, __func__);
+ }
+
+ return err;
+}
+#endif /* #ifdef QL_DBG */
+
+/*
+ * Name: ql_hw_add_sysctls
+ * Function: Add P3Plus specific sysctls
+ */
+void
+ql_hw_add_sysctls(qla_host_t *ha)
+{
+ device_t dev;
+
+ dev = ha->pci_dev;
+
+ ha->hw.num_sds_rings = MAX_SDS_RINGS;
+ ha->hw.num_rds_rings = MAX_RDS_RINGS;
+ ha->hw.num_tx_rings = NUM_TX_RINGS;
+
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "num_rds_rings", CTLFLAG_RD, &ha->hw.num_rds_rings,
+ ha->hw.num_rds_rings, "Number of Rcv Descriptor Rings");
+
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "num_sds_rings", CTLFLAG_RD, &ha->hw.num_sds_rings,
+ ha->hw.num_sds_rings, "Number of Status Descriptor Rings");
+
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "num_tx_rings", CTLFLAG_RD, &ha->hw.num_tx_rings,
+ ha->hw.num_tx_rings, "Number of Transmit Rings");
+
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "tx_ring_index", CTLFLAG_RW, &ha->txr_idx,
+ ha->txr_idx, "Tx Ring Used");
+
+ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "drvr_stats", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)ha, 0,
+ qla_sysctl_get_drvr_stats, "I", "Driver Maintained Statistics");
+
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "max_tx_segs", CTLFLAG_RD, &ha->hw.max_tx_segs,
+ ha->hw.max_tx_segs, "Max # of Segments in a non-TSO pkt");
+
+ ha->hw.sds_cidx_thres = 32;
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "sds_cidx_thres", CTLFLAG_RW, &ha->hw.sds_cidx_thres,
+ ha->hw.sds_cidx_thres,
+ "Number of SDS entries to process before updating"
+ " SDS Ring Consumer Index");
+
+ ha->hw.rds_pidx_thres = 32;
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "rds_pidx_thres", CTLFLAG_RW, &ha->hw.rds_pidx_thres,
+ ha->hw.rds_pidx_thres,
+ "Number of Rcv Rings Entries to post before updating"
+ " RDS Ring Producer Index");
+
+ ha->hw.mdump_active = 0;
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "minidump_active", CTLFLAG_RW, &ha->hw.mdump_active,
+ ha->hw.mdump_active,
+ "Minidump Utility is Active \n"
+ "\t 0 = Minidump Utility is not active\n"
+ "\t 1 = Minidump Utility is retrieved on this port\n"
+ "\t 2 = Minidump Utility is retrieved on the other port\n");
+
+ ha->hw.mdump_start = 0;
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "minidump_start", CTLFLAG_RW,
+ &ha->hw.mdump_start, ha->hw.mdump_start,
+ "Minidump Utility can start minidump process");
+#ifdef QL_DBG
+
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "err_inject",
+ CTLFLAG_RW, &ha->err_inject, ha->err_inject,
+ "Error to be injected\n"
+ "\t\t\t 0: No Errors\n"
+ "\t\t\t 1: rcv: rxb struct invalid\n"
+ "\t\t\t 2: rcv: mp == NULL\n"
+ "\t\t\t 3: lro: rxb struct invalid\n"
+ "\t\t\t 4: lro: mp == NULL\n"
+ "\t\t\t 5: rcv: num handles invalid\n"
+ "\t\t\t 6: reg: indirect reg rd_wr failure\n"
+ "\t\t\t 7: ocm: offchip memory rd_wr failure\n"
+ "\t\t\t 8: mbx: mailbox command failure\n"
+ "\t\t\t 9: heartbeat failure\n"
+ "\t\t\t A: temperature failure\n" );
+
+ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "peg_stop", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)ha, 0,
+ qla_sysctl_stop_pegs, "I", "Peg Stop");
+
+#endif /* #ifdef QL_DBG */
+
+}
+
+void
+ql_hw_link_status(qla_host_t *ha)
+{
+ device_printf(ha->pci_dev, "cable_oui\t\t 0x%08x\n", ha->hw.cable_oui);
+
+ if (ha->hw.link_up) {
+ device_printf(ha->pci_dev, "link Up\n");
+ } else {
+ device_printf(ha->pci_dev, "link Down\n");
+ }
+
+ if (ha->hw.flags.fduplex) {
+ device_printf(ha->pci_dev, "Full Duplex\n");
+ } else {
+ device_printf(ha->pci_dev, "Half Duplex\n");
+ }
+
+ if (ha->hw.flags.autoneg) {
+ device_printf(ha->pci_dev, "Auto Negotiation Enabled\n");
+ } else {
+ device_printf(ha->pci_dev, "Auto Negotiation Disabled\n");
+ }
+
+ switch (ha->hw.link_speed) {
+ case 0x710:
+ device_printf(ha->pci_dev, "link speed\t\t 10Gps\n");
+ break;
+
+ case 0x3E8:
+ device_printf(ha->pci_dev, "link speed\t\t 1Gps\n");
+ break;
+
+ case 0x64:
+ device_printf(ha->pci_dev, "link speed\t\t 100Mbps\n");
+ break;
+
+ default:
+ device_printf(ha->pci_dev, "link speed\t\t Unknown\n");
+ break;
+ }
+
+ switch (ha->hw.module_type) {
+
+ case 0x01:
+ device_printf(ha->pci_dev, "Module Type 10GBase-LRM\n");
+ break;
+
+ case 0x02:
+ device_printf(ha->pci_dev, "Module Type 10GBase-LR\n");
+ break;
+
+ case 0x03:
+ device_printf(ha->pci_dev, "Module Type 10GBase-SR\n");
+ break;
+
+ case 0x04:
+ device_printf(ha->pci_dev,
+ "Module Type 10GE Passive Copper(Compliant)[%d m]\n",
+ ha->hw.cable_length);
+ break;
+
+ case 0x05:
+ device_printf(ha->pci_dev, "Module Type 10GE Active"
+ " Limiting Copper(Compliant)[%d m]\n",
+ ha->hw.cable_length);
+ break;
+
+ case 0x06:
+ device_printf(ha->pci_dev,
+ "Module Type 10GE Passive Copper"
+ " (Legacy, Best Effort)[%d m]\n",
+ ha->hw.cable_length);
+ break;
+
+ case 0x07:
+ device_printf(ha->pci_dev, "Module Type 1000Base-SX\n");
+ break;
+
+ case 0x08:
+ device_printf(ha->pci_dev, "Module Type 1000Base-LX\n");
+ break;
+
+ case 0x09:
+ device_printf(ha->pci_dev, "Module Type 1000Base-CX\n");
+ break;
+
+ case 0x0A:
+ device_printf(ha->pci_dev, "Module Type 1000Base-T\n");
+ break;
+
+ case 0x0B:
+ device_printf(ha->pci_dev, "Module Type 1GE Passive Copper"
+ "(Legacy, Best Effort)\n");
+ break;
+
+ default:
+ device_printf(ha->pci_dev, "Unknown Module Type 0x%x\n",
+ ha->hw.module_type);
+ break;
+ }
+
+ if (ha->hw.link_faults == 1)
+ device_printf(ha->pci_dev, "SFP Power Fault\n");
+}
+
+/*
+ * Name: ql_free_dma
+ * Function: Frees the DMA'able memory allocated in ql_alloc_dma()
+ */
+void
+ql_free_dma(qla_host_t *ha)
+{
+ uint32_t i;
+
+ if (ha->hw.dma_buf.flags.sds_ring) {
+ for (i = 0; i < ha->hw.num_sds_rings; i++) {
+ ql_free_dmabuf(ha, &ha->hw.dma_buf.sds_ring[i]);
+ }
+ ha->hw.dma_buf.flags.sds_ring = 0;
+ }
+
+ if (ha->hw.dma_buf.flags.rds_ring) {
+ for (i = 0; i < ha->hw.num_rds_rings; i++) {
+ ql_free_dmabuf(ha, &ha->hw.dma_buf.rds_ring[i]);
+ }
+ ha->hw.dma_buf.flags.rds_ring = 0;
+ }
+
+ if (ha->hw.dma_buf.flags.tx_ring) {
+ ql_free_dmabuf(ha, &ha->hw.dma_buf.tx_ring);
+ ha->hw.dma_buf.flags.tx_ring = 0;
+ }
+ qla_minidump_free(ha);
+}
+
+/*
+ * Name: ql_alloc_dma
+ * Function: Allocates DMA'able memory for Tx/Rx Rings, Tx/Rx Contexts.
+ */
+int
+ql_alloc_dma(qla_host_t *ha)
+{
+ device_t dev;
+ uint32_t i, j, size, tx_ring_size;
+ qla_hw_t *hw;
+ qla_hw_tx_cntxt_t *tx_cntxt;
+ uint8_t *vaddr;
+ bus_addr_t paddr;
+
+ dev = ha->pci_dev;
+
+ QL_DPRINT2(ha, (dev, "%s: enter\n", __func__));
+
+ hw = &ha->hw;
+ /*
+ * Allocate Transmit Ring
+ */
+ tx_ring_size = (sizeof(q80_tx_cmd_t) * NUM_TX_DESCRIPTORS);
+ size = (tx_ring_size * ha->hw.num_tx_rings);
+
+ hw->dma_buf.tx_ring.alignment = 8;
+ hw->dma_buf.tx_ring.size = size + PAGE_SIZE;
+
+ if (ql_alloc_dmabuf(ha, &hw->dma_buf.tx_ring)) {
+ device_printf(dev, "%s: tx ring alloc failed\n", __func__);
+ goto ql_alloc_dma_exit;
+ }
+
+ vaddr = (uint8_t *)hw->dma_buf.tx_ring.dma_b;
+ paddr = hw->dma_buf.tx_ring.dma_addr;
+
+ for (i = 0; i < ha->hw.num_tx_rings; i++) {
+ tx_cntxt = (qla_hw_tx_cntxt_t *)&hw->tx_cntxt[i];
+
+ tx_cntxt->tx_ring_base = (q80_tx_cmd_t *)vaddr;
+ tx_cntxt->tx_ring_paddr = paddr;
+
+ vaddr += tx_ring_size;
+ paddr += tx_ring_size;
+ }
+
+ for (i = 0; i < ha->hw.num_tx_rings; i++) {
+ tx_cntxt = (qla_hw_tx_cntxt_t *)&hw->tx_cntxt[i];
+
+ tx_cntxt->tx_cons = (uint32_t *)vaddr;
+ tx_cntxt->tx_cons_paddr = paddr;
+
+ vaddr += sizeof (uint32_t);
+ paddr += sizeof (uint32_t);
+ }
+
+ ha->hw.dma_buf.flags.tx_ring = 1;
+
+ QL_DPRINT2(ha, (dev, "%s: tx_ring phys %p virt %p\n",
+ __func__, (void *)(hw->dma_buf.tx_ring.dma_addr),
+ hw->dma_buf.tx_ring.dma_b));
+ /*
+ * Allocate Receive Descriptor Rings
+ */
+
+ for (i = 0; i < hw->num_rds_rings; i++) {
+
+ hw->dma_buf.rds_ring[i].alignment = 8;
+ hw->dma_buf.rds_ring[i].size =
+ (sizeof(q80_recv_desc_t)) * NUM_RX_DESCRIPTORS;
+
+ if (ql_alloc_dmabuf(ha, &hw->dma_buf.rds_ring[i])) {
+ device_printf(dev, "%s: rds ring[%d] alloc failed\n",
+ __func__, i);
+
+ for (j = 0; j < i; j++)
+ ql_free_dmabuf(ha, &hw->dma_buf.rds_ring[j]);
+
+ goto ql_alloc_dma_exit;
+ }
+ QL_DPRINT4(ha, (dev, "%s: rx_ring[%d] phys %p virt %p\n",
+ __func__, i, (void *)(hw->dma_buf.rds_ring[i].dma_addr),
+ hw->dma_buf.rds_ring[i].dma_b));
+ }
+
+ hw->dma_buf.flags.rds_ring = 1;
+
+ /*
+ * Allocate Status Descriptor Rings
+ */
+
+ for (i = 0; i < hw->num_sds_rings; i++) {
+ hw->dma_buf.sds_ring[i].alignment = 8;
+ hw->dma_buf.sds_ring[i].size =
+ (sizeof(q80_stat_desc_t)) * NUM_STATUS_DESCRIPTORS;
+
+ if (ql_alloc_dmabuf(ha, &hw->dma_buf.sds_ring[i])) {
+ device_printf(dev, "%s: sds ring alloc failed\n",
+ __func__);
+
+ for (j = 0; j < i; j++)
+ ql_free_dmabuf(ha, &hw->dma_buf.sds_ring[j]);
+
+ goto ql_alloc_dma_exit;
+ }
+ QL_DPRINT4(ha, (dev, "%s: sds_ring[%d] phys %p virt %p\n",
+ __func__, i,
+ (void *)(hw->dma_buf.sds_ring[i].dma_addr),
+ hw->dma_buf.sds_ring[i].dma_b));
+ }
+ for (i = 0; i < hw->num_sds_rings; i++) {
+ hw->sds[i].sds_ring_base =
+ (q80_stat_desc_t *)hw->dma_buf.sds_ring[i].dma_b;
+ }
+
+ hw->dma_buf.flags.sds_ring = 1;
+
+ return 0;
+
+ql_alloc_dma_exit:
+ ql_free_dma(ha);
+ return -1;
+}
+
+#define Q8_MBX_MSEC_DELAY 5000
+
+static int
+qla_mbx_cmd(qla_host_t *ha, uint32_t *h_mbox, uint32_t n_hmbox,
+ uint32_t *fw_mbox, uint32_t n_fwmbox, uint32_t no_pause)
+{
+ uint32_t i;
+ uint32_t data;
+ int ret = 0;
+
+ if (QL_ERR_INJECT(ha, INJCT_MBX_CMD_FAILURE)) {
+ ret = -3;
+ ha->qla_initiate_recovery = 1;
+ goto exit_qla_mbx_cmd;
+ }
+
+ if (no_pause)
+ i = 1000;
+ else
+ i = Q8_MBX_MSEC_DELAY;
+
+ while (i) {
+ data = READ_REG32(ha, Q8_HOST_MBOX_CNTRL);
+ if (data == 0)
+ break;
+ if (no_pause) {
+ DELAY(1000);
+ } else {
+ qla_mdelay(__func__, 1);
+ }
+ i--;
+ }
+
+ if (i == 0) {
+ device_printf(ha->pci_dev, "%s: host_mbx_cntrl 0x%08x\n",
+ __func__, data);
+ ret = -1;
+ ha->qla_initiate_recovery = 1;
+ goto exit_qla_mbx_cmd;
+ }
+
+ for (i = 0; i < n_hmbox; i++) {
+ WRITE_REG32(ha, (Q8_HOST_MBOX0 + (i << 2)), *h_mbox);
+ h_mbox++;
+ }
+
+ WRITE_REG32(ha, Q8_HOST_MBOX_CNTRL, 0x1);
+
+
+ i = Q8_MBX_MSEC_DELAY;
+ while (i) {
+ data = READ_REG32(ha, Q8_FW_MBOX_CNTRL);
+
+ if ((data & 0x3) == 1) {
+ data = READ_REG32(ha, Q8_FW_MBOX0);
+ if ((data & 0xF000) != 0x8000)
+ break;
+ }
+ if (no_pause) {
+ DELAY(1000);
+ } else {
+ qla_mdelay(__func__, 1);
+ }
+ i--;
+ }
+ if (i == 0) {
+ device_printf(ha->pci_dev, "%s: fw_mbx_cntrl 0x%08x\n",
+ __func__, data);
+ ret = -2;
+ ha->qla_initiate_recovery = 1;
+ goto exit_qla_mbx_cmd;
+ }
+
+ for (i = 0; i < n_fwmbox; i++) {
+ *fw_mbox++ = READ_REG32(ha, (Q8_FW_MBOX0 + (i << 2)));
+ }
+
+ WRITE_REG32(ha, Q8_FW_MBOX_CNTRL, 0x0);
+ WRITE_REG32(ha, ha->hw.mbx_intr_mask_offset, 0x0);
+
+exit_qla_mbx_cmd:
+ return (ret);
+}
+
+static int
+qla_get_nic_partition(qla_host_t *ha)
+{
+ uint32_t *mbox, err;
+ device_t dev = ha->pci_dev;
+
+ bzero(ha->hw.mbox, (sizeof (uint32_t) * Q8_NUM_MBOX));
+
+ mbox = ha->hw.mbox;
+
+ mbox[0] = Q8_MBX_GET_NIC_PARTITION | (0x2 << 16) | (0x2 << 29);
+
+ if (qla_mbx_cmd(ha, mbox, 2, mbox, 19, 0)) {
+ device_printf(dev, "%s: failed0\n", __func__);
+ return (-1);
+ }
+ err = mbox[0] >> 25;
+
+ if ((err != 1) && (err != 0)) {
+ device_printf(dev, "%s: failed1 [0x%08x]\n", __func__, err);
+ return (-1);
+ }
+ return 0;
+}
+
+static int
+qla_config_intr_cntxt(qla_host_t *ha, uint32_t num_intrs, uint32_t create)
+{
+ uint32_t i, err;
+ device_t dev = ha->pci_dev;
+ q80_config_intr_t *c_intr;
+ q80_config_intr_rsp_t *c_intr_rsp;
+
+ c_intr = (q80_config_intr_t *)ha->hw.mbox;
+ bzero(c_intr, (sizeof (q80_config_intr_t)));
+
+ c_intr->opcode = Q8_MBX_CONFIG_INTR;
+
+ c_intr->count_version = (sizeof (q80_config_intr_t) >> 2);
+ c_intr->count_version |= Q8_MBX_CMD_VERSION;
+
+ c_intr->nentries = num_intrs;
+
+ for (i = 0; i < num_intrs; i++) {
+ if (create) {
+ c_intr->intr[i].cmd_type = Q8_MBX_CONFIG_INTR_CREATE;
+ c_intr->intr[i].msix_index = i + 1;
+ } else {
+ c_intr->intr[i].cmd_type = Q8_MBX_CONFIG_INTR_DELETE;
+ c_intr->intr[i].msix_index = ha->hw.intr_id[i];
+ }
+
+ c_intr->intr[i].cmd_type |= Q8_MBX_CONFIG_INTR_TYPE_MSI_X;
+ }
+
+ if (qla_mbx_cmd(ha, (uint32_t *)c_intr,
+ (sizeof (q80_config_intr_t) >> 2),
+ ha->hw.mbox, (sizeof (q80_config_intr_rsp_t) >> 2), 0)) {
+ device_printf(dev, "%s: failed0\n", __func__);
+ return (-1);
+ }
+
+ c_intr_rsp = (q80_config_intr_rsp_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(c_intr_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed1 [0x%08x, %d]\n", __func__, err,
+ c_intr_rsp->nentries);
+
+ for (i = 0; i < c_intr_rsp->nentries; i++) {
+ device_printf(dev, "%s: [%d]:[0x%x 0x%x 0x%x]\n",
+ __func__, i,
+ c_intr_rsp->intr[i].status,
+ c_intr_rsp->intr[i].intr_id,
+ c_intr_rsp->intr[i].intr_src);
+ }
+
+ return (-1);
+ }
+
+ for (i = 0; ((i < num_intrs) && create); i++) {
+ if (!c_intr_rsp->intr[i].status) {
+ ha->hw.intr_id[i] = c_intr_rsp->intr[i].intr_id;
+ ha->hw.intr_src[i] = c_intr_rsp->intr[i].intr_src;
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * Name: qla_config_rss
+ * Function: Configure RSS for the context/interface.
+ */
+static const uint64_t rss_key[] = { 0xbeac01fa6a42b73bULL,
+ 0x8030f20c77cb2da3ULL,
+ 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
+ 0x255b0ec26d5a56daULL };
+
+static int
+qla_config_rss(qla_host_t *ha, uint16_t cntxt_id)
+{
+ q80_config_rss_t *c_rss;
+ q80_config_rss_rsp_t *c_rss_rsp;
+ uint32_t err, i;
+ device_t dev = ha->pci_dev;
+
+ c_rss = (q80_config_rss_t *)ha->hw.mbox;
+ bzero(c_rss, (sizeof (q80_config_rss_t)));
+
+ c_rss->opcode = Q8_MBX_CONFIG_RSS;
+
+ c_rss->count_version = (sizeof (q80_config_rss_t) >> 2);
+ c_rss->count_version |= Q8_MBX_CMD_VERSION;
+
+ c_rss->hash_type = (Q8_MBX_RSS_HASH_TYPE_IPV4_TCP_IP |
+ Q8_MBX_RSS_HASH_TYPE_IPV6_TCP_IP);
+
+ c_rss->flags = Q8_MBX_RSS_FLAGS_ENABLE_RSS;
+ c_rss->flags |= Q8_MBX_RSS_FLAGS_USE_IND_TABLE;
+
+ c_rss->indtbl_mask = Q8_MBX_RSS_INDTBL_MASK;
+
+ c_rss->indtbl_mask |= Q8_MBX_RSS_FLAGS_MULTI_RSS_VALID;
+ c_rss->flags |= Q8_MBX_RSS_FLAGS_TYPE_CRSS;
+
+ c_rss->cntxt_id = cntxt_id;
+
+ for (i = 0; i < 5; i++) {
+ c_rss->rss_key[i] = rss_key[i];
+ }
+
+ if (qla_mbx_cmd(ha, (uint32_t *)c_rss,
+ (sizeof (q80_config_rss_t) >> 2),
+ ha->hw.mbox, (sizeof(q80_config_rss_rsp_t) >> 2), 0)) {
+ device_printf(dev, "%s: failed0\n", __func__);
+ return (-1);
+ }
+ c_rss_rsp = (q80_config_rss_rsp_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(c_rss_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed1 [0x%08x]\n", __func__, err);
+ return (-1);
+ }
+ return 0;
+}
+
+static uint8_t rss_ind_default_table[Q8_RSS_IND_TBL_SIZE];
+
+static int
+qla_set_rss_ind_table(qla_host_t *ha, uint32_t start_idx, uint32_t count,
+ uint16_t cntxt_id, uint8_t *ind_table)
+{
+ q80_config_rss_ind_table_t *c_rss_ind;
+ q80_config_rss_ind_table_rsp_t *c_rss_ind_rsp;
+ uint32_t err;
+ device_t dev = ha->pci_dev;
+
+ if ((count > Q8_RSS_IND_TBL_SIZE) ||
+ ((start_idx + count - 1) > Q8_RSS_IND_TBL_MAX_IDX)) {
+ device_printf(dev, "%s: illegal count [%d, %d]\n", __func__,
+ start_idx, count);
+ return (-1);
+ }
+
+ c_rss_ind = (q80_config_rss_ind_table_t *)ha->hw.mbox;
+ bzero(c_rss_ind, sizeof (q80_config_rss_ind_table_t));
+
+ c_rss_ind->opcode = Q8_MBX_CONFIG_RSS_TABLE;
+ c_rss_ind->count_version = (sizeof (q80_config_rss_ind_table_t) >> 2);
+ c_rss_ind->count_version |= Q8_MBX_CMD_VERSION;
+
+ c_rss_ind->start_idx = start_idx;
+ c_rss_ind->end_idx = start_idx + count - 1;
+ c_rss_ind->cntxt_id = cntxt_id;
+ bcopy(ind_table, c_rss_ind->ind_table, count);
+
+ if (qla_mbx_cmd(ha, (uint32_t *)c_rss_ind,
+ (sizeof (q80_config_rss_ind_table_t) >> 2), ha->hw.mbox,
+ (sizeof(q80_config_rss_ind_table_rsp_t) >> 2), 0)) {
+ device_printf(dev, "%s: failed0\n", __func__);
+ return (-1);
+ }
+
+ c_rss_ind_rsp = (q80_config_rss_ind_table_rsp_t *)ha->hw.mbox;
+ err = Q8_MBX_RSP_STATUS(c_rss_ind_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed1 [0x%08x]\n", __func__, err);
+ return (-1);
+ }
+ return 0;
+}
+
+/*
+ * Name: qla_config_intr_coalesce
+ * Function: Configure Interrupt Coalescing.
+ */
+static int
+qla_config_intr_coalesce(qla_host_t *ha, uint16_t cntxt_id, int tenable)
+{
+ q80_config_intr_coalesc_t *intrc;
+ q80_config_intr_coalesc_rsp_t *intrc_rsp;
+ uint32_t err, i;
+ device_t dev = ha->pci_dev;
+
+ intrc = (q80_config_intr_coalesc_t *)ha->hw.mbox;
+ bzero(intrc, (sizeof (q80_config_intr_coalesc_t)));
+
+ intrc->opcode = Q8_MBX_CONFIG_INTR_COALESCE;
+ intrc->count_version = (sizeof (q80_config_intr_coalesc_t) >> 2);
+ intrc->count_version |= Q8_MBX_CMD_VERSION;
+
+ intrc->flags = Q8_MBX_INTRC_FLAGS_RCV;
+ intrc->cntxt_id = cntxt_id;
+
+ intrc->max_pkts = 256;
+ intrc->max_mswait = 3;
+
+ if (tenable) {
+ intrc->flags |= Q8_MBX_INTRC_FLAGS_PERIODIC;
+ intrc->timer_type = Q8_MBX_INTRC_TIMER_PERIODIC;
+
+ for (i = 0; i < ha->hw.num_sds_rings; i++) {
+ intrc->sds_ring_mask |= (1 << i);
+ }
+ intrc->ms_timeout = 1000;
+ }
+
+ if (qla_mbx_cmd(ha, (uint32_t *)intrc,
+ (sizeof (q80_config_intr_coalesc_t) >> 2),
+ ha->hw.mbox, (sizeof(q80_config_intr_coalesc_rsp_t) >> 2), 0)) {
+ device_printf(dev, "%s: failed0\n", __func__);
+ return (-1);
+ }
+ intrc_rsp = (q80_config_intr_coalesc_rsp_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(intrc_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed1 [0x%08x]\n", __func__, err);
+ return (-1);
+ }
+
+ return 0;
+}
+
+
+/*
+ * Name: qla_config_mac_addr
+ * Function: binds a MAC address to the context/interface.
+ * Can be unicast, multicast or broadcast.
+ */
+static int
+qla_config_mac_addr(qla_host_t *ha, uint8_t *mac_addr, uint32_t add_mac)
+{
+ q80_config_mac_addr_t *cmac;
+ q80_config_mac_addr_rsp_t *cmac_rsp;
+ uint32_t err;
+ device_t dev = ha->pci_dev;
+
+ cmac = (q80_config_mac_addr_t *)ha->hw.mbox;
+ bzero(cmac, (sizeof (q80_config_mac_addr_t)));
+
+ cmac->opcode = Q8_MBX_CONFIG_MAC_ADDR;
+ cmac->count_version = sizeof (q80_config_mac_addr_t) >> 2;
+ cmac->count_version |= Q8_MBX_CMD_VERSION;
+
+ if (add_mac)
+ cmac->cmd = Q8_MBX_CMAC_CMD_ADD_MAC_ADDR;
+ else
+ cmac->cmd = Q8_MBX_CMAC_CMD_DEL_MAC_ADDR;
+
+ cmac->cmd |= Q8_MBX_CMAC_CMD_CAM_INGRESS;
+
+ cmac->nmac_entries = 1;
+ cmac->cntxt_id = ha->hw.rcv_cntxt_id;
+ bcopy(mac_addr, cmac->mac_addr[0].addr, 6);
+
+ if (qla_mbx_cmd(ha, (uint32_t *)cmac,
+ (sizeof (q80_config_mac_addr_t) >> 2),
+ ha->hw.mbox, (sizeof(q80_config_mac_addr_rsp_t) >> 2), 1)) {
+ device_printf(dev, "%s: %s failed0\n", __func__,
+ (add_mac ? "Add" : "Del"));
+ return (-1);
+ }
+ cmac_rsp = (q80_config_mac_addr_rsp_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(cmac_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: %s "
+ "%02x:%02x:%02x:%02x:%02x:%02x failed1 [0x%08x]\n",
+ __func__, (add_mac ? "Add" : "Del"),
+ mac_addr[0], mac_addr[1], mac_addr[2],
+ mac_addr[3], mac_addr[4], mac_addr[5], err);
+ return (-1);
+ }
+
+ return 0;
+}
+
+
+/*
+ * Name: qla_set_mac_rcv_mode
+ * Function: Enable/Disable AllMulticast and Promiscous Modes.
+ */
+static int
+qla_set_mac_rcv_mode(qla_host_t *ha, uint32_t mode)
+{
+ q80_config_mac_rcv_mode_t *rcv_mode;
+ uint32_t err;
+ q80_config_mac_rcv_mode_rsp_t *rcv_mode_rsp;
+ device_t dev = ha->pci_dev;
+
+ rcv_mode = (q80_config_mac_rcv_mode_t *)ha->hw.mbox;
+ bzero(rcv_mode, (sizeof (q80_config_mac_rcv_mode_t)));
+
+ rcv_mode->opcode = Q8_MBX_CONFIG_MAC_RX_MODE;
+ rcv_mode->count_version = sizeof (q80_config_mac_rcv_mode_t) >> 2;
+ rcv_mode->count_version |= Q8_MBX_CMD_VERSION;
+
+ rcv_mode->mode = mode;
+
+ rcv_mode->cntxt_id = ha->hw.rcv_cntxt_id;
+
+ if (qla_mbx_cmd(ha, (uint32_t *)rcv_mode,
+ (sizeof (q80_config_mac_rcv_mode_t) >> 2),
+ ha->hw.mbox, (sizeof(q80_config_mac_rcv_mode_rsp_t) >> 2), 1)) {
+ device_printf(dev, "%s: failed0\n", __func__);
+ return (-1);
+ }
+ rcv_mode_rsp = (q80_config_mac_rcv_mode_rsp_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(rcv_mode_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed1 [0x%08x]\n", __func__, err);
+ return (-1);
+ }
+
+ return 0;
+}
+
+int
+ql_set_promisc(qla_host_t *ha)
+{
+ int ret;
+
+ ha->hw.mac_rcv_mode |= Q8_MBX_MAC_RCV_PROMISC_ENABLE;
+ ret = qla_set_mac_rcv_mode(ha, ha->hw.mac_rcv_mode);
+ return (ret);
+}
+
+int
+ql_set_allmulti(qla_host_t *ha)
+{
+ int ret;
+
+ ha->hw.mac_rcv_mode |= Q8_MBX_MAC_ALL_MULTI_ENABLE;
+ ret = qla_set_mac_rcv_mode(ha, ha->hw.mac_rcv_mode);
+ return (ret);
+}
+
+
+/*
+ * Name: ql_set_max_mtu
+ * Function:
+ * Sets the maximum transfer unit size for the specified rcv context.
+ */
+int
+ql_set_max_mtu(qla_host_t *ha, uint32_t mtu, uint16_t cntxt_id)
+{
+ device_t dev;
+ q80_set_max_mtu_t *max_mtu;
+ q80_set_max_mtu_rsp_t *max_mtu_rsp;
+ uint32_t err;
+
+ dev = ha->pci_dev;
+
+ max_mtu = (q80_set_max_mtu_t *)ha->hw.mbox;
+ bzero(max_mtu, (sizeof (q80_set_max_mtu_t)));
+
+ max_mtu->opcode = Q8_MBX_SET_MAX_MTU;
+ max_mtu->count_version = (sizeof (q80_set_max_mtu_t) >> 2);
+ max_mtu->count_version |= Q8_MBX_CMD_VERSION;
+
+ max_mtu->cntxt_id = cntxt_id;
+ max_mtu->mtu = mtu;
+
+ if (qla_mbx_cmd(ha, (uint32_t *)max_mtu,
+ (sizeof (q80_set_max_mtu_t) >> 2),
+ ha->hw.mbox, (sizeof (q80_set_max_mtu_rsp_t) >> 2), 1)) {
+ device_printf(dev, "%s: failed\n", __func__);
+ return -1;
+ }
+
+ max_mtu_rsp = (q80_set_max_mtu_rsp_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(max_mtu_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed [0x%08x]\n", __func__, err);
+ }
+
+ return 0;
+}
+
+static int
+qla_link_event_req(qla_host_t *ha, uint16_t cntxt_id)
+{
+ device_t dev;
+ q80_link_event_t *lnk;
+ q80_link_event_rsp_t *lnk_rsp;
+ uint32_t err;
+
+ dev = ha->pci_dev;
+
+ lnk = (q80_link_event_t *)ha->hw.mbox;
+ bzero(lnk, (sizeof (q80_link_event_t)));
+
+ lnk->opcode = Q8_MBX_LINK_EVENT_REQ;
+ lnk->count_version = (sizeof (q80_link_event_t) >> 2);
+ lnk->count_version |= Q8_MBX_CMD_VERSION;
+
+ lnk->cntxt_id = cntxt_id;
+ lnk->cmd = Q8_LINK_EVENT_CMD_ENABLE_ASYNC;
+
+ if (qla_mbx_cmd(ha, (uint32_t *)lnk, (sizeof (q80_link_event_t) >> 2),
+ ha->hw.mbox, (sizeof (q80_link_event_rsp_t) >> 2), 0)) {
+ device_printf(dev, "%s: failed\n", __func__);
+ return -1;
+ }
+
+ lnk_rsp = (q80_link_event_rsp_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(lnk_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed [0x%08x]\n", __func__, err);
+ }
+
+ return 0;
+}
+
+static int
+qla_config_fw_lro(qla_host_t *ha, uint16_t cntxt_id)
+{
+ device_t dev;
+ q80_config_fw_lro_t *fw_lro;
+ q80_config_fw_lro_rsp_t *fw_lro_rsp;
+ uint32_t err;
+
+ dev = ha->pci_dev;
+
+ fw_lro = (q80_config_fw_lro_t *)ha->hw.mbox;
+ bzero(fw_lro, sizeof(q80_config_fw_lro_t));
+
+ fw_lro->opcode = Q8_MBX_CONFIG_FW_LRO;
+ fw_lro->count_version = (sizeof (q80_config_fw_lro_t) >> 2);
+ fw_lro->count_version |= Q8_MBX_CMD_VERSION;
+
+ fw_lro->flags |= Q8_MBX_FW_LRO_IPV4 | Q8_MBX_FW_LRO_IPV4_WO_DST_IP_CHK;
+
+ fw_lro->cntxt_id = cntxt_id;
+
+ if (qla_mbx_cmd(ha, (uint32_t *)fw_lro,
+ (sizeof (q80_config_fw_lro_t) >> 2),
+ ha->hw.mbox, (sizeof (q80_config_fw_lro_rsp_t) >> 2), 0)) {
+ device_printf(dev, "%s: failed\n", __func__);
+ return -1;
+ }
+
+ fw_lro_rsp = (q80_config_fw_lro_rsp_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(fw_lro_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed [0x%08x]\n", __func__, err);
+ }
+
+ return 0;
+}
+
+static void
+qla_xmt_stats(qla_host_t *ha, q80_xmt_stats_t *xstat)
+{
+ device_t dev = ha->pci_dev;
+
+ device_printf(dev, "%s: total_bytes\t\t%" PRIu64 "\n", __func__,
+ xstat->total_bytes);
+ device_printf(dev, "%s: total_pkts\t\t%" PRIu64 "\n", __func__,
+ xstat->total_pkts);
+ device_printf(dev, "%s: errors\t\t%" PRIu64 "\n", __func__,
+ xstat->errors);
+ device_printf(dev, "%s: pkts_dropped\t%" PRIu64 "\n", __func__,
+ xstat->pkts_dropped);
+ device_printf(dev, "%s: switch_pkts\t\t%" PRIu64 "\n", __func__,
+ xstat->switch_pkts);
+ device_printf(dev, "%s: num_buffers\t\t%" PRIu64 "\n", __func__,
+ xstat->num_buffers);
+}
+
+static void
+qla_rcv_stats(qla_host_t *ha, q80_rcv_stats_t *rstat)
+{
+ device_t dev = ha->pci_dev;
+
+ device_printf(dev, "%s: total_bytes\t\t\t%" PRIu64 "\n", __func__,
+ rstat->total_bytes);
+ device_printf(dev, "%s: total_pkts\t\t\t%" PRIu64 "\n", __func__,
+ rstat->total_pkts);
+ device_printf(dev, "%s: lro_pkt_count\t\t%" PRIu64 "\n", __func__,
+ rstat->lro_pkt_count);
+ device_printf(dev, "%s: sw_pkt_count\t\t%" PRIu64 "\n", __func__,
+ rstat->sw_pkt_count);
+ device_printf(dev, "%s: ip_chksum_err\t\t%" PRIu64 "\n", __func__,
+ rstat->ip_chksum_err);
+ device_printf(dev, "%s: pkts_wo_acntxts\t\t%" PRIu64 "\n", __func__,
+ rstat->pkts_wo_acntxts);
+ device_printf(dev, "%s: pkts_dropped_no_sds_card\t%" PRIu64 "\n",
+ __func__, rstat->pkts_dropped_no_sds_card);
+ device_printf(dev, "%s: pkts_dropped_no_sds_host\t%" PRIu64 "\n",
+ __func__, rstat->pkts_dropped_no_sds_host);
+ device_printf(dev, "%s: oversized_pkts\t\t%" PRIu64 "\n", __func__,
+ rstat->oversized_pkts);
+ device_printf(dev, "%s: pkts_dropped_no_rds\t\t%" PRIu64 "\n",
+ __func__, rstat->pkts_dropped_no_rds);
+ device_printf(dev, "%s: unxpctd_mcast_pkts\t\t%" PRIu64 "\n",
+ __func__, rstat->unxpctd_mcast_pkts);
+ device_printf(dev, "%s: re1_fbq_error\t\t%" PRIu64 "\n", __func__,
+ rstat->re1_fbq_error);
+ device_printf(dev, "%s: invalid_mac_addr\t\t%" PRIu64 "\n", __func__,
+ rstat->invalid_mac_addr);
+ device_printf(dev, "%s: rds_prime_trys\t\t%" PRIu64 "\n", __func__,
+ rstat->rds_prime_trys);
+ device_printf(dev, "%s: rds_prime_success\t\t%" PRIu64 "\n", __func__,
+ rstat->rds_prime_success);
+ device_printf(dev, "%s: lro_flows_added\t\t%" PRIu64 "\n", __func__,
+ rstat->lro_flows_added);
+ device_printf(dev, "%s: lro_flows_deleted\t\t%" PRIu64 "\n", __func__,
+ rstat->lro_flows_deleted);
+ device_printf(dev, "%s: lro_flows_active\t\t%" PRIu64 "\n", __func__,
+ rstat->lro_flows_active);
+ device_printf(dev, "%s: pkts_droped_unknown\t\t%" PRIu64 "\n",
+ __func__, rstat->pkts_droped_unknown);
+}
+
+static void
+qla_mac_stats(qla_host_t *ha, q80_mac_stats_t *mstat)
+{
+ device_t dev = ha->pci_dev;
+
+ device_printf(dev, "%s: xmt_frames\t\t\t%" PRIu64 "\n", __func__,
+ mstat->xmt_frames);
+ device_printf(dev, "%s: xmt_bytes\t\t\t%" PRIu64 "\n", __func__,
+ mstat->xmt_bytes);
+ device_printf(dev, "%s: xmt_mcast_pkts\t\t%" PRIu64 "\n", __func__,
+ mstat->xmt_mcast_pkts);
+ device_printf(dev, "%s: xmt_bcast_pkts\t\t%" PRIu64 "\n", __func__,
+ mstat->xmt_bcast_pkts);
+ device_printf(dev, "%s: xmt_pause_frames\t\t%" PRIu64 "\n", __func__,
+ mstat->xmt_pause_frames);
+ device_printf(dev, "%s: xmt_cntrl_pkts\t\t%" PRIu64 "\n", __func__,
+ mstat->xmt_cntrl_pkts);
+ device_printf(dev, "%s: xmt_pkt_lt_64bytes\t\t%" PRIu64 "\n",
+ __func__, mstat->xmt_pkt_lt_64bytes);
+ device_printf(dev, "%s: xmt_pkt_lt_127bytes\t\t%" PRIu64 "\n",
+ __func__, mstat->xmt_pkt_lt_127bytes);
+ device_printf(dev, "%s: xmt_pkt_lt_255bytes\t\t%" PRIu64 "\n",
+ __func__, mstat->xmt_pkt_lt_255bytes);
+ device_printf(dev, "%s: xmt_pkt_lt_511bytes\t\t%" PRIu64 "\n",
+ __func__, mstat->xmt_pkt_lt_511bytes);
+ device_printf(dev, "%s: xmt_pkt_lt_1023bytes\t%" PRIu64 "\n",
+ __func__, mstat->xmt_pkt_lt_1023bytes);
+ device_printf(dev, "%s: xmt_pkt_lt_1518bytes\t%" PRIu64 "\n",
+ __func__, mstat->xmt_pkt_lt_1518bytes);
+ device_printf(dev, "%s: xmt_pkt_gt_1518bytes\t%" PRIu64 "\n",
+ __func__, mstat->xmt_pkt_gt_1518bytes);
+
+ device_printf(dev, "%s: rcv_frames\t\t\t%" PRIu64 "\n", __func__,
+ mstat->rcv_frames);
+ device_printf(dev, "%s: rcv_bytes\t\t\t%" PRIu64 "\n", __func__,
+ mstat->rcv_bytes);
+ device_printf(dev, "%s: rcv_mcast_pkts\t\t%" PRIu64 "\n", __func__,
+ mstat->rcv_mcast_pkts);
+ device_printf(dev, "%s: rcv_bcast_pkts\t\t%" PRIu64 "\n", __func__,
+ mstat->rcv_bcast_pkts);
+ device_printf(dev, "%s: rcv_pause_frames\t\t%" PRIu64 "\n", __func__,
+ mstat->rcv_pause_frames);
+ device_printf(dev, "%s: rcv_cntrl_pkts\t\t%" PRIu64 "\n", __func__,
+ mstat->rcv_cntrl_pkts);
+ device_printf(dev, "%s: rcv_pkt_lt_64bytes\t\t%" PRIu64 "\n",
+ __func__, mstat->rcv_pkt_lt_64bytes);
+ device_printf(dev, "%s: rcv_pkt_lt_127bytes\t\t%" PRIu64 "\n",
+ __func__, mstat->rcv_pkt_lt_127bytes);
+ device_printf(dev, "%s: rcv_pkt_lt_255bytes\t\t%" PRIu64 "\n",
+ __func__, mstat->rcv_pkt_lt_255bytes);
+ device_printf(dev, "%s: rcv_pkt_lt_511bytes\t\t%" PRIu64 "\n",
+ __func__, mstat->rcv_pkt_lt_511bytes);
+ device_printf(dev, "%s: rcv_pkt_lt_1023bytes\t%" PRIu64 "\n",
+ __func__, mstat->rcv_pkt_lt_1023bytes);
+ device_printf(dev, "%s: rcv_pkt_lt_1518bytes\t%" PRIu64 "\n",
+ __func__, mstat->rcv_pkt_lt_1518bytes);
+ device_printf(dev, "%s: rcv_pkt_gt_1518bytes\t%" PRIu64 "\n",
+ __func__, mstat->rcv_pkt_gt_1518bytes);
+
+ device_printf(dev, "%s: rcv_len_error\t\t%" PRIu64 "\n", __func__,
+ mstat->rcv_len_error);
+ device_printf(dev, "%s: rcv_len_small\t\t%" PRIu64 "\n", __func__,
+ mstat->rcv_len_small);
+ device_printf(dev, "%s: rcv_len_large\t\t%" PRIu64 "\n", __func__,
+ mstat->rcv_len_large);
+ device_printf(dev, "%s: rcv_jabber\t\t\t%" PRIu64 "\n", __func__,
+ mstat->rcv_jabber);
+ device_printf(dev, "%s: rcv_dropped\t\t\t%" PRIu64 "\n", __func__,
+ mstat->rcv_dropped);
+ device_printf(dev, "%s: fcs_error\t\t\t%" PRIu64 "\n", __func__,
+ mstat->fcs_error);
+ device_printf(dev, "%s: align_error\t\t\t%" PRIu64 "\n", __func__,
+ mstat->align_error);
+}
+
+
+static int
+qla_get_hw_stats(qla_host_t *ha, uint32_t cmd)
+{
+ device_t dev;
+ q80_get_stats_t *stat;
+ q80_get_stats_rsp_t *stat_rsp;
+ uint32_t err;
+
+ dev = ha->pci_dev;
+
+ stat = (q80_get_stats_t *)ha->hw.mbox;
+ bzero(stat, (sizeof (q80_get_stats_t)));
+
+ stat->opcode = Q8_MBX_GET_STATS;
+ stat->count_version = 2;
+ stat->count_version |= Q8_MBX_CMD_VERSION;
+
+ stat->cmd = cmd;
+
+ if (qla_mbx_cmd(ha, (uint32_t *)stat, 2,
+ ha->hw.mbox, (sizeof (q80_get_stats_rsp_t) >> 2), 0)) {
+ device_printf(dev, "%s: failed\n", __func__);
+ return -1;
+ }
+
+ stat_rsp = (q80_get_stats_rsp_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(stat_rsp->regcnt_status);
+
+ if (err) {
+ return -1;
+ }
+
+ return 0;
+}
+
+void
+ql_get_stats(qla_host_t *ha)
+{
+ q80_get_stats_rsp_t *stat_rsp;
+ q80_mac_stats_t *mstat;
+ q80_xmt_stats_t *xstat;
+ q80_rcv_stats_t *rstat;
+ uint32_t cmd;
+
+ stat_rsp = (q80_get_stats_rsp_t *)ha->hw.mbox;
+ /*
+ * Get MAC Statistics
+ */
+ cmd = Q8_GET_STATS_CMD_TYPE_MAC;
+
+ cmd |= ((ha->pci_func & 0x1) << 16);
+
+ if (qla_get_hw_stats(ha, cmd) == 0) {
+ mstat = (q80_mac_stats_t *)&stat_rsp->u.mac;
+ qla_mac_stats(ha, mstat);
+ } else {
+ device_printf(ha->pci_dev, "%s: mac failed [0x%08x]\n",
+ __func__, ha->hw.mbox[0]);
+ }
+ /*
+ * Get RCV Statistics
+ */
+ cmd = Q8_GET_STATS_CMD_RCV | Q8_GET_STATS_CMD_TYPE_CNTXT;
+ cmd |= (ha->hw.rcv_cntxt_id << 16);
+
+ if (qla_get_hw_stats(ha, cmd) == 0) {
+ rstat = (q80_rcv_stats_t *)&stat_rsp->u.rcv;
+ qla_rcv_stats(ha, rstat);
+ } else {
+ device_printf(ha->pci_dev, "%s: rcv failed [0x%08x]\n",
+ __func__, ha->hw.mbox[0]);
+ }
+ /*
+ * Get XMT Statistics
+ */
+ cmd = Q8_GET_STATS_CMD_XMT | Q8_GET_STATS_CMD_TYPE_CNTXT;
+ cmd |= (ha->hw.tx_cntxt[ha->txr_idx].tx_cntxt_id << 16);
+
+
+ if (qla_get_hw_stats(ha, cmd) == 0) {
+ xstat = (q80_xmt_stats_t *)&stat_rsp->u.xmt;
+ qla_xmt_stats(ha, xstat);
+ } else {
+ device_printf(ha->pci_dev, "%s: xmt failed [0x%08x]\n",
+ __func__, ha->hw.mbox[0]);
+ }
+}
+
+/*
+ * Name: qla_tx_tso
+ * Function: Checks if the packet to be transmitted is a candidate for
+ * Large TCP Segment Offload. If yes, the appropriate fields in the Tx
+ * Ring Structure are plugged in.
+ */
+static int
+qla_tx_tso(qla_host_t *ha, struct mbuf *mp, q80_tx_cmd_t *tx_cmd, uint8_t *hdr)
+{
+ struct ether_vlan_header *eh;
+ struct ip *ip = NULL;
+ struct ip6_hdr *ip6 = NULL;
+ struct tcphdr *th = NULL;
+ uint32_t ehdrlen, hdrlen, ip_hlen, tcp_hlen, tcp_opt_off;
+ uint16_t etype, opcode, offload = 1;
+ device_t dev;
+
+ dev = ha->pci_dev;
+
+
+ eh = mtod(mp, struct ether_vlan_header *);
+
+ if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
+ ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
+ etype = ntohs(eh->evl_proto);
+ } else {
+ ehdrlen = ETHER_HDR_LEN;
+ etype = ntohs(eh->evl_encap_proto);
+ }
+
+ hdrlen = 0;
+
+ switch (etype) {
+ case ETHERTYPE_IP:
+
+ tcp_opt_off = ehdrlen + sizeof(struct ip) +
+ sizeof(struct tcphdr);
+
+ if (mp->m_len < tcp_opt_off) {
+ m_copydata(mp, 0, tcp_opt_off, hdr);
+ ip = (struct ip *)(hdr + ehdrlen);
+ } else {
+ ip = (struct ip *)(mp->m_data + ehdrlen);
+ }
+
+ ip_hlen = ip->ip_hl << 2;
+ opcode = Q8_TX_CMD_OP_XMT_TCP_LSO;
+
+
+ if ((ip->ip_p != IPPROTO_TCP) ||
+ (ip_hlen != sizeof (struct ip))){
+ /* IP Options are not supported */
+
+ offload = 0;
+ } else
+ th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
+
+ break;
+
+ case ETHERTYPE_IPV6:
+
+ tcp_opt_off = ehdrlen + sizeof(struct ip6_hdr) +
+ sizeof (struct tcphdr);
+
+ if (mp->m_len < tcp_opt_off) {
+ m_copydata(mp, 0, tcp_opt_off, hdr);
+ ip6 = (struct ip6_hdr *)(hdr + ehdrlen);
+ } else {
+ ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
+ }
+
+ ip_hlen = sizeof(struct ip6_hdr);
+ opcode = Q8_TX_CMD_OP_XMT_TCP_LSO_IPV6;
+
+ if (ip6->ip6_nxt != IPPROTO_TCP) {
+ //device_printf(dev, "%s: ipv6\n", __func__);
+ offload = 0;
+ } else
+ th = (struct tcphdr *)((caddr_t)ip6 + ip_hlen);
+ break;
+
+ default:
+ QL_DPRINT8(ha, (dev, "%s: type!=ip\n", __func__));
+ offload = 0;
+ break;
+ }
+
+ if (!offload)
+ return (-1);
+
+ tcp_hlen = th->th_off << 2;
+ hdrlen = ehdrlen + ip_hlen + tcp_hlen;
+
+ if (mp->m_len < hdrlen) {
+ if (mp->m_len < tcp_opt_off) {
+ if (tcp_hlen > sizeof(struct tcphdr)) {
+ m_copydata(mp, tcp_opt_off,
+ (tcp_hlen - sizeof(struct tcphdr)),
+ &hdr[tcp_opt_off]);
+ }
+ } else {
+ m_copydata(mp, 0, hdrlen, hdr);
+ }
+ }
+
+ tx_cmd->mss = mp->m_pkthdr.tso_segsz;
+
+ tx_cmd->flags_opcode = opcode ;
+ tx_cmd->tcp_hdr_off = ip_hlen + ehdrlen;
+ tx_cmd->total_hdr_len = hdrlen;
+
+ /* Check for Multicast least significant bit of MSB == 1 */
+ if (eh->evl_dhost[0] & 0x01) {
+ tx_cmd->flags_opcode |= Q8_TX_CMD_FLAGS_MULTICAST;
+ }
+
+ if (mp->m_len < hdrlen) {
+ printf("%d\n", hdrlen);
+ return (1);
+ }
+
+ return (0);
+}
+
+/*
+ * Name: qla_tx_chksum
+ * Function: Checks if the packet to be transmitted is a candidate for
+ * TCP/UDP Checksum offload. If yes, the appropriate fields in the Tx
+ * Ring Structure are plugged in.
+ */
+static int
+qla_tx_chksum(qla_host_t *ha, struct mbuf *mp, uint32_t *op_code,
+ uint32_t *tcp_hdr_off)
+{
+ struct ether_vlan_header *eh;
+ struct ip *ip;
+ struct ip6_hdr *ip6;
+ uint32_t ehdrlen, ip_hlen;
+ uint16_t etype, opcode, offload = 1;
+ device_t dev;
+ uint8_t buf[sizeof(struct ip6_hdr)];
+
+ dev = ha->pci_dev;
+
+ *op_code = 0;
+
+ if ((mp->m_pkthdr.csum_flags & (CSUM_TCP|CSUM_UDP)) == 0)
+ return (-1);
+
+ eh = mtod(mp, struct ether_vlan_header *);
+
+ if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
+ ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
+ etype = ntohs(eh->evl_proto);
+ } else {
+ ehdrlen = ETHER_HDR_LEN;
+ etype = ntohs(eh->evl_encap_proto);
+ }
+
+
+ switch (etype) {
+ case ETHERTYPE_IP:
+ ip = (struct ip *)(mp->m_data + ehdrlen);
+
+ ip_hlen = sizeof (struct ip);
+
+ if (mp->m_len < (ehdrlen + ip_hlen)) {
+ m_copydata(mp, ehdrlen, sizeof(struct ip), buf);
+ ip = (struct ip *)buf;
+ }
+
+ if (ip->ip_p == IPPROTO_TCP)
+ opcode = Q8_TX_CMD_OP_XMT_TCP_CHKSUM;
+ else if (ip->ip_p == IPPROTO_UDP)
+ opcode = Q8_TX_CMD_OP_XMT_UDP_CHKSUM;
+ else {
+ //device_printf(dev, "%s: ipv4\n", __func__);
+ offload = 0;
+ }
+ break;
+
+ case ETHERTYPE_IPV6:
+ ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
+
+ ip_hlen = sizeof(struct ip6_hdr);
+
+ if (mp->m_len < (ehdrlen + ip_hlen)) {
+ m_copydata(mp, ehdrlen, sizeof (struct ip6_hdr),
+ buf);
+ ip6 = (struct ip6_hdr *)buf;
+ }
+
+ if (ip6->ip6_nxt == IPPROTO_TCP)
+ opcode = Q8_TX_CMD_OP_XMT_TCP_CHKSUM_IPV6;
+ else if (ip6->ip6_nxt == IPPROTO_UDP)
+ opcode = Q8_TX_CMD_OP_XMT_UDP_CHKSUM_IPV6;
+ else {
+ //device_printf(dev, "%s: ipv6\n", __func__);
+ offload = 0;
+ }
+ break;
+
+ default:
+ offload = 0;
+ break;
+ }
+ if (!offload)
+ return (-1);
+
+ *op_code = opcode;
+ *tcp_hdr_off = (ip_hlen + ehdrlen);
+
+ return (0);
+}
+
+#define QLA_TX_MIN_FREE 2
+/*
+ * Name: ql_hw_send
+ * Function: Transmits a packet. It first checks if the packet is a
+ * candidate for Large TCP Segment Offload and then for UDP/TCP checksum
+ * offload. If either of these creteria are not met, it is transmitted
+ * as a regular ethernet frame.
+ */
+int
+ql_hw_send(qla_host_t *ha, bus_dma_segment_t *segs, int nsegs,
+ uint32_t tx_idx, struct mbuf *mp, uint32_t txr_idx)
+{
+ struct ether_vlan_header *eh;
+ qla_hw_t *hw = &ha->hw;
+ q80_tx_cmd_t *tx_cmd, tso_cmd;
+ bus_dma_segment_t *c_seg;
+ uint32_t num_tx_cmds, hdr_len = 0;
+ uint32_t total_length = 0, bytes, tx_cmd_count = 0, txr_next;
+ device_t dev;
+ int i, ret;
+ uint8_t *src = NULL, *dst = NULL;
+ uint8_t frame_hdr[QL_FRAME_HDR_SIZE];
+ uint32_t op_code = 0;
+ uint32_t tcp_hdr_off = 0;
+
+ dev = ha->pci_dev;
+
+ /*
+ * Always make sure there is atleast one empty slot in the tx_ring
+ * tx_ring is considered full when there only one entry available
+ */
+ num_tx_cmds = (nsegs + (Q8_TX_CMD_MAX_SEGMENTS - 1)) >> 2;
+
+ total_length = mp->m_pkthdr.len;
+ if (total_length > QLA_MAX_TSO_FRAME_SIZE) {
+ device_printf(dev, "%s: total length exceeds maxlen(%d)\n",
+ __func__, total_length);
+ return (-1);
+ }
+ eh = mtod(mp, struct ether_vlan_header *);
+
+ if (mp->m_pkthdr.csum_flags & CSUM_TSO) {
+
+ bzero((void *)&tso_cmd, sizeof(q80_tx_cmd_t));
+
+ src = frame_hdr;
+ ret = qla_tx_tso(ha, mp, &tso_cmd, src);
+
+ if (!(ret & ~1)) {
+ /* find the additional tx_cmd descriptors required */
+
+ if (mp->m_flags & M_VLANTAG)
+ tso_cmd.total_hdr_len += ETHER_VLAN_ENCAP_LEN;
+
+ hdr_len = tso_cmd.total_hdr_len;
+
+ bytes = sizeof(q80_tx_cmd_t) - Q8_TX_CMD_TSO_ALIGN;
+ bytes = QL_MIN(bytes, hdr_len);
+
+ num_tx_cmds++;
+ hdr_len -= bytes;
+
+ while (hdr_len) {
+ bytes = QL_MIN((sizeof(q80_tx_cmd_t)), hdr_len);
+ hdr_len -= bytes;
+ num_tx_cmds++;
+ }
+ hdr_len = tso_cmd.total_hdr_len;
+
+ if (ret == 0)
+ src = (uint8_t *)eh;
+ } else
+ return (EINVAL);
+ } else {
+ (void)qla_tx_chksum(ha, mp, &op_code, &tcp_hdr_off);
+ }
+
+ if (hw->tx_cntxt[txr_idx].txr_free <= (num_tx_cmds + QLA_TX_MIN_FREE)) {
+ qla_hw_tx_done_locked(ha, txr_idx);
+ if (hw->tx_cntxt[txr_idx].txr_free <=
+ (num_tx_cmds + QLA_TX_MIN_FREE)) {
+ QL_DPRINT8(ha, (dev, "%s: (hw->txr_free <= "
+ "(num_tx_cmds + QLA_TX_MIN_FREE))\n",
+ __func__));
+ return (-1);
+ }
+ }
+
+ tx_cmd = &hw->tx_cntxt[txr_idx].tx_ring_base[tx_idx];
+
+ if (!(mp->m_pkthdr.csum_flags & CSUM_TSO)) {
+
+ if (nsegs > ha->hw.max_tx_segs)
+ ha->hw.max_tx_segs = nsegs;
+
+ bzero((void *)tx_cmd, sizeof(q80_tx_cmd_t));
+
+ if (op_code) {
+ tx_cmd->flags_opcode = op_code;
+ tx_cmd->tcp_hdr_off = tcp_hdr_off;
+
+ } else {
+ tx_cmd->flags_opcode = Q8_TX_CMD_OP_XMT_ETHER;
+ }
+ } else {
+ bcopy(&tso_cmd, tx_cmd, sizeof(q80_tx_cmd_t));
+ ha->tx_tso_frames++;
+ }
+
+ if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
+ tx_cmd->flags_opcode |= Q8_TX_CMD_FLAGS_VLAN_TAGGED;
+ } else if (mp->m_flags & M_VLANTAG) {
+
+ if (hdr_len) { /* TSO */
+ tx_cmd->flags_opcode |= (Q8_TX_CMD_FLAGS_VLAN_TAGGED |
+ Q8_TX_CMD_FLAGS_HW_VLAN_ID);
+ tx_cmd->tcp_hdr_off += ETHER_VLAN_ENCAP_LEN;
+ } else
+ tx_cmd->flags_opcode |= Q8_TX_CMD_FLAGS_HW_VLAN_ID;
+
+ ha->hw_vlan_tx_frames++;
+ tx_cmd->vlan_tci = mp->m_pkthdr.ether_vtag;
+ }
+
+
+ tx_cmd->n_bufs = (uint8_t)nsegs;
+ tx_cmd->data_len_lo = (uint8_t)(total_length & 0xFF);
+ tx_cmd->data_len_hi = qla_host_to_le16(((uint16_t)(total_length >> 8)));
+ tx_cmd->cntxtid = Q8_TX_CMD_PORT_CNXTID(ha->pci_func);
+
+ c_seg = segs;
+
+ while (1) {
+ for (i = 0; ((i < Q8_TX_CMD_MAX_SEGMENTS) && nsegs); i++) {
+
+ switch (i) {
+ case 0:
+ tx_cmd->buf1_addr = c_seg->ds_addr;
+ tx_cmd->buf1_len = c_seg->ds_len;
+ break;
+
+ case 1:
+ tx_cmd->buf2_addr = c_seg->ds_addr;
+ tx_cmd->buf2_len = c_seg->ds_len;
+ break;
+
+ case 2:
+ tx_cmd->buf3_addr = c_seg->ds_addr;
+ tx_cmd->buf3_len = c_seg->ds_len;
+ break;
+
+ case 3:
+ tx_cmd->buf4_addr = c_seg->ds_addr;
+ tx_cmd->buf4_len = c_seg->ds_len;
+ break;
+ }
+
+ c_seg++;
+ nsegs--;
+ }
+
+ txr_next = hw->tx_cntxt[txr_idx].txr_next =
+ (hw->tx_cntxt[txr_idx].txr_next + 1) &
+ (NUM_TX_DESCRIPTORS - 1);
+ tx_cmd_count++;
+
+ if (!nsegs)
+ break;
+
+ tx_cmd = &hw->tx_cntxt[txr_idx].tx_ring_base[txr_next];
+ bzero((void *)tx_cmd, sizeof(q80_tx_cmd_t));
+ }
+
+ if (mp->m_pkthdr.csum_flags & CSUM_TSO) {
+
+ /* TSO : Copy the header in the following tx cmd descriptors */
+
+ txr_next = hw->tx_cntxt[txr_idx].txr_next;
+
+ tx_cmd = &hw->tx_cntxt[txr_idx].tx_ring_base[txr_next];
+ bzero((void *)tx_cmd, sizeof(q80_tx_cmd_t));
+
+ bytes = sizeof(q80_tx_cmd_t) - Q8_TX_CMD_TSO_ALIGN;
+ bytes = QL_MIN(bytes, hdr_len);
+
+ dst = (uint8_t *)tx_cmd + Q8_TX_CMD_TSO_ALIGN;
+
+ if (mp->m_flags & M_VLANTAG) {
+ /* first copy the src/dst MAC addresses */
+ bcopy(src, dst, (ETHER_ADDR_LEN * 2));
+ dst += (ETHER_ADDR_LEN * 2);
+ src += (ETHER_ADDR_LEN * 2);
+
+ *((uint16_t *)dst) = htons(ETHERTYPE_VLAN);
+ dst += 2;
+ *((uint16_t *)dst) = htons(mp->m_pkthdr.ether_vtag);
+ dst += 2;
+
+ /* bytes left in src header */
+ hdr_len -= ((ETHER_ADDR_LEN * 2) +
+ ETHER_VLAN_ENCAP_LEN);
+
+ /* bytes left in TxCmd Entry */
+ bytes -= ((ETHER_ADDR_LEN * 2) + ETHER_VLAN_ENCAP_LEN);
+
+
+ bcopy(src, dst, bytes);
+ src += bytes;
+ hdr_len -= bytes;
+ } else {
+ bcopy(src, dst, bytes);
+ src += bytes;
+ hdr_len -= bytes;
+ }
+
+ txr_next = hw->tx_cntxt[txr_idx].txr_next =
+ (hw->tx_cntxt[txr_idx].txr_next + 1) &
+ (NUM_TX_DESCRIPTORS - 1);
+ tx_cmd_count++;
+
+ while (hdr_len) {
+ tx_cmd = &hw->tx_cntxt[txr_idx].tx_ring_base[txr_next];
+ bzero((void *)tx_cmd, sizeof(q80_tx_cmd_t));
+
+ bytes = QL_MIN((sizeof(q80_tx_cmd_t)), hdr_len);
+
+ bcopy(src, tx_cmd, bytes);
+ src += bytes;
+ hdr_len -= bytes;
+
+ txr_next = hw->tx_cntxt[txr_idx].txr_next =
+ (hw->tx_cntxt[txr_idx].txr_next + 1) &
+ (NUM_TX_DESCRIPTORS - 1);
+ tx_cmd_count++;
+ }
+ }
+
+ hw->tx_cntxt[txr_idx].txr_free =
+ hw->tx_cntxt[txr_idx].txr_free - tx_cmd_count;
+
+ QL_UPDATE_TX_PRODUCER_INDEX(ha, hw->tx_cntxt[txr_idx].txr_next,\
+ txr_idx);
+ QL_DPRINT8(ha, (dev, "%s: return\n", __func__));
+
+ return (0);
+}
+
+
+static int
+qla_config_rss_ind_table(qla_host_t *ha)
+{
+ uint32_t i, count;
+ uint8_t rss_ind_tbl[16];
+
+ bzero(rss_ind_default_table, sizeof(rss_ind_default_table));
+
+
+ for (i = 0; i < 16; i++) {
+ rss_ind_tbl[i] = i % ha->hw.num_sds_rings;
+ }
+
+ for (i = 0; i <= Q8_RSS_IND_TBL_MAX_IDX ; i = i + 16) {
+
+ if ((i + 16) > Q8_RSS_IND_TBL_MAX_IDX) {
+ count = Q8_RSS_IND_TBL_MAX_IDX - i + 1;
+ } else {
+ count = 16;
+ }
+
+ if (qla_set_rss_ind_table(ha, i, count, ha->hw.rcv_cntxt_id,
+ rss_ind_tbl))
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * Name: ql_del_hw_if
+ * Function: Destroys the hardware specific entities corresponding to an
+ * Ethernet Interface
+ */
+void
+ql_del_hw_if(qla_host_t *ha)
+{
+
+ qla_del_rcv_cntxt(ha);
+ qla_del_xmt_cntxt(ha);
+
+ if (ha->hw.flags.init_intr_cnxt) {
+ qla_config_intr_cntxt(ha, ha->hw.num_sds_rings, 0);
+ ha->hw.flags.init_intr_cnxt = 0;
+ }
+}
+
+/*
+ * Name: ql_init_hw_if
+ * Function: Creates the hardware specific entities corresponding to an
+ * Ethernet Interface - Transmit and Receive Contexts. Sets the MAC Address
+ * corresponding to the interface. Enables LRO if allowed.
+ */
+int
+ql_init_hw_if(qla_host_t *ha)
+{
+ device_t dev;
+ uint32_t i;
+ uint8_t bcast_mac[6];
+ qla_rdesc_t *rdesc;
+
+ dev = ha->pci_dev;
+
+ for (i = 0; i < ha->hw.num_sds_rings; i++) {
+ bzero(ha->hw.dma_buf.sds_ring[i].dma_b,
+ ha->hw.dma_buf.sds_ring[i].size);
+ }
+ ha->hw.mbx_intr_mask_offset = READ_REG32(ha, Q8_MBOX_INT_MASK_MSIX);
+
+ /* Use MSI-X vector 0; Enable Firmware Mailbox Interrupt */
+ WRITE_REG32(ha, Q8_MBOX_INT_ENABLE, BIT_2);
+ WRITE_REG32(ha, ha->hw.mbx_intr_mask_offset, 0x0);
+
+ qla_get_nic_partition(ha);
+
+ if (qla_config_intr_cntxt(ha, ha->hw.num_sds_rings, 1) == 0) {
+ ha->hw.flags.init_intr_cnxt = 1;
+ } else
+ return (-1);
+
+ if (ha->hw.mdump_init == 0) {
+ qla_minidump_init(ha);
+ }
+
+ /*
+ * Create Receive Context
+ */
+ if (qla_init_rcv_cntxt(ha)) {
+ return (-1);
+ }
+
+ for (i = 0; i < ha->hw.num_rds_rings; i++) {
+ rdesc = &ha->hw.rds[i];
+ rdesc->rx_next = NUM_RX_DESCRIPTORS - 2;
+ rdesc->rx_in = 0;
+ /* Update the RDS Producer Indices */
+ QL_UPDATE_RDS_PRODUCER_INDEX(ha, rdesc->prod_std,\
+ rdesc->rx_next);
+ }
+
+
+ /*
+ * Create Transmit Context
+ */
+ if (qla_init_xmt_cntxt(ha)) {
+ qla_del_rcv_cntxt(ha);
+ return (-1);
+ }
+ ha->hw.max_tx_segs = 0;
+
+ if (qla_config_mac_addr(ha, ha->hw.mac_addr, 1))
+ return(-1);
+
+ ha->hw.flags.unicast_mac = 1;
+
+ bcast_mac[0] = 0xFF; bcast_mac[1] = 0xFF; bcast_mac[2] = 0xFF;
+ bcast_mac[3] = 0xFF; bcast_mac[4] = 0xFF; bcast_mac[5] = 0xFF;
+
+ if (qla_config_mac_addr(ha, bcast_mac, 1))
+ return (-1);
+
+ ha->hw.flags.bcast_mac = 1;
+
+ /*
+ * program any cached multicast addresses
+ */
+ if (qla_hw_add_all_mcast(ha))
+ return (-1);
+
+ if (qla_config_rss(ha, ha->hw.rcv_cntxt_id))
+ return (-1);
+
+ if (qla_config_rss_ind_table(ha))
+ return (-1);
+
+ if (qla_config_intr_coalesce(ha, ha->hw.rcv_cntxt_id, 0))
+ return (-1);
+
+ if (qla_link_event_req(ha, ha->hw.rcv_cntxt_id))
+ return (-1);
+
+ if (qla_config_fw_lro(ha, ha->hw.rcv_cntxt_id))
+ return (-1);
+
+ for (i = 0; i < ha->hw.num_sds_rings; i++)
+ QL_ENABLE_INTERRUPTS(ha, i);
+
+ return (0);
+}
+
+static int
+qla_map_sds_to_rds(qla_host_t *ha)
+{
+ device_t dev = ha->pci_dev;
+ q80_rq_map_sds_to_rds_t *map_rings;
+ q80_rsp_add_rcv_rings_t *map_rings_rsp;
+ uint32_t i, err;
+ qla_hw_t *hw = &ha->hw;
+
+ map_rings = (q80_rq_map_sds_to_rds_t *)ha->hw.mbox;
+ bzero(map_rings, sizeof(q80_rq_map_sds_to_rds_t));
+
+ map_rings->opcode = Q8_MBX_MAP_SDS_TO_RDS;
+ map_rings->count_version = (sizeof (q80_rq_map_sds_to_rds_t) >> 2);
+ map_rings->count_version |= Q8_MBX_CMD_VERSION;
+
+ map_rings->cntxt_id = hw->rcv_cntxt_id;
+ map_rings->num_rings = hw->num_sds_rings;
+
+ for (i = 0; i < hw->num_sds_rings; i++) {
+ map_rings->sds_rds[i].sds_ring = i;
+ map_rings->sds_rds[i].rds_ring = i;
+ }
+
+ if (qla_mbx_cmd(ha, (uint32_t *)map_rings,
+ (sizeof (q80_rq_map_sds_to_rds_t) >> 2),
+ ha->hw.mbox, (sizeof(q80_rsp_add_rcv_rings_t) >> 2), 0)) {
+ device_printf(dev, "%s: failed0\n", __func__);
+ return (-1);
+ }
+
+ map_rings_rsp = (q80_rsp_add_rcv_rings_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(map_rings_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed1 [0x%08x]\n", __func__, err);
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * Name: qla_init_rcv_cntxt
+ * Function: Creates the Receive Context.
+ */
+static int
+qla_init_rcv_cntxt(qla_host_t *ha)
+{
+ q80_rq_rcv_cntxt_t *rcntxt;
+ q80_rsp_rcv_cntxt_t *rcntxt_rsp;
+ q80_stat_desc_t *sdesc;
+ int i, j;
+ qla_hw_t *hw = &ha->hw;
+ device_t dev;
+ uint32_t err;
+ uint32_t rcntxt_sds_rings;
+ uint32_t rcntxt_rds_rings;
+
+ dev = ha->pci_dev;
+
+ /*
+ * Create Receive Context
+ */
+
+ for (i = 0; i < hw->num_sds_rings; i++) {
+ sdesc = (q80_stat_desc_t *)&hw->sds[i].sds_ring_base[0];
+
+ for (j = 0; j < NUM_STATUS_DESCRIPTORS; j++) {
+ sdesc->data[0] = 1ULL;
+ sdesc->data[1] = 1ULL;
+ }
+ }
+
+ rcntxt_sds_rings = hw->num_sds_rings;
+ if (hw->num_sds_rings > MAX_RCNTXT_SDS_RINGS)
+ rcntxt_sds_rings = MAX_RCNTXT_SDS_RINGS;
+
+ rcntxt_rds_rings = hw->num_rds_rings;
+
+ if (hw->num_rds_rings > MAX_RDS_RING_SETS)
+ rcntxt_rds_rings = MAX_RDS_RING_SETS;
+
+ rcntxt = (q80_rq_rcv_cntxt_t *)ha->hw.mbox;
+ bzero(rcntxt, (sizeof (q80_rq_rcv_cntxt_t)));
+
+ rcntxt->opcode = Q8_MBX_CREATE_RX_CNTXT;
+ rcntxt->count_version = (sizeof (q80_rq_rcv_cntxt_t) >> 2);
+ rcntxt->count_version |= Q8_MBX_CMD_VERSION;
+
+ rcntxt->cap0 = Q8_RCV_CNTXT_CAP0_BASEFW |
+ Q8_RCV_CNTXT_CAP0_LRO |
+ Q8_RCV_CNTXT_CAP0_HW_LRO |
+ Q8_RCV_CNTXT_CAP0_RSS |
+ Q8_RCV_CNTXT_CAP0_SGL_JUMBO |
+ Q8_RCV_CNTXT_CAP0_SGL_LRO;
+
+ if (ha->hw.num_rds_rings > 1) {
+ rcntxt->nrds_sets_rings = rcntxt_rds_rings | (1 << 5);
+ rcntxt->cap0 |= Q8_RCV_CNTXT_CAP0_MULTI_RDS;
+ } else
+ rcntxt->nrds_sets_rings = 0x1 | (1 << 5);
+
+ rcntxt->nsds_rings = rcntxt_sds_rings;
+
+ rcntxt->rds_producer_mode = Q8_RCV_CNTXT_RDS_PROD_MODE_UNIQUE;
+
+ rcntxt->rcv_vpid = 0;
+
+ for (i = 0; i < rcntxt_sds_rings; i++) {
+ rcntxt->sds[i].paddr =
+ qla_host_to_le64(hw->dma_buf.sds_ring[i].dma_addr);
+ rcntxt->sds[i].size =
+ qla_host_to_le32(NUM_STATUS_DESCRIPTORS);
+ if (ha->msix_count == 2) {
+ rcntxt->sds[i].intr_id =
+ qla_host_to_le16(hw->intr_id[0]);
+ rcntxt->sds[i].intr_src_bit = qla_host_to_le16((i));
+ } else {
+ rcntxt->sds[i].intr_id =
+ qla_host_to_le16(hw->intr_id[i]);
+ rcntxt->sds[i].intr_src_bit = qla_host_to_le16(0);
+ }
+ }
+
+ for (i = 0; i < rcntxt_rds_rings; i++) {
+ rcntxt->rds[i].paddr_std =
+ qla_host_to_le64(hw->dma_buf.rds_ring[i].dma_addr);
+ rcntxt->rds[i].std_bsize = qla_host_to_le64(MCLBYTES);
+ rcntxt->rds[i].std_nentries =
+ qla_host_to_le32(NUM_RX_DESCRIPTORS);
+ }
+
+ if (qla_mbx_cmd(ha, (uint32_t *)rcntxt,
+ (sizeof (q80_rq_rcv_cntxt_t) >> 2),
+ ha->hw.mbox, (sizeof(q80_rsp_rcv_cntxt_t) >> 2), 0)) {
+ device_printf(dev, "%s: failed0\n", __func__);
+ return (-1);
+ }
+
+ rcntxt_rsp = (q80_rsp_rcv_cntxt_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(rcntxt_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed1 [0x%08x]\n", __func__, err);
+ return (-1);
+ }
+
+ for (i = 0; i < rcntxt_sds_rings; i++) {
+ hw->sds[i].sds_consumer = rcntxt_rsp->sds_cons[i];
+ }
+
+ for (i = 0; i < rcntxt_rds_rings; i++) {
+ hw->rds[i].prod_std = rcntxt_rsp->rds[i].prod_std;
+ }
+
+ hw->rcv_cntxt_id = rcntxt_rsp->cntxt_id;
+
+ ha->hw.flags.init_rx_cnxt = 1;
+
+ if (hw->num_sds_rings > MAX_RCNTXT_SDS_RINGS) {
+ err = qla_add_rcv_rings(ha, MAX_RCNTXT_SDS_RINGS);
+ if (err)
+ return -1;
+ }
+
+ if (hw->num_rds_rings > 1) {
+ err = qla_map_sds_to_rds(ha);
+ if (err)
+ return -1;
+ }
+
+ return (0);
+}
+
+static int
+qla_add_rcv_rings(qla_host_t *ha, uint32_t sds_idx)
+{
+ device_t dev = ha->pci_dev;
+ q80_rq_add_rcv_rings_t *add_rcv;
+ q80_rsp_add_rcv_rings_t *add_rcv_rsp;
+ uint32_t i,j, err;
+ uint8_t nsds;
+ qla_hw_t *hw = &ha->hw;
+
+ nsds = hw->num_sds_rings - MAX_RCNTXT_SDS_RINGS;
+
+ add_rcv = (q80_rq_add_rcv_rings_t *)ha->hw.mbox;
+ bzero(add_rcv, sizeof (q80_rq_add_rcv_rings_t));
+
+ add_rcv->opcode = Q8_MBX_ADD_RX_RINGS;
+ add_rcv->count_version = (sizeof (q80_rq_add_rcv_rings_t) >> 2);
+ add_rcv->count_version |= Q8_MBX_CMD_VERSION;
+
+ if (hw->num_rds_rings > 1)
+ add_rcv->nrds_sets_rings = nsds | (1 << 5);
+ else
+ add_rcv->nrds_sets_rings = 0;
+
+ add_rcv->nsds_rings = nsds;
+ add_rcv->cntxt_id = hw->rcv_cntxt_id;
+
+ for (i = 0; i < nsds; i++) {
+
+ j = i + sds_idx;
+
+ add_rcv->sds[i].paddr =
+ qla_host_to_le64(hw->dma_buf.sds_ring[j].dma_addr);
+
+ add_rcv->sds[i].size =
+ qla_host_to_le32(NUM_STATUS_DESCRIPTORS);
+
+ if (ha->msix_count == 2) {
+ add_rcv->sds[i].intr_id =
+ qla_host_to_le16(hw->intr_id[0]);
+ add_rcv->sds[i].intr_src_bit = qla_host_to_le16(j);
+ } else {
+ add_rcv->sds[i].intr_id =
+ qla_host_to_le16(hw->intr_id[j]);
+ add_rcv->sds[i].intr_src_bit = qla_host_to_le16(0);
+ }
+
+ }
+ for (i = 0; ((i < nsds) && (hw->num_rds_rings > 1)); i++) {
+ j = i + sds_idx;
+ add_rcv->rds[i].paddr_std =
+ qla_host_to_le64(hw->dma_buf.rds_ring[j].dma_addr);
+ add_rcv->rds[i].std_bsize = qla_host_to_le64(MCLBYTES);
+ add_rcv->rds[i].std_nentries =
+ qla_host_to_le32(NUM_RX_DESCRIPTORS);
+ }
+
+
+ if (qla_mbx_cmd(ha, (uint32_t *)add_rcv,
+ (sizeof (q80_rq_add_rcv_rings_t) >> 2),
+ ha->hw.mbox, (sizeof(q80_rsp_add_rcv_rings_t) >> 2), 0)) {
+ device_printf(dev, "%s: failed0\n", __func__);
+ return (-1);
+ }
+
+ add_rcv_rsp = (q80_rsp_add_rcv_rings_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(add_rcv_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed1 [0x%08x]\n", __func__, err);
+ return (-1);
+ }
+
+ for (i = sds_idx; i < hw->num_sds_rings; i++) {
+ hw->sds[i].sds_consumer = add_rcv_rsp->sds_cons[(i - sds_idx)];
+ }
+ for (i = sds_idx; i < hw->num_rds_rings; i++) {
+ hw->rds[i].prod_std = add_rcv_rsp->rds[(i - sds_idx)].prod_std;
+ }
+ return (0);
+}
+
+/*
+ * Name: qla_del_rcv_cntxt
+ * Function: Destroys the Receive Context.
+ */
+static void
+qla_del_rcv_cntxt(qla_host_t *ha)
+{
+ device_t dev = ha->pci_dev;
+ q80_rcv_cntxt_destroy_t *rcntxt;
+ q80_rcv_cntxt_destroy_rsp_t *rcntxt_rsp;
+ uint32_t err;
+ uint8_t bcast_mac[6];
+
+ if (!ha->hw.flags.init_rx_cnxt)
+ return;
+
+ if (qla_hw_del_all_mcast(ha))
+ return;
+
+ if (ha->hw.flags.bcast_mac) {
+
+ bcast_mac[0] = 0xFF; bcast_mac[1] = 0xFF; bcast_mac[2] = 0xFF;
+ bcast_mac[3] = 0xFF; bcast_mac[4] = 0xFF; bcast_mac[5] = 0xFF;
+
+ if (qla_config_mac_addr(ha, bcast_mac, 0))
+ return;
+ ha->hw.flags.bcast_mac = 0;
+
+ }
+
+ if (ha->hw.flags.unicast_mac) {
+ if (qla_config_mac_addr(ha, ha->hw.mac_addr, 0))
+ return;
+ ha->hw.flags.unicast_mac = 0;
+ }
+
+ rcntxt = (q80_rcv_cntxt_destroy_t *)ha->hw.mbox;
+ bzero(rcntxt, (sizeof (q80_rcv_cntxt_destroy_t)));
+
+ rcntxt->opcode = Q8_MBX_DESTROY_RX_CNTXT;
+ rcntxt->count_version = (sizeof (q80_rcv_cntxt_destroy_t) >> 2);
+ rcntxt->count_version |= Q8_MBX_CMD_VERSION;
+
+ rcntxt->cntxt_id = ha->hw.rcv_cntxt_id;
+
+ if (qla_mbx_cmd(ha, (uint32_t *)rcntxt,
+ (sizeof (q80_rcv_cntxt_destroy_t) >> 2),
+ ha->hw.mbox, (sizeof(q80_rcv_cntxt_destroy_rsp_t) >> 2), 0)) {
+ device_printf(dev, "%s: failed0\n", __func__);
+ return;
+ }
+ rcntxt_rsp = (q80_rcv_cntxt_destroy_rsp_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(rcntxt_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed1 [0x%08x]\n", __func__, err);
+ }
+
+ ha->hw.flags.init_rx_cnxt = 0;
+ return;
+}
+
+/*
+ * Name: qla_init_xmt_cntxt
+ * Function: Creates the Transmit Context.
+ */
+static int
+qla_init_xmt_cntxt_i(qla_host_t *ha, uint32_t txr_idx)
+{
+ device_t dev;
+ qla_hw_t *hw = &ha->hw;
+ q80_rq_tx_cntxt_t *tcntxt;
+ q80_rsp_tx_cntxt_t *tcntxt_rsp;
+ uint32_t err;
+ qla_hw_tx_cntxt_t *hw_tx_cntxt;
+
+ hw_tx_cntxt = &hw->tx_cntxt[txr_idx];
+
+ dev = ha->pci_dev;
+
+ /*
+ * Create Transmit Context
+ */
+ tcntxt = (q80_rq_tx_cntxt_t *)ha->hw.mbox;
+ bzero(tcntxt, (sizeof (q80_rq_tx_cntxt_t)));
+
+ tcntxt->opcode = Q8_MBX_CREATE_TX_CNTXT;
+ tcntxt->count_version = (sizeof (q80_rq_tx_cntxt_t) >> 2);
+ tcntxt->count_version |= Q8_MBX_CMD_VERSION;
+
+ tcntxt->cap0 = Q8_TX_CNTXT_CAP0_BASEFW | Q8_TX_CNTXT_CAP0_LSO;
+
+ tcntxt->ntx_rings = 1;
+
+ tcntxt->tx_ring[0].paddr =
+ qla_host_to_le64(hw_tx_cntxt->tx_ring_paddr);
+ tcntxt->tx_ring[0].tx_consumer =
+ qla_host_to_le64(hw_tx_cntxt->tx_cons_paddr);
+ tcntxt->tx_ring[0].nentries = qla_host_to_le16(NUM_TX_DESCRIPTORS);
+
+ tcntxt->tx_ring[0].intr_id = qla_host_to_le16(hw->intr_id[0]);
+ tcntxt->tx_ring[0].intr_src_bit = qla_host_to_le16(0);
+
+
+ hw_tx_cntxt->txr_free = NUM_TX_DESCRIPTORS;
+ hw_tx_cntxt->txr_next = hw_tx_cntxt->txr_comp = 0;
+
+ if (qla_mbx_cmd(ha, (uint32_t *)tcntxt,
+ (sizeof (q80_rq_tx_cntxt_t) >> 2),
+ ha->hw.mbox,
+ (sizeof(q80_rsp_tx_cntxt_t) >> 2), 0)) {
+ device_printf(dev, "%s: failed0\n", __func__);
+ return (-1);
+ }
+ tcntxt_rsp = (q80_rsp_tx_cntxt_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(tcntxt_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed1 [0x%08x]\n", __func__, err);
+ return -1;
+ }
+
+ hw_tx_cntxt->tx_prod_reg = tcntxt_rsp->tx_ring[0].prod_index;
+ hw_tx_cntxt->tx_cntxt_id = tcntxt_rsp->tx_ring[0].cntxt_id;
+
+ return (0);
+}
+
+
+/*
+ * Name: qla_del_xmt_cntxt
+ * Function: Destroys the Transmit Context.
+ */
+static int
+qla_del_xmt_cntxt_i(qla_host_t *ha, uint32_t txr_idx)
+{
+ device_t dev = ha->pci_dev;
+ q80_tx_cntxt_destroy_t *tcntxt;
+ q80_tx_cntxt_destroy_rsp_t *tcntxt_rsp;
+ uint32_t err;
+
+ tcntxt = (q80_tx_cntxt_destroy_t *)ha->hw.mbox;
+ bzero(tcntxt, (sizeof (q80_tx_cntxt_destroy_t)));
+
+ tcntxt->opcode = Q8_MBX_DESTROY_TX_CNTXT;
+ tcntxt->count_version = (sizeof (q80_tx_cntxt_destroy_t) >> 2);
+ tcntxt->count_version |= Q8_MBX_CMD_VERSION;
+
+ tcntxt->cntxt_id = ha->hw.tx_cntxt[txr_idx].tx_cntxt_id;
+
+ if (qla_mbx_cmd(ha, (uint32_t *)tcntxt,
+ (sizeof (q80_tx_cntxt_destroy_t) >> 2),
+ ha->hw.mbox, (sizeof (q80_tx_cntxt_destroy_rsp_t) >> 2), 0)) {
+ device_printf(dev, "%s: failed0\n", __func__);
+ return (-1);
+ }
+ tcntxt_rsp = (q80_tx_cntxt_destroy_rsp_t *)ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(tcntxt_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed1 [0x%08x]\n", __func__, err);
+ return (-1);
+ }
+
+ return (0);
+}
+static void
+qla_del_xmt_cntxt(qla_host_t *ha)
+{
+ uint32_t i;
+
+ if (!ha->hw.flags.init_tx_cnxt)
+ return;
+
+ for (i = 0; i < ha->hw.num_tx_rings; i++) {
+ if (qla_del_xmt_cntxt_i(ha, i))
+ break;
+ }
+ ha->hw.flags.init_tx_cnxt = 0;
+}
+
+static int
+qla_init_xmt_cntxt(qla_host_t *ha)
+{
+ uint32_t i, j;
+
+ for (i = 0; i < ha->hw.num_tx_rings; i++) {
+ if (qla_init_xmt_cntxt_i(ha, i) != 0) {
+ for (j = 0; j < i; j++)
+ qla_del_xmt_cntxt_i(ha, j);
+ return (-1);
+ }
+ }
+ ha->hw.flags.init_tx_cnxt = 1;
+ return (0);
+}
+
+static int
+qla_hw_add_all_mcast(qla_host_t *ha)
+{
+ int i, nmcast;
+
+ nmcast = ha->hw.nmcast;
+
+ for (i = 0 ; ((i < Q8_MAX_NUM_MULTICAST_ADDRS) && nmcast); i++) {
+ if ((ha->hw.mcast[i].addr[0] != 0) ||
+ (ha->hw.mcast[i].addr[1] != 0) ||
+ (ha->hw.mcast[i].addr[2] != 0) ||
+ (ha->hw.mcast[i].addr[3] != 0) ||
+ (ha->hw.mcast[i].addr[4] != 0) ||
+ (ha->hw.mcast[i].addr[5] != 0)) {
+
+ if (qla_config_mac_addr(ha, ha->hw.mcast[i].addr, 1)) {
+ device_printf(ha->pci_dev, "%s: failed\n",
+ __func__);
+ return (-1);
+ }
+
+ nmcast--;
+ }
+ }
+ return 0;
+}
+
+static int
+qla_hw_del_all_mcast(qla_host_t *ha)
+{
+ int i, nmcast;
+
+ nmcast = ha->hw.nmcast;
+
+ for (i = 0 ; ((i < Q8_MAX_NUM_MULTICAST_ADDRS) && nmcast); i++) {
+ if ((ha->hw.mcast[i].addr[0] != 0) ||
+ (ha->hw.mcast[i].addr[1] != 0) ||
+ (ha->hw.mcast[i].addr[2] != 0) ||
+ (ha->hw.mcast[i].addr[3] != 0) ||
+ (ha->hw.mcast[i].addr[4] != 0) ||
+ (ha->hw.mcast[i].addr[5] != 0)) {
+
+ if (qla_config_mac_addr(ha, ha->hw.mcast[i].addr, 0))
+ return (-1);
+
+ nmcast--;
+ }
+ }
+ return 0;
+}
+
+static int
+qla_hw_add_mcast(qla_host_t *ha, uint8_t *mta)
+{
+ int i;
+
+ for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) {
+
+ if (QL_MAC_CMP(ha->hw.mcast[i].addr, mta) == 0)
+ return 0; /* its been already added */
+ }
+
+ for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) {
+
+ if ((ha->hw.mcast[i].addr[0] == 0) &&
+ (ha->hw.mcast[i].addr[1] == 0) &&
+ (ha->hw.mcast[i].addr[2] == 0) &&
+ (ha->hw.mcast[i].addr[3] == 0) &&
+ (ha->hw.mcast[i].addr[4] == 0) &&
+ (ha->hw.mcast[i].addr[5] == 0)) {
+
+ if (qla_config_mac_addr(ha, mta, 1))
+ return (-1);
+
+ bcopy(mta, ha->hw.mcast[i].addr, Q8_MAC_ADDR_LEN);
+ ha->hw.nmcast++;
+
+ return 0;
+ }
+ }
+ return 0;
+}
+
+static int
+qla_hw_del_mcast(qla_host_t *ha, uint8_t *mta)
+{
+ int i;
+
+ for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) {
+ if (QL_MAC_CMP(ha->hw.mcast[i].addr, mta) == 0) {
+
+ if (qla_config_mac_addr(ha, mta, 0))
+ return (-1);
+
+ ha->hw.mcast[i].addr[0] = 0;
+ ha->hw.mcast[i].addr[1] = 0;
+ ha->hw.mcast[i].addr[2] = 0;
+ ha->hw.mcast[i].addr[3] = 0;
+ ha->hw.mcast[i].addr[4] = 0;
+ ha->hw.mcast[i].addr[5] = 0;
+
+ ha->hw.nmcast--;
+
+ return 0;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Name: ql_hw_set_multi
+ * Function: Sets the Multicast Addresses provided the host O.S into the
+ * hardware (for the given interface)
+ */
+int
+ql_hw_set_multi(qla_host_t *ha, uint8_t *mcast, uint32_t mcnt,
+ uint32_t add_mac)
+{
+ int i;
+ uint8_t *mta = mcast;
+ int ret = 0;
+
+ for (i = 0; i < mcnt; i++) {
+ if (add_mac) {
+ ret = qla_hw_add_mcast(ha, mta);
+ if (ret)
+ break;
+ } else {
+ ret = qla_hw_del_mcast(ha, mta);
+ if (ret)
+ break;
+ }
+
+ mta += Q8_MAC_ADDR_LEN;
+ }
+ return (ret);
+}
+
+/*
+ * Name: qla_hw_tx_done_locked
+ * Function: Handle Transmit Completions
+ */
+static void
+qla_hw_tx_done_locked(qla_host_t *ha, uint32_t txr_idx)
+{
+ qla_tx_buf_t *txb;
+ qla_hw_t *hw = &ha->hw;
+ uint32_t comp_idx, comp_count = 0;
+ qla_hw_tx_cntxt_t *hw_tx_cntxt;
+
+ hw_tx_cntxt = &hw->tx_cntxt[txr_idx];
+
+ /* retrieve index of last entry in tx ring completed */
+ comp_idx = qla_le32_to_host(*(hw_tx_cntxt->tx_cons));
+
+ while (comp_idx != hw_tx_cntxt->txr_comp) {
+
+ txb = &ha->tx_ring[txr_idx].tx_buf[hw_tx_cntxt->txr_comp];
+
+ hw_tx_cntxt->txr_comp++;
+ if (hw_tx_cntxt->txr_comp == NUM_TX_DESCRIPTORS)
+ hw_tx_cntxt->txr_comp = 0;
+
+ comp_count++;
+
+ if (txb->m_head) {
+ ha->ifp->if_opackets++;
+
+ bus_dmamap_sync(ha->tx_tag, txb->map,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(ha->tx_tag, txb->map);
+ m_freem(txb->m_head);
+
+ txb->m_head = NULL;
+ }
+ }
+
+ hw_tx_cntxt->txr_free += comp_count;
+ return;
+}
+
+/*
+ * Name: ql_hw_tx_done
+ * Function: Handle Transmit Completions
+ */
+void
+ql_hw_tx_done(qla_host_t *ha)
+{
+ int i;
+ uint32_t flag = 0;
+
+ if (!mtx_trylock(&ha->tx_lock)) {
+ QL_DPRINT8(ha, (ha->pci_dev,
+ "%s: !mtx_trylock(&ha->tx_lock)\n", __func__));
+ return;
+ }
+ for (i = 0; i < ha->hw.num_tx_rings; i++) {
+ qla_hw_tx_done_locked(ha, i);
+ if (ha->hw.tx_cntxt[i].txr_free <= (NUM_TX_DESCRIPTORS >> 1))
+ flag = 1;
+ }
+
+ if (!flag)
+ ha->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+ QLA_TX_UNLOCK(ha);
+ return;
+}
+
+void
+ql_update_link_state(qla_host_t *ha)
+{
+ uint32_t link_state;
+ uint32_t prev_link_state;
+
+ if (!(ha->ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ ha->hw.link_up = 0;
+ return;
+ }
+ link_state = READ_REG32(ha, Q8_LINK_STATE);
+
+ prev_link_state = ha->hw.link_up;
+
+ if (ha->pci_func == 0)
+ ha->hw.link_up = (((link_state & 0xF) == 1)? 1 : 0);
+ else
+ ha->hw.link_up = ((((link_state >> 4)& 0xF) == 1)? 1 : 0);
+
+ if (prev_link_state != ha->hw.link_up) {
+ if (ha->hw.link_up) {
+ if_link_state_change(ha->ifp, LINK_STATE_UP);
+ } else {
+ if_link_state_change(ha->ifp, LINK_STATE_DOWN);
+ }
+ }
+ return;
+}
+
+void
+ql_hw_stop_rcv(qla_host_t *ha)
+{
+ int i, done, count = 100;
+
+ while (count--) {
+ done = 1;
+ for (i = 0; i < ha->hw.num_sds_rings; i++) {
+ if (ha->hw.sds[i].rcv_active)
+ done = 0;
+ }
+ if (done)
+ break;
+ else
+ qla_mdelay(__func__, 10);
+ }
+ if (!count)
+ device_printf(ha->pci_dev, "%s: Counter expired.\n", __func__);
+
+ return;
+}
+
+int
+ql_hw_check_health(qla_host_t *ha)
+{
+ uint32_t val;
+
+ ha->hw.health_count++;
+
+ if (ha->hw.health_count < 1000)
+ return 0;
+
+ ha->hw.health_count = 0;
+
+ val = READ_REG32(ha, Q8_ASIC_TEMPERATURE);
+
+ if (((val & 0xFFFF) == 2) || ((val & 0xFFFF) == 3) ||
+ (QL_ERR_INJECT(ha, INJCT_TEMPERATURE_FAILURE))) {
+ device_printf(ha->pci_dev, "%s: Temperature Alert [0x%08x]\n",
+ __func__, val);
+ return -1;
+ }
+
+ val = READ_REG32(ha, Q8_FIRMWARE_HEARTBEAT);
+
+ if ((val != ha->hw.hbeat_value) &&
+ (!(QL_ERR_INJECT(ha, INJCT_TEMPERATURE_FAILURE)))) {
+ ha->hw.hbeat_value = val;
+ return 0;
+ }
+ device_printf(ha->pci_dev, "%s: Heartbeat Failue [0x%08x]\n",
+ __func__, val);
+
+ return -1;
+}
+
+static int
+qla_get_minidump_tmplt_size(qla_host_t *ha, uint32_t *size)
+{
+ uint32_t err;
+ device_t dev = ha->pci_dev;
+ q80_config_md_templ_size_t *md_size;
+ q80_config_md_templ_size_rsp_t *md_size_rsp;
+
+ md_size = (q80_config_md_templ_size_t *) ha->hw.mbox;
+ bzero(md_size, sizeof(q80_config_md_templ_size_t));
+
+ md_size->opcode = Q8_MBX_GET_MINIDUMP_TMPLT_SIZE;
+ md_size->count_version = (sizeof (q80_config_md_templ_size_t) >> 2);
+ md_size->count_version |= Q8_MBX_CMD_VERSION;
+
+ if (qla_mbx_cmd(ha, (uint32_t *) md_size,
+ (sizeof(q80_config_md_templ_size_t) >> 2), ha->hw.mbox,
+ (sizeof(q80_config_md_templ_size_rsp_t) >> 2), 0)) {
+
+ device_printf(dev, "%s: failed\n", __func__);
+
+ return (-1);
+ }
+
+ md_size_rsp = (q80_config_md_templ_size_rsp_t *) ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(md_size_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed [0x%08x]\n", __func__, err);
+ return(-1);
+ }
+
+ *size = md_size_rsp->templ_size;
+
+ return (0);
+}
+
+static int
+qla_get_minidump_template(qla_host_t *ha)
+{
+ uint32_t err;
+ device_t dev = ha->pci_dev;
+ q80_config_md_templ_cmd_t *md_templ;
+ q80_config_md_templ_cmd_rsp_t *md_templ_rsp;
+
+ md_templ = (q80_config_md_templ_cmd_t *) ha->hw.mbox;
+ bzero(md_templ, (sizeof (q80_config_md_templ_cmd_t)));
+
+ md_templ->opcode = Q8_MBX_GET_MINIDUMP_TMPLT;
+ md_templ->count_version = ( sizeof(q80_config_md_templ_cmd_t) >> 2);
+ md_templ->count_version |= Q8_MBX_CMD_VERSION;
+
+ md_templ->buf_addr = ha->hw.dma_buf.minidump.dma_addr;
+ md_templ->buff_size = ha->hw.dma_buf.minidump.size;
+
+ if (qla_mbx_cmd(ha, (uint32_t *) md_templ,
+ (sizeof(q80_config_md_templ_cmd_t) >> 2),
+ ha->hw.mbox,
+ (sizeof(q80_config_md_templ_cmd_rsp_t) >> 2), 0)) {
+
+ device_printf(dev, "%s: failed\n", __func__);
+
+ return (-1);
+ }
+
+ md_templ_rsp = (q80_config_md_templ_cmd_rsp_t *) ha->hw.mbox;
+
+ err = Q8_MBX_RSP_STATUS(md_templ_rsp->regcnt_status);
+
+ if (err) {
+ device_printf(dev, "%s: failed [0x%08x]\n", __func__, err);
+ return (-1);
+ }
+
+ return (0);
+
+}
+
+static int
+qla_minidump_init(qla_host_t *ha)
+{
+ int ret;
+ uint32_t template_size = 0;
+ device_t dev = ha->pci_dev;
+
+ /*
+ * Get Minidump Template Size
+ */
+ ret = qla_get_minidump_tmplt_size(ha, &template_size);
+
+ if (ret || (template_size == 0)) {
+ device_printf(dev, "%s: failed [%d, %d]\n", __func__, ret,
+ template_size);
+ return (-1);
+ }
+
+ /*
+ * Allocate Memory for Minidump Template
+ */
+
+ ha->hw.dma_buf.minidump.alignment = 8;
+ ha->hw.dma_buf.minidump.size = template_size;
+
+ if (ql_alloc_dmabuf(ha, &ha->hw.dma_buf.minidump)) {
+
+ device_printf(dev, "%s: minidump dma alloc failed\n", __func__);
+
+ return (-1);
+ }
+ ha->hw.dma_buf.flags.minidump = 1;
+
+ /*
+ * Retrieve Minidump Template
+ */
+ ret = qla_get_minidump_template(ha);
+
+ if (ret) {
+ qla_minidump_free(ha);
+ } else {
+ ha->hw.mdump_init = 1;
+ }
+
+ return (ret);
+}
+
+
+static void
+qla_minidump_free(qla_host_t *ha)
+{
+ ha->hw.mdump_init = 0;
+ if (ha->hw.dma_buf.flags.minidump) {
+ ha->hw.dma_buf.flags.minidump = 0;
+ ql_free_dmabuf(ha, &ha->hw.dma_buf.minidump);
+ }
+ return;
+}
+
+void
+ql_minidump(qla_host_t *ha)
+{
+ uint32_t delay = 6000;
+
+ if (!ha->hw.mdump_init)
+ return;
+
+ if (!ha->hw.mdump_active)
+ return;
+
+ if (ha->hw.mdump_active == 1) {
+ ha->hw.mdump_start_seq_index = ql_stop_sequence(ha);
+ ha->hw.mdump_start = 1;
+ }
+
+ while (delay-- && ha->hw.mdump_active) {
+ qla_mdelay(__func__, 100);
+ }
+ ha->hw.mdump_start = 0;
+ ql_start_sequence(ha, ha->hw.mdump_start_seq_index);
+
+ return;
+}
diff --git a/sys/dev/qlxgbe/ql_hw.h b/sys/dev/qlxgbe/ql_hw.h
new file mode 100644
index 000000000000..bdc32eba0fde
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_hw.h
@@ -0,0 +1,1588 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/*
+ * File: ql_hw.h
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ */
+#ifndef _QL_HW_H_
+#define _QL_HW_H_
+
+/*
+ * PCIe Registers; Direct Mapped; Offsets from BAR0
+ */
+
+/*
+ * Register offsets for QLE8030
+ */
+
+/*
+ * Firmware Mailbox Registers
+ * 0 thru 511; offsets 0x800 thru 0xFFC; 32bits each
+ */
+#define Q8_FW_MBOX0 0x00000800
+#define Q8_FW_MBOX511 0x00000FFC
+
+/*
+ * Host Mailbox Registers
+ * 0 thru 511; offsets 0x000 thru 0x7FC; 32bits each
+ */
+#define Q8_HOST_MBOX0 0x00000000
+#define Q8_HOST_MBOX511 0x000007FC
+
+#define Q8_MBOX_INT_ENABLE 0x00001000
+#define Q8_MBOX_INT_MASK_MSIX 0x00001200
+#define Q8_MBOX_INT_LEGACY 0x00003010
+
+#define Q8_HOST_MBOX_CNTRL 0x00003038
+#define Q8_FW_MBOX_CNTRL 0x0000303C
+
+#define Q8_PEG_HALT_STATUS1 0x000034A8
+#define Q8_PEG_HALT_STATUS2 0x000034AC
+#define Q8_FIRMWARE_HEARTBEAT 0x000034B0
+
+#define Q8_FLASH_LOCK_ID 0x00003500
+#define Q8_DRIVER_LOCK_ID 0x00003504
+#define Q8_FW_CAPABILITIES 0x00003528
+
+#define Q8_FW_VER_MAJOR 0x00003550
+#define Q8_FW_VER_MINOR 0x00003554
+#define Q8_FW_VER_SUB 0x00003558
+
+#define Q8_BOOTLD_ADDR 0x0000355C
+#define Q8_BOOTLD_SIZE 0x00003560
+
+#define Q8_FW_IMAGE_ADDR 0x00003564
+#define Q8_FW_BUILD_NUMBER 0x00003568
+#define Q8_FW_IMAGE_VALID 0x000035FC
+
+#define Q8_CMDPEG_STATE 0x00003650
+
+#define Q8_LINK_STATE 0x00003698
+#define Q8_LINK_STATE_2 0x0000369C
+
+#define Q8_LINK_SPEED_0 0x000036E0
+#define Q8_LINK_SPEED_1 0x000036E4
+#define Q8_LINK_SPEED_2 0x000036E8
+#define Q8_LINK_SPEED_3 0x000036EC
+
+#define Q8_MAX_LINK_SPEED_0 0x000036F0
+#define Q8_MAX_LINK_SPEED_1 0x000036F4
+#define Q8_MAX_LINK_SPEED_2 0x000036F8
+#define Q8_MAX_LINK_SPEED_3 0x000036FC
+
+#define Q8_ASIC_TEMPERATURE 0x000037B4
+
+/*
+ * CRB Window Registers
+ * 0 thru 15; offsets 0x3800 thru 0x383C; 32bits each
+ */
+#define Q8_CRB_WINDOW_PF0 0x00003800
+#define Q8_CRB_WINDOW_PF15 0x0000383C
+
+#define Q8_FLASH_LOCK 0x00003850
+#define Q8_FLASH_UNLOCK 0x00003854
+
+#define Q8_DRIVER_LOCK 0x00003868
+#define Q8_DRIVER_UNLOCK 0x0000386C
+
+#define Q8_LEGACY_INT_PTR 0x000038C0
+#define Q8_LEGACY_INT_TRIG 0x000038C4
+#define Q8_LEGACY_INT_MASK 0x000038C8
+
+#define Q8_WILD_CARD 0x000038F0
+#define Q8_INFORMANT 0x000038FC
+
+/*
+ * Ethernet Interface Specific Registers
+ */
+#define Q8_DRIVER_OP_MODE 0x00003570
+#define Q8_API_VERSION 0x0000356C
+#define Q8_NPAR_STATE 0x0000359C
+
+/*
+ * End of PCIe Registers; Direct Mapped; Offsets from BAR0
+ */
+
+/*
+ * Indirect Registers
+ */
+#define Q8_LED_DUAL_0 0x28084C80
+#define Q8_LED_SINGLE_0 0x28084C90
+
+#define Q8_LED_DUAL_1 0x28084CA0
+#define Q8_LED_SINGLE_1 0x28084CB0
+
+#define Q8_LED_DUAL_2 0x28084CC0
+#define Q8_LED_SINGLE_2 0x28084CD0
+
+#define Q8_LED_DUAL_3 0x28084CE0
+#define Q8_LED_SINGLE_3 0x28084CF0
+
+#define Q8_GPIO_1 0x28084D00
+#define Q8_GPIO_2 0x28084D10
+#define Q8_GPIO_3 0x28084D20
+#define Q8_GPIO_4 0x28084D40
+#define Q8_GPIO_5 0x28084D50
+#define Q8_GPIO_6 0x28084D60
+#define Q8_GPIO_7 0x42100060
+#define Q8_GPIO_8 0x42100064
+
+#define Q8_FLASH_SPI_STATUS 0x2808E010
+#define Q8_FLASH_SPI_CONTROL 0x2808E014
+
+#define Q8_FLASH_STATUS 0x42100004
+#define Q8_FLASH_CONTROL 0x42110004
+#define Q8_FLASH_ADDRESS 0x42110008
+#define Q8_FLASH_WR_DATA 0x4211000C
+#define Q8_FLASH_RD_DATA 0x42110018
+
+#define Q8_FLASH_DIRECT_WINDOW 0x42110030
+#define Q8_FLASH_DIRECT_DATA 0x42150000
+
+#define Q8_MS_CNTRL 0x41000090
+
+#define Q8_MS_ADDR_LO 0x41000094
+#define Q8_MS_ADDR_HI 0x41000098
+
+#define Q8_MS_WR_DATA_0_31 0x410000A0
+#define Q8_MS_WR_DATA_32_63 0x410000A4
+#define Q8_MS_WR_DATA_64_95 0x410000B0
+#define Q8_MS_WR_DATA_96_127 0x410000B4
+
+#define Q8_MS_RD_DATA_0_31 0x410000A8
+#define Q8_MS_RD_DATA_32_63 0x410000AC
+#define Q8_MS_RD_DATA_64_95 0x410000B8
+#define Q8_MS_RD_DATA_96_127 0x410000BC
+
+#define Q8_CRB_PEG_0 0x3400003c
+#define Q8_CRB_PEG_1 0x3410003c
+#define Q8_CRB_PEG_2 0x3420003c
+#define Q8_CRB_PEG_3 0x3430003c
+#define Q8_CRB_PEG_4 0x34B0003c
+
+/*
+ * Macros for reading and writing registers
+ */
+
+#if defined(__i386__) || defined(__amd64__)
+#define Q8_MB() __asm volatile("mfence" ::: "memory")
+#define Q8_WMB() __asm volatile("sfence" ::: "memory")
+#define Q8_RMB() __asm volatile("lfence" ::: "memory")
+#else
+#define Q8_MB()
+#define Q8_WMB()
+#define Q8_RMB()
+#endif
+
+#define READ_REG32(ha, reg) bus_read_4((ha->pci_reg), reg)
+
+#define WRITE_REG32(ha, reg, val) \
+ {\
+ bus_write_4((ha->pci_reg), reg, val);\
+ bus_read_4((ha->pci_reg), reg);\
+ }
+
+#define Q8_NUM_MBOX 512
+
+#define Q8_MAX_NUM_MULTICAST_ADDRS 1023
+#define Q8_MAC_ADDR_LEN 6
+
+/*
+ * Firmware Interface
+ */
+
+/*
+ * Command Response Interface - Commands
+ */
+
+#define Q8_MBX_CONFIG_IP_ADDRESS 0x0001
+#define Q8_MBX_CONFIG_INTR 0x0002
+#define Q8_MBX_MAP_INTR_SRC 0x0003
+#define Q8_MBX_MAP_SDS_TO_RDS 0x0006
+#define Q8_MBX_CREATE_RX_CNTXT 0x0007
+#define Q8_MBX_DESTROY_RX_CNTXT 0x0008
+#define Q8_MBX_CREATE_TX_CNTXT 0x0009
+#define Q8_MBX_DESTROY_TX_CNTXT 0x000A
+#define Q8_MBX_ADD_RX_RINGS 0x000B
+#define Q8_MBX_CONFIG_LRO_FLOW 0x000C
+#define Q8_MBX_CONFIG_MAC_LEARNING 0x000D
+#define Q8_MBX_GET_STATS 0x000F
+#define Q8_MBX_GENERATE_INTR 0x0011
+#define Q8_MBX_SET_MAX_MTU 0x0012
+#define Q8_MBX_MAC_ADDR_CNTRL 0x001F
+#define Q8_MBX_GET_PCI_CONFIG 0x0020
+#define Q8_MBX_GET_NIC_PARTITION 0x0021
+#define Q8_MBX_SET_NIC_PARTITION 0x0022
+#define Q8_MBX_QUERY_WOL_CAP 0x002C
+#define Q8_MBX_SET_WOL_CONFIG 0x002D
+#define Q8_MBX_GET_MINIDUMP_TMPLT_SIZE 0x002F
+#define Q8_MBX_GET_MINIDUMP_TMPLT 0x0030
+#define Q8_MBX_GET_FW_DCBX_CAPS 0x0034
+#define Q8_MBX_QUERY_DCBX_SETTINGS 0x0035
+#define Q8_MBX_CONFIG_RSS 0x0041
+#define Q8_MBX_CONFIG_RSS_TABLE 0x0042
+#define Q8_MBX_CONFIG_INTR_COALESCE 0x0043
+#define Q8_MBX_CONFIG_LED 0x0044
+#define Q8_MBX_CONFIG_MAC_ADDR 0x0045
+#define Q8_MBX_CONFIG_STATISTICS 0x0046
+#define Q8_MBX_CONFIG_LOOPBACK 0x0047
+#define Q8_MBX_LINK_EVENT_REQ 0x0048
+#define Q8_MBX_CONFIG_MAC_RX_MODE 0x0049
+#define Q8_MBX_CONFIG_FW_LRO 0x004A
+#define Q8_MBX_INIT_NIC_FUNC 0x0060
+#define Q8_MBX_STOP_NIC_FUNC 0x0061
+#define Q8_MBX_SET_PORT_CONFIG 0x0066
+#define Q8_MBX_GET_PORT_CONFIG 0x0067
+#define Q8_MBX_GET_LINK_STATUS 0x0068
+
+
+
+/*
+ * Mailbox Command Response
+ */
+#define Q8_MBX_RSP_SUCCESS 0x0001
+#define Q8_MBX_RSP_RESPONSE_FAILURE 0x0002
+#define Q8_MBX_RSP_NO_CARD_CRB 0x0003
+#define Q8_MBX_RSP_NO_CARD_MEM 0x0004
+#define Q8_MBX_RSP_NO_CARD_RSRC 0x0005
+#define Q8_MBX_RSP_INVALID_ARGS 0x0006
+#define Q8_MBX_RSP_INVALID_ACTION 0x0007
+#define Q8_MBX_RSP_INVALID_STATE 0x0008
+#define Q8_MBX_RSP_NOT_SUPPORTED 0x0009
+#define Q8_MBX_RSP_NOT_PERMITTED 0x000A
+#define Q8_MBX_RSP_NOT_READY 0x000B
+#define Q8_MBX_RSP_DOES_NOT_EXIST 0x000C
+#define Q8_MBX_RSP_ALREADY_EXISTS 0x000D
+#define Q8_MBX_RSP_BAD_SIGNATURE 0x000E
+#define Q8_MBX_RSP_CMD_NOT_IMPLEMENTED 0x000F
+#define Q8_MBX_RSP_CMD_INVALID 0x0010
+#define Q8_MBX_RSP_TIMEOUT 0x0011
+#define Q8_MBX_RSP_CMD_FAILED 0x0012
+#define Q8_MBX_RSP_FATAL_TEMP 0x0013
+#define Q8_MBX_RSP_MAX_EXCEEDED 0x0014
+#define Q8_MBX_RSP_UNSPECIFIED 0x0015
+#define Q8_MBX_RSP_INTR_CREATE_FAILED 0x0017
+#define Q8_MBX_RSP_INTR_DELETE_FAILED 0x0018
+#define Q8_MBX_RSP_INTR_INVALID_OP 0x0019
+#define Q8_MBX_RSP_IDC_INTRMD_RSP 0x001A
+
+#define Q8_MBX_CMD_VERSION (0x2 << 13)
+#define Q8_MBX_RSP_STATUS(x) (((!(x >> 9)) || ((x >> 9) == 1)) ? 0: (x >> 9))
+/*
+ * Configure IP Address
+ */
+typedef struct _q80_config_ip_addr {
+ uint16_t opcode;
+ uint16_t count_version;
+
+ uint8_t cmd;
+#define Q8_MBX_CONFIG_IP_ADD_IP 0x1
+#define Q8_MBX_CONFIG_IP_DEL_IP 0x2
+
+ uint8_t ip_type;
+#define Q8_MBX_CONFIG_IP_V4 0x0
+#define Q8_MBX_CONFIG_IP_V6 0x1
+
+ uint16_t rsrvd;
+ union {
+ struct {
+ uint32_t addr;
+ uint32_t rsrvd[3];
+ } ipv4;
+ uint8_t ipv6_addr[16];
+ } u;
+} __packed q80_config_ip_addr_t;
+
+typedef struct _q80_config_ip_addr_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_config_ip_addr_rsp_t;
+
+/*
+ * Configure Interrupt Command
+ */
+typedef struct _q80_intr {
+ uint8_t cmd_type;
+#define Q8_MBX_CONFIG_INTR_CREATE 0x1
+#define Q8_MBX_CONFIG_INTR_DELETE 0x2
+#define Q8_MBX_CONFIG_INTR_TYPE_LINE (0x1 << 4)
+#define Q8_MBX_CONFIG_INTR_TYPE_MSI_X (0x3 << 4)
+
+ uint8_t rsrvd;
+ uint16_t msix_index;
+} __packed q80_intr_t;
+
+#define Q8_MAX_INTR_VECTORS 16
+typedef struct _q80_config_intr {
+ uint16_t opcode;
+ uint16_t count_version;
+ uint8_t nentries;
+ uint8_t rsrvd[3];
+ q80_intr_t intr[Q8_MAX_INTR_VECTORS];
+} __packed q80_config_intr_t;
+
+typedef struct _q80_intr_rsp {
+ uint8_t status;
+ uint8_t cmd;
+ uint16_t intr_id;
+ uint32_t intr_src;
+} q80_intr_rsp_t;
+
+typedef struct _q80_config_intr_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+ uint8_t nentries;
+ uint8_t rsrvd[3];
+ q80_intr_rsp_t intr[Q8_MAX_INTR_VECTORS];
+} __packed q80_config_intr_rsp_t;
+
+/*
+ * Configure LRO Flow Command
+ */
+typedef struct _q80_config_lro_flow {
+ uint16_t opcode;
+ uint16_t count_version;
+
+ uint8_t cmd;
+#define Q8_MBX_CONFIG_LRO_FLOW_ADD 0x01
+#define Q8_MBX_CONFIG_LRO_FLOW_DELETE 0x02
+
+ uint8_t type_ts;
+#define Q8_MBX_CONFIG_LRO_FLOW_IPV4 0x00
+#define Q8_MBX_CONFIG_LRO_FLOW_IPV6 0x01
+#define Q8_MBX_CONFIG_LRO_FLOW_TS_ABSENT 0x00
+#define Q8_MBX_CONFIG_LRO_FLOW_TS_PRESENT 0x02
+
+ uint16_t rsrvd;
+ union {
+ struct {
+ uint32_t addr;
+ uint32_t rsrvd[3];
+ } ipv4;
+ uint8_t ipv6_addr[16];
+ } dst;
+ union {
+ struct {
+ uint32_t addr;
+ uint32_t rsrvd[3];
+ } ipv4;
+ uint8_t ipv6_addr[16];
+ } src;
+ uint16_t dst_port;
+ uint16_t src_port;
+} __packed q80_config_lro_flow_t;
+
+typedef struct _q80_config_lro_flow_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_config_lro_flow_rsp_t;
+
+typedef struct _q80_set_max_mtu {
+ uint16_t opcode;
+ uint16_t count_version;
+ uint32_t cntxt_id;
+ uint32_t mtu;
+} __packed q80_set_max_mtu_t;
+
+typedef struct _q80_set_max_mtu_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_set_max_mtu_rsp_t;
+
+/*
+ * Configure RSS
+ */
+typedef struct _q80_config_rss {
+ uint16_t opcode;
+ uint16_t count_version;
+
+ uint16_t cntxt_id;
+ uint16_t rsrvd;
+
+ uint8_t hash_type;
+#define Q8_MBX_RSS_HASH_TYPE_IPV4_TCP_IP (0x3 << 4)
+#define Q8_MBX_RSS_HASH_TYPE_IPV6_TCP_IP (0x3 << 6)
+
+ uint8_t flags;
+#define Q8_MBX_RSS_FLAGS_ENABLE_RSS (0x1)
+#define Q8_MBX_RSS_FLAGS_USE_IND_TABLE (0x2)
+#define Q8_MBX_RSS_FLAGS_TYPE_CRSS (0x4)
+
+ uint16_t indtbl_mask;
+#define Q8_MBX_RSS_INDTBL_MASK 0x7F
+#define Q8_MBX_RSS_FLAGS_MULTI_RSS_VALID 0x8000
+
+ uint32_t multi_rss;
+#define Q8_MBX_RSS_MULTI_RSS_ENGINE_ASSIGN BIT_30
+#define Q8_MBX_RSS_USE_MULTI_RSS_ENGINES BIT_31
+
+ uint64_t rss_key[5];
+} __packed q80_config_rss_t;
+
+typedef struct _q80_config_rss_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_config_rss_rsp_t;
+
+/*
+ * Configure RSS Indirection Table
+ */
+#define Q8_RSS_IND_TBL_SIZE 40
+#define Q8_RSS_IND_TBL_MIN_IDX 0
+#define Q8_RSS_IND_TBL_MAX_IDX 127
+
+typedef struct _q80_config_rss_ind_table {
+ uint16_t opcode;
+ uint16_t count_version;
+ uint8_t start_idx;
+ uint8_t end_idx;
+ uint16_t cntxt_id;
+ uint8_t ind_table[40];
+} __packed q80_config_rss_ind_table_t;
+
+typedef struct _q80_config_rss_ind_table_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_config_rss_ind_table_rsp_t;
+
+/*
+ * Configure Interrupt Coalescing and Generation
+ */
+typedef struct _q80_config_intr_coalesc {
+ uint16_t opcode;
+ uint16_t count_version;
+ uint16_t flags;
+#define Q8_MBX_INTRC_FLAGS_RCV 1
+#define Q8_MBX_INTRC_FLAGS_XMT 2
+#define Q8_MBX_INTRC_FLAGS_PERIODIC (1 << 3)
+
+ uint16_t cntxt_id;
+ uint16_t max_pkts;
+ uint16_t max_mswait;
+ uint8_t timer_type;
+#define Q8_MBX_INTRC_TIMER_NONE 0
+#define Q8_MBX_INTRC_TIMER_SINGLE 1
+#define Q8_MBX_INTRC_TIMER_PERIODIC 2
+
+ uint16_t sds_ring_mask;
+
+ uint8_t rsrvd;
+ uint32_t ms_timeout;
+} __packed q80_config_intr_coalesc_t;
+
+typedef struct _q80_config_intr_coalesc_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_config_intr_coalesc_rsp_t;
+
+/*
+ * Configure MAC Address
+ */
+typedef struct _q80_mac_addr {
+ uint8_t addr[6];
+ uint16_t vlan_tci;
+} __packed q80_mac_addr_t;
+
+#define Q8_MAX_MAC_ADDRS 64
+
+typedef struct _q80_config_mac_addr {
+ uint16_t opcode;
+ uint16_t count_version;
+ uint8_t cmd;
+#define Q8_MBX_CMAC_CMD_ADD_MAC_ADDR 1
+#define Q8_MBX_CMAC_CMD_DEL_MAC_ADDR 2
+
+#define Q8_MBX_CMAC_CMD_CAM_BOTH (0x0 << 6)
+#define Q8_MBX_CMAC_CMD_CAM_INGRESS (0x1 << 6)
+#define Q8_MBX_CMAC_CMD_CAM_EGRESS (0x2 << 6)
+
+ uint8_t nmac_entries;
+ uint16_t cntxt_id;
+ q80_mac_addr_t mac_addr[Q8_MAX_MAC_ADDRS];
+} __packed q80_config_mac_addr_t;
+
+typedef struct _q80_config_mac_addr_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+ uint8_t cmd;
+ uint8_t nmac_entries;
+ uint16_t cntxt_id;
+ uint32_t status[Q8_MAX_MAC_ADDRS];
+} __packed q80_config_mac_addr_rsp_t;
+
+/*
+ * Configure MAC Receive Mode
+ */
+typedef struct _q80_config_mac_rcv_mode {
+ uint16_t opcode;
+ uint16_t count_version;
+
+ uint8_t mode;
+#define Q8_MBX_MAC_RCV_PROMISC_ENABLE 0x1
+#define Q8_MBX_MAC_ALL_MULTI_ENABLE 0x2
+
+ uint8_t rsrvd;
+ uint16_t cntxt_id;
+} __packed q80_config_mac_rcv_mode_t;
+
+typedef struct _q80_config_mac_rcv_mode_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_config_mac_rcv_mode_rsp_t;
+
+/*
+ * Configure Firmware Controlled LRO
+ */
+typedef struct _q80_config_fw_lro {
+ uint16_t opcode;
+ uint16_t count_version;
+
+ uint8_t flags;
+#define Q8_MBX_FW_LRO_IPV4 0x1
+#define Q8_MBX_FW_LRO_IPV6 0x2
+#define Q8_MBX_FW_LRO_IPV4_WO_DST_IP_CHK 0x4
+#define Q8_MBX_FW_LRO_IPV6_WO_DST_IP_CHK 0x8
+
+ uint8_t rsrvd;
+ uint16_t cntxt_id;
+} __packed q80_config_fw_lro_t;
+
+typedef struct _q80_config_fw_lro_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_config_fw_lro_rsp_t;
+
+/*
+ * Minidump mailbox commands
+ */
+typedef struct _q80_config_md_templ_size {
+ uint16_t opcode;
+ uint16_t count_version;
+} __packed q80_config_md_templ_size_t;
+
+typedef struct _q80_config_md_templ_size_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+ uint32_t rsrvd;
+ uint32_t templ_size;
+ uint32_t templ_version;
+} __packed q80_config_md_templ_size_rsp_t;
+
+typedef struct _q80_config_md_templ_cmd {
+ uint16_t opcode;
+ uint16_t count_version;
+ uint64_t buf_addr; /* physical address of buffer */
+ uint32_t buff_size;
+ uint32_t offset;
+} __packed q80_config_md_templ_cmd_t;
+
+typedef struct _q80_config_md_templ_cmd_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+ uint32_t rsrvd;
+ uint32_t templ_size;
+ uint32_t buff_size;
+ uint32_t offset;
+} __packed q80_config_md_templ_cmd_rsp_t;
+
+/*
+ * Link Event Request Command
+ */
+typedef struct _q80_link_event {
+ uint16_t opcode;
+ uint16_t count_version;
+ uint8_t cmd;
+#define Q8_LINK_EVENT_CMD_STOP_PERIODIC 0
+#define Q8_LINK_EVENT_CMD_ENABLE_ASYNC 1
+
+ uint8_t flags;
+#define Q8_LINK_EVENT_FLAGS_SEND_RSP 1
+
+ uint16_t cntxt_id;
+} __packed q80_link_event_t;
+
+typedef struct _q80_link_event_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_link_event_rsp_t;
+
+/*
+ * Get Statistics Command
+ */
+typedef struct _q80_rcv_stats {
+ uint64_t total_bytes;
+ uint64_t total_pkts;
+ uint64_t lro_pkt_count;
+ uint64_t sw_pkt_count;
+ uint64_t ip_chksum_err;
+ uint64_t pkts_wo_acntxts;
+ uint64_t pkts_dropped_no_sds_card;
+ uint64_t pkts_dropped_no_sds_host;
+ uint64_t oversized_pkts;
+ uint64_t pkts_dropped_no_rds;
+ uint64_t unxpctd_mcast_pkts;
+ uint64_t re1_fbq_error;
+ uint64_t invalid_mac_addr;
+ uint64_t rds_prime_trys;
+ uint64_t rds_prime_success;
+ uint64_t lro_flows_added;
+ uint64_t lro_flows_deleted;
+ uint64_t lro_flows_active;
+ uint64_t pkts_droped_unknown;
+} __packed q80_rcv_stats_t;
+
+typedef struct _q80_xmt_stats {
+ uint64_t total_bytes;
+ uint64_t total_pkts;
+ uint64_t errors;
+ uint64_t pkts_dropped;
+ uint64_t switch_pkts;
+ uint64_t num_buffers;
+} __packed q80_xmt_stats_t;
+
+typedef struct _q80_mac_stats {
+ uint64_t xmt_frames;
+ uint64_t xmt_bytes;
+ uint64_t xmt_mcast_pkts;
+ uint64_t xmt_bcast_pkts;
+ uint64_t xmt_pause_frames;
+ uint64_t xmt_cntrl_pkts;
+ uint64_t xmt_pkt_lt_64bytes;
+ uint64_t xmt_pkt_lt_127bytes;
+ uint64_t xmt_pkt_lt_255bytes;
+ uint64_t xmt_pkt_lt_511bytes;
+ uint64_t xmt_pkt_lt_1023bytes;
+ uint64_t xmt_pkt_lt_1518bytes;
+ uint64_t xmt_pkt_gt_1518bytes;
+ uint64_t rsrvd0[3];
+ uint64_t rcv_frames;
+ uint64_t rcv_bytes;
+ uint64_t rcv_mcast_pkts;
+ uint64_t rcv_bcast_pkts;
+ uint64_t rcv_pause_frames;
+ uint64_t rcv_cntrl_pkts;
+ uint64_t rcv_pkt_lt_64bytes;
+ uint64_t rcv_pkt_lt_127bytes;
+ uint64_t rcv_pkt_lt_255bytes;
+ uint64_t rcv_pkt_lt_511bytes;
+ uint64_t rcv_pkt_lt_1023bytes;
+ uint64_t rcv_pkt_lt_1518bytes;
+ uint64_t rcv_pkt_gt_1518bytes;
+ uint64_t rsrvd1[3];
+ uint64_t rcv_len_error;
+ uint64_t rcv_len_small;
+ uint64_t rcv_len_large;
+ uint64_t rcv_jabber;
+ uint64_t rcv_dropped;
+ uint64_t fcs_error;
+ uint64_t align_error;
+} __packed q80_mac_stats_t;
+
+typedef struct _q80_get_stats {
+ uint16_t opcode;
+ uint16_t count_version;
+
+ uint32_t cmd;
+#define Q8_GET_STATS_CMD_CLEAR 0x01
+#define Q8_GET_STATS_CMD_RCV 0x00
+#define Q8_GET_STATS_CMD_XMT 0x02
+#define Q8_GET_STATS_CMD_TYPE_CNTXT 0x00
+#define Q8_GET_STATS_CMD_TYPE_MAC 0x04
+#define Q8_GET_STATS_CMD_TYPE_FUNC 0x08
+#define Q8_GET_STATS_CMD_TYPE_VPORT 0x0C
+
+} __packed q80_get_stats_t;
+
+typedef struct _q80_get_stats_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+ uint32_t cmd;
+ union {
+ q80_rcv_stats_t rcv;
+ q80_xmt_stats_t xmt;
+ q80_mac_stats_t mac;
+ } u;
+} __packed q80_get_stats_rsp_t;
+
+/*
+ * Init NIC Function
+ * Used to Register DCBX Configuration Change AEN
+ */
+typedef struct _q80_init_nic_func {
+ uint16_t opcode;
+ uint16_t count_version;
+
+ uint32_t options;
+#define Q8_INIT_NIC_REG_DCBX_CHNG_AEN 0x02
+#define Q8_INIT_NIC_REG_SFP_CHNG_AEN 0x04
+
+} __packed q80_init_nic_func_t;
+
+typedef struct _q80_init_nic_func_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_init_nic_func_rsp_t;
+
+/*
+ * Stop NIC Function
+ * Used to DeRegister DCBX Configuration Change AEN
+ */
+typedef struct _q80_stop_nic_func {
+ uint16_t opcode;
+ uint16_t count_version;
+
+ uint32_t options;
+#define Q8_STOP_NIC_DEREG_DCBX_CHNG_AEN 0x02
+#define Q8_STOP_NIC_DEREG_SFP_CHNG_AEN 0x04
+
+} __packed q80_stop_nic_func_t;
+
+typedef struct _q80_stop_nic_func_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_stop_nic_func_rsp_t;
+
+/*
+ * Query Firmware DCBX Capabilities
+ */
+typedef struct _q80_query_fw_dcbx_caps {
+ uint16_t opcode;
+ uint16_t count_version;
+} __packed q80_query_fw_dcbx_caps_t;
+
+typedef struct _q80_query_fw_dcbx_caps_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+
+ uint32_t dcbx_caps;
+#define Q8_QUERY_FW_DCBX_CAPS_TSA 0x00000001
+#define Q8_QUERY_FW_DCBX_CAPS_ETS 0x00000002
+#define Q8_QUERY_FW_DCBX_CAPS_DCBX_CEE_1_01 0x00000004
+#define Q8_QUERY_FW_DCBX_CAPS_DCBX_IEEE_1_0 0x00000008
+#define Q8_QUERY_FW_DCBX_MAX_TC_MASK 0x00F00000
+#define Q8_QUERY_FW_DCBX_MAX_ETS_TC_MASK 0x0F000000
+#define Q8_QUERY_FW_DCBX_MAX_PFC_TC_MASK 0xF0000000
+
+} __packed q80_query_fw_dcbx_caps_rsp_t;
+
+/*
+ * Set Port Configuration command
+ * Used to set Ethernet Standard Pause values
+ */
+
+typedef struct _q80_set_port_cfg {
+ uint16_t opcode;
+ uint16_t count_version;
+
+ uint32_t cfg_bits;
+
+#define Q8_PORT_CFG_BITS_LOOPBACK_MODE_MASK (0x7 << 1)
+#define Q8_PORT_CFG_BITS_LOOPBACK_MODE_NONE (0x0 << 1)
+#define Q8_PORT_CFG_BITS_LOOPBACK_MODE_HSS (0x2 << 1)
+#define Q8_PORT_CFG_BITS_LOOPBACK_MODE_PHY (0x3 << 1)
+#define Q8_PORT_CFG_BITS_LOOPBACK_MODE_EXT (0x4 << 1)
+
+#define Q8_VALID_LOOPBACK_MODE(mode) \
+ (((mode) == Q8_PORT_CFG_BITS_LOOPBACK_MODE_NONE) || \
+ (((mode) >= Q8_PORT_CFG_BITS_LOOPBACK_MODE_HSS) && \
+ ((mode) <= Q8_PORT_CFG_BITS_LOOPBACK_MODE_EXT)))
+
+#define Q8_PORT_CFG_BITS_DCBX_ENABLE BIT_4
+
+#define Q8_PORT_CFG_BITS_PAUSE_CFG_MASK (0x3 << 5)
+#define Q8_PORT_CFG_BITS_PAUSE_DISABLED (0x0 << 5)
+#define Q8_PORT_CFG_BITS_PAUSE_STD (0x1 << 5)
+#define Q8_PORT_CFG_BITS_PAUSE_PPM (0x2 << 5)
+
+#define Q8_PORT_CFG_BITS_LNKCAP_10MB BIT_8
+#define Q8_PORT_CFG_BITS_LNKCAP_100MB BIT_9
+#define Q8_PORT_CFG_BITS_LNKCAP_1GB BIT_10
+#define Q8_PORT_CFG_BITS_LNKCAP_10GB BIT_11
+
+#define Q8_PORT_CFG_BITS_AUTONEG BIT_15
+#define Q8_PORT_CFG_BITS_XMT_DISABLE BIT_17
+#define Q8_PORT_CFG_BITS_FEC_RQSTD BIT_18
+#define Q8_PORT_CFG_BITS_EEE_RQSTD BIT_19
+
+#define Q8_PORT_CFG_BITS_STDPAUSE_DIR_MASK (0x3 << 20)
+#define Q8_PORT_CFG_BITS_STDPAUSE_XMT_RCV (0x0 << 20)
+#define Q8_PORT_CFG_BITS_STDPAUSE_XMT (0x1 << 20)
+#define Q8_PORT_CFG_BITS_STDPAUSE_RCV (0x2 << 20)
+
+} __packed q80_set_port_cfg_t;
+
+typedef struct _q80_set_port_cfg_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_set_port_cfg_rsp_t;
+
+/*
+ * Get Port Configuration Command
+ */
+
+typedef struct _q80_get_port_cfg {
+ uint16_t opcode;
+ uint16_t count_version;
+} __packed q80_get_port_cfg_t;
+
+typedef struct _q80_get_port_cfg_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+
+ uint32_t cfg_bits; /* same as in q80_set_port_cfg_t */
+
+ uint8_t phys_port_type;
+ uint8_t rsvd[3];
+} __packed q80_get_port_cfg_rsp_t;
+
+/*
+ * Get Link Status Command
+ * Used to get current PAUSE values for the port
+ */
+
+typedef struct _q80_get_link_status {
+ uint16_t opcode;
+ uint16_t count_version;
+} __packed q80_get_link_status_t;
+
+typedef struct _q80_get_link_status_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+
+ uint32_t cfg_bits;
+#define Q8_GET_LINK_STAT_CFG_BITS_LINK_UP BIT_0
+
+#define Q8_GET_LINK_STAT_CFG_BITS_LINK_SPEED_MASK (0x7 << 3)
+#define Q8_GET_LINK_STAT_CFG_BITS_LINK_SPEED_UNKNOWN (0x0 << 3)
+#define Q8_GET_LINK_STAT_CFG_BITS_LINK_SPEED_10MB (0x1 << 3)
+#define Q8_GET_LINK_STAT_CFG_BITS_LINK_SPEED_100MB (0x2 << 3)
+#define Q8_GET_LINK_STAT_CFG_BITS_LINK_SPEED_1GB (0x3 << 3)
+#define Q8_GET_LINK_STAT_CFG_BITS_LINK_SPEED_10GB (0x4 << 3)
+
+#define Q8_GET_LINK_STAT_CFG_BITS_PAUSE_CFG_MASK (0x3 << 6)
+#define Q8_GET_LINK_STAT_CFG_BITS_PAUSE_CFG_DISABLE (0x0 << 6)
+#define Q8_GET_LINK_STAT_CFG_BITS_PAUSE_CFG_STD (0x1 << 6)
+#define Q8_GET_LINK_STAT_CFG_BITS_PAUSE_CFG_PPM (0x2 << 6)
+
+#define Q8_GET_LINK_STAT_CFG_BITS_LOOPBACK_MASK (0x7 << 8)
+#define Q8_GET_LINK_STAT_CFG_BITS_LOOPBACK_NONE (0x0 << 6)
+#define Q8_GET_LINK_STAT_CFG_BITS_LOOPBACK_HSS (0x2 << 6)
+#define Q8_GET_LINK_STAT_CFG_BITS_LOOPBACK_PHY (0x3 << 6)
+
+#define Q8_GET_LINK_STAT_CFG_BITS_FEC_ENABLED BIT_12
+#define Q8_GET_LINK_STAT_CFG_BITS_EEE_ENABLED BIT_13
+
+#define Q8_GET_LINK_STAT_CFG_BITS_STDPAUSE_DIR_MASK (0x3 << 20)
+#define Q8_GET_LINK_STAT_CFG_BITS_STDPAUSE_NONE (0x0 << 20)
+#define Q8_GET_LINK_STAT_CFG_BITS_STDPAUSE_XMT (0x1 << 20)
+#define Q8_GET_LINK_STAT_CFG_BITS_STDPAUSE_RCV (0x2 << 20)
+#define Q8_GET_LINK_STAT_CFG_BITS_STDPAUSE_XMT_RCV (0x3 << 20)
+
+ uint32_t link_state;
+#define Q8_GET_LINK_STAT_LOSS_OF_SIGNAL BIT_0
+#define Q8_GET_LINK_STAT_PORT_RST_DONE BIT_3
+#define Q8_GET_LINK_STAT_PHY_LINK_DOWN BIT_4
+#define Q8_GET_LINK_STAT_PCS_LINK_DOWN BIT_5
+#define Q8_GET_LINK_STAT_MAC_LOCAL_FAULT BIT_6
+#define Q8_GET_LINK_STAT_MAC_REMOTE_FAULT BIT_7
+#define Q8_GET_LINK_STAT_XMT_DISABLED BIT_9
+#define Q8_GET_LINK_STAT_SFP_XMT_FAULT BIT_10
+
+ uint32_t sfp_info;
+#define Q8_GET_LINK_STAT_SFP_TRNCVR_MASK 0x3
+#define Q8_GET_LINK_STAT_SFP_TRNCVR_NOT_EXPECTED 0x0
+#define Q8_GET_LINK_STAT_SFP_TRNCVR_NONE 0x1
+#define Q8_GET_LINK_STAT_SFP_TRNCVR_INVALID 0x2
+#define Q8_GET_LINK_STAT_SFP_TRNCVR_VALID 0x3
+
+#define Q8_GET_LINK_STAT_SFP_ADDTL_INFO_MASK (0x3 << 2)
+#define Q8_GET_LINK_STAT_SFP_ADDTL_INFO_UNREC_TRSVR (0x0 << 2)
+#define Q8_GET_LINK_STAT_SFP_ADDTL_INFO_NOT_QLOGIC (0x1 << 2)
+#define Q8_GET_LINK_STAT_SFP_ADDTL_INFO_SPEED_FAILED (0x2 << 2)
+#define Q8_GET_LINK_STAT_SFP_ADDTL_INFO_ACCESS_ERROR (0x3 << 2)
+
+#define Q8_GET_LINK_STAT_SFP_MOD_TYPE_MASK (0x1F << 4)
+#define Q8_GET_LINK_STAT_SFP_MOD_NONE (0x00 << 4)
+#define Q8_GET_LINK_STAT_SFP_MOD_10GBLRM (0x01 << 4)
+#define Q8_GET_LINK_STAT_SFP_MOD_10GBLR (0x02 << 4)
+#define Q8_GET_LINK_STAT_SFP_MOD_10GBSR (0x03 << 4)
+#define Q8_GET_LINK_STAT_SFP_MOD_10GBC_P (0x04 << 4)
+#define Q8_GET_LINK_STAT_SFP_MOD_10GBC_AL (0x05 << 4)
+#define Q8_GET_LINK_STAT_SFP_MOD_10GBC_PL (0x06 << 4)
+#define Q8_GET_LINK_STAT_SFP_MOD_1GBSX (0x07 << 4)
+#define Q8_GET_LINK_STAT_SFP_MOD_1GBLX (0x08 << 4)
+#define Q8_GET_LINK_STAT_SFP_MOD_1GBCX (0x09 << 4)
+#define Q8_GET_LINK_STAT_SFP_MOD_1GBT (0x0A << 4)
+#define Q8_GET_LINK_STAT_SFP_MOD_1GBC_PL (0x0B << 4)
+#define Q8_GET_LINK_STAT_SFP_MOD_UNKNOWN (0x0F << 4)
+
+#define Q8_GET_LINK_STAT_SFP_MULTI_RATE_MOD BIT_9
+#define Q8_GET_LINK_STAT_SFP_XMT_FAULT BIT_10
+#define Q8_GET_LINK_STAT_SFP_COPPER_CBL_LENGTH_MASK (0xFF << 16)
+
+} __packed q80_get_link_status_rsp_t;
+
+
+/*
+ * Transmit Related Definitions
+ */
+/* Max# of TX Rings per Tx Create Cntxt Mbx Cmd*/
+#define MAX_TCNTXT_RINGS 8
+
+/*
+ * Transmit Context - Q8_CMD_CREATE_TX_CNTXT Command Configuration Data
+ */
+
+typedef struct _q80_rq_tx_ring {
+ uint64_t paddr;
+ uint64_t tx_consumer;
+ uint16_t nentries;
+ uint16_t intr_id;
+ uint8_t intr_src_bit;
+ uint8_t rsrvd[3];
+} __packed q80_rq_tx_ring_t;
+
+typedef struct _q80_rq_tx_cntxt {
+ uint16_t opcode;
+ uint16_t count_version;
+
+ uint32_t cap0;
+#define Q8_TX_CNTXT_CAP0_BASEFW (1 << 0)
+#define Q8_TX_CNTXT_CAP0_LSO (1 << 6)
+#define Q8_TX_CNTXT_CAP0_TC (1 << 25)
+
+ uint32_t cap1;
+ uint32_t cap2;
+ uint32_t cap3;
+ uint8_t ntx_rings;
+ uint8_t traffic_class; /* bits 8-10; others reserved */
+ uint16_t tx_vpid;
+ q80_rq_tx_ring_t tx_ring[MAX_TCNTXT_RINGS];
+} __packed q80_rq_tx_cntxt_t;
+
+typedef struct _q80_rsp_tx_ring {
+ uint32_t prod_index;
+ uint16_t cntxt_id;
+ uint8_t state;
+ uint8_t rsrvd;
+} q80_rsp_tx_ring_t;
+
+typedef struct _q80_rsp_tx_cntxt {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+ uint8_t ntx_rings;
+ uint8_t phy_port;
+ uint8_t virt_port;
+ uint8_t rsrvd;
+ q80_rsp_tx_ring_t tx_ring[MAX_TCNTXT_RINGS];
+} __packed q80_rsp_tx_cntxt_t;
+
+typedef struct _q80_tx_cntxt_destroy {
+ uint16_t opcode;
+ uint16_t count_version;
+ uint32_t cntxt_id;
+} __packed q80_tx_cntxt_destroy_t;
+
+typedef struct _q80_tx_cntxt_destroy_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_tx_cntxt_destroy_rsp_t;
+
+/*
+ * Transmit Command Descriptor
+ * These commands are issued on the Transmit Ring associated with a Transmit
+ * context
+ */
+typedef struct _q80_tx_cmd {
+ uint8_t tcp_hdr_off; /* TCP Header Offset */
+ uint8_t ip_hdr_off; /* IP Header Offset */
+ uint16_t flags_opcode; /* Bits 0-6: flags; 7-12: opcode */
+
+ /* flags field */
+#define Q8_TX_CMD_FLAGS_MULTICAST 0x01
+#define Q8_TX_CMD_FLAGS_LSO_TSO 0x02
+#define Q8_TX_CMD_FLAGS_VLAN_TAGGED 0x10
+#define Q8_TX_CMD_FLAGS_HW_VLAN_ID 0x40
+
+ /* opcode field */
+#define Q8_TX_CMD_OP_XMT_UDP_CHKSUM_IPV6 (0xC << 7)
+#define Q8_TX_CMD_OP_XMT_TCP_CHKSUM_IPV6 (0xB << 7)
+#define Q8_TX_CMD_OP_XMT_TCP_LSO_IPV6 (0x6 << 7)
+#define Q8_TX_CMD_OP_XMT_TCP_LSO (0x5 << 7)
+#define Q8_TX_CMD_OP_XMT_UDP_CHKSUM (0x3 << 7)
+#define Q8_TX_CMD_OP_XMT_TCP_CHKSUM (0x2 << 7)
+#define Q8_TX_CMD_OP_XMT_ETHER (0x1 << 7)
+
+ uint8_t n_bufs; /* # of data segs in data buffer */
+ uint8_t data_len_lo; /* data length lower 8 bits */
+ uint16_t data_len_hi; /* data length upper 16 bits */
+
+ uint64_t buf2_addr; /* buffer 2 address */
+
+ uint16_t rsrvd0;
+ uint16_t mss; /* MSS for this packet */
+ uint8_t cntxtid; /* Bits 7-4: ContextId; 3-0: reserved */
+
+#define Q8_TX_CMD_PORT_CNXTID(c_id) ((c_id & 0xF) << 4)
+
+ uint8_t total_hdr_len; /* MAC+IP+TCP Header Length for LSO */
+ uint16_t rsrvd1;
+
+ uint64_t buf3_addr; /* buffer 3 address */
+ uint64_t buf1_addr; /* buffer 1 address */
+
+ uint16_t buf1_len; /* length of buffer 1 */
+ uint16_t buf2_len; /* length of buffer 2 */
+ uint16_t buf3_len; /* length of buffer 3 */
+ uint16_t buf4_len; /* length of buffer 4 */
+
+ uint64_t buf4_addr; /* buffer 4 address */
+
+ uint32_t rsrvd2;
+ uint16_t rsrvd3;
+ uint16_t vlan_tci; /* VLAN TCI when hw tagging is enabled*/
+
+} __packed q80_tx_cmd_t; /* 64 bytes */
+
+#define Q8_TX_CMD_MAX_SEGMENTS 4
+#define Q8_TX_CMD_TSO_ALIGN 2
+#define Q8_TX_MAX_NON_TSO_SEGS 62
+
+
+/*
+ * Receive Related Definitions
+ */
+#define MAX_RDS_RING_SETS 8 /* Max# of Receive Descriptor Rings */
+#define MAX_SDS_RINGS 4 /* Max# of Status Descriptor Rings */
+
+typedef struct _q80_rq_sds_ring {
+ uint64_t paddr; /* physical addr of status ring in system memory */
+ uint64_t hdr_split1;
+ uint64_t hdr_split2;
+ uint16_t size; /* number of entries in status ring */
+ uint16_t hdr_split1_size;
+ uint16_t hdr_split2_size;
+ uint16_t hdr_split_count;
+ uint16_t intr_id;
+ uint8_t intr_src_bit;
+ uint8_t rsrvd[5];
+} __packed q80_rq_sds_ring_t; /* 10 32bit words */
+
+typedef struct _q80_rq_rds_ring {
+ uint64_t paddr_std; /* physical addr of rcv ring in system memory */
+ uint64_t paddr_jumbo; /* physical addr of rcv ring in system memory */
+ uint16_t std_bsize;
+ uint16_t std_nentries;
+ uint16_t jumbo_bsize;
+ uint16_t jumbo_nentries;
+} __packed q80_rq_rds_ring_t; /* 6 32bit words */
+
+#define MAX_RCNTXT_SDS_RINGS 8
+
+typedef struct _q80_rq_rcv_cntxt {
+ uint16_t opcode;
+ uint16_t count_version;
+ uint32_t cap0;
+#define Q8_RCV_CNTXT_CAP0_BASEFW (1 << 0)
+#define Q8_RCV_CNTXT_CAP0_MULTI_RDS (1 << 1)
+#define Q8_RCV_CNTXT_CAP0_LRO (1 << 5)
+#define Q8_RCV_CNTXT_CAP0_HW_LRO (1 << 10)
+#define Q8_RCV_CNTXT_CAP0_VLAN_ALIGN (1 << 14)
+#define Q8_RCV_CNTXT_CAP0_RSS (1 << 15)
+#define Q8_RCV_CNTXT_CAP0_MSFT_RSS (1 << 16)
+#define Q8_RCV_CNTXT_CAP0_SGL_JUMBO (1 << 18)
+#define Q8_RCV_CNTXT_CAP0_SGL_LRO (1 << 19)
+
+ uint32_t cap1;
+ uint32_t cap2;
+ uint32_t cap3;
+ uint8_t nrds_sets_rings;
+ uint8_t nsds_rings;
+ uint16_t rds_producer_mode;
+#define Q8_RCV_CNTXT_RDS_PROD_MODE_UNIQUE 0
+#define Q8_RCV_CNTXT_RDS_PROD_MODE_SHARED 1
+
+ uint16_t rcv_vpid;
+ uint16_t rsrvd0;
+ uint32_t rsrvd1;
+ q80_rq_sds_ring_t sds[MAX_RCNTXT_SDS_RINGS];
+ q80_rq_rds_ring_t rds[MAX_RDS_RING_SETS];
+} __packed q80_rq_rcv_cntxt_t;
+
+typedef struct _q80_rsp_rds_ring {
+ uint32_t prod_std;
+ uint32_t prod_jumbo;
+} __packed q80_rsp_rds_ring_t; /* 8 bytes */
+
+typedef struct _q80_rsp_rcv_cntxt {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+ uint8_t nrds_sets_rings;
+ uint8_t nsds_rings;
+ uint16_t cntxt_id;
+ uint8_t state;
+ uint8_t num_funcs;
+ uint8_t phy_port;
+ uint8_t virt_port;
+ uint32_t sds_cons[MAX_RCNTXT_SDS_RINGS];
+ q80_rsp_rds_ring_t rds[MAX_RDS_RING_SETS];
+} __packed q80_rsp_rcv_cntxt_t;
+
+typedef struct _q80_rcv_cntxt_destroy {
+ uint16_t opcode;
+ uint16_t count_version;
+ uint32_t cntxt_id;
+} __packed q80_rcv_cntxt_destroy_t;
+
+typedef struct _q80_rcv_cntxt_destroy_rsp {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+} __packed q80_rcv_cntxt_destroy_rsp_t;
+
+
+/*
+ * Add Receive Rings
+ */
+typedef struct _q80_rq_add_rcv_rings {
+ uint16_t opcode;
+ uint16_t count_version;
+ uint8_t nrds_sets_rings;
+ uint8_t nsds_rings;
+ uint16_t cntxt_id;
+ q80_rq_sds_ring_t sds[MAX_RCNTXT_SDS_RINGS];
+ q80_rq_rds_ring_t rds[MAX_RDS_RING_SETS];
+} __packed q80_rq_add_rcv_rings_t;
+
+typedef struct _q80_rsp_add_rcv_rings {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+ uint8_t nrds_sets_rings;
+ uint8_t nsds_rings;
+ uint16_t cntxt_id;
+ uint32_t sds_cons[MAX_RCNTXT_SDS_RINGS];
+ q80_rsp_rds_ring_t rds[MAX_RDS_RING_SETS];
+} __packed q80_rsp_add_rcv_rings_t;
+
+/*
+ * Map Status Ring to Receive Descriptor Set
+ */
+
+#define MAX_SDS_TO_RDS_MAP 16
+
+typedef struct _q80_sds_rds_map_e {
+ uint8_t sds_ring;
+ uint8_t rsrvd0;
+ uint8_t rds_ring;
+ uint8_t rsrvd1;
+} __packed q80_sds_rds_map_e_t;
+
+typedef struct _q80_rq_map_sds_to_rds {
+ uint16_t opcode;
+ uint16_t count_version;
+ uint16_t cntxt_id;
+ uint16_t num_rings;
+ q80_sds_rds_map_e_t sds_rds[MAX_SDS_TO_RDS_MAP];
+} __packed q80_rq_map_sds_to_rds_t;
+
+
+typedef struct _q80_rsp_map_sds_to_rds {
+ uint16_t opcode;
+ uint16_t regcnt_status;
+ uint16_t cntxt_id;
+ uint16_t num_rings;
+ q80_sds_rds_map_e_t sds_rds[MAX_SDS_TO_RDS_MAP];
+} __packed q80_rsp_map_sds_to_rds_t;
+
+
+/*
+ * Receive Descriptor corresponding to each entry in the receive ring
+ */
+typedef struct _q80_rcv_desc {
+ uint16_t handle;
+ uint16_t rsrvd;
+ uint32_t buf_size; /* buffer size in bytes */
+ uint64_t buf_addr; /* physical address of buffer */
+} __packed q80_recv_desc_t;
+
+/*
+ * Status Descriptor corresponding to each entry in the Status ring
+ */
+typedef struct _q80_stat_desc {
+ uint64_t data[2];
+} __packed q80_stat_desc_t;
+
+/*
+ * definitions for data[0] field of Status Descriptor
+ */
+#define Q8_STAT_DESC_RSS_HASH(data) (data & 0xFFFFFFFF)
+#define Q8_STAT_DESC_TOTAL_LENGTH(data) ((data >> 32) & 0x3FFF)
+#define Q8_STAT_DESC_TOTAL_LENGTH_SGL_RCV(data) ((data >> 32) & 0xFFFF)
+#define Q8_STAT_DESC_HANDLE(data) ((data >> 48) & 0xFFFF)
+/*
+ * definitions for data[1] field of Status Descriptor
+ */
+
+#define Q8_STAT_DESC_OPCODE(data) ((data >> 42) & 0xF)
+#define Q8_STAT_DESC_OPCODE_RCV_PKT 0x01
+#define Q8_STAT_DESC_OPCODE_LRO_PKT 0x02
+#define Q8_STAT_DESC_OPCODE_SGL_LRO 0x04
+#define Q8_STAT_DESC_OPCODE_SGL_RCV 0x05
+#define Q8_STAT_DESC_OPCODE_CONT 0x06
+
+/*
+ * definitions for data[1] field of Status Descriptor for standard frames
+ * status descriptor opcode equals 0x04
+ */
+#define Q8_STAT_DESC_STATUS(data) ((data >> 39) & 0x0007)
+#define Q8_STAT_DESC_STATUS_CHKSUM_NOT_DONE 0x00
+#define Q8_STAT_DESC_STATUS_NO_CHKSUM 0x01
+#define Q8_STAT_DESC_STATUS_CHKSUM_OK 0x02
+#define Q8_STAT_DESC_STATUS_CHKSUM_ERR 0x03
+
+#define Q8_STAT_DESC_VLAN(data) ((data >> 47) & 1)
+#define Q8_STAT_DESC_VLAN_ID(data) ((data >> 48) & 0xFFFF)
+
+#define Q8_STAT_DESC_PROTOCOL(data) ((data >> 44) & 0x000F)
+#define Q8_STAT_DESC_L2_OFFSET(data) ((data >> 48) & 0x001F)
+#define Q8_STAT_DESC_COUNT(data) ((data >> 37) & 0x0007)
+
+/*
+ * definitions for data[0-1] fields of Status Descriptor for LRO
+ * status descriptor opcode equals 0x04
+ */
+
+/* definitions for data[1] field */
+#define Q8_LRO_STAT_DESC_SEQ_NUM(data) (uint32_t)(data)
+
+/*
+ * definitions specific to opcode 0x04 data[1]
+ */
+#define Q8_STAT_DESC_COUNT_SGL_LRO(data) ((data >> 13) & 0x0007)
+#define Q8_SGL_LRO_STAT_L2_OFFSET(data) ((data >> 16) & 0xFF)
+#define Q8_SGL_LRO_STAT_L4_OFFSET(data) ((data >> 24) & 0xFF)
+#define Q8_SGL_LRO_STAT_TS(data) ((data >> 40) & 0x1)
+#define Q8_SGL_LRO_STAT_PUSH_BIT(data) ((data >> 41) & 0x1)
+
+
+/*
+ * definitions specific to opcode 0x05 data[1]
+ */
+#define Q8_STAT_DESC_COUNT_SGL_RCV(data) ((data >> 37) & 0x0003)
+
+/*
+ * definitions for opcode 0x06
+ */
+/* definitions for data[0] field */
+#define Q8_SGL_STAT_DESC_HANDLE1(data) (data & 0xFFFF)
+#define Q8_SGL_STAT_DESC_HANDLE2(data) ((data >> 16) & 0xFFFF)
+#define Q8_SGL_STAT_DESC_HANDLE3(data) ((data >> 32) & 0xFFFF)
+#define Q8_SGL_STAT_DESC_HANDLE4(data) ((data >> 48) & 0xFFFF)
+
+/* definitions for data[1] field */
+#define Q8_SGL_STAT_DESC_HANDLE5(data) (data & 0xFFFF)
+#define Q8_SGL_STAT_DESC_HANDLE6(data) ((data >> 16) & 0xFFFF)
+#define Q8_SGL_STAT_DESC_NUM_HANDLES(data) ((data >> 32) & 0x7)
+#define Q8_SGL_STAT_DESC_HANDLE7(data) ((data >> 48) & 0xFFFF)
+
+/** Driver Related Definitions Begin **/
+
+#define TX_SMALL_PKT_SIZE 128 /* size in bytes of small packets */
+
+/* The number of descriptors should be a power of 2 */
+#define NUM_TX_DESCRIPTORS 1024
+#define NUM_STATUS_DESCRIPTORS 1024
+
+
+#define NUM_RX_DESCRIPTORS 2048
+#define MAX_RDS_RINGS MAX_SDS_RINGS /* Max# of Rcv Descriptor Rings */
+
+/*
+ * structure describing various dma buffers
+ */
+
+typedef struct qla_dmabuf {
+ volatile struct {
+ uint32_t tx_ring :1,
+ rds_ring :1,
+ sds_ring :1,
+ minidump :1;
+ } flags;
+
+ qla_dma_t tx_ring;
+ qla_dma_t rds_ring[MAX_RDS_RINGS];
+ qla_dma_t sds_ring[MAX_SDS_RINGS];
+ qla_dma_t minidump;
+} qla_dmabuf_t;
+
+typedef struct _qla_sds {
+ q80_stat_desc_t *sds_ring_base; /* start of sds ring */
+ uint32_t sdsr_next; /* next entry in SDS ring to process */
+ struct lro_ctrl lro;
+ void *rxb_free;
+ uint32_t rx_free;
+ volatile uint32_t rcv_active;
+ uint32_t sds_consumer;
+ uint64_t intr_count;
+} qla_sds_t;
+
+#define Q8_MAX_LRO_CONT_DESC 7
+#define Q8_MAX_HANDLES_LRO (1 + (Q8_MAX_LRO_CONT_DESC * 7))
+#define Q8_MAX_HANDLES_NON_LRO 8
+
+typedef struct _qla_sgl_rcv {
+ uint16_t pkt_length;
+ uint16_t num_handles;
+ uint16_t chksum_status;
+ uint32_t rss_hash;
+ uint16_t rss_hash_flags;
+ uint16_t vlan_tag;
+ uint16_t handle[Q8_MAX_HANDLES_NON_LRO];
+} qla_sgl_rcv_t;
+
+typedef struct _qla_sgl_lro {
+ uint16_t flags;
+#define Q8_LRO_COMP_TS 0x1
+#define Q8_LRO_COMP_PUSH_BIT 0x2
+ uint16_t l2_offset;
+ uint16_t l4_offset;
+
+ uint16_t payload_length;
+ uint16_t num_handles;
+ uint32_t rss_hash;
+ uint16_t rss_hash_flags;
+ uint16_t vlan_tag;
+ uint16_t handle[Q8_MAX_HANDLES_LRO];
+} qla_sgl_lro_t;
+
+typedef union {
+ qla_sgl_rcv_t rcv;
+ qla_sgl_lro_t lro;
+} qla_sgl_comp_t;
+
+#define QL_FRAME_HDR_SIZE (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN +\
+ sizeof (struct ip6_hdr) + sizeof (struct tcphdr) + 16)
+
+typedef struct _qla_hw_tx_cntxt {
+ q80_tx_cmd_t *tx_ring_base;
+ bus_addr_t tx_ring_paddr;
+
+ volatile uint32_t *tx_cons; /* tx consumer shadow reg */
+ bus_addr_t tx_cons_paddr;
+
+ volatile uint32_t txr_free; /* # of free entries in tx ring */
+ volatile uint32_t txr_next; /* # next available tx ring entry */
+ volatile uint32_t txr_comp; /* index of last tx entry completed */
+
+ uint32_t tx_prod_reg;
+ uint16_t tx_cntxt_id;
+ uint8_t frame_hdr[QL_FRAME_HDR_SIZE];
+
+} qla_hw_tx_cntxt_t;
+
+typedef struct _qla_mcast {
+ uint16_t rsrvd;
+ uint8_t addr[6];
+} __packed qla_mcast_t;
+
+typedef struct _qla_rdesc {
+ volatile uint32_t prod_std;
+ volatile uint32_t prod_jumbo;
+ volatile uint32_t rx_next; /* next standard rcv ring to arm fw */
+ volatile int32_t rx_in; /* next standard rcv ring to add mbufs */
+ volatile uint64_t count;
+} qla_rdesc_t;
+
+typedef struct _qla_flash_desc_table {
+ uint32_t flash_valid;
+ uint16_t flash_ver;
+ uint16_t flash_len;
+ uint16_t flash_cksum;
+ uint16_t flash_unused;
+ uint8_t flash_model[16];
+ uint16_t flash_manuf;
+ uint16_t flash_id;
+ uint8_t flash_flag;
+ uint8_t erase_cmd;
+ uint8_t alt_erase_cmd;
+ uint8_t write_enable_cmd;
+ uint8_t write_enable_bits;
+ uint8_t write_statusreg_cmd;
+ uint8_t unprotected_sec_cmd;
+ uint8_t read_manuf_cmd;
+ uint32_t block_size;
+ uint32_t alt_block_size;
+ uint32_t flash_size;
+ uint32_t write_enable_data;
+ uint8_t readid_addr_len;
+ uint8_t write_disable_bits;
+ uint8_t read_dev_id_len;
+ uint8_t chip_erase_cmd;
+ uint16_t read_timeo;
+ uint8_t protected_sec_cmd;
+ uint8_t resvd[65];
+} __packed qla_flash_desc_table_t;
+
+#define NUM_TX_RINGS 4
+
+/*
+ * struct for storing hardware specific information for a given interface
+ */
+typedef struct _qla_hw {
+ struct {
+ uint32_t
+ unicast_mac :1,
+ bcast_mac :1,
+ loopback_mode :2,
+ init_tx_cnxt :1,
+ init_rx_cnxt :1,
+ init_intr_cnxt :1,
+ fduplex :1,
+ autoneg :1,
+ fdt_valid :1;
+ } flags;
+
+
+ uint16_t link_speed;
+ uint16_t cable_length;
+ uint32_t cable_oui;
+ uint8_t link_up;
+ uint8_t module_type;
+ uint8_t link_faults;
+
+ uint8_t mac_rcv_mode;
+
+ uint32_t max_mtu;
+
+ uint8_t mac_addr[ETHER_ADDR_LEN];
+
+ uint32_t num_sds_rings;
+ uint32_t num_rds_rings;
+ uint32_t num_tx_rings;
+
+ qla_dmabuf_t dma_buf;
+
+ /* Transmit Side */
+
+ qla_hw_tx_cntxt_t tx_cntxt[NUM_TX_RINGS];
+
+ /* Receive Side */
+
+ uint16_t rcv_cntxt_id;
+
+ uint32_t mbx_intr_mask_offset;
+
+ uint16_t intr_id[MAX_SDS_RINGS];
+ uint32_t intr_src[MAX_SDS_RINGS];
+
+ qla_sds_t sds[MAX_SDS_RINGS];
+ uint32_t mbox[Q8_NUM_MBOX];
+ qla_rdesc_t rds[MAX_RDS_RINGS];
+
+ uint32_t rds_pidx_thres;
+ uint32_t sds_cidx_thres;
+
+ /* multicast address list */
+ uint32_t nmcast;
+ qla_mcast_t mcast[Q8_MAX_NUM_MULTICAST_ADDRS];
+
+ /* reset sequence */
+#define Q8_MAX_RESET_SEQ_IDX 16
+ uint32_t rst_seq[Q8_MAX_RESET_SEQ_IDX];
+ uint32_t rst_seq_idx;
+
+ /* heart beat register value */
+ uint32_t hbeat_value;
+ uint32_t health_count;
+
+ uint32_t max_tx_segs;
+
+ /* Flash Descriptor Table */
+ qla_flash_desc_table_t fdt;
+
+ /* Minidump Related */
+ uint32_t mdump_init;
+ uint32_t mdump_start;
+ uint32_t mdump_active;
+ uint32_t mdump_start_seq_index;
+} qla_hw_t;
+
+#define QL_UPDATE_RDS_PRODUCER_INDEX(ha, prod_reg, val) \
+ WRITE_REG32(ha, prod_reg, val);
+
+#define QL_UPDATE_TX_PRODUCER_INDEX(ha, val, i) \
+ WRITE_REG32(ha, ha->hw.tx_cntxt[i].tx_prod_reg, val)
+
+#define QL_UPDATE_SDS_CONSUMER_INDEX(ha, i, val) \
+ WRITE_REG32(ha, ha->hw.sds[i].sds_consumer, val)
+
+#define QL_ENABLE_INTERRUPTS(ha, i) WRITE_REG32(ha, ha->hw.intr_src[i], 0);
+
+
+#define QL_BUFFER_ALIGN 16
+
+
+/*
+ * Flash Configuration
+ */
+#define Q8_BOARD_CONFIG_OFFSET 0x370000
+#define Q8_BOARD_CONFIG_LENGTH 0x2000
+
+#define Q8_BOARD_CONFIG_MAC0_LO 0x400
+
+#define Q8_FDT_LOCK_MAGIC_ID 0x00FD00FD
+#define Q8_FDT_FLASH_ADDR_VAL 0xFD009F
+#define Q8_FDT_FLASH_CTRL_VAL 0x3F
+#define Q8_FDT_MASK_VAL 0xFF
+
+#define Q8_WR_ENABLE_FL_ADDR 0xFD0100
+#define Q8_WR_ENABLE_FL_CTRL 0x5
+
+#define Q8_ERASE_LOCK_MAGIC_ID 0x00EF00EF
+#define Q8_ERASE_FL_ADDR_MASK 0xFD0300
+#define Q8_ERASE_FL_CTRL_MASK 0x3D
+
+#define Q8_WR_FL_LOCK_MAGIC_ID 0xABCDABCD
+#define Q8_WR_FL_ADDR_MASK 0x800000
+#define Q8_WR_FL_CTRL_MASK 0x3D
+
+#define QL_FDT_OFFSET 0x3F0000
+#define Q8_FLASH_SECTOR_SIZE 0x10000
+
+/*
+ * Off Chip Memory Access
+ */
+
+typedef struct _q80_offchip_mem_val {
+ uint32_t data_lo;
+ uint32_t data_hi;
+ uint32_t data_ulo;
+ uint32_t data_uhi;
+} q80_offchip_mem_val_t;
+
+#endif /* #ifndef _QL_HW_H_ */
diff --git a/sys/dev/qlxgbe/ql_inline.h b/sys/dev/qlxgbe/ql_inline.h
new file mode 100644
index 000000000000..b69270270e0c
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_inline.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/*
+ * File: ql_inline.h
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ */
+#ifndef _QL_INLINE_H_
+#define _QL_INLINE_H_
+
+
+#define QL8_SEMLOCK_TIMEOUT 1000/* QLA8020 Semaphore Lock Timeout 10ms */
+
+
+/*
+ * Inline functions for hardware semaphores
+ */
+
+/*
+ * Name: qla_sem_lock
+ * Function: Locks one of the semaphore registers (semaphore 2,3,5 & 7)
+ * If the id_reg is valid, then id_val is written into it.
+ * This is for debugging purpose
+ * Returns: 0 on success; otherwise its failed.
+ */
+static __inline int
+qla_sem_lock(qla_host_t *ha, uint32_t sem_reg, uint32_t id_reg, uint32_t id_val)
+{
+ int count = QL8_SEMLOCK_TIMEOUT;
+
+ while (count) {
+ if ((READ_REG32(ha, sem_reg) & BIT_0))
+ break;
+ count--;
+
+ if (!count)
+ return(-1);
+ qla_mdelay(__func__, 10);
+ }
+ if (id_reg)
+ WRITE_REG32(ha, id_reg, id_val);
+
+ return(0);
+}
+
+/*
+ * Name: qla_sem_unlock
+ * Function: Unlocks the semaphore registers (semaphore 2,3,5 & 7)
+ * previously locked by qla_sem_lock()
+ */
+static __inline void
+qla_sem_unlock(qla_host_t *ha, uint32_t sem_reg)
+{
+ READ_REG32(ha, sem_reg);
+}
+
+static __inline int
+qla_get_ifq_snd_maxlen(qla_host_t *ha)
+{
+ return(((NUM_TX_DESCRIPTORS * 4) - 1));
+}
+
+static __inline uint32_t
+qla_get_optics(qla_host_t *ha)
+{
+ uint32_t link_speed;
+
+ link_speed = READ_REG32(ha, Q8_LINK_SPEED_0);
+ if (ha->pci_func == 0)
+ link_speed = link_speed & 0xFF;
+ else
+ link_speed = (link_speed >> 8) & 0xFF;
+
+ switch (link_speed) {
+ case 0x1:
+ link_speed = IFM_100_FX;
+ break;
+
+ case 0x10:
+ link_speed = IFM_1000_SX;
+ break;
+
+ default:
+ if ((ha->hw.module_type == 0x4) ||
+ (ha->hw.module_type == 0x5) ||
+ (ha->hw.module_type == 0x6))
+ link_speed = (IFM_10G_TWINAX);
+ else
+ link_speed = (IFM_10G_LR | IFM_10G_SR);
+ break;
+ }
+
+ return(link_speed);
+}
+
+static __inline uint8_t *
+qla_get_mac_addr(qla_host_t *ha)
+{
+ return (ha->hw.mac_addr);
+}
+
+static __inline void
+qla_set_hw_rcv_desc(qla_host_t *ha, uint32_t r_idx, uint32_t index,
+ uint32_t handle, bus_addr_t paddr, uint32_t buf_size)
+{
+ volatile q80_recv_desc_t *rcv_desc;
+
+ rcv_desc = (q80_recv_desc_t *)ha->hw.dma_buf.rds_ring[r_idx].dma_b;
+
+ rcv_desc += index;
+
+ rcv_desc->handle = (uint16_t)handle;
+ rcv_desc->buf_size = buf_size;
+ rcv_desc->buf_addr = paddr;
+
+ return;
+}
+
+static __inline void
+qla_init_hw_rcv_descriptors(qla_host_t *ha)
+{
+ int i;
+
+ for (i = 0; i < ha->hw.num_rds_rings; i++)
+ bzero((void *)ha->hw.dma_buf.rds_ring[i].dma_b,
+ (sizeof(q80_recv_desc_t) * NUM_RX_DESCRIPTORS));
+}
+
+static __inline int
+qla_lock(qla_host_t *ha, const char *str, uint32_t no_delay)
+{
+ int ret = -1;
+
+ while (1) {
+ mtx_lock(&ha->hw_lock);
+ if (!ha->hw_lock_held) {
+ ha->hw_lock_held = 1;
+ ha->qla_lock = str;
+ ret = 0;
+ mtx_unlock(&ha->hw_lock);
+ break;
+ }
+ mtx_unlock(&ha->hw_lock);
+
+ if (no_delay)
+ break;
+ else
+ qla_mdelay(__func__, 1);
+ }
+ return (ret);
+}
+
+static __inline void
+qla_unlock(qla_host_t *ha, const char *str)
+{
+ mtx_lock(&ha->hw_lock);
+ ha->hw_lock_held = 0;
+ ha->qla_unlock = str;
+ mtx_unlock(&ha->hw_lock);
+}
+
+#endif /* #ifndef _QL_INLINE_H_ */
diff --git a/sys/dev/qlxgbe/ql_ioctl.c b/sys/dev/qlxgbe/ql_ioctl.c
new file mode 100644
index 000000000000..8ee74a50996d
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_ioctl.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * File: ql_ioctl.c
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+
+#include "ql_os.h"
+#include "ql_hw.h"
+#include "ql_def.h"
+#include "ql_inline.h"
+#include "ql_glbl.h"
+#include "ql_ioctl.h"
+
+static int ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
+ struct thread *td);
+
+static struct cdevsw qla_cdevsw = {
+ .d_version = D_VERSION,
+ .d_ioctl = ql_eioctl,
+ .d_name = "qlcnic",
+};
+
+int
+ql_make_cdev(qla_host_t *ha)
+{
+ ha->ioctl_dev = make_dev(&qla_cdevsw,
+ ha->ifp->if_dunit,
+ UID_ROOT,
+ GID_WHEEL,
+ 0600,
+ "%s",
+ if_name(ha->ifp));
+
+ if (ha->ioctl_dev == NULL)
+ return (-1);
+
+ ha->ioctl_dev->si_drv1 = ha;
+
+ return (0);
+}
+
+void
+ql_del_cdev(qla_host_t *ha)
+{
+ if (ha->ioctl_dev != NULL)
+ destroy_dev(ha->ioctl_dev);
+ return;
+}
+
+static int
+ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
+ struct thread *td)
+{
+ qla_host_t *ha;
+ int rval = 0;
+ device_t pci_dev;
+ struct ifnet *ifp;
+
+ q80_offchip_mem_val_t val;
+ qla_rd_pci_ids_t *pci_ids;
+ qla_rd_fw_dump_t *fw_dump;
+ union {
+ qla_reg_val_t *rv;
+ qla_rd_flash_t *rdf;
+ qla_wr_flash_t *wrf;
+ qla_erase_flash_t *erf;
+ qla_offchip_mem_val_t *mem;
+ } u;
+
+
+ if ((ha = (qla_host_t *)dev->si_drv1) == NULL)
+ return ENXIO;
+
+ pci_dev= ha->pci_dev;
+
+ switch(cmd) {
+
+ case QLA_RDWR_REG:
+
+ u.rv = (qla_reg_val_t *)data;
+
+ if (u.rv->direct) {
+ if (u.rv->rd) {
+ u.rv->val = READ_REG32(ha, u.rv->reg);
+ } else {
+ WRITE_REG32(ha, u.rv->reg, u.rv->val);
+ }
+ } else {
+ if ((rval = ql_rdwr_indreg32(ha, u.rv->reg, &u.rv->val,
+ u.rv->rd)))
+ rval = ENXIO;
+ }
+ break;
+
+ case QLA_RD_FLASH:
+
+ if (!ha->hw.flags.fdt_valid) {
+ rval = EIO;
+ break;
+ }
+
+ u.rdf = (qla_rd_flash_t *)data;
+ if ((rval = ql_rd_flash32(ha, u.rdf->off, &u.rdf->data)))
+ rval = ENXIO;
+ break;
+
+ case QLA_WR_FLASH:
+
+ ifp = ha->ifp;
+
+ if (ifp == NULL) {
+ rval = ENXIO;
+ break;
+ }
+
+ if (ifp->if_drv_flags & (IFF_DRV_OACTIVE | IFF_DRV_RUNNING)) {
+ rval = ENXIO;
+ break;
+ }
+
+ if (!ha->hw.flags.fdt_valid) {
+ rval = EIO;
+ break;
+ }
+
+ u.wrf = (qla_wr_flash_t *)data;
+ if ((rval = ql_wr_flash_buffer(ha, u.wrf->off, u.wrf->size,
+ u.wrf->buffer))) {
+ printf("flash write failed[%d]\n", rval);
+ rval = ENXIO;
+ }
+ break;
+
+ case QLA_ERASE_FLASH:
+
+ ifp = ha->ifp;
+
+ if (ifp == NULL) {
+ rval = ENXIO;
+ break;
+ }
+
+ if (ifp->if_drv_flags & (IFF_DRV_OACTIVE | IFF_DRV_RUNNING)) {
+ rval = ENXIO;
+ break;
+ }
+
+ if (!ha->hw.flags.fdt_valid) {
+ rval = EIO;
+ break;
+ }
+
+ u.erf = (qla_erase_flash_t *)data;
+ if ((rval = ql_erase_flash(ha, u.erf->off,
+ u.erf->size))) {
+ printf("flash erase failed[%d]\n", rval);
+ rval = ENXIO;
+ }
+ break;
+
+ case QLA_RDWR_MS_MEM:
+ u.mem = (qla_offchip_mem_val_t *)data;
+
+ if ((rval = ql_rdwr_offchip_mem(ha, u.mem->off, &val,
+ u.mem->rd)))
+ rval = ENXIO;
+ else {
+ u.mem->data_lo = val.data_lo;
+ u.mem->data_hi = val.data_hi;
+ u.mem->data_ulo = val.data_ulo;
+ u.mem->data_uhi = val.data_uhi;
+ }
+
+ break;
+
+ case QLA_RD_FW_DUMP_SIZE:
+
+ if (ha->hw.mdump_init == 0) {
+ rval = EINVAL;
+ break;
+ }
+
+ fw_dump = (qla_rd_fw_dump_t *)data;
+ fw_dump->template_size = ha->hw.dma_buf.minidump.size;
+ fw_dump->pci_func = ha->pci_func;
+
+ break;
+
+ case QLA_RD_FW_DUMP:
+
+ if (ha->hw.mdump_init == 0) {
+ rval = EINVAL;
+ break;
+ }
+
+ fw_dump = (qla_rd_fw_dump_t *)data;
+ if ((rval = copyout(ha->hw.dma_buf.minidump.dma_b,
+ fw_dump->md_template, fw_dump->template_size)))
+ rval = ENXIO;
+ break;
+
+ case QLA_RD_PCI_IDS:
+ pci_ids = (qla_rd_pci_ids_t *)data;
+ pci_ids->ven_id = pci_get_vendor(pci_dev);
+ pci_ids->dev_id = pci_get_device(pci_dev);
+ pci_ids->subsys_ven_id = pci_get_subvendor(pci_dev);
+ pci_ids->subsys_dev_id = pci_get_subdevice(pci_dev);
+ pci_ids->rev_id = pci_read_config(pci_dev, PCIR_REVID, 1);
+ break;
+
+ default:
+ break;
+ }
+
+ return rval;
+}
+
diff --git a/sys/dev/qlxgbe/ql_ioctl.h b/sys/dev/qlxgbe/ql_ioctl.h
new file mode 100644
index 000000000000..f1865a60c421
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_ioctl.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/*
+ * File: ql_ioctl.h
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ */
+
+#ifndef _QL_IOCTL_H_
+#define _QL_IOCTL_H_
+
+#include <sys/ioccom.h>
+
+struct qla_reg_val {
+ uint16_t rd;
+ uint16_t direct;
+ uint32_t reg;
+ uint32_t val;
+};
+typedef struct qla_reg_val qla_reg_val_t;
+
+struct qla_rd_flash {
+ uint32_t off;
+ uint32_t data;
+};
+typedef struct qla_rd_flash qla_rd_flash_t;
+
+struct qla_wr_flash {
+ uint32_t off;
+ uint32_t size;
+ void *buffer;
+ uint32_t pattern;
+};
+typedef struct qla_wr_flash qla_wr_flash_t;
+
+struct qla_erase_flash {
+ uint32_t off;
+ uint32_t size;
+};
+typedef struct qla_erase_flash qla_erase_flash_t;
+
+struct qla_rd_pci_ids {
+ uint16_t ven_id;
+ uint16_t dev_id;
+ uint16_t subsys_ven_id;
+ uint16_t subsys_dev_id;
+ uint8_t rev_id;
+};
+typedef struct qla_rd_pci_ids qla_rd_pci_ids_t;
+
+/*
+ * structure encapsulating the value to read/write from/to offchip (MS) memory
+ */
+struct qla_offchip_mem_val {
+ uint16_t rd;
+ uint64_t off;
+ uint32_t data_lo;
+ uint32_t data_hi;
+ uint32_t data_ulo;
+ uint32_t data_uhi;
+};
+typedef struct qla_offchip_mem_val qla_offchip_mem_val_t;
+
+struct qla_rd_fw_dump {
+ uint16_t pci_func;
+ uint32_t template_size;
+ void *md_template;
+};
+typedef struct qla_rd_fw_dump qla_rd_fw_dump_t;
+
+/*
+ * Read/Write Register
+ */
+#define QLA_RDWR_REG _IOWR('q', 1, qla_reg_val_t)
+
+/*
+ * Read Flash
+ */
+#define QLA_RD_FLASH _IOWR('q', 2, qla_rd_flash_t)
+
+/*
+ * Write Flash
+ */
+#define QLA_WR_FLASH _IOWR('q', 3, qla_wr_flash_t)
+
+/*
+ * Read Offchip (MS) Memory
+ */
+#define QLA_RDWR_MS_MEM _IOWR('q', 4, qla_offchip_mem_val_t)
+
+/*
+ * Erase Flash
+ */
+#define QLA_ERASE_FLASH _IOWR('q', 5, qla_erase_flash_t)
+
+/*
+ * Read PCI IDs
+ */
+#define QLA_RD_PCI_IDS _IOWR('q', 6, qla_rd_pci_ids_t)
+
+/*
+ * Read Minidump Template Size
+ */
+#define QLA_RD_FW_DUMP_SIZE _IOWR('q', 7, qla_rd_fw_dump_t)
+
+/*
+ * Read Minidump Template
+ */
+#define QLA_RD_FW_DUMP _IOWR('q', 8, qla_rd_fw_dump_t)
+
+#endif /* #ifndef _QL_IOCTL_H_ */
diff --git a/sys/dev/qlxgbe/ql_isr.c b/sys/dev/qlxgbe/ql_isr.c
new file mode 100644
index 000000000000..28ae30f6d8cc
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_isr.c
@@ -0,0 +1,889 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * File: ql_isr.c
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+
+#include "ql_os.h"
+#include "ql_hw.h"
+#include "ql_def.h"
+#include "ql_inline.h"
+#include "ql_ver.h"
+#include "ql_glbl.h"
+#include "ql_dbg.h"
+
+static void qla_replenish_normal_rx(qla_host_t *ha, qla_sds_t *sdsp,
+ uint32_t r_idx);
+
+static void
+qla_rcv_error(qla_host_t *ha)
+{
+ ha->flags.stop_rcv = 1;
+ ha->qla_initiate_recovery = 1;
+}
+
+
+/*
+ * Name: qla_rx_intr
+ * Function: Handles normal ethernet frames received
+ */
+static void
+qla_rx_intr(qla_host_t *ha, qla_sgl_rcv_t *sgc, uint32_t sds_idx)
+{
+ qla_rx_buf_t *rxb;
+ struct mbuf *mp = NULL, *mpf = NULL, *mpl = NULL;
+ struct ifnet *ifp = ha->ifp;
+ qla_sds_t *sdsp;
+ struct ether_vlan_header *eh;
+ uint32_t i, rem_len = 0;
+ uint32_t r_idx = 0;
+ qla_rx_ring_t *rx_ring;
+
+ if (ha->hw.num_rds_rings > 1)
+ r_idx = sds_idx;
+
+ ha->hw.rds[r_idx].count++;
+
+ sdsp = &ha->hw.sds[sds_idx];
+ rx_ring = &ha->rx_ring[r_idx];
+
+ for (i = 0; i < sgc->num_handles; i++) {
+ rxb = &rx_ring->rx_buf[sgc->handle[i] & 0x7FFF];
+
+ QL_ASSERT(ha, (rxb != NULL),
+ ("%s: [sds_idx]=[%d] rxb != NULL\n", __func__,\
+ sds_idx));
+
+ if ((rxb == NULL) || QL_ERR_INJECT(ha, INJCT_RX_RXB_INVAL)) {
+ /* log the error */
+ device_printf(ha->pci_dev,
+ "%s invalid rxb[%d, %d, 0x%04x]\n",
+ __func__, sds_idx, i, sgc->handle[i]);
+ qla_rcv_error(ha);
+ return;
+ }
+
+ mp = rxb->m_head;
+ if (i == 0)
+ mpf = mp;
+
+ QL_ASSERT(ha, (mp != NULL),
+ ("%s: [sds_idx]=[%d] mp != NULL\n", __func__,\
+ sds_idx));
+
+ bus_dmamap_sync(ha->rx_tag, rxb->map, BUS_DMASYNC_POSTREAD);
+
+ rxb->m_head = NULL;
+ rxb->next = sdsp->rxb_free;
+ sdsp->rxb_free = rxb;
+ sdsp->rx_free++;
+
+ if ((mp == NULL) || QL_ERR_INJECT(ha, INJCT_RX_MP_NULL)) {
+ /* log the error */
+ device_printf(ha->pci_dev,
+ "%s mp == NULL [%d, %d, 0x%04x]\n",
+ __func__, sds_idx, i, sgc->handle[i]);
+ qla_rcv_error(ha);
+ return;
+ }
+
+ if (i == 0) {
+ mpl = mpf = mp;
+ mp->m_flags |= M_PKTHDR;
+ mp->m_pkthdr.len = sgc->pkt_length;
+ mp->m_pkthdr.rcvif = ifp;
+ rem_len = mp->m_pkthdr.len;
+ } else {
+ mp->m_flags &= ~M_PKTHDR;
+ mpl->m_next = mp;
+ mpl = mp;
+ rem_len = rem_len - mp->m_len;
+ }
+ }
+
+ mpl->m_len = rem_len;
+
+ eh = mtod(mpf, struct ether_vlan_header *);
+
+ if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
+ uint32_t *data = (uint32_t *)eh;
+
+ mpf->m_pkthdr.ether_vtag = ntohs(eh->evl_tag);
+ mpf->m_flags |= M_VLANTAG;
+
+ *(data + 3) = *(data + 2);
+ *(data + 2) = *(data + 1);
+ *(data + 1) = *data;
+
+ m_adj(mpf, ETHER_VLAN_ENCAP_LEN);
+ }
+
+ if (sgc->chksum_status == Q8_STAT_DESC_STATUS_CHKSUM_OK) {
+ mpf->m_pkthdr.csum_flags = CSUM_IP_CHECKED | CSUM_IP_VALID |
+ CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
+ mpf->m_pkthdr.csum_data = 0xFFFF;
+ } else {
+ mpf->m_pkthdr.csum_flags = 0;
+ }
+
+ ifp->if_ipackets++;
+
+ mpf->m_pkthdr.flowid = sgc->rss_hash;
+ mpf->m_flags |= M_FLOWID;
+
+ (*ifp->if_input)(ifp, mpf);
+
+ if (sdsp->rx_free > ha->std_replenish)
+ qla_replenish_normal_rx(ha, sdsp, r_idx);
+
+ return;
+}
+
+#define QLA_TCP_HDR_SIZE 20
+#define QLA_TCP_TS_OPTION_SIZE 12
+
+/*
+ * Name: qla_lro_intr
+ * Function: Handles normal ethernet frames received
+ */
+static int
+qla_lro_intr(qla_host_t *ha, qla_sgl_lro_t *sgc, uint32_t sds_idx)
+{
+ qla_rx_buf_t *rxb;
+ struct mbuf *mp = NULL, *mpf = NULL, *mpl = NULL;
+ struct ifnet *ifp = ha->ifp;
+ qla_sds_t *sdsp;
+ struct ether_vlan_header *eh;
+ uint32_t i, rem_len = 0, pkt_length, iplen;
+ struct tcphdr *th;
+ struct ip *ip = NULL;
+ struct ip6_hdr *ip6 = NULL;
+ uint16_t etype;
+ uint32_t r_idx = 0;
+ qla_rx_ring_t *rx_ring;
+
+ if (ha->hw.num_rds_rings > 1)
+ r_idx = sds_idx;
+
+ ha->hw.rds[r_idx].count++;
+
+ rx_ring = &ha->rx_ring[r_idx];
+
+ ha->lro_pkt_count++;
+
+ sdsp = &ha->hw.sds[sds_idx];
+
+ pkt_length = sgc->payload_length + sgc->l4_offset;
+
+ if (sgc->flags & Q8_LRO_COMP_TS) {
+ pkt_length += QLA_TCP_HDR_SIZE + QLA_TCP_TS_OPTION_SIZE;
+ } else {
+ pkt_length += QLA_TCP_HDR_SIZE;
+ }
+ ha->lro_bytes += pkt_length;
+
+ for (i = 0; i < sgc->num_handles; i++) {
+ rxb = &rx_ring->rx_buf[sgc->handle[i] & 0x7FFF];
+
+ QL_ASSERT(ha, (rxb != NULL),
+ ("%s: [sds_idx]=[%d] rxb != NULL\n", __func__,\
+ sds_idx));
+
+ if ((rxb == NULL) || QL_ERR_INJECT(ha, INJCT_LRO_RXB_INVAL)) {
+ /* log the error */
+ device_printf(ha->pci_dev,
+ "%s invalid rxb[%d, %d, 0x%04x]\n",
+ __func__, sds_idx, i, sgc->handle[i]);
+ qla_rcv_error(ha);
+ return (0);
+ }
+
+ mp = rxb->m_head;
+ if (i == 0)
+ mpf = mp;
+
+ QL_ASSERT(ha, (mp != NULL),
+ ("%s: [sds_idx]=[%d] mp != NULL\n", __func__,\
+ sds_idx));
+
+ bus_dmamap_sync(ha->rx_tag, rxb->map, BUS_DMASYNC_POSTREAD);
+
+ rxb->m_head = NULL;
+ rxb->next = sdsp->rxb_free;
+ sdsp->rxb_free = rxb;
+ sdsp->rx_free++;
+
+ if ((mp == NULL) || QL_ERR_INJECT(ha, INJCT_LRO_MP_NULL)) {
+ /* log the error */
+ device_printf(ha->pci_dev,
+ "%s mp == NULL [%d, %d, 0x%04x]\n",
+ __func__, sds_idx, i, sgc->handle[i]);
+ qla_rcv_error(ha);
+ return (0);
+ }
+
+ if (i == 0) {
+ mpl = mpf = mp;
+ mp->m_flags |= M_PKTHDR;
+ mp->m_pkthdr.len = pkt_length;
+ mp->m_pkthdr.rcvif = ifp;
+ rem_len = mp->m_pkthdr.len;
+ } else {
+ mp->m_flags &= ~M_PKTHDR;
+ mpl->m_next = mp;
+ mpl = mp;
+ rem_len = rem_len - mp->m_len;
+ }
+ }
+
+ mpl->m_len = rem_len;
+
+ th = (struct tcphdr *)(mpf->m_data + sgc->l4_offset);
+
+ if (sgc->flags & Q8_LRO_COMP_PUSH_BIT)
+ th->th_flags |= TH_PUSH;
+
+ m_adj(mpf, sgc->l2_offset);
+
+ eh = mtod(mpf, struct ether_vlan_header *);
+
+ if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
+ uint32_t *data = (uint32_t *)eh;
+
+ mpf->m_pkthdr.ether_vtag = ntohs(eh->evl_tag);
+ mpf->m_flags |= M_VLANTAG;
+
+ *(data + 3) = *(data + 2);
+ *(data + 2) = *(data + 1);
+ *(data + 1) = *data;
+
+ m_adj(mpf, ETHER_VLAN_ENCAP_LEN);
+
+ etype = ntohs(eh->evl_proto);
+ } else {
+ etype = ntohs(eh->evl_encap_proto);
+ }
+
+ if (etype == ETHERTYPE_IP) {
+ ip = (struct ip *)(mpf->m_data + ETHER_HDR_LEN);
+
+ iplen = (ip->ip_hl << 2) + (th->th_off << 2) +
+ sgc->payload_length;
+
+ ip->ip_len = htons(iplen);
+
+ ha->ipv4_lro++;
+ } else if (etype == ETHERTYPE_IPV6) {
+ ip6 = (struct ip6_hdr *)(mpf->m_data + ETHER_HDR_LEN);
+
+ iplen = (th->th_off << 2) + sgc->payload_length;
+
+ ip6->ip6_plen = htons(iplen);
+
+ ha->ipv6_lro++;
+ } else {
+ m_freem(mpf);
+
+ if (sdsp->rx_free > ha->std_replenish)
+ qla_replenish_normal_rx(ha, sdsp, r_idx);
+ return 0;
+ }
+
+ mpf->m_pkthdr.csum_flags = CSUM_IP_CHECKED | CSUM_IP_VALID |
+ CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
+ mpf->m_pkthdr.csum_data = 0xFFFF;
+
+ mpf->m_pkthdr.flowid = sgc->rss_hash;
+ mpf->m_flags |= M_FLOWID;
+
+ ifp->if_ipackets++;
+
+ (*ifp->if_input)(ifp, mpf);
+
+ if (sdsp->rx_free > ha->std_replenish)
+ qla_replenish_normal_rx(ha, sdsp, r_idx);
+
+ return (0);
+}
+
+static int
+qla_rcv_cont_sds(qla_host_t *ha, uint32_t sds_idx, uint32_t comp_idx,
+ uint32_t dcount, uint16_t *handle, uint16_t *nhandles)
+{
+ uint32_t i;
+ uint16_t num_handles;
+ q80_stat_desc_t *sdesc;
+ uint32_t opcode;
+
+ *nhandles = 0;
+ dcount--;
+
+ for (i = 0; i < dcount; i++) {
+ comp_idx = (comp_idx + 1) & (NUM_STATUS_DESCRIPTORS-1);
+ sdesc = (q80_stat_desc_t *)
+ &ha->hw.sds[sds_idx].sds_ring_base[comp_idx];
+
+ opcode = Q8_STAT_DESC_OPCODE((sdesc->data[1]));
+
+ if (!opcode) {
+ device_printf(ha->pci_dev, "%s: opcode=0 %p %p\n",
+ __func__, (void *)sdesc->data[0],
+ (void *)sdesc->data[1]);
+ return -1;
+ }
+
+ num_handles = Q8_SGL_STAT_DESC_NUM_HANDLES((sdesc->data[1]));
+ if (!num_handles) {
+ device_printf(ha->pci_dev, "%s: opcode=0 %p %p\n",
+ __func__, (void *)sdesc->data[0],
+ (void *)sdesc->data[1]);
+ return -1;
+ }
+
+ if (QL_ERR_INJECT(ha, INJCT_NUM_HNDLE_INVALID))
+ num_handles = -1;
+
+ switch (num_handles) {
+
+ case 1:
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0]));
+ break;
+
+ case 2:
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE2((sdesc->data[0]));
+ break;
+
+ case 3:
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE2((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE3((sdesc->data[0]));
+ break;
+
+ case 4:
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE2((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE3((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE4((sdesc->data[0]));
+ break;
+
+ case 5:
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE2((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE3((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE4((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE5((sdesc->data[1]));
+ break;
+
+ case 6:
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE2((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE3((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE4((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE5((sdesc->data[1]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE6((sdesc->data[1]));
+ break;
+
+ case 7:
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE2((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE3((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE4((sdesc->data[0]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE5((sdesc->data[1]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE6((sdesc->data[1]));
+ *handle++ = Q8_SGL_STAT_DESC_HANDLE7((sdesc->data[1]));
+ break;
+
+ default:
+ device_printf(ha->pci_dev,
+ "%s: invalid num handles %p %p\n",
+ __func__, (void *)sdesc->data[0],
+ (void *)sdesc->data[1]);
+
+ QL_ASSERT(ha, (0),\
+ ("%s: %s [nh, sds, d0, d1]=[%d, %d, %p, %p]\n",
+ __func__, "invalid num handles", sds_idx, num_handles,
+ (void *)sdesc->data[0],(void *)sdesc->data[1]));
+
+ qla_rcv_error(ha);
+ return 0;
+ }
+ *nhandles = *nhandles + num_handles;
+ }
+ return 0;
+}
+
+/*
+ * Name: qla_rcv_isr
+ * Function: Main Interrupt Service Routine
+ */
+static uint32_t
+qla_rcv_isr(qla_host_t *ha, uint32_t sds_idx, uint32_t count)
+{
+ device_t dev;
+ qla_hw_t *hw;
+ uint32_t comp_idx, c_idx = 0, desc_count = 0, opcode;
+ volatile q80_stat_desc_t *sdesc, *sdesc0 = NULL;
+ uint32_t ret = 0;
+ qla_sgl_comp_t sgc;
+ uint16_t nhandles;
+ uint32_t sds_replenish_threshold = 0;
+
+ dev = ha->pci_dev;
+ hw = &ha->hw;
+
+ hw->sds[sds_idx].rcv_active = 1;
+ if (ha->flags.stop_rcv) {
+ hw->sds[sds_idx].rcv_active = 0;
+ return 0;
+ }
+
+ QL_DPRINT2(ha, (dev, "%s: [%d]enter\n", __func__, sds_idx));
+
+ /*
+ * receive interrupts
+ */
+ comp_idx = hw->sds[sds_idx].sdsr_next;
+
+ while (count-- && !ha->flags.stop_rcv) {
+
+ sdesc = (q80_stat_desc_t *)
+ &hw->sds[sds_idx].sds_ring_base[comp_idx];
+
+ opcode = Q8_STAT_DESC_OPCODE((sdesc->data[1]));
+
+ if (!opcode)
+ break;
+
+ hw->sds[sds_idx].intr_count++;
+ switch (opcode) {
+
+ case Q8_STAT_DESC_OPCODE_RCV_PKT:
+
+ desc_count = 1;
+
+ bzero(&sgc, sizeof(qla_sgl_comp_t));
+
+ sgc.rcv.pkt_length =
+ Q8_STAT_DESC_TOTAL_LENGTH((sdesc->data[0]));
+ sgc.rcv.num_handles = 1;
+ sgc.rcv.handle[0] =
+ Q8_STAT_DESC_HANDLE((sdesc->data[0]));
+ sgc.rcv.chksum_status =
+ Q8_STAT_DESC_STATUS((sdesc->data[1]));
+
+ sgc.rcv.rss_hash =
+ Q8_STAT_DESC_RSS_HASH((sdesc->data[0]));
+
+ if (Q8_STAT_DESC_VLAN((sdesc->data[1]))) {
+ sgc.rcv.vlan_tag =
+ Q8_STAT_DESC_VLAN_ID((sdesc->data[1]));
+ }
+ qla_rx_intr(ha, &sgc.rcv, sds_idx);
+ break;
+
+ case Q8_STAT_DESC_OPCODE_SGL_RCV:
+
+ desc_count =
+ Q8_STAT_DESC_COUNT_SGL_RCV((sdesc->data[1]));
+
+ if (desc_count > 1) {
+ c_idx = (comp_idx + desc_count -1) &
+ (NUM_STATUS_DESCRIPTORS-1);
+ sdesc0 = (q80_stat_desc_t *)
+ &hw->sds[sds_idx].sds_ring_base[c_idx];
+
+ if (Q8_STAT_DESC_OPCODE((sdesc0->data[1])) !=
+ Q8_STAT_DESC_OPCODE_CONT) {
+ desc_count = 0;
+ break;
+ }
+ }
+
+ bzero(&sgc, sizeof(qla_sgl_comp_t));
+
+ sgc.rcv.pkt_length =
+ Q8_STAT_DESC_TOTAL_LENGTH_SGL_RCV(\
+ (sdesc->data[0]));
+ sgc.rcv.chksum_status =
+ Q8_STAT_DESC_STATUS((sdesc->data[1]));
+
+ sgc.rcv.rss_hash =
+ Q8_STAT_DESC_RSS_HASH((sdesc->data[0]));
+
+ if (Q8_STAT_DESC_VLAN((sdesc->data[1]))) {
+ sgc.rcv.vlan_tag =
+ Q8_STAT_DESC_VLAN_ID((sdesc->data[1]));
+ }
+
+ QL_ASSERT(ha, (desc_count <= 2) ,\
+ ("%s: [sds_idx, data0, data1]="\
+ "%d, %p, %p]\n", __func__, sds_idx,\
+ (void *)sdesc->data[0],\
+ (void *)sdesc->data[1]));
+
+ sgc.rcv.num_handles = 1;
+ sgc.rcv.handle[0] =
+ Q8_STAT_DESC_HANDLE((sdesc->data[0]));
+
+ if (qla_rcv_cont_sds(ha, sds_idx, comp_idx, desc_count,
+ &sgc.rcv.handle[1], &nhandles)) {
+ device_printf(dev,
+ "%s: [sds_idx, dcount, data0, data1]="
+ "[%d, %d, 0x%llx, 0x%llx]\n",
+ __func__, sds_idx, desc_count,
+ (long long unsigned int)sdesc->data[0],
+ (long long unsigned int)sdesc->data[1]);
+ desc_count = 0;
+ break;
+ }
+
+ sgc.rcv.num_handles += nhandles;
+
+ qla_rx_intr(ha, &sgc.rcv, sds_idx);
+
+ break;
+
+ case Q8_STAT_DESC_OPCODE_SGL_LRO:
+
+ desc_count =
+ Q8_STAT_DESC_COUNT_SGL_LRO((sdesc->data[1]));
+
+ if (desc_count > 1) {
+ c_idx = (comp_idx + desc_count -1) &
+ (NUM_STATUS_DESCRIPTORS-1);
+ sdesc0 = (q80_stat_desc_t *)
+ &hw->sds[sds_idx].sds_ring_base[c_idx];
+
+ if (Q8_STAT_DESC_OPCODE((sdesc0->data[1])) !=
+ Q8_STAT_DESC_OPCODE_CONT) {
+ desc_count = 0;
+ break;
+ }
+ }
+ bzero(&sgc, sizeof(qla_sgl_comp_t));
+
+ sgc.lro.payload_length =
+ Q8_STAT_DESC_TOTAL_LENGTH_SGL_RCV((sdesc->data[0]));
+
+ sgc.lro.rss_hash =
+ Q8_STAT_DESC_RSS_HASH((sdesc->data[0]));
+
+ sgc.lro.num_handles = 1;
+ sgc.lro.handle[0] =
+ Q8_STAT_DESC_HANDLE((sdesc->data[0]));
+
+ if (Q8_SGL_LRO_STAT_TS((sdesc->data[1])))
+ sgc.lro.flags |= Q8_LRO_COMP_TS;
+
+ if (Q8_SGL_LRO_STAT_PUSH_BIT((sdesc->data[1])))
+ sgc.lro.flags |= Q8_LRO_COMP_PUSH_BIT;
+
+ sgc.lro.l2_offset =
+ Q8_SGL_LRO_STAT_L2_OFFSET((sdesc->data[1]));
+ sgc.lro.l4_offset =
+ Q8_SGL_LRO_STAT_L4_OFFSET((sdesc->data[1]));
+
+ if (Q8_STAT_DESC_VLAN((sdesc->data[1]))) {
+ sgc.lro.vlan_tag =
+ Q8_STAT_DESC_VLAN_ID((sdesc->data[1]));
+ }
+
+ QL_ASSERT(ha, (desc_count <= 7) ,\
+ ("%s: [sds_idx, data0, data1]="\
+ "[%d, 0x%llx, 0x%llx]\n",\
+ __func__, sds_idx,\
+ (long long unsigned int)sdesc->data[0],\
+ (long long unsigned int)sdesc->data[1]));
+
+ if (qla_rcv_cont_sds(ha, sds_idx, comp_idx,
+ desc_count, &sgc.lro.handle[1], &nhandles)) {
+ device_printf(dev,
+ "%s: [sds_idx, data0, data1]="\
+ "[%d, 0x%llx, 0x%llx]\n",\
+ __func__, sds_idx,\
+ (long long unsigned int)sdesc->data[0],\
+ (long long unsigned int)sdesc->data[1]);
+
+ desc_count = 0;
+ break;
+ }
+
+ sgc.lro.num_handles += nhandles;
+
+ if (qla_lro_intr(ha, &sgc.lro, sds_idx)) {
+ device_printf(dev,
+ "%s: [sds_idx, data0, data1]="\
+ "[%d, 0x%llx, 0x%llx]\n",\
+ __func__, sds_idx,\
+ (long long unsigned int)sdesc->data[0],\
+ (long long unsigned int)sdesc->data[1]);
+ device_printf(dev,
+ "%s: [comp_idx, c_idx, dcount, nhndls]="\
+ "[%d, %d, %d, %d]\n",\
+ __func__, comp_idx, c_idx, desc_count,
+ sgc.lro.num_handles);
+ if (desc_count > 1) {
+ device_printf(dev,
+ "%s: [sds_idx, data0, data1]="\
+ "[%d, 0x%llx, 0x%llx]\n",\
+ __func__, sds_idx,\
+ (long long unsigned int)sdesc0->data[0],\
+ (long long unsigned int)sdesc0->data[1]);
+ }
+ }
+
+ break;
+
+ default:
+ device_printf(dev, "%s: default 0x%llx!\n", __func__,
+ (long long unsigned int)sdesc->data[0]);
+ break;
+ }
+
+ if (desc_count == 0)
+ break;
+
+ sds_replenish_threshold += desc_count;
+
+
+ while (desc_count--) {
+ sdesc->data[0] = 0ULL;
+ sdesc->data[1] = 0ULL;
+ comp_idx = (comp_idx + 1) & (NUM_STATUS_DESCRIPTORS-1);
+ sdesc = (q80_stat_desc_t *)
+ &hw->sds[sds_idx].sds_ring_base[comp_idx];
+ }
+
+ if (sds_replenish_threshold > ha->hw.sds_cidx_thres) {
+ sds_replenish_threshold = 0;
+ if (hw->sds[sds_idx].sdsr_next != comp_idx) {
+ QL_UPDATE_SDS_CONSUMER_INDEX(ha, sds_idx,\
+ comp_idx);
+ }
+ hw->sds[sds_idx].sdsr_next = comp_idx;
+ }
+ }
+
+ if (ha->flags.stop_rcv)
+ goto qla_rcv_isr_exit;
+
+ if (hw->sds[sds_idx].sdsr_next != comp_idx) {
+ QL_UPDATE_SDS_CONSUMER_INDEX(ha, sds_idx, comp_idx);
+ }
+ hw->sds[sds_idx].sdsr_next = comp_idx;
+
+ sdesc = (q80_stat_desc_t *)&hw->sds[sds_idx].sds_ring_base[comp_idx];
+ opcode = Q8_STAT_DESC_OPCODE((sdesc->data[1]));
+
+ if (opcode)
+ ret = -1;
+
+qla_rcv_isr_exit:
+ hw->sds[sds_idx].rcv_active = 0;
+
+ return (ret);
+}
+
+void
+ql_mbx_isr(void *arg)
+{
+ qla_host_t *ha;
+ uint32_t data;
+ uint32_t prev_link_state;
+
+ ha = arg;
+
+ if (ha == NULL) {
+ device_printf(ha->pci_dev, "%s: arg == NULL\n", __func__);
+ return;
+ }
+
+ data = READ_REG32(ha, Q8_FW_MBOX_CNTRL);
+ if ((data & 0x3) != 0x1) {
+ WRITE_REG32(ha, ha->hw.mbx_intr_mask_offset, 0);
+ return;
+ }
+
+ data = READ_REG32(ha, Q8_FW_MBOX0);
+
+ if ((data & 0xF000) != 0x8000)
+ return;
+
+ data = data & 0xFFFF;
+
+ switch (data) {
+
+ case 0x8001: /* It's an AEN */
+
+ ha->hw.cable_oui = READ_REG32(ha, (Q8_FW_MBOX0 + 4));
+
+ data = READ_REG32(ha, (Q8_FW_MBOX0 + 8));
+ ha->hw.cable_length = data & 0xFFFF;
+
+ data = data >> 16;
+ ha->hw.link_speed = data & 0xFFF;
+
+ data = READ_REG32(ha, (Q8_FW_MBOX0 + 12));
+
+ prev_link_state = ha->hw.link_up;
+ ha->hw.link_up = (((data & 0xFF) == 0) ? 0 : 1);
+
+ if (prev_link_state != ha->hw.link_up) {
+ if (ha->hw.link_up)
+ if_link_state_change(ha->ifp, LINK_STATE_UP);
+ else
+ if_link_state_change(ha->ifp, LINK_STATE_DOWN);
+ }
+
+
+ ha->hw.module_type = ((data >> 8) & 0xFF);
+ ha->hw.flags.fduplex = (((data & 0xFF0000) == 0) ? 0 : 1);
+ ha->hw.flags.autoneg = (((data & 0xFF000000) == 0) ? 0 : 1);
+
+ data = READ_REG32(ha, (Q8_FW_MBOX0 + 16));
+ ha->hw.flags.loopback_mode = data & 0x03;
+
+ ha->hw.link_faults = (data >> 3) & 0xFF;
+
+ WRITE_REG32(ha, Q8_FW_MBOX_CNTRL, 0x0);
+ WRITE_REG32(ha, ha->hw.mbx_intr_mask_offset, 0x0);
+ break;
+
+ default:
+ device_printf(ha->pci_dev, "%s: AEN[0x%08x]\n", __func__, data);
+ WRITE_REG32(ha, Q8_FW_MBOX_CNTRL, 0x0);
+ WRITE_REG32(ha, ha->hw.mbx_intr_mask_offset, 0x0);
+ break;
+ }
+ return;
+}
+
+
+static void
+qla_replenish_normal_rx(qla_host_t *ha, qla_sds_t *sdsp, uint32_t r_idx)
+{
+ qla_rx_buf_t *rxb;
+ int count = sdsp->rx_free;
+ uint32_t rx_next;
+ qla_rdesc_t *rdesc;
+
+ /* we can play with this value via a sysctl */
+ uint32_t replenish_thresh = ha->hw.rds_pidx_thres;
+
+ rdesc = &ha->hw.rds[r_idx];
+
+ rx_next = rdesc->rx_next;
+
+ while (count--) {
+ rxb = sdsp->rxb_free;
+
+ if (rxb == NULL)
+ break;
+
+ sdsp->rxb_free = rxb->next;
+ sdsp->rx_free--;
+
+ if (ql_get_mbuf(ha, rxb, NULL) == 0) {
+ qla_set_hw_rcv_desc(ha, r_idx, rdesc->rx_in,
+ rxb->handle,
+ rxb->paddr, (rxb->m_head)->m_pkthdr.len);
+ rdesc->rx_in++;
+ if (rdesc->rx_in == NUM_RX_DESCRIPTORS)
+ rdesc->rx_in = 0;
+ rdesc->rx_next++;
+ if (rdesc->rx_next == NUM_RX_DESCRIPTORS)
+ rdesc->rx_next = 0;
+ } else {
+ device_printf(ha->pci_dev,
+ "%s: ql_get_mbuf [0,(%d),(%d)] failed\n",
+ __func__, rdesc->rx_in, rxb->handle);
+
+ rxb->m_head = NULL;
+ rxb->next = sdsp->rxb_free;
+ sdsp->rxb_free = rxb;
+ sdsp->rx_free++;
+
+ break;
+ }
+ if (replenish_thresh-- == 0) {
+ QL_UPDATE_RDS_PRODUCER_INDEX(ha, rdesc->prod_std,
+ rdesc->rx_next);
+ rx_next = rdesc->rx_next;
+ replenish_thresh = ha->hw.rds_pidx_thres;
+ }
+ }
+
+ if (rx_next != rdesc->rx_next) {
+ QL_UPDATE_RDS_PRODUCER_INDEX(ha, rdesc->prod_std,
+ rdesc->rx_next);
+ }
+}
+
+void
+ql_isr(void *arg)
+{
+ qla_ivec_t *ivec = arg;
+ qla_host_t *ha ;
+ int idx;
+ qla_hw_t *hw;
+ struct ifnet *ifp;
+ uint32_t data = 0;
+ uint32_t ret = 0;
+
+ ha = ivec->ha;
+ hw = &ha->hw;
+ ifp = ha->ifp;
+
+ if ((idx = ivec->sds_idx) >= ha->hw.num_sds_rings)
+ return;
+
+ if (idx == 0)
+ taskqueue_enqueue(ha->tx_tq, &ha->tx_task);
+
+
+
+ data = READ_REG32(ha, ha->hw.intr_src[idx]);
+
+ if (data & 0x1 )
+ ret = qla_rcv_isr(ha, idx, -1);
+
+ if (idx == 0)
+ taskqueue_enqueue(ha->tx_tq, &ha->tx_task);
+
+ if (!ha->flags.stop_rcv) {
+ QL_ENABLE_INTERRUPTS(ha, idx);
+ }
+ return;
+}
+
diff --git a/sys/dev/qlxgbe/ql_misc.c b/sys/dev/qlxgbe/ql_misc.c
new file mode 100644
index 000000000000..6c7292ff1d75
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_misc.c
@@ -0,0 +1,1304 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * File : ql_misc.c
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "ql_os.h"
+#include "ql_hw.h"
+#include "ql_def.h"
+#include "ql_inline.h"
+#include "ql_glbl.h"
+#include "ql_dbg.h"
+#include "ql_tmplt.h"
+
+#define QL_FDT_OFFSET 0x3F0000
+#define Q8_FLASH_SECTOR_SIZE 0x10000
+
+static int qla_ld_fw_init(qla_host_t *ha);
+
+/*
+ * structure encapsulating the value to read/write to offchip memory
+ */
+typedef struct _offchip_mem_val {
+ uint32_t data_lo;
+ uint32_t data_hi;
+ uint32_t data_ulo;
+ uint32_t data_uhi;
+} offchip_mem_val_t;
+
+/*
+ * Name: ql_rdwr_indreg32
+ * Function: Read/Write an Indirect Register
+ */
+int
+ql_rdwr_indreg32(qla_host_t *ha, uint32_t addr, uint32_t *val, uint32_t rd)
+{
+ uint32_t wnd_reg;
+ uint32_t count = 100;
+
+ wnd_reg = (Q8_CRB_WINDOW_PF0 | (ha->pci_func << 2));
+
+ WRITE_REG32(ha, wnd_reg, addr);
+
+ while (count--) {
+ if (READ_REG32(ha, wnd_reg) == addr)
+ break;
+ qla_mdelay(__func__, 1);
+ }
+ if (!count || QL_ERR_INJECT(ha, INJCT_RDWR_INDREG_FAILURE)) {
+ device_printf(ha->pci_dev, "%s: [0x%08x, 0x%08x, %d] failed\n",
+ __func__, addr, *val, rd);
+ ha->qla_initiate_recovery = 1;
+ return -1;
+ }
+
+ if (rd) {
+ *val = READ_REG32(ha, Q8_WILD_CARD);
+ } else {
+ WRITE_REG32(ha, Q8_WILD_CARD, *val);
+ }
+
+ return 0;
+}
+
+/*
+ * Name: ql_rdwr_offchip_mem
+ * Function: Read/Write OffChip Memory
+ */
+int
+ql_rdwr_offchip_mem(qla_host_t *ha, uint64_t addr, q80_offchip_mem_val_t *val,
+ uint32_t rd)
+{
+ uint32_t count = 100;
+ uint32_t data, step = 0;
+
+
+ if (QL_ERR_INJECT(ha, INJCT_RDWR_OFFCHIPMEM_FAILURE))
+ goto exit_ql_rdwr_offchip_mem;
+
+ data = (uint32_t)addr;
+ if (ql_rdwr_indreg32(ha, Q8_MS_ADDR_LO, &data, 0)) {
+ step = 1;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+
+ data = (uint32_t)(addr >> 32);
+ if (ql_rdwr_indreg32(ha, Q8_MS_ADDR_HI, &data, 0)) {
+ step = 2;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+
+ data = BIT_1;
+ if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
+ step = 3;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+
+ if (!rd) {
+ data = val->data_lo;
+ if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_0_31, &data, 0)) {
+ step = 4;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+
+ data = val->data_hi;
+ if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_32_63, &data, 0)) {
+ step = 5;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+
+ data = val->data_ulo;
+ if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_64_95, &data, 0)) {
+ step = 6;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+
+ data = val->data_uhi;
+ if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_96_127, &data, 0)) {
+ step = 7;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+
+ data = (BIT_2|BIT_1|BIT_0);
+ if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
+ step = 7;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+ } else {
+ data = (BIT_1|BIT_0);
+ if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
+ step = 8;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+ }
+
+ while (count--) {
+ if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 1)) {
+ step = 9;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+
+ if (!(data & BIT_3)) {
+ if (rd) {
+ if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_0_31,
+ &data, 1)) {
+ step = 10;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+ val->data_lo = data;
+
+ if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_32_63,
+ &data, 1)) {
+ step = 11;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+ val->data_hi = data;
+
+ if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_64_95,
+ &data, 1)) {
+ step = 12;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+ val->data_ulo = data;
+
+ if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_96_127,
+ &data, 1)) {
+ step = 13;
+ goto exit_ql_rdwr_offchip_mem;
+ }
+ val->data_uhi = data;
+ }
+ return 0;
+ } else
+ qla_mdelay(__func__, 1);
+ }
+
+exit_ql_rdwr_offchip_mem:
+
+ device_printf(ha->pci_dev,
+ "%s: [0x%08x 0x%08x : 0x%08x 0x%08x 0x%08x 0x%08x]"
+ " [%d] [%d] failed\n", __func__, (uint32_t)(addr >> 32),
+ (uint32_t)(addr), val->data_lo, val->data_hi, val->data_ulo,
+ val->data_uhi, rd, step);
+
+ ha->qla_initiate_recovery = 1;
+
+ return (-1);
+}
+
+/*
+ * Name: ql_rd_flash32
+ * Function: Read Flash Memory
+ */
+int
+ql_rd_flash32(qla_host_t *ha, uint32_t addr, uint32_t *data)
+{
+ uint32_t data32;
+
+ if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID, 0xABCDABCD)) {
+ device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n",
+ __func__);
+ return (-1);
+ }
+
+ data32 = addr;
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_DIRECT_WINDOW, &data32, 0)) {
+ qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
+ device_printf(ha->pci_dev,
+ "%s: Q8_FLASH_DIRECT_WINDOW[0x%08x] failed\n",
+ __func__, data32);
+ return (-1);
+ }
+
+ data32 = Q8_FLASH_DIRECT_DATA | (addr & 0xFFFF);
+ if (ql_rdwr_indreg32(ha, data32, data, 1)) {
+ qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
+ device_printf(ha->pci_dev,
+ "%s: data32:data [0x%08x] failed\n",
+ __func__, data32);
+ return (-1);
+ }
+
+ qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
+ return 0;
+}
+
+static int
+qla_get_fdt(qla_host_t *ha)
+{
+ uint32_t data32;
+ int count;
+ qla_hw_t *hw;
+
+ hw = &ha->hw;
+
+ for (count = 0; count < sizeof(qla_flash_desc_table_t); count+=4) {
+ if (ql_rd_flash32(ha, QL_FDT_OFFSET + count,
+ (uint32_t *)&hw->fdt + (count >> 2))) {
+ device_printf(ha->pci_dev,
+ "%s: Read QL_FDT_OFFSET + %d failed\n",
+ __func__, count);
+ return (-1);
+ }
+ }
+
+ if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID,
+ Q8_FDT_LOCK_MAGIC_ID)) {
+ device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n",
+ __func__);
+ return (-1);
+ }
+
+ data32 = Q8_FDT_FLASH_ADDR_VAL;
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) {
+ qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
+ device_printf(ha->pci_dev,
+ "%s: Write to Q8_FLASH_ADDRESS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ data32 = Q8_FDT_FLASH_CTRL_VAL;
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) {
+ qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
+ device_printf(ha->pci_dev,
+ "%s: Write to Q8_FLASH_CONTROL failed\n",
+ __func__);
+ return (-1);
+ }
+
+ count = 0;
+
+ do {
+ if (count < 1000) {
+ QLA_USEC_DELAY(10);
+ count += 10;
+ } else {
+ qla_mdelay(__func__, 1);
+ count += 1000;
+ }
+
+ data32 = 0;
+
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
+ qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
+ device_printf(ha->pci_dev,
+ "%s: Read Q8_FLASH_STATUS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ data32 &= 0x6;
+
+ } while ((count < 10000) && (data32 != 0x6));
+
+ if (count == 0 && data32 != 0x6) {
+ qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
+ device_printf(ha->pci_dev,
+ "%s: Poll Q8_FLASH_STATUS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_RD_DATA, &data32, 1)) {
+ qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
+ device_printf(ha->pci_dev,
+ "%s: Read Q8_FLASH_RD_DATA failed\n",
+ __func__);
+ return (-1);
+ }
+
+ qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
+
+ data32 &= Q8_FDT_MASK_VAL;
+ if (hw->fdt.flash_manuf == data32)
+ return (0);
+ else
+ return (-1);
+}
+
+static int
+qla_flash_write_enable(qla_host_t *ha, int enable)
+{
+ uint32_t data32;
+ int count = 0;
+
+ data32 = Q8_WR_ENABLE_FL_ADDR | ha->hw.fdt.write_statusreg_cmd;
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: Write to Q8_FLASH_ADDRESS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ if (enable)
+ data32 = ha->hw.fdt.write_enable_bits;
+ else
+ data32 = ha->hw.fdt.write_disable_bits;
+
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_WR_DATA, &data32, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: Write to Q8_FLASH_WR_DATA failed\n",
+ __func__);
+ return (-1);
+ }
+
+ data32 = Q8_WR_ENABLE_FL_CTRL;
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: Write to Q8_FLASH_CONTROL failed\n",
+ __func__);
+ return (-1);
+ }
+
+ do {
+ if (count < 1000) {
+ QLA_USEC_DELAY(10);
+ count += 10;
+ } else {
+ qla_mdelay(__func__, 1);
+ count += 1000;
+ }
+
+ data32 = 0;
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
+ device_printf(ha->pci_dev,
+ "%s: Read Q8_FLASH_STATUS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ data32 &= 0x6;
+
+ } while ((count < 10000) && (data32 != 0x6));
+
+ if (count == 0 && data32 != 0x6) {
+ device_printf(ha->pci_dev,
+ "%s: Poll Q8_FLASH_STATUS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ return 0;
+}
+
+static int
+qla_erase_flash_sector(qla_host_t *ha, uint32_t start)
+{
+ uint32_t data32;
+ int count = 0;
+
+ do {
+ qla_mdelay(__func__, 1);
+
+ data32 = 0;
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
+ device_printf(ha->pci_dev,
+ "%s: Read Q8_FLASH_STATUS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ data32 &= 0x6;
+
+ } while (((count++) < 1000) && (data32 != 0x6));
+
+ if (count == 0 && data32 != 0x6) {
+ device_printf(ha->pci_dev,
+ "%s: Poll Q8_FLASH_STATUS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ data32 = (start >> 16) & 0xFF;
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_WR_DATA, &data32, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: Write to Q8_FLASH_WR_DATA failed\n",
+ __func__);
+ return (-1);
+ }
+
+ data32 = Q8_ERASE_FL_ADDR_MASK | ha->hw.fdt.erase_cmd;
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: Write to Q8_FLASH_ADDRESS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ data32 = Q8_ERASE_FL_CTRL_MASK;
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: Write to Q8_FLASH_CONTROL failed\n",
+ __func__);
+ return (-1);
+ }
+
+ count = 0;
+ do {
+ qla_mdelay(__func__, 1);
+
+ data32 = 0;
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
+ device_printf(ha->pci_dev,
+ "%s: Read Q8_FLASH_STATUS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ data32 &= 0x6;
+
+ } while (((count++) < 1000) && (data32 != 0x6));
+
+ if (count == 0 && data32 != 0x6) {
+ device_printf(ha->pci_dev,
+ "%s: Poll Q8_FLASH_STATUS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ return 0;
+}
+
+int
+ql_erase_flash(qla_host_t *ha, uint32_t off, uint32_t size)
+{
+ int rval = 0;
+ uint32_t start;
+
+ if (off & (Q8_FLASH_SECTOR_SIZE -1))
+ return (-1);
+
+ if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID,
+ Q8_ERASE_LOCK_MAGIC_ID)) {
+ device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n",
+ __func__);
+ return (-1);
+ }
+
+ if (qla_flash_write_enable(ha, 1) != 0) {
+ rval = -1;
+ goto ql_erase_flash_exit;
+ }
+
+ for (start = off; start < (off + size); start = start +
+ Q8_FLASH_SECTOR_SIZE) {
+ if (qla_erase_flash_sector(ha, start)) {
+ rval = -1;
+ break;
+ }
+ }
+
+ rval = qla_flash_write_enable(ha, 0);
+
+ql_erase_flash_exit:
+ qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
+ return (rval);
+}
+
+static int
+qla_wr_flash32(qla_host_t *ha, uint32_t off, uint32_t *data)
+{
+ uint32_t data32;
+ int count = 0;
+
+ data32 = Q8_WR_FL_ADDR_MASK | (off >> 2);
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: Write to Q8_FLASH_ADDRESS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_WR_DATA, data, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: Write to Q8_FLASH_WR_DATA failed\n",
+ __func__);
+ return (-1);
+ }
+
+ data32 = Q8_WR_FL_CTRL_MASK;
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: Write to Q8_FLASH_CONTROL failed\n",
+ __func__);
+ return (-1);
+ }
+
+ do {
+ if (count < 1000) {
+ QLA_USEC_DELAY(10);
+ count += 10;
+ } else {
+ qla_mdelay(__func__, 1);
+ count += 1000;
+ }
+
+ data32 = 0;
+ if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
+ device_printf(ha->pci_dev,
+ "%s: Read Q8_FLASH_STATUS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ data32 &= 0x6;
+
+ } while ((count < 10000) && (data32 != 0x6));
+
+ if (count == 0 && data32 != 0x6) {
+ device_printf(ha->pci_dev,
+ "%s: Poll Q8_FLASH_STATUS failed\n",
+ __func__);
+ return (-1);
+ }
+
+ return 0;
+}
+
+static int
+qla_flash_write_data(qla_host_t *ha, uint32_t off, uint32_t size,
+ void *data)
+{
+ int rval = 0;
+ uint32_t start;
+ uint32_t *data32 = data;
+
+ if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID,
+ Q8_WR_FL_LOCK_MAGIC_ID)) {
+ device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n",
+ __func__);
+ rval = -1;
+ goto qla_flash_write_data_exit;
+ }
+
+ if ((qla_flash_write_enable(ha, 1) != 0)) {
+ device_printf(ha->pci_dev, "%s: failed\n",
+ __func__);
+ rval = -1;
+ goto qla_flash_write_data_unlock_exit;
+ }
+
+ for (start = off; start < (off + size); start = start + 4) {
+ if (*data32 != 0xFFFFFFFF) {
+ if (qla_wr_flash32(ha, start, data32)) {
+ rval = -1;
+ break;
+ }
+ }
+ data32++;
+ }
+
+ rval = qla_flash_write_enable(ha, 0);
+
+qla_flash_write_data_unlock_exit:
+ qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
+
+qla_flash_write_data_exit:
+ return (rval);
+}
+
+int
+ql_wr_flash_buffer(qla_host_t *ha, uint32_t off, uint32_t size, void *buf)
+{
+ int rval = 0;
+ void *data;
+
+ if (size == 0)
+ return 0;
+
+ size = size << 2;
+
+ if (buf == NULL)
+ return -1;
+
+ if ((data = malloc(size, M_QLA83XXBUF, M_NOWAIT)) == NULL) {
+ device_printf(ha->pci_dev, "%s: malloc failed \n", __func__);
+ rval = -1;
+ goto ql_wr_flash_buffer_exit;
+ }
+
+ if ((rval = copyin(buf, data, size))) {
+ device_printf(ha->pci_dev, "%s copyin failed\n", __func__);
+ goto ql_wr_flash_buffer_free_exit;
+ }
+
+ rval = qla_flash_write_data(ha, off, size, data);
+
+ql_wr_flash_buffer_free_exit:
+ free(data, M_QLA83XXBUF);
+
+ql_wr_flash_buffer_exit:
+ return (rval);
+}
+
+/*
+ * Name: qla_load_fw_from_flash
+ * Function: Reads the Bootloader from Flash and Loads into Offchip Memory
+ */
+static void
+qla_load_fw_from_flash(qla_host_t *ha)
+{
+ uint32_t flash_off = 0x10000;
+ uint64_t mem_off;
+ uint32_t count, mem_size;
+ q80_offchip_mem_val_t val;
+
+ mem_off = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR));
+ mem_size = READ_REG32(ha, Q8_BOOTLD_SIZE);
+
+ device_printf(ha->pci_dev, "%s: [0x%08x][0x%08x]\n",
+ __func__, (uint32_t)mem_off, mem_size);
+
+ /* only bootloader needs to be loaded into memory */
+ for (count = 0; count < mem_size ; ) {
+ ql_rd_flash32(ha, flash_off, &val.data_lo);
+ count = count + 4;
+ flash_off = flash_off + 4;
+
+ ql_rd_flash32(ha, flash_off, &val.data_hi);
+ count = count + 4;
+ flash_off = flash_off + 4;
+
+ ql_rd_flash32(ha, flash_off, &val.data_ulo);
+ count = count + 4;
+ flash_off = flash_off + 4;
+
+ ql_rd_flash32(ha, flash_off, &val.data_uhi);
+ count = count + 4;
+ flash_off = flash_off + 4;
+
+ ql_rdwr_offchip_mem(ha, mem_off, &val, 0);
+
+ mem_off = mem_off + 16;
+ }
+
+ return;
+}
+
+/*
+ * Name: qla_init_from_flash
+ * Function: Performs Initialization which consists of the following sequence
+ * - reset
+ * - CRB Init
+ * - Peg Init
+ * - Read the Bootloader from Flash and Load into Offchip Memory
+ * - Kick start the bootloader which loads the rest of the firmware
+ * and performs the remaining steps in the initialization process.
+ */
+static int
+qla_init_from_flash(qla_host_t *ha)
+{
+ uint32_t delay = 300;
+ uint32_t data;
+
+ qla_ld_fw_init(ha);
+
+ do {
+ data = READ_REG32(ha, Q8_CMDPEG_STATE);
+
+ QL_DPRINT2(ha,
+ (ha->pci_dev, "%s: func[%d] cmdpegstate 0x%08x\n",
+ __func__, ha->pci_func, data));
+ if (data == 0xFF01) {
+ QL_DPRINT2(ha, (ha->pci_dev,
+ "%s: func[%d] init complete\n",
+ __func__, ha->pci_func));
+ return(0);
+ }
+ qla_mdelay(__func__, 100);
+ } while (delay--);
+
+ return (-1);
+}
+
+/*
+ * Name: ql_init_hw
+ * Function: Initializes P3+ hardware.
+ */
+int
+ql_init_hw(qla_host_t *ha)
+{
+ device_t dev;
+ int ret = 0;
+ uint32_t val, delay = 300;
+
+ dev = ha->pci_dev;
+
+ QL_DPRINT1(ha, (dev, "%s: enter\n", __func__));
+
+ if (ha->pci_func & 0x1) {
+
+ while ((ha->pci_func & 0x1) && delay--) {
+
+ val = READ_REG32(ha, Q8_CMDPEG_STATE);
+
+ if (val == 0xFF01) {
+ QL_DPRINT2(ha, (dev,
+ "%s: func = %d init complete\n",
+ __func__, ha->pci_func));
+ qla_mdelay(__func__, 100);
+ goto qla_init_exit;
+ }
+ qla_mdelay(__func__, 100);
+ }
+ return (-1);
+ }
+
+
+ val = READ_REG32(ha, Q8_CMDPEG_STATE);
+ if (!cold || (val != 0xFF01)) {
+ ret = qla_init_from_flash(ha);
+ qla_mdelay(__func__, 100);
+ }
+
+qla_init_exit:
+ ha->fw_ver_major = READ_REG32(ha, Q8_FW_VER_MAJOR);
+ ha->fw_ver_minor = READ_REG32(ha, Q8_FW_VER_MINOR);
+ ha->fw_ver_sub = READ_REG32(ha, Q8_FW_VER_SUB);
+
+ if (qla_get_fdt(ha) != 0) {
+ device_printf(dev, "%s: qla_get_fdt failed\n", __func__);
+ } else {
+ ha->hw.flags.fdt_valid = 1;
+ }
+
+ return (ret);
+}
+
+void
+ql_read_mac_addr(qla_host_t *ha)
+{
+ uint8_t *macp;
+ uint32_t mac_lo;
+ uint32_t mac_hi;
+ uint32_t flash_off;
+
+ flash_off = Q8_BOARD_CONFIG_OFFSET + Q8_BOARD_CONFIG_MAC0_LO +
+ (ha->pci_func << 3);
+ ql_rd_flash32(ha, flash_off, &mac_lo);
+
+ flash_off += 4;
+ ql_rd_flash32(ha, flash_off, &mac_hi);
+
+ macp = (uint8_t *)&mac_lo;
+ ha->hw.mac_addr[5] = macp[0];
+ ha->hw.mac_addr[4] = macp[1];
+ ha->hw.mac_addr[3] = macp[2];
+ ha->hw.mac_addr[2] = macp[3];
+
+ macp = (uint8_t *)&mac_hi;
+ ha->hw.mac_addr[1] = macp[0];
+ ha->hw.mac_addr[0] = macp[1];
+
+ //device_printf(ha->pci_dev, "%s: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ // __func__, ha->hw.mac_addr[0], ha->hw.mac_addr[1],
+ // ha->hw.mac_addr[2], ha->hw.mac_addr[3],
+ // ha->hw.mac_addr[4], ha->hw.mac_addr[5]);
+
+ return;
+}
+
+/*
+ * Stop/Start/Initialization Handling
+ */
+
+static uint16_t
+qla_tmplt_16bit_checksum(qla_host_t *ha, uint16_t *buf, uint32_t size)
+{
+ uint32_t sum = 0;
+ uint32_t count = size >> 1; /* size in 16 bit words */
+
+ while (count-- > 0)
+ sum += *buf++;
+
+ while (sum >> 16)
+ sum = (sum & 0xFFFF) + (sum >> 16);
+
+ return (~sum);
+}
+
+static int
+qla_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
+{
+ q8_wrl_e_t *wr_l;
+ int i;
+
+ wr_l = (q8_wrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
+
+ for (i = 0; i < ce_hdr->opcount; i++, wr_l++) {
+
+ if (ql_rdwr_indreg32(ha, wr_l->addr, &wr_l->value, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: [0x%08x 0x%08x] error\n", __func__,
+ wr_l->addr, wr_l->value);
+ return -1;
+ }
+ if (ce_hdr->delay_to) {
+ DELAY(ce_hdr->delay_to);
+ }
+ }
+ return 0;
+}
+
+static int
+qla_rd_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
+{
+ q8_rdwrl_e_t *rd_wr_l;
+ uint32_t data;
+ int i;
+
+ rd_wr_l = (q8_rdwrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
+
+ for (i = 0; i < ce_hdr->opcount; i++, rd_wr_l++) {
+
+ if (ql_rdwr_indreg32(ha, rd_wr_l->rd_addr, &data, 1)) {
+ device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
+ __func__, rd_wr_l->rd_addr);
+
+ return -1;
+ }
+
+ if (ql_rdwr_indreg32(ha, rd_wr_l->wr_addr, &data, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: [0x%08x 0x%08x] error\n", __func__,
+ rd_wr_l->wr_addr, data);
+ return -1;
+ }
+ if (ce_hdr->delay_to) {
+ DELAY(ce_hdr->delay_to);
+ }
+ }
+ return 0;
+}
+
+static int
+qla_poll_reg(qla_host_t *ha, uint32_t addr, uint32_t ms_to, uint32_t tmask,
+ uint32_t tvalue)
+{
+ uint32_t data;
+
+ while (ms_to) {
+
+ if (ql_rdwr_indreg32(ha, addr, &data, 1)) {
+ device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
+ __func__, addr);
+ return -1;
+ }
+
+ if ((data & tmask) != tvalue) {
+ ms_to--;
+ } else
+ break;
+
+ qla_mdelay(__func__, 1);
+ }
+ return ((ms_to ? 0: -1));
+}
+
+static int
+qla_poll_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
+{
+ int i;
+ q8_poll_hdr_t *phdr;
+ q8_poll_e_t *pe;
+ uint32_t data;
+
+ phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
+ pe = (q8_poll_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
+
+ for (i = 0; i < ce_hdr->opcount; i++, pe++) {
+ if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) {
+ device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
+ __func__, pe->addr);
+ return -1;
+ }
+
+ if (ce_hdr->delay_to) {
+ if ((data & phdr->tmask) == phdr->tvalue)
+ break;
+ if (qla_poll_reg(ha, pe->addr, ce_hdr->delay_to,
+ phdr->tmask, phdr->tvalue)) {
+
+ if (ql_rdwr_indreg32(ha, pe->to_addr, &data,
+ 1)) {
+ device_printf(ha->pci_dev,
+ "%s: [0x%08x] error\n",
+ __func__, pe->to_addr);
+ return -1;
+ }
+
+ if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) {
+ device_printf(ha->pci_dev,
+ "%s: [0x%08x] error\n",
+ __func__, pe->addr);
+ return -1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+qla_poll_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
+{
+ int i;
+ q8_poll_hdr_t *phdr;
+ q8_poll_wr_e_t *wr_e;
+
+ phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
+ wr_e = (q8_poll_wr_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
+
+ for (i = 0; i < ce_hdr->opcount; i++, wr_e++) {
+
+ if (ql_rdwr_indreg32(ha, wr_e->dr_addr, &wr_e->dr_value, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: [0x%08x 0x%08x] error\n", __func__,
+ wr_e->dr_addr, wr_e->dr_value);
+ return -1;
+ }
+ if (ql_rdwr_indreg32(ha, wr_e->ar_addr, &wr_e->ar_value, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: [0x%08x 0x%08x] error\n", __func__,
+ wr_e->ar_addr, wr_e->ar_value);
+ return -1;
+ }
+ if (ce_hdr->delay_to) {
+ if (qla_poll_reg(ha, wr_e->ar_addr, ce_hdr->delay_to,
+ phdr->tmask, phdr->tvalue))
+ device_printf(ha->pci_dev, "%s: "
+ "[ar_addr, ar_value, delay, tmask,"
+ "tvalue] [0x%08x 0x%08x 0x%08x 0x%08x"
+ " 0x%08x]\n",
+ __func__, wr_e->ar_addr, wr_e->ar_value,
+ ce_hdr->delay_to, phdr->tmask,
+ phdr->tvalue);
+ }
+ }
+ return 0;
+}
+
+static int
+qla_poll_read_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
+{
+ int i;
+ q8_poll_hdr_t *phdr;
+ q8_poll_rd_e_t *rd_e;
+ uint32_t value;
+
+ phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
+ rd_e = (q8_poll_rd_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
+
+ for (i = 0; i < ce_hdr->opcount; i++, rd_e++) {
+ if (ql_rdwr_indreg32(ha, rd_e->ar_addr, &rd_e->ar_value, 0)) {
+ device_printf(ha->pci_dev,
+ "%s: [0x%08x 0x%08x] error\n", __func__,
+ rd_e->ar_addr, rd_e->ar_value);
+ return -1;
+ }
+
+ if (ce_hdr->delay_to) {
+ if (qla_poll_reg(ha, rd_e->ar_addr, ce_hdr->delay_to,
+ phdr->tmask, phdr->tvalue)) {
+ return (-1);
+ } else {
+ if (ql_rdwr_indreg32(ha, rd_e->dr_addr,
+ &value, 1)) {
+ device_printf(ha->pci_dev,
+ "%s: [0x%08x] error\n",
+ __func__, rd_e->ar_addr);
+ return -1;
+ }
+
+ ha->hw.rst_seq[ha->hw.rst_seq_idx++] = value;
+ if (ha->hw.rst_seq_idx == Q8_MAX_RESET_SEQ_IDX)
+ ha->hw.rst_seq_idx = 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+qla_rdmwr(qla_host_t *ha, uint32_t raddr, uint32_t waddr, q8_rdmwr_hdr_t *hdr)
+{
+ uint32_t value;
+
+ if (hdr->index_a >= Q8_MAX_RESET_SEQ_IDX) {
+ device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
+ hdr->index_a);
+ return -1;
+ }
+
+ if (hdr->index_a) {
+ value = ha->hw.rst_seq[hdr->index_a];
+ } else {
+ if (ql_rdwr_indreg32(ha, raddr, &value, 1)) {
+ device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
+ __func__, raddr);
+ return -1;
+ }
+ }
+
+ value &= hdr->and_value;
+ value <<= hdr->shl;
+ value >>= hdr->shr;
+ value |= hdr->or_value;
+ value ^= hdr->xor_value;
+
+ if (ql_rdwr_indreg32(ha, waddr, &value, 0)) {
+ device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
+ raddr);
+ return -1;
+ }
+ return 0;
+}
+
+static int
+qla_read_modify_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
+{
+ int i;
+ q8_rdmwr_hdr_t *rdmwr_hdr;
+ q8_rdmwr_e_t *rdmwr_e;
+
+ rdmwr_hdr = (q8_rdmwr_hdr_t *)((uint8_t *)ce_hdr +
+ sizeof (q8_ce_hdr_t));
+ rdmwr_e = (q8_rdmwr_e_t *)((uint8_t *)rdmwr_hdr +
+ sizeof(q8_rdmwr_hdr_t));
+
+ for (i = 0; i < ce_hdr->opcount; i++, rdmwr_e++) {
+
+ if (qla_rdmwr(ha, rdmwr_e->rd_addr, rdmwr_e->wr_addr,
+ rdmwr_hdr)) {
+ return -1;
+ }
+ if (ce_hdr->delay_to) {
+ DELAY(ce_hdr->delay_to);
+ }
+ }
+ return 0;
+}
+
+static int
+qla_tmplt_execute(qla_host_t *ha, uint8_t *buf, int start_idx, int *end_idx,
+ uint32_t nentries)
+{
+ int i, ret = 0, proc_end = 0;
+ q8_ce_hdr_t *ce_hdr;
+
+ for (i = start_idx; ((i < nentries) && (!proc_end)); i++) {
+ ce_hdr = (q8_ce_hdr_t *)buf;
+ ret = 0;
+
+ switch (ce_hdr->opcode) {
+ case Q8_CE_OPCODE_NOP:
+ break;
+
+ case Q8_CE_OPCODE_WRITE_LIST:
+ ret = qla_wr_list(ha, ce_hdr);
+ //printf("qla_wr_list %d\n", ret);
+ break;
+
+ case Q8_CE_OPCODE_READ_WRITE_LIST:
+ ret = qla_rd_wr_list(ha, ce_hdr);
+ //printf("qla_rd_wr_list %d\n", ret);
+ break;
+
+ case Q8_CE_OPCODE_POLL_LIST:
+ ret = qla_poll_list(ha, ce_hdr);
+ //printf("qla_poll_list %d\n", ret);
+ break;
+
+ case Q8_CE_OPCODE_POLL_WRITE_LIST:
+ ret = qla_poll_write_list(ha, ce_hdr);
+ //printf("qla_poll_write_list %d\n", ret);
+ break;
+
+ case Q8_CE_OPCODE_POLL_RD_LIST:
+ ret = qla_poll_read_list(ha, ce_hdr);
+ //printf("qla_poll_read_list %d\n", ret);
+ break;
+
+ case Q8_CE_OPCODE_READ_MODIFY_WRITE:
+ ret = qla_read_modify_write_list(ha, ce_hdr);
+ //printf("qla_read_modify_write_list %d\n", ret);
+ break;
+
+ case Q8_CE_OPCODE_SEQ_PAUSE:
+ if (ce_hdr->delay_to) {
+ qla_mdelay(__func__, ce_hdr->delay_to);
+ }
+ break;
+
+ case Q8_CE_OPCODE_SEQ_END:
+ proc_end = 1;
+ break;
+
+ case Q8_CE_OPCODE_TMPLT_END:
+ *end_idx = i;
+ return 0;
+ }
+
+ if (ret)
+ break;
+
+ buf += ce_hdr->size;
+ }
+ *end_idx = i;
+
+ return (ret);
+}
+
+
+static int
+qla_ld_fw_init(qla_host_t *ha)
+{
+ uint8_t *buf;
+ uint32_t index = 0, end_idx;
+ q8_tmplt_hdr_t *hdr;
+
+ bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
+
+ hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
+
+ if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
+ (uint32_t)hdr->size)) {
+ device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
+ __func__);
+ return -1;
+ }
+
+
+ buf = ql83xx_resetseq + hdr->stop_seq_off;
+
+// device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
+ if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
+ device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
+ return -1;
+ }
+
+ index = end_idx;
+
+ buf = ql83xx_resetseq + hdr->init_seq_off;
+
+// device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
+ if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
+ device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
+ return -1;
+ }
+
+ qla_load_fw_from_flash(ha);
+ WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
+
+ index = end_idx;
+ buf = ql83xx_resetseq + hdr->start_seq_off;
+
+// device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
+ if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
+ device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+ql_stop_sequence(qla_host_t *ha)
+{
+ uint8_t *buf;
+ uint32_t index = 0, end_idx;
+ q8_tmplt_hdr_t *hdr;
+
+ bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
+
+ hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
+
+ if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
+ (uint32_t)hdr->size)) {
+ device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
+ __func__);
+ return (-1);
+ }
+
+ buf = ql83xx_resetseq + hdr->stop_seq_off;
+
+ device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
+ if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
+ device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
+ return (-1);
+ }
+
+ return end_idx;
+}
+
+int
+ql_start_sequence(qla_host_t *ha, uint16_t index)
+{
+ uint8_t *buf;
+ uint32_t end_idx;
+ q8_tmplt_hdr_t *hdr;
+
+ bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
+
+ hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
+
+ if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
+ (uint32_t)hdr->size)) {
+ device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
+ __func__);
+ return (-1);
+ }
+
+ buf = ql83xx_resetseq + hdr->init_seq_off;
+
+ device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
+ if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
+ device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
+ return (-1);
+ }
+
+ qla_load_fw_from_flash(ha);
+ WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
+
+ index = end_idx;
+ buf = ql83xx_resetseq + hdr->start_seq_off;
+
+ device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
+ if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
+ device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
+ return -1;
+ }
+
+ return (0);
+}
+
diff --git a/sys/dev/qlxgbe/ql_os.c b/sys/dev/qlxgbe/ql_os.c
new file mode 100644
index 000000000000..757d6122f6f4
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_os.c
@@ -0,0 +1,1703 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * and ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * File: ql_os.c
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+
+#include "ql_os.h"
+#include "ql_hw.h"
+#include "ql_def.h"
+#include "ql_inline.h"
+#include "ql_ver.h"
+#include "ql_glbl.h"
+#include "ql_dbg.h"
+#include <sys/smp.h>
+
+/*
+ * Some PCI Configuration Space Related Defines
+ */
+
+#ifndef PCI_VENDOR_QLOGIC
+#define PCI_VENDOR_QLOGIC 0x1077
+#endif
+
+#ifndef PCI_PRODUCT_QLOGIC_ISP8030
+#define PCI_PRODUCT_QLOGIC_ISP8030 0x8030
+#endif
+
+#define PCI_QLOGIC_ISP8030 \
+ ((PCI_PRODUCT_QLOGIC_ISP8030 << 16) | PCI_VENDOR_QLOGIC)
+
+/*
+ * static functions
+ */
+static int qla_alloc_parent_dma_tag(qla_host_t *ha);
+static void qla_free_parent_dma_tag(qla_host_t *ha);
+static int qla_alloc_xmt_bufs(qla_host_t *ha);
+static void qla_free_xmt_bufs(qla_host_t *ha);
+static int qla_alloc_rcv_bufs(qla_host_t *ha);
+static void qla_free_rcv_bufs(qla_host_t *ha);
+static void qla_clear_tx_buf(qla_host_t *ha, qla_tx_buf_t *txb);
+
+static void qla_init_ifnet(device_t dev, qla_host_t *ha);
+static int qla_sysctl_get_stats(SYSCTL_HANDLER_ARGS);
+static int qla_sysctl_get_link_status(SYSCTL_HANDLER_ARGS);
+static void qla_release(qla_host_t *ha);
+static void qla_dmamap_callback(void *arg, bus_dma_segment_t *segs, int nsegs,
+ int error);
+static void qla_stop(qla_host_t *ha);
+static int qla_send(qla_host_t *ha, struct mbuf **m_headp);
+static void qla_tx_done(void *context, int pending);
+static void qla_get_peer(qla_host_t *ha);
+static void qla_error_recovery(void *context, int pending);
+
+/*
+ * Hooks to the Operating Systems
+ */
+static int qla_pci_probe (device_t);
+static int qla_pci_attach (device_t);
+static int qla_pci_detach (device_t);
+
+static void qla_init(void *arg);
+static int qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
+static int qla_media_change(struct ifnet *ifp);
+static void qla_media_status(struct ifnet *ifp, struct ifmediareq *ifmr);
+static void qla_start(struct ifnet *ifp);
+
+static device_method_t qla_pci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, qla_pci_probe),
+ DEVMETHOD(device_attach, qla_pci_attach),
+ DEVMETHOD(device_detach, qla_pci_detach),
+ { 0, 0 }
+};
+
+static driver_t qla_pci_driver = {
+ "ql", qla_pci_methods, sizeof (qla_host_t),
+};
+
+static devclass_t qla83xx_devclass;
+
+DRIVER_MODULE(qla83xx, pci, qla_pci_driver, qla83xx_devclass, 0, 0);
+
+MODULE_DEPEND(qla83xx, pci, 1, 1, 1);
+MODULE_DEPEND(qla83xx, ether, 1, 1, 1);
+
+MALLOC_DEFINE(M_QLA83XXBUF, "qla83xxbuf", "Buffers for qla83xx driver");
+
+#define QL_STD_REPLENISH_THRES 0
+#define QL_JUMBO_REPLENISH_THRES 32
+
+
+static char dev_str[64];
+
+/*
+ * Name: qla_pci_probe
+ * Function: Validate the PCI device to be a QLA80XX device
+ */
+static int
+qla_pci_probe(device_t dev)
+{
+ switch ((pci_get_device(dev) << 16) | (pci_get_vendor(dev))) {
+ case PCI_QLOGIC_ISP8030:
+ snprintf(dev_str, sizeof(dev_str), "%s v%d.%d.%d",
+ "Qlogic ISP 83xx PCI CNA Adapter-Ethernet Function",
+ QLA_VERSION_MAJOR, QLA_VERSION_MINOR,
+ QLA_VERSION_BUILD);
+ device_set_desc(dev, dev_str);
+ break;
+ default:
+ return (ENXIO);
+ }
+
+ if (bootverbose)
+ printf("%s: %s\n ", __func__, dev_str);
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static void
+qla_add_sysctls(qla_host_t *ha)
+{
+ device_t dev = ha->pci_dev;
+
+ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "stats", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)ha, 0,
+ qla_sysctl_get_stats, "I", "Statistics");
+
+ SYSCTL_ADD_STRING(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "fw_version", CTLFLAG_RD,
+ &ha->fw_ver_str, 0, "firmware version");
+
+ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "link_status", CTLTYPE_INT | CTLFLAG_RW,
+ (void *)ha, 0,
+ qla_sysctl_get_link_status, "I", "Link Status");
+
+ ha->dbg_level = 0;
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "debug", CTLFLAG_RW,
+ &ha->dbg_level, ha->dbg_level, "Debug Level");
+
+ ha->std_replenish = QL_STD_REPLENISH_THRES;
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "std_replenish", CTLFLAG_RW,
+ &ha->std_replenish, ha->std_replenish,
+ "Threshold for Replenishing Standard Frames");
+
+ SYSCTL_ADD_QUAD(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "ipv4_lro",
+ CTLFLAG_RD, &ha->ipv4_lro,
+ "number of ipv4 lro completions");
+
+ SYSCTL_ADD_QUAD(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "ipv6_lro",
+ CTLFLAG_RD, &ha->ipv6_lro,
+ "number of ipv6 lro completions");
+
+ SYSCTL_ADD_QUAD(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "tx_tso_frames",
+ CTLFLAG_RD, &ha->tx_tso_frames,
+ "number of Tx TSO Frames");
+
+ SYSCTL_ADD_QUAD(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "hw_vlan_tx_frames",
+ CTLFLAG_RD, &ha->hw_vlan_tx_frames,
+ "number of Tx VLAN Frames");
+
+ return;
+}
+
+static void
+qla_watchdog(void *arg)
+{
+ qla_host_t *ha = arg;
+ qla_hw_t *hw;
+ struct ifnet *ifp;
+ uint32_t i;
+ qla_hw_tx_cntxt_t *hw_tx_cntxt;
+
+ hw = &ha->hw;
+ ifp = ha->ifp;
+
+ if (ha->flags.qla_watchdog_exit) {
+ ha->qla_watchdog_exited = 1;
+ return;
+ }
+ ha->qla_watchdog_exited = 0;
+
+ if (!ha->flags.qla_watchdog_pause) {
+ if (ql_hw_check_health(ha) || ha->qla_initiate_recovery ||
+ (ha->msg_from_peer == QL_PEER_MSG_RESET)) {
+ ha->qla_watchdog_paused = 1;
+ ha->flags.qla_watchdog_pause = 1;
+ ha->qla_initiate_recovery = 0;
+ ha->err_inject = 0;
+ taskqueue_enqueue(ha->err_tq, &ha->err_task);
+ } else {
+ for (i = 0; i < ha->hw.num_tx_rings; i++) {
+ hw_tx_cntxt = &hw->tx_cntxt[i];
+ if (qla_le32_to_host(*(hw_tx_cntxt->tx_cons)) !=
+ hw_tx_cntxt->txr_comp) {
+ taskqueue_enqueue(ha->tx_tq,
+ &ha->tx_task);
+ break;
+ }
+ }
+
+ if ((ifp->if_snd.ifq_head != NULL) && QL_RUNNING(ifp)) {
+ taskqueue_enqueue(ha->tx_tq, &ha->tx_task);
+ }
+ ha->qla_watchdog_paused = 0;
+ }
+
+ } else {
+ ha->qla_watchdog_paused = 1;
+ }
+
+ ha->watchdog_ticks = ha->watchdog_ticks++ % 1000;
+ callout_reset(&ha->tx_callout, QLA_WATCHDOG_CALLOUT_TICKS,
+ qla_watchdog, ha);
+}
+
+/*
+ * Name: qla_pci_attach
+ * Function: attaches the device to the operating system
+ */
+static int
+qla_pci_attach(device_t dev)
+{
+ qla_host_t *ha = NULL;
+ uint32_t rsrc_len;
+ int i;
+
+ QL_DPRINT2(ha, (dev, "%s: enter\n", __func__));
+
+ if ((ha = device_get_softc(dev)) == NULL) {
+ device_printf(dev, "cannot get softc\n");
+ return (ENOMEM);
+ }
+
+ memset(ha, 0, sizeof (qla_host_t));
+
+ if (pci_get_device(dev) != PCI_PRODUCT_QLOGIC_ISP8030) {
+ device_printf(dev, "device is not ISP8030\n");
+ return (ENXIO);
+ }
+
+ ha->pci_func = pci_get_function(dev);
+
+ ha->pci_dev = dev;
+
+ pci_enable_busmaster(dev);
+
+ ha->reg_rid = PCIR_BAR(0);
+ ha->pci_reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &ha->reg_rid,
+ RF_ACTIVE);
+
+ if (ha->pci_reg == NULL) {
+ device_printf(dev, "unable to map any ports\n");
+ goto qla_pci_attach_err;
+ }
+
+ rsrc_len = (uint32_t) bus_get_resource_count(dev, SYS_RES_MEMORY,
+ ha->reg_rid);
+
+ mtx_init(&ha->hw_lock, "qla83xx_hw_lock", MTX_NETWORK_LOCK, MTX_DEF);
+
+ mtx_init(&ha->tx_lock, "qla83xx_tx_lock", MTX_NETWORK_LOCK, MTX_DEF);
+
+ qla_add_sysctls(ha);
+ ql_hw_add_sysctls(ha);
+
+ ha->flags.lock_init = 1;
+
+ ha->reg_rid1 = PCIR_BAR(2);
+ ha->pci_reg1 = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &ha->reg_rid1, RF_ACTIVE);
+
+ ha->msix_count = pci_msix_count(dev);
+
+ if (ha->msix_count < (ha->hw.num_sds_rings + 1)) {
+ device_printf(dev, "%s: msix_count[%d] not enough\n", __func__,
+ ha->msix_count);
+ goto qla_pci_attach_err;
+ }
+
+ QL_DPRINT2(ha, (dev, "%s: ha %p pci_func 0x%x rsrc_count 0x%08x"
+ " msix_count 0x%x pci_reg %p\n", __func__, ha,
+ ha->pci_func, rsrc_len, ha->msix_count, ha->pci_reg));
+
+ ha->msix_count = ha->hw.num_sds_rings + 1;
+
+ if (pci_alloc_msix(dev, &ha->msix_count)) {
+ device_printf(dev, "%s: pci_alloc_msi[%d] failed\n", __func__,
+ ha->msix_count);
+ ha->msix_count = 0;
+ goto qla_pci_attach_err;
+ }
+
+ ha->mbx_irq_rid = 1;
+ ha->mbx_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &ha->mbx_irq_rid,
+ (RF_ACTIVE | RF_SHAREABLE));
+ if (ha->mbx_irq == NULL) {
+ device_printf(dev, "could not allocate mbx interrupt\n");
+ goto qla_pci_attach_err;
+ }
+ if (bus_setup_intr(dev, ha->mbx_irq, (INTR_TYPE_NET | INTR_MPSAFE),
+ NULL, ql_mbx_isr, ha, &ha->mbx_handle)) {
+ device_printf(dev, "could not setup mbx interrupt\n");
+ goto qla_pci_attach_err;
+ }
+
+
+ for (i = 0; i < ha->hw.num_sds_rings; i++) {
+ ha->irq_vec[i].sds_idx = i;
+ ha->irq_vec[i].ha = ha;
+ ha->irq_vec[i].irq_rid = 2 + i;
+
+ ha->irq_vec[i].irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &ha->irq_vec[i].irq_rid,
+ (RF_ACTIVE | RF_SHAREABLE));
+
+ if (ha->irq_vec[i].irq == NULL) {
+ device_printf(dev, "could not allocate interrupt\n");
+ goto qla_pci_attach_err;
+ }
+ if (bus_setup_intr(dev, ha->irq_vec[i].irq,
+ (INTR_TYPE_NET | INTR_MPSAFE),
+ NULL, ql_isr, &ha->irq_vec[i],
+ &ha->irq_vec[i].handle)) {
+ device_printf(dev, "could not setup interrupt\n");
+ goto qla_pci_attach_err;
+ }
+ }
+
+ printf("%s: mp__ncpus %d sds %d rds %d msi-x %d\n", __func__, mp_ncpus,
+ ha->hw.num_sds_rings, ha->hw.num_rds_rings, ha->msix_count);
+
+ /* initialize hardware */
+ if (ql_init_hw(ha)) {
+ device_printf(dev, "%s: ql_init_hw failed\n", __func__);
+ goto qla_pci_attach_err;
+ }
+
+ device_printf(dev, "%s: firmware[%d.%d.%d.%d]\n", __func__,
+ ha->fw_ver_major, ha->fw_ver_minor, ha->fw_ver_sub,
+ ha->fw_ver_build);
+ snprintf(ha->fw_ver_str, sizeof(ha->fw_ver_str), "%d.%d.%d.%d",
+ ha->fw_ver_major, ha->fw_ver_minor, ha->fw_ver_sub,
+ ha->fw_ver_build);
+
+ ql_read_mac_addr(ha);
+
+ /* allocate parent dma tag */
+ if (qla_alloc_parent_dma_tag(ha)) {
+ device_printf(dev, "%s: qla_alloc_parent_dma_tag failed\n",
+ __func__);
+ goto qla_pci_attach_err;
+ }
+
+ /* alloc all dma buffers */
+ if (ql_alloc_dma(ha)) {
+ device_printf(dev, "%s: ql_alloc_dma failed\n", __func__);
+ goto qla_pci_attach_err;
+ }
+ qla_get_peer(ha);
+
+ /* create the o.s ethernet interface */
+ qla_init_ifnet(dev, ha);
+
+ ha->flags.qla_watchdog_active = 1;
+ ha->flags.qla_watchdog_pause = 1;
+
+
+ TASK_INIT(&ha->tx_task, 0, qla_tx_done, ha);
+ ha->tx_tq = taskqueue_create_fast("qla_txq", M_NOWAIT,
+ taskqueue_thread_enqueue, &ha->tx_tq);
+ taskqueue_start_threads(&ha->tx_tq, 1, PI_NET, "%s txq",
+ device_get_nameunit(ha->pci_dev));
+
+ callout_init(&ha->tx_callout, TRUE);
+ ha->flags.qla_callout_init = 1;
+
+ /* create ioctl device interface */
+ if (ql_make_cdev(ha)) {
+ device_printf(dev, "%s: ql_make_cdev failed\n", __func__);
+ goto qla_pci_attach_err;
+ }
+
+ callout_reset(&ha->tx_callout, QLA_WATCHDOG_CALLOUT_TICKS,
+ qla_watchdog, ha);
+
+ TASK_INIT(&ha->err_task, 0, qla_error_recovery, ha);
+ ha->err_tq = taskqueue_create_fast("qla_errq", M_NOWAIT,
+ taskqueue_thread_enqueue, &ha->err_tq);
+ taskqueue_start_threads(&ha->err_tq, 1, PI_NET, "%s errq",
+ device_get_nameunit(ha->pci_dev));
+
+ QL_DPRINT2(ha, (dev, "%s: exit 0\n", __func__));
+ return (0);
+
+qla_pci_attach_err:
+
+ qla_release(ha);
+
+ QL_DPRINT2(ha, (dev, "%s: exit ENXIO\n", __func__));
+ return (ENXIO);
+}
+
+/*
+ * Name: qla_pci_detach
+ * Function: Unhooks the device from the operating system
+ */
+static int
+qla_pci_detach(device_t dev)
+{
+ qla_host_t *ha = NULL;
+ struct ifnet *ifp;
+
+ QL_DPRINT2(ha, (dev, "%s: enter\n", __func__));
+
+ if ((ha = device_get_softc(dev)) == NULL) {
+ device_printf(dev, "cannot get softc\n");
+ return (ENOMEM);
+ }
+
+ ifp = ha->ifp;
+
+ (void)QLA_LOCK(ha, __func__, 0);
+ qla_stop(ha);
+ QLA_UNLOCK(ha, __func__);
+
+ qla_release(ha);
+
+ QL_DPRINT2(ha, (dev, "%s: exit\n", __func__));
+
+ return (0);
+}
+
+/*
+ * SYSCTL Related Callbacks
+ */
+static int
+qla_sysctl_get_stats(SYSCTL_HANDLER_ARGS)
+{
+ int err, ret = 0;
+ qla_host_t *ha;
+
+ err = sysctl_handle_int(oidp, &ret, 0, req);
+
+ if (err || !req->newptr)
+ return (err);
+
+ if (ret == 1) {
+ ha = (qla_host_t *)arg1;
+ ql_get_stats(ha);
+ }
+ return (err);
+}
+static int
+qla_sysctl_get_link_status(SYSCTL_HANDLER_ARGS)
+{
+ int err, ret = 0;
+ qla_host_t *ha;
+
+ err = sysctl_handle_int(oidp, &ret, 0, req);
+
+ if (err || !req->newptr)
+ return (err);
+
+ if (ret == 1) {
+ ha = (qla_host_t *)arg1;
+ ql_hw_link_status(ha);
+ }
+ return (err);
+}
+
+/*
+ * Name: qla_release
+ * Function: Releases the resources allocated for the device
+ */
+static void
+qla_release(qla_host_t *ha)
+{
+ device_t dev;
+ int i;
+
+ dev = ha->pci_dev;
+
+ if (ha->err_tq) {
+ taskqueue_drain(ha->err_tq, &ha->err_task);
+ taskqueue_free(ha->err_tq);
+ }
+
+ if (ha->tx_tq) {
+ taskqueue_drain(ha->tx_tq, &ha->tx_task);
+ taskqueue_free(ha->tx_tq);
+ }
+
+ ql_del_cdev(ha);
+
+ if (ha->flags.qla_watchdog_active) {
+ ha->flags.qla_watchdog_exit = 1;
+
+ while (ha->qla_watchdog_exited == 0)
+ qla_mdelay(__func__, 1);
+ }
+
+ if (ha->flags.qla_callout_init)
+ callout_stop(&ha->tx_callout);
+
+ if (ha->ifp != NULL)
+ ether_ifdetach(ha->ifp);
+
+ ql_free_dma(ha);
+ qla_free_parent_dma_tag(ha);
+
+ if (ha->mbx_handle)
+ (void)bus_teardown_intr(dev, ha->mbx_irq, ha->mbx_handle);
+
+ if (ha->mbx_irq)
+ (void) bus_release_resource(dev, SYS_RES_IRQ, ha->mbx_irq_rid,
+ ha->mbx_irq);
+
+ for (i = 0; i < ha->hw.num_sds_rings; i++) {
+
+ if (ha->irq_vec[i].handle) {
+ (void)bus_teardown_intr(dev, ha->irq_vec[i].irq,
+ ha->irq_vec[i].handle);
+ }
+
+ if (ha->irq_vec[i].irq) {
+ (void)bus_release_resource(dev, SYS_RES_IRQ,
+ ha->irq_vec[i].irq_rid,
+ ha->irq_vec[i].irq);
+ }
+ }
+
+ if (ha->msix_count)
+ pci_release_msi(dev);
+
+ if (ha->flags.lock_init) {
+ mtx_destroy(&ha->tx_lock);
+ mtx_destroy(&ha->hw_lock);
+ }
+
+ if (ha->pci_reg)
+ (void) bus_release_resource(dev, SYS_RES_MEMORY, ha->reg_rid,
+ ha->pci_reg);
+
+ if (ha->pci_reg1)
+ (void) bus_release_resource(dev, SYS_RES_MEMORY, ha->reg_rid1,
+ ha->pci_reg1);
+}
+
+/*
+ * DMA Related Functions
+ */
+
+static void
+qla_dmamap_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+ *((bus_addr_t *)arg) = 0;
+
+ if (error) {
+ printf("%s: bus_dmamap_load failed (%d)\n", __func__, error);
+ return;
+ }
+
+ *((bus_addr_t *)arg) = segs[0].ds_addr;
+
+ return;
+}
+
+int
+ql_alloc_dmabuf(qla_host_t *ha, qla_dma_t *dma_buf)
+{
+ int ret = 0;
+ device_t dev;
+ bus_addr_t b_addr;
+
+ dev = ha->pci_dev;
+
+ QL_DPRINT2(ha, (dev, "%s: enter\n", __func__));
+
+ ret = bus_dma_tag_create(
+ ha->parent_tag,/* parent */
+ dma_buf->alignment,
+ ((bus_size_t)(1ULL << 32)),/* boundary */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ dma_buf->size, /* maxsize */
+ 1, /* nsegments */
+ dma_buf->size, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &dma_buf->dma_tag);
+
+ if (ret) {
+ device_printf(dev, "%s: could not create dma tag\n", __func__);
+ goto ql_alloc_dmabuf_exit;
+ }
+ ret = bus_dmamem_alloc(dma_buf->dma_tag,
+ (void **)&dma_buf->dma_b,
+ (BUS_DMA_ZERO | BUS_DMA_COHERENT | BUS_DMA_NOWAIT),
+ &dma_buf->dma_map);
+ if (ret) {
+ bus_dma_tag_destroy(dma_buf->dma_tag);
+ device_printf(dev, "%s: bus_dmamem_alloc failed\n", __func__);
+ goto ql_alloc_dmabuf_exit;
+ }
+
+ ret = bus_dmamap_load(dma_buf->dma_tag,
+ dma_buf->dma_map,
+ dma_buf->dma_b,
+ dma_buf->size,
+ qla_dmamap_callback,
+ &b_addr, BUS_DMA_NOWAIT);
+
+ if (ret || !b_addr) {
+ bus_dma_tag_destroy(dma_buf->dma_tag);
+ bus_dmamem_free(dma_buf->dma_tag, dma_buf->dma_b,
+ dma_buf->dma_map);
+ ret = -1;
+ goto ql_alloc_dmabuf_exit;
+ }
+
+ dma_buf->dma_addr = b_addr;
+
+ql_alloc_dmabuf_exit:
+ QL_DPRINT2(ha, (dev, "%s: exit ret 0x%08x tag %p map %p b %p sz 0x%x\n",
+ __func__, ret, (void *)dma_buf->dma_tag,
+ (void *)dma_buf->dma_map, (void *)dma_buf->dma_b,
+ dma_buf->size));
+
+ return ret;
+}
+
+void
+ql_free_dmabuf(qla_host_t *ha, qla_dma_t *dma_buf)
+{
+ bus_dmamem_free(dma_buf->dma_tag, dma_buf->dma_b, dma_buf->dma_map);
+ bus_dma_tag_destroy(dma_buf->dma_tag);
+}
+
+static int
+qla_alloc_parent_dma_tag(qla_host_t *ha)
+{
+ int ret;
+ device_t dev;
+
+ dev = ha->pci_dev;
+
+ /*
+ * Allocate parent DMA Tag
+ */
+ ret = bus_dma_tag_create(
+ bus_get_dma_tag(dev), /* parent */
+ 1,((bus_size_t)(1ULL << 32)),/* alignment, boundary */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ BUS_SPACE_MAXSIZE_32BIT,/* maxsize */
+ 0, /* nsegments */
+ BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &ha->parent_tag);
+
+ if (ret) {
+ device_printf(dev, "%s: could not create parent dma tag\n",
+ __func__);
+ return (-1);
+ }
+
+ ha->flags.parent_tag = 1;
+
+ return (0);
+}
+
+static void
+qla_free_parent_dma_tag(qla_host_t *ha)
+{
+ if (ha->flags.parent_tag) {
+ bus_dma_tag_destroy(ha->parent_tag);
+ ha->flags.parent_tag = 0;
+ }
+}
+
+/*
+ * Name: qla_init_ifnet
+ * Function: Creates the Network Device Interface and Registers it with the O.S
+ */
+
+static void
+qla_init_ifnet(device_t dev, qla_host_t *ha)
+{
+ struct ifnet *ifp;
+
+ QL_DPRINT2(ha, (dev, "%s: enter\n", __func__));
+
+ ifp = ha->ifp = if_alloc(IFT_ETHER);
+
+ if (ifp == NULL)
+ panic("%s: cannot if_alloc()\n", device_get_nameunit(dev));
+
+ if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+
+#if __FreeBSD_version >= 1000000
+ if_initbaudrate(ifp, IF_Gbps(10));
+ ifp->if_capabilities = IFCAP_LINKSTATE;
+#else
+ ifp->if_mtu = ETHERMTU;
+ ifp->if_baudrate = (1 * 1000 * 1000 *1000);
+
+#endif /* #if __FreeBSD_version >= 1000000 */
+
+ ifp->if_init = qla_init;
+ ifp->if_softc = ha;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_ioctl = qla_ioctl;
+ ifp->if_start = qla_start;
+
+ IFQ_SET_MAXLEN(&ifp->if_snd, qla_get_ifq_snd_maxlen(ha));
+ ifp->if_snd.ifq_drv_maxlen = qla_get_ifq_snd_maxlen(ha);
+ IFQ_SET_READY(&ifp->if_snd);
+
+ ha->max_frame_size = ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
+
+ ether_ifattach(ifp, qla_get_mac_addr(ha));
+
+ ifp->if_capabilities = IFCAP_HWCSUM |
+ IFCAP_TSO4 |
+ IFCAP_JUMBO_MTU;
+
+ ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
+ ifp->if_capabilities |= IFCAP_VLAN_HWTSO;
+
+ ifp->if_capenable = ifp->if_capabilities;
+
+ ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
+
+ ifmedia_init(&ha->media, IFM_IMASK, qla_media_change, qla_media_status);
+
+ ifmedia_add(&ha->media, (IFM_ETHER | qla_get_optics(ha) | IFM_FDX), 0,
+ NULL);
+ ifmedia_add(&ha->media, (IFM_ETHER | IFM_AUTO), 0, NULL);
+
+ ifmedia_set(&ha->media, (IFM_ETHER | IFM_AUTO));
+
+ QL_DPRINT2(ha, (dev, "%s: exit\n", __func__));
+
+ return;
+}
+
+static void
+qla_init_locked(qla_host_t *ha)
+{
+ struct ifnet *ifp = ha->ifp;
+
+ qla_stop(ha);
+
+ if (qla_alloc_xmt_bufs(ha) != 0)
+ return;
+
+ if (qla_alloc_rcv_bufs(ha) != 0)
+ return;
+
+ bcopy(IF_LLADDR(ha->ifp), ha->hw.mac_addr, ETHER_ADDR_LEN);
+
+ ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_TSO;
+
+ ha->flags.stop_rcv = 0;
+ if (ql_init_hw_if(ha) == 0) {
+ ifp = ha->ifp;
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ ha->flags.qla_watchdog_pause = 0;
+ ha->hw_vlan_tx_frames = 0;
+ ha->tx_tso_frames = 0;
+ }
+
+ return;
+}
+
+static void
+qla_init(void *arg)
+{
+ qla_host_t *ha;
+
+ ha = (qla_host_t *)arg;
+
+ QL_DPRINT2(ha, (ha->pci_dev, "%s: enter\n", __func__));
+
+ (void)QLA_LOCK(ha, __func__, 0);
+ qla_init_locked(ha);
+ QLA_UNLOCK(ha, __func__);
+
+ QL_DPRINT2(ha, (ha->pci_dev, "%s: exit\n", __func__));
+}
+
+static int
+qla_set_multi(qla_host_t *ha, uint32_t add_multi)
+{
+ uint8_t mta[Q8_MAX_NUM_MULTICAST_ADDRS * Q8_MAC_ADDR_LEN];
+ struct ifmultiaddr *ifma;
+ int mcnt = 0;
+ struct ifnet *ifp = ha->ifp;
+ int ret = 0;
+
+ if_maddr_rlock(ifp);
+
+ TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+
+ if (ifma->ifma_addr->sa_family != AF_LINK)
+ continue;
+
+ if (mcnt == Q8_MAX_NUM_MULTICAST_ADDRS)
+ break;
+
+ bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
+ &mta[mcnt * Q8_MAC_ADDR_LEN], Q8_MAC_ADDR_LEN);
+
+ mcnt++;
+ }
+
+ if_maddr_runlock(ifp);
+
+ if (QLA_LOCK(ha, __func__, 1) == 0) {
+ ret = ql_hw_set_multi(ha, mta, mcnt, add_multi);
+ QLA_UNLOCK(ha, __func__);
+ }
+
+ return (ret);
+}
+
+static int
+qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+ int ret = 0;
+ struct ifreq *ifr = (struct ifreq *)data;
+ struct ifaddr *ifa = (struct ifaddr *)data;
+ qla_host_t *ha;
+
+ ha = (qla_host_t *)ifp->if_softc;
+
+ switch (cmd) {
+ case SIOCSIFADDR:
+ QL_DPRINT4(ha, (ha->pci_dev, "%s: SIOCSIFADDR (0x%lx)\n",
+ __func__, cmd));
+
+ if (ifa->ifa_addr->sa_family == AF_INET) {
+ ifp->if_flags |= IFF_UP;
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ (void)QLA_LOCK(ha, __func__, 0);
+ qla_init_locked(ha);
+ QLA_UNLOCK(ha, __func__);
+ }
+ QL_DPRINT4(ha, (ha->pci_dev,
+ "%s: SIOCSIFADDR (0x%lx) ipv4 [0x%08x]\n",
+ __func__, cmd,
+ ntohl(IA_SIN(ifa)->sin_addr.s_addr)));
+
+ arp_ifinit(ifp, ifa);
+ } else {
+ ether_ioctl(ifp, cmd, data);
+ }
+ break;
+
+ case SIOCSIFMTU:
+ QL_DPRINT4(ha, (ha->pci_dev, "%s: SIOCSIFMTU (0x%lx)\n",
+ __func__, cmd));
+
+ if (ifr->ifr_mtu > QLA_MAX_MTU) {
+ ret = EINVAL;
+ } else {
+ (void) QLA_LOCK(ha, __func__, 0);
+ ifp->if_mtu = ifr->ifr_mtu;
+ ha->max_frame_size =
+ ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ ret = ql_set_max_mtu(ha, ha->max_frame_size,
+ ha->hw.rcv_cntxt_id);
+ }
+
+ if (ifp->if_mtu > ETHERMTU)
+ ha->std_replenish = QL_JUMBO_REPLENISH_THRES;
+ else
+ ha->std_replenish = QL_STD_REPLENISH_THRES;
+
+
+ QLA_UNLOCK(ha, __func__);
+
+ if (ret)
+ ret = EINVAL;
+ }
+
+ break;
+
+ case SIOCSIFFLAGS:
+ QL_DPRINT4(ha, (ha->pci_dev, "%s: SIOCSIFFLAGS (0x%lx)\n",
+ __func__, cmd));
+
+ (void)QLA_LOCK(ha, __func__, 0);
+
+ if (ifp->if_flags & IFF_UP) {
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if ((ifp->if_flags ^ ha->if_flags) &
+ IFF_PROMISC) {
+ ret = ql_set_promisc(ha);
+ } else if ((ifp->if_flags ^ ha->if_flags) &
+ IFF_ALLMULTI) {
+ ret = ql_set_allmulti(ha);
+ }
+ } else {
+ qla_init_locked(ha);
+ ha->max_frame_size = ifp->if_mtu +
+ ETHER_HDR_LEN + ETHER_CRC_LEN;
+ ret = ql_set_max_mtu(ha, ha->max_frame_size,
+ ha->hw.rcv_cntxt_id);
+ }
+ } else {
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ qla_stop(ha);
+ ha->if_flags = ifp->if_flags;
+ }
+
+ QLA_UNLOCK(ha, __func__);
+ break;
+
+ case SIOCADDMULTI:
+ QL_DPRINT4(ha, (ha->pci_dev,
+ "%s: %s (0x%lx)\n", __func__, "SIOCADDMULTI", cmd));
+
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ if (qla_set_multi(ha, 1))
+ ret = EINVAL;
+ }
+ break;
+
+ case SIOCDELMULTI:
+ QL_DPRINT4(ha, (ha->pci_dev,
+ "%s: %s (0x%lx)\n", __func__, "SIOCDELMULTI", cmd));
+
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ if (qla_set_multi(ha, 0))
+ ret = EINVAL;
+ }
+ break;
+
+ case SIOCSIFMEDIA:
+ case SIOCGIFMEDIA:
+ QL_DPRINT4(ha, (ha->pci_dev,
+ "%s: SIOCSIFMEDIA/SIOCGIFMEDIA (0x%lx)\n",
+ __func__, cmd));
+ ret = ifmedia_ioctl(ifp, ifr, &ha->media, cmd);
+ break;
+
+ case SIOCSIFCAP:
+ {
+ int mask = ifr->ifr_reqcap ^ ifp->if_capenable;
+
+ QL_DPRINT4(ha, (ha->pci_dev, "%s: SIOCSIFCAP (0x%lx)\n",
+ __func__, cmd));
+
+ if (mask & IFCAP_HWCSUM)
+ ifp->if_capenable ^= IFCAP_HWCSUM;
+ if (mask & IFCAP_TSO4)
+ ifp->if_capenable ^= IFCAP_TSO4;
+ if (mask & IFCAP_VLAN_HWTAGGING)
+ ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
+ if (mask & IFCAP_VLAN_HWTSO)
+ ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
+
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ qla_init(ha);
+
+ VLAN_CAPABILITIES(ifp);
+ break;
+ }
+
+ default:
+ QL_DPRINT4(ha, (ha->pci_dev, "%s: default (0x%lx)\n",
+ __func__, cmd));
+ ret = ether_ioctl(ifp, cmd, data);
+ break;
+ }
+
+ return (ret);
+}
+
+static int
+qla_media_change(struct ifnet *ifp)
+{
+ qla_host_t *ha;
+ struct ifmedia *ifm;
+ int ret = 0;
+
+ ha = (qla_host_t *)ifp->if_softc;
+
+ QL_DPRINT2(ha, (ha->pci_dev, "%s: enter\n", __func__));
+
+ ifm = &ha->media;
+
+ if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
+ ret = EINVAL;
+
+ QL_DPRINT2(ha, (ha->pci_dev, "%s: exit\n", __func__));
+
+ return (ret);
+}
+
+static void
+qla_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+ qla_host_t *ha;
+
+ ha = (qla_host_t *)ifp->if_softc;
+
+ QL_DPRINT2(ha, (ha->pci_dev, "%s: enter\n", __func__));
+
+ ifmr->ifm_status = IFM_AVALID;
+ ifmr->ifm_active = IFM_ETHER;
+
+ ql_update_link_state(ha);
+ if (ha->hw.link_up) {
+ ifmr->ifm_status |= IFM_ACTIVE;
+ ifmr->ifm_active |= (IFM_FDX | qla_get_optics(ha));
+ }
+
+ QL_DPRINT2(ha, (ha->pci_dev, "%s: exit (%s)\n", __func__,\
+ (ha->hw.link_up ? "link_up" : "link_down")));
+
+ return;
+}
+
+static void
+qla_start(struct ifnet *ifp)
+{
+ struct mbuf *m_head;
+ qla_host_t *ha = (qla_host_t *)ifp->if_softc;
+
+ QL_DPRINT8(ha, (ha->pci_dev, "%s: enter\n", __func__));
+
+ if (!mtx_trylock(&ha->tx_lock)) {
+ QL_DPRINT8(ha, (ha->pci_dev,
+ "%s: mtx_trylock(&ha->tx_lock) failed\n", __func__));
+ return;
+ }
+
+ if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING) {
+ QL_DPRINT8(ha,
+ (ha->pci_dev, "%s: !IFF_DRV_RUNNING\n", __func__));
+ QLA_TX_UNLOCK(ha);
+ return;
+ }
+
+ if (!ha->watchdog_ticks)
+ ql_update_link_state(ha);
+
+ if (!ha->hw.link_up) {
+ QL_DPRINT8(ha, (ha->pci_dev, "%s: link down\n", __func__));
+ QLA_TX_UNLOCK(ha);
+ return;
+ }
+
+ while (ifp->if_snd.ifq_head != NULL) {
+ IF_DEQUEUE(&ifp->if_snd, m_head);
+
+ if (m_head == NULL) {
+ QL_DPRINT8(ha, (ha->pci_dev, "%s: m_head == NULL\n",
+ __func__));
+ break;
+ }
+
+ if (qla_send(ha, &m_head)) {
+ if (m_head == NULL)
+ break;
+ QL_DPRINT8(ha, (ha->pci_dev, "%s: PREPEND\n", __func__));
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ IF_PREPEND(&ifp->if_snd, m_head);
+ break;
+ }
+ /* Send a copy of the frame to the BPF listener */
+ ETHER_BPF_MTAP(ifp, m_head);
+ }
+ QLA_TX_UNLOCK(ha);
+ QL_DPRINT8(ha, (ha->pci_dev, "%s: exit\n", __func__));
+ return;
+}
+
+static int
+qla_send(qla_host_t *ha, struct mbuf **m_headp)
+{
+ bus_dma_segment_t segs[QLA_MAX_SEGMENTS];
+ bus_dmamap_t map;
+ int nsegs;
+ int ret = -1;
+ uint32_t tx_idx;
+ struct mbuf *m_head = *m_headp;
+ uint32_t txr_idx = ha->txr_idx;
+
+ QL_DPRINT8(ha, (ha->pci_dev, "%s: enter\n", __func__));
+
+ if (m_head->m_flags & M_FLOWID)
+ txr_idx = m_head->m_pkthdr.flowid & (ha->hw.num_tx_rings - 1);
+
+ tx_idx = ha->hw.tx_cntxt[txr_idx].txr_next;
+ map = ha->tx_ring[txr_idx].tx_buf[tx_idx].map;
+
+ ret = bus_dmamap_load_mbuf_sg(ha->tx_tag, map, m_head, segs, &nsegs,
+ BUS_DMA_NOWAIT);
+
+ if (ret == EFBIG) {
+
+ struct mbuf *m;
+
+ QL_DPRINT8(ha, (ha->pci_dev, "%s: EFBIG [%d]\n", __func__,
+ m_head->m_pkthdr.len));
+
+ m = m_defrag(m_head, M_NOWAIT);
+ if (m == NULL) {
+ ha->err_tx_defrag++;
+ m_freem(m_head);
+ *m_headp = NULL;
+ device_printf(ha->pci_dev,
+ "%s: m_defrag() = NULL [%d]\n",
+ __func__, ret);
+ return (ENOBUFS);
+ }
+ m_head = m;
+ *m_headp = m_head;
+
+ if ((ret = bus_dmamap_load_mbuf_sg(ha->tx_tag, map, m_head,
+ segs, &nsegs, BUS_DMA_NOWAIT))) {
+
+ ha->err_tx_dmamap_load++;
+
+ device_printf(ha->pci_dev,
+ "%s: bus_dmamap_load_mbuf_sg failed0[%d, %d]\n",
+ __func__, ret, m_head->m_pkthdr.len);
+
+ if (ret != ENOMEM) {
+ m_freem(m_head);
+ *m_headp = NULL;
+ }
+ return (ret);
+ }
+
+ } else if (ret) {
+
+ ha->err_tx_dmamap_load++;
+
+ device_printf(ha->pci_dev,
+ "%s: bus_dmamap_load_mbuf_sg failed1[%d, %d]\n",
+ __func__, ret, m_head->m_pkthdr.len);
+
+ if (ret != ENOMEM) {
+ m_freem(m_head);
+ *m_headp = NULL;
+ }
+ return (ret);
+ }
+
+ QL_ASSERT(ha, (nsegs != 0), ("qla_send: empty packet"));
+
+ bus_dmamap_sync(ha->tx_tag, map, BUS_DMASYNC_PREWRITE);
+
+ if (!(ret = ql_hw_send(ha, segs, nsegs, tx_idx, m_head, txr_idx))) {
+
+ ha->tx_ring[txr_idx].count++;
+ ha->tx_ring[txr_idx].tx_buf[tx_idx].m_head = m_head;
+ } else {
+ if (ret == EINVAL) {
+ if (m_head)
+ m_freem(m_head);
+ *m_headp = NULL;
+ }
+ }
+
+ QL_DPRINT8(ha, (ha->pci_dev, "%s: exit\n", __func__));
+ return (ret);
+}
+
+static void
+qla_stop(qla_host_t *ha)
+{
+ struct ifnet *ifp = ha->ifp;
+ device_t dev;
+
+ dev = ha->pci_dev;
+
+ ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING);
+
+ ha->flags.qla_watchdog_pause = 1;
+
+ while (!ha->qla_watchdog_paused)
+ qla_mdelay(__func__, 1);
+
+ ha->flags.stop_rcv = 1;
+ ql_hw_stop_rcv(ha);
+
+ ql_del_hw_if(ha);
+
+ qla_free_xmt_bufs(ha);
+ qla_free_rcv_bufs(ha);
+
+ return;
+}
+
+/*
+ * Buffer Management Functions for Transmit and Receive Rings
+ */
+static int
+qla_alloc_xmt_bufs(qla_host_t *ha)
+{
+ int ret = 0;
+ uint32_t i, j;
+ qla_tx_buf_t *txb;
+
+ if (bus_dma_tag_create(NULL, /* parent */
+ 1, 0, /* alignment, bounds */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ QLA_MAX_TSO_FRAME_SIZE, /* maxsize */
+ QLA_MAX_SEGMENTS, /* nsegments */
+ PAGE_SIZE, /* maxsegsize */
+ BUS_DMA_ALLOCNOW, /* flags */
+ NULL, /* lockfunc */
+ NULL, /* lockfuncarg */
+ &ha->tx_tag)) {
+ device_printf(ha->pci_dev, "%s: tx_tag alloc failed\n",
+ __func__);
+ return (ENOMEM);
+ }
+
+ for (i = 0; i < ha->hw.num_tx_rings; i++) {
+ bzero((void *)ha->tx_ring[i].tx_buf,
+ (sizeof(qla_tx_buf_t) * NUM_TX_DESCRIPTORS));
+ }
+
+ for (j = 0; j < ha->hw.num_tx_rings; j++) {
+ for (i = 0; i < NUM_TX_DESCRIPTORS; i++) {
+
+ txb = &ha->tx_ring[j].tx_buf[i];
+
+ if ((ret = bus_dmamap_create(ha->tx_tag,
+ BUS_DMA_NOWAIT, &txb->map))) {
+
+ ha->err_tx_dmamap_create++;
+ device_printf(ha->pci_dev,
+ "%s: bus_dmamap_create failed[%d]\n",
+ __func__, ret);
+
+ qla_free_xmt_bufs(ha);
+
+ return (ret);
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Release mbuf after it sent on the wire
+ */
+static void
+qla_clear_tx_buf(qla_host_t *ha, qla_tx_buf_t *txb)
+{
+ QL_DPRINT2(ha, (ha->pci_dev, "%s: enter\n", __func__));
+
+ if (txb->m_head && txb->map) {
+
+ bus_dmamap_unload(ha->tx_tag, txb->map);
+
+ m_freem(txb->m_head);
+ txb->m_head = NULL;
+ }
+
+ if (txb->map)
+ bus_dmamap_destroy(ha->tx_tag, txb->map);
+
+ QL_DPRINT2(ha, (ha->pci_dev, "%s: exit\n", __func__));
+}
+
+static void
+qla_free_xmt_bufs(qla_host_t *ha)
+{
+ int i, j;
+
+ for (j = 0; j < ha->hw.num_tx_rings; j++) {
+ for (i = 0; i < NUM_TX_DESCRIPTORS; i++)
+ qla_clear_tx_buf(ha, &ha->tx_ring[j].tx_buf[i]);
+ }
+
+ if (ha->tx_tag != NULL) {
+ bus_dma_tag_destroy(ha->tx_tag);
+ ha->tx_tag = NULL;
+ }
+
+ for (i = 0; i < ha->hw.num_tx_rings; i++) {
+ bzero((void *)ha->tx_ring[i].tx_buf,
+ (sizeof(qla_tx_buf_t) * NUM_TX_DESCRIPTORS));
+ }
+ return;
+}
+
+
+static int
+qla_alloc_rcv_std(qla_host_t *ha)
+{
+ int i, j, k, r, ret = 0;
+ qla_rx_buf_t *rxb;
+ qla_rx_ring_t *rx_ring;
+
+ for (r = 0; r < ha->hw.num_rds_rings; r++) {
+
+ rx_ring = &ha->rx_ring[r];
+
+ for (i = 0; i < NUM_RX_DESCRIPTORS; i++) {
+
+ rxb = &rx_ring->rx_buf[i];
+
+ ret = bus_dmamap_create(ha->rx_tag, BUS_DMA_NOWAIT,
+ &rxb->map);
+
+ if (ret) {
+ device_printf(ha->pci_dev,
+ "%s: dmamap[%d, %d] failed\n",
+ __func__, r, i);
+
+ for (k = 0; k < r; k++) {
+ for (j = 0; j < NUM_RX_DESCRIPTORS;
+ j++) {
+ rxb = &ha->rx_ring[k].rx_buf[j];
+ bus_dmamap_destroy(ha->rx_tag,
+ rxb->map);
+ }
+ }
+
+ for (j = 0; j < i; j++) {
+ bus_dmamap_destroy(ha->rx_tag,
+ rx_ring->rx_buf[j].map);
+ }
+ goto qla_alloc_rcv_std_err;
+ }
+ }
+ }
+
+ qla_init_hw_rcv_descriptors(ha);
+
+
+ for (r = 0; r < ha->hw.num_rds_rings; r++) {
+
+ rx_ring = &ha->rx_ring[r];
+
+ for (i = 0; i < NUM_RX_DESCRIPTORS; i++) {
+ rxb = &rx_ring->rx_buf[i];
+ rxb->handle = i;
+ if (!(ret = ql_get_mbuf(ha, rxb, NULL))) {
+ /*
+ * set the physical address in the
+ * corresponding descriptor entry in the
+ * receive ring/queue for the hba
+ */
+ qla_set_hw_rcv_desc(ha, r, i, rxb->handle,
+ rxb->paddr,
+ (rxb->m_head)->m_pkthdr.len);
+ } else {
+ device_printf(ha->pci_dev,
+ "%s: ql_get_mbuf [%d, %d] failed\n",
+ __func__, r, i);
+ bus_dmamap_destroy(ha->rx_tag, rxb->map);
+ goto qla_alloc_rcv_std_err;
+ }
+ }
+ }
+ return 0;
+
+qla_alloc_rcv_std_err:
+ return (-1);
+}
+
+static void
+qla_free_rcv_std(qla_host_t *ha)
+{
+ int i, r;
+ qla_rx_buf_t *rxb;
+
+ for (r = 0; r < ha->hw.num_rds_rings; r++) {
+ for (i = 0; i < NUM_RX_DESCRIPTORS; i++) {
+ rxb = &ha->rx_ring[r].rx_buf[i];
+ if (rxb->m_head != NULL) {
+ bus_dmamap_unload(ha->rx_tag, rxb->map);
+ bus_dmamap_destroy(ha->rx_tag, rxb->map);
+ m_freem(rxb->m_head);
+ rxb->m_head = NULL;
+ }
+ }
+ }
+ return;
+}
+
+static int
+qla_alloc_rcv_bufs(qla_host_t *ha)
+{
+ int i, ret = 0;
+
+ if (bus_dma_tag_create(NULL, /* parent */
+ 1, 0, /* alignment, bounds */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MJUM9BYTES, /* maxsize */
+ 1, /* nsegments */
+ MJUM9BYTES, /* maxsegsize */
+ BUS_DMA_ALLOCNOW, /* flags */
+ NULL, /* lockfunc */
+ NULL, /* lockfuncarg */
+ &ha->rx_tag)) {
+
+ device_printf(ha->pci_dev, "%s: rx_tag alloc failed\n",
+ __func__);
+
+ return (ENOMEM);
+ }
+
+ bzero((void *)ha->rx_ring, (sizeof(qla_rx_ring_t) * MAX_RDS_RINGS));
+
+ for (i = 0; i < ha->hw.num_sds_rings; i++) {
+ ha->hw.sds[i].sdsr_next = 0;
+ ha->hw.sds[i].rxb_free = NULL;
+ ha->hw.sds[i].rx_free = 0;
+ }
+
+ ret = qla_alloc_rcv_std(ha);
+
+ return (ret);
+}
+
+static void
+qla_free_rcv_bufs(qla_host_t *ha)
+{
+ int i;
+
+ qla_free_rcv_std(ha);
+
+ if (ha->rx_tag != NULL) {
+ bus_dma_tag_destroy(ha->rx_tag);
+ ha->rx_tag = NULL;
+ }
+
+ bzero((void *)ha->rx_ring, (sizeof(qla_rx_ring_t) * MAX_RDS_RINGS));
+
+ for (i = 0; i < ha->hw.num_sds_rings; i++) {
+ ha->hw.sds[i].sdsr_next = 0;
+ ha->hw.sds[i].rxb_free = NULL;
+ ha->hw.sds[i].rx_free = 0;
+ }
+
+ return;
+}
+
+int
+ql_get_mbuf(qla_host_t *ha, qla_rx_buf_t *rxb, struct mbuf *nmp)
+{
+ register struct mbuf *mp = nmp;
+ struct ifnet *ifp;
+ int ret = 0;
+ uint32_t offset;
+ bus_dma_segment_t segs[1];
+ int nsegs;
+
+ QL_DPRINT2(ha, (ha->pci_dev, "%s: enter\n", __func__));
+
+ ifp = ha->ifp;
+
+ if (mp == NULL) {
+
+ mp = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+
+ if (mp == NULL) {
+ ha->err_m_getcl++;
+ ret = ENOBUFS;
+ device_printf(ha->pci_dev,
+ "%s: m_getcl failed\n", __func__);
+ goto exit_ql_get_mbuf;
+ }
+ mp->m_len = mp->m_pkthdr.len = MCLBYTES;
+ } else {
+ mp->m_len = mp->m_pkthdr.len = MCLBYTES;
+ mp->m_data = mp->m_ext.ext_buf;
+ mp->m_next = NULL;
+ }
+
+ offset = (uint32_t)((unsigned long long)mp->m_data & 0x7ULL);
+ if (offset) {
+ offset = 8 - offset;
+ m_adj(mp, offset);
+ }
+
+ /*
+ * Using memory from the mbuf cluster pool, invoke the bus_dma
+ * machinery to arrange the memory mapping.
+ */
+ ret = bus_dmamap_load_mbuf_sg(ha->rx_tag, rxb->map,
+ mp, segs, &nsegs, BUS_DMA_NOWAIT);
+ rxb->paddr = segs[0].ds_addr;
+
+ if (ret || !rxb->paddr || (nsegs != 1)) {
+ m_free(mp);
+ rxb->m_head = NULL;
+ device_printf(ha->pci_dev,
+ "%s: bus_dmamap_load failed[%d, 0x%016llx, %d]\n",
+ __func__, ret, (long long unsigned int)rxb->paddr,
+ nsegs);
+ ret = -1;
+ goto exit_ql_get_mbuf;
+ }
+ rxb->m_head = mp;
+ bus_dmamap_sync(ha->rx_tag, rxb->map, BUS_DMASYNC_PREREAD);
+
+exit_ql_get_mbuf:
+ QL_DPRINT2(ha, (ha->pci_dev, "%s: exit ret = 0x%08x\n", __func__, ret));
+ return (ret);
+}
+
+static void
+qla_tx_done(void *context, int pending)
+{
+ qla_host_t *ha = context;
+ struct ifnet *ifp;
+
+ ifp = ha->ifp;
+
+ if (!ifp)
+ return;
+
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ QL_DPRINT8(ha, (ha->pci_dev, "%s: !IFF_DRV_RUNNING\n", __func__));
+ return;
+ }
+ ql_hw_tx_done(ha);
+
+ qla_start(ha->ifp);
+}
+
+static void
+qla_get_peer(qla_host_t *ha)
+{
+ device_t *peers;
+ int count, i, slot;
+ int my_slot = pci_get_slot(ha->pci_dev);
+
+ if (device_get_children(device_get_parent(ha->pci_dev), &peers, &count))
+ return;
+
+ for (i = 0; i < count; i++) {
+ slot = pci_get_slot(peers[i]);
+
+ if ((slot >= 0) && (slot == my_slot) &&
+ (pci_get_device(peers[i]) ==
+ pci_get_device(ha->pci_dev))) {
+ if (ha->pci_dev != peers[i])
+ ha->peer_dev = peers[i];
+ }
+ }
+}
+
+static void
+qla_send_msg_to_peer(qla_host_t *ha, uint32_t msg_to_peer)
+{
+ qla_host_t *ha_peer;
+
+ if (ha->peer_dev) {
+ if ((ha_peer = device_get_softc(ha->peer_dev)) != NULL) {
+
+ ha_peer->msg_from_peer = msg_to_peer;
+ }
+ }
+}
+
+static void
+qla_error_recovery(void *context, int pending)
+{
+ qla_host_t *ha = context;
+ uint32_t msecs_100 = 100;
+ struct ifnet *ifp = ha->ifp;
+
+ (void)QLA_LOCK(ha, __func__, 0);
+
+ ha->flags.stop_rcv = 1;
+
+ ql_hw_stop_rcv(ha);
+
+ ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING);
+
+ QLA_UNLOCK(ha, __func__);
+
+ ql_minidump(ha);
+
+ if ((ha->pci_func & 0x1) == 0) {
+
+ if (!ha->msg_from_peer)
+ qla_send_msg_to_peer(ha, QL_PEER_MSG_RESET);
+
+ while ((ha->msg_from_peer != QL_PEER_MSG_ACK) && msecs_100--)
+ qla_mdelay(__func__, 100);
+
+ ha->msg_from_peer = 0;
+
+ (void) ql_init_hw(ha);
+ qla_free_xmt_bufs(ha);
+ qla_free_rcv_bufs(ha);
+
+ qla_send_msg_to_peer(ha, QL_PEER_MSG_ACK);
+
+ } else {
+ if (ha->msg_from_peer == QL_PEER_MSG_RESET) {
+
+ ha->msg_from_peer = 0;
+
+ qla_send_msg_to_peer(ha, QL_PEER_MSG_ACK);
+ } else {
+ qla_send_msg_to_peer(ha, QL_PEER_MSG_RESET);
+ }
+
+ while ((ha->msg_from_peer != QL_PEER_MSG_ACK) && msecs_100--)
+ qla_mdelay(__func__, 100);
+ ha->msg_from_peer = 0;
+
+ (void) ql_init_hw(ha);
+ qla_free_xmt_bufs(ha);
+ qla_free_rcv_bufs(ha);
+ }
+ (void)QLA_LOCK(ha, __func__, 0);
+
+ if (qla_alloc_xmt_bufs(ha) != 0) {
+ QLA_UNLOCK(ha, __func__);
+ return;
+ }
+
+ if (qla_alloc_rcv_bufs(ha) != 0) {
+ QLA_UNLOCK(ha, __func__);
+ return;
+ }
+
+ ha->flags.stop_rcv = 0;
+ if (ql_init_hw_if(ha) == 0) {
+ ifp = ha->ifp;
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ ha->flags.qla_watchdog_pause = 0;
+ }
+
+ QLA_UNLOCK(ha, __func__);
+}
+
diff --git a/sys/dev/qlxgbe/ql_os.h b/sys/dev/qlxgbe/ql_os.h
new file mode 100644
index 000000000000..b6a9f3f06a71
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_os.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/*
+ * File: ql_os.h
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ */
+
+#ifndef _QL_OS_H_
+#define _QL_OS_H_
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/sockio.h>
+#include <sys/types.h>
+#include <machine/atomic.h>
+#include <machine/_inttypes.h>
+#include <sys/conf.h>
+
+#if __FreeBSD_version < 900044
+#error FreeBSD Version not supported - use version >= 900044
+#endif
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/bpf.h>
+#include <net/if_types.h>
+#include <net/if_vlan_var.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/in_var.h>
+#include <netinet/tcp_lro.h>
+
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#include <sys/endian.h>
+#include <sys/taskqueue.h>
+#include <sys/pcpu.h>
+
+#include <sys/unistd.h>
+#include <sys/kthread.h>
+
+#define QLA_USEC_DELAY(usec) DELAY(usec)
+
+static __inline int qla_ms_to_hz(int ms)
+{
+ int qla_hz;
+
+ struct timeval t;
+
+ t.tv_sec = ms / 1000;
+ t.tv_usec = (ms % 1000) * 1000;
+
+ qla_hz = tvtohz(&t);
+
+ if (qla_hz < 0)
+ qla_hz = 0x7fffffff;
+ if (!qla_hz)
+ qla_hz = 1;
+
+ return (qla_hz);
+}
+
+static __inline int qla_sec_to_hz(int sec)
+{
+ struct timeval t;
+
+ t.tv_sec = sec;
+ t.tv_usec = 0;
+
+ return (tvtohz(&t));
+}
+
+
+#define qla_host_to_le16(x) htole16(x)
+#define qla_host_to_le32(x) htole32(x)
+#define qla_host_to_le64(x) htole64(x)
+#define qla_host_to_be16(x) htobe16(x)
+#define qla_host_to_be32(x) htobe32(x)
+#define qla_host_to_be64(x) htobe64(x)
+
+#define qla_le16_to_host(x) le16toh(x)
+#define qla_le32_to_host(x) le32toh(x)
+#define qla_le64_to_host(x) le64toh(x)
+#define qla_be16_to_host(x) be16toh(x)
+#define qla_be32_to_host(x) be32toh(x)
+#define qla_be64_to_host(x) be64toh(x)
+
+MALLOC_DECLARE(M_QLA83XXBUF);
+
+#define qla_mdelay(fn, msecs) \
+ {\
+ if (cold) \
+ DELAY((msecs * 1000)); \
+ else \
+ pause(fn, qla_ms_to_hz(msecs)); \
+ }
+
+/*
+ * Locks
+ */
+#define QLA_LOCK(ha, str, no_delay) qla_lock(ha, str, no_delay)
+#define QLA_UNLOCK(ha, str) qla_unlock(ha, str)
+
+#define QLA_TX_LOCK(ha) mtx_lock(&ha->tx_lock);
+#define QLA_TX_UNLOCK(ha) mtx_unlock(&ha->tx_lock);
+
+/*
+ * structure encapsulating a DMA buffer
+ */
+struct qla_dma {
+ bus_size_t alignment;
+ uint32_t size;
+ void *dma_b;
+ bus_addr_t dma_addr;
+ bus_dmamap_t dma_map;
+ bus_dma_tag_t dma_tag;
+};
+typedef struct qla_dma qla_dma_t;
+
+
+#endif /* #ifndef _QL_OS_H_ */
diff --git a/sys/dev/qlxgbe/ql_reset.c b/sys/dev/qlxgbe/ql_reset.c
new file mode 100644
index 000000000000..bf90e627a018
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_reset.c
@@ -0,0 +1,1409 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * File: ql_reset.c
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "ql_os.h"
+
+unsigned int ql83xx_resetseq_version_major = 5;
+unsigned int ql83xx_resetseq_version_minor = 2;
+unsigned int ql83xx_resetseq_version_sub = 6;
+
+unsigned char ql83xx_resetseq[] = {
+ 0x01, 0x01, 0xfe, 0xca, 0xf0, 0x05, 0x2f, 0x00, 0x10, 0x00, 0x74, 0x70,
+ 0x20, 0x02, 0xc8, 0x05, 0x01, 0x00, 0x18, 0x00, 0x02, 0x00, 0x64, 0x00,
+ 0xfc, 0x21, 0x60, 0x41, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x21, 0x60, 0x41,
+ 0xff, 0xff, 0xff, 0xff, 0x04, 0x00, 0x28, 0x00, 0x03, 0x00, 0x64, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x31, 0x77,
+ 0x44, 0xc0, 0x31, 0x77, 0x48, 0xc0, 0x31, 0x77, 0x4c, 0xc0, 0x31, 0x77,
+ 0x10, 0xc0, 0x31, 0x77, 0x14, 0xc0, 0x31, 0x77, 0x01, 0x00, 0x50, 0x00,
+ 0x09, 0x00, 0x64, 0x00, 0x60, 0x4e, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00,
+ 0x70, 0x4e, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4e, 0x08, 0x28,
+ 0x00, 0x00, 0x00, 0x00, 0x90, 0x4e, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00,
+ 0xa0, 0x4e, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x4e, 0x08, 0x28,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x4e, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00,
+ 0xd0, 0x4e, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4e, 0x08, 0x28,
+ 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x00, 0x06, 0x00, 0x64, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x06, 0x20, 0x0b,
+ 0x80, 0x06, 0x20, 0x0b, 0x80, 0x16, 0x20, 0x0b, 0x80, 0x16, 0x20, 0x0b,
+ 0xa0, 0x06, 0x20, 0x0b, 0xa0, 0x06, 0x20, 0x0b, 0xa0, 0x16, 0x20, 0x0b,
+ 0xa0, 0x16, 0x20, 0x0b, 0xa0, 0x08, 0x20, 0x0b, 0xa0, 0x08, 0x20, 0x0b,
+ 0xa0, 0x18, 0x20, 0x0b, 0xa0, 0x18, 0x20, 0x0b, 0x01, 0x00, 0x28, 0x00,
+ 0x04, 0x00, 0x64, 0x00, 0x00, 0x4d, 0x08, 0x28, 0x00, 0x0c, 0x00, 0x0c,
+ 0x40, 0x4d, 0x08, 0x28, 0x00, 0x0c, 0x00, 0x0c, 0x10, 0x4d, 0x08, 0x28,
+ 0x00, 0x0c, 0x00, 0x0c, 0x50, 0x4d, 0x08, 0x28, 0x00, 0x0c, 0x00, 0x0c,
+ 0x08, 0x00, 0x90, 0x00, 0x08, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x84, 0x06, 0x20, 0x0b, 0x24, 0x05, 0x03, 0x00,
+ 0x80, 0x06, 0x20, 0x0b, 0x0c, 0x01, 0x00, 0x00, 0x84, 0x06, 0x20, 0x0b,
+ 0x08, 0x0a, 0x00, 0x00, 0x80, 0x06, 0x20, 0x0b, 0x10, 0x01, 0x00, 0x00,
+ 0x84, 0x16, 0x20, 0x0b, 0x24, 0x05, 0x03, 0x00, 0x80, 0x16, 0x20, 0x0b,
+ 0x0c, 0x01, 0x00, 0x00, 0x84, 0x16, 0x20, 0x0b, 0x08, 0x0a, 0x00, 0x00,
+ 0x80, 0x16, 0x20, 0x0b, 0x10, 0x01, 0x00, 0x00, 0xa4, 0x06, 0x20, 0x0b,
+ 0x00, 0x00, 0x01, 0x00, 0xa0, 0x06, 0x20, 0x0b, 0x00, 0x01, 0x00, 0x00,
+ 0xa4, 0x16, 0x20, 0x0b, 0x00, 0x00, 0x01, 0x00, 0xa0, 0x16, 0x20, 0x0b,
+ 0x00, 0x01, 0x00, 0x00, 0xa4, 0x08, 0x20, 0x0b, 0x00, 0x00, 0x01, 0x00,
+ 0xa0, 0x08, 0x20, 0x0b, 0x00, 0x01, 0x00, 0x00, 0xa4, 0x18, 0x20, 0x0b,
+ 0x00, 0x00, 0x01, 0x00, 0xa0, 0x18, 0x20, 0x0b, 0x00, 0x01, 0x00, 0x00,
+ 0x01, 0x00, 0x48, 0x00, 0x08, 0x00, 0x64, 0x00, 0x00, 0x00, 0x70, 0x41,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x70, 0x41, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x70, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x70, 0x41,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x70, 0x41, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x70, 0x41, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x70, 0x41,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x70, 0x41, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x30, 0x00, 0x05, 0x00, 0x64, 0x00, 0x3c, 0x00, 0x00, 0x34,
+ 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x10, 0x34, 0x01, 0x00, 0x00, 0x00,
+ 0x3c, 0x00, 0x20, 0x34, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x30, 0x34,
+ 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xb0, 0x34, 0x01, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x64, 0x00, 0x40, 0x00, 0x08, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x05, 0x00, 0x64, 0x00,
+ 0x30, 0x20, 0x60, 0x41, 0x38, 0x20, 0x60, 0x41, 0x40, 0x20, 0x60, 0x41,
+ 0x48, 0x20, 0x60, 0x41, 0x50, 0x20, 0x60, 0x41, 0x58, 0x20, 0x60, 0x41,
+ 0x60, 0x20, 0x60, 0x41, 0x68, 0x20, 0x60, 0x41, 0x70, 0x20, 0x60, 0x41,
+ 0x78, 0x20, 0x60, 0x41, 0x01, 0x00, 0x50, 0x00, 0x09, 0x00, 0x64, 0x00,
+ 0x60, 0x4e, 0x08, 0x28, 0x03, 0x00, 0x00, 0x00, 0x70, 0x4e, 0x08, 0x28,
+ 0xff, 0x0f, 0x00, 0x00, 0x80, 0x4e, 0x08, 0x28, 0xff, 0x0f, 0x00, 0x00,
+ 0x90, 0x4e, 0x08, 0x28, 0x00, 0x0f, 0x00, 0x00, 0xa0, 0x4e, 0x08, 0x28,
+ 0x00, 0x0f, 0x00, 0x00, 0xb0, 0x4e, 0x08, 0x28, 0x0f, 0x00, 0x00, 0x00,
+ 0xc0, 0x4e, 0x08, 0x28, 0x0f, 0x00, 0x00, 0x00, 0xd0, 0x4e, 0x08, 0x28,
+ 0x03, 0x00, 0x00, 0x00, 0x50, 0x4e, 0x08, 0x28, 0x01, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x10, 0x00,
+ 0x01, 0x00, 0x64, 0x00, 0x08, 0x00, 0x10, 0x42, 0x00, 0x00, 0x00, 0x24,
+ 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x20, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0d,
+ 0x00, 0x10, 0x00, 0x0d, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x64, 0x00,
+ 0x01, 0x00, 0x10, 0x00, 0x01, 0x00, 0x64, 0x00, 0x08, 0x00, 0x10, 0x42,
+ 0xff, 0xff, 0x7f, 0xf6, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00,
+ 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x60, 0x00, 0x0d, 0x04, 0x60, 0x00, 0x0d, 0x10, 0x00, 0x20, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x0d,
+ 0x04, 0x10, 0x00, 0x0d, 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x00, 0x0d, 0x0c, 0x20, 0x00, 0x0d,
+ 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x30, 0x00, 0x0d, 0x04, 0x30, 0x00, 0x0d, 0x10, 0x00, 0x28, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40, 0x00, 0x0d,
+ 0x18, 0x40, 0x00, 0x0d, 0x04, 0x50, 0x00, 0x0d, 0x04, 0x50, 0x00, 0x0d,
+ 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x10, 0x00,
+ 0x01, 0x00, 0x64, 0x00, 0x08, 0x00, 0x10, 0x42, 0xff, 0xff, 0xff, 0xf6,
+ 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x10, 0x00,
+ 0x01, 0x00, 0x64, 0x00, 0x08, 0x00, 0x10, 0x42, 0xff, 0xff, 0x7f, 0xf6,
+ 0x10, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x50, 0x00, 0x0d, 0x04, 0x50, 0x00, 0x0d, 0x18, 0x40, 0x00, 0x0d,
+ 0x18, 0x40, 0x00, 0x0d, 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x00, 0x0d, 0x04, 0x30, 0x00, 0x0d,
+ 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xe0, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0c, 0x20, 0x00, 0x0d, 0x0c, 0x20, 0x00, 0x0d, 0x10, 0x00, 0x20, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x0d,
+ 0x04, 0x10, 0x00, 0x0d, 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x60, 0x00, 0x0d, 0x04, 0x60, 0x00, 0x0d,
+ 0x01, 0x00, 0x10, 0x00, 0x01, 0x00, 0x64, 0x00, 0x08, 0x00, 0x10, 0x42,
+ 0xff, 0xff, 0x0f, 0x24, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x64, 0x00,
+ 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0d, 0x20, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x10, 0x00, 0x01, 0x00, 0x64, 0x00,
+ 0x08, 0x00, 0x10, 0x42, 0xff, 0xff, 0x0f, 0x00, 0x01, 0x00, 0x50, 0x00,
+ 0x09, 0x00, 0x64, 0x00, 0x60, 0x4e, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00,
+ 0x70, 0x4e, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4e, 0x08, 0x28,
+ 0x00, 0x00, 0x00, 0x00, 0x90, 0x4e, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00,
+ 0xa0, 0x4e, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x4e, 0x08, 0x28,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x4e, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00,
+ 0xd0, 0x4e, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4e, 0x08, 0x28,
+ 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00,
+ 0x01, 0x00, 0x10, 0x00, 0x01, 0x00, 0x64, 0x00, 0x08, 0x00, 0x10, 0x42,
+ 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x00, 0x04, 0x00, 0x64, 0x00,
+ 0x08, 0x00, 0x10, 0x42, 0x1f, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x40, 0x34,
+ 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x50, 0x34, 0x08, 0x00, 0x00, 0x00,
+ 0x28, 0x04, 0x31, 0x77, 0x00, 0x60, 0x00, 0x00, 0x01, 0x00, 0x38, 0x00,
+ 0x06, 0x00, 0x64, 0x00, 0x18, 0x00, 0x00, 0x34, 0x00, 0x00, 0x7c, 0x00,
+ 0x18, 0x00, 0x10, 0x34, 0x20, 0x00, 0x00, 0x00, 0x18, 0x00, 0x20, 0x34,
+ 0x20, 0x00, 0x00, 0x00, 0x18, 0x00, 0x30, 0x34, 0x20, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0xb0, 0x34, 0x20, 0x00, 0x00, 0x00, 0x50, 0x22, 0x60, 0x41,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x28, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xc0, 0x31, 0x77,
+ 0x44, 0xc0, 0x31, 0x77, 0x4c, 0xc0, 0x31, 0x77, 0x4c, 0xc0, 0x31, 0x77,
+ 0x14, 0xc0, 0x31, 0x77, 0x14, 0xc0, 0x31, 0x77, 0x40, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x10, 0x42, 0x08, 0x00, 0x10, 0x42,
+ 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfe, 0xca,
+ 0xf0, 0x05, 0x2f, 0x00, 0x10, 0x00, 0x2c, 0xd3, 0x20, 0x02, 0xc8, 0x05,
+ 0x01, 0x00, 0x18, 0x00, 0x02, 0x00, 0x64, 0x00, 0xfc, 0x21, 0x10, 0x22,
+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x21, 0x10, 0x22, 0xff, 0xff, 0xff, 0xff,
+ 0x04, 0x00, 0x28, 0x00, 0x03, 0x00, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x11, 0x81, 0x44, 0xc0, 0x11, 0x81,
+ 0x48, 0xc0, 0x11, 0x81, 0x4c, 0xc0, 0x11, 0x81, 0x10, 0xc0, 0x11, 0x81,
+ 0x14, 0xc0, 0x11, 0x81, 0x01, 0x00, 0x50, 0x00, 0x09, 0x00, 0x64, 0x00,
+ 0x60, 0x4e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x70, 0x4e, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x4e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x90, 0x4e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x4e, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0xb0, 0x4e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x4e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x4e, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x50, 0x4e, 0x18, 0x18, 0x01, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x40, 0x00, 0x06, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x80, 0x06, 0x10, 0x97, 0x80, 0x06, 0x10, 0x97,
+ 0x80, 0x16, 0x10, 0x97, 0x80, 0x16, 0x10, 0x97, 0xa0, 0x06, 0x10, 0x97,
+ 0xa0, 0x06, 0x10, 0x97, 0xa0, 0x16, 0x10, 0x97, 0xa0, 0x16, 0x10, 0x97,
+ 0xa0, 0x08, 0x10, 0x97, 0xa0, 0x08, 0x10, 0x97, 0xa0, 0x18, 0x10, 0x97,
+ 0xa0, 0x18, 0x10, 0x97, 0x01, 0x00, 0x28, 0x00, 0x04, 0x00, 0x64, 0x00,
+ 0x00, 0x4d, 0x18, 0x18, 0x00, 0x0c, 0x00, 0x0c, 0x40, 0x4d, 0x18, 0x18,
+ 0x00, 0x0c, 0x00, 0x0c, 0x10, 0x4d, 0x18, 0x18, 0x00, 0x0c, 0x00, 0x0c,
+ 0x50, 0x4d, 0x18, 0x18, 0x00, 0x0c, 0x00, 0x0c, 0x08, 0x00, 0x90, 0x00,
+ 0x08, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
+ 0x84, 0x06, 0x10, 0x17, 0x24, 0x05, 0x03, 0x00, 0x80, 0x06, 0x10, 0x17,
+ 0x0c, 0x01, 0x00, 0x00, 0x84, 0x06, 0x10, 0x17, 0x08, 0x0a, 0x00, 0x00,
+ 0x80, 0x06, 0x10, 0x17, 0x10, 0x01, 0x00, 0x00, 0x84, 0x16, 0x10, 0x17,
+ 0x24, 0x05, 0x03, 0x00, 0x80, 0x16, 0x10, 0x17, 0x0c, 0x01, 0x00, 0x00,
+ 0x84, 0x16, 0x10, 0x17, 0x08, 0x0a, 0x00, 0x00, 0x80, 0x16, 0x10, 0x17,
+ 0x10, 0x01, 0x00, 0x00, 0xa4, 0x06, 0x10, 0x17, 0x00, 0x00, 0x01, 0x00,
+ 0xa0, 0x06, 0x10, 0x17, 0x00, 0x01, 0x00, 0x00, 0xa4, 0x16, 0x10, 0x17,
+ 0x00, 0x00, 0x01, 0x00, 0xa0, 0x16, 0x10, 0x17, 0x00, 0x01, 0x00, 0x00,
+ 0xa4, 0x08, 0x10, 0x17, 0x00, 0x00, 0x01, 0x00, 0xa0, 0x08, 0x10, 0x17,
+ 0x00, 0x01, 0x00, 0x00, 0xa4, 0x18, 0x10, 0x17, 0x00, 0x00, 0x01, 0x00,
+ 0xa0, 0x18, 0x10, 0x17, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x48, 0x00,
+ 0x08, 0x00, 0x64, 0x00, 0x00, 0x00, 0x10, 0x0d, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x10, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x10, 0x0d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x10, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x10, 0x0d, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x02, 0x10, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x30, 0x00,
+ 0x05, 0x00, 0x64, 0x00, 0x3c, 0x00, 0x10, 0x11, 0x01, 0x00, 0x00, 0x00,
+ 0x3c, 0x00, 0x10, 0x12, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x10, 0x13,
+ 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x10, 0x14, 0x01, 0x00, 0x00, 0x00,
+ 0x3c, 0x00, 0x10, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x64, 0x00, 0x40, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x30, 0x00, 0x05, 0x00, 0x64, 0x00, 0x30, 0x20, 0x10, 0x22,
+ 0x38, 0x20, 0x10, 0x22, 0x40, 0x20, 0x10, 0x22, 0x48, 0x20, 0x10, 0x22,
+ 0x50, 0x20, 0x10, 0x22, 0x58, 0x20, 0x10, 0x22, 0x60, 0x20, 0x10, 0x22,
+ 0x68, 0x20, 0x10, 0x22, 0x70, 0x20, 0x10, 0x22, 0x78, 0x20, 0x10, 0x22,
+ 0x01, 0x00, 0x50, 0x00, 0x09, 0x00, 0x64, 0x00, 0x60, 0x4e, 0x18, 0x18,
+ 0x03, 0x00, 0x00, 0x00, 0x70, 0x4e, 0x18, 0x18, 0xff, 0x0f, 0x00, 0x00,
+ 0x80, 0x4e, 0x18, 0x18, 0xff, 0x0f, 0x00, 0x00, 0x90, 0x4e, 0x18, 0x18,
+ 0x00, 0x0f, 0x00, 0x00, 0xa0, 0x4e, 0x18, 0x18, 0x00, 0x0f, 0x00, 0x00,
+ 0xb0, 0x4e, 0x18, 0x18, 0x0f, 0x00, 0x00, 0x00, 0xc0, 0x4e, 0x18, 0x18,
+ 0x0f, 0x00, 0x00, 0x00, 0xd0, 0x4e, 0x18, 0x18, 0x03, 0x00, 0x00, 0x00,
+ 0x50, 0x4e, 0x18, 0x18, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x10, 0x00, 0x01, 0x00, 0x64, 0x00,
+ 0x08, 0x00, 0x10, 0x33, 0x00, 0x00, 0x00, 0x24, 0x20, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x85, 0x00, 0x10, 0x10, 0x05,
+ 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x10, 0x00,
+ 0x01, 0x00, 0x64, 0x00, 0x08, 0x00, 0x10, 0x33, 0xff, 0xff, 0x7f, 0xf6,
+ 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x20, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x60, 0x10, 0x85,
+ 0x04, 0x60, 0x10, 0x05, 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x10, 0x85, 0x04, 0x10, 0x10, 0x05,
+ 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0c, 0x20, 0x10, 0x85, 0x0c, 0x20, 0x10, 0x05, 0x10, 0x00, 0x20, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x10, 0x85,
+ 0x04, 0x30, 0x10, 0x05, 0x10, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x40, 0x10, 0x85, 0x18, 0x40, 0x10, 0x05,
+ 0x04, 0x50, 0x10, 0x85, 0x04, 0x50, 0x10, 0x05, 0x20, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x10, 0x00, 0x01, 0x00, 0x64, 0x00,
+ 0x08, 0x00, 0x10, 0x33, 0xff, 0xff, 0xff, 0xf6, 0x20, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x10, 0x00, 0x01, 0x00, 0x64, 0x00,
+ 0x08, 0x00, 0x10, 0x33, 0xff, 0xff, 0x7f, 0xf6, 0x10, 0x00, 0x28, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x50, 0x10, 0x85,
+ 0x04, 0x50, 0x10, 0x05, 0x18, 0x40, 0x10, 0x85, 0x18, 0x40, 0x10, 0x05,
+ 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x30, 0x10, 0x85, 0x04, 0x30, 0x10, 0x05, 0x10, 0x00, 0x20, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0xff, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x10, 0x85,
+ 0x0c, 0x20, 0x10, 0x05, 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x10, 0x85, 0x04, 0x10, 0x10, 0x05,
+ 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf8,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x60, 0x10, 0x85, 0x04, 0x60, 0x10, 0x05, 0x01, 0x00, 0x10, 0x00,
+ 0x01, 0x00, 0x64, 0x00, 0x08, 0x00, 0x10, 0x33, 0xff, 0xff, 0x0f, 0x24,
+ 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x64, 0x00, 0x10, 0x00, 0x20, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x85,
+ 0x00, 0x10, 0x10, 0x05, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00,
+ 0x01, 0x00, 0x10, 0x00, 0x01, 0x00, 0x64, 0x00, 0x08, 0x00, 0x10, 0x33,
+ 0xff, 0xff, 0x0f, 0x00, 0x01, 0x00, 0x50, 0x00, 0x09, 0x00, 0x64, 0x00,
+ 0x60, 0x4e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x70, 0x4e, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x4e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x90, 0x4e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x4e, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0xb0, 0x4e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x4e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x4e, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x50, 0x4e, 0x18, 0x18, 0x01, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x10, 0x00,
+ 0x01, 0x00, 0x64, 0x00, 0x08, 0x00, 0x10, 0x33, 0xff, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x28, 0x00, 0x04, 0x00, 0x64, 0x00, 0x08, 0x00, 0x10, 0x33,
+ 0x1f, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x10, 0x16, 0x08, 0x00, 0x00, 0x00,
+ 0x4c, 0x00, 0x10, 0x15, 0x08, 0x00, 0x00, 0x00, 0x28, 0x04, 0x11, 0x01,
+ 0x00, 0x60, 0x00, 0x00, 0x01, 0x00, 0x38, 0x00, 0x06, 0x00, 0x64, 0x00,
+ 0x18, 0x00, 0x10, 0x11, 0x00, 0x00, 0x7c, 0x00, 0x18, 0x00, 0x10, 0x12,
+ 0x20, 0x00, 0x00, 0x00, 0x18, 0x00, 0x10, 0x13, 0x20, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0x10, 0x14, 0x20, 0x00, 0x00, 0x00, 0x18, 0x00, 0x10, 0x0f,
+ 0x20, 0x00, 0x00, 0x00, 0x50, 0x22, 0x10, 0x22, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x28, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x44, 0xc0, 0x11, 0x81, 0x44, 0xc0, 0x11, 0x81,
+ 0x4c, 0xc0, 0x11, 0x81, 0x4c, 0xc0, 0x11, 0x81, 0x14, 0xc0, 0x11, 0x81,
+ 0x14, 0xc0, 0x11, 0x81, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x10, 0xb3, 0x08, 0x00, 0x10, 0x33, 0x80, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x00, 0x40, 0x40,
+ 0x05, 0x02, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xdf, 0xfc, 0xcc, 0x87
+};
+unsigned int ql83xx_resetseq_len = 16384;
diff --git a/sys/dev/qlxgbe/ql_tmplt.h b/sys/dev/qlxgbe/ql_tmplt.h
new file mode 100644
index 000000000000..703d85e6520b
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_tmplt.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/*
+ * File: ql_tmplt.h
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ */
+#ifndef _QL_TMPLT_H_
+#define _QL_TMPLT_H_
+
+
+typedef struct _q8_tmplt_hdr {
+ uint16_t version;
+ uint16_t signature;
+ uint16_t size;
+ uint16_t nentries;
+ uint16_t stop_seq_off;
+ uint16_t csum;
+ uint16_t init_seq_off;
+ uint16_t start_seq_off;
+} __packed q8_tmplt_hdr_t;
+
+
+typedef struct _q8_ce_hdr {
+ uint16_t opcode;
+ uint16_t size;
+ uint16_t opcount;
+ uint16_t delay_to;
+} __packed q8_ce_hdr_t;
+
+/*
+ * Values for opcode field in q8_ce_hdr_t
+ */
+#define Q8_CE_OPCODE_NOP 0x000
+#define Q8_CE_OPCODE_WRITE_LIST 0x001
+#define Q8_CE_OPCODE_READ_WRITE_LIST 0x002
+#define Q8_CE_OPCODE_POLL_LIST 0x004
+#define Q8_CE_OPCODE_POLL_WRITE_LIST 0x008
+#define Q8_CE_OPCODE_READ_MODIFY_WRITE 0x010
+#define Q8_CE_OPCODE_SEQ_PAUSE 0x020
+#define Q8_CE_OPCODE_SEQ_END 0x040
+#define Q8_CE_OPCODE_TMPLT_END 0x080
+#define Q8_CE_OPCODE_POLL_RD_LIST 0x100
+
+/*
+ * structure for Q8_CE_OPCODE_WRITE_LIST
+ */
+typedef struct _q8_wrl_e {
+ uint32_t addr;
+ uint32_t value;
+} __packed q8_wrl_e_t;
+
+/*
+ * structure for Q8_CE_OPCODE_READ_WRITE_LIST
+ */
+typedef struct _q8_rdwrl_e {
+ uint32_t rd_addr;
+ uint32_t wr_addr;
+} __packed q8_rdwrl_e_t;
+
+/*
+ * common for
+ * Q8_CE_OPCODE_POLL_LIST
+ * Q8_CE_OPCODE_POLL_WRITE_LIST
+ * Q8_CE_OPCODE_POLL_RD_LIST
+ */
+typedef struct _q8_poll_hdr {
+ uint32_t tmask;
+ uint32_t tvalue;
+} q8_poll_hdr_t;
+
+/*
+ * structure for Q8_CE_OPCODE_POLL_LIST
+ */
+typedef struct _q8_poll_e {
+ uint32_t addr;
+ uint32_t to_addr;
+} q8_poll_e_t;
+
+/*
+ * structure for Q8_CE_OPCODE_POLL_WRITE_LIST
+ */
+typedef struct _q8_poll_wr_e {
+ uint32_t dr_addr;
+ uint32_t dr_value;
+ uint32_t ar_addr;
+ uint32_t ar_value;
+} q8_poll_wr_e_t;
+
+/*
+ * structure for Q8_CE_OPCODE_POLL_RD_LIST
+ */
+typedef struct _q8_poll_rd_e {
+ uint32_t ar_addr;
+ uint32_t ar_value;
+ uint32_t dr_addr;
+ uint32_t rsrvd;
+} q8_poll_rd_e_t;
+
+/*
+ * structure for Q8_CE_OPCODE_READ_MODIFY_WRITE
+ */
+typedef struct _q8_rdmwr_hdr {
+ uint32_t and_value;
+ uint32_t xor_value;
+ uint32_t or_value;
+ uint8_t shl;
+ uint8_t shr;
+ uint8_t index_a;
+ uint8_t rsrvd;
+} q8_rdmwr_hdr_t;
+
+typedef struct _q8_rdmwr_e {
+ uint32_t rd_addr;
+ uint32_t wr_addr;
+} q8_rdmwr_e_t;
+
+extern unsigned char ql83xx_resetseq[];
+extern unsigned int ql83xx_resetseq_len;
+
+
+#endif /* #ifndef _QL_TMPLT_H_ */
diff --git a/sys/dev/qlxgbe/ql_ver.h b/sys/dev/qlxgbe/ql_ver.h
new file mode 100644
index 000000000000..ab7d49f7e09e
--- /dev/null
+++ b/sys/dev/qlxgbe/ql_ver.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013-2014 Qlogic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/*
+ * File: ql_ver.h
+ * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+ */
+
+#ifndef _QL_VER_H_
+#define _QL_VER_H_
+
+#define QLA_VERSION_MAJOR 3
+#define QLA_VERSION_MINOR 10
+#define QLA_VERSION_BUILD 10
+
+#endif /* #ifndef _QL_VER_H_ */
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index c2dc799f65e5..e68d9fa1c2aa 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -271,6 +271,7 @@ SUBDIR= \
pty \
puc \
${_qlxgb} \
+ ${_qlxgbe} \
ral \
${_ralfw} \
${_random} \
@@ -710,6 +711,7 @@ _padlock= padlock
.endif
_pccard= pccard
_qlxgb= qlxgb
+_qlxgbe= qlxgbe
_rdma= rdma
_s3= s3
_safe= safe
diff --git a/sys/modules/qlxgbe/Makefile b/sys/modules/qlxgbe/Makefile
new file mode 100644
index 000000000000..2cf7d9d61142
--- /dev/null
+++ b/sys/modules/qlxgbe/Makefile
@@ -0,0 +1,50 @@
+#/*
+# * Copyright (c) 2011-2012 Qlogic Corporation
+# * All rights reserved.
+# *
+# * Redistribution and use in source and binary forms, with or without
+# * modification, are permitted provided that the following conditions
+# * are met:
+# *
+# * 1. Redistributions of source code must retain the above copyright
+# * notice, this list of conditions and the following disclaimer.
+# * 2. Redistributions in binary form must reproduce the above copyright
+# * notice, this list of conditions and the following disclaimer in the
+# * documentation and/or other materials provided with the distribution.
+# *
+# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# * POSSIBILITY OF SUCH DAMAGE.
+# */
+#/*
+# * File : Makefile
+# * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
+# */
+#
+# $FreeBSD$
+#
+
+.PATH: ${.CURDIR}/../../dev/qlxgbe
+
+KMOD=if_qlxgbe
+SRCS=ql_os.c ql_dbg.c ql_hw.c ql_misc.c ql_isr.c ql_ioctl.c
+SRCS+= ql_reset.c
+SRCS+= device_if.h bus_if.h pci_if.h
+
+#CFLAGS += -DQL_DBG
+
+clean:
+ rm -f opt_bdg.h device_if.h bus_if.h pci_if.h export_syms
+ rm -f *.o *.kld *.ko
+ rm -f @ machine x86
+
+.include <bsd.kmod.mk>
+