[Zrouter-src-freebsd] ZRouter.org: push to FreeBSD HEAD tree
zrouter-src-freebsd at zrouter.org
zrouter-src-freebsd at zrouter.org
Fri Mar 2 15:40:29 UTC 2012
details: http://zrouter.org/hg/FreeBSD/head//rev/e8744e5a2f8e
changeset: 413:e8744e5a2f8e
user: ray at terran.dlink.ua
date: Fri Mar 02 17:36:33 2012 +0200
description:
Update to FreeBSD-HEAD @232391
diffstat:
head/sys/dev/aac/aac.c | 11 +-
head/sys/dev/aac/aac_pci.c | 2 +-
head/sys/dev/acpi_support/atk0110.c | 4 +-
head/sys/dev/acpica/Osd/OsdMemory.c | 12 +-
head/sys/dev/acpica/Osd/OsdSchedule.c | 8 +-
head/sys/dev/acpica/Osd/OsdSynch.c | 16 +-
head/sys/dev/acpica/Osd/OsdTable.c | 10 +-
head/sys/dev/acpica/acpi.c | 63 +-
head/sys/dev/acpica/acpi_ec.c | 4 +-
head/sys/dev/acpica/acpi_hpet.c | 4 +-
head/sys/dev/acpica/acpi_timer.c | 59 +-
head/sys/dev/acpica/acpivar.h | 5 +-
head/sys/dev/ahci/ahci.c | 10 +-
head/sys/dev/amdtemp/amdtemp.c | 257 +-
head/sys/dev/amr/amr_pci.c | 6 +-
head/sys/dev/arcmsr/arcmsr.c | 4 +-
head/sys/dev/ata/ata-pci.h | 14 +-
head/sys/dev/ata/ata-queue.c | 3 +-
head/sys/dev/ata/chipsets/ata-ahci.c | 10 +-
head/sys/dev/ata/chipsets/ata-marvell.c | 14 +-
head/sys/dev/ath/ath_dfs/null/dfs_null.c | 59 +-
head/sys/dev/ath/ath_hal/ah.h | 5 +-
head/sys/dev/ath/ath_hal/ar5416/ar5416.h | 6 +-
head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c | 4 +-
head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c | 373 +--
head/sys/dev/ath/ath_hal/ar5416/ar5416_radar.c | 387 ++
head/sys/dev/ath/ath_rate/sample/sample.c | 26 +-
head/sys/dev/ath/ath_rate/sample/sample.h | 4 +-
head/sys/dev/ath/if_ath.c | 156 +-
head/sys/dev/ath/if_ath_sysctl.c | 4 +-
head/sys/dev/ath/if_athvar.h | 7 +-
head/sys/dev/bge/if_bge.c | 6 +-
head/sys/dev/cxgb/cxgb_adapter.h | 3 +-
head/sys/dev/cxgb/cxgb_main.c | 45 +-
head/sys/dev/cxgb/cxgb_sge.c | 59 +-
head/sys/dev/cxgbe/adapter.h | 13 +-
head/sys/dev/cxgbe/common/t4_hw.c | 4 +-
head/sys/dev/cxgbe/t4_l2t.c | 11 +-
head/sys/dev/cxgbe/t4_l2t.h | 4 +-
head/sys/dev/cxgbe/t4_main.c | 104 +-
head/sys/dev/dpt/dpt_scsi.c | 3 +-
head/sys/dev/e1000/if_em.c | 16 +-
head/sys/dev/e1000/if_igb.c | 28 +-
head/sys/dev/e1000/if_lem.c | 18 +-
head/sys/dev/fb/vesa.c | 52 +-
head/sys/dev/fb/vesa.h | 4 +-
head/sys/dev/flash/mx25l.c | 37 +-
head/sys/dev/gpio/gpiobus.c | 14 +-
head/sys/dev/gpio/gpiobusvar.h | 2 +-
head/sys/dev/hwpmc/hwpmc_core.c | 501 ++-
head/sys/dev/hwpmc/hwpmc_intel.c | 11 +-
head/sys/dev/hwpmc/hwpmc_uncore.c | 109 +-
head/sys/dev/hwpmc/hwpmc_uncore.h | 4 +-
head/sys/dev/hwpmc/pmc_events.h | 308 ++-
head/sys/dev/iicbus/iicbb.c | 20 +-
head/sys/dev/iicbus/iicbb_if.m | 41 +-
head/sys/dev/iscsi/initiator/isc_sm.c | 6 +-
head/sys/dev/isp/isp_freebsd.h | 4 +-
head/sys/dev/ixgbe/ixgbe.c | 19 +-
head/sys/dev/mii/brgphy.c | 9 +-
head/sys/dev/mii/miidevs | 7 +-
head/sys/dev/mii/nsphyter.c | 8 +-
head/sys/dev/mii/rgephy.c | 20 +-
head/sys/dev/mii/smcphy.c | 66 +-
head/sys/dev/mlx/mlx.c | 5 +-
head/sys/dev/mps/mps.c | 10 +-
head/sys/dev/mps/mps_pci.c | 4 +-
head/sys/dev/mps/mps_sas.c | 376 ++-
head/sys/dev/mps/mps_sas.h | 5 +-
head/sys/dev/mps/mps_sas_lsi.c | 96 +-
head/sys/dev/mps/mps_user.c | 16 +-
head/sys/dev/mps/mpsvar.h | 17 +-
head/sys/dev/mpt/mpilib/mpi_type.h | 4 +-
head/sys/dev/mpt/mpt.c | 20 +-
head/sys/dev/mpt/mpt.h | 21 +-
head/sys/dev/mpt/mpt_cam.c | 75 +-
head/sys/dev/mpt/mpt_pci.c | 30 +-
head/sys/dev/mpt/mpt_reg.h | 3 +-
head/sys/dev/mvs/mvs.h | 5 +-
head/sys/dev/mvs/mvs_soc.c | 25 +-
head/sys/dev/netmap/if_em_netmap.h | 211 +-
head/sys/dev/netmap/if_igb_netmap.h | 232 +-
head/sys/dev/netmap/if_lem_netmap.h | 228 +-
head/sys/dev/netmap/if_re_netmap.h | 192 +-
head/sys/dev/netmap/ixgbe_netmap.h | 255 +-
head/sys/dev/netmap/netmap.c | 1237 ++++---
head/sys/dev/netmap/netmap_kern.h | 118 +-
head/sys/dev/oce/oce_hw.c | 595 +++
head/sys/dev/oce/oce_hw.h | 3464 ++++++++++++++++++++++
head/sys/dev/oce/oce_if.c | 2024 +++++++++++++
head/sys/dev/oce/oce_if.h | 1078 +++++++
head/sys/dev/oce/oce_mbox.c | 1739 +++++++++++
head/sys/dev/oce/oce_queue.c | 1212 +++++++
head/sys/dev/oce/oce_sysctl.c | 1305 ++++++++
head/sys/dev/oce/oce_util.c | 268 +
head/sys/dev/pci/pci.c | 68 +-
head/sys/dev/pci/pcivar.h | 4 +-
head/sys/dev/pcn/if_pcn.c | 4 +-
head/sys/dev/ral/if_ral_pci.c | 13 +-
head/sys/dev/re/if_re.c | 109 +-
head/sys/dev/rt2860/rt2860.c | 106 +-
head/sys/dev/sdhci/sdhci.c | 27 +-
head/sys/dev/sdhci/sdhci.h | 11 +-
head/sys/dev/sf/if_sf.c | 106 +-
head/sys/dev/sf/if_sfreg.h | 5 +-
head/sys/dev/siba/siba_cc.c | 25 +-
head/sys/dev/siba/siba_cc.h | 4 +
head/sys/dev/siba/siba_cc_uart.c | 15 +-
head/sys/dev/siba/siba_core.c | 4 +-
head/sys/dev/sound/pci/cs461x_dsp.h | 3497 +++++++++++++++++++++++
head/sys/dev/sound/pci/csa.c | 57 +-
head/sys/dev/sound/pci/csareg.h | 23 +-
head/sys/dev/sound/pci/hda/hdacc.c | 4 +-
head/sys/dev/sound/pci/hdspe-pcm.c | 709 ++++
head/sys/dev/sound/pci/hdspe.c | 410 ++
head/sys/dev/sound/pci/hdspe.h | 179 +
head/sys/dev/sound/pcm/mixer.c | 4 +-
head/sys/dev/sound/pcm/sound.c | 5 +-
head/sys/dev/sound/usb/uaudio.c | 36 +-
head/sys/dev/uart/uart_bus_siba.c | 21 +-
head/sys/dev/uart/uart_cpu_siba.c | 2 +-
head/sys/dev/uart/uart_dev_siba.c | 9 +-
head/sys/dev/usb/net/if_mos.c | 7 +-
head/sys/dev/usb/net/if_mosreg.h | 3 +-
head/sys/dev/usb/serial/u3g.c | 3 +-
head/sys/dev/usb/storage/umass.c | 127 +-
head/sys/dev/usb/usb_dev.c | 4 +-
head/sys/dev/usb/usbdevs | 4 +-
head/sys/dev/vge/if_vge.c | 4 +-
head/sys/dev/wi/if_wi.c | 7 +-
head/sys/dev/wtap/if_wtap.c | 6 +-
head/sys/dev/wtap/if_wtap_module.c | 3 +-
head/sys/dev/xen/blkback/blkback.c | 209 +-
head/sys/dev/xen/blkfront/blkfront.c | 171 +-
head/sys/dev/xen/blkfront/block.h | 42 +-
head/sys/dev/xen/netback/netback.c | 4 +-
136 files changed, 21221 insertions(+), 2803 deletions(-)
diffs (31230 lines):
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/aac/aac.c
--- a/head/sys/dev/aac/aac.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/aac/aac.c Fri Mar 02 17:36:33 2012 +0200
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/aac/aac.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/dev/aac/aac.c 231589 2012-02-13 16:48:49Z emaste $");
/*
* Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
@@ -292,6 +292,15 @@
aac_describe_controller(sc);
/*
+ * Add sysctls.
+ */
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->aac_dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(sc->aac_dev)),
+ OID_AUTO, "firmware_build", CTLFLAG_RD,
+ &sc->aac_revision.buildNumber, 0,
+ "firmware build number");
+
+ /*
* Register to probe our containers later.
*/
sc->aac_ich.ich_func = aac_startup;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/aac/aac_pci.c
--- a/head/sys/dev/aac/aac_pci.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/aac/aac_pci.c Fri Mar 02 17:36:33 2012 +0200
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/aac/aac_pci.c 227843 2011-11-22 21:28:20Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/aac/aac_pci.c 232268 2012-02-28 19:50:14Z emaste $");
/*
* PCI bus interface and resource allocation.
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/acpi_support/atk0110.c
--- a/head/sys/dev/acpi_support/atk0110.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/acpi_support/atk0110.c Fri Mar 02 17:36:33 2012 +0200
@@ -18,7 +18,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/acpi_support/atk0110.c 232256 2012-02-28 15:12:26Z kevlo $");
#include <machine/_inttypes.h>
#include <sys/param.h>
@@ -97,7 +97,7 @@
static devclass_t aibs_devclass;
DRIVER_MODULE(aibs, acpi, aibs_driver, aibs_devclass, NULL, NULL);
-
+MODULE_DEPEND(aibs, acpi, 1, 1, 1);
static char* aibs_hids[] = {
"ATK0110",
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/acpica/Osd/OsdMemory.c
--- a/head/sys/dev/acpica/Osd/OsdMemory.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/acpica/Osd/OsdMemory.c Fri Mar 02 17:36:33 2012 +0200
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/acpica/Osd/OsdMemory.c 227293 2011-11-07 06:44:47Z ed $");
+__FBSDID("$FreeBSD: head/sys/dev/acpica/Osd/OsdMemory.c 231844 2012-02-16 22:59:29Z jkim $");
#include <contrib/dev/acpica/include/acpi.h>
@@ -87,7 +87,7 @@
}
ACPI_STATUS
-AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT32 *Value, UINT32 Width)
+AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 *Value, UINT32 Width)
{
void *LogicalAddress;
@@ -105,6 +105,9 @@
case 32:
*Value = *(volatile uint32_t *)LogicalAddress;
break;
+ case 64:
+ *Value = *(volatile uint64_t *)LogicalAddress;
+ break;
}
pmap_unmapdev((vm_offset_t)LogicalAddress, Width / 8);
@@ -113,7 +116,7 @@
}
ACPI_STATUS
-AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT32 Value, UINT32 Width)
+AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT32 Width)
{
void *LogicalAddress;
@@ -131,6 +134,9 @@
case 32:
*(volatile uint32_t *)LogicalAddress = Value;
break;
+ case 64:
+ *(volatile uint64_t *)LogicalAddress = Value;
+ break;
}
pmap_unmapdev((vm_offset_t)LogicalAddress, Width / 8);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/acpica/Osd/OsdSchedule.c
--- a/head/sys/dev/acpica/Osd/OsdSchedule.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/acpica/Osd/OsdSchedule.c Fri Mar 02 17:36:33 2012 +0200
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 2000 Michael Smith
* Copyright (c) 2000 BSDi
- * Copyright (c) 2007-2009 Jung-uk Kim <jkim at FreeBSD.org>
+ * Copyright (c) 2007-2012 Jung-uk Kim <jkim at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/acpica/Osd/OsdSchedule.c 227293 2011-11-07 06:44:47Z ed $");
+__FBSDID("$FreeBSD: head/sys/dev/acpica/Osd/OsdSchedule.c 232132 2012-02-24 23:15:21Z jkim $");
#include "opt_acpi.h"
#include <sys/param.h>
@@ -248,8 +248,8 @@
KASSERT(cold == 0, ("acpi: timer op not yet supported during boot"));
binuptime(&bt);
- t = ((UINT64)10000000 * (uint32_t)(bt.frac >> 32)) >> 32;
- t += bt.sec * 10000000;
+ t = (uint64_t)bt.sec * 10000000;
+ t += ((uint64_t)10000000 * (uint32_t)(bt.frac >> 32)) >> 32;
return (t);
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/acpica/Osd/OsdSynch.c
--- a/head/sys/dev/acpica/Osd/OsdSynch.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/acpica/Osd/OsdSynch.c Fri Mar 02 17:36:33 2012 +0200
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/acpica/Osd/OsdSynch.c 227293 2011-11-07 06:44:47Z ed $");
+__FBSDID("$FreeBSD: head/sys/dev/acpica/Osd/OsdSynch.c 231474 2012-02-10 23:30:29Z jkim $");
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
@@ -566,11 +566,8 @@
}
/* Section 5.2.10.1: global lock acquire/release functions */
-#define GL_ACQUIRED (-1)
-#define GL_BUSY 0
#define GL_BIT_PENDING 0x01
#define GL_BIT_OWNED 0x02
-#define GL_BIT_MASK (GL_BIT_PENDING | GL_BIT_OWNED)
/*
* Acquire the global lock. If busy, set the pending bit. The caller
@@ -584,11 +581,12 @@
do {
old = *lock;
- new = ((old & ~GL_BIT_MASK) | GL_BIT_OWNED) |
- ((old >> 1) & GL_BIT_PENDING);
+ new = (old & ~GL_BIT_PENDING) | GL_BIT_OWNED;
+ if ((old & GL_BIT_OWNED) != 0)
+ new |= GL_BIT_PENDING;
} while (atomic_cmpset_acq_int(lock, old, new) == 0);
- return ((new < GL_BIT_MASK) ? GL_ACQUIRED : GL_BUSY);
+ return ((new & GL_BIT_PENDING) == 0);
}
/*
@@ -603,8 +601,8 @@
do {
old = *lock;
- new = old & ~GL_BIT_MASK;
+ new = old & ~(GL_BIT_PENDING | GL_BIT_OWNED);
} while (atomic_cmpset_rel_int(lock, old, new) == 0);
- return (old & GL_BIT_PENDING);
+ return ((old & GL_BIT_PENDING) != 0);
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/acpica/Osd/OsdTable.c
--- a/head/sys/dev/acpica/Osd/OsdTable.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/acpica/Osd/OsdTable.c Fri Mar 02 17:36:33 2012 +0200
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/acpica/Osd/OsdTable.c 231844 2012-02-16 22:59:29Z jkim $");
#include <sys/param.h>
#include <sys/endian.h>
@@ -96,3 +96,11 @@
return (AE_OK);
}
+
+ACPI_STATUS
+AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER *ExistingTable,
+ ACPI_PHYSICAL_ADDRESS *NewAddress, UINT32 *NewTableLength)
+{
+
+ return (AE_SUPPORT);
+}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/acpica/acpi.c
--- a/head/sys/dev/acpica/acpi.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/acpica/acpi.c Fri Mar 02 17:36:33 2012 +0200
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi.c 227293 2011-11-07 06:44:47Z ed $");
+__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi.c 231844 2012-02-16 22:59:29Z jkim $");
#include "opt_acpi.h"
#include <sys/param.h>
@@ -152,6 +152,7 @@
static void acpi_shutdown_final(void *arg, int howto);
static void acpi_enable_fixed_events(struct acpi_softc *sc);
static BOOLEAN acpi_has_hid(ACPI_HANDLE handle);
+static void acpi_resync_clock(struct acpi_softc *sc);
static int acpi_wake_sleep_prep(ACPI_HANDLE handle, int sstate);
static int acpi_wake_run_prep(ACPI_HANDLE handle, int sstate);
static int acpi_wake_prep_walk(int sstate);
@@ -277,11 +278,13 @@
SYSCTL_INT(_debug_acpi, OID_AUTO, interpreter_slack, CTLFLAG_RDTUN,
&acpi_interpreter_slack, 1, "Turn on interpreter slack mode.");
+#ifdef __amd64__
/* Reset system clock while resuming. XXX Remove once tested. */
static int acpi_reset_clock = 1;
TUNABLE_INT("debug.acpi.reset_clock", &acpi_reset_clock);
SYSCTL_INT(_debug_acpi, OID_AUTO, reset_clock, CTLFLAG_RW,
&acpi_reset_clock, 1, "Reset system clock while resuming.");
+#endif
/* Allow users to override quirks. */
TUNABLE_INT("debug.acpi.quirks", &acpi_quirks);
@@ -1812,23 +1815,29 @@
static void
acpi_probe_order(ACPI_HANDLE handle, int *order)
{
- ACPI_OBJECT_TYPE type;
-
- /*
- * 1. CPUs
- * 2. I/O port and memory system resource holders
- * 3. Embedded controllers (to handle early accesses)
- * 4. PCI Link Devices
- */
- AcpiGetType(handle, &type);
- if (type == ACPI_TYPE_PROCESSOR)
- *order = 1;
- else if (acpi_MatchHid(handle, "PNP0C01") || acpi_MatchHid(handle, "PNP0C02"))
- *order = 2;
- else if (acpi_MatchHid(handle, "PNP0C09"))
- *order = 3;
- else if (acpi_MatchHid(handle, "PNP0C0F"))
- *order = 4;
+ ACPI_OBJECT_TYPE type;
+
+ /*
+ * 0. CPUs
+ * 1. I/O port and memory system resource holders
+ * 2. Clocks and timers (to handle early accesses)
+ * 3. Embedded controllers (to handle early accesses)
+ * 4. PCI Link Devices
+ */
+ AcpiGetType(handle, &type);
+ if (type == ACPI_TYPE_PROCESSOR)
+ *order = 0;
+ else if (acpi_MatchHid(handle, "PNP0C01") ||
+ acpi_MatchHid(handle, "PNP0C02"))
+ *order = 1;
+ else if (acpi_MatchHid(handle, "PNP0100") ||
+ acpi_MatchHid(handle, "PNP0103") ||
+ acpi_MatchHid(handle, "PNP0B00"))
+ *order = 2;
+ else if (acpi_MatchHid(handle, "PNP0C09"))
+ *order = 3;
+ else if (acpi_MatchHid(handle, "PNP0C0F"))
+ *order = 4;
}
/*
@@ -1889,7 +1898,7 @@
* resources).
*/
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "scanning '%s'\n", handle_str));
- order = level * 10 + 100;
+ order = level * 10 + ACPI_DEV_BASE_ORDER;
acpi_probe_order(handle, &order);
child = BUS_ADD_CHILD(bus, order, NULL, -1);
if (child == NULL)
@@ -2706,7 +2715,8 @@
DELAY(sc->acpi_sleep_delay * 1000000);
if (state != ACPI_STATE_S1) {
- acpi_sleep_machdep(sc, state);
+ if (acpi_sleep_machdep(sc, state))
+ goto backout;
/* Re-enable ACPI hardware on wakeup from sleep state 4. */
if (state == ACPI_STATE_S4)
@@ -2731,12 +2741,16 @@
acpi_wake_prep_walk(state);
sc->acpi_sstate = ACPI_STATE_S0;
}
- if (slp_state >= ACPI_SS_SLP_PREP)
+ if (slp_state >= ACPI_SS_SLP_PREP) {
+ AcpiLeaveSleepStatePrep(state);
AcpiLeaveSleepState(state);
+ }
if (slp_state >= ACPI_SS_DEV_SUSPEND)
DEVICE_RESUME(root_bus);
- if (slp_state >= ACPI_SS_SLEPT)
+ if (slp_state >= ACPI_SS_SLEPT) {
+ acpi_resync_clock(sc);
acpi_enable_fixed_events(sc);
+ }
sc->acpi_next_sstate = 0;
mtx_unlock(&Giant);
@@ -2759,10 +2773,10 @@
return_ACPI_STATUS (status);
}
-void
+static void
acpi_resync_clock(struct acpi_softc *sc)
{
-
+#ifdef __amd64__
if (!acpi_reset_clock)
return;
@@ -2772,6 +2786,7 @@
(void)timecounter->tc_get_timecount(timecounter);
(void)timecounter->tc_get_timecount(timecounter);
inittodr(time_second + sc->acpi_sleep_delay);
+#endif
}
/* Enable or disable the device's wake GPE. */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/acpica/acpi_ec.c
--- a/head/sys/dev/acpica/acpi_ec.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/acpica/acpi_ec.c Fri Mar 02 17:36:33 2012 +0200
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi_ec.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi_ec.c 231161 2012-02-07 20:54:44Z jkim $");
#include "opt_acpi.h"
#include <sys/param.h>
@@ -295,7 +295,7 @@
}
/* Create the child device with the given unit number. */
- child = BUS_ADD_CHILD(parent, 0, "acpi_ec", ecdt->Uid);
+ child = BUS_ADD_CHILD(parent, 3, "acpi_ec", ecdt->Uid);
if (child == NULL) {
printf("%s: can't add child\n", __func__);
return;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/acpica/acpi_hpet.c
--- a/head/sys/dev/acpica/acpi_hpet.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/acpica/acpi_hpet.c Fri Mar 02 17:36:33 2012 +0200
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi_hpet.c 224919 2011-08-16 21:51:29Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi_hpet.c 231161 2012-02-07 20:54:44Z jkim $");
#include "opt_acpi.h"
#if defined(__amd64__) || defined(__ia64__)
@@ -342,7 +342,7 @@
if (found)
continue;
/* If not - create it from table info. */
- child = BUS_ADD_CHILD(parent, ACPI_DEV_BASE_ORDER, "hpet", 0);
+ child = BUS_ADD_CHILD(parent, 2, "hpet", 0);
if (child == NULL) {
printf("%s: can't add child\n", __func__);
continue;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/acpica/acpi_timer.c
--- a/head/sys/dev/acpica/acpi_timer.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/acpica/acpi_timer.c Fri Mar 02 17:36:33 2012 +0200
@@ -26,11 +26,12 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi_timer.c 222222 2011-05-23 20:12:36Z jkim $");
+__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi_timer.c 231295 2012-02-09 17:38:08Z jkim $");
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/bus.h>
+#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/sysctl.h>
@@ -60,12 +61,15 @@
static struct resource *acpi_timer_reg;
static bus_space_handle_t acpi_timer_bsh;
static bus_space_tag_t acpi_timer_bst;
+static eventhandler_tag acpi_timer_eh;
static u_int acpi_timer_frequency = 14318182 / 4;
static void acpi_timer_identify(driver_t *driver, device_t parent);
static int acpi_timer_probe(device_t dev);
static int acpi_timer_attach(device_t dev);
+static void acpi_timer_resume_handler(struct timecounter *);
+static void acpi_timer_suspend_handler(struct timecounter *);
static u_int acpi_timer_get_timecount(struct timecounter *tc);
static u_int acpi_timer_get_timecount_safe(struct timecounter *tc);
static int acpi_timer_sysctl_freq(SYSCTL_HANDLER_ARGS);
@@ -124,7 +128,7 @@
acpi_timer_dev)
return_VOID;
- if ((dev = BUS_ADD_CHILD(parent, 0, "acpi_timer", 0)) == NULL) {
+ if ((dev = BUS_ADD_CHILD(parent, 2, "acpi_timer", 0)) == NULL) {
device_printf(parent, "could not add acpi_timer0\n");
return_VOID;
}
@@ -244,9 +248,60 @@
return (ENXIO);
acpi_timer_bsh = rman_get_bushandle(acpi_timer_reg);
acpi_timer_bst = rman_get_bustag(acpi_timer_reg);
+
+ /* Register suspend event handler. */
+ if (EVENTHANDLER_REGISTER(power_suspend, acpi_timer_suspend_handler,
+ &acpi_timer_timecounter, EVENTHANDLER_PRI_LAST) == NULL)
+ device_printf(dev, "failed to register suspend event handler\n");
+
return (0);
}
+static void
+acpi_timer_resume_handler(struct timecounter *newtc)
+{
+ struct timecounter *tc;
+
+ tc = timecounter;
+ if (tc != newtc) {
+ if (bootverbose)
+ device_printf(acpi_timer_dev,
+ "restoring timecounter, %s -> %s\n",
+ tc->tc_name, newtc->tc_name);
+ (void)newtc->tc_get_timecount(newtc);
+ (void)newtc->tc_get_timecount(newtc);
+ timecounter = newtc;
+ }
+}
+
+static void
+acpi_timer_suspend_handler(struct timecounter *newtc)
+{
+ struct timecounter *tc;
+
+ /* Deregister existing resume event handler. */
+ if (acpi_timer_eh != NULL) {
+ EVENTHANDLER_DEREGISTER(power_resume, acpi_timer_eh);
+ acpi_timer_eh = NULL;
+ }
+
+ KASSERT(newtc == &acpi_timer_timecounter,
+ ("acpi_timer_suspend_handler: wrong timecounter"));
+
+ tc = timecounter;
+ if (tc != newtc) {
+ if (bootverbose)
+ device_printf(acpi_timer_dev,
+ "switching timecounter, %s -> %s\n",
+ tc->tc_name, newtc->tc_name);
+ (void)acpi_timer_read();
+ (void)acpi_timer_read();
+ timecounter = newtc;
+ acpi_timer_eh = EVENTHANDLER_REGISTER(power_resume,
+ acpi_timer_resume_handler, tc, EVENTHANDLER_PRI_LAST);
+ }
+}
+
/*
* Fetch current time value from reliable hardware.
*/
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/acpica/acpivar.h
--- a/head/sys/dev/acpica/acpivar.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/acpica/acpivar.h Fri Mar 02 17:36:33 2012 +0200
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/dev/acpica/acpivar.h 226302 2011-10-12 14:13:32Z jhb $
+ * $FreeBSD: head/sys/dev/acpica/acpivar.h 231227 2012-02-08 21:23:20Z jkim $
*/
#ifndef _ACPIVAR_H_
@@ -339,7 +339,6 @@
int acpi_ReqSleepState(struct acpi_softc *sc, int state);
int acpi_AckSleepState(struct apm_clone_data *clone, int error);
ACPI_STATUS acpi_SetSleepState(struct acpi_softc *sc, int state);
-void acpi_resync_clock(struct acpi_softc *sc);
int acpi_wake_set_enable(device_t dev, int enable);
int acpi_parse_prw(ACPI_HANDLE h, struct acpi_prw_data *prw);
ACPI_STATUS acpi_Startup(void);
@@ -473,7 +472,7 @@
* probe order sorted so that things like sysresource are available before
* their children need them.
*/
-#define ACPI_DEV_BASE_ORDER 10
+#define ACPI_DEV_BASE_ORDER 100
/* Default maximum number of tasks to enqueue. */
#ifndef ACPI_MAX_TASKS
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ahci/ahci.c
--- a/head/sys/dev/ahci/ahci.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ahci/ahci.c Fri Mar 02 17:36:33 2012 +0200
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ahci/ahci.c 229671 2012-01-06 00:22:55Z jimharris $");
+__FBSDID("$FreeBSD: head/sys/dev/ahci/ahci.c 232380 2012-03-02 08:49:07Z mav $");
#include <sys/param.h>
#include <sys/module.h>
@@ -187,13 +187,13 @@
{0x2365197b, 0x00, "JMicron JMB365", AHCI_Q_NOFORCE},
{0x2366197b, 0x00, "JMicron JMB366", AHCI_Q_NOFORCE},
{0x2368197b, 0x00, "JMicron JMB368", AHCI_Q_NOFORCE},
- {0x611111ab, 0x00, "Marvell 88SX6111", AHCI_Q_NOFORCE | AHCI_Q_1CH |
+ {0x611111ab, 0x00, "Marvell 88SE6111", AHCI_Q_NOFORCE | AHCI_Q_1CH |
AHCI_Q_EDGEIS},
- {0x612111ab, 0x00, "Marvell 88SX6121", AHCI_Q_NOFORCE | AHCI_Q_2CH |
+ {0x612111ab, 0x00, "Marvell 88SE6121", AHCI_Q_NOFORCE | AHCI_Q_2CH |
AHCI_Q_EDGEIS | AHCI_Q_NONCQ | AHCI_Q_NOCOUNT},
- {0x614111ab, 0x00, "Marvell 88SX6141", AHCI_Q_NOFORCE | AHCI_Q_4CH |
+ {0x614111ab, 0x00, "Marvell 88SE6141", AHCI_Q_NOFORCE | AHCI_Q_4CH |
AHCI_Q_EDGEIS | AHCI_Q_NONCQ | AHCI_Q_NOCOUNT},
- {0x614511ab, 0x00, "Marvell 88SX6145", AHCI_Q_NOFORCE | AHCI_Q_4CH |
+ {0x614511ab, 0x00, "Marvell 88SE6145", AHCI_Q_NOFORCE | AHCI_Q_4CH |
AHCI_Q_EDGEIS | AHCI_Q_NONCQ | AHCI_Q_NOCOUNT},
{0x91201b4b, 0x00, "Marvell 88SE912x", AHCI_Q_EDGEIS|AHCI_Q_NOBSYRES},
{0x91231b4b, 0x11, "Marvell 88SE912x", AHCI_Q_NOBSYRES|AHCI_Q_ALTSIG},
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/amdtemp/amdtemp.c
--- a/head/sys/dev/amdtemp/amdtemp.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/amdtemp/amdtemp.c Fri Mar 02 17:36:33 2012 +0200
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 2008, 2009 Rui Paulo <rpaulo at FreeBSD.org>
* Copyright (c) 2009 Norikatsu Shigemura <nork at FreeBSD.org>
- * Copyright (c) 2009 Jung-uk Kim <jkim at FreeBSD.org>
+ * Copyright (c) 2009-2012 Jung-uk Kim <jkim at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,12 +27,12 @@
*/
/*
- * Driver for the AMD CPU on-die thermal sensors for Family 0Fh/10h/11h procs.
+ * Driver for the AMD CPU on-die thermal sensors.
* Initially based on the k8temp Linux driver.
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/amdtemp/amdtemp.c 232090 2012-02-24 00:02:46Z jkim $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -47,12 +47,13 @@
#include <machine/specialreg.h>
#include <dev/pci/pcivar.h>
+#include <x86/pci_cfgreg.h>
typedef enum {
- SENSOR0_CORE0,
- SENSOR0_CORE1,
- SENSOR1_CORE0,
- SENSOR1_CORE1,
+ CORE0_SENSOR0,
+ CORE0_SENSOR1,
+ CORE1_SENSOR0,
+ CORE1_SENSOR1,
CORE0,
CORE1
} amdsensor_t;
@@ -62,11 +63,10 @@
int sc_ncores;
int sc_ntemps;
int sc_flags;
-#define AMDTEMP_FLAG_DO_QUIRK 0x01 /* DiodeOffset may be incorrect. */
-#define AMDTEMP_FLAG_DO_ZERO 0x02 /* DiodeOffset starts from 0C. */
-#define AMDTEMP_FLAG_DO_SIGN 0x04 /* DiodeOffsetSignBit is present. */
-#define AMDTEMP_FLAG_CS_SWAP 0x08 /* ThermSenseCoreSel is inverted. */
-#define AMDTEMP_FLAG_CT_10BIT 0x10 /* CurTmp is 10-bit wide. */
+#define AMDTEMP_FLAG_CS_SWAP 0x01 /* ThermSenseCoreSel is inverted. */
+#define AMDTEMP_FLAG_CT_10BIT 0x02 /* CurTmp is 10-bit wide. */
+#define AMDTEMP_FLAG_ALT_OFFSET 0x04 /* CurTmp starts at -28C. */
+ int32_t sc_offset;
int32_t (*sc_gettemp)(device_t, amdsensor_t);
struct sysctl_oid *sc_sysctl_cpu[MAXCPU];
struct intr_config_hook sc_ich;
@@ -76,6 +76,8 @@
#define DEVICEID_AMD_MISC0F 0x1103
#define DEVICEID_AMD_MISC10 0x1203
#define DEVICEID_AMD_MISC11 0x1303
+#define DEVICEID_AMD_MISC14 0x1703
+#define DEVICEID_AMD_MISC15 0x1603
static struct amdtemp_product {
uint16_t amdtemp_vendorid;
@@ -84,20 +86,28 @@
{ VENDORID_AMD, DEVICEID_AMD_MISC0F },
{ VENDORID_AMD, DEVICEID_AMD_MISC10 },
{ VENDORID_AMD, DEVICEID_AMD_MISC11 },
+ { VENDORID_AMD, DEVICEID_AMD_MISC14 },
+ { VENDORID_AMD, DEVICEID_AMD_MISC15 },
{ 0, 0 }
};
/*
- * Reported Temperature Control Register (Family 10h/11h only)
+ * Reported Temperature Control Register
*/
#define AMDTEMP_REPTMP_CTRL 0xa4
/*
- * Thermaltrip Status Register
+ * Thermaltrip Status Register (Family 0Fh only)
*/
#define AMDTEMP_THERMTP_STAT 0xe4
-#define AMDTEMP_TTSR_SELCORE 0x04 /* Family 0Fh only */
-#define AMDTEMP_TTSR_SELSENSOR 0x40 /* Family 0Fh only */
+#define AMDTEMP_TTSR_SELCORE 0x04
+#define AMDTEMP_TTSR_SELSENSOR 0x40
+
+/*
+ * DRAM Configuration High Register
+ */
+#define AMDTEMP_DRAM_CONF_HIGH 0x94 /* Function 2 */
+#define AMDTEMP_DRAM_MODE_DDR3 0x0100
/*
* CPU Family/Model Register
@@ -189,6 +199,9 @@
break;
case 0x10:
case 0x11:
+ case 0x12:
+ case 0x14:
+ case 0x15:
break;
default:
return (ENXIO);
@@ -201,26 +214,23 @@
static int
amdtemp_attach(device_t dev)
{
+ char tn[32];
+ u_int regs[4];
struct amdtemp_softc *sc = device_get_softc(dev);
struct sysctl_ctx_list *sysctlctx;
struct sysctl_oid *sysctlnode;
- uint32_t regs[4];
uint32_t cpuid, family, model;
+ u_int bid;
+ int erratum319, unit;
- /*
- * Errata #154: Incorect Diode Offset
- */
- if (cpu_id == 0x20f32) {
- do_cpuid(0x80000001, regs);
- if ((regs[1] & 0xfff) == 0x2c)
- sc->sc_flags |= AMDTEMP_FLAG_DO_QUIRK;
- }
+ erratum319 = 0;
/*
* CPUID Register is available from Revision F.
*/
- family = CPUID_TO_FAMILY(cpu_id);
- model = CPUID_TO_MODEL(cpu_id);
+ cpuid = cpu_id;
+ family = CPUID_TO_FAMILY(cpuid);
+ model = CPUID_TO_MODEL(cpuid);
if (family != 0x0f || model >= 0x40) {
cpuid = pci_read_config(dev, AMDTEMP_CPUID, 4);
family = CPUID_TO_FAMILY(cpuid);
@@ -232,11 +242,6 @@
/*
* Thermaltrip Status Register
*
- * - DiodeOffsetSignBit
- *
- * Revision D & E: bit 24
- * Other: N/A
- *
* - ThermSenseCoreSel
*
* Revision F & G: 0 - Core1, 1 - Core0
@@ -254,15 +259,37 @@
* ThermSenseCoreSel work in undocumented cases as well.
* In fact, the Linux driver suggests it may not work but
* we just assume it does until we find otherwise.
+ *
+ * XXX According to Linux, CurTmp starts at -28C on
+ * Socket AM2 Revision G processors, which is not
+ * documented anywhere.
*/
- if (model < 0x40) {
- sc->sc_flags |= AMDTEMP_FLAG_DO_ZERO;
- if (model >= 0x10)
- sc->sc_flags |= AMDTEMP_FLAG_DO_SIGN;
- } else {
+ if (model >= 0x40)
sc->sc_flags |= AMDTEMP_FLAG_CS_SWAP;
- if (model >= 0x60 && model != 0xc1)
- sc->sc_flags |= AMDTEMP_FLAG_CT_10BIT;
+ if (model >= 0x60 && model != 0xc1) {
+ do_cpuid(0x80000001, regs);
+ bid = (regs[1] >> 9) & 0x1f;
+ switch (model) {
+ case 0x68: /* Socket S1g1 */
+ case 0x6c:
+ case 0x7c:
+ break;
+ case 0x6b: /* Socket AM2 and ASB1 (2 cores) */
+ if (bid != 0x0b && bid != 0x0c)
+ sc->sc_flags |=
+ AMDTEMP_FLAG_ALT_OFFSET;
+ break;
+ case 0x6f: /* Socket AM2 and ASB1 (1 core) */
+ case 0x7f:
+ if (bid != 0x07 && bid != 0x09 &&
+ bid != 0x0c)
+ sc->sc_flags |=
+ AMDTEMP_FLAG_ALT_OFFSET;
+ break;
+ default:
+ sc->sc_flags |= AMDTEMP_FLAG_ALT_OFFSET;
+ }
+ sc->sc_flags |= AMDTEMP_FLAG_CT_10BIT;
}
/*
@@ -273,7 +300,31 @@
sc->sc_gettemp = amdtemp_gettemp0f;
break;
case 0x10:
+ /*
+ * Erratum 319 Inaccurate Temperature Measurement
+ *
+ * http://support.amd.com/us/Processor_TechDocs/41322.pdf
+ */
+ do_cpuid(0x80000001, regs);
+ switch ((regs[1] >> 28) & 0xf) {
+ case 0: /* Socket F */
+ erratum319 = 1;
+ break;
+ case 1: /* Socket AM2+ or AM3 */
+ if ((pci_cfgregread(pci_get_bus(dev),
+ pci_get_slot(dev), 2, AMDTEMP_DRAM_CONF_HIGH, 2) &
+ AMDTEMP_DRAM_MODE_DDR3) != 0 || model > 0x04 ||
+ (model == 0x04 && (cpuid & CPUID_STEPPING) >= 3))
+ break;
+ /* XXX 00100F42h (RB-C2) exists in both formats. */
+ erratum319 = 1;
+ break;
+ }
+ /* FALLTHROUGH */
case 0x11:
+ case 0x12:
+ case 0x14:
+ case 0x15:
/*
* There is only one sensor per package.
*/
@@ -289,6 +340,9 @@
if (sc->sc_ncores > MAXCPU)
return (ENXIO);
+ if (erratum319)
+ device_printf(dev,
+ "Erratum 319: temperature measurement may be inaccurate\n");
if (bootverbose)
device_printf(dev, "Found %d cores and %d sensors.\n",
sc->sc_ncores,
@@ -297,41 +351,49 @@
/*
* dev.amdtemp.N tree.
*/
+ unit = device_get_unit(dev);
+ snprintf(tn, sizeof(tn), "dev.amdtemp.%d.sensor_offset", unit);
+ TUNABLE_INT_FETCH(tn, &sc->sc_offset);
+
sysctlctx = device_get_sysctl_ctx(dev);
+ SYSCTL_ADD_INT(sysctlctx,
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+ "sensor_offset", CTLFLAG_RW, &sc->sc_offset, 0,
+ "Temperature sensor offset");
sysctlnode = SYSCTL_ADD_NODE(sysctlctx,
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
- "sensor0", CTLFLAG_RD, 0, "Sensor 0");
+ "core0", CTLFLAG_RD, 0, "Core 0");
SYSCTL_ADD_PROC(sysctlctx,
SYSCTL_CHILDREN(sysctlnode),
- OID_AUTO, "core0", CTLTYPE_INT | CTLFLAG_RD,
- dev, SENSOR0_CORE0, amdtemp_sysctl, "IK",
- "Sensor 0 / Core 0 temperature");
+ OID_AUTO, "sensor0", CTLTYPE_INT | CTLFLAG_RD,
+ dev, CORE0_SENSOR0, amdtemp_sysctl, "IK",
+ "Core 0 / Sensor 0 temperature");
if (sc->sc_ntemps > 1) {
- if (sc->sc_ncores > 1)
+ SYSCTL_ADD_PROC(sysctlctx,
+ SYSCTL_CHILDREN(sysctlnode),
+ OID_AUTO, "sensor1", CTLTYPE_INT | CTLFLAG_RD,
+ dev, CORE0_SENSOR1, amdtemp_sysctl, "IK",
+ "Core 0 / Sensor 1 temperature");
+
+ if (sc->sc_ncores > 1) {
+ sysctlnode = SYSCTL_ADD_NODE(sysctlctx,
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "core1", CTLFLAG_RD, 0, "Core 1");
+
SYSCTL_ADD_PROC(sysctlctx,
SYSCTL_CHILDREN(sysctlnode),
- OID_AUTO, "core1", CTLTYPE_INT | CTLFLAG_RD,
- dev, SENSOR0_CORE1, amdtemp_sysctl, "IK",
- "Sensor 0 / Core 1 temperature");
+ OID_AUTO, "sensor0", CTLTYPE_INT | CTLFLAG_RD,
+ dev, CORE1_SENSOR0, amdtemp_sysctl, "IK",
+ "Core 1 / Sensor 0 temperature");
- sysctlnode = SYSCTL_ADD_NODE(sysctlctx,
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
- "sensor1", CTLFLAG_RD, 0, "Sensor 1");
-
- SYSCTL_ADD_PROC(sysctlctx,
- SYSCTL_CHILDREN(sysctlnode),
- OID_AUTO, "core0", CTLTYPE_INT | CTLFLAG_RD,
- dev, SENSOR1_CORE0, amdtemp_sysctl, "IK",
- "Sensor 1 / Core 0 temperature");
-
- if (sc->sc_ncores > 1)
SYSCTL_ADD_PROC(sysctlctx,
SYSCTL_CHILDREN(sysctlnode),
- OID_AUTO, "core1", CTLTYPE_INT | CTLFLAG_RD,
- dev, SENSOR1_CORE1, amdtemp_sysctl, "IK",
- "Sensor 1 / Core 1 temperature");
+ OID_AUTO, "sensor1", CTLTYPE_INT | CTLFLAG_RD,
+ dev, CORE1_SENSOR1, amdtemp_sysctl, "IK",
+ "Core 1 / Sensor 1 temperature");
+ }
}
/*
@@ -377,7 +439,7 @@
sysctlctx = device_get_sysctl_ctx(cpu);
sensor = sc->sc_ntemps > 1 ?
- (i == 0 ? CORE0 : CORE1) : SENSOR0_CORE0;
+ (i == 0 ? CORE0 : CORE1) : CORE0_SENSOR0;
sc->sc_sysctl_cpu[i] = SYSCTL_ADD_PROC(sysctlctx,
SYSCTL_CHILDREN(device_get_sysctl_tree(cpu)),
OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD,
@@ -415,13 +477,13 @@
switch (sensor) {
case CORE0:
- auxtemp[0] = sc->sc_gettemp(dev, SENSOR0_CORE0);
- auxtemp[1] = sc->sc_gettemp(dev, SENSOR1_CORE0);
+ auxtemp[0] = sc->sc_gettemp(dev, CORE0_SENSOR0);
+ auxtemp[1] = sc->sc_gettemp(dev, CORE0_SENSOR1);
temp = imax(auxtemp[0], auxtemp[1]);
break;
case CORE1:
- auxtemp[0] = sc->sc_gettemp(dev, SENSOR0_CORE1);
- auxtemp[1] = sc->sc_gettemp(dev, SENSOR1_CORE1);
+ auxtemp[0] = sc->sc_gettemp(dev, CORE1_SENSOR0);
+ auxtemp[1] = sc->sc_gettemp(dev, CORE1_SENSOR1);
temp = imax(auxtemp[0], auxtemp[1]);
break;
default:
@@ -439,53 +501,36 @@
amdtemp_gettemp0f(device_t dev, amdsensor_t sensor)
{
struct amdtemp_softc *sc = device_get_softc(dev);
- uint32_t mask, temp;
- int32_t diode_offset, offset;
- uint8_t cfg, sel;
+ uint32_t mask, offset, temp;
/* Set Sensor/Core selector. */
- sel = 0;
+ temp = pci_read_config(dev, AMDTEMP_THERMTP_STAT, 1);
+ temp &= ~(AMDTEMP_TTSR_SELCORE | AMDTEMP_TTSR_SELSENSOR);
switch (sensor) {
- case SENSOR1_CORE0:
- sel |= AMDTEMP_TTSR_SELSENSOR;
+ case CORE0_SENSOR1:
+ temp |= AMDTEMP_TTSR_SELSENSOR;
/* FALLTHROUGH */
- case SENSOR0_CORE0:
+ case CORE0_SENSOR0:
case CORE0:
if ((sc->sc_flags & AMDTEMP_FLAG_CS_SWAP) != 0)
- sel |= AMDTEMP_TTSR_SELCORE;
+ temp |= AMDTEMP_TTSR_SELCORE;
break;
- case SENSOR1_CORE1:
- sel |= AMDTEMP_TTSR_SELSENSOR;
+ case CORE1_SENSOR1:
+ temp |= AMDTEMP_TTSR_SELSENSOR;
/* FALLTHROUGH */
- case SENSOR0_CORE1:
+ case CORE1_SENSOR0:
case CORE1:
if ((sc->sc_flags & AMDTEMP_FLAG_CS_SWAP) == 0)
- sel |= AMDTEMP_TTSR_SELCORE;
+ temp |= AMDTEMP_TTSR_SELCORE;
break;
}
- cfg = pci_read_config(dev, AMDTEMP_THERMTP_STAT, 1);
- cfg &= ~(AMDTEMP_TTSR_SELSENSOR | AMDTEMP_TTSR_SELCORE);
- pci_write_config(dev, AMDTEMP_THERMTP_STAT, cfg | sel, 1);
-
- /* CurTmp starts from -49C. */
- offset = AMDTEMP_ZERO_C_TO_K - 490;
-
- /* Adjust offset if DiodeOffset is set and valid. */
- temp = pci_read_config(dev, AMDTEMP_THERMTP_STAT, 4);
- diode_offset = (temp >> 8) & 0x3f;
- if ((sc->sc_flags & AMDTEMP_FLAG_DO_ZERO) != 0) {
- if ((sc->sc_flags & AMDTEMP_FLAG_DO_SIGN) != 0 &&
- ((temp >> 24) & 0x1) != 0)
- diode_offset *= -1;
- if ((sc->sc_flags & AMDTEMP_FLAG_DO_QUIRK) != 0 &&
- ((temp >> 25) & 0xf) <= 2)
- diode_offset += 10;
- offset += diode_offset * 10;
- } else if (diode_offset != 0)
- offset += (diode_offset - 11) * 10;
+ pci_write_config(dev, AMDTEMP_THERMTP_STAT, temp, 1);
mask = (sc->sc_flags & AMDTEMP_FLAG_CT_10BIT) != 0 ? 0x3ff : 0x3fc;
- temp = ((temp >> 14) & mask) * 5 / 2 + offset;
+ offset = (sc->sc_flags & AMDTEMP_FLAG_ALT_OFFSET) != 0 ? 28 : 49;
+ temp = pci_read_config(dev, AMDTEMP_THERMTP_STAT, 4);
+ temp = ((temp >> 14) & mask) * 5 / 2;
+ temp += AMDTEMP_ZERO_C_TO_K + (sc->sc_offset - offset) * 10;
return (temp);
}
@@ -493,20 +538,12 @@
static int32_t
amdtemp_gettemp(device_t dev, amdsensor_t sensor)
{
+ struct amdtemp_softc *sc = device_get_softc(dev);
uint32_t temp;
- int32_t diode_offset, offset;
-
- /* CurTmp starts from 0C. */
- offset = AMDTEMP_ZERO_C_TO_K;
-
- /* Adjust offset if DiodeOffset is set and valid. */
- temp = pci_read_config(dev, AMDTEMP_THERMTP_STAT, 4);
- diode_offset = (temp >> 8) & 0x7f;
- if (diode_offset > 0 && diode_offset < 0x40)
- offset += (diode_offset - 11) * 10;
temp = pci_read_config(dev, AMDTEMP_REPTMP_CTRL, 4);
- temp = ((temp >> 21) & 0x7ff) * 5 / 4 + offset;
+ temp = ((temp >> 21) & 0x7ff) * 5 / 4;
+ temp += AMDTEMP_ZERO_C_TO_K + sc->sc_offset * 10;
return (temp);
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/amr/amr_pci.c
--- a/head/sys/dev/amr/amr_pci.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/amr/amr_pci.c Fri Mar 02 17:36:33 2012 +0200
@@ -55,7 +55,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/amr/amr_pci.c 227843 2011-11-22 21:28:20Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/amr/amr_pci.c 232255 2012-02-28 15:09:56Z kevlo $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -339,11 +339,11 @@
/*
* Build the scatter/gather buffers.
*/
- if (amr_sglist_map(sc))
+ if ((error = amr_sglist_map(sc)) != 0)
goto out;
debug(2, "s/g list mapped");
- if (amr_ccb_map(sc))
+ if ((error = amr_ccb_map(sc)) != 0)
goto out;
debug(2, "ccb mapped");
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/arcmsr/arcmsr.c
--- a/head/sys/dev/arcmsr/arcmsr.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/arcmsr/arcmsr.c Fri Mar 02 17:36:33 2012 +0200
@@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/arcmsr/arcmsr.c 227912 2011-11-23 21:43:51Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/arcmsr/arcmsr.c 231924 2012-02-20 01:18:32Z delphij $");
#if 0
#define ARCMSR_DEBUG1 1
@@ -3861,7 +3861,7 @@
return(ENXIO);
sprintf(buf, "Areca %s Host Adapter RAID Controller %s\n", type, raid6 ? "(RAID6 capable)" : "");
device_set_desc_copy(dev, buf);
- return 0;
+ return (BUS_PROBE_DEFAULT);
}
/*
************************************************************************
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ata/ata-pci.h
--- a/head/sys/dev/ata/ata-pci.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ata/ata-pci.h Fri Mar 02 17:36:33 2012 +0200
@@ -23,7 +23,7 @@
* (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: head/sys/dev/ata/ata-pci.h 230132 2012-01-15 13:23:18Z uqs $
+ * $FreeBSD: head/sys/dev/ata/ata-pci.h 232380 2012-03-02 08:49:07Z mav $
*/
/* structure holding chipset config info */
@@ -279,12 +279,12 @@
#define ATA_M88SX6042 0x604211ab
#define ATA_M88SX6081 0x608111ab
#define ATA_M88SX7042 0x704211ab
-#define ATA_M88SX6101 0x610111ab
-#define ATA_M88SX6102 0x610211ab
-#define ATA_M88SX6111 0x611111ab
-#define ATA_M88SX6121 0x612111ab
-#define ATA_M88SX6141 0x614111ab
-#define ATA_M88SX6145 0x614511ab
+#define ATA_M88SE6101 0x610111ab
+#define ATA_M88SE6102 0x610211ab
+#define ATA_M88SE6111 0x611111ab
+#define ATA_M88SE6121 0x612111ab
+#define ATA_M88SE6141 0x614111ab
+#define ATA_M88SE6145 0x614511ab
#define ATA_MARVELL2_ID 0x1b4b
#define ATA_MICRON_ID 0x1042
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ata/ata-queue.c
--- a/head/sys/dev/ata/ata-queue.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ata/ata-queue.c Fri Mar 02 17:36:33 2012 +0200
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/ata-queue.c 230132 2012-01-15 13:23:18Z uqs $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/ata-queue.c 231573 2012-02-13 01:44:12Z emaste $");
#include "opt_ata.h"
#include <sys/param.h>
@@ -112,6 +112,7 @@
ATA_DEBUG_RQ(request, "wait for completion");
if (!dumping &&
sema_timedwait(&request->done, request->timeout * hz * 4)) {
+ callout_drain(&request->callout);
device_printf(request->dev,
"WARNING - %s taskqueue timeout "
"- completing request directly\n",
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ata/chipsets/ata-ahci.c
--- a/head/sys/dev/ata/chipsets/ata-ahci.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-ahci.c Fri Mar 02 17:36:33 2012 +0200
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-ahci.c 230132 2012-01-15 13:23:18Z uqs $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-ahci.c 232380 2012-03-02 08:49:07Z mav $");
#include "opt_ata.h"
#include <sys/param.h>
@@ -180,12 +180,12 @@
ctlr->ichannels = ATA_INL(ctlr->r_res2, ATA_AHCI_PI);
ctlr->channels = MAX(flsl(ctlr->ichannels),
(ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_NPMASK) + 1);
- if (pci_get_devid(dev) == ATA_M88SX6111)
+ if (pci_get_devid(dev) == ATA_M88SE6111)
ctlr->channels = 1;
- else if (pci_get_devid(dev) == ATA_M88SX6121)
+ else if (pci_get_devid(dev) == ATA_M88SE6121)
ctlr->channels = 2;
- else if (pci_get_devid(dev) == ATA_M88SX6141 ||
- pci_get_devid(dev) == ATA_M88SX6145)
+ else if (pci_get_devid(dev) == ATA_M88SE6141 ||
+ pci_get_devid(dev) == ATA_M88SE6145)
ctlr->channels = 4;
ctlr->reset = ata_ahci_reset;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ata/chipsets/ata-marvell.c
--- a/head/sys/dev/ata/chipsets/ata-marvell.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-marvell.c Fri Mar 02 17:36:33 2012 +0200
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-marvell.c 230132 2012-01-15 13:23:18Z uqs $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-marvell.c 232380 2012-03-02 08:49:07Z mav $");
#include "opt_ata.h"
#include <sys/param.h>
@@ -108,12 +108,12 @@
{ ATA_M88SX6042, 0, 4, MV_6042, ATA_SA300, "88SX6042" },
{ ATA_M88SX6081, 0, 8, MV_60XX, ATA_SA300, "88SX6081" },
{ ATA_M88SX7042, 0, 4, MV_7042, ATA_SA300, "88SX7042" },
- { ATA_M88SX6101, 0, 0, MV_61XX, ATA_UDMA6, "88SX6101" },
- { ATA_M88SX6102, 0, 0, MV_61XX, ATA_UDMA6, "88SX6102" },
- { ATA_M88SX6111, 0, 1, MV_61XX, ATA_UDMA6, "88SX6111" },
- { ATA_M88SX6121, 0, 2, MV_61XX, ATA_UDMA6, "88SX6121" },
- { ATA_M88SX6141, 0, 4, MV_61XX, ATA_UDMA6, "88SX6141" },
- { ATA_M88SX6145, 0, 4, MV_61XX, ATA_UDMA6, "88SX6145" },
+ { ATA_M88SE6101, 0, 0, MV_61XX, ATA_UDMA6, "88SE6101" },
+ { ATA_M88SE6102, 0, 0, MV_61XX, ATA_UDMA6, "88SE6102" },
+ { ATA_M88SE6111, 0, 1, MV_61XX, ATA_UDMA6, "88SE6111" },
+ { ATA_M88SE6121, 0, 2, MV_61XX, ATA_UDMA6, "88SE6121" },
+ { ATA_M88SE6141, 0, 4, MV_61XX, ATA_UDMA6, "88SE6141" },
+ { ATA_M88SE6145, 0, 4, MV_61XX, ATA_UDMA6, "88SE6145" },
{ 0x91a41b4b, 0, 0, MV_91XX, ATA_UDMA6, "88SE912x" },
{ 0, 0, 0, 0, 0, 0}};
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ath/ath_dfs/null/dfs_null.c
--- a/head/sys/dev/ath/ath_dfs/null/dfs_null.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ath/ath_dfs/null/dfs_null.c Fri Mar 02 17:36:33 2012 +0200
@@ -26,10 +26,10 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
- * $FreeBSD: head/sys/dev/ath/ath_dfs/null/dfs_null.c 230663 2012-01-28 22:24:59Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_dfs/null/dfs_null.c 231099 2012-02-06 20:23:21Z adrian $
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ath/ath_dfs/null/dfs_null.c 230663 2012-01-28 22:24:59Z adrian $");
+__FBSDID("$FreeBSD: head/sys/dev/ath/ath_dfs/null/dfs_null.c 231099 2012-02-06 20:23:21Z adrian $");
/*
* This implements an empty DFS module.
@@ -71,6 +71,28 @@
#include <dev/ath/ath_hal/ah_desc.h>
/*
+ * These are default parameters for the AR5416 and
+ * later 802.11n NICs. They simply enable some
+ * radar pulse event generation.
+ *
+ * These are very likely not valid for the AR5212 era
+ * NICs.
+ *
+ * Since these define signal sizing and threshold
+ * parameters, they may need changing based on the
+ * specific antenna and receive amplifier
+ * configuration.
+ */
+#define AR5416_DFS_FIRPWR -33
+#define AR5416_DFS_RRSSI 20
+#define AR5416_DFS_HEIGHT 10
+#define AR5416_DFS_PRSSI 15
+#define AR5416_DFS_INBAND 15
+#define AR5416_DFS_RELPWR 8
+#define AR5416_DFS_RELSTEP 12
+#define AR5416_DFS_MAXLEN 255
+
+/*
* Methods which are required
*/
@@ -98,16 +120,45 @@
int
ath_dfs_radar_enable(struct ath_softc *sc, struct ieee80211_channel *chan)
{
+#if 0
+ HAL_PHYERR_PARAM pe;
+
/* Check if the current channel is radar-enabled */
if (! IEEE80211_IS_CHAN_DFS(chan))
return (0);
+ /* Enable radar PHY error reporting */
+ sc->sc_dodfs = 1;
+
/*
- * Enabling the radar parameters and setting sc->sc_dodfs = 1
- * would occur here.
+ * These are general examples of the parameter values
+ * to use when configuring radar pulse detection for
+ * the AR5416, AR91xx, AR92xx NICs. They are only
+ * for testing and do require tuning depending upon the
+ * hardware and deployment specifics.
*/
+ pe.pe_firpwr = AR5416_DFS_FIRPWR;
+ pe.pe_rrssi = AR5416_DFS_RRSSI;
+ pe.pe_height = AR5416_DFS_HEIGHT;
+ pe.pe_prssi = AR5416_DFS_PRSSI;
+ pe.pe_inband = AR5416_DFS_INBAND;
+ pe.pe_relpwr = AR5416_DFS_RELPWR;
+ pe.pe_relstep = AR5416_DFS_RELSTEP;
+ pe.pe_maxlen = AR5416_DFS_MAXLEN;
+ pe.pe_enabled = 1;
+
+ /* Flip on extension channel events only if doing HT40 */
+ if (IEEE80211_IS_CHAN_HT40(chan))
+ pe.pe_extchannel = 1;
+ else
+ pe.pe_extchannel = 0;
+
+ ath_hal_enabledfs(sc->sc_ah, &pe);
return (1);
+#else
+ return (0);
+#endif
}
/*
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ath/ath_hal/ah.h
--- a/head/sys/dev/ath/ath_hal/ah.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ath/ath_hal/ah.h Fri Mar 02 17:36:33 2012 +0200
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $FreeBSD: head/sys/dev/ath/ath_hal/ah.h 230147 2012-01-15 19:22:34Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_hal/ah.h 231708 2012-02-14 20:05:28Z adrian $
*/
#ifndef _ATH_AH_H_
@@ -733,10 +733,11 @@
*/
int32_t pe_extchannel; /* Enable DFS on ext channel */
int32_t pe_enabled; /* Whether radar detection is enabled */
+ int32_t pe_enrelpwr;
+ int32_t pe_en_relstep_check;
} HAL_PHYERR_PARAM;
#define HAL_PHYERR_PARAM_NOVAL 65535
-#define HAL_PHYERR_PARAM_ENABLE 0x8000 /* Enable/Disable if applicable */
/*
* DFS operating mode flags.
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ath/ath_hal/ar5416/ar5416.h
--- a/head/sys/dev/ath/ath_hal/ar5416/ar5416.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ath/ath_hal/ar5416/ar5416.h Fri Mar 02 17:36:33 2012 +0200
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416.h 227374 2011-11-09 05:25:30Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416.h 231927 2012-02-20 03:07:07Z adrian $
*/
#ifndef _ATH_AR5416_H_
#define _ATH_AR5416_H_
@@ -207,11 +207,15 @@
uint32_t duration, uint32_t nextStart, HAL_QUIET_FLAG flag);
extern HAL_STATUS ar5416GetCapability(struct ath_hal *ah,
HAL_CAPABILITY_TYPE type, uint32_t capability, uint32_t *result);
+extern HAL_BOOL ar5416SetCapability(struct ath_hal *ah,
+ HAL_CAPABILITY_TYPE type, uint32_t capability, uint32_t val,
+ HAL_STATUS *status);
extern HAL_BOOL ar5416GetDiagState(struct ath_hal *ah, int request,
const void *args, uint32_t argsize,
void **result, uint32_t *resultsize);
extern HAL_BOOL ar5416SetRifsDelay(struct ath_hal *ah,
const struct ieee80211_channel *chan, HAL_BOOL enable);
+
extern void ar5416EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe);
extern void ar5416GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe);
extern HAL_BOOL ar5416ProcessRadarEvent(struct ath_hal *ah,
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
--- a/head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c Fri Mar 02 17:36:33 2012 +0200
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c 230847 2012-01-31 22:31:16Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c 231368 2012-02-10 09:58:20Z adrian $
*/
#include "opt_ah.h"
@@ -129,6 +129,7 @@
/* Misc Functions */
ah->ah_getCapability = ar5416GetCapability;
+ ah->ah_setCapability = ar5416SetCapability;
ah->ah_getDiagState = ar5416GetDiagState;
ah->ah_setLedState = ar5416SetLedState;
ah->ah_gpioCfgOutput = ar5416GpioCfgOutput;
@@ -884,6 +885,7 @@
/* AR5416 may have 3 antennas but is a 2x2 stream device */
pCap->halTxStreams = 2;
pCap->halRxStreams = 2;
+
/*
* If the TX or RX chainmask has less than 2 chains active,
* mark it as a 1-stream device for the relevant stream.
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c
--- a/head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c Fri Mar 02 17:36:33 2012 +0200
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c 228889 2011-12-26 06:07:21Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c 231927 2012-02-20 03:07:07Z adrian $
*/
#include "opt_ah.h"
@@ -27,6 +27,8 @@
#include "ar5416/ar5416reg.h"
#include "ar5416/ar5416phy.h"
+#include "ah_eeprom_v14.h" /* for owl_get_ntxchains() */
+
/*
* Return the wireless modes (a,b,g,n,t) supported by hardware.
*
@@ -430,6 +432,35 @@
return ar5212GetCapability(ah, type, capability, result);
}
+HAL_BOOL
+ar5416SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
+ u_int32_t capability, u_int32_t setting, HAL_STATUS *status)
+{
+ HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
+
+ switch (type) {
+ case HAL_CAP_RX_CHAINMASK:
+ setting &= ath_hal_eepromGet(ah, AR_EEP_RXMASK, NULL);
+ pCap->halRxChainMask = setting;
+ if (owl_get_ntxchains(setting) > 2)
+ pCap->halRxStreams = 2;
+ else
+ pCap->halRxStreams = 1;
+ return AH_TRUE;
+ case HAL_CAP_TX_CHAINMASK:
+ setting &= ath_hal_eepromGet(ah, AR_EEP_TXMASK, NULL);
+ pCap->halTxChainMask = setting;
+ if (owl_get_ntxchains(setting) > 2)
+ pCap->halTxStreams = 2;
+ else
+ pCap->halTxStreams = 1;
+ return AH_TRUE;
+ default:
+ break;
+ }
+ return ar5212SetCapability(ah, type, capability, setting, status);
+}
+
static int ar5416DetectMacHang(struct ath_hal *ah);
static int ar5416DetectBBHang(struct ath_hal *ah);
@@ -689,343 +720,3 @@
#undef N
}
#undef NUM_STATUS_READS
-
-/*
- * Get the radar parameter values and return them in the pe
- * structure
- */
-void
-ar5416GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
-{
- uint32_t val, temp;
-
- val = OS_REG_READ(ah, AR_PHY_RADAR_0);
-
- temp = MS(val,AR_PHY_RADAR_0_FIRPWR);
- temp |= 0xFFFFFF80;
- pe->pe_firpwr = temp;
- pe->pe_rrssi = MS(val, AR_PHY_RADAR_0_RRSSI);
- pe->pe_height = MS(val, AR_PHY_RADAR_0_HEIGHT);
- pe->pe_prssi = MS(val, AR_PHY_RADAR_0_PRSSI);
- pe->pe_inband = MS(val, AR_PHY_RADAR_0_INBAND);
-
- val = OS_REG_READ(ah, AR_PHY_RADAR_1);
- temp = val & AR_PHY_RADAR_1_RELPWR_ENA;
- pe->pe_relpwr = MS(val, AR_PHY_RADAR_1_RELPWR_THRESH);
- if (temp)
- pe->pe_relpwr |= HAL_PHYERR_PARAM_ENABLE;
- temp = val & AR_PHY_RADAR_1_RELSTEP_CHECK;
- pe->pe_relstep = MS(val, AR_PHY_RADAR_1_RELSTEP_THRESH);
- if (temp)
- pe->pe_enabled = 1;
- else
- pe->pe_enabled = 0;
-
- pe->pe_maxlen = MS(val, AR_PHY_RADAR_1_MAXLEN);
- pe->pe_extchannel = !! (OS_REG_READ(ah, AR_PHY_RADAR_EXT) &
- AR_PHY_RADAR_EXT_ENA);
-
- pe->pe_usefir128 = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) &
- AR_PHY_RADAR_1_USE_FIR128);
- pe->pe_blockradar = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) &
- AR_PHY_RADAR_1_BLOCK_CHECK);
- pe->pe_enmaxrssi = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) &
- AR_PHY_RADAR_1_MAX_RRSSI);
-}
-
-/*
- * Enable radar detection and set the radar parameters per the
- * values in pe
- */
-void
-ar5416EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
-{
- uint32_t val;
-
- val = OS_REG_READ(ah, AR_PHY_RADAR_0);
-
- if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) {
- val &= ~AR_PHY_RADAR_0_FIRPWR;
- val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR);
- }
- if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) {
- val &= ~AR_PHY_RADAR_0_RRSSI;
- val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI);
- }
- if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) {
- val &= ~AR_PHY_RADAR_0_HEIGHT;
- val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT);
- }
- if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) {
- val &= ~AR_PHY_RADAR_0_PRSSI;
- val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
- }
- if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) {
- val &= ~AR_PHY_RADAR_0_INBAND;
- val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND);
- }
-
- /*Enable FFT data*/
- val |= AR_PHY_RADAR_0_FFT_ENA;
-
- OS_REG_WRITE(ah, AR_PHY_RADAR_0, val | AR_PHY_RADAR_0_ENA);
-
- if (pe->pe_usefir128 == 1)
- OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_USE_FIR128);
- else if (pe->pe_usefir128 == 0)
- OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_USE_FIR128);
-
- if (pe->pe_enmaxrssi == 1)
- OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_MAX_RRSSI);
- else if (pe->pe_enmaxrssi == 0)
- OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_MAX_RRSSI);
-
- if (pe->pe_blockradar == 1)
- OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_BLOCK_CHECK);
- else if (pe->pe_blockradar == 0)
- OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_BLOCK_CHECK);
-
- if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL) {
- val = OS_REG_READ(ah, AR_PHY_RADAR_1);
- val &= ~AR_PHY_RADAR_1_MAXLEN;
- val |= SM(pe->pe_maxlen, AR_PHY_RADAR_1_MAXLEN);
- OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
- }
-
- /*
- * Enable HT/40 if the upper layer asks;
- * it should check the channel is HT/40 and HAL_CAP_EXT_CHAN_DFS
- * is available.
- */
- if (pe->pe_extchannel == 1)
- OS_REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
- else if (pe->pe_extchannel == 0)
- OS_REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
-
- if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL) {
- val = OS_REG_READ(ah, AR_PHY_RADAR_1);
- val &= ~AR_PHY_RADAR_1_RELSTEP_THRESH;
- val |= SM(pe->pe_relstep, AR_PHY_RADAR_1_RELSTEP_THRESH);
- OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
- }
- if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL) {
- val = OS_REG_READ(ah, AR_PHY_RADAR_1);
- val &= ~AR_PHY_RADAR_1_RELPWR_THRESH;
- val |= SM(pe->pe_relpwr, AR_PHY_RADAR_1_RELPWR_THRESH);
- OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
- }
-}
-
-/*
- * Extract the radar event information from the given phy error.
- *
- * Returns AH_TRUE if the phy error was actually a phy error,
- * AH_FALSE if the phy error wasn't a phy error.
- */
-
-/* Flags for pulse_bw_info */
-#define PRI_CH_RADAR_FOUND 0x01
-#define EXT_CH_RADAR_FOUND 0x02
-#define EXT_CH_RADAR_EARLY_FOUND 0x04
-
-HAL_BOOL
-ar5416ProcessRadarEvent(struct ath_hal *ah, struct ath_rx_status *rxs,
- uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event)
-{
- HAL_BOOL doDfsExtCh;
- HAL_BOOL doDfsEnhanced;
- HAL_BOOL doDfsCombinedRssi;
-
- uint8_t rssi = 0, ext_rssi = 0;
- uint8_t pulse_bw_info = 0, pulse_length_ext = 0, pulse_length_pri = 0;
- uint32_t dur = 0;
- int pri_found = 1, ext_found = 0;
- int early_ext = 0;
- int is_dc = 0;
- uint16_t datalen; /* length from the RX status field */
-
- /* Check whether the given phy error is a radar event */
- if ((rxs->rs_phyerr != HAL_PHYERR_RADAR) &&
- (rxs->rs_phyerr != HAL_PHYERR_FALSE_RADAR_EXT)) {
- return AH_FALSE;
- }
-
- /* Grab copies of the capabilities; just to make the code clearer */
- doDfsExtCh = AH_PRIVATE(ah)->ah_caps.halExtChanDfsSupport;
- doDfsEnhanced = AH_PRIVATE(ah)->ah_caps.halEnhancedDfsSupport;
- doDfsCombinedRssi = AH_PRIVATE(ah)->ah_caps.halUseCombinedRadarRssi;
-
- datalen = rxs->rs_datalen;
-
- /* If hardware supports it, use combined RSSI, else use chain 0 RSSI */
- if (doDfsCombinedRssi)
- rssi = (uint8_t) rxs->rs_rssi;
- else
- rssi = (uint8_t) rxs->rs_rssi_ctl[0];
-
- /* Set this; but only use it if doDfsExtCh is set */
- ext_rssi = (uint8_t) rxs->rs_rssi_ext[0];
-
- /* Cap it at 0 if the RSSI is a negative number */
- if (rssi & 0x80)
- rssi = 0;
-
- if (ext_rssi & 0x80)
- ext_rssi = 0;
-
- /*
- * Fetch the relevant data from the frame
- */
- if (doDfsExtCh) {
- if (datalen < 3)
- return AH_FALSE;
-
- /* Last three bytes of the frame are of interest */
- pulse_length_pri = *(buf + datalen - 3);
- pulse_length_ext = *(buf + datalen - 2);
- pulse_bw_info = *(buf + datalen - 1);
- HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, ext_rssi=%d, pulse_length_pri=%d,"
- " pulse_length_ext=%d, pulse_bw_info=%x\n",
- __func__, rssi, ext_rssi, pulse_length_pri, pulse_length_ext,
- pulse_bw_info);
- } else {
- /* The pulse width is byte 0 of the data */
- if (datalen >= 1)
- dur = ((uint8_t) buf[0]) & 0xff;
- else
- dur = 0;
-
- if (dur == 0 && rssi == 0) {
- HALDEBUG(ah, HAL_DEBUG_DFS, "%s: dur and rssi are 0\n", __func__);
- return AH_FALSE;
- }
-
- HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, dur=%d\n", __func__, rssi, dur);
-
- /* Single-channel only */
- pri_found = 1;
- ext_found = 0;
- }
-
- /*
- * If doing extended channel data, pulse_bw_info must
- * have one of the flags set.
- */
- if (doDfsExtCh && pulse_bw_info == 0x0)
- return AH_FALSE;
-
- /*
- * If the extended channel data is available, calculate
- * which to pay attention to.
- */
- if (doDfsExtCh) {
- /* If pulse is on DC, take the larger duration of the two */
- if ((pulse_bw_info & EXT_CH_RADAR_FOUND) &&
- (pulse_bw_info & PRI_CH_RADAR_FOUND)) {
- is_dc = 1;
- if (pulse_length_ext > pulse_length_pri) {
- dur = pulse_length_ext;
- pri_found = 0;
- ext_found = 1;
- } else {
- dur = pulse_length_pri;
- pri_found = 1;
- ext_found = 0;
- }
- } else if (pulse_bw_info & EXT_CH_RADAR_EARLY_FOUND) {
- dur = pulse_length_ext;
- pri_found = 0;
- ext_found = 1;
- early_ext = 1;
- } else if (pulse_bw_info & PRI_CH_RADAR_FOUND) {
- dur = pulse_length_pri;
- pri_found = 1;
- ext_found = 0;
- } else if (pulse_bw_info & EXT_CH_RADAR_FOUND) {
- dur = pulse_length_ext;
- pri_found = 0;
- ext_found = 1;
- }
-
- }
-
- /*
- * For enhanced DFS (Merlin and later), pulse_bw_info has
- * implications for selecting the correct RSSI value.
- */
- if (doDfsEnhanced) {
- switch (pulse_bw_info & 0x03) {
- case 0:
- /* No radar? */
- rssi = 0;
- break;
- case PRI_CH_RADAR_FOUND:
- /* Radar in primary channel */
- /* Cannot use ctrl channel RSSI if ext channel is stronger */
- if (ext_rssi >= (rssi + 3)) {
- rssi = 0;
- };
- break;
- case EXT_CH_RADAR_FOUND:
- /* Radar in extended channel */
- /* Cannot use ext channel RSSI if ctrl channel is stronger */
- if (rssi >= (ext_rssi + 12)) {
- rssi = 0;
- } else {
- rssi = ext_rssi;
- }
- break;
- case (PRI_CH_RADAR_FOUND | EXT_CH_RADAR_FOUND):
- /* When both are present, use stronger one */
- if (rssi < ext_rssi)
- rssi = ext_rssi;
- break;
- }
- }
-
- /*
- * If not doing enhanced DFS, choose the ext channel if
- * it is stronger than the main channel
- */
- if (doDfsExtCh && !doDfsEnhanced) {
- if ((ext_rssi > rssi) && (ext_rssi < 128))
- rssi = ext_rssi;
- }
-
- /*
- * XXX what happens if the above code decides the RSSI
- * XXX wasn't valid, an sets it to 0?
- */
-
- /*
- * Fill out dfs_event structure.
- */
- event->re_full_ts = fulltsf;
- event->re_ts = rxs->rs_tstamp;
- event->re_rssi = rssi;
- event->re_dur = dur;
-
- event->re_flags = 0;
- if (pri_found)
- event->re_flags |= HAL_DFS_EVENT_PRICH;
- if (ext_found)
- event->re_flags |= HAL_DFS_EVENT_EXTCH;
- if (early_ext)
- event->re_flags |= HAL_DFS_EVENT_EXTEARLY;
- if (is_dc)
- event->re_flags |= HAL_DFS_EVENT_ISDC;
-
- return AH_TRUE;
-}
-
-/*
- * Return whether fast-clock is currently enabled for this
- * channel.
- */
-HAL_BOOL
-ar5416IsFastClockEnabled(struct ath_hal *ah)
-{
- struct ath_hal_private *ahp = AH_PRIVATE(ah);
-
- return IS_5GHZ_FAST_CLOCK_EN(ah, ahp->ah_curchan);
-}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ath/ath_hal/ar5416/ar5416_radar.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/ath/ath_hal/ar5416/ar5416_radar.c Fri Mar 02 17:36:33 2012 +0200
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_radar.c 231927 2012-02-20 03:07:07Z adrian $
+ */
+#include "opt_ah.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ah_devid.h"
+#include "ah_desc.h" /* NB: for HAL_PHYERR* */
+
+#include "ar5416/ar5416.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+
+#include "ah_eeprom_v14.h" /* for owl_get_ntxchains() */
+
+/*
+ * Get the radar parameter values and return them in the pe
+ * structure
+ */
+void
+ar5416GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
+{
+ uint32_t val, temp;
+
+ val = OS_REG_READ(ah, AR_PHY_RADAR_0);
+
+ temp = MS(val,AR_PHY_RADAR_0_FIRPWR);
+ temp |= 0xFFFFFF80;
+ pe->pe_firpwr = temp;
+ pe->pe_rrssi = MS(val, AR_PHY_RADAR_0_RRSSI);
+ pe->pe_height = MS(val, AR_PHY_RADAR_0_HEIGHT);
+ pe->pe_prssi = MS(val, AR_PHY_RADAR_0_PRSSI);
+ pe->pe_inband = MS(val, AR_PHY_RADAR_0_INBAND);
+
+ /* RADAR_1 values */
+ val = OS_REG_READ(ah, AR_PHY_RADAR_1);
+ pe->pe_relpwr = MS(val, AR_PHY_RADAR_1_RELPWR_THRESH);
+ pe->pe_relstep = MS(val, AR_PHY_RADAR_1_RELSTEP_THRESH);
+ pe->pe_maxlen = MS(val, AR_PHY_RADAR_1_MAXLEN);
+
+ pe->pe_extchannel = !! (OS_REG_READ(ah, AR_PHY_RADAR_EXT) &
+ AR_PHY_RADAR_EXT_ENA);
+
+ pe->pe_usefir128 = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) &
+ AR_PHY_RADAR_1_USE_FIR128);
+ pe->pe_blockradar = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) &
+ AR_PHY_RADAR_1_BLOCK_CHECK);
+ pe->pe_enmaxrssi = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) &
+ AR_PHY_RADAR_1_MAX_RRSSI);
+ pe->pe_enabled = !!
+ (OS_REG_READ(ah, AR_PHY_RADAR_0) & AR_PHY_RADAR_0_ENA);
+ pe->pe_enrelpwr = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) &
+ AR_PHY_RADAR_1_RELPWR_ENA);
+ pe->pe_en_relstep_check = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) &
+ AR_PHY_RADAR_1_RELSTEP_CHECK);
+}
+
+/*
+ * Enable radar detection and set the radar parameters per the
+ * values in pe
+ */
+void
+ar5416EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
+{
+ uint32_t val;
+
+ val = OS_REG_READ(ah, AR_PHY_RADAR_0);
+
+ if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) {
+ val &= ~AR_PHY_RADAR_0_FIRPWR;
+ val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR);
+ }
+ if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) {
+ val &= ~AR_PHY_RADAR_0_RRSSI;
+ val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI);
+ }
+ if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) {
+ val &= ~AR_PHY_RADAR_0_HEIGHT;
+ val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT);
+ }
+ if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) {
+ val &= ~AR_PHY_RADAR_0_PRSSI;
+ val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
+ }
+ if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) {
+ val &= ~AR_PHY_RADAR_0_INBAND;
+ val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND);
+ }
+
+ /*Enable FFT data*/
+ val |= AR_PHY_RADAR_0_FFT_ENA;
+ OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
+
+ /* Implicitly enable */
+ if (pe->pe_enabled == 1)
+ OS_REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA);
+ else if (pe->pe_enabled == 0)
+ OS_REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA);
+
+ if (pe->pe_usefir128 == 1)
+ OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_USE_FIR128);
+ else if (pe->pe_usefir128 == 0)
+ OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_USE_FIR128);
+
+ if (pe->pe_enmaxrssi == 1)
+ OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_MAX_RRSSI);
+ else if (pe->pe_enmaxrssi == 0)
+ OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_MAX_RRSSI);
+
+ if (pe->pe_blockradar == 1)
+ OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_BLOCK_CHECK);
+ else if (pe->pe_blockradar == 0)
+ OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_BLOCK_CHECK);
+
+ if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL) {
+ val = OS_REG_READ(ah, AR_PHY_RADAR_1);
+ val &= ~AR_PHY_RADAR_1_RELSTEP_THRESH;
+ val |= SM(pe->pe_relstep, AR_PHY_RADAR_1_RELSTEP_THRESH);
+ OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
+ }
+ if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL) {
+ val = OS_REG_READ(ah, AR_PHY_RADAR_1);
+ val &= ~AR_PHY_RADAR_1_RELPWR_THRESH;
+ val |= SM(pe->pe_relpwr, AR_PHY_RADAR_1_RELPWR_THRESH);
+ OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
+ }
+
+ if (pe->pe_en_relstep_check == 1)
+ OS_REG_SET_BIT(ah, AR_PHY_RADAR_1,
+ AR_PHY_RADAR_1_RELSTEP_CHECK);
+ else if (pe->pe_en_relstep_check == 0)
+ OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1,
+ AR_PHY_RADAR_1_RELSTEP_CHECK);
+
+ if (pe->pe_enrelpwr == 1)
+ OS_REG_SET_BIT(ah, AR_PHY_RADAR_1,
+ AR_PHY_RADAR_1_RELPWR_ENA);
+ else if (pe->pe_enrelpwr == 0)
+ OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1,
+ AR_PHY_RADAR_1_RELPWR_ENA);
+
+ if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL) {
+ val = OS_REG_READ(ah, AR_PHY_RADAR_1);
+ val &= ~AR_PHY_RADAR_1_MAXLEN;
+ val |= SM(pe->pe_maxlen, AR_PHY_RADAR_1_MAXLEN);
+ OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
+ }
+
+ /*
+ * Enable HT/40 if the upper layer asks;
+ * it should check the channel is HT/40 and HAL_CAP_EXT_CHAN_DFS
+ * is available.
+ */
+ if (pe->pe_extchannel == 1)
+ OS_REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+ else if (pe->pe_extchannel == 0)
+ OS_REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
+}
+
+/*
+ * Extract the radar event information from the given phy error.
+ *
+ * Returns AH_TRUE if the phy error was actually a phy error,
+ * AH_FALSE if the phy error wasn't a phy error.
+ */
+
+/* Flags for pulse_bw_info */
+#define PRI_CH_RADAR_FOUND 0x01
+#define EXT_CH_RADAR_FOUND 0x02
+#define EXT_CH_RADAR_EARLY_FOUND 0x04
+
+HAL_BOOL
+ar5416ProcessRadarEvent(struct ath_hal *ah, struct ath_rx_status *rxs,
+ uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event)
+{
+ HAL_BOOL doDfsExtCh;
+ HAL_BOOL doDfsEnhanced;
+ HAL_BOOL doDfsCombinedRssi;
+
+ uint8_t rssi = 0, ext_rssi = 0;
+ uint8_t pulse_bw_info = 0, pulse_length_ext = 0, pulse_length_pri = 0;
+ uint32_t dur = 0;
+ int pri_found = 1, ext_found = 0;
+ int early_ext = 0;
+ int is_dc = 0;
+ uint16_t datalen; /* length from the RX status field */
+
+ /* Check whether the given phy error is a radar event */
+ if ((rxs->rs_phyerr != HAL_PHYERR_RADAR) &&
+ (rxs->rs_phyerr != HAL_PHYERR_FALSE_RADAR_EXT)) {
+ return AH_FALSE;
+ }
+
+ /* Grab copies of the capabilities; just to make the code clearer */
+ doDfsExtCh = AH_PRIVATE(ah)->ah_caps.halExtChanDfsSupport;
+ doDfsEnhanced = AH_PRIVATE(ah)->ah_caps.halEnhancedDfsSupport;
+ doDfsCombinedRssi = AH_PRIVATE(ah)->ah_caps.halUseCombinedRadarRssi;
+
+ datalen = rxs->rs_datalen;
+
+ /* If hardware supports it, use combined RSSI, else use chain 0 RSSI */
+ if (doDfsCombinedRssi)
+ rssi = (uint8_t) rxs->rs_rssi;
+ else
+ rssi = (uint8_t) rxs->rs_rssi_ctl[0];
+
+ /* Set this; but only use it if doDfsExtCh is set */
+ ext_rssi = (uint8_t) rxs->rs_rssi_ext[0];
+
+ /* Cap it at 0 if the RSSI is a negative number */
+ if (rssi & 0x80)
+ rssi = 0;
+
+ if (ext_rssi & 0x80)
+ ext_rssi = 0;
+
+ /*
+ * Fetch the relevant data from the frame
+ */
+ if (doDfsExtCh) {
+ if (datalen < 3)
+ return AH_FALSE;
+
+ /* Last three bytes of the frame are of interest */
+ pulse_length_pri = *(buf + datalen - 3);
+ pulse_length_ext = *(buf + datalen - 2);
+ pulse_bw_info = *(buf + datalen - 1);
+ HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, ext_rssi=%d, pulse_length_pri=%d,"
+ " pulse_length_ext=%d, pulse_bw_info=%x\n",
+ __func__, rssi, ext_rssi, pulse_length_pri, pulse_length_ext,
+ pulse_bw_info);
+ } else {
+ /* The pulse width is byte 0 of the data */
+ if (datalen >= 1)
+ dur = ((uint8_t) buf[0]) & 0xff;
+ else
+ dur = 0;
+
+ if (dur == 0 && rssi == 0) {
+ HALDEBUG(ah, HAL_DEBUG_DFS, "%s: dur and rssi are 0\n", __func__);
+ return AH_FALSE;
+ }
+
+ HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, dur=%d\n", __func__, rssi, dur);
+
+ /* Single-channel only */
+ pri_found = 1;
+ ext_found = 0;
+ }
+
+ /*
+ * If doing extended channel data, pulse_bw_info must
+ * have one of the flags set.
+ */
+ if (doDfsExtCh && pulse_bw_info == 0x0)
+ return AH_FALSE;
+
+ /*
+ * If the extended channel data is available, calculate
+ * which to pay attention to.
+ */
+ if (doDfsExtCh) {
+ /* If pulse is on DC, take the larger duration of the two */
+ if ((pulse_bw_info & EXT_CH_RADAR_FOUND) &&
+ (pulse_bw_info & PRI_CH_RADAR_FOUND)) {
+ is_dc = 1;
+ if (pulse_length_ext > pulse_length_pri) {
+ dur = pulse_length_ext;
+ pri_found = 0;
+ ext_found = 1;
+ } else {
+ dur = pulse_length_pri;
+ pri_found = 1;
+ ext_found = 0;
+ }
+ } else if (pulse_bw_info & EXT_CH_RADAR_EARLY_FOUND) {
+ dur = pulse_length_ext;
+ pri_found = 0;
+ ext_found = 1;
+ early_ext = 1;
+ } else if (pulse_bw_info & PRI_CH_RADAR_FOUND) {
+ dur = pulse_length_pri;
+ pri_found = 1;
+ ext_found = 0;
+ } else if (pulse_bw_info & EXT_CH_RADAR_FOUND) {
+ dur = pulse_length_ext;
+ pri_found = 0;
+ ext_found = 1;
+ }
+
+ }
+
+ /*
+ * For enhanced DFS (Merlin and later), pulse_bw_info has
+ * implications for selecting the correct RSSI value.
+ */
+ if (doDfsEnhanced) {
+ switch (pulse_bw_info & 0x03) {
+ case 0:
+ /* No radar? */
+ rssi = 0;
+ break;
+ case PRI_CH_RADAR_FOUND:
+ /* Radar in primary channel */
+ /* Cannot use ctrl channel RSSI if ext channel is stronger */
+ if (ext_rssi >= (rssi + 3)) {
+ rssi = 0;
+ };
+ break;
+ case EXT_CH_RADAR_FOUND:
+ /* Radar in extended channel */
+ /* Cannot use ext channel RSSI if ctrl channel is stronger */
+ if (rssi >= (ext_rssi + 12)) {
+ rssi = 0;
+ } else {
+ rssi = ext_rssi;
+ }
+ break;
+ case (PRI_CH_RADAR_FOUND | EXT_CH_RADAR_FOUND):
+ /* When both are present, use stronger one */
+ if (rssi < ext_rssi)
+ rssi = ext_rssi;
+ break;
+ }
+ }
+
+ /*
+ * If not doing enhanced DFS, choose the ext channel if
+ * it is stronger than the main channel
+ */
+ if (doDfsExtCh && !doDfsEnhanced) {
+ if ((ext_rssi > rssi) && (ext_rssi < 128))
+ rssi = ext_rssi;
+ }
+
+ /*
+ * XXX what happens if the above code decides the RSSI
+ * XXX wasn't valid, an sets it to 0?
+ */
+
+ /*
+ * Fill out dfs_event structure.
+ */
+ event->re_full_ts = fulltsf;
+ event->re_ts = rxs->rs_tstamp;
+ event->re_rssi = rssi;
+ event->re_dur = dur;
+
+ event->re_flags = 0;
+ if (pri_found)
+ event->re_flags |= HAL_DFS_EVENT_PRICH;
+ if (ext_found)
+ event->re_flags |= HAL_DFS_EVENT_EXTCH;
+ if (early_ext)
+ event->re_flags |= HAL_DFS_EVENT_EXTEARLY;
+ if (is_dc)
+ event->re_flags |= HAL_DFS_EVENT_ISDC;
+
+ return AH_TRUE;
+}
+
+/*
+ * Return whether fast-clock is currently enabled for this
+ * channel.
+ */
+HAL_BOOL
+ar5416IsFastClockEnabled(struct ath_hal *ah)
+{
+ struct ath_hal_private *ahp = AH_PRIVATE(ah);
+
+ return IS_5GHZ_FAST_CLOCK_EN(ah, ahp->ah_curchan);
+}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ath/ath_rate/sample/sample.c
--- a/head/sys/dev/ath/ath_rate/sample/sample.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ath/ath_rate/sample/sample.c Fri Mar 02 17:36:33 2012 +0200
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ath/ath_rate/sample/sample.c 227371 2011-11-09 04:08:01Z adrian $");
+__FBSDID("$FreeBSD: head/sys/dev/ath/ath_rate/sample/sample.c 232170 2012-02-26 06:04:44Z adrian $");
/*
* John Bicket's SampleRate control algorithm.
@@ -495,6 +495,14 @@
ath_rate_update_static_rix(sc, &an->an_node);
+ if (sn->currates != sc->sc_currates) {
+ device_printf(sc->sc_dev, "%s: currates != sc_currates!\n",
+ __func__);
+ rix = 0;
+ *try0 = ATH_TXMAXTRY;
+ goto done;
+ }
+
if (sn->static_rix != -1) {
rix = sn->static_rix;
*try0 = ATH_TXMAXTRY;
@@ -621,6 +629,20 @@
}
*try0 = mrr ? sn->sched[rix].t0 : ATH_TXMAXTRY;
done:
+
+ /*
+ * This bug totally sucks and should be fixed.
+ *
+ * For now though, let's not panic, so we can start to figure
+ * out how to better reproduce it.
+ */
+ if (rix < 0 || rix >= rt->rateCount) {
+ printf("%s: ERROR: rix %d out of bounds (rateCount=%d)\n",
+ __func__,
+ rix,
+ rt->rateCount);
+ rix = 0; /* XXX just default for now */
+ }
KASSERT(rix >= 0 && rix < rt->rateCount, ("rix is %d", rix));
*rix0 = rix;
@@ -1073,6 +1095,8 @@
sn->static_rix = -1;
ath_rate_update_static_rix(sc, ni);
+ sn->currates = sc->sc_currates;
+
/*
* Construct a bitmask of usable rates. This has all
* negotiated rates minus those marked by the hal as
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ath/ath_rate/sample/sample.h
--- a/head/sys/dev/ath/ath_rate/sample/sample.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ath/ath_rate/sample/sample.h Fri Mar 02 17:36:33 2012 +0200
@@ -33,7 +33,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
- * $FreeBSD: head/sys/dev/ath/ath_rate/sample/sample.h 227364 2011-11-08 22:43:13Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_rate/sample/sample.h 232170 2012-02-26 06:04:44Z adrian $
*/
/*
@@ -86,6 +86,8 @@
uint32_t ratemask; /* bit mask of valid rate indices */
const struct txschedule *sched; /* tx schedule table */
+ const HAL_RATE_TABLE *currates;
+
struct rate_stats stats[NUM_PACKET_SIZE_BINS][SAMPLE_MAXRATES];
int last_sample_rix[NUM_PACKET_SIZE_BINS];
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ath/if_ath.c
--- a/head/sys/dev/ath/if_ath.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ath/if_ath.c Fri Mar 02 17:36:33 2012 +0200
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 230846 2012-01-31 22:27:35Z adrian $");
+__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 232375 2012-03-02 03:11:53Z adrian $");
/*
* Driver for the Atheros Wireless LAN controller.
@@ -159,6 +159,7 @@
static struct ath_buf *ath_beacon_generate(struct ath_softc *,
struct ieee80211vap *);
static void ath_bstuck_proc(void *, int);
+static void ath_reset_proc(void *, int);
static void ath_beacon_return(struct ath_softc *, struct ath_buf *);
static void ath_beacon_free(struct ath_softc *);
static void ath_beacon_config(struct ath_softc *, struct ieee80211vap *);
@@ -284,6 +285,7 @@
int error = 0, i;
u_int wmodes;
uint8_t macaddr[IEEE80211_ADDR_LEN];
+ int rx_chainmask, tx_chainmask;
DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid);
@@ -391,6 +393,7 @@
TASK_INIT(&sc->sc_rxtask, 0, ath_rx_tasklet, sc);
TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc);
TASK_INIT(&sc->sc_bstucktask,0, ath_bstuck_proc, sc);
+ TASK_INIT(&sc->sc_resettask,0, ath_reset_proc, sc);
/*
* Allocate hardware transmit queues: one queue for
@@ -634,6 +637,29 @@
#endif
/*
+ * Allow the TX and RX chainmasks to be overridden by
+ * environment variables and/or device.hints.
+ *
+ * This must be done early - before the hardware is
+ * calibrated or before the 802.11n stream calculation
+ * is done.
+ */
+ if (resource_int_value(device_get_name(sc->sc_dev),
+ device_get_unit(sc->sc_dev), "rx_chainmask",
+ &rx_chainmask) == 0) {
+ device_printf(sc->sc_dev, "Setting RX chainmask to 0x%x\n",
+ rx_chainmask);
+ (void) ath_hal_setrxchainmask(sc->sc_ah, rx_chainmask);
+ }
+ if (resource_int_value(device_get_name(sc->sc_dev),
+ device_get_unit(sc->sc_dev), "tx_chainmask",
+ &tx_chainmask) == 0) {
+ device_printf(sc->sc_dev, "Setting TX chainmask to 0x%x\n",
+ tx_chainmask);
+ (void) ath_hal_settxchainmask(sc->sc_ah, tx_chainmask);
+ }
+
+ /*
* The if_ath 11n support is completely not ready for normal use.
* Enabling this option will likely break everything and everything.
* Don't think of doing that unless you know what you're doing.
@@ -1645,6 +1671,7 @@
struct ath_softc *sc = ifp->if_softc;
u_int64_t lastrx = sc->sc_lastrx;
u_int64_t tsf = ath_hal_gettsf64(sc->sc_ah);
+ /* XXX should take a locked ref to iv_bss */
u_int bmisstimeout =
vap->iv_bmissthreshold * vap->iv_bss->ni_intval * 1024;
@@ -1878,15 +1905,13 @@
#define MAX_TXRX_ITERATIONS 1000
static void
-ath_txrx_stop(struct ath_softc *sc)
+ath_txrx_stop_locked(struct ath_softc *sc)
{
int i = MAX_TXRX_ITERATIONS;
ATH_UNLOCK_ASSERT(sc);
- /* Stop any new TX/RX from occuring */
- taskqueue_block(sc->sc_tq);
-
- ATH_PCU_LOCK(sc);
+ ATH_PCU_LOCK_ASSERT(sc);
+
/*
* Sleep until all the pending operations have completed.
*
@@ -1900,7 +1925,6 @@
msleep(sc, &sc->sc_pcu_mtx, 0, "ath_txrx_stop", 1);
i--;
}
- ATH_PCU_UNLOCK(sc);
if (i <= 0)
device_printf(sc->sc_dev,
@@ -1909,6 +1933,19 @@
}
#undef MAX_TXRX_ITERATIONS
+#if 0
+static void
+ath_txrx_stop(struct ath_softc *sc)
+{
+ ATH_UNLOCK_ASSERT(sc);
+ ATH_PCU_UNLOCK_ASSERT(sc);
+
+ ATH_PCU_LOCK(sc);
+ ath_txrx_stop_locked(sc);
+ ATH_PCU_UNLOCK(sc);
+}
+#endif
+
static void
ath_txrx_start(struct ath_softc *sc)
{
@@ -2012,12 +2049,16 @@
ATH_PCU_UNLOCK_ASSERT(sc);
ATH_UNLOCK_ASSERT(sc);
+ /* Try to (stop any further TX/RX from occuring */
+ taskqueue_block(sc->sc_tq);
+
ATH_PCU_LOCK(sc);
+ ath_hal_intrset(ah, 0); /* disable interrupts */
+ ath_txrx_stop_locked(sc); /* Ensure TX/RX is stopped */
if (ath_reset_grablock(sc, 1) == 0) {
device_printf(sc->sc_dev, "%s: concurrent reset! Danger!\n",
__func__);
}
- ath_hal_intrset(ah, 0); /* disable interrupts */
ATH_PCU_UNLOCK(sc);
/*
@@ -2025,7 +2066,6 @@
* and block future ones from occuring. This needs to be
* done before the TX queue is drained.
*/
- ath_txrx_stop(sc);
ath_draintxq(sc, reset_type); /* stop xmit side */
/*
@@ -3125,6 +3165,23 @@
}
/*
+ * Reset the hardware, with no loss.
+ *
+ * This can't be used for a general case reset.
+ */
+static void
+ath_reset_proc(void *arg, int pending)
+{
+ struct ath_softc *sc = arg;
+ struct ifnet *ifp = sc->sc_ifp;
+
+#if 0
+ if_printf(ifp, "%s: resetting\n", __func__);
+#endif
+ ath_reset(ifp, ATH_RESET_NOLOSS);
+}
+
+/*
* Reset the hardware after detecting beacons have stopped.
*/
static void
@@ -3221,7 +3278,7 @@
if (vap == NULL)
vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */
- ni = vap->iv_bss;
+ ni = ieee80211_ref_node(vap->iv_bss);
/* extract tstamp from last beacon and convert to TU */
nexttbtt = TSF_TO_TU(LE_READ_4(ni->ni_tstamp.data + 4),
@@ -3391,6 +3448,7 @@
ath_beacon_start_adhoc(sc, vap);
}
sc->sc_syncbeacon = 0;
+ ieee80211_free_node(ni);
#undef FUDGE
#undef TSF_TO_TU
}
@@ -3829,6 +3887,7 @@
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_BEACON:
/* update rssi statistics for use by the hal */
+ /* XXX unlocked check against vap->iv_bss? */
ATH_RSSI_LPF(sc->sc_halstats.ns_avgbrssi, rssi);
if (sc->sc_syncbeacon &&
ni == vap->iv_bss && vap->iv_state == IEEE80211_S_RUN) {
@@ -5345,21 +5404,22 @@
struct ieee80211com *ic = ifp->if_l2com;
struct ath_hal *ah = sc->sc_ah;
int ret = 0;
- int dointr = 0;
/* Treat this as an interface reset */
+ ATH_PCU_UNLOCK_ASSERT(sc);
+ ATH_UNLOCK_ASSERT(sc);
+
+ /* (Try to) stop TX/RX from occuring */
+ taskqueue_block(sc->sc_tq);
+
ATH_PCU_LOCK(sc);
+ ath_hal_intrset(ah, 0); /* Stop new RX/TX completion */
+ ath_txrx_stop_locked(sc); /* Stop pending RX/TX completion */
if (ath_reset_grablock(sc, 1) == 0) {
device_printf(sc->sc_dev, "%s: concurrent reset! Danger!\n",
__func__);
}
- if (chan != sc->sc_curchan) {
- dointr = 1;
- /* XXX only do this if inreset_cnt is 1? */
- ath_hal_intrset(ah, 0);
- }
ATH_PCU_UNLOCK(sc);
- ath_txrx_stop(sc);
DPRINTF(sc, ATH_DEBUG_RESET, "%s: %u (%u MHz, flags 0x%x)\n",
__func__, ieee80211_chan2ieee(ic, chan),
@@ -5397,7 +5457,7 @@
sc->sc_diversity = ath_hal_getdiversity(ah);
/* Let DFS at it in case it's a DFS channel */
- ath_dfs_radar_enable(sc, ic->ic_curchan);
+ ath_dfs_radar_enable(sc, chan);
/*
* Re-enable rx framework.
@@ -5428,10 +5488,10 @@
ath_beacon_config(sc, NULL);
}
-#if 0
/*
* Re-enable interrupts.
*/
+#if 0
ath_hal_intrset(ah, sc->sc_imask);
#endif
}
@@ -5440,8 +5500,7 @@
ATH_PCU_LOCK(sc);
sc->sc_inreset_cnt--;
/* XXX only do this if sc_inreset_cnt == 0? */
- if (dointr)
- ath_hal_intrset(ah, sc->sc_imask);
+ ath_hal_intrset(ah, sc->sc_imask);
ATH_PCU_UNLOCK(sc);
/* XXX do this inside of IF_LOCK? */
@@ -5492,18 +5551,10 @@
DPRINTF(sc, ATH_DEBUG_CALIBRATE,
"%s: rfgain change\n", __func__);
sc->sc_stats.ast_per_rfgain++;
- /*
- * Drop lock - we can't hold it across the
- * ath_reset() call. Instead, we'll drop
- * out here, do a reset, then reschedule
- * the callout.
- */
- callout_reset(&sc->sc_cal_ch, 1, ath_calibrate, sc);
sc->sc_resetcal = 0;
sc->sc_doresetcal = AH_TRUE;
- ATH_UNLOCK(sc);
- ath_reset(ifp, ATH_RESET_NOLOSS);
- ATH_LOCK(sc);
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_resettask);
+ callout_reset(&sc->sc_cal_ch, 1, ath_calibrate, sc);
return;
}
/*
@@ -5586,11 +5637,16 @@
/* XXX calibration timer? */
+ ATH_LOCK(sc);
sc->sc_scanning = 1;
sc->sc_syncbeacon = 0;
rfilt = ath_calcrxfilter(sc);
+ ATH_UNLOCK(sc);
+
+ ATH_PCU_LOCK(sc);
ath_hal_setrxfilter(ah, rfilt);
ath_hal_setassocid(ah, ifp->if_broadcastaddr, 0);
+ ATH_PCU_UNLOCK(sc);
DPRINTF(sc, ATH_DEBUG_STATE, "%s: RX filter 0x%x bssid %s aid 0\n",
__func__, rfilt, ether_sprintf(ifp->if_broadcastaddr));
@@ -5604,12 +5660,17 @@
struct ath_hal *ah = sc->sc_ah;
u_int32_t rfilt;
+ ATH_LOCK(sc);
sc->sc_scanning = 0;
rfilt = ath_calcrxfilter(sc);
+ ATH_UNLOCK(sc);
+
+ ATH_PCU_LOCK(sc);
ath_hal_setrxfilter(ah, rfilt);
ath_hal_setassocid(ah, sc->sc_curbssid, sc->sc_curaid);
ath_hal_process_noisefloor(ah);
+ ATH_PCU_UNLOCK(sc);
DPRINTF(sc, ATH_DEBUG_STATE, "%s: RX filter 0x%x bssid %s aid 0x%x\n",
__func__, rfilt, ether_sprintf(sc->sc_curbssid),
@@ -5629,8 +5690,10 @@
* beacon timers. Note that since we only hear beacons in
* sta/ibss mode this has no effect in other operating modes.
*/
+ ATH_LOCK(sc);
if (!sc->sc_scanning && ic->ic_curchan == ic->ic_bsschan)
sc->sc_syncbeacon = 1;
+ ATH_UNLOCK(sc);
}
/*
@@ -5677,6 +5740,15 @@
ieee80211_state_name[vap->iv_state],
ieee80211_state_name[nstate]);
+ /*
+ * net80211 _should_ have the comlock asserted at this point.
+ * There are some comments around the calls to vap->iv_newstate
+ * which indicate that it (newstate) may end up dropping the
+ * lock. This and the subsequent lock assert check after newstate
+ * are an attempt to catch these and figure out how/why.
+ */
+ IEEE80211_LOCK_ASSERT(ic);
+
if (vap->iv_state == IEEE80211_S_CSA && nstate == IEEE80211_S_RUN)
csa_run_transition = 1;
@@ -5697,7 +5769,7 @@
taskqueue_unblock(sc->sc_tq);
}
- ni = vap->iv_bss;
+ ni = ieee80211_ref_node(vap->iv_bss);
rfilt = ath_calcrxfilter(sc);
stamode = (vap->iv_opmode == IEEE80211_M_STA ||
vap->iv_opmode == IEEE80211_M_AHDEMO ||
@@ -5726,9 +5798,16 @@
if (error != 0)
goto bad;
+ /*
+ * See above: ensure av_newstate() doesn't drop the lock
+ * on us.
+ */
+ IEEE80211_LOCK_ASSERT(ic);
+
if (nstate == IEEE80211_S_RUN) {
/* NB: collect bss node again, it may have changed */
- ni = vap->iv_bss;
+ ieee80211_free_node(ni);
+ ni = ieee80211_ref_node(vap->iv_bss);
DPRINTF(sc, ATH_DEBUG_STATE,
"%s(RUN): iv_flags 0x%08x bintvl %d bssid %s "
@@ -5851,6 +5930,7 @@
#endif
}
bad:
+ ieee80211_free_node(ni);
return error;
}
@@ -5869,6 +5949,7 @@
struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
ieee80211_keyix keyix, rxkeyix;
+ /* XXX should take a locked ref to vap->iv_bss */
if (!ath_key_alloc(vap, &ni->ni_ucastkey, &keyix, &rxkeyix)) {
/*
* Key cache is full; we'll fall back to doing
@@ -6135,11 +6216,12 @@
/*
* We can't hold the lock across the ath_reset() call.
+ *
+ * And since this routine can't hold a lock and sleep,
+ * do the reset deferred.
*/
if (do_reset) {
- ATH_UNLOCK(sc);
- ath_reset(sc->sc_ifp, ATH_RESET_NOLOSS);
- ATH_LOCK(sc);
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_resettask);
}
callout_schedule(&sc->sc_wd_ch, hz);
@@ -6424,6 +6506,7 @@
return;
}
}
+ /* XXX should take a locked ref to iv_bss */
tp = vap->iv_bss->ni_txparms;
/*
* Calculate the guard time for each slot. This is the
@@ -6673,6 +6756,7 @@
* Record local TSF for our last send for use
* in arbitrating slot collisions.
*/
+ /* XXX should take a locked ref to iv_bss */
vap->iv_bss->ni_tstamp.tsf = ath_hal_gettsf64(ah);
}
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ath/if_ath_sysctl.c
--- a/head/sys/dev/ath/if_ath_sysctl.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ath/if_ath_sysctl.c Fri Mar 02 17:36:33 2012 +0200
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_sysctl.c 228891 2011-12-26 07:47:05Z adrian $");
+__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_sysctl.c 232250 2012-02-28 13:19:34Z gavin $");
/*
* Driver for the Atheros Wireless LAN controller.
@@ -912,7 +912,7 @@
sc->sc_ah->ah_config.ah_ar5416_biasadj = 0;
SYSCTL_ADD_INT(ctx, child, OID_AUTO, "ar5416_biasadj", CTLFLAG_RW,
&sc->sc_ah->ah_config.ah_ar5416_biasadj, 0,
- "Enable 2ghz AR5416 direction sensitivity bias adjust");
+ "Enable 2GHz AR5416 direction sensitivity bias adjust");
sc->sc_ah->ah_config.ah_dma_beacon_response_time = 2;
SYSCTL_ADD_INT(ctx, child, OID_AUTO, "dma_brt", CTLFLAG_RW,
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ath/if_athvar.h
--- a/head/sys/dev/ath/if_athvar.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ath/if_athvar.h Fri Mar 02 17:36:33 2012 +0200
@@ -26,7 +26,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
- * $FreeBSD: head/sys/dev/ath/if_athvar.h 230493 2012-01-24 06:12:48Z adrian $
+ * $FreeBSD: head/sys/dev/ath/if_athvar.h 232163 2012-02-25 19:12:54Z adrian $
*/
/*
@@ -501,6 +501,7 @@
struct ath_txq *sc_cabq; /* tx q for cab frames */
struct task sc_bmisstask; /* bmiss int processing */
struct task sc_bstucktask; /* stuck beacon processing */
+ struct task sc_resettask; /* interface reset task */
enum {
OK, /* no change needed */
UPDATE, /* update pending */
@@ -888,6 +889,10 @@
(ath_hal_getcapability(_ah, HAL_CAP_RX_CHAINMASK, 0, _prxchainmask))
#define ath_hal_gettxchainmask(_ah, _ptxchainmask) \
(ath_hal_getcapability(_ah, HAL_CAP_TX_CHAINMASK, 0, _ptxchainmask))
+#define ath_hal_setrxchainmask(_ah, _rx) \
+ (ath_hal_setcapability(_ah, HAL_CAP_RX_CHAINMASK, 1, _rx, NULL))
+#define ath_hal_settxchainmask(_ah, _tx) \
+ (ath_hal_setcapability(_ah, HAL_CAP_TX_CHAINMASK, 1, _tx, NULL))
#define ath_hal_split4ktrans(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_SPLIT_4KB_TRANS, \
0, NULL) == HAL_OK)
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/bge/if_bge.c
--- a/head/sys/dev/bge/if_bge.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/bge/if_bge.c Fri Mar 02 17:36:33 2012 +0200
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/bge/if_bge.c 230338 2012-01-19 20:28:58Z yongari $");
+__FBSDID("$FreeBSD: head/sys/dev/bge/if_bge.c 231159 2012-02-07 20:24:52Z marius $");
/*
* Broadcom BCM570x family gigabit ethernet driver for FreeBSD.
@@ -2786,6 +2786,8 @@
sc = device_get_softc(dev);
sc->bge_dev = dev;
+ bge_add_sysctls(sc);
+
TASK_INIT(&sc->bge_intr_task, 0, bge_intr_task, sc);
/*
@@ -3198,8 +3200,6 @@
goto fail;
}
- bge_add_sysctls(sc);
-
/* Set default tuneable values. */
sc->bge_stat_ticks = BGE_TICKS_PER_SEC;
sc->bge_rx_coal_ticks = 150;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/cxgb/cxgb_adapter.h
--- a/head/sys/dev/cxgb/cxgb_adapter.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/cxgb/cxgb_adapter.h Fri Mar 02 17:36:33 2012 +0200
@@ -25,7 +25,7 @@
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-$FreeBSD$
+$FreeBSD: head/sys/dev/cxgb/cxgb_adapter.h 231116 2012-02-07 07:32:39Z np $
***************************************************************************/
@@ -572,5 +572,4 @@
void cxgb_tx_watchdog(void *arg);
int cxgb_transmit(struct ifnet *ifp, struct mbuf *m);
void cxgb_qflush(struct ifnet *ifp);
-void cxgb_start(struct ifnet *ifp);
#endif
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/cxgb/cxgb_main.c
--- a/head/sys/dev/cxgb/cxgb_main.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/cxgb/cxgb_main.c Fri Mar 02 17:36:33 2012 +0200
@@ -28,7 +28,7 @@
***************************************************************************/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/cxgb/cxgb_main.c 227843 2011-11-22 21:28:20Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/cxgb/cxgb_main.c 231317 2012-02-09 23:19:09Z np $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -227,14 +227,6 @@
SYSCTL_INT(_hw_cxgb, OID_AUTO, use_16k_clusters, CTLFLAG_RDTUN,
&cxgb_use_16k_clusters, 0, "use 16kB clusters for the jumbo queue ");
-/*
- * Tune the size of the output queue.
- */
-int cxgb_snd_queue_len = IFQ_MAXLEN;
-TUNABLE_INT("hw.cxgb.snd_queue_len", &cxgb_snd_queue_len);
-SYSCTL_INT(_hw_cxgb, OID_AUTO, snd_queue_len, CTLFLAG_RDTUN,
- &cxgb_snd_queue_len, 0, "send queue size ");
-
static int nfilters = -1;
TUNABLE_INT("hw.cxgb.nfilters", &nfilters);
SYSCTL_INT(_hw_cxgb, OID_AUTO, nfilters, CTLFLAG_RDTUN,
@@ -481,15 +473,6 @@
device_printf(dev, "Cannot allocate BAR region 0\n");
return (ENXIO);
}
- sc->udbs_rid = PCIR_BAR(2);
- sc->udbs_res = NULL;
- if (is_offload(sc) &&
- ((sc->udbs_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
- &sc->udbs_rid, RF_ACTIVE)) == NULL)) {
- device_printf(dev, "Cannot allocate BAR region 1\n");
- error = ENXIO;
- goto out;
- }
snprintf(sc->lockbuf, ADAPTER_LOCK_NAME_LEN, "cxgb controller lock %d",
device_get_unit(dev));
@@ -518,6 +501,17 @@
error = ENODEV;
goto out;
}
+
+ sc->udbs_rid = PCIR_BAR(2);
+ sc->udbs_res = NULL;
+ if (is_offload(sc) &&
+ ((sc->udbs_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &sc->udbs_rid, RF_ACTIVE)) == NULL)) {
+ device_printf(dev, "Cannot allocate BAR region 1\n");
+ error = ENXIO;
+ goto out;
+ }
+
/* Allocate the BAR for doing MSI-X. If it succeeds, try to allocate
* enough messages for the queue sets. If that fails, try falling
* back to MSI. If that fails, then try falling back to the legacy
@@ -988,7 +982,7 @@
#define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | \
IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO | \
IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE)
-#define CXGB_CAP_ENABLE (CXGB_CAP & ~IFCAP_TSO6)
+#define CXGB_CAP_ENABLE CXGB_CAP
static int
cxgb_port_attach(device_t dev)
@@ -1019,11 +1013,8 @@
ifp->if_softc = p;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = cxgb_ioctl;
- ifp->if_start = cxgb_start;
-
- ifp->if_snd.ifq_drv_maxlen = max(cxgb_snd_queue_len, ifqmaxlen);
- IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
- IFQ_SET_READY(&ifp->if_snd);
+ ifp->if_transmit = cxgb_transmit;
+ ifp->if_qflush = cxgb_qflush;
ifp->if_capabilities = CXGB_CAP;
ifp->if_capenable = CXGB_CAP_ENABLE;
@@ -1039,8 +1030,6 @@
}
ether_ifattach(ifp, p->hw_addr);
- ifp->if_transmit = cxgb_transmit;
- ifp->if_qflush = cxgb_qflush;
#ifdef DEFAULT_JUMBO
if (sc->params.nports <= 2)
@@ -2070,8 +2059,8 @@
}
if (mask & IFCAP_RXCSUM)
ifp->if_capenable ^= IFCAP_RXCSUM;
- if (mask & IFCAP_TSO4) {
- ifp->if_capenable ^= IFCAP_TSO4;
+ if (mask & IFCAP_TSO) {
+ ifp->if_capenable ^= IFCAP_TSO;
if (IFCAP_TSO & ifp->if_capenable) {
if (IFCAP_TXCSUM & ifp->if_capenable)
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/cxgb/cxgb_sge.c
--- a/head/sys/dev/cxgb/cxgb_sge.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/cxgb/cxgb_sge.c Fri Mar 02 17:36:33 2012 +0200
@@ -28,7 +28,7 @@
***************************************************************************/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/cxgb/cxgb_sge.c 231317 2012-02-09 23:19:09Z np $");
#include "opt_inet.h"
@@ -62,6 +62,7 @@
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
+#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <dev/pci/pcireg.h>
@@ -1492,10 +1493,10 @@
check_ring_tx_db(sc, txq, 0);
return (0);
} else if (tso_info) {
- int eth_type;
+ uint16_t eth_type;
struct cpl_tx_pkt_lso *hdr = (struct cpl_tx_pkt_lso *)txd;
struct ether_header *eh;
- struct ip *ip;
+ void *l3hdr;
struct tcphdr *tcp;
txd->flit[2] = 0;
@@ -1521,18 +1522,37 @@
}
eh = mtod(m0, struct ether_header *);
- if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
- eth_type = CPL_ETH_II_VLAN;
- ip = (struct ip *)((struct ether_vlan_header *)eh + 1);
+ eth_type = eh->ether_type;
+ if (eth_type == htons(ETHERTYPE_VLAN)) {
+ struct ether_vlan_header *evh = (void *)eh;
+
+ tso_info |= V_LSO_ETH_TYPE(CPL_ETH_II_VLAN);
+ l3hdr = evh + 1;
+ eth_type = evh->evl_proto;
} else {
- eth_type = CPL_ETH_II;
- ip = (struct ip *)(eh + 1);
+ tso_info |= V_LSO_ETH_TYPE(CPL_ETH_II);
+ l3hdr = eh + 1;
}
- tcp = (struct tcphdr *)(ip + 1);
-
- tso_info |= V_LSO_ETH_TYPE(eth_type) |
- V_LSO_IPHDR_WORDS(ip->ip_hl) |
- V_LSO_TCPHDR_WORDS(tcp->th_off);
+
+ if (eth_type == htons(ETHERTYPE_IP)) {
+ struct ip *ip = l3hdr;
+
+ tso_info |= V_LSO_IPHDR_WORDS(ip->ip_hl);
+ tcp = (struct tcphdr *)(ip + 1);
+ } else if (eth_type == htons(ETHERTYPE_IPV6)) {
+ struct ip6_hdr *ip6 = l3hdr;
+
+ KASSERT(ip6->ip6_nxt == IPPROTO_TCP,
+ ("%s: CSUM_TSO with ip6_nxt %d",
+ __func__, ip6->ip6_nxt));
+
+ tso_info |= F_LSO_IPV6;
+ tso_info |= V_LSO_IPHDR_WORDS(sizeof(*ip6) >> 2);
+ tcp = (struct tcphdr *)(ip6 + 1);
+ } else
+ panic("%s: CSUM_TSO but neither ip nor ip6", __func__);
+
+ tso_info |= V_LSO_TCPHDR_WORDS(tcp->th_off);
hdr->lso_info = htonl(tso_info);
if (__predict_false(mlen <= PIO_LEN)) {
@@ -1767,19 +1787,6 @@
error = drbr_enqueue(ifp, qs->txq[TXQ_ETH].txq_mr, m);
return (error);
}
-void
-cxgb_start(struct ifnet *ifp)
-{
- struct port_info *pi = ifp->if_softc;
- struct sge_qset *qs = &pi->adapter->sge.qs[pi->first_qset];
-
- if (!pi->link_config.link_ok)
- return;
-
- TXQ_LOCK(qs);
- cxgb_start_locked(qs);
- TXQ_UNLOCK(qs);
-}
void
cxgb_qflush(struct ifnet *ifp)
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/cxgbe/adapter.h
--- a/head/sys/dev/cxgbe/adapter.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/cxgbe/adapter.h Fri Mar 02 17:36:33 2012 +0200
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/dev/cxgbe/adapter.h 228561 2011-12-16 02:09:51Z np $
+ * $FreeBSD: head/sys/dev/cxgbe/adapter.h 231115 2012-02-07 06:21:59Z np $
*
*/
@@ -66,6 +66,17 @@
#define prefetch(x)
#endif
+#ifndef SYSCTL_ADD_UQUAD
+#define SYSCTL_ADD_UQUAD SYSCTL_ADD_QUAD
+#define sysctl_handle_64 sysctl_handle_quad
+#define CTLTYPE_U64 CTLTYPE_QUAD
+#endif
+
+#if (__FreeBSD_version >= 900030) || \
+ ((__FreeBSD_version >= 802507) && (__FreeBSD_version < 900000))
+#define SBUF_DRAIN 1
+#endif
+
#ifdef __amd64__
/* XXX: need systemwide bus_space_read_8/bus_space_write_8 */
static __inline uint64_t
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/cxgbe/common/t4_hw.c
--- a/head/sys/dev/cxgbe/common/t4_hw.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/cxgbe/common/t4_hw.c Fri Mar 02 17:36:33 2012 +0200
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/cxgbe/common/t4_hw.c 228561 2011-12-16 02:09:51Z np $");
+__FBSDID("$FreeBSD: head/sys/dev/cxgbe/common/t4_hw.c 231592 2012-02-13 18:41:32Z np $");
#include "common.h"
#include "t4_regs.h"
@@ -4314,7 +4314,7 @@
V_FW_VI_MAC_CMD_IDX(idx));
memcpy(p->macaddr, addr, sizeof(p->macaddr));
- ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+ ret = t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), &c);
if (ret == 0) {
ret = G_FW_VI_MAC_CMD_IDX(ntohs(p->valid_to_idx));
if (ret >= FW_CLS_TCAM_NUM_ENTRIES)
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/cxgbe/t4_l2t.c
--- a/head/sys/dev/cxgbe/t4_l2t.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/cxgbe/t4_l2t.c Fri Mar 02 17:36:33 2012 +0200
@@ -24,7 +24,7 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/cxgbe/t4_l2t.c 228561 2011-12-16 02:09:51Z np $");
+__FBSDID("$FreeBSD: head/sys/dev/cxgbe/t4_l2t.c 231115 2012-02-07 06:21:59Z np $");
#include "opt_inet.h"
@@ -259,6 +259,7 @@
return (0);
}
+#ifdef SBUF_DRAIN
static inline unsigned int
vlan_prio(const struct l2t_entry *e)
{
@@ -333,6 +334,7 @@
return (rc);
}
+#endif
#ifndef TCP_OFFLOAD_DISABLE
static inline void
@@ -652,6 +654,11 @@
} else
return (NULL);
+#ifndef VLAN_TAG
+ if (ifp->if_type == IFT_L2VLAN)
+ return (NULL);
+#endif
+
hash = addr_hash(addr, addr_len, ifp->if_index);
rw_wlock(&d->lock);
@@ -678,10 +685,12 @@
e->v6 = (addr_len == 16);
e->lle = NULL;
atomic_store_rel_int(&e->refcnt, 1);
+#ifdef VLAN_TAG
if (ifp->if_type == IFT_L2VLAN)
VLAN_TAG(ifp, &e->vlan);
else
e->vlan = VLAN_NONE;
+#endif
e->next = d->l2tab[hash].first;
d->l2tab[hash].first = e;
mtx_unlock(&e->lock);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/cxgbe/t4_l2t.h
--- a/head/sys/dev/cxgbe/t4_l2t.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/cxgbe/t4_l2t.h Fri Mar 02 17:36:33 2012 +0200
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/dev/cxgbe/t4_l2t.h 228561 2011-12-16 02:09:51Z np $
+ * $FreeBSD: head/sys/dev/cxgbe/t4_l2t.h 231115 2012-02-07 06:21:59Z np $
*
*/
@@ -67,7 +67,9 @@
int t4_l2t_set_switching(struct adapter *, struct l2t_entry *, uint16_t,
uint8_t, uint8_t *);
void t4_l2t_release(struct l2t_entry *);
+#ifdef SBUF_DRAIN
int sysctl_l2t(SYSCTL_HANDLER_ARGS);
+#endif
#ifndef TCP_OFFLOAD_DISABLE
struct l2t_entry *t4_l2t_get(struct port_info *, struct ifnet *,
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/cxgbe/t4_main.c
--- a/head/sys/dev/cxgbe/t4_main.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/cxgbe/t4_main.c Fri Mar 02 17:36:33 2012 +0200
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/cxgbe/t4_main.c 228561 2011-12-16 02:09:51Z np $");
+__FBSDID("$FreeBSD: head/sys/dev/cxgbe/t4_main.c 231172 2012-02-08 00:36:36Z np $");
#include "opt_inet.h"
@@ -112,7 +112,6 @@
/* ifnet + media interface */
static void cxgbe_init(void *);
static int cxgbe_ioctl(struct ifnet *, unsigned long, caddr_t);
-static void cxgbe_start(struct ifnet *);
static int cxgbe_transmit(struct ifnet *, struct mbuf *);
static void cxgbe_qflush(struct ifnet *);
static int cxgbe_media_change(struct ifnet *);
@@ -309,6 +308,7 @@
static int sysctl_qsize_rxq(SYSCTL_HANDLER_ARGS);
static int sysctl_qsize_txq(SYSCTL_HANDLER_ARGS);
static int sysctl_handle_t4_reg64(SYSCTL_HANDLER_ARGS);
+#ifdef SBUF_DRAIN
static int sysctl_cctrl(SYSCTL_HANDLER_ARGS);
static int sysctl_cpl_stats(SYSCTL_HANDLER_ARGS);
static int sysctl_ddp_stats(SYSCTL_HANDLER_ARGS);
@@ -324,6 +324,7 @@
static int sysctl_tids(SYSCTL_HANDLER_ARGS);
static int sysctl_tp_err_stats(SYSCTL_HANDLER_ARGS);
static int sysctl_tx_rate(SYSCTL_HANDLER_ARGS);
+#endif
static inline void txq_start(struct ifnet *, struct sge_txq *);
static uint32_t fconf_to_mode(uint32_t);
static uint32_t mode_to_fconf(uint32_t);
@@ -827,14 +828,9 @@
ifp->if_init = cxgbe_init;
ifp->if_ioctl = cxgbe_ioctl;
- ifp->if_start = cxgbe_start;
ifp->if_transmit = cxgbe_transmit;
ifp->if_qflush = cxgbe_qflush;
- ifp->if_snd.ifq_drv_maxlen = 1024;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
- IFQ_SET_READY(&ifp->if_snd);
-
ifp->if_capabilities = T4_CAP;
#ifndef TCP_OFFLOAD_DISABLE
if (is_offload(pi->adapter))
@@ -1093,21 +1089,6 @@
return (rc);
}
-static void
-cxgbe_start(struct ifnet *ifp)
-{
- struct port_info *pi = ifp->if_softc;
- struct sge_txq *txq;
- int i;
-
- for_each_txq(pi, i, txq) {
- if (TXQ_TRYLOCK(txq)) {
- txq_start(ifp, txq);
- TXQ_UNLOCK(txq);
- }
- }
-}
-
static int
cxgbe_transmit(struct ifnet *ifp, struct mbuf *m)
{
@@ -2032,6 +2013,8 @@
PORT_UNLOCK(pi);
}
+#define FW_MAC_EXACT_CHUNK 7
+
/*
* Program the port's XGMAC based on parameters in ifnet. The caller also
* indicates which parameters should be programmed (the rest are left alone).
@@ -2083,28 +2066,57 @@
}
if (flags & XGMAC_MCADDRS) {
- const uint8_t *mcaddr;
+ const uint8_t *mcaddr[FW_MAC_EXACT_CHUNK];
int del = 1;
uint64_t hash = 0;
struct ifmultiaddr *ifma;
+ int i = 0, j;
if_maddr_rlock(ifp);
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
+ if (ifma->ifma_addr->sa_family == AF_LINK)
continue;
- mcaddr = LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
-
- rc = t4_alloc_mac_filt(sc, sc->mbox, pi->viid, del, 1,
- &mcaddr, NULL, &hash, 0);
+ mcaddr[i++] =
+ LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
+
+ if (i == FW_MAC_EXACT_CHUNK) {
+ rc = t4_alloc_mac_filt(sc, sc->mbox, pi->viid,
+ del, i, mcaddr, NULL, &hash, 0);
+ if (rc < 0) {
+ rc = -rc;
+ for (j = 0; j < i; j++) {
+ if_printf(ifp,
+ "failed to add mc address"
+ " %02x:%02x:%02x:"
+ "%02x:%02x:%02x rc=%d\n",
+ mcaddr[j][0], mcaddr[j][1],
+ mcaddr[j][2], mcaddr[j][3],
+ mcaddr[j][4], mcaddr[j][5],
+ rc);
+ }
+ goto mcfail;
+ }
+ del = 0;
+ i = 0;
+ }
+ }
+ if (i > 0) {
+ rc = t4_alloc_mac_filt(sc, sc->mbox, pi->viid,
+ del, i, mcaddr, NULL, &hash, 0);
if (rc < 0) {
rc = -rc;
- if_printf(ifp, "failed to add mc address"
- " %02x:%02x:%02x:%02x:%02x:%02x rc=%d\n",
- mcaddr[0], mcaddr[1], mcaddr[2], mcaddr[3],
- mcaddr[4], mcaddr[5], rc);
+ for (j = 0; j < i; j++) {
+ if_printf(ifp,
+ "failed to add mc address"
+ " %02x:%02x:%02x:"
+ "%02x:%02x:%02x rc=%d\n",
+ mcaddr[j][0], mcaddr[j][1],
+ mcaddr[j][2], mcaddr[j][3],
+ mcaddr[j][4], mcaddr[j][5],
+ rc);
+ }
goto mcfail;
}
- del = 0;
}
rc = -t4_set_addr_hash(sc, sc->mbox, pi->viid, 0, hash, 0);
@@ -2980,6 +2992,7 @@
sizeof(sc->sge.counter_val), sysctl_int_array, "A",
"interrupt holdoff packet counter values");
+#ifdef SBUF_DRAIN
/*
* dev.t4nex.X.misc. Marked CTLFLAG_SKIP to avoid information overload.
*/
@@ -3051,6 +3064,7 @@
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_rate",
CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
sysctl_tx_rate, "A", "Tx rate");
+#endif
#ifndef TCP_OFFLOAD_DISABLE
if (is_offload(sc)) {
@@ -3465,6 +3479,7 @@
return (sysctl_handle_64(oidp, &val, 0, req));
}
+#ifdef SBUF_DRAIN
static int
sysctl_cctrl(SYSCTL_HANDLER_ARGS)
{
@@ -4297,6 +4312,7 @@
return (rc);
}
+#endif
static inline void
txq_start(struct ifnet *ifp, struct sge_txq *txq)
@@ -4854,22 +4870,22 @@
unsigned int rc = G_COOKIE(rpl->cookie);
struct filter_entry *f = &sc->tids.ftid_tab[idx];
+ ADAPTER_LOCK(sc);
if (rc == FW_FILTER_WR_FLT_ADDED) {
f->smtidx = (be64toh(rpl->oldval) >> 24) & 0xff;
f->pending = 0; /* asynchronous setup completed */
f->valid = 1;
- return (0);
+ } else {
+ if (rc != FW_FILTER_WR_FLT_DELETED) {
+ /* Add or delete failed, display an error */
+ log(LOG_ERR,
+ "filter %u setup failed with error %u\n",
+ idx, rc);
+ }
+
+ clear_filter(f);
+ sc->tids.ftids_in_use--;
}
-
- if (rc != FW_FILTER_WR_FLT_DELETED) {
- /* Add or delete failed, need to display an error */
- device_printf(sc->dev,
- "filter %u setup failed with error %u\n", idx, rc);
- }
-
- clear_filter(f);
- ADAPTER_LOCK(sc);
- sc->tids.ftids_in_use--;
ADAPTER_UNLOCK(sc);
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/dpt/dpt_scsi.c
--- a/head/sys/dev/dpt/dpt_scsi.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/dpt/dpt_scsi.c Fri Mar 02 17:36:33 2012 +0200
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/dpt/dpt_scsi.c 232185 2012-02-26 16:05:20Z kevlo $");
/*
* dpt_scsi.c: SCSI dependant code for the DPT driver
@@ -1034,7 +1034,6 @@
spi->valid = CTS_SPI_VALID_SYNC_RATE
| CTS_SPI_VALID_SYNC_OFFSET
- | CTS_SPI_VALID_SYNC_RATE
| CTS_SPI_VALID_BUS_WIDTH
| CTS_SPI_VALID_DISC;
scsi->valid = CTS_SCSI_VALID_TQ;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/e1000/if_em.c
--- a/head/sys/dev/e1000/if_em.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/e1000/if_em.c Fri Mar 02 17:36:33 2012 +0200
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/e1000/if_em.c 230024 2012-01-12 17:30:44Z luigi $*/
+/*$FreeBSD: head/sys/dev/e1000/if_em.c 232238 2012-02-27 19:05:01Z luigi $*/
#ifdef HAVE_KERNEL_OPTION_HEADERS
#include "opt_device_polling.h"
@@ -3296,12 +3296,10 @@
}
#ifdef DEV_NETMAP
if (slot) {
- int si = i + na->tx_rings[txr->me].nkr_hwofs;
+ int si = netmap_idx_n2k(&na->tx_rings[txr->me], i);
uint64_t paddr;
void *addr;
- if (si >= na->num_tx_desc)
- si -= na->num_tx_desc;
addr = PNMB(slot + si, &paddr);
txr->tx_base[i].buffer_addr = htole64(paddr);
/* reload the map for netmap mode */
@@ -3761,7 +3759,7 @@
selwakeuppri(&na->tx_rings[txr->me].si, PI_NET);
EM_TX_UNLOCK(txr);
EM_CORE_LOCK(adapter);
- selwakeuppri(&na->tx_rings[na->num_queues + 1].si, PI_NET);
+ selwakeuppri(&na->tx_si, PI_NET);
EM_CORE_UNLOCK(adapter);
EM_TX_LOCK(txr);
return (FALSE);
@@ -4053,13 +4051,10 @@
rxbuf = &rxr->rx_buffers[j];
#ifdef DEV_NETMAP
if (slot) {
- /* slot si is mapped to the j-th NIC-ring entry */
- int si = j + na->rx_rings[0].nkr_hwofs;
+ int si = netmap_idx_n2k(&na->rx_rings[rxr->me], j);
uint64_t paddr;
void *addr;
- if (si > na->num_rx_desc)
- si -= na->num_rx_desc;
addr = PNMB(slot + si, &paddr);
netmap_load_map(rxr->rxtag, rxbuf->map, addr);
/* Update descriptor */
@@ -4375,10 +4370,11 @@
if (ifp->if_capenable & IFCAP_NETMAP) {
struct netmap_adapter *na = NA(ifp);
+ na->rx_rings[rxr->me].nr_kflags |= NKR_PENDINTR;
selwakeuppri(&na->rx_rings[rxr->me].si, PI_NET);
EM_RX_UNLOCK(rxr);
EM_CORE_LOCK(adapter);
- selwakeuppri(&na->rx_rings[na->num_queues + 1].si, PI_NET);
+ selwakeuppri(&na->rx_si, PI_NET);
EM_CORE_UNLOCK(adapter);
return (0);
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/e1000/if_igb.c
--- a/head/sys/dev/e1000/if_igb.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/e1000/if_igb.c Fri Mar 02 17:36:33 2012 +0200
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/e1000/if_igb.c 229939 2012-01-10 19:57:23Z luigi $*/
+/*$FreeBSD: head/sys/dev/e1000/if_igb.c 232367 2012-03-01 22:13:10Z jhb $*/
#ifdef HAVE_KERNEL_OPTION_HEADERS
@@ -2711,7 +2711,7 @@
"MSIX Configuration Problem, "
"%d vectors configured, but %d queues wanted!\n",
msgs, want);
- return (ENXIO);
+ return (0);
}
if ((msgs) && pci_alloc_msix(dev, &msgs) == 0) {
device_printf(adapter->dev,
@@ -2721,9 +2721,11 @@
}
msi:
msgs = pci_msi_count(dev);
- if (msgs == 1 && pci_alloc_msi(dev, &msgs) == 0)
- device_printf(adapter->dev,"Using MSI interrupt\n");
- return (msgs);
+ if (msgs == 1 && pci_alloc_msi(dev, &msgs) == 0) {
+ device_printf(adapter->dev," Using MSI interrupt\n");
+ return (msgs);
+ }
+ return (0);
}
/*********************************************************************
@@ -3315,11 +3317,8 @@
}
#ifdef DEV_NETMAP
if (slot) {
- /* slot si is mapped to the i-th NIC-ring entry */
- int si = i + na->tx_rings[txr->me].nkr_hwofs;
-
- if (si < 0)
- si += na->num_tx_desc;
+ int si = netmap_idx_n2k(&na->tx_rings[txr->me], i);
+ /* no need to set the address */
netmap_load_map(txr->txtag, txbuf->map, NMB(slot + si));
}
#endif /* DEV_NETMAP */
@@ -3696,7 +3695,7 @@
selwakeuppri(&na->tx_rings[txr->me].si, PI_NET);
IGB_TX_UNLOCK(txr);
IGB_CORE_LOCK(adapter);
- selwakeuppri(&na->tx_rings[na->num_queues + 1].si, PI_NET);
+ selwakeuppri(&na->tx_si, PI_NET);
IGB_CORE_UNLOCK(adapter);
IGB_TX_LOCK(txr);
return FALSE;
@@ -4060,12 +4059,10 @@
#ifdef DEV_NETMAP
if (slot) {
/* slot sj is mapped to the i-th NIC-ring entry */
- int sj = j + na->rx_rings[rxr->me].nkr_hwofs;
+ int sj = netmap_idx_n2k(&na->rx_rings[rxr->me], j);
uint64_t paddr;
void *addr;
- if (sj < 0)
- sj += na->num_rx_desc;
addr = PNMB(slot + sj, &paddr);
netmap_load_map(rxr->ptag, rxbuf->pmap, addr);
/* Update descriptor */
@@ -4559,10 +4556,11 @@
if (ifp->if_capenable & IFCAP_NETMAP) {
struct netmap_adapter *na = NA(ifp);
+ na->rx_rings[rxr->me].nr_kflags |= NKR_PENDINTR;
selwakeuppri(&na->rx_rings[rxr->me].si, PI_NET);
IGB_RX_UNLOCK(rxr);
IGB_CORE_LOCK(adapter);
- selwakeuppri(&na->rx_rings[na->num_queues + 1].si, PI_NET);
+ selwakeuppri(&na->rx_si, PI_NET);
IGB_CORE_UNLOCK(adapter);
return (0);
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/e1000/if_lem.c
--- a/head/sys/dev/e1000/if_lem.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/e1000/if_lem.c Fri Mar 02 17:36:33 2012 +0200
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/e1000/if_lem.c 229939 2012-01-10 19:57:23Z luigi $*/
+/*$FreeBSD: head/sys/dev/e1000/if_lem.c 232238 2012-02-27 19:05:01Z luigi $*/
#ifdef HAVE_KERNEL_OPTION_HEADERS
#include "opt_device_polling.h"
@@ -2668,13 +2668,11 @@
tx_buffer->m_head = NULL;
#ifdef DEV_NETMAP
if (slot) {
- /* slot si is mapped to the i-th NIC-ring entry */
- int si = i + na->tx_rings[0].nkr_hwofs;
+ /* the i-th NIC entry goes to slot si */
+ int si = netmap_idx_n2k(&na->tx_rings[0], i);
uint64_t paddr;
void *addr;
- if (si > na->num_tx_desc)
- si -= na->num_tx_desc;
addr = PNMB(slot + si, &paddr);
adapter->tx_desc_base[si].buffer_addr = htole64(paddr);
/* reload the map for netmap mode */
@@ -3244,13 +3242,11 @@
for (i = 0; i < adapter->num_rx_desc; i++) {
#ifdef DEV_NETMAP
if (slot) {
- /* slot si is mapped to the i-th NIC-ring entry */
- int si = i + na->rx_rings[0].nkr_hwofs;
+ /* the i-th NIC entry goes to slot si */
+ int si = netmap_idx_n2k(&na->rx_rings[0], i);
uint64_t paddr;
void *addr;
- if (si > na->num_rx_desc)
- si -= na->num_rx_desc;
addr = PNMB(slot + si, &paddr);
netmap_load_map(adapter->rxtag, rx_buffer->map, addr);
/* Update descriptor */
@@ -3479,7 +3475,9 @@
#ifdef DEV_NETMAP
if (ifp->if_capenable & IFCAP_NETMAP) {
- selwakeuppri(&NA(ifp)->rx_rings[0].si, PI_NET);
+ struct netmap_adapter *na = NA(ifp);
+ na->rx_rings[0].nr_kflags |= NKR_PENDINTR;
+ selwakeuppri(&na->rx_rings[0].si, PI_NET);
EM_RX_UNLOCK(adapter);
return (0);
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/fb/vesa.c
--- a/head/sys/dev/fb/vesa.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/fb/vesa.c Fri Mar 02 17:36:33 2012 +0200
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1998 Kazutaka YOKOTA and Michael Smith
- * Copyright (c) 2009-2010 Jung-uk Kim <jkim at FreeBSD.org>
+ * Copyright (c) 2009-2012 Jung-uk Kim <jkim at FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/fb/vesa.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/dev/fb/vesa.c 232069 2012-02-23 20:54:22Z jkim $");
#include "opt_vga.h"
#include "opt_vesa.h"
@@ -80,6 +80,7 @@
static struct mtx vesa_lock;
+static int vesa_state;
static void *vesa_state_buf = NULL;
static uint32_t vesa_state_buf_offs = 0;
static ssize_t vesa_state_buf_size = 0;
@@ -205,13 +206,7 @@
#define STATE_SIZE 0
#define STATE_SAVE 1
#define STATE_LOAD 2
-#define STATE_HW (1<<0)
-#define STATE_DATA (1<<1)
-#define STATE_DAC (1<<2)
-#define STATE_REG (1<<3)
-#define STATE_MOST (STATE_HW | STATE_DATA | STATE_REG)
-#define STATE_ALL (STATE_HW | STATE_DATA | STATE_DAC | STATE_REG)
-static ssize_t vesa_bios_state_buf_size(void);
+static ssize_t vesa_bios_state_buf_size(int);
static int vesa_bios_save_restore(int code, void *p);
#ifdef MODE_TABLE_BROKEN
static int vesa_bios_get_line_length(void);
@@ -509,14 +504,14 @@
}
static ssize_t
-vesa_bios_state_buf_size(void)
+vesa_bios_state_buf_size(int state)
{
x86regs_t regs;
x86bios_init_regs(®s);
regs.R_AX = 0x4f04;
/* regs.R_DL = STATE_SIZE; */
- regs.R_CX = STATE_MOST;
+ regs.R_CX = state;
x86bios_intr(®s, 0x10);
@@ -537,7 +532,7 @@
x86bios_init_regs(®s);
regs.R_AX = 0x4f04;
regs.R_DL = code;
- regs.R_CX = STATE_MOST;
+ regs.R_CX = vesa_state;
regs.R_ES = X86BIOS_PHYSTOSEG(vesa_state_buf_offs);
regs.R_BX = X86BIOS_PHYSTOOFF(vesa_state_buf_offs);
@@ -1041,7 +1036,12 @@
x86bios_free(vmbuf, sizeof(*buf));
- vesa_state_buf_size = vesa_bios_state_buf_size();
+ /* Probe supported save/restore states. */
+ for (i = 0; i < 4; i++)
+ if (vesa_bios_state_buf_size(1 << i) > 0)
+ vesa_state |= 1 << i;
+ if (vesa_state != 0)
+ vesa_state_buf_size = vesa_bios_state_buf_size(vesa_state);
vesa_palette = x86bios_alloc(&vesa_palette_offs,
VESA_PALETTE_SIZE + vesa_state_buf_size, M_WAITOK);
if (vesa_state_buf_size > 0) {
@@ -1311,7 +1311,9 @@
if (!(info.vi_flags & V_INFO_GRAPHICS))
info.vi_flags &= ~V_INFO_LINEAR;
- if (vesa_bios_set_mode(mode | ((info.vi_flags & V_INFO_LINEAR) ? 0x4000 : 0)))
+ if ((info.vi_flags & V_INFO_LINEAR) != 0)
+ mode |= 0x4000;
+ if (vesa_bios_set_mode(mode))
return (1);
/* Palette format is reset by the above VBE function call. */
@@ -1329,7 +1331,7 @@
#if VESA_DEBUG > 0
printf("VESA: mode set!\n");
#endif
- vesa_adp->va_mode = mode;
+ vesa_adp->va_mode = mode & 0x1ff; /* Mode number is 9-bit. */
vesa_adp->va_flags &= ~V_ADP_COLOR;
vesa_adp->va_flags |=
(info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0;
@@ -1449,15 +1451,13 @@
vesa_save_state(video_adapter_t *adp, void *p, size_t size)
{
- if (adp != vesa_adp)
+ if (adp != vesa_adp || vesa_state_buf_size == 0)
return ((*prevvidsw->save_state)(adp, p, size));
- if (vesa_state_buf_size == 0)
- return (1);
if (size == 0)
return (offsetof(adp_state_t, regs) + vesa_state_buf_size);
if (size < (offsetof(adp_state_t, regs) + vesa_state_buf_size))
- return (1);
+ return (EINVAL);
((adp_state_t *)p)->sig = V_STATE_SIG;
bzero(((adp_state_t *)p)->regs, vesa_state_buf_size);
@@ -1467,18 +1467,20 @@
static int
vesa_load_state(video_adapter_t *adp, void *p)
{
+ int mode;
- if ((adp != vesa_adp) || (((adp_state_t *)p)->sig != V_STATE_SIG))
+ if (adp != vesa_adp)
return ((*prevvidsw->load_state)(adp, p));
- if (vesa_state_buf_size == 0)
- return (1);
-
/* Try BIOS POST to restore a sane state. */
(void)vesa_bios_post();
- (void)int10_set_mode(adp->va_initial_bios_mode);
- (void)vesa_set_mode(adp, adp->va_mode);
+ mode = adp->va_mode;
+ (void)vesa_set_mode(adp, adp->va_initial_mode);
+ if (mode != adp->va_initial_mode)
+ (void)vesa_set_mode(adp, mode);
+ if (((adp_state_t *)p)->sig != V_STATE_SIG)
+ return ((*prevvidsw->load_state)(adp, p));
return (vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs));
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/fb/vesa.h
--- a/head/sys/dev/fb/vesa.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/fb/vesa.h Fri Mar 02 17:36:33 2012 +0200
@@ -23,7 +23,7 @@
* (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$
+ * $FreeBSD: head/sys/dev/fb/vesa.h 231841 2012-02-16 22:33:53Z jkim $
*/
#ifndef _DEV_FB_VESA_H_
@@ -126,7 +126,7 @@
#ifdef _KERNEL
-#define VESA_MODE(x) ((x) >= M_VESA_BASE)
+#define VESA_MODE(x) ((x) >= M_VESA_BASE && (x) <= M_VESA_MODE_MAX)
int vesa_load_ioctl(void);
int vesa_unload_ioctl(void);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/flash/mx25l.c
--- a/head/sys/dev/flash/mx25l.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/flash/mx25l.c Fri Mar 02 17:36:33 2012 +0200
@@ -49,6 +49,7 @@
#define FL_NONE 0x00
#define FL_ERASE_4K 0x01
#define FL_ERASE_32K 0x02
+#define FL_2BYTE_ADDR 0x04
/*
* Define the sectorsize to be a smaller size rather than the flash
@@ -310,14 +311,20 @@
mx25l_erase_cmd(dev, offset + bytes_writen, CMD_SECTOR_ERASE);
txBuf[0] = CMD_PAGE_PROGRAM;
- txBuf[1] = ((write_offset >> 16) & 0xff);
- txBuf[2] = ((write_offset >> 8) & 0xff);
- txBuf[3] = (write_offset & 0xff);
+ if (sc->sc_flags & FL_2BYTE_ADDR) {
+ txBuf[1] = ((write_offset >> 8) & 0xff);
+ txBuf[2] = (write_offset & 0xff);
+ cmd.tx_cmd_sz = 3;
+ } else {
+ txBuf[1] = ((write_offset >> 16) & 0xff);
+ txBuf[2] = ((write_offset >> 8) & 0xff);
+ txBuf[3] = (write_offset & 0xff);
+ cmd.tx_cmd_sz = 4;
+ }
bytes_to_write = MIN(sc->sc_pagesize,
count - bytes_writen);
cmd.tx_cmd = txBuf;
- cmd.tx_cmd_sz = 4;
cmd.rx_cmd_sz = 0;
cmd.tx_data = data + bytes_writen;
cmd.tx_data_sz = bytes_to_write;
@@ -376,14 +383,20 @@
return (EIO);
txBuf[0] = CMD_FAST_READ;
- txBuf[1] = ((offset >> 16) & 0xff);
- txBuf[2] = ((offset >> 8) & 0xff);
- txBuf[3] = (offset & 0xff);
- /* Dummy byte */
- txBuf[4] = 0; /* XXX: check this */
+ if (sc->sc_flags & FL_2BYTE_ADDR) {
+ txBuf[1] = ((offset >> 8) & 0xff);
+ txBuf[2] = (offset & 0xff);
+ cmd.tx_cmd_sz = 3;
+ } else {
+ txBuf[1] = ((offset >> 16) & 0xff);
+ txBuf[2] = ((offset >> 8) & 0xff);
+ txBuf[3] = (offset & 0xff);
+ /* Dummy byte */
+ txBuf[4] = 0;
+ cmd.tx_cmd_sz = 5;
+ }
cmd.tx_cmd = txBuf;
- cmd.tx_cmd_sz = 5;
cmd.rx_cmd_sz = 0;
cmd.rx_data = data;
@@ -393,7 +406,7 @@
// printf("%s(dev=%p, offset=%jx, data=%p, count=%jx)\n", __func__, dev, offset, data, count);
err = SPIBUS_TRANSFER(pdev, dev, &cmd);
-// hexdump(cmd.rx_data, count, NULL, 0);
+ hexdump(cmd.rx_data, count, NULL, 0);
// printf("%s: err=%d\n\n", __func__, err);
@@ -477,6 +490,8 @@
/* Sectorsize for erase operations */
sc->sc_sectorsize = ident->sectorsize;
sc->sc_flags = ident->flags;
+ sc->sc_flags |= (sc->sc_disk->d_mediasize <= (64 * 1024)) ?
+ FL_2BYTE_ADDR : 0;
sc->sc_pagesize = ident->pagesize;
/* NB: use stripesize to hold the erase/region size for RedBoot */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/gpio/gpiobus.c
--- a/head/sys/dev/gpio/gpiobus.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/gpio/gpiobus.c Fri Mar 02 17:36:33 2012 +0200
@@ -55,6 +55,7 @@
static int gpiobus_suspend(device_t);
static int gpiobus_resume(device_t);
static int gpiobus_print_child(device_t, device_t);
+static void gpiobus_child_detached(device_t dev, device_t child);
static int gpiobus_child_location_str(device_t, device_t, char *, size_t);
static int gpiobus_child_pnpinfo_str(device_t, device_t, char *, size_t);
static device_t gpiobus_add_child(device_t, u_int, const char *, int);
@@ -176,7 +177,7 @@
"warning: pin %d is already mapped\n", i);
return (EINVAL);
}
- sc->sc_pins[i].mapped = 1;
+ sc->sc_pins[i].mapped = child;
}
return (0);
@@ -373,8 +374,12 @@
child = BUS_ADD_CHILD(bus, 0, dname, dunit);
devi = GPIOBUS_IVAR(child);
resource_int_value(dname, dunit, "pins", &pins);
- if (gpiobus_parse_pins(sc, child, pins))
+ device_printf(child, "Use pinmask=0x%08x\n", pins);
+ if (gpiobus_parse_pins(sc, child, pins)) {
+ if (devi)
+ gpiobus_child_detached(bus, child);
device_delete_child(bus, child);
+ }
}
static void
@@ -391,6 +396,11 @@
return;
for (pin = 0; pin < devi->npins; pin++) {
+ if (sc->sc_pins[devi->pins[pin]].mapped &&
+ (sc->sc_pins[devi->pins[pin]].mapped != child)) {
+ printf("Mapped pin %d is not owned by child \"%s\"\n",
+ pin, device_get_nameunit(child));
+ }
sc->sc_pins[devi->pins[pin]].mapped = 0;
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/gpio/gpiobusvar.h
--- a/head/sys/dev/gpio/gpiobusvar.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/gpio/gpiobusvar.h Fri Mar 02 17:36:33 2012 +0200
@@ -38,7 +38,7 @@
#define GPIOBUS_SOFTC(d) (struct gpiobus_softc *) device_get_softc(d)
struct pin {
- int mapped;
+ device_t mapped; /* Child which map that pin */
int flags;
int last;
time_t lasttime;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/hwpmc/hwpmc_core.c
--- a/head/sys/dev/hwpmc/hwpmc_core.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/hwpmc/hwpmc_core.c Fri Mar 02 17:36:33 2012 +0200
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_core.c 229470 2012-01-04 07:58:36Z fabient $");
+__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_core.c 232366 2012-03-01 21:23:26Z davide $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -556,7 +556,8 @@
#define IAP_F_I7 (1 << 4) /* CPU: Core i7 */
#define IAP_F_I7O (1 << 4) /* CPU: Core i7 (old) */
#define IAP_F_WM (1 << 5) /* CPU: Westmere */
-#define IAP_F_FM (1 << 6) /* Fixed mask */
+#define IAP_F_SB (1 << 6) /* CPU: Sandy Brdige */
+#define IAP_F_FM (1 << 7) /* Fixed mask */
#define IAP_F_ALLCPUSCORE2 \
(IAP_F_CC | IAP_F_CC2 | IAP_F_CC2E | IAP_F_CA)
@@ -596,11 +597,12 @@
IAPDESCR(02H_81H, 0x02, 0x81, IAP_F_FM | IAP_F_CA),
IAPDESCR(03H_00H, 0x03, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(03H_01H, 0x03, 0x01, IAP_F_FM | IAP_F_I7O),
- IAPDESCR(03H_02H, 0x03, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_WM),
+ IAPDESCR(03H_01H, 0x03, 0x01, IAP_F_FM | IAP_F_I7O | IAP_F_SB),
+ IAPDESCR(03H_02H, 0x03, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_WM | IAP_F_SB),
IAPDESCR(03H_04H, 0x03, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O),
- IAPDESCR(03H_08H, 0x03, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(03H_10H, 0x03, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ IAPDESCR(03H_08H, 0x03, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_SB),
+ IAPDESCR(03H_10H, 0x03, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_SB),
IAPDESCR(03H_20H, 0x03, 0x20, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(04H_00H, 0x04, 0x00, IAP_F_FM | IAP_F_CC),
@@ -610,8 +612,8 @@
IAPDESCR(04H_08H, 0x04, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(05H_00H, 0x05, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(05H_01H, 0x05, 0x01, IAP_F_FM | IAP_F_I7O),
- IAPDESCR(05H_02H, 0x05, 0x02, IAP_F_FM | IAP_F_I7O | IAP_F_WM),
+ IAPDESCR(05H_01H, 0x05, 0x01, IAP_F_FM | IAP_F_I7O | IAP_F_SB),
+ IAPDESCR(05H_02H, 0x05, 0x02, IAP_F_FM | IAP_F_I7O | IAP_F_WM | IAP_F_SB),
IAPDESCR(05H_03H, 0x05, 0x03, IAP_F_FM | IAP_F_I7O),
IAPDESCR(06H_00H, 0x06, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2 |
@@ -623,24 +625,25 @@
IAPDESCR(06H_0FH, 0x06, 0x0F, IAP_F_FM | IAP_F_I7O),
IAPDESCR(07H_00H, 0x07, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2),
- IAPDESCR(07H_01H, 0x07, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(07H_01H, 0x07, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(07H_02H, 0x07, 0x02, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(07H_03H, 0x07, 0x03, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(07H_06H, 0x07, 0x06, IAP_F_FM | IAP_F_CA),
- IAPDESCR(07H_08H, 0x07, 0x08, IAP_F_FM | IAP_F_CA),
+ IAPDESCR(07H_08H, 0x07, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_SB),
IAPDESCR(08H_01H, 0x08, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(08H_02H, 0x08, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(08H_04H, 0x08, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_WM),
+ IAP_F_WM | IAP_F_SB),
IAPDESCR(08H_05H, 0x08, 0x05, IAP_F_FM | IAP_F_CA),
IAPDESCR(08H_06H, 0x08, 0x06, IAP_F_FM | IAP_F_CA),
IAPDESCR(08H_07H, 0x08, 0x07, IAP_F_FM | IAP_F_CA),
IAPDESCR(08H_08H, 0x08, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(08H_09H, 0x08, 0x09, IAP_F_FM | IAP_F_CA),
- IAPDESCR(08H_10H, 0x08, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(08H_10H, 0x08, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(08H_20H, 0x08, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(08H_40H, 0x08, 0x40, IAP_F_FM | IAP_F_I7O),
IAPDESCR(08H_80H, 0x08, 0x80, IAP_F_FM | IAP_F_I7),
@@ -659,7 +662,10 @@
IAPDESCR(0CH_02H, 0x0C, 0x02, IAP_F_FM | IAP_F_CC2),
IAPDESCR(0CH_03H, 0x0C, 0x03, IAP_F_FM | IAP_F_CA),
- IAPDESCR(0EH_01H, 0x0E, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(0DH_03H, 0x0D, 0x03, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(0DH_40H, 0x0D, 0x40, IAP_F_FM | IAP_F_SB),
+
+ IAPDESCR(0EH_01H, 0x0E, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(0EH_02H, 0x0E, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(0FH_01H, 0x0F, 0x01, IAP_F_FM | IAP_F_I7),
@@ -670,18 +676,20 @@
IAPDESCR(0FH_80H, 0x0F, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(10H_00H, 0x10, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
- IAPDESCR(10H_01H, 0x10, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(10H_01H, 0x10, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
+ IAP_F_WM | IAP_F_SB),
IAPDESCR(10H_02H, 0x10, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(10H_04H, 0x10, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(10H_08H, 0x10, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(10H_10H, 0x10, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(10H_20H, 0x10, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(10H_40H, 0x10, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(10H_80H, 0x10, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(10H_10H, 0x10, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(10H_20H, 0x10, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(10H_40H, 0x10, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(10H_80H, 0x10, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(10H_81H, 0x10, 0x81, IAP_F_FM | IAP_F_CA),
IAPDESCR(11H_00H, 0x11, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2),
- IAPDESCR(11H_01H, 0x11, 0x01, IAP_F_FM | IAP_F_CA),
+ IAPDESCR(11H_01H, 0x11, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_SB),
+ IAPDESCR(11H_02H, 0x11, 0x02, IAP_F_FM | IAP_F_SB),
IAPDESCR(11H_81H, 0x11, 0x81, IAP_F_FM | IAP_F_CA),
IAPDESCR(12H_00H, 0x12, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
@@ -702,10 +710,11 @@
IAPDESCR(13H_81H, 0x13, 0x81, IAP_F_FM | IAP_F_CA),
IAPDESCR(14H_00H, 0x14, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2),
- IAPDESCR(14H_01H, 0x14, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(14H_01H, 0x14, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
+ IAP_F_WM | IAP_F_SB),
IAPDESCR(14H_02H, 0x14, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(17H_01H, 0x17, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(17H_01H, 0x17, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(18H_00H, 0x18, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(18H_01H, 0x18, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
@@ -727,18 +736,18 @@
IAPDESCR(23H, 0x23, IAP_M_CORE, IAP_F_ALLCPUSCORE2),
IAPDESCR(24H, 0x24, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUSCORE2),
- IAPDESCR(24H_01H, 0x24, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_01H, 0x24, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(24H_02H, 0x24, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(24H_03H, 0x24, 0x03, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(24H_04H, 0x24, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(24H_08H, 0x24, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(24H_0CH, 0x24, 0x0C, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(24H_10H, 0x24, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(24H_20H, 0x24, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(24H_30H, 0x24, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(24H_40H, 0x24, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(24H_80H, 0x24, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(24H_C0H, 0x24, 0xC0, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(24H_03H, 0x24, 0x03, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(24H_04H, 0x24, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(24H_08H, 0x24, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(24H_0CH, 0x24, 0x0C, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(24H_10H, 0x24, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(24H_20H, 0x24, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(24H_30H, 0x24, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(24H_40H, 0x24, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(24H_80H, 0x24, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(24H_C0H, 0x24, 0xC0, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(24H_AAH, 0x24, 0xAA, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(24H_FFH, 0x24, 0xFF, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
@@ -758,12 +767,12 @@
IAPDESCR(26H_FFH, 0x26, 0xFF, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(27H, 0x27, IAP_M_CORE | IAP_M_PREFETCH, IAP_F_ALLCPUSCORE2),
- IAPDESCR(27H_01H, 0x27, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(27H_01H, 0x27, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(27H_02H, 0x27, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(27H_04H, 0x27, 0x04, IAP_F_FM | IAP_F_I7O),
- IAPDESCR(27H_08H, 0x27, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(27H_04H, 0x27, 0x04, IAP_F_FM | IAP_F_I7O | IAP_F_SB),
+ IAPDESCR(27H_08H, 0x27, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(27H_0EH, 0x27, 0x0E, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(27H_0FH, 0x27, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(27H_0FH, 0x27, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(27H_10H, 0x27, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(27H_20H, 0x27, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(27H_40H, 0x27, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
@@ -774,8 +783,8 @@
IAPDESCR(28H, 0x28, IAP_M_CORE | IAP_M_MESI, IAP_F_ALLCPUSCORE2),
IAPDESCR(28H_01H, 0x28, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(28H_02H, 0x28, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(28H_04H, 0x28, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(28H_08H, 0x28, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(28H_04H, 0x28, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(28H_08H, 0x28, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(28H_0FH, 0x28, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(29H, 0x29, IAP_M_CORE | IAP_M_MESI, IAP_F_CC),
@@ -788,8 +797,10 @@
IAP_F_ALLCPUSCORE2),
IAPDESCR(2EH_01H, 0x2E, 0x01, IAP_F_FM | IAP_F_WM),
IAPDESCR(2EH_02H, 0x2E, 0x02, IAP_F_FM | IAP_F_WM),
- IAPDESCR(2EH_41H, 0x2E, 0x41, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7),
- IAPDESCR(2EH_4FH, 0x2E, 0x4F, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7),
+ IAPDESCR(2EH_41H, 0x2E, 0x41, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7 |
+ IAP_F_SB),
+ IAPDESCR(2EH_4FH, 0x2E, 0x4F, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7 |
+ IAP_F_SB),
IAPDESCR(30H, 0x30, IAP_M_CORE | IAP_M_MESI | IAP_M_PREFETCH,
IAP_F_ALLCPUSCORE2),
@@ -802,9 +813,9 @@
IAPDESCR(3BH_C0H, 0x3B, 0xC0, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(3CH_00H, 0x3C, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(3CH_01H, 0x3C, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(3CH_02H, 0x3C, 0x02, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(3DH_01H, 0x3D, 0x01, IAP_F_FM | IAP_F_I7O),
@@ -845,15 +856,17 @@
IAPDESCR(47H_00H, 0x47, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(48H_00H, 0x48, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(48H_01H, 0x48, 0x01, IAP_F_FM | IAP_F_SB),
IAPDESCR(48H_02H, 0x48, 0x02, IAP_F_FM | IAP_F_I7O),
IAPDESCR(49H_00H, 0x49, 0x00, IAP_F_FM | IAP_F_CC),
IAPDESCR(49H_01H, 0x49, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(49H_02H, 0x49, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
- IAPDESCR(49H_04H, 0x49, 0x04, IAP_F_FM | IAP_F_WM),
- IAPDESCR(49H_10H, 0x49, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(49H_04H, 0x49, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(49H_10H, 0x49, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(49H_20H, 0x49, 0x20, IAP_F_FM | IAP_F_I7),
IAPDESCR(49H_40H, 0x49, 0x40, IAP_F_FM | IAP_F_I7O),
IAPDESCR(49H_80H, 0x49, 0x80, IAP_F_FM | IAP_F_WM | IAP_F_I7),
@@ -865,12 +878,15 @@
IAPDESCR(4BH_08H, 0x4B, 0x08, IAP_F_FM | IAP_F_I7O),
IAPDESCR(4CH_00H, 0x4C, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(4CH_01H, 0x4C, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(4CH_01H, 0x4C, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(4CH_02H, 0x4C, 0x02, IAP_F_FM | IAP_F_SB),
IAPDESCR(4DH_01H, 0x4D, 0x01, IAP_F_FM | IAP_F_I7O),
IAPDESCR(4EH_01H, 0x4E, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(4EH_02H, 0x4E, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(4EH_02H, 0x4E, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(4EH_04H, 0x4E, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(4EH_10H, 0x4E, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
@@ -880,19 +896,41 @@
IAPDESCR(4FH_08H, 0x4F, 0x08, IAP_F_FM | IAP_F_I7O),
IAPDESCR(4FH_10H, 0x4F, 0x10, IAP_F_FM | IAP_F_WM),
- IAPDESCR(51H_01H, 0x51, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(51H_02H, 0x51, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(51H_04H, 0x51, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(51H_08H, 0x51, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(51H_01H, 0x51, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(51H_02H, 0x51, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(51H_04H, 0x51, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(51H_08H, 0x51, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(52H_01H, 0x52, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+
IAPDESCR(53H_01H, 0x53, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(59H_20H, 0x59, 0x20, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(59H_40H, 0x59, 0x40, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(59H_80H, 0x59, 0x80, IAP_F_FM | IAP_F_SB),
+
+ IAPDESCR(5BH_0CH, 0x5B, 0x0C, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(5BH_0FH, 0x5B, 0x0F, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(5BH_40H, 0x5B, 0x40, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(5BH_4FH, 0x5B, 0x4F, IAP_F_FM | IAP_F_SB),
+
+ IAPDESCR(5CH_01H, 0x5C, 0x01, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(5CH_02H, 0x5C, 0x02, IAP_F_FM | IAP_F_SB),
+
+ IAPDESCR(5EH_01H, 0x5E, 0x01, IAP_F_FM | IAP_F_SB),
+
IAPDESCR(60H, 0x60, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
- IAPDESCR(60H_01H, 0x60, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(60H_01H, 0x60, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7O |
+ IAP_F_SB),
IAPDESCR(60H_02H, 0x60, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
- IAPDESCR(60H_04H, 0x60, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
- IAPDESCR(60H_08H, 0x60, 0x08, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(60H_04H, 0x60, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O |
+ IAP_F_SB),
+ IAPDESCR(60H_08H, 0x60, 0x08, IAP_F_FM | IAP_F_WM | IAP_F_I7O |
+ IAP_F_SB),
IAPDESCR(61H, 0x61, IAP_M_AGENT, IAP_F_CA | IAP_F_CC2),
IAPDESCR(61H_00H, 0x61, 0x00, IAP_F_FM | IAP_F_CC),
@@ -903,8 +941,10 @@
IAPDESCR(63H, 0x63, IAP_M_AGENT | IAP_M_CORE,
IAP_F_CA | IAP_F_CC2),
IAPDESCR(63H, 0x63, IAP_M_CORE, IAP_F_CC),
- IAPDESCR(63H_01H, 0x63, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(63H_02H, 0x63, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(63H_01H, 0x63, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(63H_02H, 0x63, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(64H, 0x64, IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
IAPDESCR(64H_40H, 0x64, 0x40, IAP_F_FM | IAP_F_CC),
@@ -945,6 +985,13 @@
IAPDESCR(78H, 0x78, IAP_M_CORE, IAP_F_CC),
IAPDESCR(78H, 0x78, IAP_M_CORE | IAP_M_SNOOPTYPE, IAP_F_CA | IAP_F_CC2),
+ IAPDESCR(79H_02H, 0x79, 0x02, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(79H_04H, 0x79, 0x04, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(79H_08H, 0x79, 0x08, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(79H_10H, 0x79, 0x10, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(79H_20H, 0x79, 0x20, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(79H_30H, 0x79, 0x30, IAP_F_FM | IAP_F_SB),
+
IAPDESCR(7AH, 0x7A, IAP_M_AGENT, IAP_F_CA | IAP_F_CC2),
IAPDESCR(7BH, 0x7B, IAP_M_AGENT, IAP_F_CA | IAP_F_CC2),
@@ -959,7 +1006,7 @@
IAPDESCR(80H_00H, 0x80, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(80H_01H, 0x80, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(80H_02H, 0x80, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
- IAP_F_WM),
+ IAP_F_WM | IAP_F_SB),
IAPDESCR(80H_03H, 0x80, 0x03, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
IAP_F_WM),
IAPDESCR(80H_04H, 0x80, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
@@ -979,10 +1026,13 @@
IAPDESCR(83H_02H, 0x83, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(85H_00H, 0x85, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(85H_01H, 0x85, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(85H_02H, 0x85, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(85H_04H, 0x85, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
- IAPDESCR(85H_10H, 0x85, 0x10, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(85H_01H, 0x85, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(85H_02H, 0x85, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(85H_04H, 0x85, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O |
+ IAP_F_SB),
+ IAPDESCR(85H_10H, 0x85, 0x10, IAP_F_FM | IAP_F_I7O | IAP_F_SB),
IAPDESCR(85H_20H, 0x85, 0x20, IAP_F_FM | IAP_F_I7O),
IAPDESCR(85H_40H, 0x85, 0x40, IAP_F_FM | IAP_F_I7O),
IAPDESCR(85H_80H, 0x85, 0x80, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
@@ -990,35 +1040,54 @@
IAPDESCR(86H_00H, 0x86, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(87H_00H, 0x87, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
- IAPDESCR(87H_01H, 0x87, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(87H_01H, 0x87, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(87H_02H, 0x87, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(87H_04H, 0x87, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(87H_04H, 0x87, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(87H_08H, 0x87, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(87H_0FH, 0x87, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(88H_00H, 0x88, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
- IAPDESCR(88H_01H, 0x88, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(88H_02H, 0x88, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(88H_04H, 0x88, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(88H_01H, 0x88, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(88H_02H, 0x88, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(88H_04H, 0x88, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(88H_07H, 0x88, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(88H_08H, 0x88, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(88H_10H, 0x88, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(88H_20H, 0x88, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(88H_08H, 0x88, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(88H_10H, 0x88, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(88H_20H, 0x88, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(88H_30H, 0x88, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(88H_40H, 0x88, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(88H_40H, 0x88, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(88H_7FH, 0x88, 0x7F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(88H_80H, 0x88, 0x80, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(88H_FFH, 0x88, 0xFF, IAP_F_FM | IAP_F_SB),
IAPDESCR(89H_00H, 0x89, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
- IAPDESCR(89H_01H, 0x89, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_01H, 0x89, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(89H_02H, 0x89, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(89H_04H, 0x89, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_04H, 0x89, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(89H_07H, 0x89, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(89H_08H, 0x89, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(89H_10H, 0x89, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(89H_20H, 0x89, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_08H, 0x89, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(89H_10H, 0x89, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(89H_20H, 0x89, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(89H_30H, 0x89, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(89H_40H, 0x89, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_40H, 0x89, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(89H_7FH, 0x89, 0x7F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(89H_80H, 0x89, 0x80, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(89H_FFH, 0x89, 0xFF, IAP_F_FM | IAP_F_SB),
IAPDESCR(8AH_00H, 0x8A, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(8BH_00H, 0x8B, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
@@ -1033,26 +1102,46 @@
IAPDESCR(93H_00H, 0x93, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(94H_00H, 0x94, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(9CH_01H, 0x9C, 0x01, IAP_F_FM | IAP_F_SB),
+
IAPDESCR(97H_00H, 0x97, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(98H_00H, 0x98, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(A0H_00H, 0xA0, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(A1H_01H, 0xA1, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(A1H_02H, 0xA1, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(A1H_04H, 0xA1, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(A1H_08H, 0xA1, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(A1H_10H, 0xA1, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(A1H_20H, 0xA1, 0x20, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
-
+ IAPDESCR(A1H_01H, 0xA1, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_SB),
+ IAPDESCR(A1H_02H, 0xA1, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_SB),
+ IAPDESCR(A1H_04H, 0xA1, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_SB),
+ IAPDESCR(A1H_08H, 0xA1, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_SB),
+ IAPDESCR(A1H_0CH, 0xA1, 0x0C, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(A1H_10H, 0xA1, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_SB),
+ IAPDESCR(A1H_20H, 0xA1, 0x20, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_SB),
+ IAPDESCR(A1H_30H, 0xA1, 0x30, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(A1H_40H, 0xA1, 0x40, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(A1H_80H, 0xA1, 0x80, IAP_F_FM | IAP_F_SB),
+
IAPDESCR(A2H_00H, 0xA2, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(A2H_01H, 0xA2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(A2H_02H, 0xA2, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(A2H_04H, 0xA2, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(A2H_08H, 0xA2, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(A2H_10H, 0xA2, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(A2H_20H, 0xA2, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(A2H_40H, 0xA2, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(A2H_80H, 0xA2, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(A2H_01H, 0xA2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(A2H_02H, 0xA2, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(A2H_04H, 0xA2, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(A2H_08H, 0xA2, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(A2H_10H, 0xA2, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(A2H_20H, 0xA2, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(A2H_40H, 0xA2, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(A2H_80H, 0xA2, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(A6H_01H, 0xA6, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(A7H_01H, 0xA7, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
@@ -1063,24 +1152,36 @@
IAPDESCR(AAH_03H, 0xAA, 0x03, IAP_F_FM | IAP_F_CA),
IAPDESCR(AAH_08H, 0xAA, 0x08, IAP_F_FM | IAP_F_CC2),
- IAPDESCR(ABH_01H, 0xAB, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(ABH_02H, 0xAB, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
-
- IAPDESCR(AEH_01H, 0xAE, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(ABH_01H, 0xAB, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_SB),
+ IAPDESCR(ABH_02H, 0xAB, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_SB),
+
+ IAPDESCR(ACH_02H, 0xAC, 0x02, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(ACH_08H, 0xAC, 0x08, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(ACH_0AH, 0xAC, 0x0A, IAP_F_FM | IAP_F_SB),
+
+ IAPDESCR(AEH_01H, 0xAE, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(B0H_00H, 0xB0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
- IAPDESCR(B0H_01H, 0xB0, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(B0H_01H, 0xB0, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7O |
+ IAP_F_SB),
IAPDESCR(B0H_02H, 0xB0, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
- IAPDESCR(B0H_04H, 0xB0, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
- IAPDESCR(B0H_08H, 0xB0, 0x08, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
+ IAPDESCR(B0H_04H, 0xB0, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O |
+ IAP_F_SB),
+ IAPDESCR(B0H_08H, 0xB0, 0x08, IAP_F_FM | IAP_F_WM | IAP_F_I7O |
+ IAP_F_SB),
IAPDESCR(B0H_10H, 0xB0, 0x10, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
IAPDESCR(B0H_20H, 0xB0, 0x20, IAP_F_FM | IAP_F_I7O),
IAPDESCR(B0H_40H, 0xB0, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(B0H_80H, 0xB0, 0x80, IAP_F_FM | IAP_F_CA | IAP_F_WM | IAP_F_I7O),
IAPDESCR(B1H_00H, 0xB1, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
- IAPDESCR(B1H_01H, 0xB1, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(B1H_02H, 0xB1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B1H_01H, 0xB1, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(B1H_02H, 0xB1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(B1H_04H, 0xB1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(B1H_08H, 0xB1, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(B1H_10H, 0xB1, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
@@ -1091,7 +1192,8 @@
IAPDESCR(B1H_80H, 0xB1, 0x80, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
IAP_F_WM),
- IAPDESCR(B2H_01H, 0xB2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B2H_01H, 0xB2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(B3H_01H, 0xB3, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
IAP_F_WM | IAP_F_I7O),
@@ -1113,7 +1215,10 @@
IAPDESCR(B4H_02H, 0xB4, 0x02, IAP_F_FM | IAP_F_WM),
IAPDESCR(B4H_04H, 0xB4, 0x04, IAP_F_FM | IAP_F_WM),
- IAPDESCR(B7H_01H, 0xB7, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(B6H_01H, 0xB6, 0x01, IAP_F_FM | IAP_F_SB),
+
+ IAPDESCR(B7H_01H, 0xB7, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(B8H_01H, 0xB8, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(B8H_02H, 0xB8, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
@@ -1122,26 +1227,37 @@
IAPDESCR(BAH_01H, 0xBA, 0x01, IAP_F_FM | IAP_F_I7O),
IAPDESCR(BAH_02H, 0xBA, 0x02, IAP_F_FM | IAP_F_I7O),
- IAPDESCR(BBH_01H, 0xBB, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
-
- IAPDESCR(C0H_00H, 0xC0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(BBH_01H, 0xBB, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+
+ IAPDESCR(BDH_01H, 0xBD, 0x01, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(BDH_20H, 0xBD, 0x20, IAP_F_FM | IAP_F_SB),
+
+ IAPDESCR(BFH_05H, 0xBF, 0x05, IAP_F_FM | IAP_F_SB),
+
+ IAPDESCR(C0H_00H, 0xC0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
+ IAP_F_SB),
IAPDESCR(C0H_01H, 0xC0, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(C0H_02H, 0xC0, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(C0H_04H, 0xC0, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
IAP_F_I7 | IAP_F_WM),
IAPDESCR(C0H_08H, 0xC0, 0x08, IAP_F_FM | IAP_F_CC2E),
IAPDESCR(C1H_00H, 0xC1, 0x00, IAP_F_FM | IAP_F_CC),
IAPDESCR(C1H_01H, 0xC1, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ IAPDESCR(C1H_02H, 0xC1, 0x02, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(C1H_08H, 0xC1, 0x08, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(C1H_10H, 0xC1, 0x10, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(C1H_20H, 0xC1, 0x20, IAP_F_FM | IAP_F_SB),
IAPDESCR(C1H_FEH, 0xC1, 0xFE, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(C2H_00H, 0xC2, 0x00, IAP_F_FM | IAP_F_CC),
IAPDESCR(C2H_01H, 0xC2, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(C2H_02H, 0xC2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(C2H_04H, 0xC2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
IAP_F_I7 | IAP_F_WM),
IAPDESCR(C2H_07H, 0xC2, 0x07, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
@@ -1152,28 +1268,37 @@
IAPDESCR(C3H_00H, 0xC3, 0x00, IAP_F_FM | IAP_F_CC),
IAPDESCR(C3H_01H, 0xC3, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
IAP_F_I7 | IAP_F_WM),
- IAPDESCR(C3H_02H, 0xC3, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(C3H_02H, 0xC3, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(C3H_04H, 0xC3, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(C3H_10H, 0xC3, 0x10, IAP_F_FM | IAP_F_I7O),
+ IAPDESCR(C3H_20H, 0xC3, 0x20, IAP_F_FM | IAP_F_SB),
IAPDESCR(C4H_00H, 0xC4, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(C4H_01H, 0xC4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(C4H_02H, 0xC4, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(C4H_04H, 0xC4, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
- IAPDESCR(C4H_08H, 0xC4, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(C4H_08H, 0xC4, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_SB),
IAPDESCR(C4H_0CH, 0xC4, 0x0C, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(C4H_0FH, 0xC4, 0x0F, IAP_F_FM | IAP_F_CA),
+ IAPDESCR(C4H_10H, 0xC4, 0x10, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(C4H_20H, 0xC4, 0x20, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(C4H_40H, 0xC4, 0x40, IAP_F_FM | IAP_F_SB),
IAPDESCR(C5H_00H, 0xC5, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
- IAP_F_I7 | IAP_F_WM),
- IAPDESCR(C5H_01H, 0xC5, 0x01, IAP_F_FM | IAP_F_WM),
- IAPDESCR(C5H_02H, 0xC5, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(C5H_04H, 0xC5, 0x04, IAP_F_FM | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(C5H_01H, 0xC5, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(C5H_02H, 0xC5, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(C5H_04H, 0xC5, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(C5H_10H, 0xC5, 0x10, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(C5H_20H, 0xC5, 0x20, IAP_F_FM | IAP_F_SB),
IAPDESCR(C6H_00H, 0xC6, 0x00, IAP_F_FM | IAP_F_CC),
IAPDESCR(C6H_01H, 0xC6, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
@@ -1199,9 +1324,14 @@
IAPDESCR(CAH_00H, 0xCA, 0x00, IAP_F_FM | IAP_F_CC),
IAPDESCR(CAH_01H, 0xCA, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(CAH_02H, 0xCA, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(CAH_04H, 0xCA, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(CAH_08H, 0xCA, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ IAPDESCR(CAH_02H, 0xCA, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_SB),
+ IAPDESCR(CAH_04H, 0xCA, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_SB),
+ IAPDESCR(CAH_08H, 0xCA, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_SB),
+ IAPDESCR(CAH_10H, 0xCA, 0x10, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(CAH_1EH, 0xCA, 0x1E, IAP_F_FM | IAP_F_SB),
IAPDESCR(CBH_01H, 0xCB, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
IAP_F_I7 | IAP_F_WM),
@@ -1222,34 +1352,48 @@
IAPDESCR(CCH_02H, 0xCC, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
IAP_F_I7 | IAP_F_WM),
IAPDESCR(CCH_03H, 0xCC, 0x03, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(CCH_20H, 0xCC, 0x20, IAP_F_FM | IAP_F_SB),
IAPDESCR(CDH_00H, 0xCD, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
+ IAPDESCR(CDH_01H, 0xCD, 0x01, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(CDH_02H, 0xCD, 0x02, IAP_F_FM | IAP_F_SB),
+
IAPDESCR(CEH_00H, 0xCE, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(CFH_00H, 0xCF, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(D0H_00H, 0xD0, 0x00, IAP_F_FM | IAP_F_CC),
- IAPDESCR(D0H_01H, 0xD0, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
-
- IAPDESCR(D1H_01H, 0xD1, 0x01, IAP_F_FM | IAP_F_WM),
- IAPDESCR(D1H_02H, 0xD1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(D1H_04H, 0xD1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(D0H_01H, 0xD0, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(D0H_02H, 0xD0, 0x02, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(D0H_10H, 0xD0, 0x10, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(D0H_20H, 0xD0, 0x20, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(D0H_40H, 0xD0, 0x40, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(D0H_80H, 0xD0, 0X80, IAP_F_FM | IAP_F_SB),
+
+ IAPDESCR(D1H_01H, 0xD1, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_SB),
+ IAPDESCR(D1H_02H, 0xD1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(D1H_04H, 0xD1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(D1H_08H, 0xD1, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(D1H_40H, 0xD1, 0x40, IAP_F_FM | IAP_F_SB),
IAPDESCR(D2H_01H, 0xD2, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(D2H_02H, 0xD2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(D2H_04H, 0xD2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(D2H_08H, 0xD2, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
- IAP_F_I7 | IAP_F_WM),
+ IAP_F_I7 | IAP_F_WM | IAP_F_SB),
IAPDESCR(D2H_0FH, 0xD2, 0x0F, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
IAP_F_I7 | IAP_F_WM),
IAPDESCR(D2H_10H, 0xD2, 0x10, IAP_F_FM | IAP_F_CC2E),
IAPDESCR(D4H_01H, 0xD4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
IAP_F_I7 | IAP_F_WM),
- IAPDESCR(D4H_02H, 0xD4, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
+ IAPDESCR(D4H_02H, 0xD4, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
+ IAP_F_SB),
IAPDESCR(D4H_04H, 0xD4, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(D4H_08H, 0xD4, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(D4H_0FH, 0xD4, 0x0F, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
@@ -1311,23 +1455,40 @@
IAPDESCR(ECH_01H, 0xEC, 0x01, IAP_F_FM | IAP_F_WM),
IAPDESCR(F0H_00H, 0xF0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
- IAPDESCR(F0H_01H, 0xF0, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(F0H_02H, 0xF0, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(F0H_04H, 0xF0, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(F0H_08H, 0xF0, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(F0H_10H, 0xF0, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(F0H_20H, 0xF0, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(F0H_40H, 0xF0, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(F0H_80H, 0xF0, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
-
- IAPDESCR(F1H_02H, 0xF1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(F1H_04H, 0xF1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(F1H_07H, 0xF1, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
-
- IAPDESCR(F2H_01H, 0xF2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(F2H_02H, 0xF2, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(F2H_04H, 0xF2, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(F2H_08H, 0xF2, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F0H_01H, 0xF0, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(F0H_02H, 0xF0, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(F0H_04H, 0xF0, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(F0H_08H, 0xF0, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(F0H_10H, 0xF0, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(F0H_20H, 0xF0, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(F0H_40H, 0xF0, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(F0H_80H, 0xF0, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+
+ IAPDESCR(F1H_01H, 0xF1, 0x01, IAP_F_FM | IAP_F_SB),
+ IAPDESCR(F1H_02H, 0xF1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(F1H_04H, 0xF1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(F1H_07H, 0xF1, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+
+ IAPDESCR(F2H_01H, 0xF2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(F2H_02H, 0xF2, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(F2H_04H, 0xF2, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(F2H_08H, 0xF2, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
+ IAPDESCR(F2H_0AH, 0xF2, 0x0A, IAP_F_FM | IAP_F_SB),
IAPDESCR(F2H_0FH, 0xF2, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(F3H_01H, 0xF3, 0x01, IAP_F_FM | IAP_F_I7O),
@@ -1341,7 +1502,8 @@
IAPDESCR(F4H_02H, 0xF4, 0x02, IAP_F_FM | IAP_F_I7O),
IAPDESCR(F4H_04H, 0xF4, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O),
IAPDESCR(F4H_08H, 0xF4, 0x08, IAP_F_FM | IAP_F_I7O),
- IAPDESCR(F4H_10H, 0xF4, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
+ IAPDESCR(F4H_10H, 0xF4, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAP_F_SB),
IAPDESCR(F6H_01H, 0xF6, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
@@ -1513,6 +1675,25 @@
}
static int
+iap_event_sandybridge_ok_on_counter(enum pmc_event pe, int ri)
+{
+ uint32_t mask;
+
+ switch (pe) {
+ /*
+ * Events valid only on counter 2.
+ */
+ case PMC_EV_IAP_EVENT_48H_01H:
+ mask = 0x2;
+ break;
+ default:
+ mask = ~0; /* Any row index is ok. */
+ }
+
+ return (mask & (1 << ri));
+}
+
+static int
iap_event_ok_on_counter(enum pmc_event pe, int ri)
{
uint32_t mask;
@@ -1588,6 +1769,10 @@
if (iap_event_corei7_ok_on_counter(ev, ri) == 0)
return (EINVAL);
break;
+ case PMC_CPU_INTEL_SANDYBRIDGE:
+ if (iap_event_sandybridge_ok_on_counter(ev, ri) == 0)
+ return (EINVAL);
+ break;
case PMC_CPU_INTEL_WESTMERE:
if (iap_event_westmere_ok_on_counter(ev, ri) == 0)
return (EINVAL);
@@ -1619,6 +1804,9 @@
case PMC_CPU_INTEL_COREI7:
cpuflag = IAP_F_I7;
break;
+ case PMC_CPU_INTEL_SANDYBRIDGE:
+ cpuflag = IAP_F_SB;
+ break;
case PMC_CPU_INTEL_WESTMERE:
cpuflag = IAP_F_WM;
break;
@@ -1703,9 +1891,10 @@
}
/*
- * Only Atom CPUs support the 'ANY' qualifier.
+ * Only Atom and SandyBridge CPUs support the 'ANY' qualifier.
*/
- if (core_cputype == PMC_CPU_INTEL_ATOM)
+ if (core_cputype == PMC_CPU_INTEL_ATOM ||
+ core_cputype == PMC_CPU_INTEL_SANDYBRIDGE)
evsel |= (config & IAP_ANY);
else if (config & IAP_ANY)
return (EINVAL);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/hwpmc/hwpmc_intel.c
--- a/head/sys/dev/hwpmc/hwpmc_intel.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/hwpmc/hwpmc_intel.c Fri Mar 02 17:36:33 2012 +0200
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_intel.c 232366 2012-03-01 21:23:26Z davide $");
#include <sys/param.h>
#include <sys/pmc.h>
@@ -142,6 +142,11 @@
cputype = PMC_CPU_INTEL_WESTMERE;
nclasses = 5;
break;
+ case 0x2A: /* Per Intel document 253669-039US 05/2011. */
+ case 0x2D: /* Per Intel document 253669-041US 12/2011. */
+ cputype = PMC_CPU_INTEL_SANDYBRIDGE;
+ nclasses = 5;
+ break;
}
break;
#if defined(__i386__) || defined(__amd64__)
@@ -182,6 +187,7 @@
case PMC_CPU_INTEL_CORE2:
case PMC_CPU_INTEL_CORE2EXTREME:
case PMC_CPU_INTEL_COREI7:
+ case PMC_CPU_INTEL_SANDYBRIDGE:
case PMC_CPU_INTEL_WESTMERE:
error = pmc_core_initialize(pmc_mdep, ncpus);
break;
@@ -242,6 +248,7 @@
* Intel Corei7 and Westmere processors.
*/
case PMC_CPU_INTEL_COREI7:
+ case PMC_CPU_INTEL_SANDYBRIDGE:
case PMC_CPU_INTEL_WESTMERE:
error = pmc_uncore_initialize(pmc_mdep, ncpus);
break;
@@ -271,6 +278,7 @@
case PMC_CPU_INTEL_CORE2:
case PMC_CPU_INTEL_CORE2EXTREME:
case PMC_CPU_INTEL_COREI7:
+ case PMC_CPU_INTEL_SANDYBRIDGE:
case PMC_CPU_INTEL_WESTMERE:
pmc_core_finalize(md);
break;
@@ -301,6 +309,7 @@
#if defined(__i386__) || defined(__amd64__)
switch (md->pmd_cputype) {
case PMC_CPU_INTEL_COREI7:
+ case PMC_CPU_INTEL_SANDYBRIDGE:
case PMC_CPU_INTEL_WESTMERE:
pmc_uncore_finalize(md);
break;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/hwpmc/hwpmc_uncore.c
--- a/head/sys/dev/hwpmc/hwpmc_uncore.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/hwpmc/hwpmc_uncore.c Fri Mar 02 17:36:33 2012 +0200
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_uncore.c 230063 2012-01-13 17:13:46Z gnn $");
+__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_uncore.c 232366 2012-03-01 21:23:26Z davide $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -50,6 +50,12 @@
(PMC_CAP_EDGE | PMC_CAP_THRESHOLD | PMC_CAP_READ | PMC_CAP_WRITE | \
PMC_CAP_INVERT | PMC_CAP_QUALIFIER | PMC_CAP_PRECISE)
+#define SELECTSEL(x) \
+ (((x) == PMC_CPU_INTEL_SANDYBRIDGE) ? UCP_CB0_EVSEL0 : UCP_EVSEL0)
+
+#define SELECTOFF(x) \
+ (((x) == PMC_CPU_INTEL_SANDYBRIDGE) ? UCF_OFFSET_SB : UCF_OFFSET)
+
static enum pmc_cputype uncore_cputype;
struct uncore_cpu {
@@ -140,8 +146,8 @@
npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_num;
uncore_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_ri;
- for (n = 0; n < npmc; n++)
- wrmsr(UCP_EVSEL0 + n, 0);
+ for (n = 0; n < npmc; n++)
+ wrmsr(SELECTSEL(uncore_cputype) + n, 0);
wrmsr(UCF_CTRL, 0);
npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCF].pcd_num;
@@ -327,7 +333,7 @@
do {
ucfc->pc_resync = 0;
- ucfc->pc_globalctrl |= (1ULL << (ri + UCF_OFFSET));
+ ucfc->pc_globalctrl |= (1ULL << (ri + SELECTOFF(uncore_cputype)));
wrmsr(UC_GLOBAL_CTRL, ucfc->pc_globalctrl);
} while (ucfc->pc_resync != 0);
@@ -362,7 +368,7 @@
do {
ucfc->pc_resync = 0;
- ucfc->pc_globalctrl &= ~(1ULL << (ri + UCF_OFFSET));
+ ucfc->pc_globalctrl &= ~(1ULL << (ri + SELECTOFF(uncore_cputype)));
wrmsr(UC_GLOBAL_CTRL, ucfc->pc_globalctrl);
} while (ucfc->pc_resync != 0);
@@ -462,7 +468,8 @@
#define UCP_F_I7 (1 << 0) /* CPU: Core i7 */
#define UCP_F_WM (1 << 1) /* CPU: Westmere */
-#define UCP_F_FM (1 << 2) /* Fixed mask */
+#define UCP_F_SB (1 << 2) /* CPU: Sandy Bridge */
+#define UCP_F_FM (1 << 3) /* Fixed mask */
#define UCP_F_ALLCPUS \
(UCP_F_I7 | UCP_F_WM)
@@ -565,9 +572,16 @@
UCPDESCR(21H_02H, 0x21, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
UCPDESCR(21H_04H, 0x21, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
- UCPDESCR(22H_01H, 0x22, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
- UCPDESCR(22H_02H, 0x22, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
- UCPDESCR(22H_04H, 0x22, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
+ UCPDESCR(22H_01H, 0x22, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM |
+ UCP_F_SB),
+ UCPDESCR(22H_02H, 0x22, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM |
+ UCP_F_SB),
+ UCPDESCR(22H_04H, 0x22, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM |
+ UCP_F_SB),
+ UCPDESCR(22H_08H, 0x22, 0x08, UCP_F_FM | UCP_F_SB),
+ UCPDESCR(22H_20H, 0x22, 0x20, UCP_F_FM | UCP_F_SB),
+ UCPDESCR(22H_40H, 0x22, 0x40, UCP_F_FM | UCP_F_SB),
+ UCPDESCR(22H_80H, 0x22, 0x80, UCP_F_FM | UCP_F_SB),
UCPDESCR(23H_01H, 0x23, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
UCPDESCR(23H_02H, 0x23, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
@@ -657,12 +671,14 @@
UCPDESCR(33H_04H, 0x33, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
UCPDESCR(33H_07H, 0x33, 0x07, UCP_F_FM | UCP_F_WM),
- UCPDESCR(34H_01H, 0x34, 0x01, UCP_F_FM | UCP_F_WM),
- UCPDESCR(34H_02H, 0x34, 0x02, UCP_F_FM | UCP_F_WM),
- UCPDESCR(34H_04H, 0x34, 0x04, UCP_F_FM | UCP_F_WM),
- UCPDESCR(34H_08H, 0x34, 0x08, UCP_F_FM | UCP_F_WM),
- UCPDESCR(34H_10H, 0x34, 0x10, UCP_F_FM | UCP_F_WM),
- UCPDESCR(34H_20H, 0x34, 0x20, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(34H_01H, 0x34, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB),
+ UCPDESCR(34H_02H, 0x34, 0x02, UCP_F_FM | UCP_F_WM | UCP_F_SB),
+ UCPDESCR(34H_04H, 0x34, 0x04, UCP_F_FM | UCP_F_WM | UCP_F_SB),
+ UCPDESCR(34H_08H, 0x34, 0x08, UCP_F_FM | UCP_F_WM | UCP_F_SB),
+ UCPDESCR(34H_10H, 0x34, 0x10, UCP_F_FM | UCP_F_WM | UCP_F_SB),
+ UCPDESCR(34H_20H, 0x34, 0x20, UCP_F_FM | UCP_F_WM | UCP_F_SB),
+ UCPDESCR(34H_40H, 0x34, 0x40, UCP_F_FM | UCP_F_SB),
+ UCPDESCR(34H_80H, 0x34, 0x80, UCP_F_FM | UCP_F_SB),
UCPDESCR(35H_01H, 0x35, 0x01, UCP_F_FM | UCP_F_WM),
UCPDESCR(35H_02H, 0x35, 0x02, UCP_F_FM | UCP_F_WM),
@@ -729,20 +745,27 @@
UCPDESCR(66H_04H, 0x66, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
UCPDESCR(67H_01H, 0x67, 0x01, UCP_F_FM | UCP_F_WM),
- UCPDESCR(80H_01H, 0x80, 0x01, UCP_F_FM | UCP_F_WM),
+
+ UCPDESCR(80H_01H, 0x80, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB),
UCPDESCR(80H_02H, 0x80, 0x02, UCP_F_FM | UCP_F_WM),
UCPDESCR(80H_04H, 0x80, 0x04, UCP_F_FM | UCP_F_WM),
UCPDESCR(80H_08H, 0x80, 0x08, UCP_F_FM | UCP_F_WM),
- UCPDESCR(81H_01H, 0x81, 0x01, UCP_F_FM | UCP_F_WM),
+
+ UCPDESCR(81H_01H, 0x81, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB),
UCPDESCR(81H_02H, 0x81, 0x02, UCP_F_FM | UCP_F_WM),
UCPDESCR(81H_04H, 0x81, 0x04, UCP_F_FM | UCP_F_WM),
UCPDESCR(81H_08H, 0x81, 0x08, UCP_F_FM | UCP_F_WM),
+ UCPDESCR(81H_20H, 0x81, 0x20, UCP_F_FM | UCP_F_SB),
+ UCPDESCR(81H_80H, 0x81, 0x80, UCP_F_FM | UCP_F_SB),
+
UCPDESCR(82H_01H, 0x82, 0x01, UCP_F_FM | UCP_F_WM),
- UCPDESCR(83H_01H, 0x83, 0x01, UCP_F_FM | UCP_F_WM),
+
+ UCPDESCR(83H_01H, 0x83, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB),
UCPDESCR(83H_02H, 0x83, 0x02, UCP_F_FM | UCP_F_WM),
UCPDESCR(83H_04H, 0x83, 0x04, UCP_F_FM | UCP_F_WM),
UCPDESCR(83H_08H, 0x83, 0x08, UCP_F_FM | UCP_F_WM),
- UCPDESCR(84H_01H, 0x84, 0x01, UCP_F_FM | UCP_F_WM),
+
+ UCPDESCR(84H_01H, 0x84, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB),
UCPDESCR(84H_02H, 0x84, 0x02, UCP_F_FM | UCP_F_WM),
UCPDESCR(84H_04H, 0x84, 0x04, UCP_F_FM | UCP_F_WM),
UCPDESCR(84H_08H, 0x84, 0x08, UCP_F_FM | UCP_F_WM),
@@ -766,6 +789,27 @@
}
static int
+ucp_event_sandybridge_ok_on_counter(enum pmc_event pe, int ri)
+{
+ uint32_t mask;
+
+ switch (pe) {
+ /*
+ * Events valid only on counter 0.
+ */
+ case PMC_EV_UCP_EVENT_80H_01H:
+ case PMC_EV_UCP_EVENT_83H_01H:
+ mask = (1 << 0);
+ break;
+
+ default:
+ mask = ~0; /* Any row index is ok. */
+ }
+
+ return (mask & (1 << ri));
+}
+
+static int
ucp_allocate_pmc(int cpu, int ri, struct pmc *pm,
const struct pmc_op_pmcallocate *a)
{
@@ -786,6 +830,16 @@
ev = pm->pm_event;
+ switch (uncore_cputype) {
+ case PMC_CPU_INTEL_SANDYBRIDGE:
+ if (ucp_event_sandybridge_ok_on_counter(ev, ri) == 0)
+ return (EINVAL);
+ break;
+ default:
+ break;
+ }
+
+
/*
* Look for an event descriptor with matching CPU and event id
* fields.
@@ -795,6 +849,9 @@
case PMC_CPU_INTEL_COREI7:
cpuflag = UCP_F_I7;
break;
+ case PMC_CPU_INTEL_SANDYBRIDGE:
+ cpuflag = UCP_F_SB;
+ break;
case PMC_CPU_INTEL_WESTMERE:
cpuflag = UCP_F_WM;
break;
@@ -968,8 +1025,9 @@
evsel = pm->pm_md.pm_ucp.pm_ucp_evsel;
- PMCDBG(MDP,STA,2, "ucp-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x",
- cpu, ri, UCP_EVSEL0 + ri, evsel);
+ PMCDBG(MDP,STA,2,
+ "ucp-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x",
+ cpu, ri, SELECTSEL(uncore_cputype) + ri, evsel);
/* Event specific configuration. */
switch (pm->pm_event) {
@@ -993,8 +1051,8 @@
break;
}
- wrmsr(UCP_EVSEL0 + ri, evsel);
-
+ wrmsr(SELECTSEL(uncore_cputype) + ri, evsel);
+
do {
cc->pc_resync = 0;
cc->pc_globalctrl |= (1ULL << ri);
@@ -1024,7 +1082,8 @@
PMCDBG(MDP,STO,1, "ucp-stop cpu=%d ri=%d", cpu, ri);
- wrmsr(UCP_EVSEL0 + ri, 0); /* stop hw */
+ /* stop hw. */
+ wrmsr(SELECTSEL(uncore_cputype) + ri, 0);
do {
cc->pc_resync = 0;
@@ -1128,7 +1187,7 @@
uncore_ucf_width = 48;
ucf_initialize(md, maxcpu, uncore_ucf_npmc, uncore_ucf_width);
- uncore_pmcmask |= ((1ULL << uncore_ucf_npmc) - 1) << UCF_OFFSET;
+ uncore_pmcmask |= ((1ULL << uncore_ucf_npmc) - 1) << SELECTOFF(uncore_cputype);
PMCDBG(MDP,INI,1,"uncore-init pmcmask=0x%jx ucfri=%d", uncore_pmcmask,
uncore_ucf_ri);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/hwpmc/hwpmc_uncore.h
--- a/head/sys/dev/hwpmc/hwpmc_uncore.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/hwpmc/hwpmc_uncore.h Fri Mar 02 17:36:33 2012 +0200
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/dev/hwpmc/hwpmc_uncore.h 230063 2012-01-13 17:13:46Z gnn $
+ * $FreeBSD: head/sys/dev/hwpmc/hwpmc_uncore.h 232366 2012-03-01 21:23:26Z davide $
*/
#ifndef _DEV_HWPMC_UNCORE_H_
@@ -68,6 +68,7 @@
#define UCF_CTR0 0x394
#define UCF_OFFSET 32
+#define UCF_OFFSET_SB 29
#define UCF_CTRL 0x395
/*
@@ -77,6 +78,7 @@
#define UCP_PMC0 0x3B0
#define UCP_EVSEL0 0x3C0
#define UCP_OPCODE_MATCH 0x396
+#define UCP_CB0_EVSEL0 0x700
/*
* Simplified programming interface in Intel Performance Architecture
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/hwpmc/pmc_events.h
--- a/head/sys/dev/hwpmc/pmc_events.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/hwpmc/pmc_events.h Fri Mar 02 17:36:33 2012 +0200
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/dev/hwpmc/pmc_events.h 229470 2012-01-04 07:58:36Z fabient $
+ * $FreeBSD: head/sys/dev/hwpmc/pmc_events.h 232366 2012-03-01 21:23:26Z davide $
*/
#ifndef _DEV_HWPMC_PMC_EVENTS_H_
@@ -520,6 +520,8 @@
__PMC_EV(IAP, EVENT_0CH_01H) \
__PMC_EV(IAP, EVENT_0CH_02H) \
__PMC_EV(IAP, EVENT_0CH_03H) \
+__PMC_EV(IAP, EVENT_0DH_03H) \
+__PMC_EV(IAP, EVENT_0DH_40H) \
__PMC_EV(IAP, EVENT_0EH_01H) \
__PMC_EV(IAP, EVENT_0EH_02H) \
__PMC_EV(IAP, EVENT_0FH_01H) \
@@ -540,6 +542,7 @@
__PMC_EV(IAP, EVENT_10H_81H) \
__PMC_EV(IAP, EVENT_11H_00H) \
__PMC_EV(IAP, EVENT_11H_01H) \
+__PMC_EV(IAP, EVENT_11H_02H) \
__PMC_EV(IAP, EVENT_11H_81H) \
__PMC_EV(IAP, EVENT_12H_00H) \
__PMC_EV(IAP, EVENT_12H_01H) \
@@ -664,6 +667,7 @@
__PMC_EV(IAP, EVENT_46H_00H) \
__PMC_EV(IAP, EVENT_47H_00H) \
__PMC_EV(IAP, EVENT_48H_00H) \
+__PMC_EV(IAP, EVENT_48H_01H) \
__PMC_EV(IAP, EVENT_48H_02H) \
__PMC_EV(IAP, EVENT_49H_00H) \
__PMC_EV(IAP, EVENT_49H_01H) \
@@ -680,6 +684,7 @@
__PMC_EV(IAP, EVENT_4BH_08H) \
__PMC_EV(IAP, EVENT_4CH_00H) \
__PMC_EV(IAP, EVENT_4CH_01H) \
+__PMC_EV(IAP, EVENT_4CH_02H) \
__PMC_EV(IAP, EVENT_4DH_01H) \
__PMC_EV(IAP, EVENT_4EH_01H) \
__PMC_EV(IAP, EVENT_4EH_02H) \
@@ -696,6 +701,16 @@
__PMC_EV(IAP, EVENT_51H_08H) \
__PMC_EV(IAP, EVENT_52H_01H) \
__PMC_EV(IAP, EVENT_53H_01H) \
+__PMC_EV(IAP, EVENT_59H_20H) \
+__PMC_EV(IAP, EVENT_59H_40H) \
+__PMC_EV(IAP, EVENT_59H_80H) \
+__PMC_EV(IAP, EVENT_5BH_0CH) \
+__PMC_EV(IAP, EVENT_5BH_0FH) \
+__PMC_EV(IAP, EVENT_5BH_40H) \
+__PMC_EV(IAP, EVENT_5BH_4FH) \
+__PMC_EV(IAP, EVENT_5CH_01H) \
+__PMC_EV(IAP, EVENT_5CH_02H) \
+__PMC_EV(IAP, EVENT_5EH_01H) \
__PMC_EV(IAP, EVENT_60H) \
__PMC_EV(IAP, EVENT_60H_01H) \
__PMC_EV(IAP, EVENT_60H_02H) \
@@ -725,6 +740,12 @@
__PMC_EV(IAP, EVENT_70H) \
__PMC_EV(IAP, EVENT_77H) \
__PMC_EV(IAP, EVENT_78H) \
+__PMC_EV(IAP, EVENT_79H_02H) \
+__PMC_EV(IAP, EVENT_79H_04H) \
+__PMC_EV(IAP, EVENT_79H_08H) \
+__PMC_EV(IAP, EVENT_79H_10H) \
+__PMC_EV(IAP, EVENT_79H_20H) \
+__PMC_EV(IAP, EVENT_79H_30H) \
__PMC_EV(IAP, EVENT_7AH) \
__PMC_EV(IAP, EVENT_7BH) \
__PMC_EV(IAP, EVENT_7DH) \
@@ -773,7 +794,9 @@
__PMC_EV(IAP, EVENT_88H_20H) \
__PMC_EV(IAP, EVENT_88H_30H) \
__PMC_EV(IAP, EVENT_88H_40H) \
+__PMC_EV(IAP, EVENT_88H_80H) \
__PMC_EV(IAP, EVENT_88H_7FH) \
+__PMC_EV(IAP, EVENT_88H_FFH) \
__PMC_EV(IAP, EVENT_89H_00H) \
__PMC_EV(IAP, EVENT_89H_01H) \
__PMC_EV(IAP, EVENT_89H_02H) \
@@ -784,7 +807,9 @@
__PMC_EV(IAP, EVENT_89H_20H) \
__PMC_EV(IAP, EVENT_89H_30H) \
__PMC_EV(IAP, EVENT_89H_40H) \
+__PMC_EV(IAP, EVENT_89H_80H) \
__PMC_EV(IAP, EVENT_89H_7FH) \
+__PMC_EV(IAP, EVENT_89H_FFH) \
__PMC_EV(IAP, EVENT_8AH_00H) \
__PMC_EV(IAP, EVENT_8BH_00H) \
__PMC_EV(IAP, EVENT_8CH_00H) \
@@ -798,13 +823,18 @@
__PMC_EV(IAP, EVENT_94H_00H) \
__PMC_EV(IAP, EVENT_97H_00H) \
__PMC_EV(IAP, EVENT_98H_00H) \
+__PMC_EV(IAP, EVENT_9CH_01H) \
__PMC_EV(IAP, EVENT_A0H_00H) \
__PMC_EV(IAP, EVENT_A1H_01H) \
__PMC_EV(IAP, EVENT_A1H_02H) \
__PMC_EV(IAP, EVENT_A1H_04H) \
__PMC_EV(IAP, EVENT_A1H_08H) \
+__PMC_EV(IAP, EVENT_A1H_0CH) \
__PMC_EV(IAP, EVENT_A1H_10H) \
__PMC_EV(IAP, EVENT_A1H_20H) \
+__PMC_EV(IAP, EVENT_A1H_30H) \
+__PMC_EV(IAP, EVENT_A1H_40H) \
+__PMC_EV(IAP, EVENT_A1H_80H) \
__PMC_EV(IAP, EVENT_A2H_00H) \
__PMC_EV(IAP, EVENT_A2H_01H) \
__PMC_EV(IAP, EVENT_A2H_02H) \
@@ -823,6 +853,9 @@
__PMC_EV(IAP, EVENT_AAH_08H) \
__PMC_EV(IAP, EVENT_ABH_01H) \
__PMC_EV(IAP, EVENT_ABH_02H) \
+__PMC_EV(IAP, EVENT_ACH_02H) \
+__PMC_EV(IAP, EVENT_ACH_08H) \
+__PMC_EV(IAP, EVENT_ACH_0AH) \
__PMC_EV(IAP, EVENT_AEH_01H) \
__PMC_EV(IAP, EVENT_B0H_00H) \
__PMC_EV(IAP, EVENT_B0H_01H) \
@@ -860,6 +893,7 @@
__PMC_EV(IAP, EVENT_B4H_01H) \
__PMC_EV(IAP, EVENT_B4H_02H) \
__PMC_EV(IAP, EVENT_B4H_04H) \
+__PMC_EV(IAP, EVENT_B6H_01H) \
__PMC_EV(IAP, EVENT_B7H_01H) \
__PMC_EV(IAP, EVENT_B8H_01H) \
__PMC_EV(IAP, EVENT_B8H_02H) \
@@ -867,6 +901,9 @@
__PMC_EV(IAP, EVENT_BAH_01H) \
__PMC_EV(IAP, EVENT_BAH_02H) \
__PMC_EV(IAP, EVENT_BBH_01H) \
+__PMC_EV(IAP, EVENT_BDH_01H) \
+__PMC_EV(IAP, EVENT_BDH_20H) \
+__PMC_EV(IAP, EVENT_BFH_05H) \
__PMC_EV(IAP, EVENT_C0H_00H) \
__PMC_EV(IAP, EVENT_C0H_01H) \
__PMC_EV(IAP, EVENT_C0H_02H) \
@@ -874,6 +911,10 @@
__PMC_EV(IAP, EVENT_C0H_08H) \
__PMC_EV(IAP, EVENT_C1H_00H) \
__PMC_EV(IAP, EVENT_C1H_01H) \
+__PMC_EV(IAP, EVENT_C1H_02H) \
+__PMC_EV(IAP, EVENT_C1H_08H) \
+__PMC_EV(IAP, EVENT_C1H_10H) \
+__PMC_EV(IAP, EVENT_C1H_20H) \
__PMC_EV(IAP, EVENT_C1H_FEH) \
__PMC_EV(IAP, EVENT_C2H_00H) \
__PMC_EV(IAP, EVENT_C2H_01H) \
@@ -888,6 +929,7 @@
__PMC_EV(IAP, EVENT_C3H_02H) \
__PMC_EV(IAP, EVENT_C3H_04H) \
__PMC_EV(IAP, EVENT_C3H_10H) \
+__PMC_EV(IAP, EVENT_C3H_20H) \
__PMC_EV(IAP, EVENT_C4H_00H) \
__PMC_EV(IAP, EVENT_C4H_01H) \
__PMC_EV(IAP, EVENT_C4H_02H) \
@@ -895,10 +937,15 @@
__PMC_EV(IAP, EVENT_C4H_08H) \
__PMC_EV(IAP, EVENT_C4H_0CH) \
__PMC_EV(IAP, EVENT_C4H_0FH) \
+__PMC_EV(IAP, EVENT_C4H_10H) \
+__PMC_EV(IAP, EVENT_C4H_20H) \
+__PMC_EV(IAP, EVENT_C4H_40H) \
__PMC_EV(IAP, EVENT_C5H_00H) \
__PMC_EV(IAP, EVENT_C5H_01H) \
__PMC_EV(IAP, EVENT_C5H_02H) \
__PMC_EV(IAP, EVENT_C5H_04H) \
+__PMC_EV(IAP, EVENT_C5H_10H) \
+__PMC_EV(IAP, EVENT_C5H_20H) \
__PMC_EV(IAP, EVENT_C6H_00H) \
__PMC_EV(IAP, EVENT_C6H_01H) \
__PMC_EV(IAP, EVENT_C6H_02H) \
@@ -917,6 +964,8 @@
__PMC_EV(IAP, EVENT_CAH_02H) \
__PMC_EV(IAP, EVENT_CAH_04H) \
__PMC_EV(IAP, EVENT_CAH_08H) \
+__PMC_EV(IAP, EVENT_CAH_10H) \
+__PMC_EV(IAP, EVENT_CAH_1EH) \
__PMC_EV(IAP, EVENT_CBH_01H) \
__PMC_EV(IAP, EVENT_CBH_02H) \
__PMC_EV(IAP, EVENT_CBH_04H) \
@@ -928,15 +977,24 @@
__PMC_EV(IAP, EVENT_CCH_01H) \
__PMC_EV(IAP, EVENT_CCH_02H) \
__PMC_EV(IAP, EVENT_CCH_03H) \
+__PMC_EV(IAP, EVENT_CCH_20H) \
__PMC_EV(IAP, EVENT_CDH_00H) \
+__PMC_EV(IAP, EVENT_CDH_01H) \
+__PMC_EV(IAP, EVENT_CDH_02H) \
__PMC_EV(IAP, EVENT_CEH_00H) \
__PMC_EV(IAP, EVENT_CFH_00H) \
__PMC_EV(IAP, EVENT_D0H_00H) \
__PMC_EV(IAP, EVENT_D0H_01H) \
+__PMC_EV(IAP, EVENT_D0H_02H) \
+__PMC_EV(IAP, EVENT_D0H_10H) \
+__PMC_EV(IAP, EVENT_D0H_20H) \
+__PMC_EV(IAP, EVENT_D0H_40H) \
+__PMC_EV(IAP, EVENT_D0H_80H) \
__PMC_EV(IAP, EVENT_D1H_01H) \
__PMC_EV(IAP, EVENT_D1H_02H) \
__PMC_EV(IAP, EVENT_D1H_04H) \
__PMC_EV(IAP, EVENT_D1H_08H) \
+__PMC_EV(IAP, EVENT_D1H_40H) \
__PMC_EV(IAP, EVENT_D2H_01H) \
__PMC_EV(IAP, EVENT_D2H_02H) \
__PMC_EV(IAP, EVENT_D2H_04H) \
@@ -996,6 +1054,7 @@
__PMC_EV(IAP, EVENT_F0H_20H) \
__PMC_EV(IAP, EVENT_F0H_40H) \
__PMC_EV(IAP, EVENT_F0H_80H) \
+__PMC_EV(IAP, EVENT_F1H_01H) \
__PMC_EV(IAP, EVENT_F1H_02H) \
__PMC_EV(IAP, EVENT_F1H_04H) \
__PMC_EV(IAP, EVENT_F1H_07H) \
@@ -1003,6 +1062,7 @@
__PMC_EV(IAP, EVENT_F2H_02H) \
__PMC_EV(IAP, EVENT_F2H_04H) \
__PMC_EV(IAP, EVENT_F2H_08H) \
+__PMC_EV(IAP, EVENT_F2H_0AH) \
__PMC_EV(IAP, EVENT_F2H_0FH) \
__PMC_EV(IAP, EVENT_F3H_01H) \
__PMC_EV(IAP, EVENT_F3H_02H) \
@@ -2318,6 +2378,220 @@
__PMC_EV_ALIAS("SIMD_INT_64.PACKED_ARITH", IAP_EVENT_FDH_20H) \
__PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H)
+/*
+ * Aliases for Sandy Bridge PMC events (253669-039US May 2011)
+ */
+
+#define __PMC_EV_ALIAS_SANDYBRIDGE() \
+__PMC_EV_ALIAS_INTEL_ARCHITECTURAL() \
+__PMC_EV_ALIAS("LD_BLOCKS.DATA_UNKNOWN", IAP_EVENT_03H_01H) \
+__PMC_EV_ALIAS("LD_BLOCKS.STORE_FORWARD", IAP_EVENT_03H_02H) \
+__PMC_EV_ALIAS("LD_BLOCKS.NO_SR", IAP_EVENT_03H_08H) \
+__PMC_EV_ALIAS("LD_BLOCKS.ALL_BLOCK", IAP_EVENT_03H_10H) \
+__PMC_EV_ALIAS("MISALIGN_MEM_REF.LOADS", IAP_EVENT_05H_01H) \
+__PMC_EV_ALIAS("MISALIGN_MEM_REF.STORES", IAP_EVENT_05H_02H) \
+__PMC_EV_ALIAS("LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", IAP_EVENT_07H_01H) \
+__PMC_EV_ALIAS("LD_BLOCKS_PARTIAL.ALL_STA_BLOCK", IAP_EVENT_07H_08H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK", IAP_EVENT_08H_01H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED", IAP_EVENT_08H_02H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_DURATION", IAP_EVENT_08H_04H) \
+__PMC_EV_ALIAS("DTLB_LOAD_MISSES.STLB_HIT", IAP_EVENT_08H_10H) \
+__PMC_EV_ALIAS("INT_MISC.RECOVERY_CYCLES", IAP_EVENT_0DH_03H) \
+__PMC_EV_ALIAS("INT_MISC.RAT_STALL_CYCLES", IAP_EVENT_0DH_40H) \
+__PMC_EV_ALIAS("UOPS_ISSUED.ANY", IAP_EVENT_0EH_01H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.X87", IAP_EVENT_10H_01H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_PACKED_DOUBLE", IAP_EVENT_10H_10H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_SCALAR_SINGLE", IAP_EVENT_10H_20H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_PACKED_SINGLE", IAP_EVENT_10H_40H) \
+__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_SCALAR_DOUBLE", IAP_EVENT_10H_80H) \
+__PMC_EV_ALIAS("SIMD_FP_256.PACKED_SINGLE", IAP_EVENT_11H_01H) \
+__PMC_EV_ALIAS("SIMD_FP_256.PACKED_DOUBLE", IAP_EVENT_11H_02H) \
+__PMC_EV_ALIAS("ARITH.FPU_DIV_ACTIVE", IAP_EVENT_14H_01H) \
+__PMC_EV_ALIAS("INSTS_WRITTEN_TO_IQ.INSTS", IAP_EVENT_17H_01H) \
+__PMC_EV_ALIAS("L2_RQSTS.DEMAND_DATA_RD_HIT", IAP_EVENT_24H_01H) \
+__PMC_EV_ALIAS("L2_RQSTS.ALL_DEMAND_DATA_RD", IAP_EVENT_24H_03H) \
+__PMC_EV_ALIAS("L2_RQSTS.RFO_HITS", IAP_EVENT_24H_04H) \
+__PMC_EV_ALIAS("L2_RQSTS.RFO_MISS", IAP_EVENT_24H_08H) \
+__PMC_EV_ALIAS("L2_RQSTS.ALL_RFO", IAP_EVENT_24H_0CH) \
+__PMC_EV_ALIAS("L2_RQSTS.CODE_RD_HIT", IAP_EVENT_24H_10H) \
+__PMC_EV_ALIAS("L2_RQSTS.CODE_RD_MISS", IAP_EVENT_24H_20H) \
+__PMC_EV_ALIAS("L2_RQSTS.ALL_CODE_RD", IAP_EVENT_24H_30H) \
+__PMC_EV_ALIAS("L2_RQSTS.PF_HIT", IAP_EVENT_24H_40H) \
+__PMC_EV_ALIAS("L2_RQSTS.PF_MISS", IAP_EVENT_24H_80H) \
+__PMC_EV_ALIAS("L2_RQSTS.ALL_PF", IAP_EVENT_24H_C0H) \
+__PMC_EV_ALIAS("L2_STORE_LOCK_RQSTS.MISS", IAP_EVENT_27H_01H) \
+__PMC_EV_ALIAS("L2_STORE_LOCK_RQSTS.HIT_E", IAP_EVENT_27H_04H) \
+__PMC_EV_ALIAS("L2_STORE_LOCK_RQSTS.HIT_M", IAP_EVENT_27H_08H) \
+__PMC_EV_ALIAS("L2_STORE_LOCK_RQSTS.ALL", IAP_EVENT_27H_0FH) \
+__PMC_EV_ALIAS("L2_L1D_WB_RQSTS.HIT_E", IAP_EVENT_28H_04H) \
+__PMC_EV_ALIAS("L2_L1D_WB_RQSTS.HIT_M", IAP_EVENT_28H_08H) \
+__PMC_EV_ALIAS("LONGEST_LAT_CACHE.REFERENCE", IAP_EVENT_2EH_4FH) \
+__PMC_EV_ALIAS("LONGEST_LAT_CACHE.MISS", IAP_EVENT_2EH_41H) \
+__PMC_EV_ALIAS("CPU_CLK_UNHALTED.THREAD_P", IAP_EVENT_3CH_00H) \
+__PMC_EV_ALIAS("CPU_CLK_THREAD_UNHALTED.REF_XCLK", IAP_EVENT_3CH_01H) \
+__PMC_EV_ALIAS("L1D_PEND_MISS.PENDING", IAP_EVENT_48H_01H) \
+__PMC_EV_ALIAS("DTLB_STORE_MISSES.MISS_CAUSES_A_WALK", IAP_EVENT_49H_01H) \
+__PMC_EV_ALIAS("DTLB_STORE_MISSES.WALK_COMPLETED", IAP_EVENT_49H_02H) \
+__PMC_EV_ALIAS("DTLB_STORE_MISSES.WALK_DURATION", IAP_EVENT_49H_04H) \
+__PMC_EV_ALIAS("DTLB_STORE_MISSES.STLB_HIT", IAP_EVENT_49H_10H) \
+__PMC_EV_ALIAS("LOAD_HIT_PRE.SW_PF", IAP_EVENT_4CH_01H) \
+__PMC_EV_ALIAS("LOAD_HIT_PER.HW_PF", IAP_EVENT_4CH_02H) \
+__PMC_EV_ALIAS("HW_PRE_REQ.DL1_MISS", IAP_EVENT_4EH_02H) \
+__PMC_EV_ALIAS("L1D.REPLACEMENT", IAP_EVENT_51H_01H) \
+__PMC_EV_ALIAS("L1D.ALLOCATED_IN_M", IAP_EVENT_51H_02H) \
+__PMC_EV_ALIAS("L1D.EVICTION", IAP_EVENT_51H_04H) \
+__PMC_EV_ALIAS("L1D.ALL_M_REPLACEMENT", IAP_EVENT_51H_08H) \
+__PMC_EV_ALIAS("PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP", IAP_EVENT_59H_20H) \
+__PMC_EV_ALIAS("PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW", IAP_EVENT_59H_40H) \
+__PMC_EV_ALIAS("PARTIAL_RAT_STALLS.MUL_SINGLE_UOP", IAP_EVENT_59H_80H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS2.ALL_FL_EMPTY", IAP_EVENT_5BH_0CH) \
+__PMC_EV_ALIAS("RESOURCE_STALLS2.ALL_PRF_CONTROL", IAP_EVENT_5BH_0FH) \
+__PMC_EV_ALIAS("RESOURCE_STALLS2.BOB_FULL", IAP_EVENT_5BH_40H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS2.OOO_RSRC", IAP_EVENT_5BH_4FH) \
+__PMC_EV_ALIAS("CPL_CYCLES.RING0", IAP_EVENT_5CH_01H) \
+__PMC_EV_ALIAS("CPL_CYCLES.RING123", IAP_EVENT_5CH_02H) \
+__PMC_EV_ALIAS("RS_EVENTS.EMPTY_CYCLES", IAP_EVENT_5EH_01H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD", IAP_EVENT_60H_01H)\
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND_RFO", IAP_EVENT_60H_04H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD", IAP_EVENT_60H_08H) \
+__PMC_EV_ALIAS("LOCK_CYCLES.SPLIT_LOCK_UC_LOCK_DURATION", IAP_EVENT_63H_01H) \
+__PMC_EV_ALIAS("LOCK_CYCLES.CACHE_LOCK_DURATION", IAP_EVENT_63H_02H) \
+__PMC_EV_ALIAS("IDQ.EMPTY", IAP_EVENT_79H_02H) \
+__PMC_EV_ALIAS("IQD.MITE_UOPS", IAP_EVENT_79H_04H) \
+__PMC_EV_ALIAS("IDQ.DSB_UOPS", IAP_EVENT_79H_08H) \
+__PMC_EV_ALIAS("IDQ.MS_DSB_UOPS", IAP_EVENT_79H_10H) \
+__PMC_EV_ALIAS("IDQ.MS_MITE_UOPS", IAP_EVENT_79H_20H) \
+__PMC_EV_ALIAS("IDQ.MS_UOPS", IAP_EVENT_79H_30H) \
+__PMC_EV_ALIAS("ICACHE.MISSES", IAP_EVENT_80H_02H) \
+__PMC_EV_ALIAS("ITLB_MISSES.MISS_CAUSES_A_WALK", IAP_EVENT_85H_01H) \
+__PMC_EV_ALIAS("ITLB_MISSES.WALK_COMPLETED", IAP_EVENT_85H_02H) \
+__PMC_EV_ALIAS("ITLB_MISSES.WALK_DURATION", IAP_EVENT_85H_04H) \
+__PMC_EV_ALIAS("ITLB_MISSES.STLB_HIT", IAP_EVENT_85H_10H) \
+__PMC_EV_ALIAS("ILD_STALL.LCP", IAP_EVENT_87H_01H) \
+__PMC_EV_ALIAS("ILD_STALL.IQ_FULL", IAP_EVENT_87H_04H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.COND", IAP_EVENT_88H_01H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT_JMP", IAP_EVENT_88H_02H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_JMP_NON_CALL_RET", IAP_EVENT_88H_04H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.RETURN_NEAR", IAP_EVENT_88H_08H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_88H_10H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_88H_20H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.NONTAKEN", IAP_EVENT_88H_40H) \
+__PMC_EV_ALIAS("BR_INST_EXEC.TAKEN", IAP_EVENT_88H_80H) \
+__PMC_EV_ALIAS("BR_INST_EXE.ALL_BRANCHES", IAP_EVENT_88H_FFH) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.COND", IAP_EVENT_89H_01H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_JMP_NON_CALL_RET", IAP_EVENT_89H_04H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.RETURN_NEAR", IAP_EVENT_89H_08H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_89H_10H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_89H_20H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.NONTAKEN", IAP_EVENT_89H_40H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.TAKEN", IAP_EVENT_89H_80H) \
+__PMC_EV_ALIAS("BR_MISP_EXEC.ALL_BRANCHES", IAP_EVENT_89H_FFH) \
+__PMC_EV_ALIAS("IDQ_UOPS_NOT_DELIVERED.CORE", IAP_EVENT_9CH_01H) \
+__PMC_EV_ALIAS("UOPS_DISPATCHED_PORT.PORT_0", IAP_EVENT_A1H_01H) \
+__PMC_EV_ALIAS("UOPS_DISPATCHED_PORT.PORT_1", IAP_EVENT_A1H_02H) \
+__PMC_EV_ALIAS("UOPS_DISPATCHED_PORT.PORT_2_LD", IAP_EVENT_A1H_04H) \
+__PMC_EV_ALIAS("UOPS_DISPATCHED_PORT.PORT_2_STA", IAP_EVENT_A1H_08H) \
+__PMC_EV_ALIAS("UOPS_DISPATCHED_PORT.PORT_2", IAP_EVENT_A1H_0CH) \
+__PMC_EV_ALIAS("UOPS_DISPATCHED_PORT.PORT_3_LD", IAP_EVENT_A1H_10H) \
+__PMC_EV_ALIAS("UOPS_DISPATCHED_PORT.PORT_3_STA", IAP_EVENT_A1H_20H) \
+__PMC_EV_ALIAS("UOPS_DISPATCHED_PORT.PORT_3", IAP_EVENT_A1H_30H) \
+__PMC_EV_ALIAS("UOPS_DISPATCHED_PORT.PORT_4", IAP_EVENT_A1H_40H) \
+__PMC_EV_ALIAS("UOPS_DISPATCHED_PORT.PORT_5", IAP_EVENT_A1H_80H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.ANY", IAP_EVENT_A2H_01H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.LB", IAP_EVENT_A2H_04H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.SB", IAP_EVENT_A2H_08H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.ROB", IAP_EVENT_A2H_10H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.FCSW", IAP_EVENT_A2H_20H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.MXCSR", IAP_EVENT_A2H_40H) \
+__PMC_EV_ALIAS("RESOURCE_STALLS.OTHER", IAP_EVENT_A2H_80H) \
+__PMC_EV_ALIAS("DSB2MITE_SWITCHES.COUNT", IAP_EVENT_ABH_01H) \
+__PMC_EV_ALIAS("DSB2MITE_SWITCHES.PENALTY_CYCLES", IAP_EVENT_ABH_02H) \
+__PMC_EV_ALIAS("DSB_FILL.OTHER_CANCEL", IAP_EVENT_ACH_02H) \
+__PMC_EV_ALIAS("DSB_FILL.EXCEED_DSB_LINES", IAP_EVENT_ACH_08H) \
+__PMC_EV_ALIAS("DSB_FILL.ALL_CANCEL", IAP_EVENT_ACH_0AH) \
+__PMC_EV_ALIAS("ITLB.ITLB_FLUSH", IAP_EVENT_AEH_01H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND_DATA_RD", IAP_EVENT_B0H_01H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND_RFO", IAP_EVENT_B0H_04H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS.ALL_DATA_RD", IAP_EVENT_B0H_08H) \
+__PMC_EV_ALIAS("UOPS_DISPATCHED.THREAD", IAP_EVENT_B1H_01H) \
+__PMC_EV_ALIAS("UOPS_DISPATCHED.CORE", IAP_EVENT_B1H_02H) \
+__PMC_EV_ALIAS("OFFCORE_REQUESTS_BUFFER.SQ_FULL", IAP_EVENT_B2H_01H) \
+__PMC_EV_ALIAS("AGU_BYPASS_CANCEL.COUNT", IAP_EVENT_B6H_01H) \
+__PMC_EV_ALIAS("OFF_CORE_RESPONSE_0", IAP_EVENT_B7H_01H) \
+__PMC_EV_ALIAS("OFF_CORE_RESPONSE_1", IAP_EVENT_BBH_01H) \
+__PMC_EV_ALIAS("TLB_FLUSH.DTLB_THREAD", IAP_EVENT_BDH_01H) \
+__PMC_EV_ALIAS("TLB_FLUSH.STLB_ANY", IAP_EVENT_BDH_20H) \
+__PMC_EV_ALIAS("L1D_BLOCKS.BANK_CONFLICT_CYCLES", IAP_EVENT_BFH_05H) \
+__PMC_EV_ALIAS("INST_RETIRED.ANY_P", IAP_EVENT_C0H_00H) \
+__PMC_EV_ALIAS("INST_RETIRED.PREC_DIST", IAP_EVENT_C0H_01H) \
+__PMC_EV_ALIAS("INST_RETIRED.X87", IAP_EVENT_C0H_02H) \
+__PMC_EV_ALIAS("OTHER_ASSISTS.ITLB_MISS_RETIRED", IAP_EVENT_C1H_02H) \
+__PMC_EV_ALIAS("OTHER_ASSISTS.AVX_STORE", IAP_EVENT_C1H_08H) \
+__PMC_EV_ALIAS("OTHER_ASSISTS.AVX_TO_SSE", IAP_EVENT_C1H_10H) \
+__PMC_EV_ALIAS("OTHER_ASSISTS.SSE_TO_AVX", IAP_EVENT_C1H_20H) \
+__PMC_EV_ALIAS("UOPS_RETIRED.ALL", IAP_EVENT_C2H_01H) \
+__PMC_EV_ALIAS("UOPS_RETIRED.RETIRE_SLOTS", IAP_EVENT_C2H_02H) \
+__PMC_EV_ALIAS("MACHINE_CLEARS.MEMORY_ORDERING", IAP_EVENT_C3H_02H) \
+__PMC_EV_ALIAS("MACHINE_CLEARS.SMC", IAP_EVENT_C3H_04H) \
+__PMC_EV_ALIAS("MACHINE_CLEARS.MASKMOV", IAP_EVENT_C3H_20H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCH", IAP_EVENT_C4H_00H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.CONDITIONAL", IAP_EVENT_C4H_01H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.NEAR_CALL", IAP_EVENT_C4H_02H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES", IAP_EVENT_C4H_04H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.NEAR_RETURN", IAP_EVENT_C4H_08H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.NOT_TAKEN", IAP_EVENT_C4H_10H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.NEAR_TAKEN", IAP_EVENT_C4H_20H) \
+__PMC_EV_ALIAS("BR_INST_RETIRED.FAR_BRANCH", IAP_EVENT_C4H_40H) \
+__PMC_EV_ALIAS("BR_MISP_RETIRED.ALL_BRANCHES", IAP_EVENT_C5H_00H) \
+__PMC_EV_ALIAS("BR_MISP_RETIRED.CONDITIONAL", IAP_EVENT_C5H_01H) \
+__PMC_EV_ALIAS("BR_MISP_RETIRED.NEAR_CALL", IAP_EVENT_C5H_02H) \
+__PMC_EV_ALIAS("BR_MISP_RETIRED.ALL_BRANCHES", IAP_EVENT_C5H_04H) \
+__PMC_EV_ALIAS("BR_MISP_RETIRED.NOT_TAKEN", IAP_EVENT_C5H_10H) \
+__PMC_EV_ALIAS("BR_MISP_RETIRED.TAKEN", IAP_EVENT_C5H_20H) \
+__PMC_EV_ALIAS("FP_ASSIST.X87_OUTPUT", IAP_EVENT_CAH_02H) \
+__PMC_EV_ALIAS("FP_ASSIST.X87_INPUT", IAP_EVENT_CAH_04H) \
+__PMC_EV_ALIAS("FP_ASSIST.SIMD_OUTPUT", IAP_EVENT_CAH_08H) \
+__PMC_EV_ALIAS("FP_ASSIST.SIMD_INPUT", IAP_EVENT_CAH_10H) \
+__PMC_EV_ALIAS("FP_ASSIST.ANY", IAP_EVENT_CAH_1EH) \
+__PMC_EV_ALIAS("ROB_MISC_EVENTS.LBR_INSERTS", IAP_EVENT_CCH_20H) \
+__PMC_EV_ALIAS("MEM_TRANS_RETIRED.LOAD_LATENCY", IAP_EVENT_CDH_01H) \
+__PMC_EV_ALIAS("MEM_TRANS_RETIRED.PRECISE_STORE", IAP_EVENT_CDH_02H) \
+__PMC_EV_ALIAS("MEM_UOP_RETIRED.LOADS", IAP_EVENT_D0H_01H) \
+__PMC_EV_ALIAS("MEM_UOP_RETIRED.STORES", IAP_EVENT_D0H_02H) \
+__PMC_EV_ALIAS("MEM_UOP_RETIRED.STLB_MISS", IAP_EVENT_D0H_10H) \
+__PMC_EV_ALIAS("MEM_UOP_RETIRED.LOCK", IAP_EVENT_D0H_20H) \
+__PMC_EV_ALIAS("MEM_UOP_RETIRED.SPLIT", IAP_EVENT_D0H_40H) \
+__PMC_EV_ALIAS("MEM_UOP_RETIRED_ALL", IAP_EVENT_D0H_80H) \
+__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L1_HIT", IAP_EVENT_D1H_01H) \
+__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L2_HIT", IAP_EVENT_D1H_02H) \
+__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.LLC_HIT", IAP_EVENT_D1H_04H) \
+__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.HIT_LFB", IAP_EVENT_D1H_40H) \
+__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS", IAP_EVENT_D2H_01H) \
+__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT", IAP_EVENT_D2H_02H) \
+__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM", IAP_EVENT_D2H_04H) \
+__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_NONE", IAP_EVENT_D2H_08H) \
+__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.LLC_MISS", IAP_EVENT_D4H_02H) \
+__PMC_EV_ALIAS("L2_TRANS.DEMAND_DATA_RD", IAP_EVENT_F0H_01H) \
+__PMC_EV_ALIAS("L2_TRANS.RF0", IAP_EVENT_F0H_02H) \
+__PMC_EV_ALIAS("L2_TRANS.CODE_RD", IAP_EVENT_F0H_04H) \
+__PMC_EV_ALIAS("L2_TRANS.ALL_PF", IAP_EVENT_F0H_08H) \
+__PMC_EV_ALIAS("L2_TRANS.L1D_WB", IAP_EVENT_F0H_10H) \
+__PMC_EV_ALIAS("L2_TRANS.L2_FILL", IAP_EVENT_F0H_20H) \
+__PMC_EV_ALIAS("L2_TRANS.L2_WB", IAP_EVENT_F0H_40H) \
+__PMC_EV_ALIAS("L2_TRANS.ALL_REQUESTS", IAP_EVENT_F0H_80H) \
+__PMC_EV_ALIAS("L2_LINES_IN.I", IAP_EVENT_F1H_01H) \
+__PMC_EV_ALIAS("L2_LINES_IN.S", IAP_EVENT_F1H_02H) \
+__PMC_EV_ALIAS("L2_LINES_IN.E", IAP_EVENT_F1H_04H) \
+__PMC_EV_ALIAS("L2_LINES-IN.ALL", IAP_EVENT_F1H_07H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_CLEAN", IAP_EVENT_F2H_01H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_DIRTY", IAP_EVENT_F2H_02H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.PF_CLEAN", IAP_EVENT_F2H_04H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.PF_DIRTY", IAP_EVENT_F2H_08H) \
+__PMC_EV_ALIAS("L2_LINES_OUT.DIRTY_ALL", IAP_EVENT_F2H_0AH) \
+__PMC_EV_ALIAS("SQ_MISC.SPLIT_LOCK", IAP_EVENT_F4H_10H)
+
+
+
/* timestamp counters. */
#define __PMC_EV_TSC() \
__PMC_EV(TSC, TSC)
@@ -2408,6 +2682,10 @@
__PMC_EV(UCP, EVENT_22H_01H) \
__PMC_EV(UCP, EVENT_22H_02H) \
__PMC_EV(UCP, EVENT_22H_04H) \
+__PMC_EV(UCP, EVENT_22H_08H) \
+__PMC_EV(UCP, EVENT_22H_20H) \
+__PMC_EV(UCP, EVENT_22H_40H) \
+__PMC_EV(UCP, EVENT_22H_80H) \
__PMC_EV(UCP, EVENT_23H_01H) \
__PMC_EV(UCP, EVENT_23H_02H) \
__PMC_EV(UCP, EVENT_23H_04H) \
@@ -2485,6 +2763,8 @@
__PMC_EV(UCP, EVENT_34H_08H) \
__PMC_EV(UCP, EVENT_34H_10H) \
__PMC_EV(UCP, EVENT_34H_20H) \
+__PMC_EV(UCP, EVENT_34H_40H) \
+__PMC_EV(UCP, EVENT_34H_80H) \
__PMC_EV(UCP, EVENT_35H_01H) \
__PMC_EV(UCP, EVENT_35H_02H) \
__PMC_EV(UCP, EVENT_35H_04H) \
@@ -2546,6 +2826,8 @@
__PMC_EV(UCP, EVENT_81H_02H) \
__PMC_EV(UCP, EVENT_81H_04H) \
__PMC_EV(UCP, EVENT_81H_08H) \
+__PMC_EV(UCP, EVENT_81H_20H) \
+__PMC_EV(UCP, EVENT_81H_80H) \
__PMC_EV(UCP, EVENT_82H_01H) \
__PMC_EV(UCP, EVENT_83H_01H) \
__PMC_EV(UCP, EVENT_83H_02H) \
@@ -2959,6 +3241,30 @@
__PMC_EV_ALIAS("CYCLES_UNHALTED_L3_FLL_ENABLE", UCP_EVENT_85H_02H) \
__PMC_EV_ALIAS("CYCLES_UNHALTED_L3_FLL_DISABLE", UCP_EVENT_86H_01H)
+
+#define __PMC_EV_ALIAS_SANDYBRIDGEUC() \
+__PMC_EV_ALIAS("CB0_XSNP_RESPONSE.RSPIHITI", UCP_EVENT_22H_01H) \
+__PMC_EV_ALIAS("CB0_XSNP_RESPONSE.RSPIHITFSE", UCP_EVENT_22H_02H) \
+__PMC_EV_ALIAS("CB0_XSNP_RESPONSE.RSPSHITFSE", UCP_EVENT_22H_04H) \
+__PMC_EV_ALIAS("CB0_XSNP_RESPONSE.RSPSFWDM", UCP_EVENT_22H_08H) \
+__PMC_EV_ALIAS("CB0_XSNP_RESPONSE.AND_EXTERNAL", UCP_EVENT_22H_20H) \
+__PMC_EV_ALIAS("CB0_XSNP_RESPONSE.AND_XCORE", UCP_EVENT_22H_40H) \
+__PMC_EV_ALIAS("CB0_XSNP_RESPONSE_AND_XCORE2", UCP_EVENT_22H_80H) \
+__PMC_EV_ALIAS("CB0_CACHE_LOOKUP.M", UCP_EVENT_34H_01H) \
+__PMC_EV_ALIAS("CB0_CACHE_LOOKUP.E", UCP_EVENT_34H_02H) \
+__PMC_EV_ALIAS("CB0_CACHE_LOOKUP.S", UCP_EVENT_34H_04H) \
+__PMC_EV_ALIAS("CB0_CACHE_LOOKUP.I", UCP_EVENT_34H_08H) \
+__PMC_EV_ALIAS("CB0_CACHE_LOOKUP.AND_READ", UCP_EVENT_34H_10H) \
+__PMC_EV_ALIAS("CB0_CACHE_LOOKUP_AND_READ2", UCP_EVENT_34H_20H) \
+__PMC_EV_ALIAS("CB0_CACHE_LOOKUP.AND_EXTSNP", UCP_EVENT_34H_40H) \
+__PMC_EV_ALIAS("CB0_CACHE_LOOKUP.AND_ANY", UCP_EVENT_34H_80H) \
+__PMC_EV_ALIAS("IMPH_CB0_TRK_OCCUPANCY.ALL", UCP_EVENT_80H_01H) \
+__PMC_EV_ALIAS("IMPH_CB0_TRK_REQUEST.ALL", UCP_EVENT_81H_01H) \
+__PMC_EV_ALIAS("IMPH_CB0_TRK_REQUEST.WRITES", UCP_EVENT_81H_20H) \
+__PMC_EV_ALIAS("IMPH_CB0_TRK_REQUEST.EVICTIONS", UCP_EVENT_81H_80H) \
+__PMC_EV_ALIAS("IMPH_C0H_TRK_OCCUPANCY.ALL", UCP_EVENT_83H_01H) \
+__PMC_EV_ALIAS("IMPC_C0H_TRK_REQUEST.ALL", UCP_EVENT_84H_01H)
+
/*
* Intel XScale events from:
*
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/iicbus/iicbb.c
--- a/head/sys/dev/iicbus/iicbb.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/iicbus/iicbb.c Fri Mar 02 17:36:33 2012 +0200
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/iicbus/iicbb.c 228728 2011-12-20 02:49:01Z adrian $");
+__FBSDID("$FreeBSD: head/sys/dev/iicbus/iicbb.c 232365 2012-03-01 20:58:20Z kan $");
/*
* Generic I2C bit-banging code
@@ -76,6 +76,7 @@
static int iicbb_write(device_t, const char *, int, int *, int);
static int iicbb_read(device_t, char *, int, int *, int, int);
static int iicbb_reset(device_t, u_char, u_char, u_char *);
+static int iicbb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs);
static device_method_t iicbb_methods[] = {
/* device interface */
@@ -95,7 +96,7 @@
DEVMETHOD(iicbus_write, iicbb_write),
DEVMETHOD(iicbus_read, iicbb_read),
DEVMETHOD(iicbus_reset, iicbb_reset),
- DEVMETHOD(iicbus_transfer, iicbus_transfer_gen),
+ DEVMETHOD(iicbus_transfer, iicbb_transfer),
{ 0, 0 }
};
@@ -424,6 +425,21 @@
return (0);
}
+static int
+iicbb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
+{
+ int error;
+
+ error = IICBB_PRE_XFER(device_get_parent(dev));
+ if (error)
+ return (error);
+
+ error = iicbus_transfer_gen(dev, msgs, nmsgs);
+
+ IICBB_POST_XFER(device_get_parent(dev));
+ return (error);
+}
+
DRIVER_MODULE(iicbus, iicbb, iicbus_driver, iicbus_devclass, 0, 0);
MODULE_DEPEND(iicbb, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/iicbus/iicbb_if.m
--- a/head/sys/dev/iicbus/iicbb_if.m Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/iicbus/iicbb_if.m Fri Mar 02 17:36:33 2012 +0200
@@ -23,7 +23,7 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
-# $FreeBSD$
+# $FreeBSD: head/sys/dev/iicbus/iicbb_if.m 232365 2012-03-01 20:58:20Z kan $
#
#include <sys/bus.h>
@@ -31,13 +31,50 @@
INTERFACE iicbb;
#
+# Default implementation of optional methods
+#
+CODE {
+ static int
+ null_pre_xfer(device_t dev)
+ {
+ return 0;
+ }
+
+ static void
+ null_post_xfer(device_t dev)
+
+ {
+ }
+
+ static int
+ null_callback(device_t dev, int index, caddr_t data)
+ {
+ return 0;
+ }
+};
+
+#
# iicbus callback
#
METHOD int callback {
device_t dev;
int index;
caddr_t data;
-};
+} DEFAULT null_callback;
+
+#
+# Prepare device for I2C transfer
+#
+METHOD int pre_xfer {
+ device_t dev;
+} DEFAULT null_pre_xfer;
+
+#
+# Cleanup device after I2C transfer
+#
+METHOD void post_xfer {
+ device_t dev;
+} DEFAULT null_post_xfer;
#
# Set I2C bus data line
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/iscsi/initiator/isc_sm.c
--- a/head/sys/dev/iscsi/initiator/isc_sm.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/iscsi/initiator/isc_sm.c Fri Mar 02 17:36:33 2012 +0200
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/iscsi/initiator/isc_sm.c 231378 2012-02-10 12:35:57Z ed $");
#include "opt_iscsi_initiator.h"
@@ -652,13 +652,13 @@
isc_add_sysctls(isc_session_t *sp)
{
debug_called(8);
- sdebug(6, "sid=%d %s", sp->sid, sp->dev->si_name);
+ sdebug(6, "sid=%d %s", sp->sid, devtoname(sp->dev));
sysctl_ctx_init(&sp->clist);
sp->oid = SYSCTL_ADD_NODE(&sp->clist,
SYSCTL_CHILDREN(sp->isc->oid),
OID_AUTO,
- sp->dev->si_name+5, // iscsi0
+ devtoname(sp->dev) + 5, // iscsi0
CTLFLAG_RD,
0,
"initiator");
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/isp/isp_freebsd.h
--- a/head/sys/dev/isp/isp_freebsd.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/isp/isp_freebsd.h Fri Mar 02 17:36:33 2012 +0200
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/isp/isp_freebsd.h 228914 2011-12-27 14:59:24Z mjacob $ */
+/* $FreeBSD: head/sys/dev/isp/isp_freebsd.h 231985 2012-02-22 01:08:59Z kevlo $ */
/*-
* Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions
*
@@ -494,7 +494,7 @@
#define XS_SAVE_SENSE(xs, sense_ptr, slen) do { \
(xs)->ccb_h.status |= CAM_AUTOSNS_VALID; \
- memset(&(xs)->sense_data, 0, sizeof(&(xs)->sense_data));\
+ memset(&(xs)->sense_data, 0, sizeof((xs)->sense_data)); \
memcpy(&(xs)->sense_data, sense_ptr, imin(XS_SNSLEN(xs),\
slen)); \
if (slen < (xs)->sense_len) \
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ixgbe/ixgbe.c
--- a/head/sys/dev/ixgbe/ixgbe.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ixgbe/ixgbe.c Fri Mar 02 17:36:33 2012 +0200
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe.c 230775 2012-01-30 16:42:02Z jfv $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe.c 232238 2012-02-27 19:05:01Z luigi $*/
#ifdef HAVE_KERNEL_OPTION_HEADERS
#include "opt_inet.h"
@@ -2969,14 +2969,11 @@
* Slots in the netmap ring (indexed by "si") are
* kring->nkr_hwofs positions "ahead" wrt the
* corresponding slot in the NIC ring. In some drivers
- * (not here) nkr_hwofs can be negative. When computing
- * si = i + kring->nkr_hwofs make sure to handle wraparounds.
+ * (not here) nkr_hwofs can be negative. Function
+ * netmap_idx_n2k() handles wraparounds properly.
*/
if (slot) {
- int si = i + na->tx_rings[txr->me].nkr_hwofs;
-
- if (si >= na->num_tx_desc)
- si -= na->num_tx_desc;
+ int si = netmap_idx_n2k(&na->tx_rings[txr->me], i);
netmap_load_map(txr->txtag, txbuf->map, NMB(slot + si));
}
#endif /* DEV_NETMAP */
@@ -3494,7 +3491,7 @@
selwakeuppri(&na->tx_rings[txr->me].si, PI_NET);
IXGBE_TX_UNLOCK(txr);
IXGBE_CORE_LOCK(adapter);
- selwakeuppri(&na->tx_rings[na->num_queues + 1].si, PI_NET);
+ selwakeuppri(&na->tx_si, PI_NET);
IXGBE_CORE_UNLOCK(adapter);
IXGBE_TX_LOCK(txr);
}
@@ -3925,12 +3922,10 @@
* an mbuf, so end the block with a continue;
*/
if (slot) {
- int sj = j + na->rx_rings[rxr->me].nkr_hwofs;
+ int sj = netmap_idx_n2k(&na->rx_rings[rxr->me], j);
uint64_t paddr;
void *addr;
- if (sj >= na->num_rx_desc)
- sj -= na->num_rx_desc;
addr = PNMB(slot + sj, &paddr);
netmap_load_map(rxr->ptag, rxbuf->pmap, addr);
/* Update descriptor */
@@ -4381,7 +4376,7 @@
selwakeuppri(&na->rx_rings[rxr->me].si, PI_NET);
IXGBE_RX_UNLOCK(rxr);
IXGBE_CORE_LOCK(adapter);
- selwakeuppri(&na->rx_rings[na->num_queues + 1].si, PI_NET);
+ selwakeuppri(&na->rx_si, PI_NET);
IXGBE_CORE_UNLOCK(adapter);
return (FALSE);
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mii/brgphy.c
--- a/head/sys/dev/mii/brgphy.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mii/brgphy.c Fri Mar 02 17:36:33 2012 +0200
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/mii/brgphy.c 227913 2011-11-23 22:05:44Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/mii/brgphy.c 231913 2012-02-19 12:09:17Z marius $");
/*
* Driver for the Broadcom BCM54xx/57xx 1000baseTX PHY.
@@ -147,6 +147,7 @@
MII_PHY_DESC(BROADCOM3, BCM5719C),
MII_PHY_DESC(BROADCOM3, BCM5720C),
MII_PHY_DESC(BROADCOM3, BCM57765),
+ MII_PHY_DESC(BROADCOM3, BCM57780),
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5906),
MII_PHY_END
};
@@ -226,7 +227,8 @@
sc->mii_flags |= MIIF_HAVEFIBER;
}
break;
- } break;
+ }
+ break;
case MII_OUI_BROADCOM2:
switch (sc->mii_mpd_model) {
case MII_MODEL_BROADCOM2_BCM5708S:
@@ -943,7 +945,8 @@
if (bge_sc->bge_phy_flags & BGE_PHY_JITTER_BUG)
brgphy_fixup_jitter_bug(sc);
- brgphy_jumbo_settings(sc, ifp->if_mtu);
+ if (bge_sc->bge_flags & BGE_FLAG_JUMBO)
+ brgphy_jumbo_settings(sc, ifp->if_mtu);
if ((bge_sc->bge_phy_flags & BGE_PHY_NO_WIRESPEED) == 0)
brgphy_ethernet_wirespeed(sc);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mii/miidevs
--- a/head/sys/dev/mii/miidevs Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mii/miidevs Fri Mar 02 17:36:33 2012 +0200
@@ -1,5 +1,5 @@
-$FreeBSD: head/sys/dev/mii/miidevs 227906 2011-11-23 20:08:56Z marius $
-/*$NetBSD: miidevs,v 1.104 2011/11/12 11:10:49 sekiya Exp $*/
+$FreeBSD: head/sys/dev/mii/miidevs 231914 2012-02-19 12:25:58Z marius $
+/*$NetBSD: miidevs,v 1.105 2011/11/25 23:28:14 jakllsch Exp $*/
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -167,6 +167,7 @@
model BROADCOM BCM5714 0x0034 BCM5714 1000BASE-T media interface
model BROADCOM BCM5780 0x0035 BCM5780 1000BASE-T media interface
model BROADCOM BCM5708C 0x0036 BCM5708C 1000BASE-T media interface
+
model BROADCOM2 BCM5325 0x0003 BCM5325 10/100 5-port PHY switch
model BROADCOM2 BCM5906 0x0004 BCM5906 10/100baseTX media interface
model BROADCOM2 BCM5481 0x000a BCM5481 1000BASE-T media interface
@@ -181,6 +182,7 @@
model BROADCOM2 BCM5709C 0x003c BCM5709 10/100/1000baseT PHY
model BROADCOM2 BCM5761 0x003d BCM5761 10/100/1000baseT PHY
model BROADCOM2 BCM5709S 0x003f BCM5709S 1000/2500baseSX PHY
+model BROADCOM3 BCM57780 0x0019 BCM57780 1000BASE-T media interface
model BROADCOM3 BCM5717C 0x0020 BCM5717C 1000BASE-T media interface
model BROADCOM3 BCM5719C 0x0022 BCM5719C 1000BASE-T media interface
model BROADCOM3 BCM57765 0x0024 BCM57765 1000BASE-T media interface
@@ -281,6 +283,7 @@
model xxNATSEMI DP83891 0x0005 DP83891 1000BASE-T media interface
model xxNATSEMI DP83861 0x0006 DP83861 1000BASE-T media interface
model xxNATSEMI DP83865 0x0007 DP83865 1000BASE-T media interface
+model xxNATSEMI DP83849 0x000a DP83849 10/100 media interface
/* PMC Sierra PHYs */
model xxPMCSIERRA PM8351 0x0000 PM8351 OctalPHY Gigabit interface
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mii/nsphyter.c
--- a/head/sys/dev/mii/nsphyter.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mii/nsphyter.c Fri Mar 02 17:36:33 2012 +0200
@@ -55,11 +55,12 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/mii/nsphyter.c 227908 2011-11-23 20:27:26Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/mii/nsphyter.c 231914 2012-02-19 12:25:58Z marius $");
/*
- * driver for National Semiconductor's DP83843 `PHYTER' ethernet 10/100 PHY
- * Data Sheet available from www.national.com
+ * Driver for the National Semiconductor's DP83843, DP83847 and DP83849
+ * `PHYTER' Ethernet 10/100 PHYs
+ * Data Sheets are available from http://www.national.com
*
* We also support the DP83815 `MacPHYTER' internal PHY since, for our
* purposes, they are compatible.
@@ -114,6 +115,7 @@
MII_PHY_DESC(xxNATSEMI, DP83815),
MII_PHY_DESC(xxNATSEMI, DP83843),
MII_PHY_DESC(xxNATSEMI, DP83847),
+ MII_PHY_DESC(xxNATSEMI, DP83849),
MII_PHY_END
};
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mii/rgephy.c
--- a/head/sys/dev/mii/rgephy.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mii/rgephy.c Fri Mar 02 17:36:33 2012 +0200
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/mii/rgephy.c 227908 2011-11-23 20:27:26Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/mii/rgephy.c 232246 2012-02-28 05:23:29Z yongari $");
/*
* Driver for the RealTek 8169S/8110S/8211B/8211C internal 10/100/1000 PHY.
@@ -110,10 +110,15 @@
rgephy_attach(device_t dev)
{
struct mii_softc *sc;
+ struct mii_attach_args *ma;
+ u_int flags;
sc = device_get_softc(dev);
-
- mii_phy_dev_attach(dev, 0, &rgephy_funcs, 0);
+ ma = device_get_ivars(dev);
+ flags = 0;
+ if (strcmp(ma->mii_data->mii_ifp->if_dname, "re") == 0)
+ flags |= MIIF_PHYPRIV0;
+ mii_phy_dev_attach(dev, flags, &rgephy_funcs, 0);
/* RTL8169S do not report auto-sense; add manually. */
sc->mii_capabilities = (PHY_READ(sc, MII_BMSR) | BMSR_ANEG) &
@@ -243,7 +248,8 @@
* Check to see if we have link. If we do, we don't
* need to restart the autonegotiation process.
*/
- if (sc->mii_mpd_rev >= 2) {
+ if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 &&
+ sc->mii_mpd_rev >= 2) {
/* RTL8211B(L) */
reg = PHY_READ(sc, RGEPHY_MII_SSR);
if (reg & RGEPHY_SSR_LINK) {
@@ -298,7 +304,7 @@
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
- if (sc->mii_mpd_rev >= 2) {
+ if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) {
ssr = PHY_READ(sc, RGEPHY_MII_SSR);
if (ssr & RGEPHY_SSR_LINK)
mii->mii_media_status |= IFM_ACTIVE;
@@ -328,7 +334,7 @@
}
}
- if (sc->mii_mpd_rev >= 2) {
+ if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) {
ssr = PHY_READ(sc, RGEPHY_MII_SSR);
switch (ssr & RGEPHY_SSR_SPD_MASK) {
case RGEPHY_SSR_S1000:
@@ -484,7 +490,7 @@
{
uint16_t ssr;
- if (sc->mii_mpd_rev == 3) {
+ if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev == 3) {
/* RTL8211C(L) */
ssr = PHY_READ(sc, RGEPHY_MII_SSR);
if ((ssr & RGEPHY_SSR_ALDPS) != 0) {
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mii/smcphy.c
--- a/head/sys/dev/mii/smcphy.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mii/smcphy.c Fri Mar 02 17:36:33 2012 +0200
@@ -23,7 +23,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/mii/smcphy.c 227908 2011-11-23 20:27:26Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/mii/smcphy.c 232015 2012-02-23 01:20:21Z yongari $");
/*
* Driver for the internal PHY on the SMSC LAN91C111.
@@ -55,6 +55,7 @@
static int smcphy_service(struct mii_softc *, struct mii_data *, int);
static void smcphy_reset(struct mii_softc *);
static void smcphy_auto(struct mii_softc *, int);
+static void smcphy_status(struct mii_softc *);
static device_method_t smcphy_methods[] = {
/* device interface */
@@ -76,13 +77,20 @@
DRIVER_MODULE(smcphy, miibus, smcphy_driver, smcphy_devclass, 0, 0);
static const struct mii_phydesc smcphys[] = {
+ MII_PHY_DESC(SEEQ, 80220),
MII_PHY_DESC(SEEQ, 84220),
MII_PHY_END
};
+static const struct mii_phy_funcs smcphy80220_funcs = {
+ smcphy_service,
+ smcphy_status,
+ mii_phy_reset
+};
+
static const struct mii_phy_funcs smcphy_funcs = {
smcphy_service,
- ukphy_status,
+ smcphy_status,
smcphy_reset
};
@@ -97,11 +105,16 @@
smcphy_attach(device_t dev)
{
struct mii_softc *sc;
+ struct mii_attach_args *ma;
+ const struct mii_phy_funcs *mpf;
sc = device_get_softc(dev);
-
- mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE,
- &smcphy_funcs, 1);
+ ma = device_get_ivars(dev);
+ if (MII_MODEL(ma->mii_id2) == MII_MODEL_SEEQ_80220)
+ mpf = &smcphy80220_funcs;
+ else
+ mpf = &smcphy_funcs;
+ mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, mpf, 1);
mii_phy_setmedia(sc);
return (0);
@@ -214,3 +227,46 @@
anar = PHY_READ(sc, MII_ANAR);
PHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
}
+
+static void
+smcphy_status(struct mii_softc *sc)
+{
+ struct mii_data *mii;
+ uint32_t bmcr, bmsr, status;
+
+ mii = sc->mii_pdata;
+ mii->mii_media_status = IFM_AVALID;
+ mii->mii_media_active = IFM_ETHER;
+
+ bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
+ if ((bmsr & BMSR_LINK) != 0)
+ mii->mii_media_status |= IFM_ACTIVE;
+
+ bmcr = PHY_READ(sc, MII_BMCR);
+ if ((bmcr & BMCR_ISO) != 0) {
+ mii->mii_media_active |= IFM_NONE;
+ mii->mii_media_status = 0;
+ return;
+ }
+
+ if ((bmcr & BMCR_LOOP) != 0)
+ mii->mii_media_active |= IFM_LOOP;
+
+ if ((bmcr & BMCR_AUTOEN) != 0) {
+ if ((bmsr & BMSR_ACOMP) == 0) {
+ /* Erg, still trying, I guess... */
+ mii->mii_media_active |= IFM_NONE;
+ return;
+ }
+ }
+
+ status = PHY_READ(sc, 0x12);
+ if (status & 0x0080)
+ mii->mii_media_active |= IFM_100_TX;
+ else
+ mii->mii_media_active |= IFM_10_T;
+ if (status & 0x0040)
+ mii->mii_media_active |= IFM_FDX | mii_phy_flowstatus(sc);
+ else
+ mii->mii_media_active |= IFM_HDX;
+}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mlx/mlx.c
--- a/head/sys/dev/mlx/mlx.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mlx/mlx.c Fri Mar 02 17:36:33 2012 +0200
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/mlx/mlx.c 232219 2012-02-27 16:10:26Z kevlo $
*/
/*
@@ -2254,7 +2254,7 @@
mlx_complete(struct mlx_softc *sc)
{
struct mlx_command *mc, *nc;
- int s, count;
+ int s;
debug_called(2);
@@ -2263,7 +2263,6 @@
return;
s = splbio();
- count = 0;
/* scan the list of busy/done commands */
mc = TAILQ_FIRST(&sc->mlx_work);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mps/mps.c
--- a/head/sys/dev/mps/mps.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mps/mps.c Fri Mar 02 17:36:33 2012 +0200
@@ -51,11 +51,11 @@
*
* LSI MPT-Fusion Host Adapter FreeBSD
*
- * $FreeBSD: head/sys/dev/mps/mps.c 230592 2012-01-26 18:17:21Z ken $
+ * $FreeBSD: head/sys/dev/mps/mps.c 231240 2012-02-09 00:16:12Z ken $
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/mps/mps.c 230592 2012-01-26 18:17:21Z ken $");
+__FBSDID("$FreeBSD: head/sys/dev/mps/mps.c 231240 2012-02-09 00:16:12Z ken $");
/* Communications core for LSI MPT2 */
@@ -529,7 +529,7 @@
mps_dprint(sc, MPS_TRACE, "%s SMID %u cm %p ccb %p\n", __func__,
cm->cm_desc.Default.SMID, cm, cm->cm_ccb);
- if (sc->mps_flags & MPS_FLAGS_ATTACH_DONE)
+ if (sc->mps_flags & MPS_FLAGS_ATTACH_DONE && !(sc->mps_flags & MPS_FLAGS_SHUTDOWN))
mtx_assert(&sc->mps_mtx, MA_OWNED);
if (++sc->io_cmds_active > sc->io_cmds_highwater)
@@ -1335,6 +1335,8 @@
((error = mps_detach_sas(sc)) != 0))
return (error);
+ mps_detach_user(sc);
+
/* Put the IOC back in the READY state. */
mps_lock(sc);
if ((error = mps_transition_ready(sc)) != 0) {
@@ -2142,7 +2144,7 @@
error = mps_map_command(sc, cm);
if ((error != 0) && (error != EINPROGRESS))
return (error);
- error = msleep(cm, &sc->mps_mtx, 0, "mpswait", timeout);
+ error = msleep(cm, &sc->mps_mtx, 0, "mpswait", timeout*hz);
if (error == EWOULDBLOCK)
error = ETIMEDOUT;
return (error);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mps/mps_pci.c
--- a/head/sys/dev/mps/mps_pci.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mps/mps_pci.c Fri Mar 02 17:36:33 2012 +0200
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/mps/mps_pci.c 230592 2012-01-26 18:17:21Z ken $");
+__FBSDID("$FreeBSD: head/sys/dev/mps/mps_pci.c 231485 2012-02-11 00:28:30Z ken $");
/* PCI/PCI-X/PCIe bus interface for the LSI MPT2 controllers */
@@ -172,7 +172,7 @@
if ((id = mps_find_ident(dev)) != NULL) {
device_set_desc(dev, id->desc);
- return (BUS_PROBE_VENDOR);
+ return (BUS_PROBE_DEFAULT);
}
return (ENXIO);
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mps/mps_sas.c
--- a/head/sys/dev/mps/mps_sas.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mps/mps_sas.c Fri Mar 02 17:36:33 2012 +0200
@@ -50,11 +50,11 @@
*
* LSI MPT-Fusion Host Adapter FreeBSD
*
- * $FreeBSD: head/sys/dev/mps/mps_sas.c 230592 2012-01-26 18:17:21Z ken $
+ * $FreeBSD: head/sys/dev/mps/mps_sas.c 231716 2012-02-14 22:27:43Z ken $
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/mps/mps_sas.c 230592 2012-01-26 18:17:21Z ken $");
+__FBSDID("$FreeBSD: head/sys/dev/mps/mps_sas.c 231716 2012-02-14 22:27:43Z ken $");
/* Communications core for LSI MPT2 */
@@ -139,7 +139,6 @@
MALLOC_DEFINE(M_MPSSAS, "MPSSAS", "MPS SAS memory");
-static struct mpssas_target * mpssas_find_target_by_handle(struct mpssas_softc *, int, uint16_t);
static void mpssas_discovery_timeout(void *data);
static void mpssas_remove_device(struct mps_softc *, struct mps_command *);
static void mpssas_remove_complete(struct mps_softc *, struct mps_command *);
@@ -175,7 +174,7 @@
static void mpssas_portenable_complete(struct mps_softc *sc,
struct mps_command *cm);
-static struct mpssas_target *
+struct mpssas_target *
mpssas_find_target_by_handle(struct mpssas_softc *sassc, int start, uint16_t handle)
{
struct mpssas_target *target;
@@ -351,22 +350,123 @@
va_end(ap);
}
+
static void
-mpssas_lost_target(struct mps_softc *sc, struct mpssas_target *targ)
+mpssas_remove_volume(struct mps_softc *sc, struct mps_command *tm)
{
- struct mpssas_softc *sassc = sc->sassc;
- path_id_t pathid = cam_sim_path(sassc->sim);
- struct cam_path *path;
-
- mps_printf(sc, "%s targetid %u\n", __func__, targ->tid);
- if (xpt_create_path(&path, NULL, pathid, targ->tid, 0) != CAM_REQ_CMP) {
- mps_printf(sc, "unable to create path for lost target %d\n",
- targ->tid);
+ MPI2_SCSI_TASK_MANAGE_REPLY *reply;
+ struct mpssas_target *targ;
+ uint16_t handle;
+
+ mps_dprint(sc, MPS_INFO, "%s\n", __func__);
+
+ reply = (MPI2_SCSI_TASK_MANAGE_REPLY *)tm->cm_reply;
+ handle = (uint16_t)(uintptr_t)tm->cm_complete_data;
+ targ = tm->cm_targ;
+
+ if (reply == NULL) {
+ /* XXX retry the remove after the diag reset completes? */
+ mps_printf(sc, "%s NULL reply reseting device 0x%04x\n",
+ __func__, handle);
+ mpssas_free_tm(sc, tm);
return;
}
- xpt_async(AC_LOST_DEVICE, path, NULL);
- xpt_free_path(path);
+ if (reply->IOCStatus != MPI2_IOCSTATUS_SUCCESS) {
+ mps_printf(sc, "IOCStatus = 0x%x while resetting device 0x%x\n",
+ reply->IOCStatus, handle);
+ mpssas_free_tm(sc, tm);
+ return;
+ }
+
+ mps_printf(sc, "Reset aborted %u commands\n", reply->TerminationCount);
+ mps_free_reply(sc, tm->cm_reply_data);
+ tm->cm_reply = NULL; /* Ensures the the reply won't get re-freed */
+
+ mps_printf(sc, "clearing target %u handle 0x%04x\n", targ->tid, handle);
+
+ /*
+ * Don't clear target if remove fails because things will get confusing.
+ * Leave the devname and sasaddr intact so that we know to avoid reusing
+ * this target id if possible, and so we can assign the same target id
+ * to this device if it comes back in the future.
+ */
+ if (reply->IOCStatus == MPI2_IOCSTATUS_SUCCESS) {
+ targ = tm->cm_targ;
+ targ->handle = 0x0;
+ targ->encl_handle = 0x0;
+ targ->encl_slot = 0x0;
+ targ->exp_dev_handle = 0x0;
+ targ->phy_num = 0x0;
+ targ->linkrate = 0x0;
+ targ->devinfo = 0x0;
+ targ->flags = 0x0;
+ }
+
+ mpssas_free_tm(sc, tm);
+}
+
+
+/*
+ * No Need to call "MPI2_SAS_OP_REMOVE_DEVICE" For Volume removal.
+ * Otherwise Volume Delete is same as Bare Drive Removal.
+ */
+void
+mpssas_prepare_volume_remove(struct mpssas_softc *sassc, uint16_t handle)
+{
+ MPI2_SCSI_TASK_MANAGE_REQUEST *req;
+ struct mps_softc *sc;
+ struct mps_command *cm;
+ struct mpssas_target *targ = NULL;
+
+ mps_dprint(sassc->sc, MPS_INFO, "%s\n", __func__);
+ sc = sassc->sc;
+
+#ifdef WD_SUPPORT
+ /*
+ * If this is a WD controller, determine if the disk should be exposed
+ * to the OS or not. If disk should be exposed, return from this
+ * function without doing anything.
+ */
+ if (sc->WD_available && (sc->WD_hide_expose ==
+ MPS_WD_EXPOSE_ALWAYS)) {
+ return;
+ }
+#endif //WD_SUPPORT
+
+ targ = mpssas_find_target_by_handle(sassc, 0, handle);
+ if (targ == NULL) {
+ /* FIXME: what is the action? */
+ /* We don't know about this device? */
+ printf("%s %d : invalid handle 0x%x \n", __func__,__LINE__, handle);
+ return;
+ }
+
+ targ->flags |= MPSSAS_TARGET_INREMOVAL;
+
+ cm = mpssas_alloc_tm(sc);
+ if (cm == NULL) {
+ mps_printf(sc, "%s: command alloc failure\n", __func__);
+ return;
+ }
+
+ mpssas_rescan_target(sc, targ);
+
+ req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
+ req->DevHandle = targ->handle;
+ req->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
+ req->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
+
+ /* SAS Hard Link Reset / SATA Link Reset */
+ req->MsgFlags = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
+
+ cm->cm_targ = targ;
+ cm->cm_data = NULL;
+ cm->cm_desc.HighPriority.RequestFlags =
+ MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
+ cm->cm_complete = mpssas_remove_volume;
+ cm->cm_complete_data = (void *)(uintptr_t)handle;
+ mps_map_command(sc, cm);
}
/*
@@ -386,7 +486,7 @@
struct mps_command *cm;
struct mpssas_target *targ = NULL;
- mps_dprint(sassc->sc, MPS_TRACE, "%s\n", __func__);
+ mps_dprint(sassc->sc, MPS_INFO, "%s\n", __func__);
/*
* If this is a WD controller, determine if the disk should be exposed
@@ -403,7 +503,7 @@
if (targ == NULL) {
/* FIXME: what is the action? */
/* We don't know about this device? */
- printf("%s: invalid handle 0x%x \n", __func__, handle);
+ printf("%s %d : invalid handle 0x%x \n", __func__,__LINE__, handle);
return;
}
@@ -415,7 +515,7 @@
return;
}
- mpssas_lost_target(sc, targ);
+ mpssas_rescan_target(sc, targ);
req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
memset(req, 0, sizeof(*req));
@@ -443,7 +543,7 @@
struct mps_command *next_cm;
uint16_t handle;
- mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
+ mps_dprint(sc, MPS_INFO, "%s\n", __func__);
reply = (MPI2_SCSI_TASK_MANAGE_REPLY *)tm->cm_reply;
handle = (uint16_t)(uintptr_t)tm->cm_complete_data;
@@ -514,7 +614,7 @@
uint16_t handle;
struct mpssas_target *targ;
- mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
+ mps_dprint(sc, MPS_INFO, "%s\n", __func__);
reply = (MPI2_SAS_IOUNIT_CONTROL_REPLY *)tm->cm_reply;
handle = (uint16_t)(uintptr_t)tm->cm_complete_data;
@@ -558,6 +658,7 @@
targ->phy_num = 0x0;
targ->linkrate = 0x0;
targ->devinfo = 0x0;
+ targ->flags = 0x0;
}
mpssas_free_tm(sc, tm);
@@ -690,7 +791,7 @@
{
struct mpssas_softc *sassc;
- mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
+ mps_dprint(sc, MPS_INFO, "%s\n", __func__);
if (sc->sassc == NULL)
return (0);
@@ -733,6 +834,7 @@
}
mps_unlock(sc);
+ mps_dprint(sc, MPS_INFO, "%s:%d\n", __func__,__LINE__);
if (sassc->devq != NULL)
cam_simq_free(sassc->devq);
@@ -817,7 +919,7 @@
cpi->hba_misc = PIM_NOBUSRESET;
cpi->hba_eng_cnt = 0;
cpi->max_target = sassc->sc->facts->MaxTargets - 1;
- cpi->max_lun = 0;
+ cpi->max_lun = 8;
cpi->initiator_id = 255;
strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
strncpy(cpi->hba_vid, "LSILogic", HBA_IDLEN);
@@ -1475,11 +1577,11 @@
uint16_t eedp_flags;
sc = sassc->sc;
- mps_dprint(sc, MPS_TRACE, "%s ccb %p\n", __func__, ccb);
mtx_assert(&sc->mps_mtx, MA_OWNED);
csio = &ccb->csio;
targ = &sassc->targets[csio->ccb_h.target_id];
+ mps_dprint(sc, MPS_TRACE, "%s ccb %p target flag %x\n", __func__, ccb, targ->flags);
if (targ->handle == 0x0) {
mps_dprint(sc, MPS_TRACE, "%s NULL handle for target %u\n",
__func__, csio->ccb_h.target_id);
@@ -1487,6 +1589,13 @@
xpt_done(ccb);
return;
}
+ if (targ->flags & MPS_TARGET_FLAGS_RAID_COMPONENT) {
+ mps_dprint(sc, MPS_TRACE, "%s Raid component no SCSI IO supported %u\n",
+ __func__, csio->ccb_h.target_id);
+ csio->ccb_h.status = CAM_TID_INVALID;
+ xpt_done(ccb);
+ return;
+ }
/*
* If devinfo is 0 this will be a volume. In that case don't tell CAM
* that the volume has timed out. We want volumes to be enumerated
@@ -1684,6 +1793,198 @@
}
static void
+mps_response_code(struct mps_softc *sc, u8 response_code)
+{
+ char *desc;
+
+ switch (response_code) {
+ case MPI2_SCSITASKMGMT_RSP_TM_COMPLETE:
+ desc = "task management request completed";
+ break;
+ case MPI2_SCSITASKMGMT_RSP_INVALID_FRAME:
+ desc = "invalid frame";
+ break;
+ case MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
+ desc = "task management request not supported";
+ break;
+ case MPI2_SCSITASKMGMT_RSP_TM_FAILED:
+ desc = "task management request failed";
+ break;
+ case MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED:
+ desc = "task management request succeeded";
+ break;
+ case MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN:
+ desc = "invalid lun";
+ break;
+ case 0xA:
+ desc = "overlapped tag attempted";
+ break;
+ case MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
+ desc = "task queued, however not sent to target";
+ break;
+ default:
+ desc = "unknown";
+ break;
+ }
+ mps_dprint(sc, MPS_INFO, "response_code(0x%01x): %s\n",
+ response_code, desc);
+}
+/**
+ * mps_sc_failed_io_info - translated non-succesfull SCSI_IO request
+ */
+static void
+mps_sc_failed_io_info(struct mps_softc *sc, struct ccb_scsiio *csio,
+ Mpi2SCSIIOReply_t *mpi_reply)
+{
+ u32 response_info;
+ u8 *response_bytes;
+ u16 ioc_status = le16toh(mpi_reply->IOCStatus) &
+ MPI2_IOCSTATUS_MASK;
+ u8 scsi_state = mpi_reply->SCSIState;
+ u8 scsi_status = mpi_reply->SCSIStatus;
+ char *desc_ioc_state = NULL;
+ char *desc_scsi_status = NULL;
+ char *desc_scsi_state = sc->tmp_string;
+ u32 log_info = le32toh(mpi_reply->IOCLogInfo);
+
+ if (log_info == 0x31170000)
+ return;
+
+ switch (ioc_status) {
+ case MPI2_IOCSTATUS_SUCCESS:
+ desc_ioc_state = "success";
+ break;
+ case MPI2_IOCSTATUS_INVALID_FUNCTION:
+ desc_ioc_state = "invalid function";
+ break;
+ case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
+ desc_ioc_state = "scsi recovered error";
+ break;
+ case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
+ desc_ioc_state = "scsi invalid dev handle";
+ break;
+ case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
+ desc_ioc_state = "scsi device not there";
+ break;
+ case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
+ desc_ioc_state = "scsi data overrun";
+ break;
+ case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
+ desc_ioc_state = "scsi data underrun";
+ break;
+ case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
+ desc_ioc_state = "scsi io data error";
+ break;
+ case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
+ desc_ioc_state = "scsi protocol error";
+ break;
+ case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
+ desc_ioc_state = "scsi task terminated";
+ break;
+ case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
+ desc_ioc_state = "scsi residual mismatch";
+ break;
+ case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
+ desc_ioc_state = "scsi task mgmt failed";
+ break;
+ case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
+ desc_ioc_state = "scsi ioc terminated";
+ break;
+ case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
+ desc_ioc_state = "scsi ext terminated";
+ break;
+ case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
+ desc_ioc_state = "eedp guard error";
+ break;
+ case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
+ desc_ioc_state = "eedp ref tag error";
+ break;
+ case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
+ desc_ioc_state = "eedp app tag error";
+ break;
+ default:
+ desc_ioc_state = "unknown";
+ break;
+ }
+
+ switch (scsi_status) {
+ case MPI2_SCSI_STATUS_GOOD:
+ desc_scsi_status = "good";
+ break;
+ case MPI2_SCSI_STATUS_CHECK_CONDITION:
+ desc_scsi_status = "check condition";
+ break;
+ case MPI2_SCSI_STATUS_CONDITION_MET:
+ desc_scsi_status = "condition met";
+ break;
+ case MPI2_SCSI_STATUS_BUSY:
+ desc_scsi_status = "busy";
+ break;
+ case MPI2_SCSI_STATUS_INTERMEDIATE:
+ desc_scsi_status = "intermediate";
+ break;
+ case MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET:
+ desc_scsi_status = "intermediate condmet";
+ break;
+ case MPI2_SCSI_STATUS_RESERVATION_CONFLICT:
+ desc_scsi_status = "reservation conflict";
+ break;
+ case MPI2_SCSI_STATUS_COMMAND_TERMINATED:
+ desc_scsi_status = "command terminated";
+ break;
+ case MPI2_SCSI_STATUS_TASK_SET_FULL:
+ desc_scsi_status = "task set full";
+ break;
+ case MPI2_SCSI_STATUS_ACA_ACTIVE:
+ desc_scsi_status = "aca active";
+ break;
+ case MPI2_SCSI_STATUS_TASK_ABORTED:
+ desc_scsi_status = "task aborted";
+ break;
+ default:
+ desc_scsi_status = "unknown";
+ break;
+ }
+
+ desc_scsi_state[0] = '\0';
+ if (!scsi_state)
+ desc_scsi_state = " ";
+ if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
+ strcat(desc_scsi_state, "response info ");
+ if (scsi_state & MPI2_SCSI_STATE_TERMINATED)
+ strcat(desc_scsi_state, "state terminated ");
+ if (scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS)
+ strcat(desc_scsi_state, "no status ");
+ if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_FAILED)
+ strcat(desc_scsi_state, "autosense failed ");
+ if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID)
+ strcat(desc_scsi_state, "autosense valid ");
+
+ mps_dprint(sc, MPS_INFO, "\thandle(0x%04x), ioc_status(%s)(0x%04x), \n",
+ le16toh(mpi_reply->DevHandle),
+ desc_ioc_state, ioc_status);
+ /* We can add more detail about underflow data here
+ * TO-DO
+ * */
+ mps_dprint(sc, MPS_INFO, "\tscsi_status(%s)(0x%02x), "
+ "scsi_state(%s)(0x%02x)\n", desc_scsi_status,
+ scsi_status, desc_scsi_state, scsi_state);
+
+ if (sc->mps_debug & MPS_INFO &&
+ scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
+ mps_dprint(sc, MPS_INFO, "-> Sense Buffer Data : Start :\n");
+ scsi_sense_print(csio);
+ mps_dprint(sc, MPS_INFO, "-> Sense Buffer Data : End :\n");
+ }
+
+ if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
+ response_info = le32toh(mpi_reply->ResponseInfo);
+ response_bytes = (u8 *)&response_info;
+ mps_response_code(sc,response_bytes[0]);
+ }
+}
+
+static void
mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
{
MPI2_SCSI_IO_REPLY *rep;
@@ -2018,6 +2319,8 @@
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
break;
}
+
+ mps_sc_failed_io_info(sc,csio,rep);
if (sassc->flags & MPSSAS_QUEUE_FROZEN) {
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
@@ -2799,17 +3102,26 @@
mps_lock(sc);
for (;;) {
+ /* Sleep for 1 second and check the queue status*/
msleep(&sassc->ccb_scanq, &sc->mps_mtx, PRIBIO,
- "mps_scanq", 0);
+ "mps_scanq", 1 * hz);
if (sassc->flags & MPSSAS_SHUTDOWN) {
mps_dprint(sc, MPS_TRACE, "Scanner shutting down\n");
break;
}
+next_work:
+ // Get first work.
ccb = (union ccb *)TAILQ_FIRST(&sassc->ccb_scanq);
if (ccb == NULL)
continue;
+ // Got first work.
TAILQ_REMOVE(&sassc->ccb_scanq, &ccb->ccb_h, sim_links.tqe);
xpt_action(ccb);
+ if (sassc->flags & MPSSAS_SHUTDOWN) {
+ mps_dprint(sc, MPS_TRACE, "Scanner shutting down\n");
+ break;
+ }
+ goto next_work;
}
sassc->flags &= ~MPSSAS_SCANTHREAD;
@@ -3009,7 +3321,7 @@
}
if (!found_lun) {
lun = malloc(sizeof(struct mpssas_lun),
- M_MPT2, M_WAITOK | M_ZERO);
+ M_MPT2, M_NOWAIT | M_ZERO);
if (lun == NULL) {
mps_dprint(sc, MPS_FAULT,
"Unable to alloc LUN for "
@@ -3084,6 +3396,20 @@
if (done_ccb == NULL)
return;
+
+ /* Driver need to release devq, it Scsi command is
+ * generated by driver internally.
+ * Currently there is a single place where driver
+ * calls scsi command internally. In future if driver
+ * calls more scsi command internally, it needs to release
+ * devq internally, since those command will not go back to
+ * cam_periph.
+ */
+ if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) ) {
+ done_ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
+ xpt_release_devq(done_ccb->ccb_h.path,
+ /*count*/ 1, /*run_queue*/TRUE);
+ }
rcap_buf = (struct scsi_read_capacity_eedp *)done_ccb->csio.data_ptr;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mps/mps_sas.h
--- a/head/sys/dev/mps/mps_sas.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mps/mps_sas.h Fri Mar 02 17:36:33 2012 +0200
@@ -25,7 +25,7 @@
*
* LSI MPT-Fusion Host Adapter FreeBSD
*
- * $FreeBSD: head/sys/dev/mps/mps_sas.h 230592 2012-01-26 18:17:21Z ken $
+ * $FreeBSD: head/sys/dev/mps/mps_sas.h 231240 2012-02-09 00:16:12Z ken $
*/
struct mps_fw_event_work;
@@ -49,8 +49,11 @@
#define MPSSAS_TARGET_INRESET (1 << 1)
#define MPSSAS_TARGET_INDIAGRESET (1 << 2)
#define MPSSAS_TARGET_INREMOVAL (1 << 3)
+#define MPS_TARGET_FLAGS_RAID_COMPONENT (1 << 4)
+#define MPS_TARGET_FLAGS_VOLUME (1 << 5)
#define MPSSAS_TARGET_INRECOVERY (MPSSAS_TARGET_INABORT | \
MPSSAS_TARGET_INRESET | MPSSAS_TARGET_INCHIPRESET)
+
#define MPSSAS_TARGET_ADD (1 << 29)
#define MPSSAS_TARGET_REMOVE (1 << 30)
uint16_t tid;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mps/mps_sas_lsi.c
--- a/head/sys/dev/mps/mps_sas_lsi.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mps/mps_sas_lsi.c Fri Mar 02 17:36:33 2012 +0200
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/mps/mps_sas_lsi.c 230592 2012-01-26 18:17:21Z ken $");
+__FBSDID("$FreeBSD: head/sys/dev/mps/mps_sas_lsi.c 231240 2012-02-09 00:16:12Z ken $");
/* Communications core for LSI MPT2 */
@@ -107,7 +107,7 @@
u16 model_number[20]; /* 27-46*/
u16 reserved3[209]; /* 47-255*/
};
-
+static u32 event_count;
static void mpssas_fw_work(struct mps_softc *sc,
struct mps_fw_event_work *fw_event);
static void mpssas_fw_event_free(struct mps_softc *,
@@ -119,7 +119,7 @@
int mpssas_get_sas_address_for_sata_disk(struct mps_softc *sc,
u64 *sas_address, u16 handle, u32 device_info);
static int mpssas_volume_add(struct mps_softc *sc,
- Mpi2EventIrConfigElement_t *element);
+ u16 handle);
void
mpssas_evt_handler(struct mps_softc *sc, uintptr_t data,
@@ -191,6 +191,8 @@
struct mpssas_softc *sassc;
sassc = sc->sassc;
+ mps_dprint(sc, MPS_INFO, "(%d)->(%s) Working on Event: [%x]\n",
+ event_count++,__func__,fw_event->event);
switch (fw_event->event) {
case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
{
@@ -284,7 +286,7 @@
case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
case MPI2_EVENT_IR_CHANGE_RC_ADDED:
if (!foreign_config) {
- if (mpssas_volume_add(sc, element)) {
+ if (mpssas_volume_add(sc, le16toh(element->VolDevHandle))){
printf("%s: failed to add RAID "
"volume with handle 0x%x\n",
__func__, le16toh(element->
@@ -319,12 +321,18 @@
}
break;
case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
+ case MPI2_EVENT_IR_CHANGE_RC_HIDE:
/*
* Phys Disk of a volume has been created. Hide
* it from the OS.
*/
- mpssas_prepare_remove(sassc, element->
- PhysDiskDevHandle);
+ targ = mpssas_find_target_by_handle(sassc, 0, element->PhysDiskDevHandle);
+ if (targ == NULL)
+ break;
+
+ targ->flags |= MPS_TARGET_FLAGS_RAID_COMPONENT;
+ mpssas_rescan_target(sc, targ);
+
break;
case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
/*
@@ -379,6 +387,35 @@
"handle 0x%x", event_data->PreviousValue,
event_data->NewValue,
event_data->VolDevHandle);
+ u32 state;
+ struct mpssas_target *targ;
+ state = le32toh(event_data->NewValue);
+ switch (state) {
+ case MPI2_RAID_VOL_STATE_MISSING:
+ case MPI2_RAID_VOL_STATE_FAILED:
+ mpssas_prepare_volume_remove(sassc, event_data->
+ VolDevHandle);
+ break;
+
+ case MPI2_RAID_VOL_STATE_ONLINE:
+ case MPI2_RAID_VOL_STATE_DEGRADED:
+ case MPI2_RAID_VOL_STATE_OPTIMAL:
+ targ = mpssas_find_target_by_handle(sassc, 0, event_data->VolDevHandle);
+ if (targ) {
+ printf("%s %d: Volume handle 0x%x is already added \n",
+ __func__, __LINE__ , event_data->VolDevHandle);
+ break;
+ }
+ if (mpssas_volume_add(sc, le16toh(event_data->VolDevHandle))) {
+ printf("%s: failed to add RAID "
+ "volume with handle 0x%x\n",
+ __func__, le16toh(event_data->
+ VolDevHandle));
+ }
+ break;
+ default:
+ break;
+ }
break;
default:
break;
@@ -389,6 +426,7 @@
{
Mpi2EventDataIrPhysicalDisk_t *event_data =
fw_event->event_data;
+ struct mpssas_target *targ;
/*
* Informational only.
@@ -399,7 +437,7 @@
mps_dprint(sc, MPS_INFO, " Phys Disk Settings "
"changed from 0x%x to 0x%x for Phys Disk Number "
"%d and handle 0x%x at Enclosure handle 0x%x, Slot "
- "%d", event_data->PreviousValue,
+ "%d\n", event_data->PreviousValue,
event_data->NewValue, event_data->PhysDiskNum,
event_data->PhysDiskDevHandle,
event_data->EnclosureHandle, event_data->Slot);
@@ -407,7 +445,7 @@
case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED:
mps_dprint(sc, MPS_INFO, " Phys Disk Status changed "
"from 0x%x to 0x%x for Phys Disk Number %d and "
- "handle 0x%x at Enclosure handle 0x%x, Slot %d",
+ "handle 0x%x at Enclosure handle 0x%x, Slot %d\n",
event_data->PreviousValue, event_data->NewValue,
event_data->PhysDiskNum,
event_data->PhysDiskDevHandle,
@@ -416,12 +454,38 @@
case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED:
mps_dprint(sc, MPS_INFO, " Phys Disk State changed "
"from 0x%x to 0x%x for Phys Disk Number %d and "
- "handle 0x%x at Enclosure handle 0x%x, Slot %d",
+ "handle 0x%x at Enclosure handle 0x%x, Slot %d\n",
event_data->PreviousValue, event_data->NewValue,
event_data->PhysDiskNum,
event_data->PhysDiskDevHandle,
event_data->EnclosureHandle, event_data->Slot);
- break;
+ switch (event_data->NewValue) {
+ case MPI2_RAID_PD_STATE_ONLINE:
+ case MPI2_RAID_PD_STATE_DEGRADED:
+ case MPI2_RAID_PD_STATE_REBUILDING:
+ case MPI2_RAID_PD_STATE_OPTIMAL:
+ case MPI2_RAID_PD_STATE_HOT_SPARE:
+ targ = mpssas_find_target_by_handle(sassc, 0,
+ event_data->PhysDiskDevHandle);
+ if (targ) {
+ targ->flags |= MPS_TARGET_FLAGS_RAID_COMPONENT;
+ printf("%s %d: Found Target for handle 0x%x. \n",
+ __func__, __LINE__ , event_data->PhysDiskDevHandle);
+ }
+ break;
+ case MPI2_RAID_PD_STATE_OFFLINE:
+ case MPI2_RAID_PD_STATE_NOT_CONFIGURED:
+ case MPI2_RAID_PD_STATE_NOT_COMPATIBLE:
+ default:
+ targ = mpssas_find_target_by_handle(sassc, 0,
+ event_data->PhysDiskDevHandle);
+ if (targ) {
+ targ->flags |= ~MPS_TARGET_FLAGS_RAID_COMPONENT;
+ printf("%s %d: Found Target for handle 0x%x. \n",
+ __func__, __LINE__ , event_data->PhysDiskDevHandle);
+ }
+ break;
+ }
default:
break;
}
@@ -494,6 +558,7 @@
break;
}
+ mps_dprint(sc, MPS_INFO, "(%d)->(%s) Event Free: [%x]\n",event_count,__func__, fw_event->event);
mpssas_fw_event_free(sc, fw_event);
}
@@ -584,7 +649,7 @@
error = ENXIO;
goto out;
}
- mps_vprintf(sc, "SAS Address from SAS device page0 = %jx\n",
+ mps_dprint(sc, MPS_INFO, "SAS Address from SAS device page0 = %jx\n",
sas_address);
targ = &sassc->targets[id];
targ->devinfo = device_info;
@@ -605,12 +670,12 @@
TAILQ_INIT(&targ->timedout_commands);
SLIST_INIT(&targ->luns);
mps_describe_devinfo(targ->devinfo, devstring, 80);
- mps_vprintf(sc, "Found device <%s> <%s> <0x%04x> <%d/%d>\n", devstring,
+ mps_dprint(sc, MPS_INFO, "Found device <%s> <%s> <0x%04x> <%d/%d>\n", devstring,
mps_describe_table(mps_linkrate_names, targ->linkrate),
targ->handle, targ->encl_handle, targ->encl_slot);
if ((sassc->flags & MPSSAS_IN_STARTUP) == 0)
mpssas_rescan_target(sc, targ);
- mps_vprintf(sc, "Target id 0x%x added\n", targ->tid);
+ mps_dprint(sc, MPS_INFO, "Target id 0x%x added\n", targ->tid);
out:
mpssas_startup_decrement(sassc);
return (error);
@@ -751,12 +816,11 @@
}
static int
-mpssas_volume_add(struct mps_softc *sc, Mpi2EventIrConfigElement_t *element)
+mpssas_volume_add(struct mps_softc *sc, u16 handle)
{
struct mpssas_softc *sassc;
struct mpssas_target *targ;
u64 wwid;
- u16 handle = le16toh(element->VolDevHandle);
unsigned int id;
int error = 0;
@@ -855,7 +919,9 @@
action->Function = MPI2_FUNCTION_RAID_ACTION;
action->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
+ mps_lock(sc);
mps_request_polled(sc, cm);
+ mps_unlock(sc);
/*
* Don't check for reply, just leave.
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mps/mps_user.c
--- a/head/sys/dev/mps/mps_user.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mps/mps_user.c Fri Mar 02 17:36:33 2012 +0200
@@ -56,11 +56,11 @@
*
* LSI MPT-Fusion Host Adapter FreeBSD
*
- * $FreeBSD: head/sys/dev/mps/mps_user.c 230592 2012-01-26 18:17:21Z ken $
+ * $FreeBSD: head/sys/dev/mps/mps_user.c 231240 2012-02-09 00:16:12Z ken $
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/mps/mps_user.c 230592 2012-01-26 18:17:21Z ken $");
+__FBSDID("$FreeBSD: head/sys/dev/mps/mps_user.c 231240 2012-02-09 00:16:12Z ken $");
#include "opt_compat.h"
@@ -712,7 +712,7 @@
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
mps_lock(sc);
- err = mps_wait_command(sc, cm, 0);
+ err = mps_wait_command(sc, cm, 30);
if (err) {
mps_printf(sc, "%s: invalid request: error %d\n",
@@ -842,7 +842,7 @@
cm->cm_complete = NULL;
cm->cm_complete_data = NULL;
- err = mps_wait_command(sc, cm, 0);
+ err = mps_wait_command(sc, cm, 30);
if (err != 0) {
err = EIO;
@@ -979,7 +979,7 @@
mps_lock(sc);
- err = mps_wait_command(sc, cm, 0);
+ err = mps_wait_command(sc, cm, 30);
if (err) {
mps_printf(sc, "%s: invalid request: error %d\n", __func__,
@@ -1098,10 +1098,12 @@
* Need to get BIOS Config Page 3 for the BIOS Version.
*/
data->BiosVersion = 0;
+ mps_lock(sc);
if (mps_config_get_bios_pg3(sc, &mpi_reply, &config_page))
printf("%s: Error while retrieving BIOS Version\n", __func__);
else
data->BiosVersion = config_page.BiosVersion;
+ mps_unlock(sc);
}
static void
@@ -1194,7 +1196,7 @@
/*
* Send command synchronously.
*/
- status = mps_wait_command(sc, cm, 0);
+ status = mps_wait_command(sc, cm, 30);
if (status) {
mps_printf(sc, "%s: invalid request: error %d\n", __func__,
status);
@@ -1278,7 +1280,7 @@
/*
* Send command synchronously.
*/
- status = mps_wait_command(sc, cm, 0);
+ status = mps_wait_command(sc, cm, 30);
if (status) {
mps_printf(sc, "%s: invalid request: error %d\n", __func__,
status);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mps/mpsvar.h
--- a/head/sys/dev/mps/mpsvar.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mps/mpsvar.h Fri Mar 02 17:36:33 2012 +0200
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/dev/mps/mpsvar.h 230592 2012-01-26 18:17:21Z ken $
+ * $FreeBSD: head/sys/dev/mps/mpsvar.h 231240 2012-02-09 00:16:12Z ken $
*/
/*-
* Copyright (c) 2011 LSI Corp.
@@ -52,13 +52,13 @@
*
* LSI MPT-Fusion Host Adapter FreeBSD
*
- * $FreeBSD: head/sys/dev/mps/mpsvar.h 230592 2012-01-26 18:17:21Z ken $
+ * $FreeBSD: head/sys/dev/mps/mpsvar.h 231240 2012-02-09 00:16:12Z ken $
*/
#ifndef _MPSVAR_H
#define _MPSVAR_H
-#define MPS_DRIVER_VERSION "11.255.03.00-fbsd"
+#define MPS_DRIVER_VERSION "13.00.00.00-fbsd"
#define MPS_DB_MAX_WAIT 2500
@@ -78,6 +78,7 @@
#define MPS_PERIODIC_DELAY 1 /* 1 second heartbeat/watchdog check */
#define MPS_SCSI_RI_INVALID_FRAME (0x00000002)
+#define MPS_STRING_LENGTH 64
/*
* host mapping related macro definitions
@@ -309,7 +310,7 @@
struct callout periodic;
struct mpssas_softc *sassc;
-
+ char tmp_string[MPS_STRING_LENGTH];
TAILQ_HEAD(, mps_command) req_list;
TAILQ_HEAD(, mps_command) high_priority_req_list;
TAILQ_HEAD(, mps_chain) chain_list;
@@ -521,6 +522,12 @@
cm->cm_max_segs = 0;
cm->cm_lun = 0;
cm->cm_state = MPS_CM_STATE_FREE;
+ cm->cm_data = NULL;
+ cm->cm_length = 0;
+ cm->cm_out_len = 0;
+ cm->cm_sglsize = 0;
+ cm->cm_sge = NULL;
+
TAILQ_FOREACH_SAFE(chain, &cm->cm_chain_list, chain_link, chain_temp) {
TAILQ_REMOVE(&cm->cm_chain_list, chain, chain_link);
mps_free_chain(sc, chain);
@@ -749,7 +756,9 @@
void mpssas_evt_handler(struct mps_softc *sc, uintptr_t data,
MPI2_EVENT_NOTIFICATION_REPLY *event);
void mpssas_prepare_remove(struct mpssas_softc *sassc, uint16_t handle);
+void mpssas_prepare_volume_remove(struct mpssas_softc *sassc, uint16_t handle);
int mpssas_startup(struct mps_softc *sc);
+struct mpssas_target * mpssas_find_target_by_handle(struct mpssas_softc *, int, uint16_t);
SYSCTL_DECL(_hw_mps);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mpt/mpilib/mpi_type.h
--- a/head/sys/dev/mpt/mpilib/mpi_type.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mpt/mpilib/mpi_type.h Fri Mar 02 17:36:33 2012 +0200
@@ -1,4 +1,4 @@
-/* $FreeBSD$ */
+/* $FreeBSD: head/sys/dev/mpt/mpilib/mpi_type.h 231678 2012-02-14 12:50:20Z tijl $ */
/*
* Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
* All rights reserved.
@@ -84,7 +84,7 @@
#else
-#if defined(unix) || defined(__arm) || defined(ALPHA) || defined(__PPC__) || defined(__ppc)
+#if defined(__unix__) || defined(__arm) || defined(ALPHA) || defined(__PPC__) || defined(__ppc)
typedef signed int S32;
typedef unsigned int U32;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mpt/mpt.c
--- a/head/sys/dev/mpt/mpt.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mpt/mpt.c Fri Mar 02 17:36:33 2012 +0200
@@ -96,7 +96,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/mpt/mpt.c 227001 2011-11-01 18:28:33Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/mpt/mpt.c 231518 2012-02-11 12:03:44Z marius $");
#include <dev/mpt/mpt.h>
#include <dev/mpt/mpt_cam.h> /* XXX For static handler registration */
@@ -148,7 +148,7 @@
mpt_pers_find(struct mpt_softc *mpt, u_int start_at)
{
KASSERT(start_at <= MPT_MAX_PERSONALITIES,
- ("mpt_pers_find: starting position out of range\n"));
+ ("mpt_pers_find: starting position out of range"));
while (start_at < MPT_MAX_PERSONALITIES
&& (mpt->mpt_pers_mask & (0x1 << start_at)) == 0) {
@@ -1053,6 +1053,12 @@
mpt_lprt(mpt, MPT_PRT_DEBUG, "hard reset\n");
+ if (mpt->is_1078) {
+ mpt_write(mpt, MPT_OFFSET_RESET_1078, 0x07);
+ DELAY(1000);
+ return;
+ }
+
error = mpt_enable_diag_mode(mpt);
if (error) {
mpt_prt(mpt, "WARNING - Could not enter diagnostic mode !\n");
@@ -1197,8 +1203,7 @@
uint32_t offset, reply_baddr;
if (req == NULL || req != &mpt->request_pool[req->index]) {
- panic("mpt_free_request bad req ptr\n");
- return;
+ panic("mpt_free_request: bad req ptr");
}
if ((nxt = req->chain) != NULL) {
req->chain = NULL;
@@ -1261,7 +1266,7 @@
req = TAILQ_FIRST(&mpt->request_free_list);
if (req != NULL) {
KASSERT(req == &mpt->request_pool[req->index],
- ("mpt_get_request: corrupted request free list\n"));
+ ("mpt_get_request: corrupted request free list"));
KASSERT(req->state == REQ_STATE_FREE,
("req %p:%u not free on free list %x index %d function %x",
req, req->serno, req->state, req->index,
@@ -2451,6 +2456,11 @@
uint32_t ext_offset;
uint32_t data;
+ if (mpt->pci_pio_reg == NULL) {
+ mpt_prt(mpt, "No PIO resource!\n");
+ return (ENXIO);
+ }
+
mpt_prt(mpt, "Downloading Firmware - Image Size %d\n",
mpt->fw_image_size);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mpt/mpt.h
--- a/head/sys/dev/mpt/mpt.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mpt/mpt.h Fri Mar 02 17:36:33 2012 +0200
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/mpt/mpt.h 224493 2011-07-29 18:35:10Z marius $ */
+/* $FreeBSD: head/sys/dev/mpt/mpt.h 231518 2012-02-11 12:03:44Z marius $ */
/*-
* Generic defines for LSI '909 FC adapters.
* FreeBSD Version.
@@ -608,7 +608,7 @@
#endif
uint32_t mpt_pers_mask;
uint32_t
- : 8,
+ : 7,
unit : 8,
ready : 1,
fw_uploaded : 1,
@@ -625,7 +625,8 @@
disabled : 1,
is_spi : 1,
is_sas : 1,
- is_fc : 1;
+ is_fc : 1,
+ is_1078 : 1;
u_int cfg_role;
u_int role; /* role: none, ini, target, both */
@@ -851,7 +852,7 @@
mpt->mpt_splsaved = s;
} else {
splx(s);
- panic("Recursed lock with mask: 0x%x\n", s);
+ panic("Recursed lock with mask: 0x%x", s);
}
}
@@ -863,7 +864,7 @@
splx(mpt->mpt_splsaved);
}
} else
- panic("Negative lock count\n");
+ panic("Negative lock count");
}
static __inline int
@@ -982,12 +983,14 @@
static __inline void
mpt_pio_write(struct mpt_softc *mpt, size_t offset, uint32_t val)
{
+ KASSERT(mpt->pci_pio_reg != NULL, ("no PIO resource"));
bus_space_write_4(mpt->pci_pio_st, mpt->pci_pio_sh, offset, val);
}
static __inline uint32_t
mpt_pio_read(struct mpt_softc *mpt, int offset)
{
+ KASSERT(mpt->pci_pio_reg != NULL, ("no PIO resource"));
return (bus_space_read_4(mpt->pci_pio_st, mpt->pci_pio_sh, offset));
}
/*********************** Reply Frame/Request Management ***********************/
@@ -1144,7 +1147,7 @@
mpt_tag_2_req(struct mpt_softc *mpt, uint32_t tag)
{
uint16_t rtg = (tag >> 18);
- KASSERT(rtg < mpt->tgt_cmds_allocated, ("bad tag %d\n", tag));
+ KASSERT(rtg < mpt->tgt_cmds_allocated, ("bad tag %d", tag));
KASSERT(mpt->tgt_cmd_ptrs, ("no cmd backpointer array"));
KASSERT(mpt->tgt_cmd_ptrs[rtg], ("no cmd backpointer"));
return (mpt->tgt_cmd_ptrs[rtg]);
@@ -1211,7 +1214,7 @@
return;
}
}
- panic("%s(%d): req %p:%u function %x not in els or tgt ptrs\n",
+ panic("%s(%d): req %p:%u function %x not in els or tgt ptrs",
s, line, req, req->serno,
((PTR_MSG_REQUEST_HEADER)req->req_vbuf)->Function);
}
@@ -1225,13 +1228,13 @@
int i;
for (i = 0; i < mpt->els_cmds_allocated; i++) {
KASSERT(req != mpt->els_cmd_ptrs[i],
- ("%s(%d): req %p:%u func %x in els ptrs at ioindex %d\n",
+ ("%s(%d): req %p:%u func %x in els ptrs at ioindex %d",
s, line, req, req->serno,
((PTR_MSG_REQUEST_HEADER)req->req_vbuf)->Function, i));
}
for (i = 0; i < mpt->tgt_cmds_allocated; i++) {
KASSERT(req != mpt->tgt_cmd_ptrs[i],
- ("%s(%d): req %p:%u func %x in tgt ptrs at ioindex %d\n",
+ ("%s(%d): req %p:%u func %x in tgt ptrs at ioindex %d",
s, line, req, req->serno,
((PTR_MSG_REQUEST_HEADER)req->req_vbuf)->Function, i));
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mpt/mpt_cam.c
--- a/head/sys/dev/mpt/mpt_cam.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mpt/mpt_cam.c Fri Mar 02 17:36:33 2012 +0200
@@ -94,7 +94,7 @@
* OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/mpt/mpt_cam.c 226118 2011-10-07 21:23:42Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/mpt/mpt_cam.c 231518 2012-02-11 12:03:44Z marius $");
#include <dev/mpt/mpt.h>
#include <dev/mpt/mpt_cam.h>
@@ -1279,8 +1279,9 @@
char *mpt_off;
union ccb *ccb;
struct mpt_softc *mpt;
- int seg, first_lim;
- uint32_t flags, nxt_off;
+ bus_addr_t chain_list_addr;
+ int first_lim, seg, this_seg_lim;
+ uint32_t addr, cur_off, flags, nxt_off, tf;
void *sglp = NULL;
MSG_REQUEST_HEADER *hdrp;
SGE_SIMPLE64 *se;
@@ -1356,7 +1357,7 @@
MPT_TGT_STATE(mpt, cmd_req)->req = NULL;
}
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
- KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d\n", __LINE__));
+ KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d", __LINE__));
xpt_done(ccb);
CAMLOCK_2_MPTLOCK(mpt);
mpt_free_request(mpt, req);
@@ -1434,16 +1435,20 @@
se = (SGE_SIMPLE64 *) sglp;
for (seg = 0; seg < first_lim; seg++, se++, dm_segs++) {
- uint32_t tf;
-
+ tf = flags;
memset(se, 0, sizeof (*se));
+ MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
se->Address.Low = htole32(dm_segs->ds_addr & 0xffffffff);
if (sizeof(bus_addr_t) > 4) {
- se->Address.High =
- htole32(((uint64_t)dm_segs->ds_addr) >> 32);
+ addr = ((uint64_t)dm_segs->ds_addr) >> 32;
+ /* SAS1078 36GB limitation WAR */
+ if (mpt->is_1078 && (((uint64_t)dm_segs->ds_addr +
+ MPI_SGE_LENGTH(se->FlagsLength)) >> 32) == 9) {
+ addr |= (1 << 31);
+ tf |= MPI_SGE_FLAGS_LOCAL_ADDRESS;
+ }
+ se->Address.High = htole32(addr);
}
- MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
- tf = flags;
if (seg == first_lim - 1) {
tf |= MPI_SGE_FLAGS_LAST_ELEMENT;
}
@@ -1468,15 +1473,11 @@
/*
* Make up the rest of the data segments out of a chain element
- * (contiained in the current request frame) which points to
+ * (contained in the current request frame) which points to
* SIMPLE64 elements in the next request frame, possibly ending
* with *another* chain element (if there's more).
*/
while (seg < nseg) {
- int this_seg_lim;
- uint32_t tf, cur_off;
- bus_addr_t chain_list_addr;
-
/*
* Point to the chain descriptor. Note that the chain
* descriptor is at the end of the *previous* list (whether
@@ -1504,7 +1505,7 @@
nxt_off += MPT_RQSL(mpt);
/*
- * Now initialized the chain descriptor.
+ * Now initialize the chain descriptor.
*/
memset(ce, 0, sizeof (*ce));
@@ -1554,16 +1555,24 @@
* set the end of list and end of buffer flags.
*/
while (seg < this_seg_lim) {
+ tf = flags;
memset(se, 0, sizeof (*se));
+ MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
se->Address.Low = htole32(dm_segs->ds_addr &
0xffffffff);
if (sizeof (bus_addr_t) > 4) {
- se->Address.High =
- htole32(((uint64_t)dm_segs->ds_addr) >> 32);
+ addr = ((uint64_t)dm_segs->ds_addr) >> 32;
+ /* SAS1078 36GB limitation WAR */
+ if (mpt->is_1078 &&
+ (((uint64_t)dm_segs->ds_addr +
+ MPI_SGE_LENGTH(se->FlagsLength)) >>
+ 32) == 9) {
+ addr |= (1 << 31);
+ tf |= MPI_SGE_FLAGS_LOCAL_ADDRESS;
+ }
+ se->Address.High = htole32(addr);
}
- MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
- tf = flags;
- if (seg == this_seg_lim - 1) {
+ if (seg == this_seg_lim - 1) {
tf |= MPI_SGE_FLAGS_LAST_ELEMENT;
}
if (seg == nseg - 1) {
@@ -1634,7 +1643,7 @@
bus_dmamap_unload(mpt->buffer_dmat, req->dmap);
}
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
- KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d\n", __LINE__));
+ KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d", __LINE__));
xpt_done(ccb);
CAMLOCK_2_MPTLOCK(mpt);
mpt_free_request(mpt, req);
@@ -1759,7 +1768,7 @@
MPT_TGT_STATE(mpt, cmd_req)->req = NULL;
}
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
- KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d\n", __LINE__));
+ KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d", __LINE__));
xpt_done(ccb);
CAMLOCK_2_MPTLOCK(mpt);
mpt_free_request(mpt, req);
@@ -1868,7 +1877,7 @@
/*
* Make up the rest of the data segments out of a chain element
- * (contiained in the current request frame) which points to
+ * (contained in the current request frame) which points to
* SIMPLE32 elements in the next request frame, possibly ending
* with *another* chain element (if there's more).
*/
@@ -1904,7 +1913,7 @@
nxt_off += MPT_RQSL(mpt);
/*
- * Now initialized the chain descriptor.
+ * Now initialize the chain descriptor.
*/
memset(ce, 0, sizeof (*ce));
@@ -1958,7 +1967,7 @@
MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
tf = flags;
- if (seg == this_seg_lim - 1) {
+ if (seg == this_seg_lim - 1) {
tf |= MPI_SGE_FLAGS_LAST_ELEMENT;
}
if (seg == nseg - 1) {
@@ -2029,7 +2038,7 @@
bus_dmamap_unload(mpt->buffer_dmat, req->dmap);
}
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
- KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d\n", __LINE__));
+ KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d", __LINE__));
xpt_done(ccb);
CAMLOCK_2_MPTLOCK(mpt);
mpt_free_request(mpt, req);
@@ -2737,7 +2746,7 @@
mpt_prt(mpt, "mpt_scsi_reply_handler: %p:%u complete\n",
req, req->serno);
}
- KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d\n", __LINE__));
+ KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d", __LINE__));
MPTLOCK_2_CAMLOCK(mpt);
xpt_done(ccb);
CAMLOCK_2_MPTLOCK(mpt);
@@ -3652,7 +3661,7 @@
break;
}
mpt_calc_geometry(ccg, /*extended*/1);
- KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d\n", __LINE__));
+ KASSERT(ccb->ccb_h.status, ("zero ccb sts at %d", __LINE__));
break;
}
case XPT_PATH_INQ: /* Path routing inquiry */
@@ -4551,7 +4560,7 @@
request_t *req;
KASSERT((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE,
- ("dxfer_len %u but direction is NONE\n", csio->dxfer_len));
+ ("dxfer_len %u but direction is NONE", csio->dxfer_len));
if ((req = mpt_get_request(mpt, FALSE)) == NULL) {
if (mpt->outofbeer == 0) {
@@ -5455,7 +5464,7 @@
mpt_set_ccb_status(ccb, CAM_REQ_CMP);
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
KASSERT(ccb->ccb_h.status,
- ("zero ccb sts at %d\n", __LINE__));
+ ("zero ccb sts at %d", __LINE__));
tgt->state = TGT_STATE_IN_CAM;
if (mpt->outofbeer) {
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
@@ -5517,7 +5526,7 @@
mpt_set_ccb_status(ccb, CAM_REQ_CMP);
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
KASSERT(ccb->ccb_h.status,
- ("ZERO ccb sts at %d\n", __LINE__));
+ ("ZERO ccb sts at %d", __LINE__));
tgt->ccb = NULL;
} else {
mpt_lprt(mpt, MPT_PRT_DEBUG,
@@ -5589,7 +5598,7 @@
}
tgt = MPT_TGT_STATE(mpt, req);
KASSERT(tgt->state == TGT_STATE_LOADING,
- ("bad state 0x%x on reply to buffer post\n", tgt->state));
+ ("bad state 0x%x on reply to buffer post", tgt->state));
mpt_assign_serno(mpt, req);
tgt->state = TGT_STATE_LOADED;
break;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mpt/mpt_pci.c
--- a/head/sys/dev/mpt/mpt_pci.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mpt/mpt_pci.c Fri Mar 02 17:36:33 2012 +0200
@@ -99,7 +99,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/mpt/mpt_pci.c 224493 2011-07-29 18:35:10Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/mpt/mpt_pci.c 231518 2012-02-11 12:03:44Z marius $");
#include <dev/mpt/mpt.h>
#include <dev/mpt/mpt_cam.h>
@@ -438,6 +438,10 @@
case PCI_PRODUCT_LSI_FC7X04X:
mpt->is_fc = 1;
break;
+ case PCI_PRODUCT_LSI_SAS1078:
+ case PCI_PRODUCT_LSI_SAS1078DE:
+ mpt->is_1078 = 1;
+ /* FALLTHROUGH */
case PCI_PRODUCT_LSI_SAS1064:
case PCI_PRODUCT_LSI_SAS1064A:
case PCI_PRODUCT_LSI_SAS1064E:
@@ -445,8 +449,6 @@
case PCI_PRODUCT_LSI_SAS1066E:
case PCI_PRODUCT_LSI_SAS1068:
case PCI_PRODUCT_LSI_SAS1068E:
- case PCI_PRODUCT_LSI_SAS1078:
- case PCI_PRODUCT_LSI_SAS1078DE:
mpt->is_sas = 1;
break;
default:
@@ -527,23 +529,31 @@
mpt->pci_pio_reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
&mpt_io_bar, RF_ACTIVE);
if (mpt->pci_pio_reg == NULL) {
- device_printf(dev, "unable to map registers in PIO mode\n");
- goto bad;
+ if (bootverbose) {
+ device_printf(dev,
+ "unable to map registers in PIO mode\n");
+ }
+ } else {
+ mpt->pci_pio_st = rman_get_bustag(mpt->pci_pio_reg);
+ mpt->pci_pio_sh = rman_get_bushandle(mpt->pci_pio_reg);
}
- mpt->pci_pio_st = rman_get_bustag(mpt->pci_pio_reg);
- mpt->pci_pio_sh = rman_get_bushandle(mpt->pci_pio_reg);
/* Allocate kernel virtual memory for the 9x9's Mem0 region */
mpt_mem_bar = PCIR_BAR(mpt_mem_bar);
mpt->pci_reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&mpt_mem_bar, RF_ACTIVE);
if (mpt->pci_reg == NULL) {
- device_printf(dev, "Unable to memory map registers.\n");
- if (mpt->is_sas) {
+ if (bootverbose || mpt->is_sas || mpt->pci_pio_reg == NULL) {
+ device_printf(dev,
+ "Unable to memory map registers.\n");
+ }
+ if (mpt->is_sas || mpt->pci_pio_reg == NULL) {
device_printf(dev, "Giving Up.\n");
goto bad;
}
- device_printf(dev, "Falling back to PIO mode.\n");
+ if (bootverbose) {
+ device_printf(dev, "Falling back to PIO mode.\n");
+ }
mpt->pci_st = mpt->pci_pio_st;
mpt->pci_sh = mpt->pci_pio_sh;
} else {
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mpt/mpt_reg.h
--- a/head/sys/dev/mpt/mpt_reg.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mpt/mpt_reg.h Fri Mar 02 17:36:33 2012 +0200
@@ -1,4 +1,4 @@
-/* $FreeBSD$ */
+/* $FreeBSD: head/sys/dev/mpt/mpt_reg.h 231518 2012-02-11 12:03:44Z marius $ */
/*-
* Generic defines for LSI '909 FC adapters.
* FreeBSD Version.
@@ -77,6 +77,7 @@
#define MPT_OFFSET_REPLY_Q 0x44
#define MPT_OFFSET_HOST_INDEX 0x50
#define MPT_OFFSET_FUBAR 0x90
+#define MPT_OFFSET_RESET_1078 0x10fc
/* Bit Maps for DOORBELL register */
enum DB_STATE_BITS {
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mvs/mvs.h
--- a/head/sys/dev/mvs/mvs.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mvs/mvs.h Fri Mar 02 17:36:33 2012 +0200
@@ -23,7 +23,7 @@
* (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: head/sys/dev/mvs/mvs.h 220830 2011-04-19 10:57:40Z mav $
+ * $FreeBSD: head/sys/dev/mvs/mvs.h 230865 2012-02-01 13:39:52Z raj $
*/
#include "mvs_if.h"
@@ -61,6 +61,9 @@
#define CHIP_SOC_LED 0x2C /* SoC LED Configuration */
+/* Additional mask for SoC devices with less than 4 channels */
+#define CHIP_SOC_HC0_MASK(num) (0xff >> ((4 - (num)) * 2))
+
/* Chip CCC registers */
#define CHIP_ICC 0x18008
#define CHIP_ICC_ALL_PORTS (1 << 4) /* all ports irq event */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/mvs/mvs_soc.c
--- a/head/sys/dev/mvs/mvs_soc.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/mvs/mvs_soc.c Fri Mar 02 17:36:33 2012 +0200
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/mvs/mvs_soc.c 227849 2011-11-22 21:56:55Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/mvs/mvs_soc.c 230865 2012-02-01 13:39:52Z raj $");
#include <sys/param.h>
#include <sys/module.h>
@@ -216,7 +216,9 @@
if (ccc)
ccim |= IC_HC0_COAL_DONE;
/* Enable chip interrupts */
- ctlr->gmim = (ccc ? IC_HC0_COAL_DONE : IC_DONE_HC0) | IC_ERR_HC0;
+ ctlr->gmim = ((ccc ? IC_HC0_COAL_DONE :
+ (IC_DONE_HC0 & CHIP_SOC_HC0_MASK(ctlr->channels))) |
+ (IC_ERR_HC0 & CHIP_SOC_HC0_MASK(ctlr->channels)));
ATA_OUTL(ctlr->r_mem, CHIP_SOC_MIM, ctlr->gmim | ctlr->pmim);
return (0);
}
@@ -291,25 +293,26 @@
struct mvs_controller *ctlr = data;
struct mvs_intr_arg arg;
void (*function)(void *);
- int p;
+ int p, chan_num;
u_int32_t ic, aic;
ic = ATA_INL(ctlr->r_mem, CHIP_SOC_MIC);
if ((ic & IC_HC0) == 0)
return;
+
/* Acknowledge interrupts of this HC. */
aic = 0;
- if (ic & (IC_DONE_IRQ << 0))
- aic |= HC_IC_DONE(0) | HC_IC_DEV(0);
- if (ic & (IC_DONE_IRQ << 2))
- aic |= HC_IC_DONE(1) | HC_IC_DEV(1);
- if (ic & (IC_DONE_IRQ << 4))
- aic |= HC_IC_DONE(2) | HC_IC_DEV(2);
- if (ic & (IC_DONE_IRQ << 6))
- aic |= HC_IC_DONE(3) | HC_IC_DEV(3);
+
+ /* Processing interrupts from each initialized channel */
+ for (chan_num = 0; chan_num < ctlr->channels; chan_num++) {
+ if (ic & (IC_DONE_IRQ << (chan_num * 2)))
+ aic |= HC_IC_DONE(chan_num) | HC_IC_DEV(chan_num);
+ }
+
if (ic & IC_HC0_COAL_DONE)
aic |= HC_IC_COAL;
ATA_OUTL(ctlr->r_mem, HC_IC, ~aic);
+
/* Call per-port interrupt handler. */
for (p = 0; p < ctlr->channels; p++) {
arg.cause = ic & (IC_ERR_IRQ|IC_DONE_IRQ);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/netmap/if_em_netmap.h
--- a/head/sys/dev/netmap/if_em_netmap.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/netmap/if_em_netmap.h Fri Mar 02 17:36:33 2012 +0200
@@ -24,55 +24,30 @@
*/
/*
- * $FreeBSD: head/sys/dev/netmap/if_em_netmap.h 229939 2012-01-10 19:57:23Z luigi $
- * $Id: if_em_netmap.h 9802 2011-12-02 18:42:37Z luigi $
+ * $FreeBSD: head/sys/dev/netmap/if_em_netmap.h 232238 2012-02-27 19:05:01Z luigi $
+ * $Id: if_em_netmap.h 10627 2012-02-23 19:37:15Z luigi $
*
- * netmap changes for if_em.
+ * netmap support for em.
*
- * For structure and details on the individual functions please see
- * ixgbe_netmap.h
+ * For more details on netmap support please see ixgbe_netmap.h
*/
+
#include <net/netmap.h>
#include <sys/selinfo.h>
#include <vm/vm.h>
#include <vm/pmap.h> /* vtophys ? */
#include <dev/netmap/netmap_kern.h>
+
static void em_netmap_block_tasks(struct adapter *);
static void em_netmap_unblock_tasks(struct adapter *);
-static int em_netmap_reg(struct ifnet *, int onoff);
-static int em_netmap_txsync(void *, u_int, int);
-static int em_netmap_rxsync(void *, u_int, int);
-static void em_netmap_lock_wrapper(void *, int, u_int);
+
static void
-em_netmap_attach(struct adapter *adapter)
+em_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int queueid)
{
- struct netmap_adapter na;
-
- bzero(&na, sizeof(na));
-
- na.ifp = adapter->ifp;
- na.separate_locks = 1;
- na.num_tx_desc = adapter->num_tx_desc;
- na.num_rx_desc = adapter->num_rx_desc;
- na.nm_txsync = em_netmap_txsync;
- na.nm_rxsync = em_netmap_rxsync;
- na.nm_lock = em_netmap_lock_wrapper;
- na.nm_register = em_netmap_reg;
- na.buff_size = NETMAP_BUF_SIZE;
- netmap_attach(&na, adapter->num_queues);
-}
-
-
-/*
- * wrapper to export locks to the generic code
- */
-static void
-em_netmap_lock_wrapper(void *_a, int what, u_int queueid)
-{
- struct adapter *adapter = _a;
+ struct adapter *adapter = ifp->if_softc;
ASSERT(queueid < adapter->num_queues);
switch (what) {
@@ -138,8 +113,9 @@
}
}
+
/*
- * register-unregister routine
+ * Register/unregister routine
*/
static int
em_netmap_reg(struct ifnet *ifp, int onoff)
@@ -171,7 +147,7 @@
}
} else {
fail:
- /* restore if_transmit */
+ /* return to non-netmap mode */
ifp->if_transmit = na->if_transmit;
ifp->if_capenable &= ~IFCAP_NETMAP;
em_init_locked(adapter); /* also enable intr */
@@ -180,18 +156,19 @@
return (error);
}
+
/*
- * Reconcile hardware and user view of the transmit ring.
+ * Reconcile kernel and user view of the transmit ring.
*/
static int
-em_netmap_txsync(void *a, u_int ring_nr, int do_lock)
+em_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
{
- struct adapter *adapter = a;
+ struct adapter *adapter = ifp->if_softc;
struct tx_ring *txr = &adapter->tx_rings[ring_nr];
- struct netmap_adapter *na = NA(adapter->ifp);
+ struct netmap_adapter *na = NA(ifp);
struct netmap_kring *kring = &na->tx_rings[ring_nr];
struct netmap_ring *ring = kring->ring;
- int j, k, l, n = 0, lim = kring->nkr_num_slots - 1;
+ u_int j, k, l, n = 0, lim = kring->nkr_num_slots - 1;
/* generate an interrupt approximately every half ring */
int report_frequency = kring->nkr_num_slots >> 1;
@@ -205,18 +182,17 @@
bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
BUS_DMASYNC_POSTREAD);
- /* check for new packets to send.
- * j indexes the netmap ring, l indexes the nic ring, and
- * j = kring->nr_hwcur, l = E1000_TDT (not tracked),
- * j == (l + kring->nkr_hwofs) % ring_size
+ /*
+ * Process new packets to send. j is the current index in the
+ * netmap ring, l is the corresponding index in the NIC ring.
*/
j = kring->nr_hwcur;
- if (j != k) { /* we have packets to send */
- l = j - kring->nkr_hwofs;
- if (l < 0)
- l += lim + 1;
- while (j != k) {
+ if (j != k) { /* we have new packets to send */
+ l = netmap_idx_k2n(kring, j);
+ for (n = 0; j != k; n++) {
+ /* slot is the current slot in the netmap ring */
struct netmap_slot *slot = &ring->slot[j];
+ /* curr is the current slot in the nic ring */
struct e1000_tx_desc *curr = &txr->tx_base[l];
struct em_buffer *txbuf = &txr->tx_buffers[l];
int flags = ((slot->flags & NS_REPORT) ||
@@ -224,7 +200,8 @@
E1000_TXD_CMD_RS : 0;
uint64_t paddr;
void *addr = PNMB(slot, &paddr);
- int len = slot->len;
+ u_int len = slot->len;
+
if (addr == netmap_buffer_base || len > NETMAP_BUF_SIZE) {
if (do_lock)
EM_TX_UNLOCK(txr);
@@ -232,26 +209,21 @@
}
slot->flags &= ~NS_REPORT;
- curr->upper.data = 0;
- curr->lower.data =
- htole32(adapter->txd_cmd | len |
- (E1000_TXD_CMD_EOP | flags) );
if (slot->flags & NS_BUF_CHANGED) {
curr->buffer_addr = htole64(paddr);
/* buffer has changed, reload map */
netmap_reload_map(txr->txtag, txbuf->map, addr);
slot->flags &= ~NS_BUF_CHANGED;
}
-
+ curr->upper.data = 0;
+ curr->lower.data = htole32(adapter->txd_cmd | len |
+ (E1000_TXD_CMD_EOP | flags) );
bus_dmamap_sync(txr->txtag, txbuf->map,
BUS_DMASYNC_PREWRITE);
j = (j == lim) ? 0 : j + 1;
l = (l == lim) ? 0 : l + 1;
- n++;
}
- kring->nr_hwcur = k;
-
- /* decrease avail by number of sent packets */
+ kring->nr_hwcur = k; /* the saved ring->cur */
kring->nr_hwavail -= n;
bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
@@ -263,9 +235,9 @@
if (n == 0 || kring->nr_hwavail < 1) {
int delta;
- /* record completed transmissions using THD. */
+ /* record completed transmissions using TDH */
l = E1000_READ_REG(&adapter->hw, E1000_TDH(ring_nr));
- if (l >= kring->nkr_num_slots) { /* XXX can happen */
+ if (l >= kring->nkr_num_slots) { /* XXX can it happen ? */
D("TDH wrap %d", l);
l -= kring->nkr_num_slots;
}
@@ -278,7 +250,7 @@
kring->nr_hwavail += delta;
}
}
- /* update avail to what the hardware knows */
+ /* update avail to what the kernel knows */
ring->avail = kring->nr_hwavail;
if (do_lock)
@@ -286,18 +258,21 @@
return 0;
}
+
/*
* Reconcile kernel and user view of the receive ring.
*/
static int
-em_netmap_rxsync(void *a, u_int ring_nr, int do_lock)
+em_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
{
- struct adapter *adapter = a;
+ struct adapter *adapter = ifp->if_softc;
struct rx_ring *rxr = &adapter->rx_rings[ring_nr];
- struct netmap_adapter *na = NA(adapter->ifp);
+ struct netmap_adapter *na = NA(ifp);
struct netmap_kring *kring = &na->rx_rings[ring_nr];
struct netmap_ring *ring = kring->ring;
- int j, k, l, n, lim = kring->nkr_num_slots - 1;
+ u_int j, l, n, lim = kring->nkr_num_slots - 1;
+ int force_update = do_lock || kring->nr_kflags & NKR_PENDINTR;
+ u_int k = ring->cur, resvd = ring->reserved;
k = ring->cur;
if (k > lim)
@@ -305,53 +280,51 @@
if (do_lock)
EM_RX_LOCK(rxr);
+
/* XXX check sync modes */
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- /* import newly received packets into the netmap ring.
- * j is an index in the netmap ring, l in the NIC ring, and
- * j = (kring->nr_hwcur + kring->nr_hwavail) % ring_size
- * l = rxr->next_to_check;
- * and
- * j == (l + kring->nkr_hwofs) % ring_size
+ /*
+ * Import newly received packets into the netmap ring.
+ * j is an index in the netmap ring, l in the NIC ring.
*/
l = rxr->next_to_check;
- j = l + kring->nkr_hwofs;
- /* here nkr_hwofs can be negative so must check for j < 0 */
- if (j < 0)
- j += lim + 1;
- else if (j > lim)
- j -= lim + 1;
- for (n = 0; ; n++) {
- struct e1000_rx_desc *curr = &rxr->rx_base[l];
+ j = netmap_idx_n2k(kring, l);
+ if (netmap_no_pendintr || force_update) {
+ for (n = 0; ; n++) {
+ struct e1000_rx_desc *curr = &rxr->rx_base[l];
+ uint32_t staterr = le32toh(curr->status);
- if ((curr->status & E1000_RXD_STAT_DD) == 0)
- break;
- ring->slot[j].len = le16toh(curr->length);
- bus_dmamap_sync(rxr->rxtag, rxr->rx_buffers[l].map,
- BUS_DMASYNC_POSTREAD);
- j = (j == lim) ? 0 : j + 1;
- /* make sure next_to_refresh follows next_to_check */
- rxr->next_to_refresh = l; // XXX
- l = (l == lim) ? 0 : l + 1;
- }
- if (n) {
- rxr->next_to_check = l;
- kring->nr_hwavail += n;
+ if ((staterr & E1000_RXD_STAT_DD) == 0)
+ break;
+ ring->slot[j].len = le16toh(curr->length);
+ bus_dmamap_sync(rxr->rxtag, rxr->rx_buffers[l].map,
+ BUS_DMASYNC_POSTREAD);
+ j = (j == lim) ? 0 : j + 1;
+ /* make sure next_to_refresh follows next_to_check */
+ rxr->next_to_refresh = l; // XXX
+ l = (l == lim) ? 0 : l + 1;
+ }
+ if (n) { /* update the state variables */
+ rxr->next_to_check = l;
+ kring->nr_hwavail += n;
+ }
+ kring->nr_kflags &= ~NKR_PENDINTR;
}
- /* skip past packets that userspace has already processed */
- j = kring->nr_hwcur;
- if (j != k) { /* userspace has read some packets. */
- n = 0;
- l = j - kring->nkr_hwofs; /* NIC ring index */
- /* here nkr_hwofs can be negative so check for l > lim */
- if (l < 0)
- l += lim + 1;
- else if (l > lim)
- l -= lim + 1;
- while (j != k) {
+ /* skip past packets that userspace has released */
+ j = kring->nr_hwcur; /* netmap ring index */
+ if (resvd > 0) {
+ if (resvd + ring->avail >= lim + 1) {
+ D("XXX invalid reserve/avail %d %d", resvd, ring->avail);
+ ring->reserved = resvd = 0; // XXX panic...
+ }
+ k = (k >= resvd) ? k - resvd : k + lim + 1 - resvd;
+ }
+ if (j != k) { /* userspace has released some packets. */
+ l = netmap_idx_k2n(kring, j); /* NIC ring index */
+ for (n = 0; j != k; n++) {
struct netmap_slot *slot = &ring->slot[j];
struct e1000_rx_desc *curr = &rxr->rx_base[l];
struct em_buffer *rxbuf = &rxr->rx_buffers[l];
@@ -364,20 +337,17 @@
return netmap_ring_reinit(kring);
}
- curr->status = 0;
if (slot->flags & NS_BUF_CHANGED) {
curr->buffer_addr = htole64(paddr);
/* buffer has changed, reload map */
netmap_reload_map(rxr->rxtag, rxbuf->map, addr);
slot->flags &= ~NS_BUF_CHANGED;
}
-
+ curr->status = 0;
bus_dmamap_sync(rxr->rxtag, rxbuf->map,
BUS_DMASYNC_PREREAD);
-
j = (j == lim) ? 0 : j + 1;
l = (l == lim) ? 0 : l + 1;
- n++;
}
kring->nr_hwavail -= n;
kring->nr_hwcur = k;
@@ -391,8 +361,29 @@
E1000_WRITE_REG(&adapter->hw, E1000_RDT(rxr->me), l);
}
/* tell userspace that there are new packets */
- ring->avail = kring->nr_hwavail ;
+ ring->avail = kring->nr_hwavail - resvd;
if (do_lock)
EM_RX_UNLOCK(rxr);
return 0;
}
+
+
+static void
+em_netmap_attach(struct adapter *adapter)
+{
+ struct netmap_adapter na;
+
+ bzero(&na, sizeof(na));
+
+ na.ifp = adapter->ifp;
+ na.separate_locks = 1;
+ na.num_tx_desc = adapter->num_tx_desc;
+ na.num_rx_desc = adapter->num_rx_desc;
+ na.nm_txsync = em_netmap_txsync;
+ na.nm_rxsync = em_netmap_rxsync;
+ na.nm_lock = em_netmap_lock_wrapper;
+ na.nm_register = em_netmap_reg;
+ netmap_attach(&na, adapter->num_queues);
+}
+
+/* end of file */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/netmap/if_igb_netmap.h
--- a/head/sys/dev/netmap/if_igb_netmap.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/netmap/if_igb_netmap.h Fri Mar 02 17:36:33 2012 +0200
@@ -24,52 +24,28 @@
*/
/*
- * $FreeBSD: head/sys/dev/netmap/if_igb_netmap.h 229939 2012-01-10 19:57:23Z luigi $
- * $Id: if_igb_netmap.h 9802 2011-12-02 18:42:37Z luigi $
+ * $FreeBSD: head/sys/dev/netmap/if_igb_netmap.h 232238 2012-02-27 19:05:01Z luigi $
+ * $Id: if_igb_netmap.h 10627 2012-02-23 19:37:15Z luigi $
*
- * netmap modifications for igb
- * contribured by Ahmed Kooli
+ * Netmap support for igb, partly contributed by Ahmed Kooli
+ * For details on netmap support please see ixgbe_netmap.h
*/
+
#include <net/netmap.h>
#include <sys/selinfo.h>
#include <vm/vm.h>
#include <vm/pmap.h> /* vtophys ? */
#include <dev/netmap/netmap_kern.h>
-static int igb_netmap_reg(struct ifnet *, int onoff);
-static int igb_netmap_txsync(void *, u_int, int);
-static int igb_netmap_rxsync(void *, u_int, int);
-static void igb_netmap_lock_wrapper(void *, int, u_int);
-
-
-static void
-igb_netmap_attach(struct adapter *adapter)
-{
- struct netmap_adapter na;
-
- bzero(&na, sizeof(na));
-
- na.ifp = adapter->ifp;
- na.separate_locks = 1;
- na.num_tx_desc = adapter->num_tx_desc;
- na.num_rx_desc = adapter->num_rx_desc;
- na.nm_txsync = igb_netmap_txsync;
- na.nm_rxsync = igb_netmap_rxsync;
- na.nm_lock = igb_netmap_lock_wrapper;
- na.nm_register = igb_netmap_reg;
- na.buff_size = NETMAP_BUF_SIZE;
- netmap_attach(&na, adapter->num_queues);
-}
-
/*
* wrapper to export locks to the generic code
*/
static void
-igb_netmap_lock_wrapper(void *_a, int what, u_int queueid)
+igb_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int queueid)
{
- struct adapter *adapter = _a;
+ struct adapter *adapter = ifp->if_softc;
ASSERT(queueid < adapter->num_queues);
switch (what) {
@@ -96,8 +72,7 @@
/*
- * support for netmap register/unregisted. We are already under core lock.
- * only called on the first init or the last unregister.
+ * register-unregister routine
*/
static int
igb_netmap_reg(struct ifnet *ifp, int onoff)
@@ -107,7 +82,7 @@
int error = 0;
if (na == NULL)
- return EINVAL;
+ return EINVAL; /* no netmap support here */
igb_disable_intr(adapter);
@@ -117,7 +92,6 @@
if (onoff) {
ifp->if_capenable |= IFCAP_NETMAP;
- /* save if_transmit to restore it later */
na->if_transmit = ifp->if_transmit;
ifp->if_transmit = netmap_start;
@@ -131,7 +105,7 @@
/* restore if_transmit */
ifp->if_transmit = na->if_transmit;
ifp->if_capenable &= ~IFCAP_NETMAP;
- igb_init_locked(adapter); /* also enables intr */
+ igb_init_locked(adapter); /* also enable intr */
}
return (error);
}
@@ -141,14 +115,14 @@
* Reconcile kernel and user view of the transmit ring.
*/
static int
-igb_netmap_txsync(void *a, u_int ring_nr, int do_lock)
+igb_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
{
- struct adapter *adapter = a;
+ struct adapter *adapter = ifp->if_softc;
struct tx_ring *txr = &adapter->tx_rings[ring_nr];
- struct netmap_adapter *na = NA(adapter->ifp);
+ struct netmap_adapter *na = NA(ifp);
struct netmap_kring *kring = &na->tx_rings[ring_nr];
struct netmap_ring *ring = kring->ring;
- int j, k, l, n = 0, lim = kring->nkr_num_slots - 1;
+ u_int j, k, l, n = 0, lim = kring->nkr_num_slots - 1;
/* generate an interrupt approximately every half ring */
int report_frequency = kring->nkr_num_slots >> 1;
@@ -162,31 +136,31 @@
bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
BUS_DMASYNC_POSTREAD);
- /* update avail to what the hardware knows */
- ring->avail = kring->nr_hwavail;
+ /* check for new packets to send.
+ * j indexes the netmap ring, l indexes the nic ring, and
+ * j = kring->nr_hwcur, l = E1000_TDT (not tracked),
+ * j == (l + kring->nkr_hwofs) % ring_size
+ */
+ j = kring->nr_hwcur;
+ if (j != k) { /* we have new packets to send */
+ /* 82575 needs the queue index added */
+ u32 olinfo_status =
+ (adapter->hw.mac.type == e1000_82575) ? (txr->me << 4) : 0;
- j = kring->nr_hwcur; /* netmap ring index */
- if (j != k) { /* we have new packets to send */
- u32 olinfo_status = 0;
-
- l = j - kring->nkr_hwofs; /* NIC ring index */
- if (l < 0)
- l += lim + 1;
- /* 82575 needs the queue index added */
- if (adapter->hw.mac.type == e1000_82575)
- olinfo_status |= txr->me << 4;
-
- while (j != k) {
+ l = netmap_idx_k2n(kring, j);
+ for (n = 0; j != k; n++) {
+ /* slot is the current slot in the netmap ring */
struct netmap_slot *slot = &ring->slot[j];
- struct igb_tx_buffer *txbuf = &txr->tx_buffers[l];
+ /* curr is the current slot in the nic ring */
union e1000_adv_tx_desc *curr =
(union e1000_adv_tx_desc *)&txr->tx_base[l];
- uint64_t paddr;
- void *addr = PNMB(slot, &paddr);
+ struct igb_tx_buffer *txbuf = &txr->tx_buffers[l];
int flags = ((slot->flags & NS_REPORT) ||
j == 0 || j == report_frequency) ?
E1000_ADVTXD_DCMD_RS : 0;
- int len = slot->len;
+ uint64_t paddr;
+ void *addr = PNMB(slot, &paddr);
+ u_int len = slot->len;
if (addr == netmap_buffer_base || len > NETMAP_BUF_SIZE) {
if (do_lock)
@@ -195,8 +169,13 @@
}
slot->flags &= ~NS_REPORT;
- // XXX do we need to set the address ?
+ if (slot->flags & NS_BUF_CHANGED) {
+ /* buffer has changed, reload map */
+ netmap_reload_map(txr->txtag, txbuf->map, addr);
+ slot->flags &= ~NS_BUF_CHANGED;
+ }
curr->read.buffer_addr = htole64(paddr);
+ // XXX check olinfo and cmd_type_len
curr->read.olinfo_status =
htole32(olinfo_status |
(len<< E1000_ADVTXD_PAYLEN_SHIFT));
@@ -205,23 +184,14 @@
E1000_ADVTXD_DCMD_IFCS |
E1000_ADVTXD_DCMD_DEXT |
E1000_ADVTXD_DCMD_EOP | flags);
- if (slot->flags & NS_BUF_CHANGED) {
- /* buffer has changed, reload map */
- netmap_reload_map(txr->txtag, txbuf->map, addr);
- slot->flags &= ~NS_BUF_CHANGED;
- }
bus_dmamap_sync(txr->txtag, txbuf->map,
BUS_DMASYNC_PREWRITE);
j = (j == lim) ? 0 : j + 1;
l = (l == lim) ? 0 : l + 1;
- n++;
}
- kring->nr_hwcur = k;
-
- /* decrease avail by number of sent packets */
+ kring->nr_hwcur = k; /* the saved ring->cur */
kring->nr_hwavail -= n;
- ring->avail = kring->nr_hwavail;
/* Set the watchdog XXX ? */
txr->queue_status = IGB_QUEUE_WORKING;
@@ -232,23 +202,28 @@
E1000_WRITE_REG(&adapter->hw, E1000_TDT(txr->me), l);
}
+
if (n == 0 || kring->nr_hwavail < 1) {
int delta;
- /* record completed transmission using TDH */
+ /* record completed transmissions using TDH */
l = E1000_READ_REG(&adapter->hw, E1000_TDH(ring_nr));
- if (l >= kring->nkr_num_slots) /* XXX can it happen ? */
+ if (l >= kring->nkr_num_slots) { /* XXX can it happen ? */
+ D("TDH wrap %d", l);
l -= kring->nkr_num_slots;
+ }
delta = l - txr->next_to_clean;
if (delta) {
- /* new tx were completed */
+ /* some completed, increment hwavail. */
if (delta < 0)
delta += kring->nkr_num_slots;
txr->next_to_clean = l;
kring->nr_hwavail += delta;
- ring->avail = kring->nr_hwavail;
}
}
+ /* update avail to what the kernel knows */
+ ring->avail = kring->nr_hwavail;
+
if (do_lock)
IGB_TX_UNLOCK(txr);
return 0;
@@ -259,14 +234,16 @@
* Reconcile kernel and user view of the receive ring.
*/
static int
-igb_netmap_rxsync(void *a, u_int ring_nr, int do_lock)
+igb_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
{
- struct adapter *adapter = a;
+ struct adapter *adapter = ifp->if_softc;
struct rx_ring *rxr = &adapter->rx_rings[ring_nr];
- struct netmap_adapter *na = NA(adapter->ifp);
+ struct netmap_adapter *na = NA(ifp);
struct netmap_kring *kring = &na->rx_rings[ring_nr];
struct netmap_ring *ring = kring->ring;
- int j, k, l, n, lim = kring->nkr_num_slots - 1;
+ u_int j, l, n, lim = kring->nkr_num_slots - 1;
+ int force_update = do_lock || kring->nr_kflags & NKR_PENDINTR;
+ u_int k = ring->cur, resvd = ring->reserved;
k = ring->cur;
if (k > lim)
@@ -275,45 +252,48 @@
if (do_lock)
IGB_RX_LOCK(rxr);
- /* Sync the ring. */
+ /* XXX check sync modes */
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ /*
+ * import newly received packets into the netmap ring.
+ * j is an index in the netmap ring, l in the NIC ring.
+ */
l = rxr->next_to_check;
- j = l + kring->nkr_hwofs;
- if (j > lim)
- j -= lim + 1;
- for (n = 0; ; n++) {
- union e1000_adv_rx_desc *curr = &rxr->rx_base[l];
- uint32_t staterr = le32toh(curr->wb.upper.status_error);
+ j = netmap_idx_n2k(kring, l);
+ if (netmap_no_pendintr || force_update) {
+ for (n = 0; ; n++) {
+ union e1000_adv_rx_desc *curr = &rxr->rx_base[l];
+ uint32_t staterr = le32toh(curr->wb.upper.status_error);
- if ((staterr & E1000_RXD_STAT_DD) == 0)
- break;
- ring->slot[j].len = le16toh(curr->wb.upper.length);
-
- bus_dmamap_sync(rxr->ptag,
- rxr->rx_buffers[l].pmap, BUS_DMASYNC_POSTREAD);
- j = (j == lim) ? 0 : j + 1;
- l = (l == lim) ? 0 : l + 1;
- }
- if (n) {
- rxr->next_to_check = l;
- kring->nr_hwavail += n;
+ if ((staterr & E1000_RXD_STAT_DD) == 0)
+ break;
+ ring->slot[j].len = le16toh(curr->wb.upper.length);
+ bus_dmamap_sync(rxr->ptag,
+ rxr->rx_buffers[l].pmap, BUS_DMASYNC_POSTREAD);
+ j = (j == lim) ? 0 : j + 1;
+ l = (l == lim) ? 0 : l + 1;
+ }
+ if (n) { /* update the state variables */
+ rxr->next_to_check = l;
+ kring->nr_hwavail += n;
+ }
+ kring->nr_kflags &= ~NKR_PENDINTR;
}
- /* skip past packets that userspace has already processed,
- * making them available for reception.
- * advance nr_hwcur and issue a bus_dmamap_sync on the
- * buffers so it is safe to write to them.
- * Also increase nr_hwavail
- */
- j = kring->nr_hwcur;
- l = kring->nr_hwcur - kring->nkr_hwofs;
- if (l < 0)
- l += lim + 1;
- if (j != k) { /* userspace has read some packets. */
- n = 0;
- while (j != k) {
+ /* skip past packets that userspace has released */
+ j = kring->nr_hwcur; /* netmap ring index */
+ if (resvd > 0) {
+ if (resvd + ring->avail >= lim + 1) {
+ D("XXX invalid reserve/avail %d %d", resvd, ring->avail);
+ ring->reserved = resvd = 0; // XXX panic...
+ }
+ k = (k >= resvd) ? k - resvd : k + lim + 1 - resvd;
+ }
+ if (j != k) { /* userspace has released some packets. */
+ l = netmap_idx_k2n(kring, j);
+ for (n = 0; j != k; n++) {
struct netmap_slot *slot = ring->slot + j;
union e1000_adv_rx_desc *curr = &rxr->rx_base[l];
struct igb_rx_buf *rxbuf = rxr->rx_buffers + l;
@@ -326,33 +306,51 @@
return netmap_ring_reinit(kring);
}
- curr->wb.upper.status_error = 0;
- curr->read.pkt_addr = htole64(paddr);
if (slot->flags & NS_BUF_CHANGED) {
netmap_reload_map(rxr->ptag, rxbuf->pmap, addr);
slot->flags &= ~NS_BUF_CHANGED;
}
-
+ curr->read.pkt_addr = htole64(paddr);
+ curr->wb.upper.status_error = 0;
bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
BUS_DMASYNC_PREREAD);
-
j = (j == lim) ? 0 : j + 1;
l = (l == lim) ? 0 : l + 1;
- n++;
}
kring->nr_hwavail -= n;
- kring->nr_hwcur = ring->cur;
+ kring->nr_hwcur = k;
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- /* IMPORTANT: we must leave one free slot in the ring,
+ /*
+ * IMPORTANT: we must leave one free slot in the ring,
* so move l back by one unit
*/
l = (l == 0) ? lim : l - 1;
E1000_WRITE_REG(&adapter->hw, E1000_RDT(rxr->me), l);
}
/* tell userspace that there are new packets */
- ring->avail = kring->nr_hwavail ;
+ ring->avail = kring->nr_hwavail - resvd;
if (do_lock)
IGB_RX_UNLOCK(rxr);
return 0;
}
+
+
+static void
+igb_netmap_attach(struct adapter *adapter)
+{
+ struct netmap_adapter na;
+
+ bzero(&na, sizeof(na));
+
+ na.ifp = adapter->ifp;
+ na.separate_locks = 1;
+ na.num_tx_desc = adapter->num_tx_desc;
+ na.num_rx_desc = adapter->num_rx_desc;
+ na.nm_txsync = igb_netmap_txsync;
+ na.nm_rxsync = igb_netmap_rxsync;
+ na.nm_lock = igb_netmap_lock_wrapper;
+ na.nm_register = igb_netmap_reg;
+ netmap_attach(&na, adapter->num_queues);
+}
+/* end of file */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/netmap/if_lem_netmap.h
--- a/head/sys/dev/netmap/if_lem_netmap.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/netmap/if_lem_netmap.h Fri Mar 02 17:36:33 2012 +0200
@@ -23,14 +23,14 @@
* SUCH DAMAGE.
*/
+
/*
- * $FreeBSD: head/sys/dev/netmap/if_lem_netmap.h 229939 2012-01-10 19:57:23Z luigi $
- * $Id: if_lem_netmap.h 9802 2011-12-02 18:42:37Z luigi $
+ * $FreeBSD: head/sys/dev/netmap/if_lem_netmap.h 232238 2012-02-27 19:05:01Z luigi $
+ * $Id: if_lem_netmap.h 10627 2012-02-23 19:37:15Z luigi $
*
- * netmap support for if_lem.c
+ * netmap support for "lem"
*
- * For structure and details on the individual functions please see
- * ixgbe_netmap.h
+ * For details on netmap support please see ixgbe_netmap.h
*/
#include <net/netmap.h>
@@ -39,38 +39,11 @@
#include <vm/pmap.h> /* vtophys ? */
#include <dev/netmap/netmap_kern.h>
-static int lem_netmap_reg(struct ifnet *, int onoff);
-static int lem_netmap_txsync(void *, u_int, int);
-static int lem_netmap_rxsync(void *, u_int, int);
-static void lem_netmap_lock_wrapper(void *, int, u_int);
-
-
-SYSCTL_NODE(_dev, OID_AUTO, lem, CTLFLAG_RW, 0, "lem card");
static void
-lem_netmap_attach(struct adapter *adapter)
+lem_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int ringid)
{
- struct netmap_adapter na;
-
- bzero(&na, sizeof(na));
-
- na.ifp = adapter->ifp;
- na.separate_locks = 1;
- na.num_tx_desc = adapter->num_tx_desc;
- na.num_rx_desc = adapter->num_rx_desc;
- na.nm_txsync = lem_netmap_txsync;
- na.nm_rxsync = lem_netmap_rxsync;
- na.nm_lock = lem_netmap_lock_wrapper;
- na.nm_register = lem_netmap_reg;
- na.buff_size = NETMAP_BUF_SIZE;
- netmap_attach(&na, 1);
-}
-
-
-static void
-lem_netmap_lock_wrapper(void *_a, int what, u_int ringid)
-{
- struct adapter *adapter = _a;
+ struct adapter *adapter = ifp->if_softc;
/* only one ring here so ignore the ringid */
switch (what) {
@@ -97,7 +70,7 @@
/*
- * Register/unregister routine
+ * Register/unregister
*/
static int
lem_netmap_reg(struct ifnet *ifp, int onoff)
@@ -114,7 +87,6 @@
/* Tell the stack that the interface is no longer active */
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
- /* lem_netmap_block_tasks(adapter); */
#ifndef EM_LEGACY_IRQ // XXX do we need this ?
taskqueue_block(adapter->tq);
taskqueue_drain(adapter->tq, &adapter->rxtx_task);
@@ -123,9 +95,6 @@
if (onoff) {
ifp->if_capenable |= IFCAP_NETMAP;
- /* save if_transmit to restore it when exiting.
- * XXX what about if_start and if_qflush ?
- */
na->if_transmit = ifp->if_transmit;
ifp->if_transmit = netmap_start;
@@ -136,10 +105,10 @@
}
} else {
fail:
- /* restore non-netmap mode */
+ /* return to non-netmap mode */
ifp->if_transmit = na->if_transmit;
ifp->if_capenable &= ~IFCAP_NETMAP;
- lem_init_locked(adapter); /* also enables intr */
+ lem_init_locked(adapter); /* also enable intr */
}
#ifndef EM_LEGACY_IRQ
@@ -154,17 +123,18 @@
* Reconcile kernel and user view of the transmit ring.
*/
static int
-lem_netmap_txsync(void *a, u_int ring_nr, int do_lock)
+lem_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
{
- struct adapter *adapter = a;
- struct netmap_adapter *na = NA(adapter->ifp);
- struct netmap_kring *kring = &na->tx_rings[0];
+ struct adapter *adapter = ifp->if_softc;
+ struct netmap_adapter *na = NA(ifp);
+ struct netmap_kring *kring = &na->tx_rings[ring_nr];
struct netmap_ring *ring = kring->ring;
- int j, k, l, n = 0, lim = kring->nkr_num_slots - 1;
+ u_int j, k, l, n = 0, lim = kring->nkr_num_slots - 1;
/* generate an interrupt approximately every half ring */
int report_frequency = kring->nkr_num_slots >> 1;
+ /* take a copy of ring->cur now, and never read it again */
k = ring->cur;
if (k > lim)
return netmap_ring_reinit(kring);
@@ -173,25 +143,25 @@
EM_TX_LOCK(adapter);
bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
BUS_DMASYNC_POSTREAD);
-
- /* update avail to what the hardware knows */
- ring->avail = kring->nr_hwavail;
-
- j = kring->nr_hwcur; /* points into the netmap ring */
+ /*
+ * Process new packets to send. j is the current index in the
+ * netmap ring, l is the corresponding index in the NIC ring.
+ */
+ j = kring->nr_hwcur;
if (j != k) { /* we have new packets to send */
- l = j - kring->nkr_hwofs; /* points into the NIC ring */
- if (l < 0)
- l += lim + 1;
- while (j != k) {
+ l = netmap_idx_k2n(kring, j);
+ for (n = 0; j != k; n++) {
+ /* slot is the current slot in the netmap ring */
struct netmap_slot *slot = &ring->slot[j];
+ /* curr is the current slot in the nic ring */
struct e1000_tx_desc *curr = &adapter->tx_desc_base[l];
struct em_buffer *txbuf = &adapter->tx_buffer_area[l];
- uint64_t paddr;
- void *addr = PNMB(slot, &paddr);
int flags = ((slot->flags & NS_REPORT) ||
j == 0 || j == report_frequency) ?
E1000_TXD_CMD_RS : 0;
- int len = slot->len;
+ uint64_t paddr;
+ void *addr = PNMB(slot, &paddr);
+ u_int len = slot->len;
if (addr == netmap_buffer_base || len > NETMAP_BUF_SIZE) {
if (do_lock)
@@ -200,28 +170,24 @@
}
slot->flags &= ~NS_REPORT;
+ if (slot->flags & NS_BUF_CHANGED) {
+ /* buffer has changed, reload map */
+ netmap_reload_map(adapter->txtag, txbuf->map, addr);
+ curr->buffer_addr = htole64(paddr);
+ slot->flags &= ~NS_BUF_CHANGED;
+ }
curr->upper.data = 0;
curr->lower.data =
htole32( adapter->txd_cmd | len |
(E1000_TXD_CMD_EOP | flags) );
- if (slot->flags & NS_BUF_CHANGED) {
- curr->buffer_addr = htole64(paddr);
- /* buffer has changed, reload map */
- netmap_reload_map(adapter->txtag, txbuf->map, addr);
- slot->flags &= ~NS_BUF_CHANGED;
- }
bus_dmamap_sync(adapter->txtag, txbuf->map,
BUS_DMASYNC_PREWRITE);
j = (j == lim) ? 0 : j + 1;
l = (l == lim) ? 0 : l + 1;
- n++;
}
- kring->nr_hwcur = k;
-
- /* decrease avail by number of sent packets */
+ kring->nr_hwcur = k; /* the saved ring->cur */
kring->nr_hwavail -= n;
- ring->avail = kring->nr_hwavail;
bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
@@ -234,19 +200,22 @@
/* record completed transmissions using TDH */
l = E1000_READ_REG(&adapter->hw, E1000_TDH(0));
- if (l >= kring->nkr_num_slots) { /* can it happen ? */
+ if (l >= kring->nkr_num_slots) { /* XXX can it happen ? */
D("bad TDH %d", l);
l -= kring->nkr_num_slots;
}
delta = l - adapter->next_tx_to_clean;
if (delta) {
+ /* some tx completed, increment hwavail. */
if (delta < 0)
delta += kring->nkr_num_slots;
adapter->next_tx_to_clean = l;
kring->nr_hwavail += delta;
- ring->avail = kring->nr_hwavail;
}
}
+ /* update avail to what the kernel knows */
+ ring->avail = kring->nr_hwavail;
+
if (do_lock)
EM_TX_UNLOCK(adapter);
return 0;
@@ -257,60 +226,71 @@
* Reconcile kernel and user view of the receive ring.
*/
static int
-lem_netmap_rxsync(void *a, u_int ring_nr, int do_lock)
+lem_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
{
- struct adapter *adapter = a;
- struct netmap_adapter *na = NA(adapter->ifp);
- struct netmap_kring *kring = &na->rx_rings[0];
+ struct adapter *adapter = ifp->if_softc;
+ struct netmap_adapter *na = NA(ifp);
+ struct netmap_kring *kring = &na->rx_rings[ring_nr];
struct netmap_ring *ring = kring->ring;
- int j, k, l, n, lim = kring->nkr_num_slots - 1;
+ int j, l, n, lim = kring->nkr_num_slots - 1;
+ int force_update = do_lock || kring->nr_kflags & NKR_PENDINTR;
+ u_int k = ring->cur, resvd = ring->reserved;
- k = ring->cur;
if (k > lim)
return netmap_ring_reinit(kring);
if (do_lock)
EM_RX_LOCK(adapter);
+
/* XXX check sync modes */
bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- /* import newly received packets into the netmap ring */
- l = adapter->next_rx_desc_to_check; /* points into the NIC ring */
- j = l + kring->nkr_hwofs; /* points into the netmap ring */
- if (j > lim)
- j -= lim + 1;
- for (n = 0; ; n++) {
- struct e1000_rx_desc *curr = &adapter->rx_desc_base[l];
- int len;
+ /*
+ * Import newly received packets into the netmap ring.
+ * j is an index in the netmap ring, l in the NIC ring.
+ */
+ l = adapter->next_rx_desc_to_check;
+ j = netmap_idx_n2k(kring, l);
+ if (netmap_no_pendintr || force_update) {
+ for (n = 0; ; n++) {
+ struct e1000_rx_desc *curr = &adapter->rx_desc_base[l];
+ uint32_t staterr = le32toh(curr->status);
+ int len;
- if ((curr->status & E1000_RXD_STAT_DD) == 0)
- break;
- len = le16toh(curr->length) - 4; // CRC
-
- if (len < 0) {
- D("bogus pkt size at %d", j);
- len = 0;
+ if ((staterr & E1000_RXD_STAT_DD) == 0)
+ break;
+ len = le16toh(curr->length) - 4; // CRC
+ if (len < 0) {
+ D("bogus pkt size at %d", j);
+ len = 0;
+ }
+ ring->slot[j].len = len;
+ bus_dmamap_sync(adapter->rxtag,
+ adapter->rx_buffer_area[l].map,
+ BUS_DMASYNC_POSTREAD);
+ j = (j == lim) ? 0 : j + 1;
+ l = (l == lim) ? 0 : l + 1;
}
- ring->slot[j].len = len;
- bus_dmamap_sync(adapter->rxtag, adapter->rx_buffer_area[l].map,
- BUS_DMASYNC_POSTREAD);
- j = (j == lim) ? 0 : j + 1;
- l = (l == lim) ? 0 : l + 1;
- }
- if (n) {
- adapter->next_rx_desc_to_check = l;
- kring->nr_hwavail += n;
+ if (n) { /* update the state variables */
+ adapter->next_rx_desc_to_check = l;
+ kring->nr_hwavail += n;
+ }
+ kring->nr_kflags &= ~NKR_PENDINTR;
}
- /* skip past packets that userspace has already processed */
- j = kring->nr_hwcur; /* netmap ring index */
- if (j != k) { /* userspace has read some packets. */
- n = 0;
- l = j - kring->nkr_hwofs; /* NIC ring index */
- if (l < 0)
- l += lim + 1;
- while (j != k) {
+ /* skip past packets that userspace has released */
+ j = kring->nr_hwcur; /* netmap ring index */
+ if (resvd > 0) {
+ if (resvd + ring->avail >= lim + 1) {
+ D("XXX invalid reserve/avail %d %d", resvd, ring->avail);
+ ring->reserved = resvd = 0; // XXX panic...
+ }
+ k = (k >= resvd) ? k - resvd : k + lim + 1 - resvd;
+ }
+ if (j != k) { /* userspace has released some packets. */
+ l = netmap_idx_k2n(kring, j); /* NIC ring index */
+ for (n = 0; j != k; n++) {
struct netmap_slot *slot = &ring->slot[j];
struct e1000_rx_desc *curr = &adapter->rx_desc_base[l];
struct em_buffer *rxbuf = &adapter->rx_buffer_area[l];
@@ -322,20 +302,20 @@
EM_RX_UNLOCK(adapter);
return netmap_ring_reinit(kring);
}
- curr->status = 0;
+
if (slot->flags & NS_BUF_CHANGED) {
+ /* buffer has changed, reload map */
+ netmap_reload_map(adapter->rxtag, rxbuf->map, addr);
curr->buffer_addr = htole64(paddr);
- /* buffer has changed, and reload map */
- netmap_reload_map(adapter->rxtag, rxbuf->map, addr);
slot->flags &= ~NS_BUF_CHANGED;
}
+ curr->status = 0;
bus_dmamap_sync(adapter->rxtag, rxbuf->map,
BUS_DMASYNC_PREREAD);
j = (j == lim) ? 0 : j + 1;
l = (l == lim) ? 0 : l + 1;
- n++;
}
kring->nr_hwavail -= n;
kring->nr_hwcur = k;
@@ -348,12 +328,30 @@
l = (l == 0) ? lim : l - 1;
E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), l);
}
-
/* tell userspace that there are new packets */
- ring->avail = kring->nr_hwavail ;
+ ring->avail = kring->nr_hwavail - resvd;
if (do_lock)
EM_RX_UNLOCK(adapter);
return 0;
}
+static void
+lem_netmap_attach(struct adapter *adapter)
+{
+ struct netmap_adapter na;
+
+ bzero(&na, sizeof(na));
+
+ na.ifp = adapter->ifp;
+ na.separate_locks = 1;
+ na.num_tx_desc = adapter->num_tx_desc;
+ na.num_rx_desc = adapter->num_rx_desc;
+ na.nm_txsync = lem_netmap_txsync;
+ na.nm_rxsync = lem_netmap_rxsync;
+ na.nm_lock = lem_netmap_lock_wrapper;
+ na.nm_register = lem_netmap_reg;
+ netmap_attach(&na, 1);
+}
+
+/* end of file */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/netmap/if_re_netmap.h
--- a/head/sys/dev/netmap/if_re_netmap.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/netmap/if_re_netmap.h Fri Mar 02 17:36:33 2012 +0200
@@ -24,51 +24,29 @@
*/
/*
- * $FreeBSD: head/sys/dev/netmap/if_re_netmap.h 230055 2012-01-13 11:01:23Z luigi $
- * $Id: if_re_netmap.h 10075 2011-12-25 22:55:48Z luigi $
+ * $FreeBSD: head/sys/dev/netmap/if_re_netmap.h 232238 2012-02-27 19:05:01Z luigi $
+ * $Id: if_re_netmap.h 10609 2012-02-22 19:44:58Z luigi $
*
- * netmap support for if_re
+ * netmap support for "re"
+ * For details on netmap support please see ixgbe_netmap.h
*/
+
#include <net/netmap.h>
#include <sys/selinfo.h>
#include <vm/vm.h>
#include <vm/pmap.h> /* vtophys ? */
#include <dev/netmap/netmap_kern.h>
-static int re_netmap_reg(struct ifnet *, int onoff);
-static int re_netmap_txsync(void *, u_int, int);
-static int re_netmap_rxsync(void *, u_int, int);
-static void re_netmap_lock_wrapper(void *, int, u_int);
-
-static void
-re_netmap_attach(struct rl_softc *sc)
-{
- struct netmap_adapter na;
-
- bzero(&na, sizeof(na));
-
- na.ifp = sc->rl_ifp;
- na.separate_locks = 0;
- na.num_tx_desc = sc->rl_ldata.rl_tx_desc_cnt;
- na.num_rx_desc = sc->rl_ldata.rl_rx_desc_cnt;
- na.nm_txsync = re_netmap_txsync;
- na.nm_rxsync = re_netmap_rxsync;
- na.nm_lock = re_netmap_lock_wrapper;
- na.nm_register = re_netmap_reg;
- na.buff_size = NETMAP_BUF_SIZE;
- netmap_attach(&na, 1);
-}
-
/*
* wrapper to export locks to the generic code
* We should not use the tx/rx locks
*/
static void
-re_netmap_lock_wrapper(void *_a, int what, u_int queueid)
+re_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int queueid)
{
- struct rl_softc *adapter = _a;
+ struct rl_softc *adapter = ifp->if_softc;
switch (what) {
case NETMAP_CORE_LOCK:
@@ -134,9 +112,9 @@
* Reconcile kernel and user view of the transmit ring.
*/
static int
-re_netmap_txsync(void *a, u_int ring_nr, int do_lock)
+re_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
{
- struct rl_softc *sc = a;
+ struct rl_softc *sc = ifp->if_softc;
struct rl_txdesc *txd = sc->rl_ldata.rl_tx_desc;
struct netmap_adapter *na = NA(sc->rl_ifp);
struct netmap_kring *kring = &na->tx_rings[ring_nr];
@@ -171,14 +149,13 @@
kring->nr_hwavail += n;
}
- /* update avail to what the hardware knows */
+ /* update avail to what the kernel knows */
ring->avail = kring->nr_hwavail;
j = kring->nr_hwcur;
if (j != k) { /* we have new packets to send */
- n = 0;
l = sc->rl_ldata.rl_tx_prodidx;
- while (j != k) {
+ for (n = 0; j != k; n++) {
struct netmap_slot *slot = &ring->slot[j];
struct rl_desc *desc = &sc->rl_ldata.rl_tx_list[l];
int cmd = slot->len | RL_TDESC_CMD_EOF |
@@ -211,13 +188,10 @@
txd[l].tx_dmamap, BUS_DMASYNC_PREWRITE);
j = (j == lim) ? 0 : j + 1;
l = (l == lim) ? 0 : l + 1;
- n++;
}
sc->rl_ldata.rl_tx_prodidx = l;
- kring->nr_hwcur = k;
-
- /* decrease avail by number of sent packets */
- ring->avail -= n;
+ kring->nr_hwcur = k; /* the saved ring->cur */
+ ring->avail -= n; // XXX see others
kring->nr_hwavail = ring->avail;
bus_dmamap_sync(sc->rl_ldata.rl_tx_list_tag,
@@ -237,14 +211,16 @@
* Reconcile kernel and user view of the receive ring.
*/
static int
-re_netmap_rxsync(void *a, u_int ring_nr, int do_lock)
+re_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
{
- struct rl_softc *sc = a;
+ struct rl_softc *sc = ifp->if_softc;
struct rl_rxdesc *rxd = sc->rl_ldata.rl_rx_desc;
struct netmap_adapter *na = NA(sc->rl_ifp);
struct netmap_kring *kring = &na->rx_rings[ring_nr];
struct netmap_ring *ring = kring->ring;
- int j, k, l, n, lim = kring->nkr_num_slots - 1;
+ int j, l, n, lim = kring->nkr_num_slots - 1;
+ int force_update = do_lock || kring->nr_kflags & NKR_PENDINTR;
+ u_int k = ring->cur, resvd = ring->reserved;
k = ring->cur;
if (k > lim)
@@ -258,49 +234,54 @@
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
/*
+ * Import newly received packets into the netmap ring.
+ * j is an index in the netmap ring, l in the NIC ring.
+ *
* The device uses all the buffers in the ring, so we need
* another termination condition in addition to RL_RDESC_STAT_OWN
* cleared (all buffers could have it cleared. The easiest one
* is to limit the amount of data reported up to 'lim'
*/
l = sc->rl_ldata.rl_rx_prodidx; /* next pkt to check */
- j = l + kring->nkr_hwofs;
- for (n = kring->nr_hwavail; n < lim ; n++) {
- struct rl_desc *cur_rx = &sc->rl_ldata.rl_rx_list[l];
- uint32_t rxstat = le32toh(cur_rx->rl_cmdstat);
- uint32_t total_len;
+ j = netmap_idx_n2k(kring, l); /* the kring index */
+ if (netmap_no_pendintr || force_update) {
+ for (n = kring->nr_hwavail; n < lim ; n++) {
+ struct rl_desc *cur_rx = &sc->rl_ldata.rl_rx_list[l];
+ uint32_t rxstat = le32toh(cur_rx->rl_cmdstat);
+ uint32_t total_len;
- if ((rxstat & RL_RDESC_STAT_OWN) != 0)
- break;
- total_len = rxstat & sc->rl_rxlenmask;
- /* XXX subtract crc */
- total_len = (total_len < 4) ? 0 : total_len - 4;
- kring->ring->slot[j].len = total_len;
- /* sync was in re_newbuf() */
- bus_dmamap_sync(sc->rl_ldata.rl_rx_mtag,
- rxd[l].rx_dmamap, BUS_DMASYNC_POSTREAD);
- j = (j == lim) ? 0 : j + 1;
- l = (l == lim) ? 0 : l + 1;
- }
- if (n != kring->nr_hwavail) {
- sc->rl_ldata.rl_rx_prodidx = l;
- sc->rl_ifp->if_ipackets += n - kring->nr_hwavail;
- kring->nr_hwavail = n;
+ if ((rxstat & RL_RDESC_STAT_OWN) != 0)
+ break;
+ total_len = rxstat & sc->rl_rxlenmask;
+ /* XXX subtract crc */
+ total_len = (total_len < 4) ? 0 : total_len - 4;
+ kring->ring->slot[j].len = total_len;
+ /* sync was in re_newbuf() */
+ bus_dmamap_sync(sc->rl_ldata.rl_rx_mtag,
+ rxd[l].rx_dmamap, BUS_DMASYNC_POSTREAD);
+ j = (j == lim) ? 0 : j + 1;
+ l = (l == lim) ? 0 : l + 1;
+ }
+ if (n != kring->nr_hwavail) {
+ sc->rl_ldata.rl_rx_prodidx = l;
+ sc->rl_ifp->if_ipackets += n - kring->nr_hwavail;
+ kring->nr_hwavail = n;
+ }
+ kring->nr_kflags &= ~NKR_PENDINTR;
}
- /* skip past packets that userspace has already processed,
- * making them available for reception.
- * advance nr_hwcur and issue a bus_dmamap_sync on the
- * buffers so it is safe to write to them.
- * Also increase nr_hwavail
- */
+ /* skip past packets that userspace has released */
j = kring->nr_hwcur;
- if (j != k) { /* userspace has read some packets. */
- n = 0;
- l = kring->nr_hwcur - kring->nkr_hwofs;
- if (l < 0)
- l += lim + 1;
- while (j != k) {
+ if (resvd > 0) {
+ if (resvd + ring->avail >= lim + 1) {
+ D("XXX invalid reserve/avail %d %d", resvd, ring->avail);
+ ring->reserved = resvd = 0; // XXX panic...
+ }
+ k = (k >= resvd) ? k - resvd : k + lim + 1 - resvd;
+ }
+ if (j != k) { /* userspace has released some packets. */
+ l = netmap_idx_k2n(kring, j); /* the NIC index */
+ for (n = 0; j != k; n++) {
struct netmap_slot *slot = ring->slot + j;
struct rl_desc *desc = &sc->rl_ldata.rl_rx_list[l];
int cmd = na->buff_size | RL_RDESC_CMD_OWN;
@@ -316,20 +297,19 @@
if (l == lim) /* mark end of ring */
cmd |= RL_RDESC_CMD_EOR;
- desc->rl_cmdstat = htole32(cmd);
slot->flags &= ~NS_REPORT;
if (slot->flags & NS_BUF_CHANGED) {
+ netmap_reload_map(sc->rl_ldata.rl_rx_mtag,
+ rxd[l].rx_dmamap, addr);
desc->rl_bufaddr_lo = htole32(RL_ADDR_LO(paddr));
desc->rl_bufaddr_hi = htole32(RL_ADDR_HI(paddr));
- netmap_reload_map(sc->rl_ldata.rl_rx_mtag,
- rxd[l].rx_dmamap, addr);
slot->flags &= ~NS_BUF_CHANGED;
}
+ desc->rl_cmdstat = htole32(cmd);
bus_dmamap_sync(sc->rl_ldata.rl_rx_mtag,
rxd[l].rx_dmamap, BUS_DMASYNC_PREREAD);
j = (j == lim) ? 0 : j + 1;
l = (l == lim) ? 0 : l + 1;
- n++;
}
kring->nr_hwavail -= n;
kring->nr_hwcur = k;
@@ -340,7 +320,7 @@
BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
}
/* tell userspace that there are new packets */
- ring->avail = kring->nr_hwavail;
+ ring->avail = kring->nr_hwavail - resvd;
if (do_lock)
RL_UNLOCK(sc);
return 0;
@@ -369,15 +349,10 @@
/* l points in the netmap ring, i points in the NIC ring */
for (i = 0; i < n; i++) {
- void *addr;
uint64_t paddr;
- struct netmap_kring *kring = &na->tx_rings[0];
- int l = i + kring->nkr_hwofs;
+ int l = netmap_idx_n2k(&na->tx_rings[0], i);
+ void *addr = PNMB(slot + l, &paddr);
- if (l >= n)
- l -= n;
-
- addr = PNMB(slot + l, &paddr);
desc[i].rl_bufaddr_lo = htole32(RL_ADDR_LO(paddr));
desc[i].rl_bufaddr_hi = htole32(RL_ADDR_HI(paddr));
netmap_load_map(sc->rl_ldata.rl_tx_mtag,
@@ -392,19 +367,21 @@
struct netmap_slot *slot = netmap_reset(na, NR_RX, 0, 0);
struct rl_desc *desc = sc->rl_ldata.rl_rx_list;
uint32_t cmdstat;
- int i, n;
+ int i, n, max_avail;
if (!slot)
return;
n = sc->rl_ldata.rl_rx_desc_cnt;
+ /*
+ * Userspace owned hwavail packets before the reset,
+ * so the NIC that last hwavail descriptors of the ring
+ * are still owned by the driver (and keep one empty).
+ */
+ max_avail = n - 1 - na->rx_rings[0].nr_hwavail;
for (i = 0; i < n; i++) {
void *addr;
uint64_t paddr;
- struct netmap_kring *kring = &na->rx_rings[0];
- int l = i + kring->nkr_hwofs;
-
- if (l >= n)
- l -= n;
+ int l = netmap_idx_n2k(&na->rx_rings[0], i);
addr = PNMB(slot + l, &paddr);
@@ -415,15 +392,30 @@
desc[i].rl_bufaddr_lo = htole32(RL_ADDR_LO(paddr));
desc[i].rl_bufaddr_hi = htole32(RL_ADDR_HI(paddr));
cmdstat = na->buff_size;
- if (i == n - 1)
+ if (i == n - 1) /* mark the end of ring */
cmdstat |= RL_RDESC_CMD_EOR;
- /*
- * userspace knows that hwavail packets were ready before the
- * reset, so we need to tell the NIC that last hwavail
- * descriptors of the ring are still owned by the driver.
- */
- if (i < n - 1 - kring->nr_hwavail) // XXX + 1 ?
+ if (i < max_avail)
cmdstat |= RL_RDESC_CMD_OWN;
desc[i].rl_cmdstat = htole32(cmdstat);
}
}
+
+
+static void
+re_netmap_attach(struct rl_softc *sc)
+{
+ struct netmap_adapter na;
+
+ bzero(&na, sizeof(na));
+
+ na.ifp = sc->rl_ifp;
+ na.separate_locks = 0;
+ na.num_tx_desc = sc->rl_ldata.rl_tx_desc_cnt;
+ na.num_rx_desc = sc->rl_ldata.rl_rx_desc_cnt;
+ na.nm_txsync = re_netmap_txsync;
+ na.nm_rxsync = re_netmap_rxsync;
+ na.nm_lock = re_netmap_lock_wrapper;
+ na.nm_register = re_netmap_reg;
+ netmap_attach(&na, 1);
+}
+/* end of file */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/netmap/ixgbe_netmap.h
--- a/head/sys/dev/netmap/ixgbe_netmap.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/netmap/ixgbe_netmap.h Fri Mar 02 17:36:33 2012 +0200
@@ -24,8 +24,8 @@
*/
/*
- * $FreeBSD: head/sys/dev/netmap/ixgbe_netmap.h 230572 2012-01-26 09:55:16Z luigi $
- * $Id: ixgbe_netmap.h 9802 2011-12-02 18:42:37Z luigi $
+ * $FreeBSD: head/sys/dev/netmap/ixgbe_netmap.h 232238 2012-02-27 19:05:01Z luigi $
+ * $Id: ixgbe_netmap.h 10627 2012-02-23 19:37:15Z luigi $
*
* netmap modifications for ixgbe
*
@@ -47,59 +47,16 @@
#include <vm/pmap.h>
*/
-
#include <dev/netmap/netmap_kern.h>
-/*
- * prototypes for the new API calls that are used by the
- * *_netmap_attach() routine.
- */
-static int ixgbe_netmap_reg(struct ifnet *, int onoff);
-static int ixgbe_netmap_txsync(void *, u_int, int);
-static int ixgbe_netmap_rxsync(void *, u_int, int);
-static void ixgbe_netmap_lock_wrapper(void *, int, u_int);
-
-
-/*
- * The attach routine, called near the end of ixgbe_attach(),
- * fills the parameters for netmap_attach() and calls it.
- * It cannot fail, in the worst case (such as no memory)
- * netmap mode will be disabled and the driver will only
- * operate in standard mode.
- */
-static void
-ixgbe_netmap_attach(struct adapter *adapter)
-{
- struct netmap_adapter na;
-
- bzero(&na, sizeof(na));
-
- na.ifp = adapter->ifp;
- na.separate_locks = 1; /* this card has separate rx/tx locks */
- na.num_tx_desc = adapter->num_tx_desc;
- na.num_rx_desc = adapter->num_rx_desc;
- na.nm_txsync = ixgbe_netmap_txsync;
- na.nm_rxsync = ixgbe_netmap_rxsync;
- na.nm_lock = ixgbe_netmap_lock_wrapper;
- na.nm_register = ixgbe_netmap_reg;
- /*
- * XXX where do we put this comment ?
- * adapter->rx_mbuf_sz is set by SIOCSETMTU, but in netmap mode
- * we allocate the buffers on the first register. So we must
- * disallow a SIOCSETMTU when if_capenable & IFCAP_NETMAP is set.
- */
- na.buff_size = NETMAP_BUF_SIZE;
- netmap_attach(&na, adapter->num_queues);
-}
-
/*
* wrapper to export locks to the generic netmap code.
*/
static void
-ixgbe_netmap_lock_wrapper(void *_a, int what, u_int queueid)
+ixgbe_netmap_lock_wrapper(struct ifnet *_a, int what, u_int queueid)
{
- struct adapter *adapter = _a;
+ struct adapter *adapter = _a->if_softc;
ASSERT(queueid < adapter->num_queues);
switch (what) {
@@ -126,7 +83,7 @@
/*
- * Netmap register/unregister. We are already under core lock.
+ * Register/unregister. We are already under core lock.
* Only called on the first register or the last unregister.
*/
static int
@@ -136,8 +93,8 @@
struct netmap_adapter *na = NA(ifp);
int error = 0;
- if (!na) /* probably, netmap_attach() failed */
- return EINVAL;
+ if (na == NULL)
+ return EINVAL; /* no netmap support here */
ixgbe_disable_intr(adapter);
@@ -197,14 +154,14 @@
* buffers irrespective of interrupt mitigation.
*/
static int
-ixgbe_netmap_txsync(void *a, u_int ring_nr, int do_lock)
+ixgbe_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
{
- struct adapter *adapter = a;
+ struct adapter *adapter = ifp->if_softc;
struct tx_ring *txr = &adapter->tx_rings[ring_nr];
struct netmap_adapter *na = NA(adapter->ifp);
struct netmap_kring *kring = &na->tx_rings[ring_nr];
struct netmap_ring *ring = kring->ring;
- int j, k, l, n = 0, lim = kring->nkr_num_slots - 1;
+ u_int j, k = ring->cur, l, n = 0, lim = kring->nkr_num_slots - 1;
/*
* ixgbe can generate an interrupt on every tx packet, but it
@@ -213,19 +170,10 @@
*/
int report_frequency = kring->nkr_num_slots >> 1;
+ if (k > lim)
+ return netmap_ring_reinit(kring);
if (do_lock)
IXGBE_TX_LOCK(txr);
- /* take a copy of ring->cur now, and never read it again */
- k = ring->cur;
- l = k - kring->nr_hwcur;
- if (l < 0)
- l += lim + 1;
- /* if cur is invalid reinitialize the ring. */
- if (k > lim || l > kring->nr_hwavail) {
- if (do_lock)
- IXGBE_TX_UNLOCK(txr);
- return netmap_ring_reinit(kring);
- }
bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
BUS_DMASYNC_POSTREAD);
@@ -247,11 +195,10 @@
*/
j = kring->nr_hwcur;
if (j != k) { /* we have new packets to send */
- l = j - kring->nkr_hwofs;
- if (l < 0) /* wraparound */
- l += lim + 1;
-
- while (j != k) {
+ prefetch(&ring->slot[j]);
+ l = netmap_idx_k2n(kring, j); /* NIC index */
+ prefetch(&txr->tx_buffers[l]);
+ for (n = 0; j != k; n++) {
/*
* Collect per-slot info.
* Note that txbuf and curr are indexed by l.
@@ -262,17 +209,25 @@
* Many other drivers preserve the address, so
* we only need to access it if NS_BUF_CHANGED
* is set.
+ * XXX note, on this device the dmamap* calls are
+ * not necessary because tag is 0, however just accessing
+ * the per-packet tag kills 1Mpps at 900 MHz.
*/
struct netmap_slot *slot = &ring->slot[j];
+ union ixgbe_adv_tx_desc *curr = &txr->tx_base[l];
struct ixgbe_tx_buf *txbuf = &txr->tx_buffers[l];
- union ixgbe_adv_tx_desc *curr = &txr->tx_base[l];
uint64_t paddr;
- void *addr = PNMB(slot, &paddr);
// XXX type for flags and len ?
int flags = ((slot->flags & NS_REPORT) ||
j == 0 || j == report_frequency) ?
IXGBE_TXD_CMD_RS : 0;
- int len = slot->len;
+ u_int len = slot->len;
+ void *addr = PNMB(slot, &paddr);
+
+ j = (j == lim) ? 0 : j + 1;
+ l = (l == lim) ? 0 : l + 1;
+ prefetch(&ring->slot[j]);
+ prefetch(&txr->tx_buffers[l]);
/*
* Quick check for valid addr and len.
@@ -288,41 +243,29 @@
return netmap_ring_reinit(kring);
}
+ if (slot->flags & NS_BUF_CHANGED) {
+ /* buffer has changed, unload and reload map */
+ netmap_reload_map(txr->txtag, txbuf->map, addr);
+ slot->flags &= ~NS_BUF_CHANGED;
+ }
slot->flags &= ~NS_REPORT;
/*
* Fill the slot in the NIC ring.
* In this driver we need to rewrite the buffer
* address in the NIC ring. Other drivers do not
* need this.
+ * Use legacy descriptor, it is faster.
*/
curr->read.buffer_addr = htole64(paddr);
- curr->read.olinfo_status = htole32(len << IXGBE_ADVTXD_PAYLEN_SHIFT);
- curr->read.cmd_type_len =
- htole32(txr->txd_cmd | len |
- (IXGBE_ADVTXD_DTYP_DATA |
- IXGBE_ADVTXD_DCMD_DEXT |
- IXGBE_ADVTXD_DCMD_IFCS |
- IXGBE_TXD_CMD_EOP | flags) );
- /* If the buffer has changed, unload and reload map
- * (and possibly the physical address in the NIC
- * slot, but we did it already).
- */
- if (slot->flags & NS_BUF_CHANGED) {
- /* buffer has changed, unload and reload map */
- netmap_reload_map(txr->txtag, txbuf->map, addr);
- slot->flags &= ~NS_BUF_CHANGED;
- }
+ curr->read.olinfo_status = 0;
+ curr->read.cmd_type_len = htole32(len | flags |
+ IXGBE_ADVTXD_DCMD_IFCS | IXGBE_TXD_CMD_EOP);
/* make sure changes to the buffer are synced */
- bus_dmamap_sync(txr->txtag, txbuf->map,
- BUS_DMASYNC_PREWRITE);
- j = (j == lim) ? 0 : j + 1;
- l = (l == lim) ? 0 : l + 1;
- n++;
+ bus_dmamap_sync(txr->txtag, txbuf->map, BUS_DMASYNC_PREWRITE);
}
kring->nr_hwcur = k; /* the saved ring->cur */
-
- /* decrease avail by number of sent packets */
+ /* decrease avail by number of packets sent */
kring->nr_hwavail -= n;
/* synchronize the NIC ring */
@@ -354,7 +297,8 @@
* otherwise we go to sleep (in netmap_poll()) and will be
* woken up when slot nr_kflags will be ready.
*/
- struct ixgbe_legacy_tx_desc *txd = (struct ixgbe_legacy_tx_desc *)txr->tx_base;
+ struct ixgbe_legacy_tx_desc *txd =
+ (struct ixgbe_legacy_tx_desc *)txr->tx_base;
j = txr->next_to_clean + kring->nkr_num_slots/2;
if (j >= kring->nkr_num_slots)
@@ -363,11 +307,9 @@
j= (j < kring->nkr_num_slots / 4 || j >= kring->nkr_num_slots*3/4) ?
0 : report_frequency;
kring->nr_kflags = j; /* the slot to check */
- j = txd[j].upper.fields.status & IXGBE_TXD_STAT_DD;
+ j = txd[j].upper.fields.status & IXGBE_TXD_STAT_DD; // XXX cpu_to_le32 ?
}
- if (!j) {
- netmap_skip_txsync++;
- } else {
+ if (j) {
int delta;
/*
@@ -405,7 +347,6 @@
if (do_lock)
IXGBE_TX_UNLOCK(txr);
return 0;
-
}
@@ -426,27 +367,22 @@
* do_lock has a special meaning: please refer to txsync.
*/
static int
-ixgbe_netmap_rxsync(void *a, u_int ring_nr, int do_lock)
+ixgbe_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
{
- struct adapter *adapter = a;
+ struct adapter *adapter = ifp->if_softc;
struct rx_ring *rxr = &adapter->rx_rings[ring_nr];
struct netmap_adapter *na = NA(adapter->ifp);
struct netmap_kring *kring = &na->rx_rings[ring_nr];
struct netmap_ring *ring = kring->ring;
- int j, k, l, n, lim = kring->nkr_num_slots - 1;
+ u_int j, l, n, lim = kring->nkr_num_slots - 1;
int force_update = do_lock || kring->nr_kflags & NKR_PENDINTR;
+ u_int k = ring->cur, resvd = ring->reserved;
- k = ring->cur; /* cache and check value, same as in txsync */
- n = k - kring->nr_hwcur;
- if (n < 0)
- n += lim + 1;
- if (k > lim || n > kring->nr_hwavail) /* userspace is cheating */
+ if (k > lim)
return netmap_ring_reinit(kring);
if (do_lock)
IXGBE_RX_LOCK(rxr);
- if (n < 0)
- n += lim + 1;
/* XXX check sync modes */
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
@@ -467,44 +403,46 @@
* rxr->next_to_check is set to 0 on a ring reinit
*/
l = rxr->next_to_check;
- j = rxr->next_to_check + kring->nkr_hwofs;
- if (j > lim)
- j -= lim + 1;
+ j = netmap_idx_n2k(kring, l);
- if (force_update) {
- for (n = 0; ; n++) {
- union ixgbe_adv_rx_desc *curr = &rxr->rx_base[l];
- uint32_t staterr = le32toh(curr->wb.upper.status_error);
+ if (netmap_no_pendintr || force_update) {
+ for (n = 0; ; n++) {
+ union ixgbe_adv_rx_desc *curr = &rxr->rx_base[l];
+ uint32_t staterr = le32toh(curr->wb.upper.status_error);
- if ((staterr & IXGBE_RXD_STAT_DD) == 0)
- break;
- ring->slot[j].len = le16toh(curr->wb.upper.length);
- bus_dmamap_sync(rxr->ptag,
- rxr->rx_buffers[l].pmap, BUS_DMASYNC_POSTREAD);
- j = (j == lim) ? 0 : j + 1;
- l = (l == lim) ? 0 : l + 1;
+ if ((staterr & IXGBE_RXD_STAT_DD) == 0)
+ break;
+ ring->slot[j].len = le16toh(curr->wb.upper.length);
+ bus_dmamap_sync(rxr->ptag,
+ rxr->rx_buffers[l].pmap, BUS_DMASYNC_POSTREAD);
+ j = (j == lim) ? 0 : j + 1;
+ l = (l == lim) ? 0 : l + 1;
+ }
+ if (n) { /* update the state variables */
+ rxr->next_to_check = l;
+ kring->nr_hwavail += n;
+ }
+ kring->nr_kflags &= ~NKR_PENDINTR;
}
- if (n) { /* update the state variables */
- rxr->next_to_check = l;
- kring->nr_hwavail += n;
- }
- kring->nr_kflags &= ~NKR_PENDINTR;
- }
/*
- * Skip past packets that userspace has already processed
- * (from kring->nr_hwcur to ring->cur excluded), and make
- * the buffers available for reception.
+ * Skip past packets that userspace has released
+ * (from kring->nr_hwcur to ring->cur - ring->reserved excluded),
+ * and make the buffers available for reception.
* As usual j is the index in the netmap ring, l is the index
* in the NIC ring, and j == (l + kring->nkr_hwofs) % ring_size
*/
j = kring->nr_hwcur;
- if (j != k) { /* userspace has read some packets. */
- n = 0;
- l = kring->nr_hwcur - kring->nkr_hwofs;
- if (l < 0)
- l += lim + 1;
- while (j != k) {
+ if (resvd > 0) {
+ if (resvd + ring->avail >= lim + 1) {
+ D("XXX invalid reserve/avail %d %d", resvd, ring->avail);
+ ring->reserved = resvd = 0; // XXX panic...
+ }
+ k = (k >= resvd) ? k - resvd : k + lim + 1 - resvd;
+ }
+ if (j != k) { /* userspace has released some packets. */
+ l = netmap_idx_k2n(kring, j);
+ for (n = 0; j != k; n++) {
/* collect per-slot info, with similar validations
* and flag handling as in the txsync code.
*
@@ -522,19 +460,16 @@
if (addr == netmap_buffer_base) /* bad buf */
goto ring_reset;
- curr->wb.upper.status_error = 0;
- curr->read.pkt_addr = htole64(paddr);
if (slot->flags & NS_BUF_CHANGED) {
netmap_reload_map(rxr->ptag, rxbuf->pmap, addr);
slot->flags &= ~NS_BUF_CHANGED;
}
-
+ curr->wb.upper.status_error = 0;
+ curr->read.pkt_addr = htole64(paddr);
bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
BUS_DMASYNC_PREREAD);
-
j = (j == lim) ? 0 : j + 1;
l = (l == lim) ? 0 : l + 1;
- n++;
}
kring->nr_hwavail -= n;
kring->nr_hwcur = k;
@@ -547,7 +482,8 @@
IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(rxr->me), l);
}
/* tell userspace that there are new packets */
- ring->avail = kring->nr_hwavail ;
+ ring->avail = kring->nr_hwavail - resvd;
+
if (do_lock)
IXGBE_RX_UNLOCK(rxr);
return 0;
@@ -557,4 +493,31 @@
IXGBE_RX_UNLOCK(rxr);
return netmap_ring_reinit(kring);
}
+
+
+/*
+ * The attach routine, called near the end of ixgbe_attach(),
+ * fills the parameters for netmap_attach() and calls it.
+ * It cannot fail, in the worst case (such as no memory)
+ * netmap mode will be disabled and the driver will only
+ * operate in standard mode.
+ */
+static void
+ixgbe_netmap_attach(struct adapter *adapter)
+{
+ struct netmap_adapter na;
+
+ bzero(&na, sizeof(na));
+
+ na.ifp = adapter->ifp;
+ na.separate_locks = 1; /* this card has separate rx/tx locks */
+ na.num_tx_desc = adapter->num_tx_desc;
+ na.num_rx_desc = adapter->num_rx_desc;
+ na.nm_txsync = ixgbe_netmap_txsync;
+ na.nm_rxsync = ixgbe_netmap_rxsync;
+ na.nm_lock = ixgbe_netmap_lock_wrapper;
+ na.nm_register = ixgbe_netmap_reg;
+ netmap_attach(&na, adapter->num_queues);
+}
+
/* end of file */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/netmap/netmap.c
--- a/head/sys/dev/netmap/netmap.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/netmap/netmap.c Fri Mar 02 17:36:33 2012 +0200
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 Matteo Landi, Luigi Rizzo. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -9,7 +9,7 @@
* 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 AUTHOR 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
@@ -24,9 +24,6 @@
*/
/*
- * $FreeBSD: head/sys/dev/netmap/netmap.c 230572 2012-01-26 09:55:16Z luigi $
- * $Id: netmap.c 9795 2011-12-02 11:39:08Z luigi $
- *
* This module supports memory mapped access to network devices,
* see netmap(4).
*
@@ -56,7 +53,7 @@
*/
#include <sys/cdefs.h> /* prerequisite */
-__FBSDID("$FreeBSD: head/sys/dev/netmap/netmap.c 230572 2012-01-26 09:55:16Z luigi $");
+__FBSDID("$FreeBSD: head/sys/dev/netmap/netmap.c 232238 2012-02-27 19:05:01Z luigi $");
#include <sys/types.h>
#include <sys/module.h>
@@ -90,8 +87,41 @@
/*
* lock and unlock for the netmap memory allocator
*/
-#define NMA_LOCK() mtx_lock(&netmap_mem_d->nm_mtx);
-#define NMA_UNLOCK() mtx_unlock(&netmap_mem_d->nm_mtx);
+#define NMA_LOCK() mtx_lock(&nm_mem->nm_mtx);
+#define NMA_UNLOCK() mtx_unlock(&nm_mem->nm_mtx);
+struct netmap_mem_d;
+static struct netmap_mem_d *nm_mem; /* Our memory allocator. */
+
+u_int netmap_total_buffers;
+char *netmap_buffer_base; /* address of an invalid buffer */
+
+/* user-controlled variables */
+int netmap_verbose;
+
+static int netmap_no_timestamp; /* don't timestamp on rxsync */
+
+SYSCTL_NODE(_dev, OID_AUTO, netmap, CTLFLAG_RW, 0, "Netmap args");
+SYSCTL_INT(_dev_netmap, OID_AUTO, verbose,
+ CTLFLAG_RW, &netmap_verbose, 0, "Verbose mode");
+SYSCTL_INT(_dev_netmap, OID_AUTO, no_timestamp,
+ CTLFLAG_RW, &netmap_no_timestamp, 0, "no_timestamp");
+int netmap_buf_size = 2048;
+TUNABLE_INT("hw.netmap.buf_size", &netmap_buf_size);
+SYSCTL_INT(_dev_netmap, OID_AUTO, buf_size,
+ CTLFLAG_RD, &netmap_buf_size, 0, "Size of packet buffers");
+int netmap_mitigate = 1;
+SYSCTL_INT(_dev_netmap, OID_AUTO, mitigate, CTLFLAG_RW, &netmap_mitigate, 0, "");
+int netmap_no_pendintr;
+SYSCTL_INT(_dev_netmap, OID_AUTO, no_pendintr,
+ CTLFLAG_RW, &netmap_no_pendintr, 0, "Always look for new received packets.");
+
+
+
+/*----- memory allocator -----------------*/
+/*
+ * Here we have the low level routines for memory allocator
+ * and its primary users.
+ */
/*
* Default amount of memory pre-allocated by the module.
@@ -128,30 +158,13 @@
uint32_t *bitmap; /* one bit per buffer, 1 means free */
};
struct netmap_buf_pool nm_buf_pool;
-/* XXX move these two vars back into netmap_buf_pool */
-u_int netmap_total_buffers;
-char *netmap_buffer_base; /* address of an invalid buffer */
-
-/* user-controlled variables */
-int netmap_verbose;
-
-static int no_timestamp; /* don't timestamp on rxsync */
-
-SYSCTL_NODE(_dev, OID_AUTO, netmap, CTLFLAG_RW, 0, "Netmap args");
-SYSCTL_INT(_dev_netmap, OID_AUTO, verbose,
- CTLFLAG_RW, &netmap_verbose, 0, "Verbose mode");
-SYSCTL_INT(_dev_netmap, OID_AUTO, no_timestamp,
- CTLFLAG_RW, &no_timestamp, 0, "no_timestamp");
SYSCTL_INT(_dev_netmap, OID_AUTO, total_buffers,
CTLFLAG_RD, &nm_buf_pool.total_buffers, 0, "total_buffers");
SYSCTL_INT(_dev_netmap, OID_AUTO, free_buffers,
CTLFLAG_RD, &nm_buf_pool.free, 0, "free_buffers");
-int netmap_mitigate = 1;
-SYSCTL_INT(_dev_netmap, OID_AUTO, mitigate, CTLFLAG_RW, &netmap_mitigate, 0, "");
-int netmap_skip_txsync;
-SYSCTL_INT(_dev_netmap, OID_AUTO, skip_txsync, CTLFLAG_RW, &netmap_skip_txsync, 0, "");
-int netmap_skip_rxsync;
-SYSCTL_INT(_dev_netmap, OID_AUTO, skip_rxsync, CTLFLAG_RW, &netmap_skip_rxsync, 0, "");
+
+
+
/*
* Allocate n buffers from the ring, and fill the slot.
@@ -239,196 +252,114 @@
area. */
};
-
-/* Structure associated to each thread which registered an interface. */
-struct netmap_priv_d {
- struct netmap_if *np_nifp; /* netmap interface descriptor. */
-
- struct ifnet *np_ifp; /* device for which we hold a reference */
- int np_ringid; /* from the ioctl */
- u_int np_qfirst, np_qlast; /* range of rings to scan */
- uint16_t np_txpoll;
-};
-
/* Shorthand to compute a netmap interface offset. */
#define netmap_if_offset(v) \
- ((char *) (v) - (char *) netmap_mem_d->nm_buffer)
+ ((char *) (v) - (char *) nm_mem->nm_buffer)
/* .. and get a physical address given a memory offset */
#define netmap_ofstophys(o) \
- (vtophys(netmap_mem_d->nm_buffer) + (o))
+ (vtophys(nm_mem->nm_buffer) + (o))
-static struct cdev *netmap_dev; /* /dev/netmap character device. */
-static struct netmap_mem_d *netmap_mem_d; /* Our memory allocator. */
+/*------ netmap memory allocator -------*/
+/*
+ * Request for a chunk of memory.
+ *
+ * Memory objects are arranged into a list, hence we need to walk this
+ * list until we find an object with the needed amount of data free.
+ * This sounds like a completely inefficient implementation, but given
+ * the fact that data allocation is done once, we can handle it
+ * flawlessly.
+ *
+ * Return NULL on failure.
+ */
+static void *
+netmap_malloc(size_t size, __unused const char *msg)
+{
+ struct netmap_mem_obj *mem_obj, *new_mem_obj;
+ void *ret = NULL;
-static d_mmap_t netmap_mmap;
-static d_ioctl_t netmap_ioctl;
-static d_poll_t netmap_poll;
+ NMA_LOCK();
+ TAILQ_FOREACH(mem_obj, &nm_mem->nm_molist, nmo_next) {
+ if (mem_obj->nmo_used != 0 || mem_obj->nmo_size < size)
+ continue;
-#ifdef NETMAP_KEVENT
-static d_kqfilter_t netmap_kqfilter;
-#endif
+ new_mem_obj = malloc(sizeof(struct netmap_mem_obj), M_NETMAP,
+ M_WAITOK | M_ZERO);
+ TAILQ_INSERT_BEFORE(mem_obj, new_mem_obj, nmo_next);
-static struct cdevsw netmap_cdevsw = {
- .d_version = D_VERSION,
- .d_name = "netmap",
- .d_mmap = netmap_mmap,
- .d_ioctl = netmap_ioctl,
- .d_poll = netmap_poll,
-#ifdef NETMAP_KEVENT
- .d_kqfilter = netmap_kqfilter,
-#endif
-};
+ new_mem_obj->nmo_used = 1;
+ new_mem_obj->nmo_size = size;
+ new_mem_obj->nmo_data = mem_obj->nmo_data;
+ memset(new_mem_obj->nmo_data, 0, new_mem_obj->nmo_size);
-#ifdef NETMAP_KEVENT
-static int netmap_kqread(struct knote *, long);
-static int netmap_kqwrite(struct knote *, long);
-static void netmap_kqdetach(struct knote *);
+ mem_obj->nmo_size -= size;
+ mem_obj->nmo_data = (char *) mem_obj->nmo_data + size;
+ if (mem_obj->nmo_size == 0) {
+ TAILQ_REMOVE(&nm_mem->nm_molist, mem_obj,
+ nmo_next);
+ free(mem_obj, M_NETMAP);
+ }
-static struct filterops netmap_read_filterops = {
- .f_isfd = 1,
- .f_attach = NULL,
- .f_detach = netmap_kqdetach,
- .f_event = netmap_kqread,
-};
-
-static struct filterops netmap_write_filterops = {
- .f_isfd = 1,
- .f_attach = NULL,
- .f_detach = netmap_kqdetach,
- .f_event = netmap_kqwrite,
-};
+ ret = new_mem_obj->nmo_data;
+
+ break;
+ }
+ NMA_UNLOCK();
+ ND("%s: %d bytes at %p", msg, size, ret);
+
+ return (ret);
+}
/*
- * support for the kevent() system call.
+ * Return the memory to the allocator.
*
- * This is the kevent filter, and is executed each time a new event
- * is triggered on the device. This function execute some operation
- * depending on the received filter.
- *
- * The implementation should test the filters and should implement
- * filter operations we are interested on (a full list in /sys/event.h).
- *
- * On a match we should:
- * - set kn->kn_fop
- * - set kn->kn_hook
- * - call knlist_add() to deliver the event to the application.
- *
- * Return 0 if the event should be delivered to the application.
- */
-static int
-netmap_kqfilter(struct cdev *dev, struct knote *kn)
-{
- /* declare variables needed to read/write */
-
- switch(kn->kn_filter) {
- case EVFILT_READ:
- if (netmap_verbose)
- D("%s kqfilter: EVFILT_READ" ifp->if_xname);
-
- /* read operations */
- kn->kn_fop = &netmap_read_filterops;
- break;
-
- case EVFILT_WRITE:
- if (netmap_verbose)
- D("%s kqfilter: EVFILT_WRITE" ifp->if_xname);
-
- /* write operations */
- kn->kn_fop = &netmap_write_filterops;
- break;
-
- default:
- if (netmap_verbose)
- D("%s kqfilter: invalid filter" ifp->if_xname);
- return(EINVAL);
- }
-
- kn->kn_hook = 0;//
- knlist_add(&netmap_sc->tun_rsel.si_note, kn, 0);
-
- return (0);
-}
-#endif /* NETMAP_KEVENT */
-
-/*
- * File descriptor's private data destructor.
- *
- * Call nm_register(ifp,0) to stop netmap mode on the interface and
- * revert to normal operation. We expect that np_ifp has not gone.
+ * While freeing a memory object, we try to merge adjacent chunks in
+ * order to reduce memory fragmentation.
*/
static void
-netmap_dtor(void *data)
+netmap_free(void *addr, const char *msg)
{
- struct netmap_priv_d *priv = data;
- struct ifnet *ifp = priv->np_ifp;
- struct netmap_adapter *na = NA(ifp);
- struct netmap_if *nifp = priv->np_nifp;
+ size_t size;
+ struct netmap_mem_obj *cur, *prev, *next;
- if (0)
- printf("%s starting for %p ifp %p\n", __FUNCTION__, priv,
- priv ? priv->np_ifp : NULL);
+ if (addr == NULL) {
+ D("NULL addr for %s", msg);
+ return;
+ }
- na->nm_lock(ifp->if_softc, NETMAP_CORE_LOCK, 0);
+ NMA_LOCK();
+ TAILQ_FOREACH(cur, &nm_mem->nm_molist, nmo_next) {
+ if (cur->nmo_data == addr && cur->nmo_used)
+ break;
+ }
+ if (cur == NULL) {
+ NMA_UNLOCK();
+ D("invalid addr %s %p", msg, addr);
+ return;
+ }
- na->refcount--;
- if (na->refcount <= 0) { /* last instance */
- u_int i;
+ size = cur->nmo_size;
+ cur->nmo_used = 0;
- D("deleting last netmap instance for %s", ifp->if_xname);
- /*
- * there is a race here with *_netmap_task() and
- * netmap_poll(), which don't run under NETMAP_CORE_LOCK.
- * na->refcount == 0 && na->ifp->if_capenable & IFCAP_NETMAP
- * (aka NETMAP_DELETING(na)) are a unique marker that the
- * device is dying.
- * Before destroying stuff we sleep a bit, and then complete
- * the job. NIOCREG should realize the condition and
- * loop until they can continue; the other routines
- * should check the condition at entry and quit if
- * they cannot run.
- */
- na->nm_lock(ifp->if_softc, NETMAP_CORE_UNLOCK, 0);
- tsleep(na, 0, "NIOCUNREG", 4);
- na->nm_lock(ifp->if_softc, NETMAP_CORE_LOCK, 0);
- na->nm_register(ifp, 0); /* off, clear IFCAP_NETMAP */
- /* Wake up any sleeping threads. netmap_poll will
- * then return POLLERR
- */
- for (i = 0; i < na->num_queues + 2; i++) {
- selwakeuppri(&na->tx_rings[i].si, PI_NET);
- selwakeuppri(&na->rx_rings[i].si, PI_NET);
- }
- /* release all buffers */
- NMA_LOCK();
- for (i = 0; i < na->num_queues + 1; i++) {
- int j, lim;
- struct netmap_ring *ring;
+ /* merge current chunk of memory with the previous one,
+ if present. */
+ prev = TAILQ_PREV(cur, netmap_mem_obj_h, nmo_next);
+ if (prev && prev->nmo_used == 0) {
+ TAILQ_REMOVE(&nm_mem->nm_molist, cur, nmo_next);
+ prev->nmo_size += cur->nmo_size;
+ free(cur, M_NETMAP);
+ cur = prev;
+ }
- ND("tx queue %d", i);
- ring = na->tx_rings[i].ring;
- lim = na->tx_rings[i].nkr_num_slots;
- for (j = 0; j < lim; j++)
- netmap_free_buf(nifp, ring->slot[j].buf_idx);
-
- ND("rx queue %d", i);
- ring = na->rx_rings[i].ring;
- lim = na->rx_rings[i].nkr_num_slots;
- for (j = 0; j < lim; j++)
- netmap_free_buf(nifp, ring->slot[j].buf_idx);
- }
- NMA_UNLOCK();
- netmap_free_rings(na);
- wakeup(na);
+ /* merge with the next one */
+ next = TAILQ_NEXT(cur, nmo_next);
+ if (next && next->nmo_used == 0) {
+ TAILQ_REMOVE(&nm_mem->nm_molist, next, nmo_next);
+ cur->nmo_size += next->nmo_size;
+ free(next, M_NETMAP);
}
- netmap_if_free(nifp);
-
- na->nm_lock(ifp->if_softc, NETMAP_CORE_UNLOCK, 0);
-
- if_rele(ifp);
-
- bzero(priv, sizeof(*priv)); /* XXX for safety */
- free(priv, M_DEVBUF);
+ NMA_UNLOCK();
+ ND("freed %s %d bytes at %p", msg, size, addr);
}
@@ -443,21 +374,24 @@
{
struct netmap_if *nifp;
struct netmap_ring *ring;
+ struct netmap_kring *kring;
char *buff;
- u_int i, len, ofs;
- u_int n = na->num_queues + 1; /* shorthand, include stack queue */
+ u_int i, len, ofs, numdesc;
+ u_int nrx = na->num_rx_queues + 1; /* shorthand, include stack queue */
+ u_int ntx = na->num_tx_queues + 1; /* shorthand, include stack queue */
/*
* the descriptor is followed inline by an array of offsets
* to the tx and rx rings in the shared memory region.
*/
- len = sizeof(struct netmap_if) + 2 * n * sizeof(ssize_t);
+ len = sizeof(struct netmap_if) + (nrx + ntx) * sizeof(ssize_t);
nifp = netmap_if_malloc(len);
if (nifp == NULL)
return (NULL);
/* initialize base fields */
- *(int *)(uintptr_t)&nifp->ni_num_queues = na->num_queues;
+ *(int *)(uintptr_t)&nifp->ni_rx_queues = na->num_rx_queues;
+ *(int *)(uintptr_t)&nifp->ni_tx_queues = na->num_tx_queues;
strncpy(nifp->ni_name, ifname, IFNAMSIZ);
(na->refcount)++; /* XXX atomic ? we are under lock */
@@ -465,16 +399,15 @@
goto final;
/*
- * If this is the first instance, allocate the shadow rings and
- * buffers for this card (one for each hw queue, one for the host).
+ * First instance. Allocate the netmap rings
+ * (one for each hw queue, one pair for the host).
* The rings are contiguous, but have variable size.
* The entire block is reachable at
- * na->tx_rings[0].ring
+ * na->tx_rings[0]
*/
-
- len = n * (2 * sizeof(struct netmap_ring) +
- (na->num_tx_desc + na->num_rx_desc) *
- sizeof(struct netmap_slot) );
+ len = (ntx + nrx) * sizeof(struct netmap_ring) +
+ (ntx * na->num_tx_desc + nrx * na->num_rx_desc) *
+ sizeof(struct netmap_slot);
buff = netmap_ring_malloc(len);
if (buff == NULL) {
D("failed to allocate %d bytes for %s shadow ring",
@@ -484,9 +417,8 @@
netmap_if_free(nifp);
return (NULL);
}
- /* do we have the bufers ? we are in need of num_tx_desc buffers for
- * each tx ring and num_tx_desc buffers for each rx ring. */
- len = n * (na->num_tx_desc + na->num_rx_desc);
+ /* Check whether we have enough buffers */
+ len = ntx * na->num_tx_desc + nrx * na->num_rx_desc;
NMA_LOCK();
if (nm_buf_pool.free < len) {
NMA_UNLOCK();
@@ -498,11 +430,7 @@
* and initialize the rings. We are under NMA_LOCK().
*/
ofs = 0;
- for (i = 0; i < n; i++) {
- struct netmap_kring *kring;
- int numdesc;
-
- /* Transmit rings */
+ for (i = 0; i < ntx; i++) { /* Transmit rings */
kring = &na->tx_rings[i];
numdesc = na->num_tx_desc;
bzero(kring, sizeof(*kring));
@@ -512,7 +440,7 @@
*(ssize_t *)(uintptr_t)&ring->buf_ofs =
nm_buf_pool.base - (char *)ring;
ND("txring[%d] at %p ofs %d", i, ring, ring->buf_ofs);
- *(int *)(int *)(uintptr_t)&ring->num_slots =
+ *(uint32_t *)(uintptr_t)&ring->num_slots =
kring->nkr_num_slots = numdesc;
/*
@@ -523,12 +451,14 @@
*/
ring->avail = kring->nr_hwavail = numdesc - 1;
ring->cur = kring->nr_hwcur = 0;
+ *(uint16_t *)(uintptr_t)&ring->nr_buf_size = NETMAP_BUF_SIZE;
netmap_new_bufs(nifp, ring->slot, numdesc);
ofs += sizeof(struct netmap_ring) +
numdesc * sizeof(struct netmap_slot);
+ }
- /* Receive rings */
+ for (i = 0; i < nrx; i++) { /* Receive rings */
kring = &na->rx_rings[i];
numdesc = na->num_rx_desc;
bzero(kring, sizeof(*kring));
@@ -538,34 +468,249 @@
*(ssize_t *)(uintptr_t)&ring->buf_ofs =
nm_buf_pool.base - (char *)ring;
ND("rxring[%d] at %p offset %d", i, ring, ring->buf_ofs);
- *(int *)(int *)(uintptr_t)&ring->num_slots =
+ *(uint32_t *)(uintptr_t)&ring->num_slots =
kring->nkr_num_slots = numdesc;
ring->cur = kring->nr_hwcur = 0;
ring->avail = kring->nr_hwavail = 0; /* empty */
+ *(uint16_t *)(uintptr_t)&ring->nr_buf_size = NETMAP_BUF_SIZE;
netmap_new_bufs(nifp, ring->slot, numdesc);
ofs += sizeof(struct netmap_ring) +
numdesc * sizeof(struct netmap_slot);
}
NMA_UNLOCK();
- for (i = 0; i < n+1; i++) {
- // XXX initialize the selrecord structs.
- }
+ // XXX initialize the selrecord structs.
+
final:
/*
* fill the slots for the rx and tx queues. They contain the offset
* between the ring and nifp, so the information is usable in
* userspace to reach the ring from the nifp.
*/
- for (i = 0; i < n; i++) {
- char *base = (char *)nifp;
+ for (i = 0; i < ntx; i++) {
*(ssize_t *)(uintptr_t)&nifp->ring_ofs[i] =
- (char *)na->tx_rings[i].ring - base;
- *(ssize_t *)(uintptr_t)&nifp->ring_ofs[i+n] =
- (char *)na->rx_rings[i].ring - base;
+ (char *)na->tx_rings[i].ring - (char *)nifp;
+ }
+ for (i = 0; i < nrx; i++) {
+ *(ssize_t *)(uintptr_t)&nifp->ring_ofs[i+ntx] =
+ (char *)na->rx_rings[i].ring - (char *)nifp;
}
return (nifp);
}
+/*
+ * Initialize the memory allocator.
+ *
+ * Create the descriptor for the memory , allocate the pool of memory
+ * and initialize the list of memory objects with a single chunk
+ * containing the whole pre-allocated memory marked as free.
+ *
+ * Start with a large size, then halve as needed if we fail to
+ * allocate the block. While halving, always add one extra page
+ * because buffers 0 and 1 are used for special purposes.
+ * Return 0 on success, errno otherwise.
+ */
+static int
+netmap_memory_init(void)
+{
+ struct netmap_mem_obj *mem_obj;
+ void *buf = NULL;
+ int i, n, sz = NETMAP_MEMORY_SIZE;
+ int extra_sz = 0; // space for rings and two spare buffers
+
+ for (; sz >= 1<<20; sz >>=1) {
+ extra_sz = sz/200;
+ extra_sz = (extra_sz + 2*PAGE_SIZE - 1) & ~(PAGE_SIZE-1);
+ buf = contigmalloc(sz + extra_sz,
+ M_NETMAP,
+ M_WAITOK | M_ZERO,
+ 0, /* low address */
+ -1UL, /* high address */
+ PAGE_SIZE, /* alignment */
+ 0 /* boundary */
+ );
+ if (buf)
+ break;
+ }
+ if (buf == NULL)
+ return (ENOMEM);
+ sz += extra_sz;
+ nm_mem = malloc(sizeof(struct netmap_mem_d), M_NETMAP,
+ M_WAITOK | M_ZERO);
+ mtx_init(&nm_mem->nm_mtx, "netmap memory allocator lock", NULL,
+ MTX_DEF);
+ TAILQ_INIT(&nm_mem->nm_molist);
+ nm_mem->nm_buffer = buf;
+ nm_mem->nm_totalsize = sz;
+
+ /*
+ * A buffer takes 2k, a slot takes 8 bytes + ring overhead,
+ * so the ratio is 200:1. In other words, we can use 1/200 of
+ * the memory for the rings, and the rest for the buffers,
+ * and be sure we never run out.
+ */
+ nm_mem->nm_size = sz/200;
+ nm_mem->nm_buf_start =
+ (nm_mem->nm_size + PAGE_SIZE - 1) & ~(PAGE_SIZE-1);
+ nm_mem->nm_buf_len = sz - nm_mem->nm_buf_start;
+
+ nm_buf_pool.base = nm_mem->nm_buffer;
+ nm_buf_pool.base += nm_mem->nm_buf_start;
+ netmap_buffer_base = nm_buf_pool.base;
+ D("netmap_buffer_base %p (offset %d)",
+ netmap_buffer_base, (int)nm_mem->nm_buf_start);
+ /* number of buffers, they all start as free */
+
+ netmap_total_buffers = nm_buf_pool.total_buffers =
+ nm_mem->nm_buf_len / NETMAP_BUF_SIZE;
+ nm_buf_pool.bufsize = NETMAP_BUF_SIZE;
+
+ D("Have %d MB, use %dKB for rings, %d buffers at %p",
+ (sz >> 20), (int)(nm_mem->nm_size >> 10),
+ nm_buf_pool.total_buffers, nm_buf_pool.base);
+
+ /* allocate and initialize the bitmap. Entry 0 is considered
+ * always busy (used as default when there are no buffers left).
+ */
+ n = (nm_buf_pool.total_buffers + 31) / 32;
+ nm_buf_pool.bitmap = malloc(sizeof(uint32_t) * n, M_NETMAP,
+ M_WAITOK | M_ZERO);
+ nm_buf_pool.bitmap[0] = ~3; /* slot 0 and 1 always busy */
+ for (i = 1; i < n; i++)
+ nm_buf_pool.bitmap[i] = ~0;
+ nm_buf_pool.free = nm_buf_pool.total_buffers - 2;
+
+ mem_obj = malloc(sizeof(struct netmap_mem_obj), M_NETMAP,
+ M_WAITOK | M_ZERO);
+ TAILQ_INSERT_HEAD(&nm_mem->nm_molist, mem_obj, nmo_next);
+ mem_obj->nmo_used = 0;
+ mem_obj->nmo_size = nm_mem->nm_size;
+ mem_obj->nmo_data = nm_mem->nm_buffer;
+
+ return (0);
+}
+
+
+/*
+ * Finalize the memory allocator.
+ *
+ * Free all the memory objects contained inside the list, and deallocate
+ * the pool of memory; finally free the memory allocator descriptor.
+ */
+static void
+netmap_memory_fini(void)
+{
+ struct netmap_mem_obj *mem_obj;
+
+ while (!TAILQ_EMPTY(&nm_mem->nm_molist)) {
+ mem_obj = TAILQ_FIRST(&nm_mem->nm_molist);
+ TAILQ_REMOVE(&nm_mem->nm_molist, mem_obj, nmo_next);
+ if (mem_obj->nmo_used == 1) {
+ printf("netmap: leaked %d bytes at %p\n",
+ (int)mem_obj->nmo_size,
+ mem_obj->nmo_data);
+ }
+ free(mem_obj, M_NETMAP);
+ }
+ contigfree(nm_mem->nm_buffer, nm_mem->nm_totalsize, M_NETMAP);
+ // XXX mutex_destroy(nm_mtx);
+ free(nm_mem, M_NETMAP);
+}
+/*------------- end of memory allocator -----------------*/
+
+
+/* Structure associated to each thread which registered an interface. */
+struct netmap_priv_d {
+ struct netmap_if *np_nifp; /* netmap interface descriptor. */
+
+ struct ifnet *np_ifp; /* device for which we hold a reference */
+ int np_ringid; /* from the ioctl */
+ u_int np_qfirst, np_qlast; /* range of rings to scan */
+ uint16_t np_txpoll;
+};
+
+
+/*
+ * File descriptor's private data destructor.
+ *
+ * Call nm_register(ifp,0) to stop netmap mode on the interface and
+ * revert to normal operation. We expect that np_ifp has not gone.
+ */
+static void
+netmap_dtor_locked(void *data)
+{
+ struct netmap_priv_d *priv = data;
+ struct ifnet *ifp = priv->np_ifp;
+ struct netmap_adapter *na = NA(ifp);
+ struct netmap_if *nifp = priv->np_nifp;
+
+ na->refcount--;
+ if (na->refcount <= 0) { /* last instance */
+ u_int i, j, lim;
+
+ D("deleting last netmap instance for %s", ifp->if_xname);
+ /*
+ * there is a race here with *_netmap_task() and
+ * netmap_poll(), which don't run under NETMAP_REG_LOCK.
+ * na->refcount == 0 && na->ifp->if_capenable & IFCAP_NETMAP
+ * (aka NETMAP_DELETING(na)) are a unique marker that the
+ * device is dying.
+ * Before destroying stuff we sleep a bit, and then complete
+ * the job. NIOCREG should realize the condition and
+ * loop until they can continue; the other routines
+ * should check the condition at entry and quit if
+ * they cannot run.
+ */
+ na->nm_lock(ifp, NETMAP_REG_UNLOCK, 0);
+ tsleep(na, 0, "NIOCUNREG", 4);
+ na->nm_lock(ifp, NETMAP_REG_LOCK, 0);
+ na->nm_register(ifp, 0); /* off, clear IFCAP_NETMAP */
+ /* Wake up any sleeping threads. netmap_poll will
+ * then return POLLERR
+ */
+ for (i = 0; i < na->num_tx_queues + 1; i++)
+ selwakeuppri(&na->tx_rings[i].si, PI_NET);
+ for (i = 0; i < na->num_rx_queues + 1; i++)
+ selwakeuppri(&na->rx_rings[i].si, PI_NET);
+ selwakeuppri(&na->tx_si, PI_NET);
+ selwakeuppri(&na->rx_si, PI_NET);
+ /* release all buffers */
+ NMA_LOCK();
+ for (i = 0; i < na->num_tx_queues + 1; i++) {
+ struct netmap_ring *ring = na->tx_rings[i].ring;
+ lim = na->tx_rings[i].nkr_num_slots;
+ for (j = 0; j < lim; j++)
+ netmap_free_buf(nifp, ring->slot[j].buf_idx);
+ }
+ for (i = 0; i < na->num_rx_queues + 1; i++) {
+ struct netmap_ring *ring = na->rx_rings[i].ring;
+ lim = na->rx_rings[i].nkr_num_slots;
+ for (j = 0; j < lim; j++)
+ netmap_free_buf(nifp, ring->slot[j].buf_idx);
+ }
+ NMA_UNLOCK();
+ netmap_free_rings(na);
+ wakeup(na);
+ }
+ netmap_if_free(nifp);
+}
+
+
+static void
+netmap_dtor(void *data)
+{
+ struct netmap_priv_d *priv = data;
+ struct ifnet *ifp = priv->np_ifp;
+ struct netmap_adapter *na = NA(ifp);
+
+ na->nm_lock(ifp, NETMAP_REG_LOCK, 0);
+ netmap_dtor_locked(data);
+ na->nm_lock(ifp, NETMAP_REG_UNLOCK, 0);
+
+ if_rele(ifp);
+ bzero(priv, sizeof(*priv)); /* XXX for safety */
+ free(priv, M_DEVBUF);
+}
+
/*
* mmap(2) support for the "netmap" device.
@@ -576,14 +721,16 @@
*
* Return 0 on success, -1 otherwise.
*/
+
static int
+netmap_mmap(__unused struct cdev *dev,
#if __FreeBSD_version < 900000
-netmap_mmap(__unused struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr,
- int nprot)
+ vm_offset_t offset, vm_paddr_t *paddr, int nprot
#else
-netmap_mmap(__unused struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr,
- int nprot, __unused vm_memattr_t *memattr)
+ vm_ooffset_t offset, vm_paddr_t *paddr, int nprot,
+ __unused vm_memattr_t *memattr
#endif
+ )
{
if (nprot & PROT_EXEC)
return (-1); // XXX -1 or EINVAL ?
@@ -607,7 +754,7 @@
static void
netmap_sync_to_host(struct netmap_adapter *na)
{
- struct netmap_kring *kring = &na->tx_rings[na->num_queues];
+ struct netmap_kring *kring = &na->tx_rings[na->num_tx_queues];
struct netmap_ring *ring = kring->ring;
struct mbuf *head = NULL, *tail = NULL, *m;
u_int k, n, lim = kring->nkr_num_slots - 1;
@@ -617,7 +764,7 @@
netmap_ring_reinit(kring);
return;
}
- // na->nm_lock(na->ifp->if_softc, NETMAP_CORE_LOCK, 0);
+ // na->nm_lock(na->ifp, NETMAP_CORE_LOCK, 0);
/* Take packets from hwcur to cur and pass them up.
* In case of no buffers we give up. At the end of the loop,
@@ -644,16 +791,15 @@
}
kring->nr_hwcur = k;
kring->nr_hwavail = ring->avail = lim;
- // na->nm_lock(na->ifp->if_softc, NETMAP_CORE_UNLOCK, 0);
+ // na->nm_lock(na->ifp, NETMAP_CORE_UNLOCK, 0);
/* send packets up, outside the lock */
while ((m = head) != NULL) {
head = head->m_nextpkt;
m->m_nextpkt = NULL;
- m->m_pkthdr.rcvif = na->ifp;
if (netmap_verbose & NM_VERB_HOST)
- D("sending up pkt %p size %d", m, m->m_pkthdr.len);
- (na->ifp->if_input)(na->ifp, m);
+ D("sending up pkt %p size %d", m, MBUF_LEN(m));
+ NM_SEND_UP(na->ifp, m);
}
}
@@ -668,31 +814,37 @@
static void
netmap_sync_from_host(struct netmap_adapter *na, struct thread *td)
{
- struct netmap_kring *kring = &na->rx_rings[na->num_queues];
+ struct netmap_kring *kring = &na->rx_rings[na->num_rx_queues];
struct netmap_ring *ring = kring->ring;
- int error = 1, delta;
- u_int k = ring->cur, lim = kring->nkr_num_slots;
+ u_int j, n, lim = kring->nkr_num_slots;
+ u_int k = ring->cur, resvd = ring->reserved;
- na->nm_lock(na->ifp->if_softc, NETMAP_CORE_LOCK, 0);
- if (k >= lim) /* bad value */
- goto done;
- delta = k - kring->nr_hwcur;
- if (delta < 0)
- delta += lim;
- kring->nr_hwavail -= delta;
- if (kring->nr_hwavail < 0) /* error */
- goto done;
+ na->nm_lock(na->ifp, NETMAP_CORE_LOCK, 0);
+ if (k >= lim) {
+ netmap_ring_reinit(kring);
+ return;
+ }
+ /* new packets are already set in nr_hwavail */
+ /* skip past packets that userspace has released */
+ j = kring->nr_hwcur;
+ if (resvd > 0) {
+ if (resvd + ring->avail >= lim + 1) {
+ D("XXX invalid reserve/avail %d %d", resvd, ring->avail);
+ ring->reserved = resvd = 0; // XXX panic...
+ }
+ k = (k >= resvd) ? k - resvd : k + lim - resvd;
+ }
+ if (j != k) {
+ n = k >= j ? k - j : k + lim - j;
+ kring->nr_hwavail -= n;
kring->nr_hwcur = k;
- error = 0;
- k = ring->avail = kring->nr_hwavail;
+ }
+ k = ring->avail = kring->nr_hwavail - resvd;
if (k == 0 && td)
selrecord(td, &kring->si);
if (k && (netmap_verbose & NM_VERB_HOST))
D("%d pkts from stack", k);
-done:
- na->nm_lock(na->ifp->if_softc, NETMAP_CORE_UNLOCK, 0);
- if (error)
- netmap_ring_reinit(kring);
+ na->nm_lock(na->ifp, NETMAP_CORE_UNLOCK, 0);
}
@@ -757,13 +909,13 @@
}
if (errors) {
int pos = kring - kring->na->tx_rings;
- int n = kring->na->num_queues + 2;
+ int n = kring->na->num_tx_queues + 1;
D("total %d errors", errors);
errors++;
D("%s %s[%d] reinit, cur %d -> %d avail %d -> %d",
kring->na->ifp->if_xname,
- pos < n ? "TX" : "RX", pos < n ? pos : pos - n,
+ pos < n ? "TX" : "RX", pos < n ? pos : pos - n,
ring->cur, kring->nr_hwcur,
ring->avail, kring->nr_hwavail);
ring->cur = kring->nr_hwcur;
@@ -782,39 +934,40 @@
{
struct ifnet *ifp = priv->np_ifp;
struct netmap_adapter *na = NA(ifp);
- void *adapter = na->ifp->if_softc; /* shorthand */
u_int i = ringid & NETMAP_RING_MASK;
- /* first time we don't lock */
+ /* initially (np_qfirst == np_qlast) we don't want to lock */
int need_lock = (priv->np_qfirst != priv->np_qlast);
+ int lim = na->num_rx_queues;
- if ( (ringid & NETMAP_HW_RING) && i >= na->num_queues) {
+ if (na->num_tx_queues > lim)
+ lim = na->num_tx_queues;
+ if ( (ringid & NETMAP_HW_RING) && i >= lim) {
D("invalid ring id %d", i);
return (EINVAL);
}
if (need_lock)
- na->nm_lock(adapter, NETMAP_CORE_LOCK, 0);
+ na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
priv->np_ringid = ringid;
if (ringid & NETMAP_SW_RING) {
- priv->np_qfirst = na->num_queues;
- priv->np_qlast = na->num_queues + 1;
+ priv->np_qfirst = NETMAP_SW_RING;
+ priv->np_qlast = 0;
} else if (ringid & NETMAP_HW_RING) {
priv->np_qfirst = i;
priv->np_qlast = i + 1;
} else {
priv->np_qfirst = 0;
- priv->np_qlast = na->num_queues;
+ priv->np_qlast = NETMAP_HW_RING ;
}
priv->np_txpoll = (ringid & NETMAP_NO_TX_POLL) ? 0 : 1;
if (need_lock)
- na->nm_lock(adapter, NETMAP_CORE_UNLOCK, 0);
+ na->nm_lock(ifp, NETMAP_CORE_UNLOCK, 0);
if (ringid & NETMAP_SW_RING)
D("ringid %s set to SW RING", ifp->if_xname);
else if (ringid & NETMAP_HW_RING)
D("ringid %s set to HW RING %d", ifp->if_xname,
priv->np_qfirst);
else
- D("ringid %s set to all %d HW RINGS", ifp->if_xname,
- priv->np_qlast);
+ D("ringid %s set to all %d HW RINGS", ifp->if_xname, lim);
return 0;
}
@@ -839,9 +992,8 @@
struct ifnet *ifp;
struct nmreq *nmr = (struct nmreq *) data;
struct netmap_adapter *na;
- void *adapter;
int error;
- u_int i;
+ u_int i, lim;
struct netmap_if *nifp;
CURVNET_SET(TD_TO_VNET(td));
@@ -856,22 +1008,36 @@
switch (cmd) {
case NIOCGINFO: /* return capabilities etc */
/* memsize is always valid */
- nmr->nr_memsize = netmap_mem_d->nm_totalsize;
+ nmr->nr_memsize = nm_mem->nm_totalsize;
nmr->nr_offset = 0;
- nmr->nr_numrings = 0;
- nmr->nr_numslots = 0;
+ nmr->nr_rx_rings = nmr->nr_tx_rings = 0;
+ nmr->nr_rx_slots = nmr->nr_tx_slots = 0;
+ if (nmr->nr_version != NETMAP_API) {
+ D("API mismatch got %d have %d",
+ nmr->nr_version, NETMAP_API);
+ nmr->nr_version = NETMAP_API;
+ error = EINVAL;
+ break;
+ }
if (nmr->nr_name[0] == '\0') /* just get memory info */
break;
error = get_ifp(nmr->nr_name, &ifp); /* get a refcount */
if (error)
break;
na = NA(ifp); /* retrieve netmap_adapter */
- nmr->nr_numrings = na->num_queues;
- nmr->nr_numslots = na->num_tx_desc;
+ nmr->nr_rx_rings = na->num_rx_queues;
+ nmr->nr_tx_rings = na->num_tx_queues;
+ nmr->nr_rx_slots = na->num_rx_desc;
+ nmr->nr_tx_slots = na->num_tx_desc;
if_rele(ifp); /* return the refcount */
break;
case NIOCREGIF:
+ if (nmr->nr_version != NETMAP_API) {
+ nmr->nr_version = NETMAP_API;
+ error = EINVAL;
+ break;
+ }
if (priv != NULL) { /* thread already registered */
error = netmap_set_ringid(priv, nmr->nr_ringid);
break;
@@ -881,7 +1047,6 @@
if (error)
break;
na = NA(ifp); /* retrieve netmap adapter */
- adapter = na->ifp->if_softc; /* shorthand */
/*
* Allocate the private per-thread structure.
* XXX perhaps we can use a blocking malloc ?
@@ -894,12 +1059,11 @@
break;
}
-
for (i = 10; i > 0; i--) {
- na->nm_lock(adapter, NETMAP_CORE_LOCK, 0);
+ na->nm_lock(ifp, NETMAP_REG_LOCK, 0);
if (!NETMAP_DELETING(na))
break;
- na->nm_lock(adapter, NETMAP_CORE_UNLOCK, 0);
+ na->nm_lock(ifp, NETMAP_REG_UNLOCK, 0);
tsleep(na, 0, "NIOCREGIF", hz/10);
}
if (i == 0) {
@@ -924,29 +1088,20 @@
* and make it use the shared buffers.
*/
error = na->nm_register(ifp, 1); /* mode on */
- if (error) {
- /*
- * do something similar to netmap_dtor().
- */
- netmap_free_rings(na);
- // XXX tx_rings is inline, must not be freed.
- // free(na->tx_rings, M_DEVBUF); // XXX wrong ?
- na->tx_rings = na->rx_rings = NULL;
- na->refcount--;
- netmap_if_free(nifp);
- nifp = NULL;
- }
+ if (error)
+ netmap_dtor_locked(priv);
}
if (error) { /* reg. failed, release priv and ref */
error:
- na->nm_lock(adapter, NETMAP_CORE_UNLOCK, 0);
+ na->nm_lock(ifp, NETMAP_REG_UNLOCK, 0);
+ if_rele(ifp); /* return the refcount */
+ bzero(priv, sizeof(*priv));
free(priv, M_DEVBUF);
- if_rele(ifp); /* return the refcount */
break;
}
- na->nm_lock(adapter, NETMAP_CORE_UNLOCK, 0);
+ na->nm_lock(ifp, NETMAP_REG_UNLOCK, 0);
error = devfs_set_cdevpriv(priv, netmap_dtor);
if (error != 0) {
@@ -958,9 +1113,11 @@
}
/* return the offset of the netmap_if object */
- nmr->nr_numrings = na->num_queues;
- nmr->nr_numslots = na->num_tx_desc;
- nmr->nr_memsize = netmap_mem_d->nm_totalsize;
+ nmr->nr_rx_rings = na->num_rx_queues;
+ nmr->nr_tx_rings = na->num_tx_queues;
+ nmr->nr_rx_slots = na->num_rx_desc;
+ nmr->nr_tx_slots = na->num_tx_desc;
+ nmr->nr_memsize = nm_mem->nm_totalsize;
nmr->nr_offset = netmap_if_offset(nifp);
break;
@@ -983,31 +1140,32 @@
}
ifp = priv->np_ifp; /* we have a reference */
na = NA(ifp); /* retrieve netmap adapter */
- adapter = ifp->if_softc; /* shorthand */
-
- if (priv->np_qfirst == na->num_queues) {
- /* queues to/from host */
+ if (priv->np_qfirst == NETMAP_SW_RING) { /* host rings */
if (cmd == NIOCTXSYNC)
netmap_sync_to_host(na);
else
netmap_sync_from_host(na, NULL);
break;
}
+ /* find the last ring to scan */
+ lim = priv->np_qlast;
+ if (lim == NETMAP_HW_RING)
+ lim = (cmd == NIOCTXSYNC) ? na->num_tx_queues : na->num_rx_queues;
- for (i = priv->np_qfirst; i < priv->np_qlast; i++) {
+ for (i = priv->np_qfirst; i < lim; i++) {
if (cmd == NIOCTXSYNC) {
struct netmap_kring *kring = &na->tx_rings[i];
if (netmap_verbose & NM_VERB_TXSYNC)
D("sync tx ring %d cur %d hwcur %d",
i, kring->ring->cur,
kring->nr_hwcur);
- na->nm_txsync(adapter, i, 1 /* do lock */);
+ na->nm_txsync(ifp, i, 1 /* do lock */);
if (netmap_verbose & NM_VERB_TXSYNC)
D("after sync tx ring %d cur %d hwcur %d",
i, kring->ring->cur,
kring->nr_hwcur);
} else {
- na->nm_rxsync(adapter, i, 1 /* do lock */);
+ na->nm_rxsync(ifp, i, 1 /* do lock */);
microtime(&na->rx_rings[i].ring->ts);
}
}
@@ -1021,11 +1179,8 @@
D("ignore BIOCIMMEDIATE/BIOCSHDRCMPLT/BIOCSHDRCMPLT/BIOCSSEESENT");
break;
- default:
+ default: /* allow device-specific ioctls */
{
- /*
- * allow device calls
- */
struct socket so;
bzero(&so, sizeof(so));
error = get_ifp(nmr->nr_name, &ifp); /* keep reference */
@@ -1035,6 +1190,7 @@
// so->so_proto not null.
error = ifioctl(&so, cmd, data, td);
if_rele(ifp);
+ break;
}
}
@@ -1061,7 +1217,7 @@
struct ifnet *ifp;
struct netmap_kring *kring;
u_int core_lock, i, check_all, want_tx, want_rx, revents = 0;
- void *adapter;
+ u_int lim_tx, lim_rx;
enum {NO_CL, NEED_CL, LOCKED_CL }; /* see below */
if (devfs_get_cdevpriv((void **)&priv) != 0 || priv == NULL)
@@ -1077,20 +1233,20 @@
want_tx = events & (POLLOUT | POLLWRNORM);
want_rx = events & (POLLIN | POLLRDNORM);
- adapter = ifp->if_softc;
na = NA(ifp); /* retrieve netmap adapter */
+ lim_tx = na->num_tx_queues;
+ lim_rx = na->num_rx_queues;
/* how many queues we are scanning */
- i = priv->np_qfirst;
- if (i == na->num_queues) { /* from/to host */
+ if (priv->np_qfirst == NETMAP_SW_RING) {
if (priv->np_txpoll || want_tx) {
/* push any packets up, then we are always ready */
- kring = &na->tx_rings[i];
+ kring = &na->tx_rings[lim_tx];
netmap_sync_to_host(na);
revents |= want_tx;
}
if (want_rx) {
- kring = &na->rx_rings[i];
+ kring = &na->rx_rings[lim_rx];
if (kring->ring->avail == 0)
netmap_sync_from_host(na, td);
if (kring->ring->avail > 0) {
@@ -1121,7 +1277,7 @@
* there are pending packets to send. The latter can be disabled
* passing NETMAP_NO_TX_POLL in the NIOCREG call.
*/
- check_all = (i + 1 != priv->np_qlast);
+ check_all = (priv->np_qlast == NETMAP_HW_RING) && (lim_tx > 1 || lim_rx > 1);
/*
* core_lock indicates what to do with the core lock.
@@ -1138,25 +1294,29 @@
* LOCKED_CL core lock is set, so we need to release it.
*/
core_lock = (check_all || !na->separate_locks) ? NEED_CL : NO_CL;
+ if (priv->np_qlast != NETMAP_HW_RING) {
+ lim_tx = lim_rx = priv->np_qlast;
+ }
+
/*
* We start with a lock free round which is good if we have
* data available. If this fails, then lock and call the sync
* routines.
*/
- for (i = priv->np_qfirst; want_rx && i < priv->np_qlast; i++) {
- kring = &na->rx_rings[i];
- if (kring->ring->avail > 0) {
- revents |= want_rx;
- want_rx = 0; /* also breaks the loop */
- }
+ for (i = priv->np_qfirst; want_rx && i < lim_rx; i++) {
+ kring = &na->rx_rings[i];
+ if (kring->ring->avail > 0) {
+ revents |= want_rx;
+ want_rx = 0; /* also breaks the loop */
}
- for (i = priv->np_qfirst; want_tx && i < priv->np_qlast; i++) {
- kring = &na->tx_rings[i];
- if (kring->ring->avail > 0) {
- revents |= want_tx;
- want_tx = 0; /* also breaks the loop */
- }
+ }
+ for (i = priv->np_qfirst; want_tx && i < lim_tx; i++) {
+ kring = &na->tx_rings[i];
+ if (kring->ring->avail > 0) {
+ revents |= want_tx;
+ want_tx = 0; /* also breaks the loop */
}
+ }
/*
* If we to push packets out (priv->np_txpoll) or want_tx is
@@ -1164,23 +1324,30 @@
* to avoid that the tx rings stall).
*/
if (priv->np_txpoll || want_tx) {
- for (i = priv->np_qfirst; i < priv->np_qlast; i++) {
+ for (i = priv->np_qfirst; i < lim_tx; i++) {
kring = &na->tx_rings[i];
+ /*
+ * Skip the current ring if want_tx == 0
+ * (we have already done a successful sync on
+ * a previous ring) AND kring->cur == kring->hwcur
+ * (there are no pending transmissions for this ring).
+ */
if (!want_tx && kring->ring->cur == kring->nr_hwcur)
continue;
if (core_lock == NEED_CL) {
- na->nm_lock(adapter, NETMAP_CORE_LOCK, 0);
+ na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
core_lock = LOCKED_CL;
}
if (na->separate_locks)
- na->nm_lock(adapter, NETMAP_TX_LOCK, i);
+ na->nm_lock(ifp, NETMAP_TX_LOCK, i);
if (netmap_verbose & NM_VERB_TXSYNC)
D("send %d on %s %d",
kring->ring->cur,
ifp->if_xname, i);
- if (na->nm_txsync(adapter, i, 0 /* no lock */))
+ if (na->nm_txsync(ifp, i, 0 /* no lock */))
revents |= POLLERR;
+ /* Check avail/call selrecord only if called with POLLOUT */
if (want_tx) {
if (kring->ring->avail > 0) {
/* stop at the first ring. We don't risk
@@ -1192,7 +1359,7 @@
selrecord(td, &kring->si);
}
if (na->separate_locks)
- na->nm_lock(adapter, NETMAP_TX_UNLOCK, i);
+ na->nm_lock(ifp, NETMAP_TX_UNLOCK, i);
}
}
@@ -1201,38 +1368,38 @@
* Do it on all rings because otherwise we starve.
*/
if (want_rx) {
- for (i = priv->np_qfirst; i < priv->np_qlast; i++) {
+ for (i = priv->np_qfirst; i < lim_rx; i++) {
kring = &na->rx_rings[i];
if (core_lock == NEED_CL) {
- na->nm_lock(adapter, NETMAP_CORE_LOCK, 0);
+ na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
core_lock = LOCKED_CL;
}
if (na->separate_locks)
- na->nm_lock(adapter, NETMAP_RX_LOCK, i);
+ na->nm_lock(ifp, NETMAP_RX_LOCK, i);
- if (na->nm_rxsync(adapter, i, 0 /* no lock */))
+ if (na->nm_rxsync(ifp, i, 0 /* no lock */))
revents |= POLLERR;
- if (no_timestamp == 0 ||
- kring->ring->flags & NR_TIMESTAMP)
+ if (netmap_no_timestamp == 0 ||
+ kring->ring->flags & NR_TIMESTAMP) {
microtime(&kring->ring->ts);
+ }
if (kring->ring->avail > 0)
revents |= want_rx;
else if (!check_all)
selrecord(td, &kring->si);
if (na->separate_locks)
- na->nm_lock(adapter, NETMAP_RX_UNLOCK, i);
+ na->nm_lock(ifp, NETMAP_RX_UNLOCK, i);
}
}
- if (check_all && revents == 0) {
- i = na->num_queues + 1; /* the global queue */
+ if (check_all && revents == 0) { /* signal on the global queue */
if (want_tx)
- selrecord(td, &na->tx_rings[i].si);
+ selrecord(td, &na->tx_si);
if (want_rx)
- selrecord(td, &na->rx_rings[i].si);
+ selrecord(td, &na->rx_si);
}
if (core_lock == LOCKED_CL)
- na->nm_lock(adapter, NETMAP_CORE_UNLOCK, 0);
+ na->nm_lock(ifp, NETMAP_CORE_UNLOCK, 0);
return (revents);
}
@@ -1240,6 +1407,48 @@
/*------- driver support routines ------*/
/*
+ * default lock wrapper.
+ */
+static void
+netmap_lock_wrapper(struct ifnet *dev, int what, u_int queueid)
+{
+ struct netmap_adapter *na = NA(dev);
+
+ switch (what) {
+#ifdef linux /* some system do not need lock on register */
+ case NETMAP_REG_LOCK:
+ case NETMAP_REG_UNLOCK:
+ break;
+#endif /* linux */
+
+ case NETMAP_CORE_LOCK:
+ mtx_lock(&na->core_lock);
+ break;
+
+ case NETMAP_CORE_UNLOCK:
+ mtx_unlock(&na->core_lock);
+ break;
+
+ case NETMAP_TX_LOCK:
+ mtx_lock(&na->tx_rings[queueid].q_lock);
+ break;
+
+ case NETMAP_TX_UNLOCK:
+ mtx_unlock(&na->tx_rings[queueid].q_lock);
+ break;
+
+ case NETMAP_RX_LOCK:
+ mtx_lock(&na->rx_rings[queueid].q_lock);
+ break;
+
+ case NETMAP_RX_UNLOCK:
+ mtx_unlock(&na->rx_rings[queueid].q_lock);
+ break;
+ }
+}
+
+
+/*
* Initialize a ``netmap_adapter`` object created by driver on attach.
* We allocate a block of memory with room for a struct netmap_adapter
* plus two sets of N+2 struct netmap_kring (where N is the number
@@ -1248,12 +1457,13 @@
* kring N is for the host stack queue
* kring N+1 is only used for the selinfo for all queues.
* Return 0 on success, ENOMEM otherwise.
+ *
+ * na->num_tx_queues can be set for cards with different tx/rx setups
*/
int
netmap_attach(struct netmap_adapter *na, int num_queues)
{
- int n = num_queues + 2;
- int size = sizeof(*na) + 2 * n * sizeof(struct netmap_kring);
+ int i, n, size;
void *buf;
struct ifnet *ifp = na->ifp;
@@ -1261,17 +1471,42 @@
D("ifp not set, giving up");
return EINVAL;
}
+ /* clear other fields ? */
na->refcount = 0;
- na->num_queues = num_queues;
+ if (na->num_tx_queues == 0)
+ na->num_tx_queues = num_queues;
+ na->num_rx_queues = num_queues;
+ /* on each direction we have N+1 resources
+ * 0..n-1 are the hardware rings
+ * n is the ring attached to the stack.
+ */
+ n = na->num_rx_queues + na->num_tx_queues + 2;
+ size = sizeof(*na) + n * sizeof(struct netmap_kring);
buf = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
if (buf) {
WNA(ifp) = buf;
na->tx_rings = (void *)((char *)buf + sizeof(*na));
- na->rx_rings = na->tx_rings + n;
+ na->rx_rings = na->tx_rings + na->num_tx_queues + 1;
+ na->buff_size = NETMAP_BUF_SIZE;
bcopy(na, buf, sizeof(*na));
ifp->if_capabilities |= IFCAP_NETMAP;
+
+ na = buf;
+ if (na->nm_lock == NULL)
+ na->nm_lock = netmap_lock_wrapper;
+ mtx_init(&na->core_lock, "netmap core lock", NULL, MTX_DEF);
+ for (i = 0 ; i < na->num_tx_queues + 1; i++)
+ mtx_init(&na->tx_rings[i].q_lock, "netmap txq lock", NULL, MTX_DEF);
+ for (i = 0 ; i < na->num_rx_queues + 1; i++)
+ mtx_init(&na->rx_rings[i].q_lock, "netmap rxq lock", NULL, MTX_DEF);
}
+#ifdef linux
+ D("netdev_ops %p", ifp->netdev_ops);
+ /* prepare a clone of the netdev ops */
+ na->nm_ndo = *ifp->netdev_ops;
+ na->nm_ndo.ndo_start_xmit = netmap_start_linux;
+#endif
D("%s for %s", buf ? "ok" : "failed", ifp->if_xname);
return (buf ? 0 : ENOMEM);
@@ -1291,10 +1526,16 @@
if (!na)
return;
- for (i = 0; i < na->num_queues + 2; i++) {
+ for (i = 0; i < na->num_tx_queues + 1; i++) {
knlist_destroy(&na->tx_rings[i].si.si_note);
+ mtx_destroy(&na->tx_rings[i].q_lock);
+ }
+ for (i = 0; i < na->num_rx_queues + 1; i++) {
knlist_destroy(&na->rx_rings[i].si.si_note);
+ mtx_destroy(&na->rx_rings[i].q_lock);
}
+ knlist_destroy(&na->tx_si.si_note);
+ knlist_destroy(&na->rx_si.si_note);
bzero(na, sizeof(*na));
WNA(ifp) = NULL;
free(na, M_DEVBUF);
@@ -1310,21 +1551,21 @@
netmap_start(struct ifnet *ifp, struct mbuf *m)
{
struct netmap_adapter *na = NA(ifp);
- struct netmap_kring *kring = &na->rx_rings[na->num_queues];
- u_int i, len = m->m_pkthdr.len;
+ struct netmap_kring *kring = &na->rx_rings[na->num_rx_queues];
+ u_int i, len = MBUF_LEN(m);
int error = EBUSY, lim = kring->nkr_num_slots - 1;
struct netmap_slot *slot;
if (netmap_verbose & NM_VERB_HOST)
D("%s packet %d len %d from the stack", ifp->if_xname,
kring->nr_hwcur + kring->nr_hwavail, len);
- na->nm_lock(ifp->if_softc, NETMAP_CORE_LOCK, 0);
+ na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
if (kring->nr_hwavail >= lim) {
D("stack ring %s full\n", ifp->if_xname);
goto done; /* no space */
}
- if (len > na->buff_size) {
- D("drop packet size %d > %d", len, na->buff_size);
+ if (len > NETMAP_BUF_SIZE) {
+ D("drop packet size %d > %d", len, NETMAP_BUF_SIZE);
goto done; /* too long for us */
}
@@ -1337,11 +1578,11 @@
slot->len = len;
kring->nr_hwavail++;
if (netmap_verbose & NM_VERB_HOST)
- D("wake up host ring %s %d", na->ifp->if_xname, na->num_queues);
+ D("wake up host ring %s %d", na->ifp->if_xname, na->num_rx_queues);
selwakeuppri(&kring->si, PI_NET);
error = 0;
done:
- na->nm_lock(ifp->if_softc, NETMAP_CORE_UNLOCK, 0);
+ na->nm_lock(ifp, NETMAP_CORE_UNLOCK, 0);
/* release the mbuf in either cases of success or failure. As an
* alternative, put the mbuf in a free list and free the list
@@ -1363,21 +1604,21 @@
u_int new_cur)
{
struct netmap_kring *kring;
- struct netmap_ring *ring;
int new_hwofs, lim;
if (na == NULL)
return NULL; /* no netmap support here */
if (!(na->ifp->if_capenable & IFCAP_NETMAP))
return NULL; /* nothing to reinitialize */
- kring = tx == NR_TX ? na->tx_rings + n : na->rx_rings + n;
- ring = kring->ring;
+
+ if (tx == NR_TX) {
+ kring = na->tx_rings + n;
+ new_hwofs = kring->nr_hwcur - new_cur;
+ } else {
+ kring = na->rx_rings + n;
+ new_hwofs = kring->nr_hwcur + kring->nr_hwavail - new_cur;
+ }
lim = kring->nkr_num_slots - 1;
-
- if (tx == NR_TX)
- new_hwofs = kring->nr_hwcur - new_cur;
- else
- new_hwofs = kring->nr_hwcur + kring->nr_hwavail - new_cur;
if (new_hwofs > lim)
new_hwofs -= lim + 1;
@@ -1390,236 +1631,79 @@
tx == NR_TX ? "TX" : "RX", n);
/*
+ * Wakeup on the individual and global lock
* We do the wakeup here, but the ring is not yet reconfigured.
* However, we are under lock so there are no races.
*/
selwakeuppri(&kring->si, PI_NET);
- selwakeuppri(&kring[na->num_queues + 1 - n].si, PI_NET);
+ selwakeuppri(tx == NR_TX ? &na->tx_si : &na->rx_si, PI_NET);
return kring->ring->slot;
}
-/*------ netmap memory allocator -------*/
/*
- * Request for a chunk of memory.
- *
- * Memory objects are arranged into a list, hence we need to walk this
- * list until we find an object with the needed amount of data free.
- * This sounds like a completely inefficient implementation, but given
- * the fact that data allocation is done once, we can handle it
- * flawlessly.
- *
- * Return NULL on failure.
+ * Default functions to handle rx/tx interrupts
+ * we have 4 cases:
+ * 1 ring, single lock:
+ * lock(core); wake(i=0); unlock(core)
+ * N rings, single lock:
+ * lock(core); wake(i); wake(N+1) unlock(core)
+ * 1 ring, separate locks: (i=0)
+ * lock(i); wake(i); unlock(i)
+ * N rings, separate locks:
+ * lock(i); wake(i); unlock(i); lock(core) wake(N+1) unlock(core)
+ * work_done is non-null on the RX path.
*/
-static void *
-netmap_malloc(size_t size, __unused const char *msg)
+int
+netmap_rx_irq(struct ifnet *ifp, int q, int *work_done)
{
- struct netmap_mem_obj *mem_obj, *new_mem_obj;
- void *ret = NULL;
+ struct netmap_adapter *na;
+ struct netmap_kring *r;
+ NM_SELINFO_T *main_wq;
- NMA_LOCK();
- TAILQ_FOREACH(mem_obj, &netmap_mem_d->nm_molist, nmo_next) {
- if (mem_obj->nmo_used != 0 || mem_obj->nmo_size < size)
- continue;
-
- new_mem_obj = malloc(sizeof(struct netmap_mem_obj), M_NETMAP,
- M_WAITOK | M_ZERO);
- TAILQ_INSERT_BEFORE(mem_obj, new_mem_obj, nmo_next);
-
- new_mem_obj->nmo_used = 1;
- new_mem_obj->nmo_size = size;
- new_mem_obj->nmo_data = mem_obj->nmo_data;
- memset(new_mem_obj->nmo_data, 0, new_mem_obj->nmo_size);
-
- mem_obj->nmo_size -= size;
- mem_obj->nmo_data = (char *) mem_obj->nmo_data + size;
- if (mem_obj->nmo_size == 0) {
- TAILQ_REMOVE(&netmap_mem_d->nm_molist, mem_obj,
- nmo_next);
- free(mem_obj, M_NETMAP);
+ if (!(ifp->if_capenable & IFCAP_NETMAP))
+ return 0;
+ na = NA(ifp);
+ if (work_done) { /* RX path */
+ r = na->rx_rings + q;
+ r->nr_kflags |= NKR_PENDINTR;
+ main_wq = (na->num_rx_queues > 1) ? &na->tx_si : NULL;
+ } else { /* tx path */
+ r = na->tx_rings + q;
+ main_wq = (na->num_tx_queues > 1) ? &na->rx_si : NULL;
+ work_done = &q; /* dummy */
+ }
+ if (na->separate_locks) {
+ mtx_lock(&r->q_lock);
+ selwakeuppri(&r->si, PI_NET);
+ mtx_unlock(&r->q_lock);
+ if (main_wq) {
+ mtx_lock(&na->core_lock);
+ selwakeuppri(main_wq, PI_NET);
+ mtx_unlock(&na->core_lock);
}
-
- ret = new_mem_obj->nmo_data;
-
- break;
+ } else {
+ mtx_lock(&na->core_lock);
+ selwakeuppri(&r->si, PI_NET);
+ if (main_wq)
+ selwakeuppri(main_wq, PI_NET);
+ mtx_unlock(&na->core_lock);
}
- NMA_UNLOCK();
- ND("%s: %d bytes at %p", msg, size, ret);
-
- return (ret);
+ *work_done = 1; /* do not fire napi again */
+ return 1;
}
-/*
- * Return the memory to the allocator.
- *
- * While freeing a memory object, we try to merge adjacent chunks in
- * order to reduce memory fragmentation.
- */
-static void
-netmap_free(void *addr, const char *msg)
-{
- size_t size;
- struct netmap_mem_obj *cur, *prev, *next;
- if (addr == NULL) {
- D("NULL addr for %s", msg);
- return;
- }
+static struct cdevsw netmap_cdevsw = {
+ .d_version = D_VERSION,
+ .d_name = "netmap",
+ .d_mmap = netmap_mmap,
+ .d_ioctl = netmap_ioctl,
+ .d_poll = netmap_poll,
+};
- NMA_LOCK();
- TAILQ_FOREACH(cur, &netmap_mem_d->nm_molist, nmo_next) {
- if (cur->nmo_data == addr && cur->nmo_used)
- break;
- }
- if (cur == NULL) {
- NMA_UNLOCK();
- D("invalid addr %s %p", msg, addr);
- return;
- }
- size = cur->nmo_size;
- cur->nmo_used = 0;
-
- /* merge current chunk of memory with the previous one,
- if present. */
- prev = TAILQ_PREV(cur, netmap_mem_obj_h, nmo_next);
- if (prev && prev->nmo_used == 0) {
- TAILQ_REMOVE(&netmap_mem_d->nm_molist, cur, nmo_next);
- prev->nmo_size += cur->nmo_size;
- free(cur, M_NETMAP);
- cur = prev;
- }
-
- /* merge with the next one */
- next = TAILQ_NEXT(cur, nmo_next);
- if (next && next->nmo_used == 0) {
- TAILQ_REMOVE(&netmap_mem_d->nm_molist, next, nmo_next);
- cur->nmo_size += next->nmo_size;
- free(next, M_NETMAP);
- }
- NMA_UNLOCK();
- ND("freed %s %d bytes at %p", msg, size, addr);
-}
-
-
-/*
- * Initialize the memory allocator.
- *
- * Create the descriptor for the memory , allocate the pool of memory
- * and initialize the list of memory objects with a single chunk
- * containing the whole pre-allocated memory marked as free.
- *
- * Start with a large size, then halve as needed if we fail to
- * allocate the block. While halving, always add one extra page
- * because buffers 0 and 1 are used for special purposes.
- * Return 0 on success, errno otherwise.
- */
-static int
-netmap_memory_init(void)
-{
- struct netmap_mem_obj *mem_obj;
- void *buf = NULL;
- int i, n, sz = NETMAP_MEMORY_SIZE;
- int extra_sz = 0; // space for rings and two spare buffers
-
- for (; sz >= 1<<20; sz >>=1) {
- extra_sz = sz/200;
- extra_sz = (extra_sz + 2*PAGE_SIZE - 1) & ~(PAGE_SIZE-1);
- buf = contigmalloc(sz + extra_sz,
- M_NETMAP,
- M_WAITOK | M_ZERO,
- 0, /* low address */
- -1UL, /* high address */
- PAGE_SIZE, /* alignment */
- 0 /* boundary */
- );
- if (buf)
- break;
- }
- if (buf == NULL)
- return (ENOMEM);
- sz += extra_sz;
- netmap_mem_d = malloc(sizeof(struct netmap_mem_d), M_NETMAP,
- M_WAITOK | M_ZERO);
- mtx_init(&netmap_mem_d->nm_mtx, "netmap memory allocator lock", NULL,
- MTX_DEF);
- TAILQ_INIT(&netmap_mem_d->nm_molist);
- netmap_mem_d->nm_buffer = buf;
- netmap_mem_d->nm_totalsize = sz;
-
- /*
- * A buffer takes 2k, a slot takes 8 bytes + ring overhead,
- * so the ratio is 200:1. In other words, we can use 1/200 of
- * the memory for the rings, and the rest for the buffers,
- * and be sure we never run out.
- */
- netmap_mem_d->nm_size = sz/200;
- netmap_mem_d->nm_buf_start =
- (netmap_mem_d->nm_size + PAGE_SIZE - 1) & ~(PAGE_SIZE-1);
- netmap_mem_d->nm_buf_len = sz - netmap_mem_d->nm_buf_start;
-
- nm_buf_pool.base = netmap_mem_d->nm_buffer;
- nm_buf_pool.base += netmap_mem_d->nm_buf_start;
- netmap_buffer_base = nm_buf_pool.base;
- D("netmap_buffer_base %p (offset %d)",
- netmap_buffer_base, (int)netmap_mem_d->nm_buf_start);
- /* number of buffers, they all start as free */
-
- netmap_total_buffers = nm_buf_pool.total_buffers =
- netmap_mem_d->nm_buf_len / NETMAP_BUF_SIZE;
- nm_buf_pool.bufsize = NETMAP_BUF_SIZE;
-
- D("Have %d MB, use %dKB for rings, %d buffers at %p",
- (sz >> 20), (int)(netmap_mem_d->nm_size >> 10),
- nm_buf_pool.total_buffers, nm_buf_pool.base);
-
- /* allocate and initialize the bitmap. Entry 0 is considered
- * always busy (used as default when there are no buffers left).
- */
- n = (nm_buf_pool.total_buffers + 31) / 32;
- nm_buf_pool.bitmap = malloc(sizeof(uint32_t) * n, M_NETMAP,
- M_WAITOK | M_ZERO);
- nm_buf_pool.bitmap[0] = ~3; /* slot 0 and 1 always busy */
- for (i = 1; i < n; i++)
- nm_buf_pool.bitmap[i] = ~0;
- nm_buf_pool.free = nm_buf_pool.total_buffers - 2;
-
- mem_obj = malloc(sizeof(struct netmap_mem_obj), M_NETMAP,
- M_WAITOK | M_ZERO);
- TAILQ_INSERT_HEAD(&netmap_mem_d->nm_molist, mem_obj, nmo_next);
- mem_obj->nmo_used = 0;
- mem_obj->nmo_size = netmap_mem_d->nm_size;
- mem_obj->nmo_data = netmap_mem_d->nm_buffer;
-
- return (0);
-}
-
-
-/*
- * Finalize the memory allocator.
- *
- * Free all the memory objects contained inside the list, and deallocate
- * the pool of memory; finally free the memory allocator descriptor.
- */
-static void
-netmap_memory_fini(void)
-{
- struct netmap_mem_obj *mem_obj;
-
- while (!TAILQ_EMPTY(&netmap_mem_d->nm_molist)) {
- mem_obj = TAILQ_FIRST(&netmap_mem_d->nm_molist);
- TAILQ_REMOVE(&netmap_mem_d->nm_molist, mem_obj, nmo_next);
- if (mem_obj->nmo_used == 1) {
- printf("netmap: leaked %d bytes at %p\n",
- (int)mem_obj->nmo_size,
- mem_obj->nmo_data);
- }
- free(mem_obj, M_NETMAP);
- }
- contigfree(netmap_mem_d->nm_buffer, netmap_mem_d->nm_totalsize, M_NETMAP);
- // XXX mutex_destroy(nm_mtx);
- free(netmap_mem_d, M_NETMAP);
-}
+static struct cdev *netmap_dev; /* /dev/netmap character device. */
/*
@@ -1635,19 +1719,16 @@
{
int error;
-
error = netmap_memory_init();
if (error != 0) {
printf("netmap: unable to initialize the memory allocator.");
return (error);
}
printf("netmap: loaded module with %d Mbytes\n",
- (int)(netmap_mem_d->nm_totalsize >> 20));
-
+ (int)(nm_mem->nm_totalsize >> 20));
netmap_dev = make_dev(&netmap_cdevsw, 0, UID_ROOT, GID_WHEEL, 0660,
"netmap");
-
- return (0);
+ return (error);
}
@@ -1660,9 +1741,7 @@
netmap_fini(void)
{
destroy_dev(netmap_dev);
-
netmap_memory_fini();
-
printf("netmap: unloaded module.\n");
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/netmap/netmap_kern.h
--- a/head/sys/dev/netmap/netmap_kern.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/netmap/netmap_kern.h Fri Mar 02 17:36:33 2012 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Matteo Landi, Luigi Rizzo. All rights reserved.
+ * Copyright (C) 2011-2012 Matteo Landi, Luigi Rizzo. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,8 +24,8 @@
*/
/*
- * $FreeBSD: head/sys/dev/netmap/netmap_kern.h 230572 2012-01-26 09:55:16Z luigi $
- * $Id: netmap_kern.h 9795 2011-12-02 11:39:08Z luigi $
+ * $FreeBSD: head/sys/dev/netmap/netmap_kern.h 232238 2012-02-27 19:05:01Z luigi $
+ * $Id: netmap_kern.h 10602 2012-02-21 16:47:55Z luigi $
*
* The header contains the definitions of constants and function
* prototypes used only in kernelspace.
@@ -34,6 +34,20 @@
#ifndef _NET_NETMAP_KERN_H_
#define _NET_NETMAP_KERN_H_
+#if defined(__FreeBSD__)
+#define NM_LOCK_T struct mtx
+#define NM_SELINFO_T struct selinfo
+#define MBUF_LEN(m) ((m)->m_pkthdr.len)
+#define NM_SEND_UP(ifp, m) ((ifp)->if_input)(ifp, m)
+#elif defined (linux)
+#define NM_LOCK_T spinlock_t
+#define NM_SELINFO_T wait_queue_head_t
+#define MBUF_LEN(m) ((m)->len)
+#define NM_SEND_UP(ifp, m) netif_rx(m)
+#else
+#error unsupported platform
+#endif
+
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_NETMAP);
#endif
@@ -51,13 +65,19 @@
struct netmap_adapter;
/*
- * private, kernel view of a ring.
+ * private, kernel view of a ring. Keeps track of the status of
+ * a ring across system calls.
*
- * XXX 20110627-todo
- * The index in the NIC and netmap ring is offset by nkr_hwofs slots.
+ * nr_hwcur index of the next buffer to refill.
+ * It corresponds to ring->cur - ring->reserved
+ *
+ * nr_hwavail the number of slots "owned" by userspace.
+ * nr_hwavail =:= ring->avail + ring->reserved
+ *
+ * The indexes in the NIC and netmap rings are offset by nkr_hwofs slots.
* This is so that, on a reset, buffers owned by userspace are not
* modified by the kernel. In particular:
- * RX rings: the next empty buffer (hwcur + hwavail + hwofs) coincides
+ * RX rings: the next empty buffer (hwcur + hwavail + hwofs) coincides with
* the next empty buffer as known by the hardware (next_to_check or so).
* TX rings: hwcur + hwofs coincides with next_to_send
*/
@@ -70,12 +90,13 @@
u_int nkr_num_slots;
int nkr_hwofs; /* offset between NIC and netmap ring */
- struct netmap_adapter *na; // debugging
- struct selinfo si; /* poll/select wait queue */
+ struct netmap_adapter *na;
+ NM_SELINFO_T si; /* poll/select wait queue */
+ NM_LOCK_T q_lock; /* used if no device lock available */
} __attribute__((__aligned__(64)));
/*
- * This struct is part of and extends the 'struct adapter' (or
+ * This struct extends the 'struct adapter' (or
* equivalent) device descriptor. It contains all fields needed to
* support netmap operation.
*/
@@ -87,15 +108,16 @@
int separate_locks; /* set if the interface suports different
locks for rx, tx and core. */
- u_int num_queues; /* number of tx/rx queue pairs: this is
+ u_int num_rx_queues; /* number of tx/rx queue pairs: this is
a duplicate field needed to simplify the
signature of ``netmap_detach``. */
+ u_int num_tx_queues; // if nonzero, overrides num_queues XXX
u_int num_tx_desc; /* number of descriptor in each queue */
u_int num_rx_desc;
- u_int buff_size;
+ u_int buff_size; // XXX deprecate, use NETMAP_BUF_SIZE
- u_int flags;
+ //u_int flags; // XXX unused
/* tx_rings and rx_rings are private but allocated
* as a contiguous chunk of memory. Each array has
* N+1 entries, for the adapter queues and for the host queue.
@@ -103,11 +125,13 @@
struct netmap_kring *tx_rings; /* array of TX rings. */
struct netmap_kring *rx_rings; /* array of RX rings. */
+ NM_SELINFO_T tx_si, rx_si; /* global wait queues */
+
/* copy of if_qflush and if_transmit pointers, to intercept
* packets from the network stack when netmap is active.
* XXX probably if_qflush is not necessary.
*/
- void (*if_qflush)(struct ifnet *);
+ //void (*if_qflush)(struct ifnet *); // XXX unused
int (*if_transmit)(struct ifnet *, struct mbuf *);
/* references to the ifnet and device routines, used by
@@ -115,10 +139,15 @@
*/
struct ifnet *ifp; /* adapter is ifp->if_softc */
+ NM_LOCK_T core_lock; /* used if no device lock available */
+
int (*nm_register)(struct ifnet *, int onoff);
- void (*nm_lock)(void *, int what, u_int ringid);
- int (*nm_txsync)(void *, u_int ring, int lock);
- int (*nm_rxsync)(void *, u_int ring, int lock);
+ void (*nm_lock)(struct ifnet *, int what, u_int ringid);
+ int (*nm_txsync)(struct ifnet *, u_int ring, int lock);
+ int (*nm_rxsync)(struct ifnet *, u_int ring, int lock);
+#ifdef linux
+ struct net_device_ops nm_ndo;
+#endif /* linux */
};
/*
@@ -144,6 +173,12 @@
NETMAP_CORE_LOCK, NETMAP_CORE_UNLOCK,
NETMAP_TX_LOCK, NETMAP_TX_UNLOCK,
NETMAP_RX_LOCK, NETMAP_RX_UNLOCK,
+#ifdef __FreeBSD__
+#define NETMAP_REG_LOCK NETMAP_CORE_LOCK
+#define NETMAP_REG_UNLOCK NETMAP_CORE_UNLOCK
+#else
+ NETMAP_REG_LOCK, NETMAP_REG_UNLOCK
+#endif
};
/*
@@ -172,8 +207,10 @@
enum txrx tx, int n, u_int new_cur);
int netmap_ring_reinit(struct netmap_kring *);
+extern int netmap_buf_size;
+#define NETMAP_BUF_SIZE netmap_buf_size
extern int netmap_mitigate;
-extern int netmap_skip_txsync, netmap_skip_rxsync;
+extern int netmap_no_pendintr;
extern u_int netmap_total_buffers;
extern char *netmap_buffer_base;
extern int netmap_verbose; // XXX debugging
@@ -226,6 +263,36 @@
}
}
+/*
+ * functions to map NIC to KRING indexes (n2k) and vice versa (k2n)
+ */
+static inline int
+netmap_idx_n2k(struct netmap_kring *kr, int idx)
+{
+ int n = kr->nkr_num_slots;
+ idx += kr->nkr_hwofs;
+ if (idx < 0)
+ return idx + n;
+ else if (idx < n)
+ return idx;
+ else
+ return idx - n;
+}
+
+
+static inline int
+netmap_idx_k2n(struct netmap_kring *kr, int idx)
+{
+ int n = kr->nkr_num_slots;
+ idx -= kr->nkr_hwofs;
+ if (idx < 0)
+ return idx + n;
+ else if (idx < n)
+ return idx;
+ else
+ return idx - n;
+}
+
/*
* NMB return the virtual address of a buffer (buffer 0 on bad index)
@@ -236,11 +303,7 @@
{
uint32_t i = slot->buf_idx;
return (i >= netmap_total_buffers) ? netmap_buffer_base :
-#if NETMAP_BUF_SIZE == 2048
- netmap_buffer_base + (i << 11);
-#else
netmap_buffer_base + (i *NETMAP_BUF_SIZE);
-#endif
}
static inline void *
@@ -248,13 +311,16 @@
{
uint32_t i = slot->buf_idx;
void *ret = (i >= netmap_total_buffers) ? netmap_buffer_base :
-#if NETMAP_BUF_SIZE == 2048
- netmap_buffer_base + (i << 11);
-#else
netmap_buffer_base + (i *NETMAP_BUF_SIZE);
-#endif
*pp = vtophys(ret);
return ret;
}
+/* default functions to handle rx/tx interrupts */
+int netmap_rx_irq(struct ifnet *, int, int *);
+#define netmap_tx_irq(_n, _q) netmap_rx_irq(_n, _q, NULL)
+#ifdef __linux__
+#define bus_dmamap_sync(_a, _b, _c) // wmb() or rmb() ?
+netdev_tx_t netmap_start_linux(struct sk_buff *skb, struct net_device *dev);
+#endif
#endif /* _NET_NETMAP_KERN_H_ */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/oce/oce_hw.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/oce/oce_hw.c Fri Mar 02 17:36:33 2012 +0200
@@ -0,0 +1,595 @@
+/*-
+ * Copyright (C) 2012 Emulex
+ * 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.
+ *
+ * 3. Neither the name of the Emulex Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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.
+ *
+ * Contact Information:
+ * freebsd-drivers at emulex.com
+ *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
+ */
+
+/* $FreeBSD: head/sys/dev/oce/oce_hw.c 231879 2012-02-17 13:55:17Z luigi $ */
+
+#include "oce_if.h"
+
+static int oce_POST(POCE_SOFTC sc);
+
+/**
+ * @brief Function to post status
+ * @param sc software handle to the device
+ */
+static int
+oce_POST(POCE_SOFTC sc)
+{
+ mpu_ep_semaphore_t post_status;
+ int tmo = 60000;
+
+ /* read semaphore CSR */
+ post_status.dw0 = OCE_READ_REG32(sc, csr, MPU_EP_SEMAPHORE(sc));
+
+ /* if host is ready then wait for fw ready else send POST */
+ if (post_status.bits.stage <= POST_STAGE_AWAITING_HOST_RDY) {
+ post_status.bits.stage = POST_STAGE_CHIP_RESET;
+ OCE_WRITE_REG32(sc, csr, MPU_EP_SEMAPHORE(sc), post_status.dw0);
+ }
+
+ /* wait for FW ready */
+ for (;;) {
+ if (--tmo == 0)
+ break;
+
+ DELAY(1000);
+
+ post_status.dw0 = OCE_READ_REG32(sc, csr, MPU_EP_SEMAPHORE(sc));
+ if (post_status.bits.error) {
+ device_printf(sc->dev,
+ "POST failed: %x\n", post_status.dw0);
+ return ENXIO;
+ }
+ if (post_status.bits.stage == POST_STAGE_ARMFW_READY)
+ return 0;
+ }
+
+ device_printf(sc->dev, "POST timed out: %x\n", post_status.dw0);
+
+ return ENXIO;
+}
+
+/**
+ * @brief Function for hardware initialization
+ * @param sc software handle to the device
+ */
+int
+oce_hw_init(POCE_SOFTC sc)
+{
+ int rc = 0;
+
+ rc = oce_POST(sc);
+ if (rc)
+ return rc;
+
+ /* create the bootstrap mailbox */
+ rc = oce_dma_alloc(sc, sizeof(struct oce_bmbx), &sc->bsmbx, 0);
+ if (rc) {
+ device_printf(sc->dev, "Mailbox alloc failed\n");
+ return rc;
+ }
+
+ rc = oce_reset_fun(sc);
+ if (rc)
+ goto error;
+
+
+ rc = oce_mbox_init(sc);
+ if (rc)
+ goto error;
+
+
+ rc = oce_get_fw_version(sc);
+ if (rc)
+ goto error;
+
+
+ rc = oce_get_fw_config(sc);
+ if (rc)
+ goto error;
+
+
+ sc->macaddr.size_of_struct = 6;
+ rc = oce_read_mac_addr(sc, 0, 1, MAC_ADDRESS_TYPE_NETWORK,
+ &sc->macaddr);
+ if (rc)
+ goto error;
+
+ if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE3)) {
+ rc = oce_mbox_check_native_mode(sc);
+ if (rc)
+ goto error;
+ } else
+ sc->be3_native = 0;
+
+ return rc;
+
+error:
+ oce_dma_free(sc, &sc->bsmbx);
+ device_printf(sc->dev, "Hardware initialisation failed\n");
+ return rc;
+}
+
+
+
+/**
+ * @brief Releases the obtained pci resources
+ * @param sc software handle to the device
+ */
+void
+oce_hw_pci_free(POCE_SOFTC sc)
+{
+ int pci_cfg_barnum = 0;
+
+ if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE2))
+ pci_cfg_barnum = OCE_DEV_BE2_CFG_BAR;
+ else
+ pci_cfg_barnum = OCE_DEV_CFG_BAR;
+
+ if (sc->devcfg_res != NULL) {
+ bus_release_resource(sc->dev,
+ SYS_RES_MEMORY,
+ PCIR_BAR(pci_cfg_barnum), sc->devcfg_res);
+ sc->devcfg_res = (struct resource *)NULL;
+ sc->devcfg_btag = (bus_space_tag_t) 0;
+ sc->devcfg_bhandle = (bus_space_handle_t)0;
+ sc->devcfg_vhandle = (void *)NULL;
+ }
+
+ if (sc->csr_res != NULL) {
+ bus_release_resource(sc->dev,
+ SYS_RES_MEMORY,
+ PCIR_BAR(OCE_PCI_CSR_BAR), sc->csr_res);
+ sc->csr_res = (struct resource *)NULL;
+ sc->csr_btag = (bus_space_tag_t)0;
+ sc->csr_bhandle = (bus_space_handle_t)0;
+ sc->csr_vhandle = (void *)NULL;
+ }
+
+ if (sc->db_res != NULL) {
+ bus_release_resource(sc->dev,
+ SYS_RES_MEMORY,
+ PCIR_BAR(OCE_PCI_DB_BAR), sc->db_res);
+ sc->db_res = (struct resource *)NULL;
+ sc->db_btag = (bus_space_tag_t)0;
+ sc->db_bhandle = (bus_space_handle_t)0;
+ sc->db_vhandle = (void *)NULL;
+ }
+}
+
+
+
+
+/**
+ * @brief Function to get the PCI capabilities
+ * @param sc software handle to the device
+ */
+static
+void oce_get_pci_capabilities(POCE_SOFTC sc)
+{
+ uint32_t val;
+
+ if (pci_find_extcap(sc->dev, PCIY_PCIX, &val) == 0) {
+ if (val != 0)
+ sc->flags |= OCE_FLAGS_PCIX;
+ }
+
+ if (pci_find_extcap(sc->dev, PCIY_EXPRESS, &val) == 0) {
+ if (val != 0) {
+ uint16_t link_status =
+ pci_read_config(sc->dev, val + 0x12, 2);
+
+ sc->flags |= OCE_FLAGS_PCIE;
+ sc->pcie_link_speed = link_status & 0xf;
+ sc->pcie_link_width = (link_status >> 4) & 0x3f;
+ }
+ }
+
+ if (pci_find_extcap(sc->dev, PCIY_MSI, &val) == 0) {
+ if (val != 0)
+ sc->flags |= OCE_FLAGS_MSI_CAPABLE;
+ }
+
+ if (pci_find_extcap(sc->dev, PCIY_MSIX, &val) == 0) {
+ if (val != 0) {
+ val = pci_msix_count(sc->dev);
+ sc->flags |= OCE_FLAGS_MSIX_CAPABLE;
+ }
+ }
+}
+
+/**
+ * @brief Allocate PCI resources.
+ *
+ * @param sc software handle to the device
+ * @returns 0 if successful, or error
+ */
+int
+oce_hw_pci_alloc(POCE_SOFTC sc)
+{
+ int rr, pci_cfg_barnum = 0;
+ pci_sli_intf_t intf;
+
+ pci_enable_busmaster(sc->dev);
+
+ oce_get_pci_capabilities(sc);
+
+ sc->fn = pci_get_function(sc->dev);
+
+ /* setup the device config region */
+ if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE2))
+ pci_cfg_barnum = OCE_DEV_BE2_CFG_BAR;
+ else
+ pci_cfg_barnum = OCE_DEV_CFG_BAR;
+
+ rr = PCIR_BAR(pci_cfg_barnum);
+
+ if (IS_BE(sc))
+ sc->devcfg_res = bus_alloc_resource_any(sc->dev,
+ SYS_RES_MEMORY, &rr,
+ RF_ACTIVE|RF_SHAREABLE);
+ else
+ sc->devcfg_res = bus_alloc_resource(sc->dev,
+ SYS_RES_MEMORY, &rr,
+ 0ul, ~0ul, 32768,
+ RF_ACTIVE|RF_SHAREABLE);
+
+ if (!sc->devcfg_res)
+ goto error;
+
+ sc->devcfg_btag = rman_get_bustag(sc->devcfg_res);
+ sc->devcfg_bhandle = rman_get_bushandle(sc->devcfg_res);
+ sc->devcfg_vhandle = rman_get_virtual(sc->devcfg_res);
+
+ /* Read the SLI_INTF register and determine whether we
+ * can use this port and its features
+ */
+ intf.dw0 = pci_read_config((sc)->dev,OCE_INTF_REG_OFFSET,4);
+
+ if (intf.bits.sli_valid != OCE_INTF_VALID_SIG)
+ goto error;
+
+ if (intf.bits.sli_rev != OCE_INTF_SLI_REV4) {
+ device_printf(sc->dev, "Adapter doesnt support SLI4\n");
+ goto error;
+ }
+
+ if (intf.bits.sli_if_type == OCE_INTF_IF_TYPE_1)
+ sc->flags |= OCE_FLAGS_MBOX_ENDIAN_RQD;
+
+ if (intf.bits.sli_hint1 == OCE_INTF_FUNC_RESET_REQD)
+ sc->flags |= OCE_FLAGS_FUNCRESET_RQD;
+
+ if (intf.bits.sli_func_type == OCE_INTF_VIRT_FUNC)
+ sc->flags |= OCE_FLAGS_VIRTUAL_PORT;
+
+ /* Lancer has one BAR (CFG) but BE3 has three (CFG, CSR, DB) */
+ if (IS_BE(sc)) {
+ /* set up CSR region */
+ rr = PCIR_BAR(OCE_PCI_CSR_BAR);
+ sc->csr_res = bus_alloc_resource_any(sc->dev,
+ SYS_RES_MEMORY, &rr, RF_ACTIVE|RF_SHAREABLE);
+ if (!sc->csr_res)
+ goto error;
+ sc->csr_btag = rman_get_bustag(sc->csr_res);
+ sc->csr_bhandle = rman_get_bushandle(sc->csr_res);
+ sc->csr_vhandle = rman_get_virtual(sc->csr_res);
+
+ /* set up DB doorbell region */
+ rr = PCIR_BAR(OCE_PCI_DB_BAR);
+ sc->db_res = bus_alloc_resource_any(sc->dev,
+ SYS_RES_MEMORY, &rr, RF_ACTIVE|RF_SHAREABLE);
+ if (!sc->db_res)
+ goto error;
+ sc->db_btag = rman_get_bustag(sc->db_res);
+ sc->db_bhandle = rman_get_bushandle(sc->db_res);
+ sc->db_vhandle = rman_get_virtual(sc->db_res);
+ }
+
+ return 0;
+
+error:
+ oce_hw_pci_free(sc);
+ return ENXIO;
+}
+
+
+/**
+ * @brief Function for device shutdown
+ * @param sc software handle to the device
+ * @returns 0 on success, error otherwise
+ */
+void
+oce_hw_shutdown(POCE_SOFTC sc)
+{
+
+ oce_stats_free(sc);
+ /* disable hardware interrupts */
+ oce_hw_intr_disable(sc);
+#if defined(INET6) || defined(INET)
+ /* Free LRO resources */
+ oce_free_lro(sc);
+#endif
+ /* Release queue*/
+ oce_queue_release_all(sc);
+ /*Delete Network Interface*/
+ oce_delete_nw_interface(sc);
+ /* After fw clean we dont send any cmds to fw.*/
+ oce_fw_clean(sc);
+ /* release intr resources */
+ oce_intr_free(sc);
+ /* release PCI resources */
+ oce_hw_pci_free(sc);
+ /* free mbox specific resources */
+ LOCK_DESTROY(&sc->bmbx_lock);
+ LOCK_DESTROY(&sc->dev_lock);
+
+ oce_dma_free(sc, &sc->bsmbx);
+}
+
+
+/**
+ * @brief Function for creating nw interface.
+ * @param sc software handle to the device
+ * @returns 0 on success, error otherwise
+ */
+int
+oce_create_nw_interface(POCE_SOFTC sc)
+{
+ int rc;
+ uint32_t capab_flags;
+ uint32_t capab_en_flags;
+
+ /* interface capabilities to give device when creating interface */
+ capab_flags = OCE_CAPAB_FLAGS;
+
+ /* capabilities to enable by default (others set dynamically) */
+ capab_en_flags = OCE_CAPAB_ENABLE;
+
+ if (IS_XE201(sc)) {
+ /* LANCER A0 workaround */
+ capab_en_flags &= ~MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR;
+ capab_flags &= ~MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR;
+ }
+
+ /* enable capabilities controlled via driver startup parameters */
+ if (sc->rss_enable)
+ capab_en_flags |= MBX_RX_IFACE_FLAGS_RSS;
+ else {
+ capab_en_flags &= ~MBX_RX_IFACE_FLAGS_RSS;
+ capab_flags &= ~MBX_RX_IFACE_FLAGS_RSS;
+ }
+
+ rc = oce_if_create(sc,
+ capab_flags,
+ capab_en_flags,
+ 0, &sc->macaddr.mac_addr[0], &sc->if_id);
+ if (rc)
+ return rc;
+
+ atomic_inc_32(&sc->nifs);
+
+ sc->if_cap_flags = capab_en_flags;
+
+ /* Enable VLAN Promisc on HW */
+ rc = oce_config_vlan(sc, (uint8_t) sc->if_id, NULL, 0, 1, 1);
+ if (rc)
+ goto error;
+
+ /* set default flow control */
+ rc = oce_set_flow_control(sc, sc->flow_control);
+ if (rc)
+ goto error;
+
+ rc = oce_rxf_set_promiscuous(sc, sc->promisc);
+ if (rc)
+ goto error;
+
+ return rc;
+
+error:
+ oce_delete_nw_interface(sc);
+ return rc;
+
+}
+
+/**
+ * @brief Function to delete a nw interface.
+ * @param sc software handle to the device
+ */
+void
+oce_delete_nw_interface(POCE_SOFTC sc)
+{
+ /* currently only single interface is implmeneted */
+ if (sc->nifs > 0) {
+ oce_if_del(sc, sc->if_id);
+ atomic_dec_32(&sc->nifs);
+ }
+}
+
+/**
+ * @brief Soft reset.
+ * @param sc software handle to the device
+ * @returns 0 on success, error otherwise
+ */
+int
+oce_pci_soft_reset(POCE_SOFTC sc)
+{
+ int rc;
+ mpu_ep_control_t ctrl;
+
+ ctrl.dw0 = OCE_READ_REG32(sc, csr, MPU_EP_CONTROL);
+ ctrl.bits.cpu_reset = 1;
+ OCE_WRITE_REG32(sc, csr, MPU_EP_CONTROL, ctrl.dw0);
+ DELAY(50);
+ rc=oce_POST(sc);
+
+ return rc;
+}
+
+/**
+ * @brief Function for hardware start
+ * @param sc software handle to the device
+ * @returns 0 on success, error otherwise
+ */
+int
+oce_hw_start(POCE_SOFTC sc)
+{
+ struct link_status link = { 0 };
+ int rc = 0;
+
+ rc = oce_get_link_status(sc, &link);
+ if (rc)
+ return 1;
+
+ if (link.logical_link_status == NTWK_LOGICAL_LINK_UP) {
+ sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->link_status = NTWK_LOGICAL_LINK_UP;
+ if_link_state_change(sc->ifp, LINK_STATE_UP);
+ } else {
+ sc->ifp->if_drv_flags &=
+ ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->link_status = NTWK_LOGICAL_LINK_DOWN;
+ if_link_state_change(sc->ifp, LINK_STATE_DOWN);
+ }
+
+ if (link.mac_speed > 0 && link.mac_speed < 5)
+ sc->link_speed = link.mac_speed;
+ else
+ sc->link_speed = 0;
+
+ sc->qos_link_speed = (uint32_t )link.qos_link_speed * 10;
+
+ rc = oce_start_mq(sc->mq);
+
+ /* we need to get MCC aync events. So enable intrs and arm
+ first EQ, Other EQs will be armed after interface is UP
+ */
+ oce_hw_intr_enable(sc);
+ oce_arm_eq(sc, sc->eq[0]->eq_id, 0, TRUE, FALSE);
+
+ /* Send first mcc cmd and after that we get gracious
+ MCC notifications from FW
+ */
+ oce_first_mcc_cmd(sc);
+
+ return rc;
+}
+
+
+/**
+ * @brief Function for hardware enable interupts.
+ * @param sc software handle to the device
+ */
+void
+oce_hw_intr_enable(POCE_SOFTC sc)
+{
+ uint32_t reg;
+
+ reg = OCE_READ_REG32(sc, devcfg, PCICFG_INTR_CTRL);
+ reg |= HOSTINTR_MASK;
+ OCE_WRITE_REG32(sc, devcfg, PCICFG_INTR_CTRL, reg);
+
+}
+
+
+/**
+ * @brief Function for hardware disable interupts
+ * @param sc software handle to the device
+ */
+void
+oce_hw_intr_disable(POCE_SOFTC sc)
+{
+ uint32_t reg;
+
+ reg = OCE_READ_REG32(sc, devcfg, PCICFG_INTR_CTRL);
+ reg &= ~HOSTINTR_MASK;
+ OCE_WRITE_REG32(sc, devcfg, PCICFG_INTR_CTRL, reg);
+}
+
+
+
+/**
+ * @brief Function for hardware update multicast filter
+ * @param sc software handle to the device
+ */
+int
+oce_hw_update_multicast(POCE_SOFTC sc)
+{
+ struct ifnet *ifp = sc->ifp;
+ struct ifmultiaddr *ifma;
+ struct mbx_set_common_iface_multicast *req = NULL;
+ OCE_DMA_MEM dma;
+ int rc = 0;
+
+ /* Allocate DMA mem*/
+ if (oce_dma_alloc(sc, sizeof(struct mbx_set_common_iface_multicast),
+ &dma, 0))
+ return ENOMEM;
+
+ req = OCE_DMAPTR(&dma, struct mbx_set_common_iface_multicast);
+ bzero(req, sizeof(struct mbx_set_common_iface_multicast));
+
+#if __FreeBSD_version > 800000
+ if_maddr_rlock(ifp);
+#endif
+ TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ if (ifma->ifma_addr->sa_family != AF_LINK)
+ continue;
+
+ if (req->params.req.num_mac == OCE_MAX_MC_FILTER_SIZE) {
+ /*More multicast addresses than our hardware table
+ So Enable multicast promiscus in our hardware to
+ accept all multicat packets
+ */
+ req->params.req.promiscuous = 1;
+ break;
+ }
+ bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
+ &req->params.req.mac[req->params.req.num_mac],
+ ETH_ADDR_LEN);
+ req->params.req.num_mac = req->params.req.num_mac + 1;
+ }
+#if __FreeBSD_version > 800000
+ if_maddr_runlock(ifp);
+#endif
+ req->params.req.if_id = sc->if_id;
+ rc = oce_update_multicast(sc, &dma);
+ oce_dma_free(sc, &dma);
+ return rc;
+}
+
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/oce/oce_hw.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/oce/oce_hw.h Fri Mar 02 17:36:33 2012 +0200
@@ -0,0 +1,3464 @@
+/*-
+ * Copyright (C) 2012 Emulex
+ * 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.
+ *
+ * 3. Neither the name of the Emulex Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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.
+ *
+ * Contact Information:
+ * freebsd-drivers at emulex.com
+ *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
+ */
+
+/* $FreeBSD: head/sys/dev/oce/oce_hw.h 231879 2012-02-17 13:55:17Z luigi $ */
+
+#include <sys/types.h>
+
+#undef _BIG_ENDIAN /* TODO */
+#pragma pack(1)
+
+#define OC_CNA_GEN2 0x2
+#define OC_CNA_GEN3 0x3
+#define DEVID_TIGERSHARK 0x700
+#define DEVID_TOMCAT 0x710
+
+/* PCI CSR offsets */
+#define PCICFG_F1_CSR 0x0 /* F1 for NIC */
+#define PCICFG_SEMAPHORE 0xbc
+#define PCICFG_SOFT_RESET 0x5c
+#define PCICFG_UE_STATUS_HI_MASK 0xac
+#define PCICFG_UE_STATUS_LO_MASK 0xa8
+#define PCICFG_ONLINE0 0xb0
+#define PCICFG_ONLINE1 0xb4
+#define INTR_EN 0x20000000
+#define IMAGE_TRANSFER_SIZE (32 * 1024) /* 32K at a time */
+
+/* CSR register offsets */
+#define MPU_EP_CONTROL 0
+#define MPU_EP_SEMAPHORE_BE3 0xac
+#define MPU_EP_SEMAPHORE_XE201 0x400
+#define MPU_EP_SEMAPHORE(sc) \
+ ((IS_BE(sc)) ? MPU_EP_SEMAPHORE_BE3 : MPU_EP_SEMAPHORE_XE201)
+#define PCICFG_INTR_CTRL 0xfc
+#define HOSTINTR_MASK (1 << 29)
+#define HOSTINTR_PFUNC_SHIFT 26
+#define HOSTINTR_PFUNC_MASK 7
+
+/* POST status reg struct */
+#define POST_STAGE_POWER_ON_RESET 0x00
+#define POST_STAGE_AWAITING_HOST_RDY 0x01
+#define POST_STAGE_HOST_RDY 0x02
+#define POST_STAGE_CHIP_RESET 0x03
+#define POST_STAGE_ARMFW_READY 0xc000
+#define POST_STAGE_ARMFW_UE 0xf000
+
+/* DOORBELL registers */
+#define PD_RXULP_DB 0x0100
+#define PD_TXULP_DB 0x0060
+#define DB_RQ_ID_MASK 0x3FF
+
+#define PD_CQ_DB 0x0120
+#define PD_EQ_DB PD_CQ_DB
+#define PD_MPU_MBOX_DB 0x0160
+#define PD_MQ_DB 0x0140
+
+/* EQE completion types */
+#define EQ_MINOR_CODE_COMPLETION 0x00
+#define EQ_MINOR_CODE_OTHER 0x01
+#define EQ_MAJOR_CODE_COMPLETION 0x00
+
+/* Link Status field values */
+#define PHY_LINK_FAULT_NONE 0x0
+#define PHY_LINK_FAULT_LOCAL 0x01
+#define PHY_LINK_FAULT_REMOTE 0x02
+
+#define PHY_LINK_SPEED_ZERO 0x0 /* No link */
+#define PHY_LINK_SPEED_10MBPS 0x1 /* (10 Mbps) */
+#define PHY_LINK_SPEED_100MBPS 0x2 /* (100 Mbps) */
+#define PHY_LINK_SPEED_1GBPS 0x3 /* (1 Gbps) */
+#define PHY_LINK_SPEED_10GBPS 0x4 /* (10 Gbps) */
+
+#define PHY_LINK_DUPLEX_NONE 0x0
+#define PHY_LINK_DUPLEX_HALF 0x1
+#define PHY_LINK_DUPLEX_FULL 0x2
+
+#define NTWK_PORT_A 0x0 /* (Port A) */
+#define NTWK_PORT_B 0x1 /* (Port B) */
+
+#define PHY_LINK_SPEED_ZERO 0x0 /* (No link.) */
+#define PHY_LINK_SPEED_10MBPS 0x1 /* (10 Mbps) */
+#define PHY_LINK_SPEED_100MBPS 0x2 /* (100 Mbps) */
+#define PHY_LINK_SPEED_1GBPS 0x3 /* (1 Gbps) */
+#define PHY_LINK_SPEED_10GBPS 0x4 /* (10 Gbps) */
+
+/* Hardware Address types */
+#define MAC_ADDRESS_TYPE_STORAGE 0x0 /* (Storage MAC Address) */
+#define MAC_ADDRESS_TYPE_NETWORK 0x1 /* (Network MAC Address) */
+#define MAC_ADDRESS_TYPE_PD 0x2 /* (Protection Domain MAC Addr) */
+#define MAC_ADDRESS_TYPE_MANAGEMENT 0x3 /* (Management MAC Address) */
+#define MAC_ADDRESS_TYPE_FCOE 0x4 /* (FCoE MAC Address) */
+
+/* CREATE_IFACE capability and cap_en flags */
+#define MBX_RX_IFACE_FLAGS_RSS 0x4
+#define MBX_RX_IFACE_FLAGS_PROMISCUOUS 0x8
+#define MBX_RX_IFACE_FLAGS_BROADCAST 0x10
+#define MBX_RX_IFACE_FLAGS_UNTAGGED 0x20
+#define MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS 0x80
+#define MBX_RX_IFACE_FLAGS_VLAN 0x100
+#define MBX_RX_IFACE_FLAGS_MCAST_PROMISCUOUS 0x200
+#define MBX_RX_IFACE_FLAGS_PASS_L2_ERR 0x400
+#define MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR 0x800
+#define MBX_RX_IFACE_FLAGS_MULTICAST 0x1000
+#define MBX_RX_IFACE_RX_FILTER_IF_MULTICAST_HASH 0x2000
+#define MBX_RX_IFACE_FLAGS_HDS 0x4000
+#define MBX_RX_IFACE_FLAGS_DIRECTED 0x8000
+#define MBX_RX_IFACE_FLAGS_VMQ 0x10000
+#define MBX_RX_IFACE_FLAGS_NETQ 0x20000
+#define MBX_RX_IFACE_FLAGS_QGROUPS 0x40000
+#define MBX_RX_IFACE_FLAGS_LSO 0x80000
+#define MBX_RX_IFACE_FLAGS_LRO 0x100000
+
+#define MQ_RING_CONTEXT_SIZE_16 0x5 /* (16 entries) */
+#define MQ_RING_CONTEXT_SIZE_32 0x6 /* (32 entries) */
+#define MQ_RING_CONTEXT_SIZE_64 0x7 /* (64 entries) */
+#define MQ_RING_CONTEXT_SIZE_128 0x8 /* (128 entries) */
+
+#define MBX_DB_READY_BIT 0x1
+#define MBX_DB_HI_BIT 0x2
+#define ASYNC_EVENT_CODE_LINK_STATE 0x1
+#define ASYNC_EVENT_LINK_UP 0x1
+#define ASYNC_EVENT_LINK_DOWN 0x0
+#define ASYNC_EVENT_GRP5 0x5
+#define ASYNC_EVENT_PVID_STATE 0x3
+#define VLAN_VID_MASK 0x0FFF
+
+/* port link_status */
+#define ASYNC_EVENT_LOGICAL 0x02
+
+/* Logical Link Status */
+#define NTWK_LOGICAL_LINK_DOWN 0
+#define NTWK_LOGICAL_LINK_UP 1
+
+/* Rx filter bits */
+#define NTWK_RX_FILTER_IP_CKSUM 0x1
+#define NTWK_RX_FILTER_TCP_CKSUM 0x2
+#define NTWK_RX_FILTER_UDP_CKSUM 0x4
+#define NTWK_RX_FILTER_STRIP_CRC 0x8
+
+/* max SGE per mbx */
+#define MAX_MBX_SGE 19
+
+/* Max multicast filter size*/
+#define OCE_MAX_MC_FILTER_SIZE 64
+
+/* PCI SLI (Service Level Interface) capabilities register */
+#define OCE_INTF_REG_OFFSET 0x58
+#define OCE_INTF_VALID_SIG 6 /* register's signature */
+#define OCE_INTF_FUNC_RESET_REQD 1
+#define OCE_INTF_HINT1_NOHINT 0
+#define OCE_INTF_HINT1_SEMAINIT 1
+#define OCE_INTF_HINT1_STATCTRL 2
+#define OCE_INTF_IF_TYPE_0 0
+#define OCE_INTF_IF_TYPE_1 1
+#define OCE_INTF_IF_TYPE_2 2
+#define OCE_INTF_IF_TYPE_3 3
+#define OCE_INTF_SLI_REV3 3 /* not supported by driver */
+#define OCE_INTF_SLI_REV4 4 /* driver supports SLI-4 */
+#define OCE_INTF_PHYS_FUNC 0
+#define OCE_INTF_VIRT_FUNC 1
+#define OCE_INTF_FAMILY_BE2 0 /* not supported by driver */
+#define OCE_INTF_FAMILY_BE3 1 /* driver supports BE3 */
+#define OCE_INTF_FAMILY_A0_CHIP 0xA /* Lancer A0 chip (supported) */
+#define OCE_INTF_FAMILY_B0_CHIP 0xB /* Lancer B0 chip (future) */
+
+#define NIC_WQE_SIZE 16
+#define NIC_UNICAST 0x00
+#define NIC_MULTICAST 0x01
+#define NIC_BROADCAST 0x02
+
+#define NIC_HDS_NO_SPLIT 0x00
+#define NIC_HDS_SPLIT_L3PL 0x01
+#define NIC_HDS_SPLIT_L4PL 0x02
+
+#define NIC_WQ_TYPE_FORWARDING 0x01
+#define NIC_WQ_TYPE_STANDARD 0x02
+#define NIC_WQ_TYPE_LOW_LATENCY 0x04
+
+#define OCE_RESET_STATS 1
+#define OCE_RETAIN_STATS 0
+#define OCE_TXP_SW_SZ 48
+
+typedef union pci_sli_intf_u {
+ uint32_t dw0;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t sli_valid:3;
+ uint32_t sli_hint2:5;
+ uint32_t sli_hint1:8;
+ uint32_t sli_if_type:4;
+ uint32_t sli_family:4;
+ uint32_t sli_rev:4;
+ uint32_t rsv0:3;
+ uint32_t sli_func_type:1;
+#else
+ uint32_t sli_func_type:1;
+ uint32_t rsv0:3;
+ uint32_t sli_rev:4;
+ uint32_t sli_family:4;
+ uint32_t sli_if_type:4;
+ uint32_t sli_hint1:8;
+ uint32_t sli_hint2:5;
+ uint32_t sli_valid:3;
+#endif
+ } bits;
+} pci_sli_intf_t;
+
+
+
+/* physical address structure to be used in MBX */
+struct phys_addr {
+ /* dw0 */
+ uint32_t lo;
+ /* dw1 */
+ uint32_t hi;
+};
+
+
+
+typedef union pcicfg_intr_ctl_u {
+ uint32_t dw0;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t winselect:2;
+ uint32_t hostintr:1;
+ uint32_t pfnum:3;
+ uint32_t vf_cev_int_line_en:1;
+ uint32_t winaddr:23;
+ uint32_t membarwinen:1;
+#else
+ uint32_t membarwinen:1;
+ uint32_t winaddr:23;
+ uint32_t vf_cev_int_line_en:1;
+ uint32_t pfnum:3;
+ uint32_t hostintr:1;
+ uint32_t winselect:2;
+#endif
+ } bits;
+} pcicfg_intr_ctl_t;
+
+
+
+
+typedef union pcicfg_semaphore_u {
+ uint32_t dw0;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t rsvd:31;
+ uint32_t lock:1;
+#else
+ uint32_t lock:1;
+ uint32_t rsvd:31;
+#endif
+ } bits;
+} pcicfg_semaphore_t;
+
+
+
+
+typedef union pcicfg_soft_reset_u {
+ uint32_t dw0;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t nec_ll_rcvdetect:8;
+ uint32_t dbg_all_reqs_62_49:14;
+ uint32_t scratchpad0:1;
+ uint32_t exception_oe:1;
+ uint32_t soft_reset:1;
+ uint32_t rsvd0:7;
+#else
+ uint32_t rsvd0:7;
+ uint32_t soft_reset:1;
+ uint32_t exception_oe:1;
+ uint32_t scratchpad0:1;
+ uint32_t dbg_all_reqs_62_49:14;
+ uint32_t nec_ll_rcvdetect:8;
+#endif
+ } bits;
+} pcicfg_soft_reset_t;
+
+
+
+
+typedef union pcicfg_online1_u {
+ uint32_t dw0;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t host8_online:1;
+ uint32_t host7_online:1;
+ uint32_t host6_online:1;
+ uint32_t host5_online:1;
+ uint32_t host4_online:1;
+ uint32_t host3_online:1;
+ uint32_t host2_online:1;
+ uint32_t ipc_online:1;
+ uint32_t arm_online:1;
+ uint32_t txp_online:1;
+ uint32_t xaui_online:1;
+ uint32_t rxpp_online:1;
+ uint32_t txpb_online:1;
+ uint32_t rr_online:1;
+ uint32_t pmem_online:1;
+ uint32_t pctl1_online:1;
+ uint32_t pctl0_online:1;
+ uint32_t pcs1online_online:1;
+ uint32_t mpu_iram_online:1;
+ uint32_t pcs0online_online:1;
+ uint32_t mgmt_mac_online:1;
+ uint32_t lpcmemhost_online:1;
+#else
+ uint32_t lpcmemhost_online:1;
+ uint32_t mgmt_mac_online:1;
+ uint32_t pcs0online_online:1;
+ uint32_t mpu_iram_online:1;
+ uint32_t pcs1online_online:1;
+ uint32_t pctl0_online:1;
+ uint32_t pctl1_online:1;
+ uint32_t pmem_online:1;
+ uint32_t rr_online:1;
+ uint32_t txpb_online:1;
+ uint32_t rxpp_online:1;
+ uint32_t xaui_online:1;
+ uint32_t txp_online:1;
+ uint32_t arm_online:1;
+ uint32_t ipc_online:1;
+ uint32_t host2_online:1;
+ uint32_t host3_online:1;
+ uint32_t host4_online:1;
+ uint32_t host5_online:1;
+ uint32_t host6_online:1;
+ uint32_t host7_online:1;
+ uint32_t host8_online:1;
+#endif
+ } bits;
+} pcicfg_online1_t;
+
+
+
+typedef union mpu_ep_semaphore_u {
+ uint32_t dw0;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t error:1;
+ uint32_t backup_fw:1;
+ uint32_t iscsi_no_ip:1;
+ uint32_t iscsi_ip_conflict:1;
+ uint32_t option_rom_installed:1;
+ uint32_t iscsi_drv_loaded:1;
+ uint32_t rsvd0:10;
+ uint32_t stage:16;
+#else
+ uint32_t stage:16;
+ uint32_t rsvd0:10;
+ uint32_t iscsi_drv_loaded:1;
+ uint32_t option_rom_installed:1;
+ uint32_t iscsi_ip_conflict:1;
+ uint32_t iscsi_no_ip:1;
+ uint32_t backup_fw:1;
+ uint32_t error:1;
+#endif
+ } bits;
+} mpu_ep_semaphore_t;
+
+
+
+
+typedef union mpu_ep_control_u {
+ uint32_t dw0;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t cpu_reset:1;
+ uint32_t rsvd1:15;
+ uint32_t ep_ram_init_status:1;
+ uint32_t rsvd0:12;
+ uint32_t m2_rxpbuf:1;
+ uint32_t m1_rxpbuf:1;
+ uint32_t m0_rxpbuf:1;
+#else
+ uint32_t m0_rxpbuf:1;
+ uint32_t m1_rxpbuf:1;
+ uint32_t m2_rxpbuf:1;
+ uint32_t rsvd0:12;
+ uint32_t ep_ram_init_status:1;
+ uint32_t rsvd1:15;
+ uint32_t cpu_reset:1;
+#endif
+ } bits;
+} mpu_ep_control_t;
+
+
+
+
+/* RX doorbell */
+typedef union pd_rxulp_db_u {
+ uint32_t dw0;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t num_posted:8;
+ uint32_t invalidate:1;
+ uint32_t rsvd1:13;
+ uint32_t qid:10;
+#else
+ uint32_t qid:10;
+ uint32_t rsvd1:13;
+ uint32_t invalidate:1;
+ uint32_t num_posted:8;
+#endif
+ } bits;
+} pd_rxulp_db_t;
+
+
+/* TX doorbell */
+typedef union pd_txulp_db_u {
+ uint32_t dw0;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t rsvd1:2;
+ uint32_t num_posted:14;
+ uint32_t rsvd0:6;
+ uint32_t qid:10;
+#else
+ uint32_t qid:10;
+ uint32_t rsvd0:6;
+ uint32_t num_posted:14;
+ uint32_t rsvd1:2;
+#endif
+ } bits;
+} pd_txulp_db_t;
+
+/* CQ doorbell */
+typedef union cq_db_u {
+ uint32_t dw0;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t rsvd1:2;
+ uint32_t rearm:1;
+ uint32_t num_popped:13;
+ uint32_t rsvd0:5;
+ uint32_t event:1;
+ uint32_t qid:10;
+#else
+ uint32_t qid:10;
+ uint32_t event:1;
+ uint32_t rsvd0:5;
+ uint32_t num_popped:13;
+ uint32_t rearm:1;
+ uint32_t rsvd1:2;
+#endif
+ } bits;
+} cq_db_t;
+
+/* EQ doorbell */
+typedef union eq_db_u {
+ uint32_t dw0;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t rsvd1:2;
+ uint32_t rearm:1;
+ uint32_t num_popped:13;
+ uint32_t rsvd0:5;
+ uint32_t event:1;
+ uint32_t clrint:1;
+ uint32_t qid:9;
+#else
+ uint32_t qid:9;
+ uint32_t clrint:1;
+ uint32_t event:1;
+ uint32_t rsvd0:5;
+ uint32_t num_popped:13;
+ uint32_t rearm:1;
+ uint32_t rsvd1:2;
+#endif
+ } bits;
+} eq_db_t;
+
+/* bootstrap mbox doorbell */
+typedef union pd_mpu_mbox_db_u {
+ uint32_t dw0;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t address:30;
+ uint32_t hi:1;
+ uint32_t ready:1;
+#else
+ uint32_t ready:1;
+ uint32_t hi:1;
+ uint32_t address:30;
+#endif
+ } bits;
+} pd_mpu_mbox_db_t;
+
+/* MQ ring doorbell */
+typedef union pd_mq_db_u {
+ uint32_t dw0;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t rsvd1:2;
+ uint32_t num_posted:14;
+ uint32_t rsvd0:5;
+ uint32_t mq_id:11;
+#else
+ uint32_t mq_id:11;
+ uint32_t rsvd0:5;
+ uint32_t num_posted:14;
+ uint32_t rsvd1:2;
+#endif
+ } bits;
+} pd_mq_db_t;
+
+/*
+ * Event Queue Entry
+ */
+struct oce_eqe {
+ uint32_t evnt;
+};
+
+/* MQ scatter gather entry. Array of these make an SGL */
+struct oce_mq_sge {
+ uint32_t pa_lo;
+ uint32_t pa_hi;
+ uint32_t length;
+};
+
+/*
+ * payload can contain an SGL or an embedded array of upto 59 dwords
+ */
+struct oce_mbx_payload {
+ union {
+ union {
+ struct oce_mq_sge sgl[MAX_MBX_SGE];
+ uint32_t embedded[59];
+ } u1;
+ uint32_t dw[59];
+ } u0;
+};
+
+/*
+ * MQ MBX structure
+ */
+struct oce_mbx {
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t special:8;
+ uint32_t rsvd1:16;
+ uint32_t sge_count:5;
+ uint32_t rsvd0:2;
+ uint32_t embedded:1;
+#else
+ uint32_t embedded:1;
+ uint32_t rsvd0:2;
+ uint32_t sge_count:5;
+ uint32_t rsvd1:16;
+ uint32_t special:8;
+#endif
+ } s;
+ uint32_t dw0;
+ } u0;
+
+ uint32_t payload_length;
+ uint32_t tag[2];
+ uint32_t rsvd2[1];
+ struct oce_mbx_payload payload;
+};
+
+/* completion queue entry for MQ */
+struct oce_mq_cqe {
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ /* dw0 */
+ uint32_t extended_status:16;
+ uint32_t completion_status:16;
+ /* dw1 dw2 */
+ uint32_t mq_tag[2];
+ /* dw3 */
+ uint32_t valid:1;
+ uint32_t async_event:1;
+ uint32_t hpi_buffer_cmpl:1;
+ uint32_t completed:1;
+ uint32_t consumed:1;
+ uint32_t rsvd0:3;
+ uint32_t async_type:8;
+ uint32_t event_type:8;
+ uint32_t rsvd1:8;
+#else
+ /* dw0 */
+ uint32_t completion_status:16;
+ uint32_t extended_status:16;
+ /* dw1 dw2 */
+ uint32_t mq_tag[2];
+ /* dw3 */
+ uint32_t rsvd1:8;
+ uint32_t event_type:8;
+ uint32_t async_type:8;
+ uint32_t rsvd0:3;
+ uint32_t consumed:1;
+ uint32_t completed:1;
+ uint32_t hpi_buffer_cmpl:1;
+ uint32_t async_event:1;
+ uint32_t valid:1;
+#endif
+ } s;
+ uint32_t dw[4];
+ } u0;
+};
+
+/* Mailbox Completion Status Codes */
+enum MBX_COMPLETION_STATUS {
+ MBX_CQE_STATUS_SUCCESS = 0x00,
+ MBX_CQE_STATUS_INSUFFICIENT_PRIVILEDGES = 0x01,
+ MBX_CQE_STATUS_INVALID_PARAMETER = 0x02,
+ MBX_CQE_STATUS_INSUFFICIENT_RESOURCES = 0x03,
+ MBX_CQE_STATUS_QUEUE_FLUSHING = 0x04,
+ MBX_CQE_STATUS_DMA_FAILED = 0x05
+};
+
+struct oce_async_cqe_link_state {
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ /* dw0 */
+ uint8_t speed;
+ uint8_t duplex;
+ uint8_t link_status;
+ uint8_t phy_port;
+ /* dw1 */
+ uint16_t qos_link_speed;
+ uint8_t rsvd0;
+ uint8_t fault;
+ /* dw2 */
+ uint32_t event_tag;
+ /* dw3 */
+ uint32_t valid:1;
+ uint32_t async_event:1;
+ uint32_t rsvd2:6;
+ uint32_t event_type:8;
+ uint32_t event_code:8;
+ uint32_t rsvd1:8;
+#else
+ /* dw0 */
+ uint8_t phy_port;
+ uint8_t link_status;
+ uint8_t duplex;
+ uint8_t speed;
+ /* dw1 */
+ uint8_t fault;
+ uint8_t rsvd0;
+ uint16_t qos_link_speed;
+ /* dw2 */
+ uint32_t event_tag;
+ /* dw3 */
+ uint32_t rsvd1:8;
+ uint32_t event_code:8;
+ uint32_t event_type:8;
+ uint32_t rsvd2:6;
+ uint32_t async_event:1;
+ uint32_t valid:1;
+#endif
+ } s;
+ uint32_t dw[4];
+ } u0;
+};
+
+
+/* PVID aync event */
+struct oce_async_event_grp5_pvid_state {
+ uint8_t enabled;
+ uint8_t rsvd0;
+ uint16_t tag;
+ uint32_t event_tag;
+ uint32_t rsvd1;
+ uint32_t code;
+};
+
+typedef union oce_mq_ext_ctx_u {
+ uint32_t dw[6];
+ struct {
+ #ifdef _BIG_ENDIAN
+ /* dw0 */
+ uint32_t dw4rsvd1:16;
+ uint32_t num_pages:16;
+ /* dw1 */
+ uint32_t async_evt_bitmap;
+ /* dw2 */
+ uint32_t cq_id:10;
+ uint32_t dw5rsvd2:2;
+ uint32_t ring_size:4;
+ uint32_t dw5rsvd1:16;
+ /* dw3 */
+ uint32_t valid:1;
+ uint32_t dw6rsvd1:31;
+ /* dw4 */
+ uint32_t dw7rsvd1:21;
+ uint32_t async_cq_id:10;
+ uint32_t async_cq_valid:1;
+ #else
+ /* dw0 */
+ uint32_t num_pages:16;
+ uint32_t dw4rsvd1:16;
+ /* dw1 */
+ uint32_t async_evt_bitmap;
+ /* dw2 */
+ uint32_t dw5rsvd1:16;
+ uint32_t ring_size:4;
+ uint32_t dw5rsvd2:2;
+ uint32_t cq_id:10;
+ /* dw3 */
+ uint32_t dw6rsvd1:31;
+ uint32_t valid:1;
+ /* dw4 */
+ uint32_t async_cq_valid:1;
+ uint32_t async_cq_id:10;
+ uint32_t dw7rsvd1:21;
+ #endif
+ /* dw5 */
+ uint32_t dw8rsvd1;
+ } v0;
+} oce_mq_ext_ctx_t;
+
+
+/* MQ mailbox structure */
+struct oce_bmbx {
+ struct oce_mbx mbx;
+ struct oce_mq_cqe cqe;
+};
+
+/* ---[ MBXs start here ]---------------------------------------------- */
+/* MBXs sub system codes */
+enum MBX_SUBSYSTEM_CODES {
+ MBX_SUBSYSTEM_RSVD = 0,
+ MBX_SUBSYSTEM_COMMON = 1,
+ MBX_SUBSYSTEM_COMMON_ISCSI = 2,
+ MBX_SUBSYSTEM_NIC = 3,
+ MBX_SUBSYSTEM_TOE = 4,
+ MBX_SUBSYSTEM_PXE_UNDI = 5,
+ MBX_SUBSYSTEM_ISCSI_INI = 6,
+ MBX_SUBSYSTEM_ISCSI_TGT = 7,
+ MBX_SUBSYSTEM_MILI_PTL = 8,
+ MBX_SUBSYSTEM_MILI_TMD = 9,
+ MBX_SUBSYSTEM_RDMA = 10,
+ MBX_SUBSYSTEM_LOWLEVEL = 11,
+ MBX_SUBSYSTEM_LRO = 13,
+ IOCBMBX_SUBSYSTEM_DCBX = 15,
+ IOCBMBX_SUBSYSTEM_DIAG = 16,
+ IOCBMBX_SUBSYSTEM_VENDOR = 17
+};
+
+/* common ioctl opcodes */
+enum COMMON_SUBSYSTEM_OPCODES {
+/* These opcodes are common to both networking and storage PCI functions
+ * They are used to reserve resources and configure CNA. These opcodes
+ * all use the MBX_SUBSYSTEM_COMMON subsystem code.
+ */
+ OPCODE_COMMON_QUERY_IFACE_MAC = 1,
+ OPCODE_COMMON_SET_IFACE_MAC = 2,
+ OPCODE_COMMON_SET_IFACE_MULTICAST = 3,
+ OPCODE_COMMON_CONFIG_IFACE_VLAN = 4,
+ OPCODE_COMMON_QUERY_LINK_CONFIG = 5,
+ OPCODE_COMMON_READ_FLASHROM = 6,
+ OPCODE_COMMON_WRITE_FLASHROM = 7,
+ OPCODE_COMMON_QUERY_MAX_MBX_BUFFER_SIZE = 8,
+ OPCODE_COMMON_CREATE_CQ = 12,
+ OPCODE_COMMON_CREATE_EQ = 13,
+ OPCODE_COMMON_CREATE_MQ = 21,
+ OPCODE_COMMON_GET_QOS = 27,
+ OPCODE_COMMON_SET_QOS = 28,
+ OPCODE_COMMON_READ_EPROM = 30,
+ OPCODE_COMMON_GET_CNTL_ATTRIBUTES = 32,
+ OPCODE_COMMON_NOP = 33,
+ OPCODE_COMMON_SET_IFACE_RX_FILTER = 34,
+ OPCODE_COMMON_GET_FW_VERSION = 35,
+ OPCODE_COMMON_SET_FLOW_CONTROL = 36,
+ OPCODE_COMMON_GET_FLOW_CONTROL = 37,
+ OPCODE_COMMON_SET_FRAME_SIZE = 39,
+ OPCODE_COMMON_MODIFY_EQ_DELAY = 41,
+ OPCODE_COMMON_CREATE_IFACE = 50,
+ OPCODE_COMMON_DESTROY_IFACE = 51,
+ OPCODE_COMMON_MODIFY_MSI_MESSAGES = 52,
+ OPCODE_COMMON_DESTROY_MQ = 53,
+ OPCODE_COMMON_DESTROY_CQ = 54,
+ OPCODE_COMMON_DESTROY_EQ = 55,
+ OPCODE_COMMON_UPLOAD_TCP = 56,
+ OPCODE_COMMON_SET_NTWK_LINK_SPEED = 57,
+ OPCODE_COMMON_QUERY_FIRMWARE_CONFIG = 58,
+ OPCODE_COMMON_ADD_IFACE_MAC = 59,
+ OPCODE_COMMON_DEL_IFACE_MAC = 60,
+ OPCODE_COMMON_FUNCTION_RESET = 61,
+ OPCODE_COMMON_SET_PHYSICAL_LINK_CONFIG = 62,
+ OPCODE_COMMON_GET_BOOT_CONFIG = 66,
+ OPCPDE_COMMON_SET_BOOT_CONFIG = 67,
+ OPCODE_COMMON_SET_BEACON_CONFIG = 69,
+ OPCODE_COMMON_GET_BEACON_CONFIG = 70,
+ OPCODE_COMMON_GET_PHYSICAL_LINK_CONFIG = 71,
+ OPCODE_COMMON_GET_OEM_ATTRIBUTES = 76,
+ OPCODE_COMMON_GET_PORT_NAME = 77,
+ OPCODE_COMMON_GET_CONFIG_SIGNATURE = 78,
+ OPCODE_COMMON_SET_CONFIG_SIGNATURE = 79,
+ OPCODE_COMMON_SET_LOGICAL_LINK_CONFIG = 80,
+ OPCODE_COMMON_GET_BE_CONFIGURATION_RESOURCES = 81,
+ OPCODE_COMMON_SET_BE_CONFIGURATION_RESOURCES = 82,
+ OPCODE_COMMON_GET_RESET_NEEDED = 84,
+ OPCODE_COMMON_GET_SERIAL_NUMBER = 85,
+ OPCODE_COMMON_GET_NCSI_CONFIG = 86,
+ OPCODE_COMMON_SET_NCSI_CONFIG = 87,
+ OPCODE_COMMON_CREATE_MQ_EXT = 90,
+ OPCODE_COMMON_SET_FUNCTION_PRIVILEGES = 100,
+ OPCODE_COMMON_SET_VF_PORT_TYPE = 101,
+ OPCODE_COMMON_GET_PHY_CONFIG = 102,
+ OPCODE_COMMON_SET_FUNCTIONAL_CAPS = 103,
+ OPCODE_COMMON_GET_ADAPTER_ID = 110,
+ OPCODE_COMMON_GET_UPGRADE_FEATURES = 111,
+ OPCODE_COMMON_GET_INSTALLED_FEATURES = 112,
+ OPCODE_COMMON_GET_AVAIL_PERSONALITIES = 113,
+ OPCODE_COMMON_GET_CONFIG_PERSONALITIES = 114,
+ OPCODE_COMMON_SEND_ACTIVATION = 115,
+ OPCODE_COMMON_RESET_LICENSES = 116,
+ OPCODE_COMMON_GET_CNTL_ADDL_ATTRIBUTES = 121,
+ OPCODE_COMMON_QUERY_TCB = 144,
+ OPCODE_COMMON_ADD_IFACE_QUEUE_FILTER = 145,
+ OPCODE_COMMON_DEL_IFACE_QUEUE_FILTER = 146,
+ OPCODE_COMMON_GET_IFACE_MAC_LIST = 147,
+ OPCODE_COMMON_SET_IFACE_MAC_LIST = 148,
+ OPCODE_COMMON_MODIFY_CQ = 149,
+ OPCODE_COMMON_GET_IFACE_VLAN_LIST = 150,
+ OPCODE_COMMON_SET_IFACE_VLAN_LIST = 151,
+ OPCODE_COMMON_GET_HSW_CONFIG = 152,
+ OPCODE_COMMON_SET_HSW_CONFIG = 153,
+ OPCODE_COMMON_GET_RESOURCE_EXTENT_INFO = 154,
+ OPCODE_COMMON_GET_ALLOCATED_RESOURCE_EXTENTS = 155,
+ OPCODE_COMMON_ALLOC_RESOURCE_EXTENTS = 156,
+ OPCODE_COMMON_DEALLOC_RESOURCE_EXTENTS = 157,
+ OPCODE_COMMON_SET_DIAG_REGISTERS = 158,
+ OPCODE_COMMON_GET_FUNCTION_CONFIG = 160,
+ OPCODE_COMMON_GET_PROFILE_CAPACITIES = 161,
+ OPCODE_COMMON_GET_MR_PROFILE_CAPACITIES = 162,
+ OPCODE_COMMON_SET_MR_PROFILE_CAPACITIES = 163,
+ OPCODE_COMMON_GET_PROFILE_CONFIG = 164,
+ OPCODE_COMMON_SET_PROFILE_CONFIG = 165,
+ OPCODE_COMMON_GET_PROFILE_LIST = 166,
+ OPCODE_COMMON_GET_ACTIVE_PROFILE = 167,
+ OPCODE_COMMON_SET_ACTIVE_PROFILE = 168,
+ OPCODE_COMMON_GET_FUNCTION_PRIVILEGES = 170,
+ OPCODE_COMMON_READ_OBJECT = 171,
+ OPCODE_COMMON_WRITE_OBJECT = 172
+};
+
+/* common ioctl header */
+#define OCE_MBX_VER_V2 0x0002 /* Version V2 mailbox command */
+#define OCE_MBX_VER_V1 0x0001 /* Version V1 mailbox command */
+#define OCE_MBX_VER_V0 0x0000 /* Version V0 mailbox command */
+struct mbx_hdr {
+ union {
+ uint32_t dw[4];
+ struct {
+ #ifdef _BIG_ENDIAN
+ /* dw 0 */
+ uint32_t domain:8;
+ uint32_t port_number:8;
+ uint32_t subsystem:8;
+ uint32_t opcode:8;
+ /* dw 1 */
+ uint32_t timeout;
+ /* dw 2 */
+ uint32_t request_length;
+ /* dw 3 */
+ uint32_t rsvd0:24;
+ uint32_t version:8;
+ #else
+ /* dw 0 */
+ uint32_t opcode:8;
+ uint32_t subsystem:8;
+ uint32_t port_number:8;
+ uint32_t domain:8;
+ /* dw 1 */
+ uint32_t timeout;
+ /* dw 2 */
+ uint32_t request_length;
+ /* dw 3 */
+ uint32_t version:8;
+ uint32_t rsvd0:24;
+ #endif
+ } req;
+ struct {
+ #ifdef _BIG_ENDIAN
+ /* dw 0 */
+ uint32_t domain:8;
+ uint32_t rsvd0:8;
+ uint32_t subsystem:8;
+ uint32_t opcode:8;
+ /* dw 1 */
+ uint32_t rsvd1:16;
+ uint32_t additional_status:8;
+ uint32_t status:8;
+ #else
+ /* dw 0 */
+ uint32_t opcode:8;
+ uint32_t subsystem:8;
+ uint32_t rsvd0:8;
+ uint32_t domain:8;
+ /* dw 1 */
+ uint32_t status:8;
+ uint32_t additional_status:8;
+ uint32_t rsvd1:16;
+ #endif
+ uint32_t rsp_length;
+ uint32_t actual_rsp_length;
+ } rsp;
+ } u0;
+};
+#define OCE_BMBX_RHDR_SZ 20
+#define OCE_MBX_RRHDR_SZ sizeof (struct mbx_hdr)
+#define OCE_MBX_ADDL_STATUS(_MHDR) ((_MHDR)->u0.rsp.additional_status)
+#define OCE_MBX_STATUS(_MHDR) ((_MHDR)->u0.rsp.status)
+
+/* [05] OPCODE_COMMON_QUERY_LINK_CONFIG */
+struct mbx_query_common_link_config {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t rsvd0;
+ } req;
+
+ struct {
+ /* dw 0 */
+ uint8_t physical_port;
+ uint8_t mac_duplex;
+ uint8_t mac_speed;
+ uint8_t mac_fault;
+ /* dw 1 */
+ uint8_t mgmt_mac_duplex;
+ uint8_t mgmt_mac_speed;
+ uint16_t qos_link_speed;
+ uint32_t logical_link_status;
+ } rsp;
+ } params;
+};
+
+/* [57] OPCODE_COMMON_SET_LINK_SPEED */
+struct mbx_set_common_link_speed {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ uint8_t rsvd0;
+ uint8_t mac_speed;
+ uint8_t virtual_port;
+ uint8_t physical_port;
+#else
+ uint8_t physical_port;
+ uint8_t virtual_port;
+ uint8_t mac_speed;
+ uint8_t rsvd0;
+#endif
+ } req;
+
+ struct {
+ uint32_t rsvd0;
+ } rsp;
+
+ uint32_t dw;
+ } params;
+};
+
+struct mac_address_format {
+ uint16_t size_of_struct;
+ uint8_t mac_addr[6];
+};
+
+/* [01] OPCODE_COMMON_QUERY_IFACE_MAC */
+struct mbx_query_common_iface_mac {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ uint16_t if_id;
+ uint8_t permanent;
+ uint8_t type;
+#else
+ uint8_t type;
+ uint8_t permanent;
+ uint16_t if_id;
+#endif
+
+ } req;
+
+ struct {
+ struct mac_address_format mac;
+ } rsp;
+ } params;
+};
+
+/* [02] OPCODE_COMMON_SET_IFACE_MAC */
+struct mbx_set_common_iface_mac {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ /* dw 0 */
+ uint16_t if_id;
+ uint8_t invalidate;
+ uint8_t type;
+#else
+ /* dw 0 */
+ uint8_t type;
+ uint8_t invalidate;
+ uint16_t if_id;
+#endif
+ /* dw 1 */
+ struct mac_address_format mac;
+ } req;
+
+ struct {
+ uint32_t rsvd0;
+ } rsp;
+
+ uint32_t dw[2];
+ } params;
+};
+
+/* [03] OPCODE_COMMON_SET_IFACE_MULTICAST */
+struct mbx_set_common_iface_multicast {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ /* dw 0 */
+ uint16_t num_mac;
+ uint8_t promiscuous;
+ uint8_t if_id;
+ /* dw 1-48 */
+ struct {
+ uint8_t byte[6];
+ } mac[32];
+
+ } req;
+
+ struct {
+ uint32_t rsvd0;
+ } rsp;
+
+ uint32_t dw[49];
+ } params;
+};
+
+struct qinq_vlan {
+#ifdef _BIG_ENDIAN
+ uint16_t inner;
+ uint16_t outer;
+#else
+ uint16_t outer;
+ uint16_t inner;
+#endif
+};
+
+struct normal_vlan {
+ uint16_t vtag;
+};
+
+struct ntwk_if_vlan_tag {
+ union {
+ struct normal_vlan normal;
+ struct qinq_vlan qinq;
+ } u0;
+};
+
+/* [50] OPCODE_COMMON_CREATE_IFACE */
+struct mbx_create_common_iface {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t version;
+ uint32_t cap_flags;
+ uint32_t enable_flags;
+ uint8_t mac_addr[6];
+ uint8_t rsvd0;
+ uint8_t mac_invalid;
+ struct ntwk_if_vlan_tag vlan_tag;
+ } req;
+
+ struct {
+ uint32_t if_id;
+ uint32_t pmac_id;
+ } rsp;
+ uint32_t dw[4];
+ } params;
+};
+
+/* [51] OPCODE_COMMON_DESTROY_IFACE */
+struct mbx_destroy_common_iface {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t if_id;
+ } req;
+
+ struct {
+ uint32_t rsvd0;
+ } rsp;
+
+ uint32_t dw;
+ } params;
+};
+
+/* event queue context structure */
+struct oce_eq_ctx {
+#ifdef _BIG_ENDIAN
+ uint32_t dw4rsvd1:16;
+ uint32_t num_pages:16;
+
+ uint32_t size:1;
+ uint32_t dw5rsvd2:1;
+ uint32_t valid:1;
+ uint32_t dw5rsvd1:29;
+
+ uint32_t armed:1;
+ uint32_t dw6rsvd2:2;
+ uint32_t count:3;
+ uint32_t dw6rsvd1:26;
+
+ uint32_t dw7rsvd2:9;
+ uint32_t delay_mult:10;
+ uint32_t dw7rsvd1:13;
+
+ uint32_t dw8rsvd1;
+#else
+ uint32_t num_pages:16;
+ uint32_t dw4rsvd1:16;
+
+ uint32_t dw5rsvd1:29;
+ uint32_t valid:1;
+ uint32_t dw5rsvd2:1;
+ uint32_t size:1;
+
+ uint32_t dw6rsvd1:26;
+ uint32_t count:3;
+ uint32_t dw6rsvd2:2;
+ uint32_t armed:1;
+
+ uint32_t dw7rsvd1:13;
+ uint32_t delay_mult:10;
+ uint32_t dw7rsvd2:9;
+
+ uint32_t dw8rsvd1;
+#endif
+};
+
+/* [13] OPCODE_COMMON_CREATE_EQ */
+struct mbx_create_common_eq {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ struct oce_eq_ctx ctx;
+ struct phys_addr pages[8];
+ } req;
+
+ struct {
+ uint16_t eq_id;
+ uint16_t rsvd0;
+ } rsp;
+ } params;
+};
+
+/* [55] OPCODE_COMMON_DESTROY_EQ */
+struct mbx_destroy_common_eq {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ uint16_t rsvd0;
+ uint16_t id;
+#else
+ uint16_t id;
+ uint16_t rsvd0;
+#endif
+ } req;
+
+ struct {
+ uint32_t rsvd0;
+ } rsp;
+ } params;
+};
+
+/* SLI-4 CQ context - use version V0 for B3, version V2 for Lancer */
+typedef union oce_cq_ctx_u {
+ uint32_t dw[5];
+ struct {
+ #ifdef _BIG_ENDIAN
+ /* dw4 */
+ uint32_t dw4rsvd1:16;
+ uint32_t num_pages:16;
+ /* dw5 */
+ uint32_t eventable:1;
+ uint32_t dw5rsvd3:1;
+ uint32_t valid:1;
+ uint32_t count:2;
+ uint32_t dw5rsvd2:12;
+ uint32_t nodelay:1;
+ uint32_t coalesce_wm:2;
+ uint32_t dw5rsvd1:12;
+ /* dw6 */
+ uint32_t armed:1;
+ uint32_t dw6rsvd2:1;
+ uint32_t eq_id:8;
+ uint32_t dw6rsvd1:22;
+ #else
+ /* dw4 */
+ uint32_t num_pages:16;
+ uint32_t dw4rsvd1:16;
+ /* dw5 */
+ uint32_t dw5rsvd1:12;
+ uint32_t coalesce_wm:2;
+ uint32_t nodelay:1;
+ uint32_t dw5rsvd2:12;
+ uint32_t count:2;
+ uint32_t valid:1;
+ uint32_t dw5rsvd3:1;
+ uint32_t eventable:1;
+ /* dw6 */
+ uint32_t dw6rsvd1:22;
+ uint32_t eq_id:8;
+ uint32_t dw6rsvd2:1;
+ uint32_t armed:1;
+ #endif
+ /* dw7 */
+ uint32_t dw7rsvd1;
+ /* dw8 */
+ uint32_t dw8rsvd1;
+ } v0;
+ struct {
+ #ifdef _BIG_ENDIAN
+ /* dw4 */
+ uint32_t dw4rsvd1:8;
+ uint32_t page_size:8;
+ uint32_t num_pages:16;
+ /* dw5 */
+ uint32_t eventable:1;
+ uint32_t dw5rsvd3:1;
+ uint32_t valid:1;
+ uint32_t count:2;
+ uint32_t dw5rsvd2:11;
+ uint32_t autovalid:1;
+ uint32_t nodelay:1;
+ uint32_t coalesce_wm:2;
+ uint32_t dw5rsvd1:12;
+ /* dw6 */
+ uint32_t armed:1;
+ uint32_t dw6rsvd1:15;
+ uint32_t eq_id:16;
+ /* dw7 */
+ uint32_t dw7rsvd1:16;
+ uint32_t cqe_count:16;
+ #else
+ /* dw4 */
+ uint32_t num_pages:16;
+ uint32_t page_size:8;
+ uint32_t dw4rsvd1:8;
+ /* dw5 */
+ uint32_t dw5rsvd1:12;
+ uint32_t coalesce_wm:2;
+ uint32_t nodelay:1;
+ uint32_t autovalid:1;
+ uint32_t dw5rsvd2:11;
+ uint32_t count:2;
+ uint32_t valid:1;
+ uint32_t dw5rsvd3:1;
+ uint32_t eventable:1;
+ /* dw6 */
+ uint32_t eq_id:8;
+ uint32_t dw6rsvd1:15;
+ uint32_t armed:1;
+ /* dw7 */
+ uint32_t cqe_count:16;
+ uint32_t dw7rsvd1:16;
+ #endif
+ /* dw8 */
+ uint32_t dw8rsvd1;
+ } v2;
+} oce_cq_ctx_t;
+
+/* [12] OPCODE_COMMON_CREATE_CQ */
+struct mbx_create_common_cq {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ oce_cq_ctx_t cq_ctx;
+ struct phys_addr pages[4];
+ } req;
+
+ struct {
+ uint16_t cq_id;
+ uint16_t rsvd0;
+ } rsp;
+ } params;
+};
+
+/* [54] OPCODE_COMMON_DESTROY_CQ */
+struct mbx_destroy_common_cq {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ uint16_t rsvd0;
+ uint16_t id;
+#else
+ uint16_t id;
+ uint16_t rsvd0;
+#endif
+ } req;
+
+ struct {
+ uint32_t rsvd0;
+ } rsp;
+ } params;
+};
+
+typedef union oce_mq_ctx_u {
+ uint32_t dw[5];
+ struct {
+ #ifdef _BIG_ENDIAN
+ /* dw4 */
+ uint32_t dw4rsvd1:16;
+ uint32_t num_pages:16;
+ /* dw5 */
+ uint32_t cq_id:10;
+ uint32_t dw5rsvd2:2;
+ uint32_t ring_size:4;
+ uint32_t dw5rsvd1:16;
+ /* dw6 */
+ uint32_t valid:1;
+ uint32_t dw6rsvd1:31;
+ /* dw7 */
+ uint32_t dw7rsvd1:21;
+ uint32_t async_cq_id:10;
+ uint32_t async_cq_valid:1;
+ #else
+ /* dw4 */
+ uint32_t num_pages:16;
+ uint32_t dw4rsvd1:16;
+ /* dw5 */
+ uint32_t dw5rsvd1:16;
+ uint32_t ring_size:4;
+ uint32_t dw5rsvd2:2;
+ uint32_t cq_id:10;
+ /* dw6 */
+ uint32_t dw6rsvd1:31;
+ uint32_t valid:1;
+ /* dw7 */
+ uint32_t async_cq_valid:1;
+ uint32_t async_cq_id:10;
+ uint32_t dw7rsvd1:21;
+ #endif
+ /* dw8 */
+ uint32_t dw8rsvd1;
+ } v0;
+} oce_mq_ctx_t;
+
+/**
+ * @brief [21] OPCODE_COMMON_CREATE_MQ
+ * A MQ must be at least 16 entries deep (corresponding to 1 page) and
+ * at most 128 entries deep (corresponding to 8 pages).
+ */
+struct mbx_create_common_mq {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ oce_mq_ctx_t context;
+ struct phys_addr pages[8];
+ } req;
+
+ struct {
+ uint32_t mq_id:16;
+ uint32_t rsvd0:16;
+ } rsp;
+ } params;
+};
+
+struct mbx_create_common_mq_ex {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ oce_mq_ext_ctx_t context;
+ struct phys_addr pages[8];
+ } req;
+
+ struct {
+ uint32_t mq_id:16;
+ uint32_t rsvd0:16;
+ } rsp;
+ } params;
+};
+
+
+
+/* [53] OPCODE_COMMON_DESTROY_MQ */
+struct mbx_destroy_common_mq {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ uint16_t rsvd0;
+ uint16_t id;
+#else
+ uint16_t id;
+ uint16_t rsvd0;
+#endif
+ } req;
+
+ struct {
+ uint32_t rsvd0;
+ } rsp;
+ } params;
+};
+
+/* [35] OPCODE_COMMON_GET_ FW_VERSION */
+struct mbx_get_common_fw_version {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t rsvd0;
+ } req;
+
+ struct {
+ uint8_t fw_ver_str[32];
+ uint8_t fw_on_flash_ver_str[32];
+ } rsp;
+ } params;
+};
+
+/* [52] OPCODE_COMMON_CEV_MODIFY_MSI_MESSAGES */
+struct mbx_common_cev_modify_msi_messages {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t num_msi_msgs;
+ } req;
+
+ struct {
+ uint32_t rsvd0;
+ } rsp;
+ } params;
+};
+
+/* [36] OPCODE_COMMON_SET_FLOW_CONTROL */
+/* [37] OPCODE_COMMON_GET_FLOW_CONTROL */
+struct mbx_common_get_set_flow_control {
+ struct mbx_hdr hdr;
+#ifdef _BIG_ENDIAN
+ uint16_t tx_flow_control;
+ uint16_t rx_flow_control;
+#else
+ uint16_t rx_flow_control;
+ uint16_t tx_flow_control;
+#endif
+};
+
+enum e_flash_opcode {
+ MGMT_FLASHROM_OPCODE_FLASH = 1,
+ MGMT_FLASHROM_OPCODE_SAVE = 2
+};
+
+/* [06] OPCODE_READ_COMMON_FLASHROM */
+/* [07] OPCODE_WRITE_COMMON_FLASHROM */
+
+struct mbx_common_read_write_flashrom {
+ struct mbx_hdr hdr;
+ uint32_t flash_op_code;
+ uint32_t flash_op_type;
+ uint32_t data_buffer_size;
+ uint32_t data_offset;
+ uint8_t data_buffer[4]; /* + IMAGE_TRANSFER_SIZE */
+};
+
+struct oce_phy_info {
+ uint16_t phy_type;
+ uint16_t interface_type;
+ uint32_t misc_params;
+ uint16_t ext_phy_details;
+ uint16_t rsvd;
+ uint16_t auto_speeds_supported;
+ uint16_t fixed_speeds_supported;
+ uint32_t future_use[2];
+};
+
+struct mbx_common_phy_info {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t rsvd0[4];
+ } req;
+ struct {
+ struct oce_phy_info phy_info;
+ } rsp;
+ } params;
+};
+
+/*Lancer firmware*/
+
+struct mbx_lancer_common_write_object {
+ union {
+ struct {
+ struct mbx_hdr hdr;
+ uint32_t write_length: 24;
+ uint32_t rsvd: 7;
+ uint32_t eof: 1;
+ uint32_t write_offset;
+ uint8_t object_name[104];
+ uint32_t descriptor_count;
+ uint32_t buffer_length;
+ uint32_t address_lower;
+ uint32_t address_upper;
+ } req;
+ struct {
+ uint8_t opcode;
+ uint8_t subsystem;
+ uint8_t rsvd1[2];
+ uint8_t status;
+ uint8_t additional_status;
+ uint8_t rsvd2[2];
+ uint32_t response_length;
+ uint32_t actual_response_length;
+ uint32_t actual_write_length;
+ } rsp;
+ } params;
+};
+
+/**
+ * @brief MBX Common Quiery Firmaware Config
+ * This command retrieves firmware configuration parameters and adapter
+ * resources available to the driver originating the request. The firmware
+ * configuration defines supported protocols by the installed adapter firmware.
+ * This includes which ULP processors support the specified protocols and
+ * the number of TCP connections allowed for that protocol.
+ */
+struct mbx_common_query_fw_config {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t rsvd0[30];
+ } req;
+
+ struct {
+ uint32_t config_number;
+ uint32_t asic_revision;
+ uint32_t port_id; /* used for stats retrieval */
+ uint32_t function_mode;
+ struct {
+
+ uint32_t ulp_mode;
+ uint32_t nic_wqid_base;
+ uint32_t nic_wq_tot;
+ uint32_t toe_wqid_base;
+ uint32_t toe_wq_tot;
+ uint32_t toe_rqid_base;
+ uint32_t toe_rqid_tot;
+ uint32_t toe_defrqid_base;
+ uint32_t toe_defrqid_count;
+ uint32_t lro_rqid_base;
+ uint32_t lro_rqid_tot;
+ uint32_t iscsi_icd_base;
+ uint32_t iscsi_icd_count;
+ } ulp[2];
+ uint32_t function_caps;
+ uint32_t cqid_base;
+ uint32_t cqid_tot;
+ uint32_t eqid_base;
+ uint32_t eqid_tot;
+ } rsp;
+ } params;
+};
+
+enum CQFW_CONFIG_NUMBER {
+ FCN_NIC_ISCSI_Initiator = 0x0,
+ FCN_ISCSI_Target = 0x3,
+ FCN_FCoE = 0x7,
+ FCN_ISCSI_Initiator_Target = 0x9,
+ FCN_NIC_RDMA_TOE = 0xA,
+ FCN_NIC_RDMA_FCoE = 0xB,
+ FCN_NIC_RDMA_iSCSI = 0xC,
+ FCN_NIC_iSCSI_FCoE = 0xD
+};
+
+/**
+ * @brief Function Capabilites
+ * This field contains the flags indicating the capabilities of
+ * the SLI Host’s PCI function.
+ */
+enum CQFW_FUNCTION_CAPABILITIES {
+ FNC_UNCLASSIFIED_STATS = 0x1,
+ FNC_RSS = 0x2,
+ FNC_PROMISCUOUS = 0x4,
+ FNC_LEGACY_MODE = 0x8,
+ FNC_HDS = 0x4000,
+ FNC_VMQ = 0x10000,
+ FNC_NETQ = 0x20000,
+ FNC_QGROUPS = 0x40000,
+ FNC_LRO = 0x100000,
+ FNC_VLAN_OFFLOAD = 0x800000
+};
+
+enum CQFW_ULP_MODES_SUPPORTED {
+ ULP_TOE_MODE = 0x1,
+ ULP_NIC_MODE = 0x2,
+ ULP_RDMA_MODE = 0x4,
+ ULP_ISCSI_INI_MODE = 0x10,
+ ULP_ISCSI_TGT_MODE = 0x20,
+ ULP_FCOE_INI_MODE = 0x40,
+ ULP_FCOE_TGT_MODE = 0x80,
+ ULP_DAL_MODE = 0x100,
+ ULP_LRO_MODE = 0x200
+};
+
+/**
+ * @brief Function Modes Supported
+ * Valid function modes (or protocol-types) supported on the SLI-Host’s
+ * PCIe function. This field is a logical OR of the following values:
+ */
+enum CQFW_FUNCTION_MODES_SUPPORTED {
+ FNM_TOE_MODE = 0x1, /* TCP offload supported */
+ FNM_NIC_MODE = 0x2, /* Raw Ethernet supported */
+ FNM_RDMA_MODE = 0x4, /* RDMA protocol supported */
+ FNM_VM_MODE = 0x8, /* Virtual Machines supported */
+ FNM_ISCSI_INI_MODE = 0x10, /* iSCSI initiator supported */
+ FNM_ISCSI_TGT_MODE = 0x20, /* iSCSI target plus initiator */
+ FNM_FCOE_INI_MODE = 0x40, /* FCoE Initiator supported */
+ FNM_FCOE_TGT_MODE = 0x80, /* FCoE target supported */
+ FNM_DAL_MODE = 0x100, /* DAL supported */
+ FNM_LRO_MODE = 0x200, /* LRO supported */
+ FNM_FLEX10_MODE = 0x400, /* QinQ, FLEX-10 or VNIC */
+ FNM_NCSI_MODE = 0x800, /* NCSI supported */
+ FNM_IPV6_MODE = 0x1000, /* IPV6 stack enabled */
+ FNM_BE2_COMPAT_MODE = 0x2000, /* BE2 compatibility (BE3 disable)*/
+ FNM_INVALID_MODE = 0x8000, /* Invalid */
+ FNM_BE3_COMPAT_MODE = 0x10000, /* BE3 features */
+ FNM_VNIC_MODE = 0x20000, /* Set when IBM vNIC mode is set */
+ FNM_VNTAG_MODE = 0x40000, /* Set when VNTAG mode is set */
+ FNM_UMC_MODE = 0x1000000, /* Set when UMC mode is set */
+ FNM_UMC_DEF_EN = 0x100000, /* Set when UMC Default is set */
+ FNM_ONE_GB_EN = 0x200000, /* Set when 1GB Default is set */
+ FNM_VNIC_DEF_VALID = 0x400000, /* Set when VNIC_DEF_EN is valid */
+ FNM_VNIC_DEF_EN = 0x800000 /* Set when VNIC Default enabled */
+};
+
+
+struct mbx_common_config_vlan {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ uint8_t num_vlans;
+ uint8_t untagged;
+ uint8_t promisc;
+ uint8_t if_id;
+#else
+ uint8_t if_id;
+ uint8_t promisc;
+ uint8_t untagged;
+ uint8_t num_vlans;
+#endif
+ union {
+ struct normal_vlan normal_vlans[64];
+ struct qinq_vlan qinq_vlans[32];
+ } tags;
+ } req;
+
+ struct {
+ uint32_t rsvd;
+ } rsp;
+ } params;
+};
+
+typedef struct iface_rx_filter_ctx {
+ uint32_t global_flags_mask;
+ uint32_t global_flags;
+ uint32_t iface_flags_mask;
+ uint32_t iface_flags;
+ uint32_t if_id;
+ #define IFACE_RX_NUM_MCAST_MAX 64
+ uint32_t num_mcast;
+ struct mbx_mcast_addr {
+ uint8_t byte[6];
+ } mac[IFACE_RX_NUM_MCAST_MAX];
+} iface_rx_filter_ctx_t;
+
+/* [34] OPCODE_COMMON_SET_IFACE_RX_FILTER */
+struct mbx_set_common_iface_rx_filter {
+ struct mbx_hdr hdr;
+ union {
+ iface_rx_filter_ctx_t req;
+ iface_rx_filter_ctx_t rsp;
+ } params;
+};
+
+/* [41] OPCODE_COMMON_MODIFY_EQ_DELAY */
+struct mbx_modify_common_eq_delay {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t num_eq;
+ struct {
+ uint32_t eq_id;
+ uint32_t phase;
+ uint32_t dm;
+ } delay[8];
+ } req;
+
+ struct {
+ uint32_t rsvd0;
+ } rsp;
+ } params;
+};
+
+/* [59] OPCODE_ADD_COMMON_IFACE_MAC */
+struct mbx_add_common_iface_mac {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t if_id;
+ uint8_t mac_address[6];
+ uint8_t rsvd0[2];
+ } req;
+ struct {
+ uint32_t pmac_id;
+ } rsp;
+ } params;
+};
+
+/* [60] OPCODE_DEL_COMMON_IFACE_MAC */
+struct mbx_del_common_iface_mac {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t if_id;
+ uint32_t pmac_id;
+ } req;
+ struct {
+ uint32_t rsvd0;
+ } rsp;
+ } params;
+};
+
+/* [8] OPCODE_QUERY_COMMON_MAX_MBX_BUFFER_SIZE */
+struct mbx_query_common_max_mbx_buffer_size {
+ struct mbx_hdr hdr;
+ struct {
+ uint32_t max_ioctl_bufsz;
+ } rsp;
+};
+
+/* [61] OPCODE_COMMON_FUNCTION_RESET */
+struct ioctl_common_function_reset {
+ struct mbx_hdr hdr;
+};
+
+/* [80] OPCODE_COMMON_FUNCTION_LINK_CONFIG */
+struct mbx_common_func_link_cfg {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t enable;
+ } req;
+ struct {
+ uint32_t rsvd0;
+ } rsp;
+ } params;
+};
+
+/* [103] OPCODE_COMMON_SET_FUNCTIONAL_CAPS */
+#define CAP_SW_TIMESTAMPS 2
+#define CAP_BE3_NATIVE_ERX_API 4
+
+struct mbx_common_set_function_cap {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t valid_capability_flags;
+ uint32_t capability_flags;
+ uint8_t sbz[212];
+ } req;
+ struct {
+ uint32_t valid_capability_flags;
+ uint32_t capability_flags;
+ uint8_t sbz[212];
+ } rsp;
+ } params;
+};
+struct mbx_lowlevel_test_loopback_mode {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t loopback_type;
+ uint32_t num_pkts;
+ uint64_t pattern;
+ uint32_t src_port;
+ uint32_t dest_port;
+ uint32_t pkt_size;
+ }req;
+ struct {
+ uint32_t status;
+ uint32_t num_txfer;
+ uint32_t num_rx;
+ uint32_t miscomp_off;
+ uint32_t ticks_compl;
+ }rsp;
+ } params;
+};
+
+struct mbx_lowlevel_set_loopback_mode {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint8_t src_port;
+ uint8_t dest_port;
+ uint8_t loopback_type;
+ uint8_t loopback_state;
+ } req;
+ struct {
+ uint8_t rsvd0[4];
+ } rsp;
+ } params;
+};
+
+struct flash_file_hdr {
+ uint8_t sign[52];
+ uint8_t ufi_version[4];
+ uint32_t file_len;
+ uint32_t cksum;
+ uint32_t antidote;
+ uint32_t num_imgs;
+ uint8_t build[24];
+ uint8_t rsvd[32];
+};
+
+struct image_hdr {
+ uint32_t imageid;
+ uint32_t imageoffset;
+ uint32_t imagelength;
+ uint32_t image_checksum;
+ uint8_t image_version[32];
+};
+
+struct flash_section_hdr {
+ uint32_t format_rev;
+ uint32_t cksum;
+ uint32_t antidote;
+ uint32_t num_images;
+ uint8_t id_string[128];
+ uint32_t rsvd[4];
+};
+
+struct flash_section_entry {
+ uint32_t type;
+ uint32_t offset;
+ uint32_t pad_size;
+ uint32_t image_size;
+ uint32_t cksum;
+ uint32_t entry_point;
+ uint32_t rsvd0;
+ uint32_t rsvd1;
+ uint8_t ver_data[32];
+};
+
+struct flash_sec_info {
+ uint8_t cookie[32];
+ struct flash_section_hdr fsec_hdr;
+ struct flash_section_entry fsec_entry[32];
+};
+
+
+enum LOWLEVEL_SUBSYSTEM_OPCODES {
+/* Opcodes used for lowlevel functions common to many subystems.
+ * Some of these opcodes are used for diagnostic functions only.
+ * These opcodes use the MBX_SUBSYSTEM_LOWLEVEL subsystem code.
+ */
+ OPCODE_LOWLEVEL_TEST_LOOPBACK = 18,
+ OPCODE_LOWLEVEL_SET_LOOPBACK_MODE = 19,
+ OPCODE_LOWLEVEL_GET_LOOPBACK_MODE = 20
+};
+
+enum LLDP_SUBSYSTEM_OPCODES {
+/* Opcodes used for LLDP susbsytem for configuring the LLDP state machines. */
+ OPCODE_LLDP_GET_CFG = 1,
+ OPCODE_LLDP_SET_CFG = 2,
+ OPCODE_LLDP_GET_STATS = 3
+};
+
+enum DCBX_SUBSYSTEM_OPCODES {
+/* Opcodes used for DCBX. */
+ OPCODE_DCBX_GET_CFG = 1,
+ OPCODE_DCBX_SET_CFG = 2,
+ OPCODE_DCBX_GET_MIB_INFO = 3,
+ OPCODE_DCBX_GET_DCBX_MODE = 4,
+ OPCODE_DCBX_SET_MODE = 5
+};
+
+enum DMTF_SUBSYSTEM_OPCODES {
+/* Opcodes used for DCBX subsystem. */
+ OPCODE_DMTF_EXEC_CLP_CMD = 1
+};
+
+enum DIAG_SUBSYSTEM_OPCODES {
+/* Opcodes used for diag functions common to many subsystems. */
+ OPCODE_DIAG_RUN_DMA_TEST = 1,
+ OPCODE_DIAG_RUN_MDIO_TEST = 2,
+ OPCODE_DIAG_RUN_NLB_TEST = 3,
+ OPCODE_DIAG_RUN_ARM_TIMER_TEST = 4,
+ OPCODE_DIAG_GET_MAC = 5
+};
+
+enum VENDOR_SUBSYSTEM_OPCODES {
+/* Opcodes used for Vendor subsystem. */
+ OPCODE_VENDOR_SLI = 1
+};
+
+/* Management Status Codes */
+enum MGMT_STATUS_SUCCESS {
+ MGMT_SUCCESS = 0,
+ MGMT_FAILED = 1,
+ MGMT_ILLEGAL_REQUEST = 2,
+ MGMT_ILLEGAL_FIELD = 3,
+ MGMT_INSUFFICIENT_BUFFER = 4,
+ MGMT_UNAUTHORIZED_REQUEST = 5,
+ MGMT_INVALID_ISNS_ADDRESS = 10,
+ MGMT_INVALID_IPADDR = 11,
+ MGMT_INVALID_GATEWAY = 12,
+ MGMT_INVALID_SUBNETMASK = 13,
+ MGMT_INVALID_TARGET_IPADDR = 16,
+ MGMT_TGTTBL_FULL = 20,
+ MGMT_FLASHROM_SAVE_FAILED = 23,
+ MGMT_IOCTLHANDLE_ALLOC_FAILED = 27,
+ MGMT_INVALID_SESSION = 31,
+ MGMT_INVALID_CONNECTION = 32,
+ MGMT_BTL_PATH_EXCEEDS_OSM_LIMIT = 33,
+ MGMT_BTL_TGTID_EXCEEDS_OSM_LIMIT = 34,
+ MGMT_BTL_PATH_TGTID_OCCUPIED = 35,
+ MGMT_BTL_NO_FREE_SLOT_PATH = 36,
+ MGMT_BTL_NO_FREE_SLOT_TGTID = 37,
+ MGMT_POLL_IOCTL_TIMEOUT = 40,
+ MGMT_ERROR_ACITISCSI = 41,
+ MGMT_BUFFER_SIZE_EXCEED_OSM_OR_OS_LIMIT = 43,
+ MGMT_REBOOT_REQUIRED = 44,
+ MGMT_INSUFFICIENT_TIMEOUT = 45,
+ MGMT_IPADDR_NOT_SET = 46,
+ MGMT_IPADDR_DUP_DETECTED = 47,
+ MGMT_CANT_REMOVE_LAST_CONNECTION = 48,
+ MGMT_TARGET_BUSY = 49,
+ MGMT_TGT_ERR_LISTEN_SOCKET = 50,
+ MGMT_TGT_ERR_BIND_SOCKET = 51,
+ MGMT_TGT_ERR_NO_SOCKET = 52,
+ MGMT_TGT_ERR_ISNS_COMM_FAILED = 55,
+ MGMT_CANNOT_DELETE_BOOT_TARGET = 56,
+ MGMT_TGT_PORTAL_MODE_IN_LISTEN = 57,
+ MGMT_FCF_IN_USE = 58 ,
+ MGMT_NO_CQE = 59,
+ MGMT_TARGET_NOT_FOUND = 65,
+ MGMT_NOT_SUPPORTED = 66,
+ MGMT_NO_FCF_RECORDS = 67,
+ MGMT_FEATURE_NOT_SUPPORTED = 68,
+ MGMT_VPD_FUNCTION_OUT_OF_RANGE = 69,
+ MGMT_VPD_FUNCTION_TYPE_INCORRECT = 70,
+ MGMT_INVALID_NON_EMBEDDED_WRB = 71,
+ MGMT_OOR = 100,
+ MGMT_INVALID_PD = 101,
+ MGMT_STATUS_PD_INUSE = 102,
+ MGMT_INVALID_CQ = 103,
+ MGMT_INVALID_QP = 104,
+ MGMT_INVALID_STAG = 105,
+ MGMT_ORD_EXCEEDS = 106,
+ MGMT_IRD_EXCEEDS = 107,
+ MGMT_SENDQ_WQE_EXCEEDS = 108,
+ MGMT_RECVQ_RQE_EXCEEDS = 109,
+ MGMT_SGE_SEND_EXCEEDS = 110,
+ MGMT_SGE_WRITE_EXCEEDS = 111,
+ MGMT_SGE_RECV_EXCEEDS = 112,
+ MGMT_INVALID_STATE_CHANGE = 113,
+ MGMT_MW_BOUND = 114,
+ MGMT_INVALID_VA = 115,
+ MGMT_INVALID_LENGTH = 116,
+ MGMT_INVALID_FBO = 117,
+ MGMT_INVALID_ACC_RIGHTS = 118,
+ MGMT_INVALID_PBE_SIZE = 119,
+ MGMT_INVALID_PBL_ENTRY = 120,
+ MGMT_INVALID_PBL_OFFSET = 121,
+ MGMT_ADDR_NON_EXIST = 122,
+ MGMT_INVALID_VLANID = 123,
+ MGMT_INVALID_MTU = 124,
+ MGMT_INVALID_BACKLOG = 125,
+ MGMT_CONNECTION_INPROGRESS = 126,
+ MGMT_INVALID_RQE_SIZE = 127,
+ MGMT_INVALID_RQE_ENTRY = 128
+};
+
+/* Additional Management Status Codes */
+enum MGMT_ADDI_STATUS {
+ MGMT_ADDI_NO_STATUS = 0,
+ MGMT_ADDI_INVALID_IPTYPE = 1,
+ MGMT_ADDI_TARGET_HANDLE_NOT_FOUND = 9,
+ MGMT_ADDI_SESSION_HANDLE_NOT_FOUND = 10,
+ MGMT_ADDI_CONNECTION_HANDLE_NOT_FOUND = 11,
+ MGMT_ADDI_ACTIVE_SESSIONS_PRESENT = 16,
+ MGMT_ADDI_SESSION_ALREADY_OPENED = 17,
+ MGMT_ADDI_SESSION_ALREADY_CLOSED = 18,
+ MGMT_ADDI_DEST_HOST_UNREACHABLE = 19,
+ MGMT_ADDI_LOGIN_IN_PROGRESS = 20,
+ MGMT_ADDI_TCP_CONNECT_FAILED = 21,
+ MGMT_ADDI_INSUFFICIENT_RESOURCES = 22,
+ MGMT_ADDI_LINK_DOWN = 23,
+ MGMT_ADDI_DHCP_ERROR = 24,
+ MGMT_ADDI_CONNECTION_OFFLOADED = 25,
+ MGMT_ADDI_CONNECTION_NOT_OFFLOADED = 26,
+ MGMT_ADDI_CONNECTION_UPLOAD_IN_PROGRESS = 27,
+ MGMT_ADDI_REQUEST_REJECTED = 28,
+ MGMT_ADDI_INVALID_SUBSYSTEM = 29,
+ MGMT_ADDI_INVALID_OPCODE = 30,
+ MGMT_ADDI_INVALID_MAXCONNECTION_PARAM = 31,
+ MGMT_ADDI_INVALID_KEY = 32,
+ MGMT_ADDI_INVALID_DOMAIN = 35,
+ MGMT_ADDI_LOGIN_INITIATOR_ERROR = 43,
+ MGMT_ADDI_LOGIN_AUTHENTICATION_ERROR = 44,
+ MGMT_ADDI_LOGIN_AUTHORIZATION_ERROR = 45,
+ MGMT_ADDI_LOGIN_NOT_FOUND = 46,
+ MGMT_ADDI_LOGIN_TARGET_REMOVED = 47,
+ MGMT_ADDI_LOGIN_UNSUPPORTED_VERSION = 48,
+ MGMT_ADDI_LOGIN_TOO_MANY_CONNECTIONS = 49,
+ MGMT_ADDI_LOGIN_MISSING_PARAMETER = 50,
+ MGMT_ADDI_LOGIN_NO_SESSION_SPANNING = 51,
+ MGMT_ADDI_LOGIN_SESSION_TYPE_NOT_SUPPORTED = 52,
+ MGMT_ADDI_LOGIN_SESSION_DOES_NOT_EXIST = 53,
+ MGMT_ADDI_LOGIN_INVALID_DURING_LOGIN = 54,
+ MGMT_ADDI_LOGIN_TARGET_ERROR = 55,
+ MGMT_ADDI_LOGIN_SERVICE_UNAVAILABLE = 56,
+ MGMT_ADDI_LOGIN_OUT_OF_RESOURCES = 57,
+ MGMT_ADDI_SAME_CHAP_SECRET = 58,
+ MGMT_ADDI_INVALID_SECRET_LENGTH = 59,
+ MGMT_ADDI_DUPLICATE_ENTRY = 60,
+ MGMT_ADDI_SETTINGS_MODIFIED_REBOOT_REQD = 63,
+ MGMT_ADDI_INVALID_EXTENDED_TIMEOUT = 64,
+ MGMT_ADDI_INVALID_INTERFACE_HANDLE = 65,
+ MGMT_ADDI_ERR_VLAN_ON_DEF_INTERFACE = 66,
+ MGMT_ADDI_INTERFACE_DOES_NOT_EXIST = 67,
+ MGMT_ADDI_INTERFACE_ALREADY_EXISTS = 68,
+ MGMT_ADDI_INVALID_VLAN_RANGE = 69,
+ MGMT_ADDI_ERR_SET_VLAN = 70,
+ MGMT_ADDI_ERR_DEL_VLAN = 71,
+ MGMT_ADDI_CANNOT_DEL_DEF_INTERFACE = 72,
+ MGMT_ADDI_DHCP_REQ_ALREADY_PENDING = 73,
+ MGMT_ADDI_TOO_MANY_INTERFACES = 74,
+ MGMT_ADDI_INVALID_REQUEST = 75
+};
+
+enum NIC_SUBSYSTEM_OPCODES {
+/**
+ * @brief NIC Subsystem Opcodes (see Network SLI-4 manual >= Rev4, v21-2)
+ * These opcodes are used for configuring the Ethernet interfaces.
+ * These opcodes all use the MBX_SUBSYSTEM_NIC subsystem code.
+ */
+ NIC_CONFIG_RSS = 1,
+ NIC_CONFIG_ACPI = 2,
+ NIC_CONFIG_PROMISCUOUS = 3,
+ NIC_GET_STATS = 4,
+ NIC_CREATE_WQ = 7,
+ NIC_CREATE_RQ = 8,
+ NIC_DELETE_WQ = 9,
+ NIC_DELETE_RQ = 10,
+ NIC_CONFIG_ACPI_WOL_MAGIC = 12,
+ NIC_GET_NETWORK_STATS = 13,
+ NIC_CREATE_HDS_RQ = 16,
+ NIC_DELETE_HDS_RQ = 17,
+ NIC_GET_PPORT_STATS = 18,
+ NIC_GET_VPORT_STATS = 19,
+ NIC_GET_QUEUE_STATS = 20
+};
+
+/* Hash option flags for RSS enable */
+enum RSS_ENABLE_FLAGS {
+ RSS_ENABLE_NONE = 0x0, /* (No RSS) */
+ RSS_ENABLE_IPV4 = 0x1, /* (IPV4 HASH enabled ) */
+ RSS_ENABLE_TCP_IPV4 = 0x2, /* (TCP IPV4 Hash enabled) */
+ RSS_ENABLE_IPV6 = 0x4, /* (IPV6 HASH enabled) */
+ RSS_ENABLE_TCP_IPV6 = 0x8 /* (TCP IPV6 HASH */
+};
+#define RSS_ENABLE (RSS_ENABLE_IPV4 | RSS_ENABLE_TCP_IPV4)
+#define RSS_DISABLE RSS_ENABLE_NONE
+
+/* NIC header WQE */
+struct oce_nic_hdr_wqe {
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ /* dw0 */
+ uint32_t rsvd0;
+
+ /* dw1 */
+ uint32_t last_seg_udp_len:14;
+ uint32_t rsvd1:18;
+
+ /* dw2 */
+ uint32_t lso_mss:14;
+ uint32_t num_wqe:5;
+ uint32_t rsvd4:2;
+ uint32_t vlan:1;
+ uint32_t lso:1;
+ uint32_t tcpcs:1;
+ uint32_t udpcs:1;
+ uint32_t ipcs:1;
+ uint32_t rsvd3:1;
+ uint32_t rsvd2:1;
+ uint32_t forward:1;
+ uint32_t crc:1;
+ uint32_t event:1;
+ uint32_t complete:1;
+
+ /* dw3 */
+ uint32_t vlan_tag:16;
+ uint32_t total_length:16;
+#else
+ /* dw0 */
+ uint32_t rsvd0;
+
+ /* dw1 */
+ uint32_t rsvd1:18;
+ uint32_t last_seg_udp_len:14;
+
+ /* dw2 */
+ uint32_t complete:1;
+ uint32_t event:1;
+ uint32_t crc:1;
+ uint32_t forward:1;
+ uint32_t rsvd2:1;
+ uint32_t rsvd3:1;
+ uint32_t ipcs:1;
+ uint32_t udpcs:1;
+ uint32_t tcpcs:1;
+ uint32_t lso:1;
+ uint32_t vlan:1;
+ uint32_t rsvd4:2;
+ uint32_t num_wqe:5;
+ uint32_t lso_mss:14;
+
+ /* dw3 */
+ uint32_t total_length:16;
+ uint32_t vlan_tag:16;
+#endif
+ } s;
+ uint32_t dw[4];
+ } u0;
+};
+
+/* NIC fragment WQE */
+struct oce_nic_frag_wqe {
+ union {
+ struct {
+ /* dw0 */
+ uint32_t frag_pa_hi;
+ /* dw1 */
+ uint32_t frag_pa_lo;
+ /* dw2 */
+ uint32_t rsvd0;
+ uint32_t frag_len;
+ } s;
+ uint32_t dw[4];
+ } u0;
+};
+
+/* Ethernet Tx Completion Descriptor */
+struct oce_nic_tx_cqe {
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ /* dw 0 */
+ uint32_t status:4;
+ uint32_t rsvd0:8;
+ uint32_t port:2;
+ uint32_t ct:2;
+ uint32_t wqe_index:16;
+
+ /* dw 1 */
+ uint32_t rsvd1:5;
+ uint32_t cast_enc:2;
+ uint32_t lso:1;
+ uint32_t nwh_bytes:8;
+ uint32_t user_bytes:16;
+
+ /* dw 2 */
+ uint32_t rsvd2;
+
+ /* dw 3 */
+ uint32_t valid:1;
+ uint32_t rsvd3:4;
+ uint32_t wq_id:11;
+ uint32_t num_pkts:16;
+#else
+ /* dw 0 */
+ uint32_t wqe_index:16;
+ uint32_t ct:2;
+ uint32_t port:2;
+ uint32_t rsvd0:8;
+ uint32_t status:4;
+
+ /* dw 1 */
+ uint32_t user_bytes:16;
+ uint32_t nwh_bytes:8;
+ uint32_t lso:1;
+ uint32_t cast_enc:2;
+ uint32_t rsvd1:5;
+ /* dw 2 */
+ uint32_t rsvd2;
+
+ /* dw 3 */
+ uint32_t num_pkts:16;
+ uint32_t wq_id:11;
+ uint32_t rsvd3:4;
+ uint32_t valid:1;
+#endif
+ } s;
+ uint32_t dw[4];
+ } u0;
+};
+#define WQ_CQE_VALID(_cqe) (_cqe->u0.dw[3])
+#define WQ_CQE_INVALIDATE(_cqe) (_cqe->u0.dw[3] = 0)
+
+/* Receive Queue Entry (RQE) */
+struct oce_nic_rqe {
+ union {
+ struct {
+ uint32_t frag_pa_hi;
+ uint32_t frag_pa_lo;
+ } s;
+ uint32_t dw[2];
+ } u0;
+};
+
+/* NIC Receive CQE */
+struct oce_nic_rx_cqe {
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ /* dw 0 */
+ uint32_t ip_options:1;
+ uint32_t port:1;
+ uint32_t pkt_size:14;
+ uint32_t vlan_tag:16;
+
+ /* dw 1 */
+ uint32_t num_fragments:3;
+ uint32_t switched:1;
+ uint32_t ct:2;
+ uint32_t frag_index:10;
+ uint32_t rsvd0:1;
+ uint32_t vlan_tag_present:1;
+ uint32_t mac_dst:6;
+ uint32_t ip_ver:1;
+ uint32_t l4_cksum_pass:1;
+ uint32_t ip_cksum_pass:1;
+ uint32_t udpframe:1;
+ uint32_t tcpframe:1;
+ uint32_t ipframe:1;
+ uint32_t rss_hp:1;
+ uint32_t error:1;
+
+ /* dw 2 */
+ uint32_t valid:1;
+ uint32_t hds_type:2;
+ uint32_t lro_pkt:1;
+ uint32_t rsvd4:1;
+ uint32_t hds_hdr_size:12;
+ uint32_t hds_hdr_frag_index:10;
+ uint32_t rss_bank:1;
+ uint32_t qnq:1;
+ uint32_t pkt_type:2;
+ uint32_t rss_flush:1;
+
+ /* dw 3 */
+ uint32_t rss_hash_value;
+#else
+ /* dw 0 */
+ uint32_t vlan_tag:16;
+ uint32_t pkt_size:14;
+ uint32_t port:1;
+ uint32_t ip_options:1;
+ /* dw 1 */
+ uint32_t error:1;
+ uint32_t rss_hp:1;
+ uint32_t ipframe:1;
+ uint32_t tcpframe:1;
+ uint32_t udpframe:1;
+ uint32_t ip_cksum_pass:1;
+ uint32_t l4_cksum_pass:1;
+ uint32_t ip_ver:1;
+ uint32_t mac_dst:6;
+ uint32_t vlan_tag_present:1;
+ uint32_t rsvd0:1;
+ uint32_t frag_index:10;
+ uint32_t ct:2;
+ uint32_t switched:1;
+ uint32_t num_fragments:3;
+
+ /* dw 2 */
+ uint32_t rss_flush:1;
+ uint32_t pkt_type:2;
+ uint32_t qnq:1;
+ uint32_t rss_bank:1;
+ uint32_t hds_hdr_frag_index:10;
+ uint32_t hds_hdr_size:12;
+ uint32_t rsvd4:1;
+ uint32_t lro_pkt:1;
+ uint32_t hds_type:2;
+ uint32_t valid:1;
+ /* dw 3 */
+ uint32_t rss_hash_value;
+#endif
+ } s;
+ uint32_t dw[4];
+ } u0;
+};
+/* NIC Receive CQE_v1 */
+struct oce_nic_rx_cqe_v1 {
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ /* dw 0 */
+ uint32_t ip_options:1;
+ uint32_t vlan_tag_present:1;
+ uint32_t pkt_size:14;
+ uint32_t vlan_tag:16;
+
+ /* dw 1 */
+ uint32_t num_fragments:3;
+ uint32_t switched:1;
+ uint32_t ct:2;
+ uint32_t frag_index:10;
+ uint32_t rsvd0:1;
+ uint32_t mac_dst:7;
+ uint32_t ip_ver:1;
+ uint32_t l4_cksum_pass:1;
+ uint32_t ip_cksum_pass:1;
+ uint32_t udpframe:1;
+ uint32_t tcpframe:1;
+ uint32_t ipframe:1;
+ uint32_t rss_hp:1;
+ uint32_t error:1;
+
+ /* dw 2 */
+ uint32_t valid:1;
+ uint32_t rsvd4:13;
+ uint32_t hds_hdr_size:
+ uint32_t hds_hdr_frag_index:8;
+ uint32_t vlantag:1;
+ uint32_t port:2;
+ uint32_t rss_bank:1;
+ uint32_t qnq:1;
+ uint32_t pkt_type:2;
+ uint32_t rss_flush:1;
+
+ /* dw 3 */
+ uint32_t rss_hash_value;
+ #else
+ /* dw 0 */
+ uint32_t vlan_tag:16;
+ uint32_t pkt_size:14;
+ uint32_t vlan_tag_present:1;
+ uint32_t ip_options:1;
+ /* dw 1 */
+ uint32_t error:1;
+ uint32_t rss_hp:1;
+ uint32_t ipframe:1;
+ uint32_t tcpframe:1;
+ uint32_t udpframe:1;
+ uint32_t ip_cksum_pass:1;
+ uint32_t l4_cksum_pass:1;
+ uint32_t ip_ver:1;
+ uint32_t mac_dst:7;
+ uint32_t rsvd0:1;
+ uint32_t frag_index:10;
+ uint32_t ct:2;
+ uint32_t switched:1;
+ uint32_t num_fragments:3;
+
+ /* dw 2 */
+ uint32_t rss_flush:1;
+ uint32_t pkt_type:2;
+ uint32_t qnq:1;
+ uint32_t rss_bank:1;
+ uint32_t port:2;
+ uint32_t vlantag:1;
+ uint32_t hds_hdr_frag_index:8;
+ uint32_t hds_hdr_size:2;
+ uint32_t rsvd4:13;
+ uint32_t valid:1;
+ /* dw 3 */
+ uint32_t rss_hash_value;
+#endif
+ } s;
+ uint32_t dw[4];
+ } u0;
+};
+
+#define RQ_CQE_VALID_MASK 0x80
+#define RQ_CQE_VALID(_cqe) (_cqe->u0.dw[2])
+#define RQ_CQE_INVALIDATE(_cqe) (_cqe->u0.dw[2] = 0)
+
+struct mbx_config_nic_promiscuous {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ uint16_t rsvd0;
+ uint8_t port1_promisc;
+ uint8_t port0_promisc;
+#else
+ uint8_t port0_promisc;
+ uint8_t port1_promisc;
+ uint16_t rsvd0;
+#endif
+ } req;
+
+ struct {
+ uint32_t rsvd0;
+ } rsp;
+ } params;
+};
+
+typedef union oce_wq_ctx_u {
+ uint32_t dw[17];
+ struct {
+#ifdef _BIG_ENDIAN
+ /* dw4 */
+ uint32_t dw4rsvd2:8;
+ uint32_t nic_wq_type:8;
+ uint32_t dw4rsvd1:8;
+ uint32_t num_pages:8;
+ /* dw5 */
+ uint32_t dw5rsvd2:12;
+ uint32_t wq_size:4;
+ uint32_t dw5rsvd1:16;
+ /* dw6 */
+ uint32_t valid:1;
+ uint32_t dw6rsvd1:31;
+ /* dw7 */
+ uint32_t dw7rsvd1:16;
+ uint32_t cq_id:16;
+#else
+ /* dw4 */
+ uint32_t num_pages:8;
+#if 0
+ uint32_t dw4rsvd1:8;
+#else
+/* PSP: this workaround is not documented: fill 0x01 for ulp_mask */
+ uint32_t ulp_mask:8;
+#endif
+ uint32_t nic_wq_type:8;
+ uint32_t dw4rsvd2:8;
+ /* dw5 */
+ uint32_t dw5rsvd1:16;
+ uint32_t wq_size:4;
+ uint32_t dw5rsvd2:12;
+ /* dw6 */
+ uint32_t dw6rsvd1:31;
+ uint32_t valid:1;
+ /* dw7 */
+ uint32_t cq_id:16;
+ uint32_t dw7rsvd1:16;
+#endif
+ /* dw8 - dw20 */
+ uint32_t dw8_20rsvd1[13];
+ } v0;
+ struct {
+#ifdef _BIG_ENDIAN
+ /* dw4 */
+ uint32_t dw4rsvd2:8;
+ uint32_t nic_wq_type:8;
+ uint32_t dw4rsvd1:8;
+ uint32_t num_pages:8;
+ /* dw5 */
+ uint32_t dw5rsvd2:12;
+ uint32_t wq_size:4;
+ uint32_t iface_id:16;
+ /* dw6 */
+ uint32_t valid:1;
+ uint32_t dw6rsvd1:31;
+ /* dw7 */
+ uint32_t dw7rsvd1:16;
+ uint32_t cq_id:16;
+#else
+ /* dw4 */
+ uint32_t num_pages:8;
+ uint32_t dw4rsvd1:8;
+ uint32_t nic_wq_type:8;
+ uint32_t dw4rsvd2:8;
+ /* dw5 */
+ uint32_t iface_id:16;
+ uint32_t wq_size:4;
+ uint32_t dw5rsvd2:12;
+ /* dw6 */
+ uint32_t dw6rsvd1:31;
+ uint32_t valid:1;
+ /* dw7 */
+ uint32_t cq_id:16;
+ uint32_t dw7rsvd1:16;
+#endif
+ /* dw8 - dw20 */
+ uint32_t dw8_20rsvd1[13];
+ } v1;
+} oce_wq_ctx_t;
+
+/**
+ * @brief [07] NIC_CREATE_WQ
+ * @note
+ * Lancer requires an InterfaceID to be specified with every WQ. This
+ * is the basis for NIC IOV where the Interface maps to a vPort and maps
+ * to both Tx and Rx sides.
+ */
+#define OCE_WQ_TYPE_FORWARDING 0x1 /* wq forwards pkts to TOE */
+#define OCE_WQ_TYPE_STANDARD 0x2 /* wq sends network pkts */
+struct mbx_create_nic_wq {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint8_t num_pages;
+ uint8_t ulp_num;
+ uint16_t nic_wq_type;
+ uint16_t if_id;
+ uint8_t wq_size;
+ uint8_t rsvd1;
+ uint32_t rsvd2;
+ uint16_t cq_id;
+ uint16_t rsvd3;
+ uint32_t rsvd4[13];
+ struct phys_addr pages[8];
+
+ } req;
+
+ struct {
+ uint16_t wq_id;
+ uint16_t rid;
+ uint32_t db_offset;
+ uint8_t tc_id;
+ uint8_t rsvd0[3];
+ } rsp;
+ } params;
+};
+
+/* [09] NIC_DELETE_WQ */
+struct mbx_delete_nic_wq {
+ /* dw0 - dw3 */
+ struct mbx_hdr hdr;
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ /* dw4 */
+ uint16_t rsvd0;
+ uint16_t wq_id;
+#else
+ /* dw4 */
+ uint16_t wq_id;
+ uint16_t rsvd0;
+#endif
+ } req;
+ struct {
+ uint32_t rsvd0;
+ } rsp;
+ } params;
+};
+
+
+
+struct mbx_create_nic_rq {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint16_t cq_id;
+ uint8_t frag_size;
+ uint8_t num_pages;
+ struct phys_addr pages[2];
+ uint32_t if_id;
+ uint16_t max_frame_size;
+ uint16_t page_size;
+ uint32_t is_rss_queue;
+ } req;
+
+ struct {
+ uint16_t rq_id;
+ uint8_t rss_cpuid;
+ uint8_t rsvd0;
+ } rsp;
+
+ } params;
+};
+
+
+
+/* [10] NIC_DELETE_RQ */
+struct mbx_delete_nic_rq {
+ /* dw0 - dw3 */
+ struct mbx_hdr hdr;
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ /* dw4 */
+ uint16_t bypass_flush;
+ uint16_t rq_id;
+#else
+ /* dw4 */
+ uint16_t rq_id;
+ uint16_t bypass_flush;
+#endif
+ } req;
+
+ struct {
+ /* dw4 */
+ uint32_t rsvd0;
+ } rsp;
+ } params;
+};
+
+
+
+
+struct oce_port_rxf_stats_v0 {
+ uint32_t rx_bytes_lsd; /* dword 0*/
+ uint32_t rx_bytes_msd; /* dword 1*/
+ uint32_t rx_total_frames; /* dword 2*/
+ uint32_t rx_unicast_frames; /* dword 3*/
+ uint32_t rx_multicast_frames; /* dword 4*/
+ uint32_t rx_broadcast_frames; /* dword 5*/
+ uint32_t rx_crc_errors; /* dword 6*/
+ uint32_t rx_alignment_symbol_errors; /* dword 7*/
+ uint32_t rx_pause_frames; /* dword 8*/
+ uint32_t rx_control_frames; /* dword 9*/
+ uint32_t rx_in_range_errors; /* dword 10*/
+ uint32_t rx_out_range_errors; /* dword 11*/
+ uint32_t rx_frame_too_long; /* dword 12*/
+ uint32_t rx_address_match_errors; /* dword 13*/
+ uint32_t rx_vlan_mismatch; /* dword 14*/
+ uint32_t rx_dropped_too_small; /* dword 15*/
+ uint32_t rx_dropped_too_short; /* dword 16*/
+ uint32_t rx_dropped_header_too_small; /* dword 17*/
+ uint32_t rx_dropped_tcp_length; /* dword 18*/
+ uint32_t rx_dropped_runt; /* dword 19*/
+ uint32_t rx_64_byte_packets; /* dword 20*/
+ uint32_t rx_65_127_byte_packets; /* dword 21*/
+ uint32_t rx_128_256_byte_packets; /* dword 22*/
+ uint32_t rx_256_511_byte_packets; /* dword 23*/
+ uint32_t rx_512_1023_byte_packets; /* dword 24*/
+ uint32_t rx_1024_1518_byte_packets; /* dword 25*/
+ uint32_t rx_1519_2047_byte_packets; /* dword 26*/
+ uint32_t rx_2048_4095_byte_packets; /* dword 27*/
+ uint32_t rx_4096_8191_byte_packets; /* dword 28*/
+ uint32_t rx_8192_9216_byte_packets; /* dword 29*/
+ uint32_t rx_ip_checksum_errs; /* dword 30*/
+ uint32_t rx_tcp_checksum_errs; /* dword 31*/
+ uint32_t rx_udp_checksum_errs; /* dword 32*/
+ uint32_t rx_non_rss_packets; /* dword 33*/
+ uint32_t rx_ipv4_packets; /* dword 34*/
+ uint32_t rx_ipv6_packets; /* dword 35*/
+ uint32_t rx_ipv4_bytes_lsd; /* dword 36*/
+ uint32_t rx_ipv4_bytes_msd; /* dword 37*/
+ uint32_t rx_ipv6_bytes_lsd; /* dword 38*/
+ uint32_t rx_ipv6_bytes_msd; /* dword 39*/
+ uint32_t rx_chute1_packets; /* dword 40*/
+ uint32_t rx_chute2_packets; /* dword 41*/
+ uint32_t rx_chute3_packets; /* dword 42*/
+ uint32_t rx_management_packets; /* dword 43*/
+ uint32_t rx_switched_unicast_packets; /* dword 44*/
+ uint32_t rx_switched_multicast_packets; /* dword 45*/
+ uint32_t rx_switched_broadcast_packets; /* dword 46*/
+ uint32_t tx_bytes_lsd; /* dword 47*/
+ uint32_t tx_bytes_msd; /* dword 48*/
+ uint32_t tx_unicastframes; /* dword 49*/
+ uint32_t tx_multicastframes; /* dword 50*/
+ uint32_t tx_broadcastframes; /* dword 51*/
+ uint32_t tx_pauseframes; /* dword 52*/
+ uint32_t tx_controlframes; /* dword 53*/
+ uint32_t tx_64_byte_packets; /* dword 54*/
+ uint32_t tx_65_127_byte_packets; /* dword 55*/
+ uint32_t tx_128_256_byte_packets; /* dword 56*/
+ uint32_t tx_256_511_byte_packets; /* dword 57*/
+ uint32_t tx_512_1023_byte_packets; /* dword 58*/
+ uint32_t tx_1024_1518_byte_packets; /* dword 59*/
+ uint32_t tx_1519_2047_byte_packets; /* dword 60*/
+ uint32_t tx_2048_4095_byte_packets; /* dword 61*/
+ uint32_t tx_4096_8191_byte_packets; /* dword 62*/
+ uint32_t tx_8192_9216_byte_packets; /* dword 63*/
+ uint32_t rxpp_fifo_overflow_drop; /* dword 64*/
+ uint32_t rx_input_fifo_overflow_drop; /* dword 65*/
+};
+
+
+struct oce_rxf_stats_v0 {
+ struct oce_port_rxf_stats_v0 port[2];
+ uint32_t rx_drops_no_pbuf; /* dword 132*/
+ uint32_t rx_drops_no_txpb; /* dword 133*/
+ uint32_t rx_drops_no_erx_descr; /* dword 134*/
+ uint32_t rx_drops_no_tpre_descr; /* dword 135*/
+ uint32_t management_rx_port_packets; /* dword 136*/
+ uint32_t management_rx_port_bytes; /* dword 137*/
+ uint32_t management_rx_port_pause_frames;/* dword 138*/
+ uint32_t management_rx_port_errors; /* dword 139*/
+ uint32_t management_tx_port_packets; /* dword 140*/
+ uint32_t management_tx_port_bytes; /* dword 141*/
+ uint32_t management_tx_port_pause; /* dword 142*/
+ uint32_t management_rx_port_rxfifo_overflow; /* dword 143*/
+ uint32_t rx_drops_too_many_frags; /* dword 144*/
+ uint32_t rx_drops_invalid_ring; /* dword 145*/
+ uint32_t forwarded_packets; /* dword 146*/
+ uint32_t rx_drops_mtu; /* dword 147*/
+ uint32_t rsvd0[7];
+ uint32_t port0_jabber_events;
+ uint32_t port1_jabber_events;
+ uint32_t rsvd1[6];
+};
+
+struct oce_port_rxf_stats_v1 {
+ uint32_t rsvd0[12];
+ uint32_t rx_crc_errors;
+ uint32_t rx_alignment_symbol_errors;
+ uint32_t rx_pause_frames;
+ uint32_t rx_priority_pause_frames;
+ uint32_t rx_control_frames;
+ uint32_t rx_in_range_errors;
+ uint32_t rx_out_range_errors;
+ uint32_t rx_frame_too_long;
+ uint32_t rx_address_match_errors;
+ uint32_t rx_dropped_too_small;
+ uint32_t rx_dropped_too_short;
+ uint32_t rx_dropped_header_too_small;
+ uint32_t rx_dropped_tcp_length;
+ uint32_t rx_dropped_runt;
+ uint32_t rsvd1[10];
+ uint32_t rx_ip_checksum_errs;
+ uint32_t rx_tcp_checksum_errs;
+ uint32_t rx_udp_checksum_errs;
+ uint32_t rsvd2[7];
+ uint32_t rx_switched_unicast_packets;
+ uint32_t rx_switched_multicast_packets;
+ uint32_t rx_switched_broadcast_packets;
+ uint32_t rsvd3[3];
+ uint32_t tx_pauseframes;
+ uint32_t tx_priority_pauseframes;
+ uint32_t tx_controlframes;
+ uint32_t rsvd4[10];
+ uint32_t rxpp_fifo_overflow_drop;
+ uint32_t rx_input_fifo_overflow_drop;
+ uint32_t pmem_fifo_overflow_drop;
+ uint32_t jabber_events;
+ uint32_t rsvd5[3];
+};
+
+
+struct oce_rxf_stats_v1 {
+ struct oce_port_rxf_stats_v1 port[4];
+ uint32_t rsvd0[2];
+ uint32_t rx_drops_no_pbuf;
+ uint32_t rx_drops_no_txpb;
+ uint32_t rx_drops_no_erx_descr;
+ uint32_t rx_drops_no_tpre_descr;
+ uint32_t rsvd1[6];
+ uint32_t rx_drops_too_many_frags;
+ uint32_t rx_drops_invalid_ring;
+ uint32_t forwarded_packets;
+ uint32_t rx_drops_mtu;
+ uint32_t rsvd2[14];
+};
+
+struct oce_erx_stats_v1 {
+ uint32_t rx_drops_no_fragments[68];
+ uint32_t rsvd[4];
+};
+
+
+struct oce_erx_stats_v0 {
+ uint32_t rx_drops_no_fragments[44];
+ uint32_t rsvd[4];
+};
+
+struct oce_pmem_stats {
+ uint32_t eth_red_drops;
+ uint32_t rsvd[5];
+};
+
+struct oce_hw_stats_v1 {
+ struct oce_rxf_stats_v1 rxf;
+ uint32_t rsvd0[OCE_TXP_SW_SZ];
+ struct oce_erx_stats_v1 erx;
+ struct oce_pmem_stats pmem;
+ uint32_t rsvd1[18];
+};
+
+struct oce_hw_stats_v0 {
+ struct oce_rxf_stats_v0 rxf;
+ uint32_t rsvd[48];
+ struct oce_erx_stats_v0 erx;
+ struct oce_pmem_stats pmem;
+};
+
+struct mbx_get_nic_stats_v0 {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t rsvd0;
+ } req;
+
+ union {
+ struct oce_hw_stats_v0 stats;
+ } rsp;
+ } params;
+};
+
+struct mbx_get_nic_stats {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ uint32_t rsvd0;
+ } req;
+
+ struct {
+ struct oce_hw_stats_v1 stats;
+ } rsp;
+ } params;
+};
+
+
+/* [18(0x12)] NIC_GET_PPORT_STATS */
+struct pport_stats {
+ uint64_t tx_pkts;
+ uint64_t tx_unicast_pkts;
+ uint64_t tx_multicast_pkts;
+ uint64_t tx_broadcast_pkts;
+ uint64_t tx_bytes;
+ uint64_t tx_unicast_bytes;
+ uint64_t tx_multicast_bytes;
+ uint64_t tx_broadcast_bytes;
+ uint64_t tx_discards;
+ uint64_t tx_errors;
+ uint64_t tx_pause_frames;
+ uint64_t tx_pause_on_frames;
+ uint64_t tx_pause_off_frames;
+ uint64_t tx_internal_mac_errors;
+ uint64_t tx_control_frames;
+ uint64_t tx_pkts_64_bytes;
+ uint64_t tx_pkts_65_to_127_bytes;
+ uint64_t tx_pkts_128_to_255_bytes;
+ uint64_t tx_pkts_256_to_511_bytes;
+ uint64_t tx_pkts_512_to_1023_bytes;
+ uint64_t tx_pkts_1024_to_1518_bytes;
+ uint64_t tx_pkts_1519_to_2047_bytes;
+ uint64_t tx_pkts_2048_to_4095_bytes;
+ uint64_t tx_pkts_4096_to_8191_bytes;
+ uint64_t tx_pkts_8192_to_9216_bytes;
+ uint64_t tx_lso_pkts;
+ uint64_t rx_pkts;
+ uint64_t rx_unicast_pkts;
+ uint64_t rx_multicast_pkts;
+ uint64_t rx_broadcast_pkts;
+ uint64_t rx_bytes;
+ uint64_t rx_unicast_bytes;
+ uint64_t rx_multicast_bytes;
+ uint64_t rx_broadcast_bytes;
+ uint32_t rx_unknown_protos;
+ uint32_t reserved_word69;
+ uint64_t rx_discards;
+ uint64_t rx_errors;
+ uint64_t rx_crc_errors;
+ uint64_t rx_alignment_errors;
+ uint64_t rx_symbol_errors;
+ uint64_t rx_pause_frames;
+ uint64_t rx_pause_on_frames;
+ uint64_t rx_pause_off_frames;
+ uint64_t rx_frames_too_long;
+ uint64_t rx_internal_mac_errors;
+ uint32_t rx_undersize_pkts;
+ uint32_t rx_oversize_pkts;
+ uint32_t rx_fragment_pkts;
+ uint32_t rx_jabbers;
+ uint64_t rx_control_frames;
+ uint64_t rx_control_frames_unknown_opcode;
+ uint32_t rx_in_range_errors;
+ uint32_t rx_out_of_range_errors;
+ uint32_t rx_address_match_errors;
+ uint32_t rx_vlan_mismatch_errors;
+ uint32_t rx_dropped_too_small;
+ uint32_t rx_dropped_too_short;
+ uint32_t rx_dropped_header_too_small;
+ uint32_t rx_dropped_invalid_tcp_length;
+ uint32_t rx_dropped_runt;
+ uint32_t rx_ip_checksum_errors;
+ uint32_t rx_tcp_checksum_errors;
+ uint32_t rx_udp_checksum_errors;
+ uint32_t rx_non_rss_pkts;
+ uint64_t reserved_word111;
+ uint64_t rx_ipv4_pkts;
+ uint64_t rx_ipv6_pkts;
+ uint64_t rx_ipv4_bytes;
+ uint64_t rx_ipv6_bytes;
+ uint64_t rx_nic_pkts;
+ uint64_t rx_tcp_pkts;
+ uint64_t rx_iscsi_pkts;
+ uint64_t rx_management_pkts;
+ uint64_t rx_switched_unicast_pkts;
+ uint64_t rx_switched_multicast_pkts;
+ uint64_t rx_switched_broadcast_pkts;
+ uint64_t num_forwards;
+ uint32_t rx_fifo_overflow;
+ uint32_t rx_input_fifo_overflow;
+ uint64_t rx_drops_too_many_frags;
+ uint32_t rx_drops_invalid_queue;
+ uint32_t reserved_word141;
+ uint64_t rx_drops_mtu;
+ uint64_t rx_pkts_64_bytes;
+ uint64_t rx_pkts_65_to_127_bytes;
+ uint64_t rx_pkts_128_to_255_bytes;
+ uint64_t rx_pkts_256_to_511_bytes;
+ uint64_t rx_pkts_512_to_1023_bytes;
+ uint64_t rx_pkts_1024_to_1518_bytes;
+ uint64_t rx_pkts_1519_to_2047_bytes;
+ uint64_t rx_pkts_2048_to_4095_bytes;
+ uint64_t rx_pkts_4096_to_8191_bytes;
+ uint64_t rx_pkts_8192_to_9216_bytes;
+};
+
+struct mbx_get_pport_stats {
+ /* dw0 - dw3 */
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ /* dw4 */
+#ifdef _BIG_ENDIAN
+ uint32_t reset_stats:8;
+ uint32_t rsvd0:8;
+ uint32_t port_number:16;
+#else
+ uint32_t port_number:16;
+ uint32_t rsvd0:8;
+ uint32_t reset_stats:8;
+#endif
+ } req;
+
+ union {
+ struct pport_stats pps;
+ uint32_t pport_stats[164 - 4 + 1];
+ } rsp;
+ } params;
+};
+
+/* [19(0x13)] NIC_GET_VPORT_STATS */
+struct vport_stats {
+ uint64_t tx_pkts;
+ uint64_t tx_unicast_pkts;
+ uint64_t tx_multicast_pkts;
+ uint64_t tx_broadcast_pkts;
+ uint64_t tx_bytes;
+ uint64_t tx_unicast_bytes;
+ uint64_t tx_multicast_bytes;
+ uint64_t tx_broadcast_bytes;
+ uint64_t tx_discards;
+ uint64_t tx_errors;
+ uint64_t tx_pkts_64_bytes;
+ uint64_t tx_pkts_65_to_127_bytes;
+ uint64_t tx_pkts_128_to_255_bytes;
+ uint64_t tx_pkts_256_to_511_bytes;
+ uint64_t tx_pkts_512_to_1023_bytes;
+ uint64_t tx_pkts_1024_to_1518_bytes;
+ uint64_t tx_pkts_1519_to_9699_bytes;
+ uint64_t tx_pkts_over_9699_bytes;
+ uint64_t rx_pkts;
+ uint64_t rx_unicast_pkts;
+ uint64_t rx_multicast_pkts;
+ uint64_t rx_broadcast_pkts;
+ uint64_t rx_bytes;
+ uint64_t rx_unicast_bytes;
+ uint64_t rx_multicast_bytes;
+ uint64_t rx_broadcast_bytes;
+ uint64_t rx_discards;
+ uint64_t rx_errors;
+ uint64_t rx_pkts_64_bytes;
+ uint64_t rx_pkts_65_to_127_bytes;
+ uint64_t rx_pkts_128_to_255_bytes;
+ uint64_t rx_pkts_256_to_511_bytes;
+ uint64_t rx_pkts_512_to_1023_bytes;
+ uint64_t rx_pkts_1024_to_1518_bytes;
+ uint64_t rx_pkts_1519_to_9699_bytes;
+ uint64_t rx_pkts_gt_9699_bytes;
+};
+struct mbx_get_vport_stats {
+ /* dw0 - dw3 */
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ /* dw4 */
+#ifdef _BIG_ENDIAN
+ uint32_t reset_stats:8;
+ uint32_t rsvd0:8;
+ uint32_t vport_number:16;
+#else
+ uint32_t vport_number:16;
+ uint32_t rsvd0:8;
+ uint32_t reset_stats:8;
+#endif
+ } req;
+
+ union {
+ struct vport_stats vps;
+ uint32_t vport_stats[75 - 4 + 1];
+ } rsp;
+ } params;
+};
+
+/**
+ * @brief [20(0x14)] NIC_GET_QUEUE_STATS
+ * The significant difference between vPort and Queue statistics is
+ * the packet byte counters.
+ */
+struct queue_stats {
+ uint64_t packets;
+ uint64_t bytes;
+ uint64_t errors;
+ uint64_t drops;
+ uint64_t buffer_errors; /* rsvd when tx */
+};
+
+#define QUEUE_TYPE_WQ 0
+#define QUEUE_TYPE_RQ 1
+#define QUEUE_TYPE_HDS_RQ 1 /* same as RQ */
+
+struct mbx_get_queue_stats {
+ /* dw0 - dw3 */
+ struct mbx_hdr hdr;
+ union {
+ struct {
+ /* dw4 */
+#ifdef _BIG_ENDIAN
+ uint32_t reset_stats:8;
+ uint32_t queue_type:8;
+ uint32_t queue_id:16;
+#else
+ uint32_t queue_id:16;
+ uint32_t queue_type:8;
+ uint32_t reset_stats:8;
+#endif
+ } req;
+
+ union {
+ struct queue_stats qs;
+ uint32_t queue_stats[13 - 4 + 1];
+ } rsp;
+ } params;
+};
+
+
+/* [01] NIC_CONFIG_RSS */
+#define OCE_HASH_TBL_SZ 10
+#define OCE_CPU_TBL_SZ 128
+#define OCE_FLUSH 1 /* RSS flush completion per CQ port */
+struct mbx_config_nic_rss {
+ struct mbx_hdr hdr;
+ union {
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t if_id;
+ uint16_t cpu_tbl_sz_log2;
+ uint16_t enable_rss;
+ uint32_t hash[OCE_HASH_TBL_SZ];
+ uint8_t cputable[OCE_CPU_TBL_SZ];
+ uint8_t rsvd[3];
+ uint8_t flush;
+#else
+ uint32_t if_id;
+ uint16_t enable_rss;
+ uint16_t cpu_tbl_sz_log2;
+ uint32_t hash[OCE_HASH_TBL_SZ];
+ uint8_t cputable[OCE_CPU_TBL_SZ];
+ uint8_t flush;
+ uint8_t rsvd[3];
+#endif
+ } req;
+ struct {
+ uint8_t rsvd[3];
+ uint8_t rss_bank;
+ } rsp;
+ } params;
+};
+
+
+#pragma pack()
+
+
+typedef uint32_t oce_stat_t; /* statistic counter */
+
+enum OCE_RXF_PORT_STATS {
+ RXF_RX_BYTES_LSD,
+ RXF_RX_BYTES_MSD,
+ RXF_RX_TOTAL_FRAMES,
+ RXF_RX_UNICAST_FRAMES,
+ RXF_RX_MULTICAST_FRAMES,
+ RXF_RX_BROADCAST_FRAMES,
+ RXF_RX_CRC_ERRORS,
+ RXF_RX_ALIGNMENT_SYMBOL_ERRORS,
+ RXF_RX_PAUSE_FRAMES,
+ RXF_RX_CONTROL_FRAMES,
+ RXF_RX_IN_RANGE_ERRORS,
+ RXF_RX_OUT_RANGE_ERRORS,
+ RXF_RX_FRAME_TOO_LONG,
+ RXF_RX_ADDRESS_MATCH_ERRORS,
+ RXF_RX_VLAN_MISMATCH,
+ RXF_RX_DROPPED_TOO_SMALL,
+ RXF_RX_DROPPED_TOO_SHORT,
+ RXF_RX_DROPPED_HEADER_TOO_SMALL,
+ RXF_RX_DROPPED_TCP_LENGTH,
+ RXF_RX_DROPPED_RUNT,
+ RXF_RX_64_BYTE_PACKETS,
+ RXF_RX_65_127_BYTE_PACKETS,
+ RXF_RX_128_256_BYTE_PACKETS,
+ RXF_RX_256_511_BYTE_PACKETS,
+ RXF_RX_512_1023_BYTE_PACKETS,
+ RXF_RX_1024_1518_BYTE_PACKETS,
+ RXF_RX_1519_2047_BYTE_PACKETS,
+ RXF_RX_2048_4095_BYTE_PACKETS,
+ RXF_RX_4096_8191_BYTE_PACKETS,
+ RXF_RX_8192_9216_BYTE_PACKETS,
+ RXF_RX_IP_CHECKSUM_ERRS,
+ RXF_RX_TCP_CHECKSUM_ERRS,
+ RXF_RX_UDP_CHECKSUM_ERRS,
+ RXF_RX_NON_RSS_PACKETS,
+ RXF_RX_IPV4_PACKETS,
+ RXF_RX_IPV6_PACKETS,
+ RXF_RX_IPV4_BYTES_LSD,
+ RXF_RX_IPV4_BYTES_MSD,
+ RXF_RX_IPV6_BYTES_LSD,
+ RXF_RX_IPV6_BYTES_MSD,
+ RXF_RX_CHUTE1_PACKETS,
+ RXF_RX_CHUTE2_PACKETS,
+ RXF_RX_CHUTE3_PACKETS,
+ RXF_RX_MANAGEMENT_PACKETS,
+ RXF_RX_SWITCHED_UNICAST_PACKETS,
+ RXF_RX_SWITCHED_MULTICAST_PACKETS,
+ RXF_RX_SWITCHED_BROADCAST_PACKETS,
+ RXF_TX_BYTES_LSD,
+ RXF_TX_BYTES_MSD,
+ RXF_TX_UNICAST_FRAMES,
+ RXF_TX_MULTICAST_FRAMES,
+ RXF_TX_BROADCAST_FRAMES,
+ RXF_TX_PAUSE_FRAMES,
+ RXF_TX_CONTROL_FRAMES,
+ RXF_TX_64_BYTE_PACKETS,
+ RXF_TX_65_127_BYTE_PACKETS,
+ RXF_TX_128_256_BYTE_PACKETS,
+ RXF_TX_256_511_BYTE_PACKETS,
+ RXF_TX_512_1023_BYTE_PACKETS,
+ RXF_TX_1024_1518_BYTE_PACKETS,
+ RXF_TX_1519_2047_BYTE_PACKETS,
+ RXF_TX_2048_4095_BYTE_PACKETS,
+ RXF_TX_4096_8191_BYTE_PACKETS,
+ RXF_TX_8192_9216_BYTE_PACKETS,
+ RXF_RX_FIFO_OVERFLOW,
+ RXF_RX_INPUT_FIFO_OVERFLOW,
+ RXF_PORT_STATS_N_WORDS
+};
+
+enum OCE_RXF_ADDL_STATS {
+ RXF_RX_DROPS_NO_PBUF,
+ RXF_RX_DROPS_NO_TXPB,
+ RXF_RX_DROPS_NO_ERX_DESCR,
+ RXF_RX_DROPS_NO_TPRE_DESCR,
+ RXF_MANAGEMENT_RX_PORT_PACKETS,
+ RXF_MANAGEMENT_RX_PORT_BYTES,
+ RXF_MANAGEMENT_RX_PORT_PAUSE_FRAMES,
+ RXF_MANAGEMENT_RX_PORT_ERRORS,
+ RXF_MANAGEMENT_TX_PORT_PACKETS,
+ RXF_MANAGEMENT_TX_PORT_BYTES,
+ RXF_MANAGEMENT_TX_PORT_PAUSE,
+ RXF_MANAGEMENT_RX_PORT_RXFIFO_OVERFLOW,
+ RXF_RX_DROPS_TOO_MANY_FRAGS,
+ RXF_RX_DROPS_INVALID_RING,
+ RXF_FORWARDED_PACKETS,
+ RXF_RX_DROPS_MTU,
+ RXF_ADDL_STATS_N_WORDS
+};
+
+enum OCE_TX_CHUTE_PORT_STATS {
+ CTPT_XMT_IPV4_PKTS,
+ CTPT_XMT_IPV4_LSD,
+ CTPT_XMT_IPV4_MSD,
+ CTPT_XMT_IPV6_PKTS,
+ CTPT_XMT_IPV6_LSD,
+ CTPT_XMT_IPV6_MSD,
+ CTPT_REXMT_IPV4_PKTs,
+ CTPT_REXMT_IPV4_LSD,
+ CTPT_REXMT_IPV4_MSD,
+ CTPT_REXMT_IPV6_PKTs,
+ CTPT_REXMT_IPV6_LSD,
+ CTPT_REXMT_IPV6_MSD,
+ CTPT_N_WORDS,
+};
+
+enum OCE_RX_ERR_STATS {
+ RX_DROPS_NO_FRAGMENTS_0,
+ RX_DROPS_NO_FRAGMENTS_1,
+ RX_DROPS_NO_FRAGMENTS_2,
+ RX_DROPS_NO_FRAGMENTS_3,
+ RX_DROPS_NO_FRAGMENTS_4,
+ RX_DROPS_NO_FRAGMENTS_5,
+ RX_DROPS_NO_FRAGMENTS_6,
+ RX_DROPS_NO_FRAGMENTS_7,
+ RX_DROPS_NO_FRAGMENTS_8,
+ RX_DROPS_NO_FRAGMENTS_9,
+ RX_DROPS_NO_FRAGMENTS_10,
+ RX_DROPS_NO_FRAGMENTS_11,
+ RX_DROPS_NO_FRAGMENTS_12,
+ RX_DROPS_NO_FRAGMENTS_13,
+ RX_DROPS_NO_FRAGMENTS_14,
+ RX_DROPS_NO_FRAGMENTS_15,
+ RX_DROPS_NO_FRAGMENTS_16,
+ RX_DROPS_NO_FRAGMENTS_17,
+ RX_DROPS_NO_FRAGMENTS_18,
+ RX_DROPS_NO_FRAGMENTS_19,
+ RX_DROPS_NO_FRAGMENTS_20,
+ RX_DROPS_NO_FRAGMENTS_21,
+ RX_DROPS_NO_FRAGMENTS_22,
+ RX_DROPS_NO_FRAGMENTS_23,
+ RX_DROPS_NO_FRAGMENTS_24,
+ RX_DROPS_NO_FRAGMENTS_25,
+ RX_DROPS_NO_FRAGMENTS_26,
+ RX_DROPS_NO_FRAGMENTS_27,
+ RX_DROPS_NO_FRAGMENTS_28,
+ RX_DROPS_NO_FRAGMENTS_29,
+ RX_DROPS_NO_FRAGMENTS_30,
+ RX_DROPS_NO_FRAGMENTS_31,
+ RX_DROPS_NO_FRAGMENTS_32,
+ RX_DROPS_NO_FRAGMENTS_33,
+ RX_DROPS_NO_FRAGMENTS_34,
+ RX_DROPS_NO_FRAGMENTS_35,
+ RX_DROPS_NO_FRAGMENTS_36,
+ RX_DROPS_NO_FRAGMENTS_37,
+ RX_DROPS_NO_FRAGMENTS_38,
+ RX_DROPS_NO_FRAGMENTS_39,
+ RX_DROPS_NO_FRAGMENTS_40,
+ RX_DROPS_NO_FRAGMENTS_41,
+ RX_DROPS_NO_FRAGMENTS_42,
+ RX_DROPS_NO_FRAGMENTS_43,
+ RX_DEBUG_WDMA_SENT_HOLD,
+ RX_DEBUG_WDMA_PBFREE_SENT_HOLD,
+ RX_DEBUG_WDMA_0B_PBFREE_SENT_HOLD,
+ RX_DEBUG_PMEM_PBUF_DEALLOC,
+ RX_ERRORS_N_WORDS
+};
+
+enum OCE_PMEM_ERR_STATS {
+ PMEM_ETH_RED_DROPS,
+ PMEM_LRO_RED_DROPS,
+ PMEM_ULP0_RED_DROPS,
+ PMEM_ULP1_RED_DROPS,
+ PMEM_GLOBAL_RED_DROPS,
+ PMEM_ERRORS_N_WORDS
+};
+
+/**
+ * @brief Statistics for a given Physical Port
+ * These satisfy all the required BE2 statistics and also the
+ * following MIB objects:
+ *
+ * RFC 2863 - The Interfaces Group MIB
+ * RFC 2819 - Remote Network Monitoring Management Information Base (RMON)
+ * RFC 3635 - Managed Objects for the Ethernet-like Interface Types
+ * RFC 4502 - Remote Network Monitoring Mgmt Information Base Ver-2 (RMON2)
+ *
+ */
+enum OCE_PPORT_STATS {
+ PPORT_TX_PKTS = 0,
+ PPORT_TX_UNICAST_PKTS = 2,
+ PPORT_TX_MULTICAST_PKTS = 4,
+ PPORT_TX_BROADCAST_PKTS = 6,
+ PPORT_TX_BYTES = 8,
+ PPORT_TX_UNICAST_BYTES = 10,
+ PPORT_TX_MULTICAST_BYTES = 12,
+ PPORT_TX_BROADCAST_BYTES = 14,
+ PPORT_TX_DISCARDS = 16,
+ PPORT_TX_ERRORS = 18,
+ PPORT_TX_PAUSE_FRAMES = 20,
+ PPORT_TX_PAUSE_ON_FRAMES = 22,
+ PPORT_TX_PAUSE_OFF_FRAMES = 24,
+ PPORT_TX_INTERNAL_MAC_ERRORS = 26,
+ PPORT_TX_CONTROL_FRAMES = 28,
+ PPORT_TX_PKTS_64_BYTES = 30,
+ PPORT_TX_PKTS_65_TO_127_BYTES = 32,
+ PPORT_TX_PKTS_128_TO_255_BYTES = 34,
+ PPORT_TX_PKTS_256_TO_511_BYTES = 36,
+ PPORT_TX_PKTS_512_TO_1023_BYTES = 38,
+ PPORT_TX_PKTS_1024_TO_1518_BYTES = 40,
+ PPORT_TX_PKTS_1519_TO_2047_BYTES = 42,
+ PPORT_TX_PKTS_2048_TO_4095_BYTES = 44,
+ PPORT_TX_PKTS_4096_TO_8191_BYTES = 46,
+ PPORT_TX_PKTS_8192_TO_9216_BYTES = 48,
+ PPORT_TX_LSO_PKTS = 50,
+ PPORT_RX_PKTS = 52,
+ PPORT_RX_UNICAST_PKTS = 54,
+ PPORT_RX_MULTICAST_PKTS = 56,
+ PPORT_RX_BROADCAST_PKTS = 58,
+ PPORT_RX_BYTES = 60,
+ PPORT_RX_UNICAST_BYTES = 62,
+ PPORT_RX_MULTICAST_BYTES = 64,
+ PPORT_RX_BROADCAST_BYTES = 66,
+ PPORT_RX_UNKNOWN_PROTOS = 68,
+ PPORT_RESERVED_WORD69 = 69,
+ PPORT_RX_DISCARDS = 70,
+ PPORT_RX_ERRORS = 72,
+ PPORT_RX_CRC_ERRORS = 74,
+ PPORT_RX_ALIGNMENT_ERRORS = 76,
+ PPORT_RX_SYMBOL_ERRORS = 78,
+ PPORT_RX_PAUSE_FRAMES = 80,
+ PPORT_RX_PAUSE_ON_FRAMES = 82,
+ PPORT_RX_PAUSE_OFF_FRAMES = 84,
+ PPORT_RX_FRAMES_TOO_LONG = 86,
+ PPORT_RX_INTERNAL_MAC_ERRORS = 88,
+ PPORT_RX_UNDERSIZE_PKTS = 90,
+ PPORT_RX_OVERSIZE_PKTS = 91,
+ PPORT_RX_FRAGMENT_PKTS = 92,
+ PPORT_RX_JABBERS = 93,
+ PPORT_RX_CONTROL_FRAMES = 94,
+ PPORT_RX_CONTROL_FRAMES_UNK_OPCODE = 96,
+ PPORT_RX_IN_RANGE_ERRORS = 98,
+ PPORT_RX_OUT_OF_RANGE_ERRORS = 99,
+ PPORT_RX_ADDRESS_MATCH_ERRORS = 100,
+ PPORT_RX_VLAN_MISMATCH_ERRORS = 101,
+ PPORT_RX_DROPPED_TOO_SMALL = 102,
+ PPORT_RX_DROPPED_TOO_SHORT = 103,
+ PPORT_RX_DROPPED_HEADER_TOO_SMALL = 104,
+ PPORT_RX_DROPPED_INVALID_TCP_LENGTH = 105,
+ PPORT_RX_DROPPED_RUNT = 106,
+ PPORT_RX_IP_CHECKSUM_ERRORS = 107,
+ PPORT_RX_TCP_CHECKSUM_ERRORS = 108,
+ PPORT_RX_UDP_CHECKSUM_ERRORS = 109,
+ PPORT_RX_NON_RSS_PKTS = 110,
+ PPORT_RESERVED_WORD111 = 111,
+ PPORT_RX_IPV4_PKTS = 112,
+ PPORT_RX_IPV6_PKTS = 114,
+ PPORT_RX_IPV4_BYTES = 116,
+ PPORT_RX_IPV6_BYTES = 118,
+ PPORT_RX_NIC_PKTS = 120,
+ PPORT_RX_TCP_PKTS = 122,
+ PPORT_RX_ISCSI_PKTS = 124,
+ PPORT_RX_MANAGEMENT_PKTS = 126,
+ PPORT_RX_SWITCHED_UNICAST_PKTS = 128,
+ PPORT_RX_SWITCHED_MULTICAST_PKTS = 130,
+ PPORT_RX_SWITCHED_BROADCAST_PKTS = 132,
+ PPORT_NUM_FORWARDS = 134,
+ PPORT_RX_FIFO_OVERFLOW = 136,
+ PPORT_RX_INPUT_FIFO_OVERFLOW = 137,
+ PPORT_RX_DROPS_TOO_MANY_FRAGS = 138,
+ PPORT_RX_DROPS_INVALID_QUEUE = 140,
+ PPORT_RESERVED_WORD141 = 141,
+ PPORT_RX_DROPS_MTU = 142,
+ PPORT_RX_PKTS_64_BYTES = 144,
+ PPORT_RX_PKTS_65_TO_127_BYTES = 146,
+ PPORT_RX_PKTS_128_TO_255_BYTES = 148,
+ PPORT_RX_PKTS_256_TO_511_BYTES = 150,
+ PPORT_RX_PKTS_512_TO_1023_BYTES = 152,
+ PPORT_RX_PKTS_1024_TO_1518_BYTES = 154,
+ PPORT_RX_PKTS_1519_TO_2047_BYTES = 156,
+ PPORT_RX_PKTS_2048_TO_4095_BYTES = 158,
+ PPORT_RX_PKTS_4096_TO_8191_BYTES = 160,
+ PPORT_RX_PKTS_8192_TO_9216_BYTES = 162,
+ PPORT_N_WORDS = 164
+};
+
+/**
+ * @brief Statistics for a given Virtual Port (vPort)
+ * The following describes the vPort statistics satisfying
+ * requirements of Linux/VMWare netdev statistics and
+ * Microsoft Windows Statistics along with other Operating Systems.
+ */
+enum OCE_VPORT_STATS {
+ VPORT_TX_PKTS = 0,
+ VPORT_TX_UNICAST_PKTS = 2,
+ VPORT_TX_MULTICAST_PKTS = 4,
+ VPORT_TX_BROADCAST_PKTS = 6,
+ VPORT_TX_BYTES = 8,
+ VPORT_TX_UNICAST_BYTES = 10,
+ VPORT_TX_MULTICAST_BYTES = 12,
+ VPORT_TX_BROADCAST_BYTES = 14,
+ VPORT_TX_DISCARDS = 16,
+ VPORT_TX_ERRORS = 18,
+ VPORT_TX_PKTS_64_BYTES = 20,
+ VPORT_TX_PKTS_65_TO_127_BYTES = 22,
+ VPORT_TX_PKTS_128_TO_255_BYTES = 24,
+ VPORT_TX_PKTS_256_TO_511_BYTES = 26,
+ VPORT_TX_PKTS_512_TO_1023_BYTEs = 28,
+ VPORT_TX_PKTS_1024_TO_1518_BYTEs = 30,
+ VPORT_TX_PKTS_1519_TO_9699_BYTEs = 32,
+ VPORT_TX_PKTS_OVER_9699_BYTES = 34,
+ VPORT_RX_PKTS = 36,
+ VPORT_RX_UNICAST_PKTS = 38,
+ VPORT_RX_MULTICAST_PKTS = 40,
+ VPORT_RX_BROADCAST_PKTS = 42,
+ VPORT_RX_BYTES = 44,
+ VPORT_RX_UNICAST_BYTES = 46,
+ VPORT_RX_MULTICAST_BYTES = 48,
+ VPORT_RX_BROADCAST_BYTES = 50,
+ VPORT_RX_DISCARDS = 52,
+ VPORT_RX_ERRORS = 54,
+ VPORT_RX_PKTS_64_BYTES = 56,
+ VPORT_RX_PKTS_65_TO_127_BYTES = 58,
+ VPORT_RX_PKTS_128_TO_255_BYTES = 60,
+ VPORT_RX_PKTS_256_TO_511_BYTES = 62,
+ VPORT_RX_PKTS_512_TO_1023_BYTEs = 64,
+ VPORT_RX_PKTS_1024_TO_1518_BYTEs = 66,
+ VPORT_RX_PKTS_1519_TO_9699_BYTEs = 68,
+ VPORT_RX_PKTS_OVER_9699_BYTES = 70,
+ VPORT_N_WORDS = 72
+};
+
+/**
+ * @brief Statistics for a given queue (NIC WQ, RQ, or HDS RQ)
+ * This set satisfies requirements of VMQare NetQueue and Microsoft VMQ
+ */
+enum OCE_QUEUE_TX_STATS {
+ QUEUE_TX_PKTS = 0,
+ QUEUE_TX_BYTES = 2,
+ QUEUE_TX_ERRORS = 4,
+ QUEUE_TX_DROPS = 6,
+ QUEUE_TX_N_WORDS = 8
+};
+
+enum OCE_QUEUE_RX_STATS {
+ QUEUE_RX_PKTS = 0,
+ QUEUE_RX_BYTES = 2,
+ QUEUE_RX_ERRORS = 4,
+ QUEUE_RX_DROPS = 6,
+ QUEUE_RX_BUFFER_ERRORS = 8,
+ QUEUE_RX_N_WORDS = 10
+};
+
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/oce/oce_if.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/oce/oce_if.c Fri Mar 02 17:36:33 2012 +0200
@@ -0,0 +1,2024 @@
+/*-
+ * Copyright (C) 2012 Emulex
+ * 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.
+ *
+ * 3. Neither the name of the Emulex Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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.
+ *
+ * Contact Information:
+ * freebsd-drivers at emulex.com
+ *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
+ */
+
+/* $FreeBSD: head/sys/dev/oce/oce_if.c 231879 2012-02-17 13:55:17Z luigi $ */
+
+#include "opt_inet6.h"
+#include "opt_inet.h"
+
+#include "oce_if.h"
+
+
+/* Driver entry points prototypes */
+static int oce_probe(device_t dev);
+static int oce_attach(device_t dev);
+static int oce_detach(device_t dev);
+static int oce_shutdown(device_t dev);
+static int oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data);
+static void oce_init(void *xsc);
+static int oce_multiq_start(struct ifnet *ifp, struct mbuf *m);
+static void oce_multiq_flush(struct ifnet *ifp);
+
+/* Driver interrupt routines protypes */
+static void oce_intr(void *arg, int pending);
+static int oce_setup_intr(POCE_SOFTC sc);
+static int oce_fast_isr(void *arg);
+static int oce_alloc_intr(POCE_SOFTC sc, int vector,
+ void (*isr) (void *arg, int pending));
+
+/* Media callbacks prototypes */
+static void oce_media_status(struct ifnet *ifp, struct ifmediareq *req);
+static int oce_media_change(struct ifnet *ifp);
+
+/* Transmit routines prototypes */
+static int oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index);
+static void oce_tx_restart(POCE_SOFTC sc, struct oce_wq *wq);
+static void oce_tx_complete(struct oce_wq *wq, uint32_t wqe_idx,
+ uint32_t status);
+static int oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m,
+ struct oce_wq *wq);
+
+/* Receive routines prototypes */
+static void oce_discard_rx_comp(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe);
+static int oce_cqe_vtp_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe);
+static int oce_cqe_portid_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe);
+static void oce_rx(struct oce_rq *rq, uint32_t rqe_idx,
+ struct oce_nic_rx_cqe *cqe);
+
+/* Helper function prototypes in this file */
+static int oce_attach_ifp(POCE_SOFTC sc);
+static void oce_add_vlan(void *arg, struct ifnet *ifp, uint16_t vtag);
+static void oce_del_vlan(void *arg, struct ifnet *ifp, uint16_t vtag);
+static int oce_vid_config(POCE_SOFTC sc);
+static void oce_mac_addr_set(POCE_SOFTC sc);
+static int oce_handle_passthrough(struct ifnet *ifp, caddr_t data);
+static void oce_local_timer(void *arg);
+static void oce_if_deactivate(POCE_SOFTC sc);
+static void oce_if_activate(POCE_SOFTC sc);
+static void setup_max_queues_want(POCE_SOFTC sc);
+static void update_queues_got(POCE_SOFTC sc);
+static void process_link_state(POCE_SOFTC sc,
+ struct oce_async_cqe_link_state *acqe);
+
+
+/* IP specific */
+#if defined(INET6) || defined(INET)
+static int oce_init_lro(POCE_SOFTC sc);
+static void oce_rx_flush_lro(struct oce_rq *rq);
+static struct mbuf * oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp);
+#endif
+
+static device_method_t oce_dispatch[] = {
+ DEVMETHOD(device_probe, oce_probe),
+ DEVMETHOD(device_attach, oce_attach),
+ DEVMETHOD(device_detach, oce_detach),
+ DEVMETHOD(device_shutdown, oce_shutdown),
+ {0, 0}
+};
+
+static driver_t oce_driver = {
+ "oce",
+ oce_dispatch,
+ sizeof(OCE_SOFTC)
+};
+static devclass_t oce_devclass;
+
+
+DRIVER_MODULE(oce, pci, oce_driver, oce_devclass, 0, 0);
+MODULE_DEPEND(oce, pci, 1, 1, 1);
+MODULE_DEPEND(oce, ether, 1, 1, 1);
+MODULE_VERSION(oce, 1);
+
+
+/* global vars */
+const char component_revision[32] = {"///" COMPONENT_REVISION "///"};
+
+/* Module capabilites and parameters */
+uint32_t oce_max_rsp_handled = OCE_MAX_RSP_HANDLED;
+uint32_t oce_enable_rss = OCE_MODCAP_RSS;
+
+
+TUNABLE_INT("hw.oce.max_rsp_handled", &oce_max_rsp_handled);
+TUNABLE_INT("hw.oce.enable_rss", &oce_enable_rss);
+
+
+/* Supported devices table */
+static uint32_t supportedDevices[] = {
+ (PCI_VENDOR_SERVERENGINES << 16) | PCI_PRODUCT_BE2,
+ (PCI_VENDOR_SERVERENGINES << 16) | PCI_PRODUCT_BE3,
+ (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_BE3,
+ (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_XE201,
+ (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_XE201_VF,
+};
+
+
+
+
+/*****************************************************************************
+ * Driver entry points functions *
+ *****************************************************************************/
+
+static int
+oce_probe(device_t dev)
+{
+ uint16_t vendor = 0;
+ uint16_t device = 0;
+ int i = 0;
+ char str[256] = {0};
+ POCE_SOFTC sc;
+
+ sc = device_get_softc(dev);
+ bzero(sc, sizeof(OCE_SOFTC));
+ sc->dev = dev;
+
+ vendor = pci_get_vendor(dev);
+ device = pci_get_device(dev);
+
+ for (i = 0; i < (sizeof(supportedDevices) / sizeof(uint32_t)); i++) {
+ if (vendor == ((supportedDevices[i] >> 16) & 0xffff)) {
+ if (device == (supportedDevices[i] & 0xffff)) {
+ sprintf(str, "%s:%s", "Emulex CNA NIC function",
+ component_revision);
+ device_set_desc_copy(dev, str);
+
+ switch (device) {
+ case PCI_PRODUCT_BE2:
+ sc->flags |= OCE_FLAGS_BE2;
+ break;
+ case PCI_PRODUCT_BE3:
+ sc->flags |= OCE_FLAGS_BE3;
+ break;
+ case PCI_PRODUCT_XE201:
+ case PCI_PRODUCT_XE201_VF:
+ sc->flags |= OCE_FLAGS_XE201;
+ break;
+ default:
+ return ENXIO;
+ }
+ return BUS_PROBE_DEFAULT;
+ }
+ }
+ }
+
+ return ENXIO;
+}
+
+
+static int
+oce_attach(device_t dev)
+{
+ POCE_SOFTC sc;
+ int rc = 0;
+
+ sc = device_get_softc(dev);
+
+ rc = oce_hw_pci_alloc(sc);
+ if (rc)
+ return rc;
+
+ sc->rss_enable = oce_enable_rss;
+ sc->tx_ring_size = OCE_TX_RING_SIZE;
+ sc->rx_ring_size = OCE_RX_RING_SIZE;
+ sc->rq_frag_size = OCE_RQ_BUF_SIZE;
+ sc->flow_control = OCE_DEFAULT_FLOW_CONTROL;
+ sc->promisc = OCE_DEFAULT_PROMISCUOUS;
+
+ LOCK_CREATE(&sc->bmbx_lock, "Mailbox_lock");
+ LOCK_CREATE(&sc->dev_lock, "Device_lock");
+
+ /* initialise the hardware */
+ rc = oce_hw_init(sc);
+ if (rc)
+ goto pci_res_free;
+
+ setup_max_queues_want(sc);
+
+ rc = oce_setup_intr(sc);
+ if (rc)
+ goto mbox_free;
+
+ rc = oce_queue_init_all(sc);
+ if (rc)
+ goto intr_free;
+
+ rc = oce_attach_ifp(sc);
+ if (rc)
+ goto queues_free;
+
+#if defined(INET6) || defined(INET)
+ rc = oce_init_lro(sc);
+ if (rc)
+ goto ifp_free;
+#endif
+
+ rc = oce_hw_start(sc);
+ if (rc)
+ goto lro_free;;
+
+ sc->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
+ oce_add_vlan, sc, EVENTHANDLER_PRI_FIRST);
+ sc->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
+ oce_del_vlan, sc, EVENTHANDLER_PRI_FIRST);
+
+ rc = oce_stats_init(sc);
+ if (rc)
+ goto vlan_free;
+
+ oce_add_sysctls(sc);
+
+ callout_init(&sc->timer, CALLOUT_MPSAFE);
+ rc = callout_reset(&sc->timer, 2 * hz, oce_local_timer, sc);
+ if (rc)
+ goto stats_free;
+#ifdef DEV_NETMAP
+#endif /* DEV_NETMAP */
+
+ return 0;
+
+stats_free:
+ callout_drain(&sc->timer);
+ oce_stats_free(sc);
+vlan_free:
+ if (sc->vlan_attach)
+ EVENTHANDLER_DEREGISTER(vlan_config, sc->vlan_attach);
+ if (sc->vlan_detach)
+ EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vlan_detach);
+ oce_hw_intr_disable(sc);
+lro_free:
+#if defined(INET6) || defined(INET)
+ oce_free_lro(sc);
+ifp_free:
+#endif
+ ether_ifdetach(sc->ifp);
+ if_free(sc->ifp);
+queues_free:
+ oce_queue_release_all(sc);
+intr_free:
+ oce_intr_free(sc);
+mbox_free:
+ oce_dma_free(sc, &sc->bsmbx);
+pci_res_free:
+ oce_hw_pci_free(sc);
+ LOCK_DESTROY(&sc->dev_lock);
+ LOCK_DESTROY(&sc->bmbx_lock);
+ return rc;
+
+}
+
+
+static int
+oce_detach(device_t dev)
+{
+ POCE_SOFTC sc = device_get_softc(dev);
+
+ LOCK(&sc->dev_lock);
+ oce_if_deactivate(sc);
+ UNLOCK(&sc->dev_lock);
+
+ callout_drain(&sc->timer);
+
+ if (sc->vlan_attach != NULL)
+ EVENTHANDLER_DEREGISTER(vlan_config, sc->vlan_attach);
+ if (sc->vlan_detach != NULL)
+ EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vlan_detach);
+
+ ether_ifdetach(sc->ifp);
+
+ if_free(sc->ifp);
+
+ oce_hw_shutdown(sc);
+
+ bus_generic_detach(dev);
+
+ return 0;
+}
+
+
+static int
+oce_shutdown(device_t dev)
+{
+ int rc;
+
+ rc = oce_detach(dev);
+
+ return rc;
+}
+
+
+static int
+oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
+{
+ struct ifreq *ifr = (struct ifreq *)data;
+ POCE_SOFTC sc = ifp->if_softc;
+ int rc = 0;
+ uint32_t u;
+
+ switch (command) {
+
+ case SIOCGIFMEDIA:
+ rc = ifmedia_ioctl(ifp, ifr, &sc->media, command);
+ break;
+
+ case SIOCSIFMTU:
+ if (ifr->ifr_mtu > OCE_MAX_MTU)
+ rc = EINVAL;
+ else
+ ifp->if_mtu = ifr->ifr_mtu;
+ break;
+
+ case SIOCSIFFLAGS:
+ if (ifp->if_flags & IFF_UP) {
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ oce_init(sc);
+ }
+ device_printf(sc->dev, "Interface Up\n");
+ } else {
+ LOCK(&sc->dev_lock);
+
+ sc->ifp->if_drv_flags &=
+ ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ oce_if_deactivate(sc);
+
+ UNLOCK(&sc->dev_lock);
+
+ device_printf(sc->dev, "Interface Down\n");
+ }
+
+ if ((ifp->if_flags & IFF_PROMISC) && !sc->promisc) {
+ sc->promisc = TRUE;
+ oce_rxf_set_promiscuous(sc, sc->promisc);
+ } else if (!(ifp->if_flags & IFF_PROMISC) && sc->promisc) {
+ sc->promisc = FALSE;
+ oce_rxf_set_promiscuous(sc, sc->promisc);
+ }
+
+ break;
+
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ rc = oce_hw_update_multicast(sc);
+ if (rc)
+ device_printf(sc->dev,
+ "Update multicast address failed\n");
+ break;
+
+ case SIOCSIFCAP:
+ u = ifr->ifr_reqcap ^ ifp->if_capenable;
+
+ if (u & IFCAP_TXCSUM) {
+ ifp->if_capenable ^= IFCAP_TXCSUM;
+ ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP);
+
+ if (IFCAP_TSO & ifp->if_capenable &&
+ !(IFCAP_TXCSUM & ifp->if_capenable)) {
+ ifp->if_capenable &= ~IFCAP_TSO;
+ ifp->if_hwassist &= ~CSUM_TSO;
+ if_printf(ifp,
+ "TSO disabled due to -txcsum.\n");
+ }
+ }
+
+ if (u & IFCAP_RXCSUM)
+ ifp->if_capenable ^= IFCAP_RXCSUM;
+
+ if (u & IFCAP_TSO4) {
+ ifp->if_capenable ^= IFCAP_TSO4;
+
+ if (IFCAP_TSO & ifp->if_capenable) {
+ if (IFCAP_TXCSUM & ifp->if_capenable)
+ ifp->if_hwassist |= CSUM_TSO;
+ else {
+ ifp->if_capenable &= ~IFCAP_TSO;
+ ifp->if_hwassist &= ~CSUM_TSO;
+ if_printf(ifp,
+ "Enable txcsum first.\n");
+ rc = EAGAIN;
+ }
+ } else
+ ifp->if_hwassist &= ~CSUM_TSO;
+ }
+
+ if (u & IFCAP_VLAN_HWTAGGING)
+ ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
+
+ if (u & IFCAP_VLAN_HWFILTER) {
+ ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
+ oce_vid_config(sc);
+ }
+#if defined(INET6) || defined(INET)
+ if (u & IFCAP_LRO)
+ ifp->if_capenable ^= IFCAP_LRO;
+#endif
+
+ break;
+
+ case SIOCGPRIVATE_0:
+ rc = oce_handle_passthrough(ifp, data);
+ break;
+ default:
+ rc = ether_ioctl(ifp, command, data);
+ break;
+ }
+
+ return rc;
+}
+
+
+static void
+oce_init(void *arg)
+{
+ POCE_SOFTC sc = arg;
+
+ LOCK(&sc->dev_lock);
+
+ if (sc->ifp->if_flags & IFF_UP) {
+ oce_if_deactivate(sc);
+ oce_if_activate(sc);
+ }
+
+ UNLOCK(&sc->dev_lock);
+
+}
+
+
+static int
+oce_multiq_start(struct ifnet *ifp, struct mbuf *m)
+{
+ POCE_SOFTC sc = ifp->if_softc;
+ struct oce_wq *wq = NULL;
+ int queue_index = 0;
+ int status = 0;
+
+ if ((m->m_flags & M_FLOWID) != 0)
+ queue_index = m->m_pkthdr.flowid % sc->nwqs;
+
+ wq = sc->wq[queue_index];
+
+ if (TRY_LOCK(&wq->tx_lock)) {
+ status = oce_multiq_transmit(ifp, m, wq);
+ UNLOCK(&wq->tx_lock);
+ } else {
+ status = drbr_enqueue(ifp, wq->br, m);
+ }
+ return status;
+
+}
+
+
+static void
+oce_multiq_flush(struct ifnet *ifp)
+{
+ POCE_SOFTC sc = ifp->if_softc;
+ struct mbuf *m;
+ int i = 0;
+
+ for (i = 0; i < sc->nwqs; i++) {
+ while ((m = buf_ring_dequeue_sc(sc->wq[i]->br)) != NULL)
+ m_freem(m);
+ }
+ if_qflush(ifp);
+}
+
+
+
+/*****************************************************************************
+ * Driver interrupt routines functions *
+ *****************************************************************************/
+
+static void
+oce_intr(void *arg, int pending)
+{
+
+ POCE_INTR_INFO ii = (POCE_INTR_INFO) arg;
+ POCE_SOFTC sc = ii->sc;
+ struct oce_eq *eq = ii->eq;
+ struct oce_eqe *eqe;
+ struct oce_cq *cq = NULL;
+ int i, num_eqes = 0;
+
+
+ bus_dmamap_sync(eq->ring->dma.tag, eq->ring->dma.map,
+ BUS_DMASYNC_POSTWRITE);
+ do {
+ eqe = RING_GET_CONSUMER_ITEM_VA(eq->ring, struct oce_eqe);
+ if (eqe->evnt == 0)
+ break;
+ eqe->evnt = 0;
+ bus_dmamap_sync(eq->ring->dma.tag, eq->ring->dma.map,
+ BUS_DMASYNC_POSTWRITE);
+ RING_GET(eq->ring, 1);
+ num_eqes++;
+
+ } while (TRUE);
+
+ if (!num_eqes)
+ goto eq_arm; /* Spurious */
+
+ /* Clear EQ entries, but dont arm */
+ oce_arm_eq(sc, eq->eq_id, num_eqes, FALSE, FALSE);
+
+ /* Process TX, RX and MCC. But dont arm CQ*/
+ for (i = 0; i < eq->cq_valid; i++) {
+ cq = eq->cq[i];
+ (*cq->cq_handler)(cq->cb_arg);
+ }
+
+ /* Arm all cqs connected to this EQ */
+ for (i = 0; i < eq->cq_valid; i++) {
+ cq = eq->cq[i];
+ oce_arm_cq(sc, cq->cq_id, 0, TRUE);
+ }
+
+eq_arm:
+ oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE);
+ return;
+}
+
+
+static int
+oce_setup_intr(POCE_SOFTC sc)
+{
+ int rc = 0, use_intx = 0;
+ int vector = 0, req_vectors = 0;
+
+ if (sc->rss_enable)
+ req_vectors = MAX((sc->nrqs - 1), sc->nwqs);
+ else
+ req_vectors = 1;
+
+ if (sc->flags & OCE_FLAGS_MSIX_CAPABLE) {
+ sc->intr_count = req_vectors;
+ rc = pci_alloc_msix(sc->dev, &sc->intr_count);
+ if (rc != 0) {
+ use_intx = 1;
+ pci_release_msi(sc->dev);
+ } else
+ sc->flags |= OCE_FLAGS_USING_MSIX;
+ } else
+ use_intx = 1;
+
+ if (use_intx)
+ sc->intr_count = 1;
+
+ /* Scale number of queues based on intr we got */
+ update_queues_got(sc);
+
+ if (use_intx) {
+ device_printf(sc->dev, "Using legacy interrupt\n");
+ rc = oce_alloc_intr(sc, vector, oce_intr);
+ if (rc)
+ goto error;
+ } else {
+ for (; vector < sc->intr_count; vector++) {
+ rc = oce_alloc_intr(sc, vector, oce_intr);
+ if (rc)
+ goto error;
+ }
+ }
+
+ return 0;
+error:
+ oce_intr_free(sc);
+ return rc;
+}
+
+
+static int
+oce_fast_isr(void *arg)
+{
+ POCE_INTR_INFO ii = (POCE_INTR_INFO) arg;
+ POCE_SOFTC sc = ii->sc;
+
+ if (ii->eq == NULL)
+ return FILTER_STRAY;
+
+ oce_arm_eq(sc, ii->eq->eq_id, 0, FALSE, TRUE);
+
+ taskqueue_enqueue_fast(ii->tq, &ii->task);
+
+ return FILTER_HANDLED;
+}
+
+
+static int
+oce_alloc_intr(POCE_SOFTC sc, int vector, void (*isr) (void *arg, int pending))
+{
+ POCE_INTR_INFO ii = &sc->intrs[vector];
+ int rc = 0, rr;
+
+ if (vector >= OCE_MAX_EQ)
+ return (EINVAL);
+
+ /* Set the resource id for the interrupt.
+ * MSIx is vector + 1 for the resource id,
+ * INTx is 0 for the resource id.
+ */
+ if (sc->flags & OCE_FLAGS_USING_MSIX)
+ rr = vector + 1;
+ else
+ rr = 0;
+ ii->intr_res = bus_alloc_resource_any(sc->dev,
+ SYS_RES_IRQ,
+ &rr, RF_ACTIVE|RF_SHAREABLE);
+ ii->irq_rr = rr;
+ if (ii->intr_res == NULL) {
+ device_printf(sc->dev,
+ "Could not allocate interrupt\n");
+ rc = ENXIO;
+ return rc;
+ }
+
+ TASK_INIT(&ii->task, 0, isr, ii);
+ ii->vector = vector;
+ sprintf(ii->task_name, "oce_task[%d]", ii->vector);
+ ii->tq = taskqueue_create_fast(ii->task_name,
+ M_NOWAIT,
+ taskqueue_thread_enqueue,
+ &ii->tq);
+ taskqueue_start_threads(&ii->tq, 1, PI_NET, "%s taskq",
+ device_get_nameunit(sc->dev));
+
+ ii->sc = sc;
+ rc = bus_setup_intr(sc->dev,
+ ii->intr_res,
+ INTR_TYPE_NET,
+ oce_fast_isr, NULL, ii, &ii->tag);
+ return rc;
+
+}
+
+
+void
+oce_intr_free(POCE_SOFTC sc)
+{
+ int i = 0;
+
+ for (i = 0; i < sc->intr_count; i++) {
+
+ if (sc->intrs[i].tag != NULL)
+ bus_teardown_intr(sc->dev, sc->intrs[i].intr_res,
+ sc->intrs[i].tag);
+ if (sc->intrs[i].tq != NULL)
+ taskqueue_free(sc->intrs[i].tq);
+
+ if (sc->intrs[i].intr_res != NULL)
+ bus_release_resource(sc->dev, SYS_RES_IRQ,
+ sc->intrs[i].irq_rr,
+ sc->intrs[i].intr_res);
+ sc->intrs[i].tag = NULL;
+ sc->intrs[i].intr_res = NULL;
+ }
+
+ if (sc->flags & OCE_FLAGS_USING_MSIX)
+ pci_release_msi(sc->dev);
+
+}
+
+
+
+/******************************************************************************
+* Media callbacks functions *
+******************************************************************************/
+
+static void
+oce_media_status(struct ifnet *ifp, struct ifmediareq *req)
+{
+ POCE_SOFTC sc = (POCE_SOFTC) ifp->if_softc;
+
+
+ req->ifm_status = IFM_AVALID;
+ req->ifm_active = IFM_ETHER;
+
+ if (sc->link_status == 1)
+ req->ifm_status |= IFM_ACTIVE;
+ else
+ return;
+
+ switch (sc->link_speed) {
+ case 1: /* 10 Mbps */
+ req->ifm_active |= IFM_10_T | IFM_FDX;
+ sc->speed = 10;
+ break;
+ case 2: /* 100 Mbps */
+ req->ifm_active |= IFM_100_TX | IFM_FDX;
+ sc->speed = 100;
+ break;
+ case 3: /* 1 Gbps */
+ req->ifm_active |= IFM_1000_T | IFM_FDX;
+ sc->speed = 1000;
+ break;
+ case 4: /* 10 Gbps */
+ req->ifm_active |= IFM_10G_SR | IFM_FDX;
+ sc->speed = 10000;
+ break;
+ }
+
+ return;
+}
+
+
+int
+oce_media_change(struct ifnet *ifp)
+{
+ return 0;
+}
+
+
+
+
+/*****************************************************************************
+ * Transmit routines functions *
+ *****************************************************************************/
+
+static int
+oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index)
+{
+ int rc = 0, i, retry_cnt = 0;
+ bus_dma_segment_t segs[OCE_MAX_TX_ELEMENTS];
+ struct mbuf *m, *m_temp;
+ struct oce_wq *wq = sc->wq[wq_index];
+ struct oce_packet_desc *pd;
+ uint32_t out;
+ struct oce_nic_hdr_wqe *nichdr;
+ struct oce_nic_frag_wqe *nicfrag;
+ int num_wqes;
+ uint32_t reg_value;
+
+ m = *mpp;
+ if (!m)
+ return EINVAL;
+
+ if (!(m->m_flags & M_PKTHDR)) {
+ rc = ENXIO;
+ goto free_ret;
+ }
+
+ if (m->m_pkthdr.csum_flags & CSUM_TSO) {
+ /* consolidate packet buffers for TSO/LSO segment offload */
+#if defined(INET6) || defined(INET)
+ m = oce_tso_setup(sc, mpp);
+#else
+ m = NULL;
+#endif
+ if (m == NULL) {
+ rc = ENXIO;
+ goto free_ret;
+ }
+ }
+
+ out = wq->packets_out + 1;
+ if (out == OCE_WQ_PACKET_ARRAY_SIZE)
+ out = 0;
+ if (out == wq->packets_in)
+ return EBUSY;
+
+ pd = &wq->pckts[wq->packets_out];
+retry:
+ rc = bus_dmamap_load_mbuf_sg(wq->tag,
+ pd->map,
+ m, segs, &pd->nsegs, BUS_DMA_NOWAIT);
+ if (rc == 0) {
+ num_wqes = pd->nsegs + 1;
+ if (IS_BE(sc)) {
+ /*Dummy required only for BE3.*/
+ if (num_wqes & 1)
+ num_wqes++;
+ }
+ if (num_wqes >= RING_NUM_FREE(wq->ring)) {
+ bus_dmamap_unload(wq->tag, pd->map);
+ return EBUSY;
+ }
+
+ bus_dmamap_sync(wq->tag, pd->map, BUS_DMASYNC_PREWRITE);
+ pd->mbuf = m;
+ wq->packets_out = out;
+
+ nichdr =
+ RING_GET_PRODUCER_ITEM_VA(wq->ring, struct oce_nic_hdr_wqe);
+ nichdr->u0.dw[0] = 0;
+ nichdr->u0.dw[1] = 0;
+ nichdr->u0.dw[2] = 0;
+ nichdr->u0.dw[3] = 0;
+
+ nichdr->u0.s.complete = 1;
+ nichdr->u0.s.event = 1;
+ nichdr->u0.s.crc = 1;
+ nichdr->u0.s.forward = 0;
+ nichdr->u0.s.ipcs = (m->m_pkthdr.csum_flags & CSUM_IP) ? 1 : 0;
+ nichdr->u0.s.udpcs =
+ (m->m_pkthdr.csum_flags & CSUM_UDP) ? 1 : 0;
+ nichdr->u0.s.tcpcs =
+ (m->m_pkthdr.csum_flags & CSUM_TCP) ? 1 : 0;
+ nichdr->u0.s.num_wqe = num_wqes;
+ nichdr->u0.s.total_length = m->m_pkthdr.len;
+ if (m->m_flags & M_VLANTAG) {
+ nichdr->u0.s.vlan = 1; /*Vlan present*/
+ nichdr->u0.s.vlan_tag = m->m_pkthdr.ether_vtag;
+ }
+ if (m->m_pkthdr.csum_flags & CSUM_TSO) {
+ if (m->m_pkthdr.tso_segsz) {
+ nichdr->u0.s.lso = 1;
+ nichdr->u0.s.lso_mss = m->m_pkthdr.tso_segsz;
+ }
+ if (!IS_BE(sc))
+ nichdr->u0.s.ipcs = 1;
+ }
+
+ RING_PUT(wq->ring, 1);
+ wq->ring->num_used++;
+
+ for (i = 0; i < pd->nsegs; i++) {
+ nicfrag =
+ RING_GET_PRODUCER_ITEM_VA(wq->ring,
+ struct oce_nic_frag_wqe);
+ nicfrag->u0.s.rsvd0 = 0;
+ nicfrag->u0.s.frag_pa_hi = ADDR_HI(segs[i].ds_addr);
+ nicfrag->u0.s.frag_pa_lo = ADDR_LO(segs[i].ds_addr);
+ nicfrag->u0.s.frag_len = segs[i].ds_len;
+ pd->wqe_idx = wq->ring->pidx;
+ RING_PUT(wq->ring, 1);
+ wq->ring->num_used++;
+ }
+ if (num_wqes > (pd->nsegs + 1)) {
+ nicfrag =
+ RING_GET_PRODUCER_ITEM_VA(wq->ring,
+ struct oce_nic_frag_wqe);
+ nicfrag->u0.dw[0] = 0;
+ nicfrag->u0.dw[1] = 0;
+ nicfrag->u0.dw[2] = 0;
+ nicfrag->u0.dw[3] = 0;
+ pd->wqe_idx = wq->ring->pidx;
+ RING_PUT(wq->ring, 1);
+ wq->ring->num_used++;
+ pd->nsegs++;
+ }
+
+ sc->ifp->if_opackets++;
+ wq->tx_stats.tx_reqs++;
+ wq->tx_stats.tx_wrbs += num_wqes;
+ wq->tx_stats.tx_bytes += m->m_pkthdr.len;
+ wq->tx_stats.tx_pkts++;
+
+ bus_dmamap_sync(wq->ring->dma.tag, wq->ring->dma.map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ reg_value = (num_wqes << 16) | wq->wq_id;
+ OCE_WRITE_REG32(sc, db, PD_TXULP_DB, reg_value);
+
+ } else if (rc == EFBIG) {
+ if (retry_cnt == 0) {
+ m_temp = m_defrag(m, M_DONTWAIT);
+ if (m_temp == NULL)
+ goto free_ret;
+ m = m_temp;
+ *mpp = m_temp;
+ retry_cnt = retry_cnt + 1;
+ goto retry;
+ } else
+ goto free_ret;
+ } else if (rc == ENOMEM)
+ return rc;
+ else
+ goto free_ret;
+
+ return 0;
+
+free_ret:
+ m_freem(*mpp);
+ *mpp = NULL;
+ return rc;
+}
+
+
+static void
+oce_tx_complete(struct oce_wq *wq, uint32_t wqe_idx, uint32_t status)
+{
+ uint32_t in;
+ struct oce_packet_desc *pd;
+ POCE_SOFTC sc = (POCE_SOFTC) wq->parent;
+ struct mbuf *m;
+
+ if (wq->packets_out == wq->packets_in)
+ device_printf(sc->dev, "WQ transmit descriptor missing\n");
+
+ in = wq->packets_in + 1;
+ if (in == OCE_WQ_PACKET_ARRAY_SIZE)
+ in = 0;
+
+ pd = &wq->pckts[wq->packets_in];
+ wq->packets_in = in;
+ wq->ring->num_used -= (pd->nsegs + 1);
+ bus_dmamap_sync(wq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(wq->tag, pd->map);
+
+ m = pd->mbuf;
+ m_freem(m);
+ pd->mbuf = NULL;
+
+ if (sc->ifp->if_drv_flags & IFF_DRV_OACTIVE) {
+ if (wq->ring->num_used < (wq->ring->num_items / 2)) {
+ sc->ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE);
+ oce_tx_restart(sc, wq);
+ }
+ }
+}
+
+
+static void
+oce_tx_restart(POCE_SOFTC sc, struct oce_wq *wq)
+{
+
+ if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) != IFF_DRV_RUNNING)
+ return;
+
+#if __FreeBSD_version >= 800000
+ if (!drbr_empty(sc->ifp, wq->br))
+#else
+ if (!IFQ_DRV_IS_EMPTY(&sc->ifp->if_snd))
+#endif
+ taskqueue_enqueue_fast(taskqueue_swi, &wq->txtask);
+
+}
+
+
+#if defined(INET6) || defined(INET)
+static struct mbuf *
+oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp)
+{
+ struct mbuf *m;
+#ifdef INET
+ struct ip *ip;
+#endif
+#ifdef INET6
+ struct ip6_hdr *ip6;
+#endif
+ struct ether_vlan_header *eh;
+ struct tcphdr *th;
+ uint16_t etype;
+ int total_len = 0, ehdrlen = 0;
+
+ m = *mpp;
+
+ if (M_WRITABLE(m) == 0) {
+ m = m_dup(*mpp, M_DONTWAIT);
+ if (!m)
+ return NULL;
+ m_freem(*mpp);
+ *mpp = m;
+ }
+
+ eh = mtod(m, struct ether_vlan_header *);
+ if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
+ etype = ntohs(eh->evl_proto);
+ ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
+ } else {
+ etype = ntohs(eh->evl_encap_proto);
+ ehdrlen = ETHER_HDR_LEN;
+ }
+
+ switch (etype) {
+#ifdef INET
+ case ETHERTYPE_IP:
+ ip = (struct ip *)(m->m_data + ehdrlen);
+ if (ip->ip_p != IPPROTO_TCP)
+ return NULL;
+ th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
+
+ total_len = ehdrlen + (ip->ip_hl << 2) + (th->th_off << 2);
+ break;
+#endif
+#ifdef INET6
+ case ETHERTYPE_IPV6:
+ ip6 = (struct ip6_hdr *)(m->m_data + ehdrlen);
+ if (ip6->ip6_nxt != IPPROTO_TCP)
+ return NULL;
+ th = (struct tcphdr *)((caddr_t)ip6 + sizeof(struct ip6_hdr));
+
+ total_len = ehdrlen + sizeof(struct ip6_hdr) + (th->th_off << 2);
+ break;
+#endif
+ default:
+ return NULL;
+ }
+
+ m = m_pullup(m, total_len);
+ if (!m)
+ return NULL;
+ *mpp = m;
+ return m;
+
+}
+#endif /* INET6 || INET */
+
+void
+oce_tx_task(void *arg, int npending)
+{
+ struct oce_wq *wq = arg;
+ POCE_SOFTC sc = wq->parent;
+ struct ifnet *ifp = sc->ifp;
+ int rc = 0;
+
+#if __FreeBSD_version >= 800000
+ if (TRY_LOCK(&wq->tx_lock)) {
+ rc = oce_multiq_transmit(ifp, NULL, wq);
+ if (rc) {
+ device_printf(sc->dev,
+ "TX[%d] restart failed\n", wq->queue_index);
+ }
+ UNLOCK(&wq->tx_lock);
+ }
+#else
+ oce_start(ifp);
+#endif
+
+}
+
+
+void
+oce_start(struct ifnet *ifp)
+{
+ POCE_SOFTC sc = ifp->if_softc;
+ struct mbuf *m;
+ int rc = 0;
+ int def_q = 0; /* Defualt tx queue is 0*/
+
+ if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING)
+ return;
+
+ do {
+ IF_DEQUEUE(&sc->ifp->if_snd, m);
+ if (m == NULL)
+ break;
+
+ LOCK(&sc->wq[def_q]->tx_lock);
+ rc = oce_tx(sc, &m, def_q);
+ UNLOCK(&sc->wq[def_q]->tx_lock);
+ if (rc) {
+ if (m != NULL) {
+ sc->wq[def_q]->tx_stats.tx_stops ++;
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ IFQ_DRV_PREPEND(&ifp->if_snd, m);
+ m = NULL;
+ }
+ break;
+ }
+ if (m != NULL)
+ ETHER_BPF_MTAP(ifp, m);
+
+ } while (TRUE);
+
+ return;
+}
+
+
+/* Handle the Completion Queue for transmit */
+uint16_t
+oce_wq_handler(void *arg)
+{
+ struct oce_wq *wq = (struct oce_wq *)arg;
+ POCE_SOFTC sc = wq->parent;
+ struct oce_cq *cq = wq->cq;
+ struct oce_nic_tx_cqe *cqe;
+ int num_cqes = 0;
+
+ LOCK(&wq->tx_lock);
+ bus_dmamap_sync(cq->ring->dma.tag,
+ cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
+ cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe);
+ while (cqe->u0.dw[3]) {
+ DW_SWAP((uint32_t *) cqe, sizeof(oce_wq_cqe));
+
+ wq->ring->cidx = cqe->u0.s.wqe_index + 1;
+ if (wq->ring->cidx >= wq->ring->num_items)
+ wq->ring->cidx -= wq->ring->num_items;
+
+ oce_tx_complete(wq, cqe->u0.s.wqe_index, cqe->u0.s.status);
+ wq->tx_stats.tx_compl++;
+ cqe->u0.dw[3] = 0;
+ RING_GET(cq->ring, 1);
+ bus_dmamap_sync(cq->ring->dma.tag,
+ cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
+ cqe =
+ RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe);
+ num_cqes++;
+ }
+
+ if (num_cqes)
+ oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
+ UNLOCK(&wq->tx_lock);
+
+ return 0;
+}
+
+
+static int
+oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq)
+{
+ POCE_SOFTC sc = ifp->if_softc;
+ int status = 0, queue_index = 0;
+ struct mbuf *next = NULL;
+ struct buf_ring *br = NULL;
+
+ br = wq->br;
+ queue_index = wq->queue_index;
+
+ if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING) {
+ if (m != NULL)
+ status = drbr_enqueue(ifp, br, m);
+ return status;
+ }
+
+ if (m == NULL)
+ next = drbr_dequeue(ifp, br);
+ else if (drbr_needs_enqueue(ifp, br)) {
+ if ((status = drbr_enqueue(ifp, br, m)) != 0)
+ return status;
+ next = drbr_dequeue(ifp, br);
+ } else
+ next = m;
+
+ while (next != NULL) {
+ if (oce_tx(sc, &next, queue_index)) {
+ if (next != NULL) {
+ wq->tx_stats.tx_stops ++;
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ status = drbr_enqueue(ifp, br, next);
+ }
+ break;
+ }
+ drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags);
+ ETHER_BPF_MTAP(ifp, next);
+ next = drbr_dequeue(ifp, br);
+ }
+
+ return status;
+}
+
+
+
+
+/*****************************************************************************
+ * Receive routines functions *
+ *****************************************************************************/
+
+static void
+oce_rx(struct oce_rq *rq, uint32_t rqe_idx, struct oce_nic_rx_cqe *cqe)
+{
+ uint32_t out;
+ struct oce_packet_desc *pd;
+ POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
+ int i, len, frag_len;
+ struct mbuf *m = NULL, *tail = NULL;
+ uint16_t vtag;
+
+ len = cqe->u0.s.pkt_size;
+ if (!len) {
+ /*partial DMA workaround for Lancer*/
+ oce_discard_rx_comp(rq, cqe);
+ goto exit;
+ }
+
+ /* Get vlan_tag value */
+ if(IS_BE(sc))
+ vtag = BSWAP_16(cqe->u0.s.vlan_tag);
+ else
+ vtag = cqe->u0.s.vlan_tag;
+
+
+ for (i = 0; i < cqe->u0.s.num_fragments; i++) {
+
+ if (rq->packets_out == rq->packets_in) {
+ device_printf(sc->dev,
+ "RQ transmit descriptor missing\n");
+ }
+ out = rq->packets_out + 1;
+ if (out == OCE_RQ_PACKET_ARRAY_SIZE)
+ out = 0;
+ pd = &rq->pckts[rq->packets_out];
+ rq->packets_out = out;
+
+ bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(rq->tag, pd->map);
+ rq->pending--;
+
+ frag_len = (len > rq->cfg.frag_size) ? rq->cfg.frag_size : len;
+ pd->mbuf->m_len = frag_len;
+
+ if (tail != NULL) {
+ /* additional fragments */
+ pd->mbuf->m_flags &= ~M_PKTHDR;
+ tail->m_next = pd->mbuf;
+ tail = pd->mbuf;
+ } else {
+ /* first fragment, fill out much of the packet header */
+ pd->mbuf->m_pkthdr.len = len;
+ pd->mbuf->m_pkthdr.csum_flags = 0;
+ if (IF_CSUM_ENABLED(sc)) {
+ if (cqe->u0.s.l4_cksum_pass) {
+ pd->mbuf->m_pkthdr.csum_flags |=
+ (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
+ pd->mbuf->m_pkthdr.csum_data = 0xffff;
+ }
+ if (cqe->u0.s.ip_cksum_pass) {
+ if (!cqe->u0.s.ip_ver) { /* IPV4 */
+ pd->mbuf->m_pkthdr.csum_flags |=
+ (CSUM_IP_CHECKED|CSUM_IP_VALID);
+ }
+ }
+ }
+ m = tail = pd->mbuf;
+ }
+ pd->mbuf = NULL;
+ len -= frag_len;
+ }
+
+ if (m) {
+ if (!oce_cqe_portid_valid(sc, cqe)) {
+ m_freem(m);
+ goto exit;
+ }
+
+ m->m_pkthdr.rcvif = sc->ifp;
+#if __FreeBSD_version >= 800000
+ m->m_pkthdr.flowid = rq->queue_index;
+ m->m_flags |= M_FLOWID;
+#endif
+ /* This deternies if vlan tag is Valid */
+ if (oce_cqe_vtp_valid(sc, cqe)) {
+ if (sc->function_mode & FNM_FLEX10_MODE) {
+ /* FLEX10. If QnQ is not set, neglect VLAN */
+ if (cqe->u0.s.qnq) {
+ m->m_pkthdr.ether_vtag = vtag;
+ m->m_flags |= M_VLANTAG;
+ }
+ } else if (sc->pvid != (vtag & VLAN_VID_MASK)) {
+ /* In UMC mode generally pvid will be striped by
+ hw. But in some cases we have seen it comes
+ with pvid. So if pvid == vlan, neglect vlan.
+ */
+ m->m_pkthdr.ether_vtag = vtag;
+ m->m_flags |= M_VLANTAG;
+ }
+ }
+
+ sc->ifp->if_ipackets++;
+#if defined(INET6) || defined(INET)
+ /* Try to queue to LRO */
+ if (IF_LRO_ENABLED(sc) &&
+ !(m->m_flags & M_VLANTAG) &&
+ (cqe->u0.s.ip_cksum_pass) &&
+ (cqe->u0.s.l4_cksum_pass) &&
+ (!cqe->u0.s.ip_ver) &&
+ (rq->lro.lro_cnt != 0)) {
+
+ if (tcp_lro_rx(&rq->lro, m, 0) == 0) {
+ rq->lro_pkts_queued ++;
+ goto post_done;
+ }
+ /* If LRO posting fails then try to post to STACK */
+ }
+#endif
+
+ (*sc->ifp->if_input) (sc->ifp, m);
+#if defined(INET6) || defined(INET)
+post_done:
+#endif
+ /* Update rx stats per queue */
+ rq->rx_stats.rx_pkts++;
+ rq->rx_stats.rx_bytes += cqe->u0.s.pkt_size;
+ rq->rx_stats.rx_frags += cqe->u0.s.num_fragments;
+ if (cqe->u0.s.pkt_type == OCE_MULTICAST_PACKET)
+ rq->rx_stats.rx_mcast_pkts++;
+ if (cqe->u0.s.pkt_type == OCE_UNICAST_PACKET)
+ rq->rx_stats.rx_ucast_pkts++;
+ }
+exit:
+ return;
+}
+
+
+static void
+oce_discard_rx_comp(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe)
+{
+ uint32_t out, i = 0;
+ struct oce_packet_desc *pd;
+ POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
+ int num_frags = cqe->u0.s.num_fragments;
+
+ if (IS_XE201(sc) && cqe->u0.s.error) {
+ /* Lancer A0 workaround
+ * num_frags will be 1 more than actual in case of error
+ */
+ if (num_frags)
+ num_frags -= 1;
+ }
+ for (i = 0; i < num_frags; i++) {
+ if (rq->packets_out == rq->packets_in) {
+ device_printf(sc->dev,
+ "RQ transmit descriptor missing\n");
+ }
+ out = rq->packets_out + 1;
+ if (out == OCE_RQ_PACKET_ARRAY_SIZE)
+ out = 0;
+ pd = &rq->pckts[rq->packets_out];
+ rq->packets_out = out;
+
+ bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(rq->tag, pd->map);
+ rq->pending--;
+ m_freem(pd->mbuf);
+ }
+
+}
+
+
+static int
+oce_cqe_vtp_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe)
+{
+ struct oce_nic_rx_cqe_v1 *cqe_v1;
+ int vtp = 0;
+
+ if (sc->be3_native) {
+ cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe;
+ vtp = cqe_v1->u0.s.vlan_tag_present;
+ } else
+ vtp = cqe->u0.s.vlan_tag_present;
+
+ return vtp;
+
+}
+
+
+static int
+oce_cqe_portid_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe)
+{
+ struct oce_nic_rx_cqe_v1 *cqe_v1;
+ int port_id = 0;
+
+ if (sc->be3_native && IS_BE(sc)) {
+ cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe;
+ port_id = cqe_v1->u0.s.port;
+ if (sc->port_id != port_id)
+ return 0;
+ } else
+ ;/* For BE3 legacy and Lancer this is dummy */
+
+ return 1;
+
+}
+
+#if defined(INET6) || defined(INET)
+static void
+oce_rx_flush_lro(struct oce_rq *rq)
+{
+ struct lro_ctrl *lro = &rq->lro;
+ struct lro_entry *queued;
+ POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
+
+ if (!IF_LRO_ENABLED(sc))
+ return;
+
+ while ((queued = SLIST_FIRST(&lro->lro_active)) != NULL) {
+ SLIST_REMOVE_HEAD(&lro->lro_active, next);
+ tcp_lro_flush(lro, queued);
+ }
+ rq->lro_pkts_queued = 0;
+
+ return;
+}
+
+
+static int
+oce_init_lro(POCE_SOFTC sc)
+{
+ struct lro_ctrl *lro = NULL;
+ int i = 0, rc = 0;
+
+ for (i = 0; i < sc->nrqs; i++) {
+ lro = &sc->rq[i]->lro;
+ rc = tcp_lro_init(lro);
+ if (rc != 0) {
+ device_printf(sc->dev, "LRO init failed\n");
+ return rc;
+ }
+ lro->ifp = sc->ifp;
+ }
+
+ return rc;
+}
+
+
+void
+oce_free_lro(POCE_SOFTC sc)
+{
+ struct lro_ctrl *lro = NULL;
+ int i = 0;
+
+ for (i = 0; i < sc->nrqs; i++) {
+ lro = &sc->rq[i]->lro;
+ if (lro)
+ tcp_lro_free(lro);
+ }
+}
+#endif /* INET6 || INET */
+
+int
+oce_alloc_rx_bufs(struct oce_rq *rq, int count)
+{
+ POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
+ int i, in, rc;
+ struct oce_packet_desc *pd;
+ bus_dma_segment_t segs[6];
+ int nsegs, added = 0;
+ struct oce_nic_rqe *rqe;
+ pd_rxulp_db_t rxdb_reg;
+
+
+ for (i = 0; i < count; i++) {
+ in = rq->packets_in + 1;
+ if (in == OCE_RQ_PACKET_ARRAY_SIZE)
+ in = 0;
+ if (in == rq->packets_out)
+ break; /* no more room */
+
+ pd = &rq->pckts[rq->packets_in];
+ pd->mbuf = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+ if (pd->mbuf == NULL)
+ break;
+
+ pd->mbuf->m_len = pd->mbuf->m_pkthdr.len = MCLBYTES;
+ rc = bus_dmamap_load_mbuf_sg(rq->tag,
+ pd->map,
+ pd->mbuf,
+ segs, &nsegs, BUS_DMA_NOWAIT);
+ if (rc) {
+ m_free(pd->mbuf);
+ break;
+ }
+
+ if (nsegs != 1) {
+ i--;
+ continue;
+ }
+
+ rq->packets_in = in;
+ bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_PREREAD);
+
+ rqe = RING_GET_PRODUCER_ITEM_VA(rq->ring, struct oce_nic_rqe);
+ rqe->u0.s.frag_pa_hi = ADDR_HI(segs[0].ds_addr);
+ rqe->u0.s.frag_pa_lo = ADDR_LO(segs[0].ds_addr);
+ DW_SWAP(u32ptr(rqe), sizeof(struct oce_nic_rqe));
+ RING_PUT(rq->ring, 1);
+ added++;
+ rq->pending++;
+ }
+ if (added != 0) {
+ for (i = added / OCE_MAX_RQ_POSTS; i > 0; i--) {
+ DELAY(1);
+ rxdb_reg.bits.num_posted = OCE_MAX_RQ_POSTS;
+ rxdb_reg.bits.qid = rq->rq_id;
+ OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
+ added -= OCE_MAX_RQ_POSTS;
+ }
+ if (added > 0) {
+ DELAY(1);
+ rxdb_reg.bits.qid = rq->rq_id;
+ rxdb_reg.bits.num_posted = added;
+ OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0);
+ }
+ }
+
+ return 0;
+}
+
+
+/* Handle the Completion Queue for receive */
+uint16_t
+oce_rq_handler(void *arg)
+{
+ struct oce_rq *rq = (struct oce_rq *)arg;
+ struct oce_cq *cq = rq->cq;
+ POCE_SOFTC sc = rq->parent;
+ struct oce_nic_rx_cqe *cqe;
+ int num_cqes = 0, rq_buffers_used = 0;
+
+
+ LOCK(&rq->rx_lock);
+ bus_dmamap_sync(cq->ring->dma.tag,
+ cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
+ cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
+ while (cqe->u0.dw[2]) {
+ DW_SWAP((uint32_t *) cqe, sizeof(oce_rq_cqe));
+
+ RING_GET(rq->ring, 1);
+ if (cqe->u0.s.error == 0) {
+ oce_rx(rq, cqe->u0.s.frag_index, cqe);
+ } else {
+ rq->rx_stats.rxcp_err++;
+ sc->ifp->if_ierrors++;
+ if (IS_XE201(sc))
+ /* Lancer A0 no buffer workaround */
+ oce_discard_rx_comp(rq, cqe);
+ else
+ /* Post L3/L4 errors to stack.*/
+ oce_rx(rq, cqe->u0.s.frag_index, cqe);
+
+ }
+ rq->rx_stats.rx_compl++;
+ cqe->u0.dw[2] = 0;
+
+#if defined(INET6) || defined(INET)
+ if (IF_LRO_ENABLED(sc) && rq->lro_pkts_queued >= 16) {
+ oce_rx_flush_lro(rq);
+ }
+#endif
+
+ RING_GET(cq->ring, 1);
+ bus_dmamap_sync(cq->ring->dma.tag,
+ cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
+ cqe =
+ RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
+ num_cqes++;
+ if (num_cqes >= (IS_XE201(sc) ? 8 : oce_max_rsp_handled))
+ break;
+ }
+
+#if defined(INET6) || defined(INET)
+ if (IF_LRO_ENABLED(sc))
+ oce_rx_flush_lro(rq);
+#endif
+
+ if (num_cqes) {
+ oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
+ rq_buffers_used = OCE_RQ_PACKET_ARRAY_SIZE - rq->pending;
+ if (rq_buffers_used > 1)
+ oce_alloc_rx_bufs(rq, (rq_buffers_used - 1));
+ }
+
+ UNLOCK(&rq->rx_lock);
+
+ return 0;
+
+}
+
+
+
+
+/*****************************************************************************
+ * Helper function prototypes in this file *
+ *****************************************************************************/
+
+static int
+oce_attach_ifp(POCE_SOFTC sc)
+{
+
+ sc->ifp = if_alloc(IFT_ETHER);
+ if (!sc->ifp)
+ return ENOMEM;
+
+ ifmedia_init(&sc->media, IFM_IMASK, oce_media_change, oce_media_status);
+ ifmedia_add(&sc->media, IFM_ETHER | IFM_AUTO, 0, NULL);
+ ifmedia_set(&sc->media, IFM_ETHER | IFM_AUTO);
+
+ sc->ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
+ sc->ifp->if_ioctl = oce_ioctl;
+ sc->ifp->if_start = oce_start;
+ sc->ifp->if_init = oce_init;
+ sc->ifp->if_mtu = ETHERMTU;
+ sc->ifp->if_softc = sc;
+#if __FreeBSD_version >= 800000
+ sc->ifp->if_transmit = oce_multiq_start;
+ sc->ifp->if_qflush = oce_multiq_flush;
+#endif
+
+ if_initname(sc->ifp,
+ device_get_name(sc->dev), device_get_unit(sc->dev));
+
+ sc->ifp->if_snd.ifq_drv_maxlen = OCE_MAX_TX_DESC - 1;
+ IFQ_SET_MAXLEN(&sc->ifp->if_snd, sc->ifp->if_snd.ifq_drv_maxlen);
+ IFQ_SET_READY(&sc->ifp->if_snd);
+
+ sc->ifp->if_hwassist = OCE_IF_HWASSIST;
+ sc->ifp->if_hwassist |= CSUM_TSO;
+ sc->ifp->if_hwassist |= (CSUM_IP | CSUM_TCP | CSUM_UDP);
+
+ sc->ifp->if_capabilities = OCE_IF_CAPABILITIES;
+ sc->ifp->if_capabilities |= IFCAP_HWCSUM;
+ sc->ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
+
+#if defined(INET6) || defined(INET)
+ sc->ifp->if_capabilities |= IFCAP_TSO;
+ sc->ifp->if_capabilities |= IFCAP_LRO;
+ sc->ifp->if_capabilities |= IFCAP_VLAN_HWTSO;
+#endif
+
+ sc->ifp->if_capenable = sc->ifp->if_capabilities;
+ sc->ifp->if_baudrate = IF_Gbps(10UL);
+
+ ether_ifattach(sc->ifp, sc->macaddr.mac_addr);
+
+ return 0;
+}
+
+
+static void
+oce_add_vlan(void *arg, struct ifnet *ifp, uint16_t vtag)
+{
+ POCE_SOFTC sc = ifp->if_softc;
+
+ if (ifp->if_softc != arg)
+ return;
+ if ((vtag == 0) || (vtag > 4095))
+ return;
+
+ sc->vlan_tag[vtag] = 1;
+ sc->vlans_added++;
+ oce_vid_config(sc);
+}
+
+
+static void
+oce_del_vlan(void *arg, struct ifnet *ifp, uint16_t vtag)
+{
+ POCE_SOFTC sc = ifp->if_softc;
+
+ if (ifp->if_softc != arg)
+ return;
+ if ((vtag == 0) || (vtag > 4095))
+ return;
+
+ sc->vlan_tag[vtag] = 0;
+ sc->vlans_added--;
+ oce_vid_config(sc);
+}
+
+
+/*
+ * A max of 64 vlans can be configured in BE. If the user configures
+ * more, place the card in vlan promiscuous mode.
+ */
+static int
+oce_vid_config(POCE_SOFTC sc)
+{
+ struct normal_vlan vtags[MAX_VLANFILTER_SIZE];
+ uint16_t ntags = 0, i;
+ int status = 0;
+
+ if ((sc->vlans_added <= MAX_VLANFILTER_SIZE) &&
+ (sc->ifp->if_capenable & IFCAP_VLAN_HWFILTER)) {
+ for (i = 0; i < MAX_VLANS; i++) {
+ if (sc->vlan_tag[i]) {
+ vtags[ntags].vtag = i;
+ ntags++;
+ }
+ }
+ if (ntags)
+ status = oce_config_vlan(sc, (uint8_t) sc->if_id,
+ vtags, ntags, 1, 0);
+ } else
+ status = oce_config_vlan(sc, (uint8_t) sc->if_id,
+ NULL, 0, 1, 1);
+ return status;
+}
+
+
+static void
+oce_mac_addr_set(POCE_SOFTC sc)
+{
+ uint32_t old_pmac_id = sc->pmac_id;
+ int status = 0;
+
+
+ status = bcmp((IF_LLADDR(sc->ifp)), sc->macaddr.mac_addr,
+ sc->macaddr.size_of_struct);
+ if (!status)
+ return;
+
+ status = oce_mbox_macaddr_add(sc, (uint8_t *)(IF_LLADDR(sc->ifp)),
+ sc->if_id, &sc->pmac_id);
+ if (!status) {
+ status = oce_mbox_macaddr_del(sc, sc->if_id, old_pmac_id);
+ bcopy((IF_LLADDR(sc->ifp)), sc->macaddr.mac_addr,
+ sc->macaddr.size_of_struct);
+ }
+ if (status)
+ device_printf(sc->dev, "Failed update macaddress\n");
+
+}
+
+
+static int
+oce_handle_passthrough(struct ifnet *ifp, caddr_t data)
+{
+ POCE_SOFTC sc = ifp->if_softc;
+ struct ifreq *ifr = (struct ifreq *)data;
+ int rc = ENXIO;
+ char cookie[32] = {0};
+ void *priv_data = (void *)ifr->ifr_data;
+ void *ioctl_ptr;
+ uint32_t req_size;
+ struct mbx_hdr req;
+ OCE_DMA_MEM dma_mem;
+
+
+ if (copyin(priv_data, cookie, strlen(IOCTL_COOKIE)))
+ return EFAULT;
+
+ if (memcmp(cookie, IOCTL_COOKIE, strlen(IOCTL_COOKIE)))
+ return EINVAL;
+
+ ioctl_ptr = (char *)priv_data + strlen(IOCTL_COOKIE);
+ if (copyin(ioctl_ptr, &req, sizeof(struct mbx_hdr)))
+ return EFAULT;
+
+ req_size = le32toh(req.u0.req.request_length);
+ if (req_size > 65536)
+ return EINVAL;
+
+ req_size += sizeof(struct mbx_hdr);
+ rc = oce_dma_alloc(sc, req_size, &dma_mem, 0);
+ if (rc)
+ return ENOMEM;
+
+ if (copyin(ioctl_ptr, OCE_DMAPTR(&dma_mem,char), req_size)) {
+ rc = EFAULT;
+ goto dma_free;
+ }
+
+ rc = oce_pass_through_mbox(sc, &dma_mem, req_size);
+ if (rc) {
+ rc = EIO;
+ goto dma_free;
+ }
+
+ if (copyout(OCE_DMAPTR(&dma_mem,char), ioctl_ptr, req_size))
+ rc = EFAULT;
+
+dma_free:
+ oce_dma_free(sc, &dma_mem);
+ return rc;
+
+}
+
+
+static void
+oce_local_timer(void *arg)
+{
+ POCE_SOFTC sc = arg;
+ int i = 0;
+
+ oce_refresh_nic_stats(sc);
+ oce_refresh_queue_stats(sc);
+ oce_mac_addr_set(sc);
+
+ /* TX Watch Dog*/
+ for (i = 0; i < sc->nwqs; i++)
+ oce_tx_restart(sc, sc->wq[i]);
+
+ callout_reset(&sc->timer, hz, oce_local_timer, sc);
+}
+
+
+static void
+oce_if_deactivate(POCE_SOFTC sc)
+{
+ int i, mtime = 0;
+ int wait_req = 0;
+ struct oce_rq *rq;
+ struct oce_wq *wq;
+ struct oce_eq *eq;
+
+ sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+
+ /*Wait for max of 400ms for TX completions to be done */
+ while (mtime < 400) {
+ wait_req = 0;
+ for_all_wq_queues(sc, wq, i) {
+ if (wq->ring->num_used) {
+ wait_req = 1;
+ DELAY(1);
+ break;
+ }
+ }
+ mtime += 1;
+ if (!wait_req)
+ break;
+ }
+
+ /* Stop intrs and finish any bottom halves pending */
+ oce_hw_intr_disable(sc);
+
+ for (i = 0; i < sc->intr_count; i++) {
+ if (sc->intrs[i].tq != NULL) {
+ taskqueue_drain(sc->intrs[i].tq, &sc->intrs[i].task);
+ }
+ }
+
+ /* Delete RX queue in card with flush param */
+ oce_stop_rx(sc);
+
+ /* Invalidate any pending cq and eq entries*/
+ for_all_evnt_queues(sc, eq, i)
+ oce_drain_eq(eq);
+ for_all_rq_queues(sc, rq, i)
+ oce_drain_rq_cq(rq);
+ for_all_wq_queues(sc, wq, i)
+ oce_drain_wq_cq(wq);
+
+ /* But still we need to get MCC aync events.
+ So enable intrs and also arm first EQ
+ */
+ oce_hw_intr_enable(sc);
+ oce_arm_eq(sc, sc->eq[0]->eq_id, 0, TRUE, FALSE);
+
+ DELAY(10);
+}
+
+
+static void
+oce_if_activate(POCE_SOFTC sc)
+{
+ struct oce_eq *eq;
+ struct oce_rq *rq;
+ struct oce_wq *wq;
+ int i, rc = 0;
+
+ sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
+
+ oce_hw_intr_disable(sc);
+
+ oce_start_rx(sc);
+
+ for_all_rq_queues(sc, rq, i) {
+ rc = oce_start_rq(rq);
+ if (rc)
+ device_printf(sc->dev, "Unable to start RX\n");
+ }
+
+ for_all_wq_queues(sc, wq, i) {
+ rc = oce_start_wq(wq);
+ if (rc)
+ device_printf(sc->dev, "Unable to start TX\n");
+ }
+
+
+ for_all_evnt_queues(sc, eq, i)
+ oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE);
+
+ oce_hw_intr_enable(sc);
+
+}
+
+static void
+process_link_state(POCE_SOFTC sc, struct oce_async_cqe_link_state *acqe)
+{
+ /* Update Link status */
+ if ((acqe->u0.s.link_status & ~ASYNC_EVENT_LOGICAL) ==
+ ASYNC_EVENT_LINK_UP) {
+ sc->link_status = ASYNC_EVENT_LINK_UP;
+ if_link_state_change(sc->ifp, LINK_STATE_UP);
+ } else {
+ sc->link_status = ASYNC_EVENT_LINK_DOWN;
+ if_link_state_change(sc->ifp, LINK_STATE_DOWN);
+ }
+
+ /* Update speed */
+ sc->link_speed = acqe->u0.s.speed;
+ sc->qos_link_speed = (uint32_t) acqe->u0.s.qos_link_speed * 10;
+
+}
+
+
+/* Handle the Completion Queue for the Mailbox/Async notifications */
+uint16_t
+oce_mq_handler(void *arg)
+{
+ struct oce_mq *mq = (struct oce_mq *)arg;
+ POCE_SOFTC sc = mq->parent;
+ struct oce_cq *cq = mq->cq;
+ int num_cqes = 0, evt_type = 0, optype = 0;
+ struct oce_mq_cqe *cqe;
+ struct oce_async_cqe_link_state *acqe;
+ struct oce_async_event_grp5_pvid_state *gcqe;
+
+
+ bus_dmamap_sync(cq->ring->dma.tag,
+ cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
+ cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
+
+ while (cqe->u0.dw[3]) {
+ DW_SWAP((uint32_t *) cqe, sizeof(oce_mq_cqe));
+ if (cqe->u0.s.async_event) {
+ evt_type = cqe->u0.s.event_type;
+ optype = cqe->u0.s.async_type;
+ if (evt_type == ASYNC_EVENT_CODE_LINK_STATE) {
+ /* Link status evt */
+ acqe = (struct oce_async_cqe_link_state *)cqe;
+ process_link_state(sc, acqe);
+ } else if ((evt_type == ASYNC_EVENT_GRP5) &&
+ (optype == ASYNC_EVENT_PVID_STATE)) {
+ /* GRP5 PVID */
+ gcqe =
+ (struct oce_async_event_grp5_pvid_state *)cqe;
+ if (gcqe->enabled)
+ sc->pvid = gcqe->tag & VLAN_VID_MASK;
+ else
+ sc->pvid = 0;
+
+ }
+ }
+ cqe->u0.dw[3] = 0;
+ RING_GET(cq->ring, 1);
+ bus_dmamap_sync(cq->ring->dma.tag,
+ cq->ring->dma.map, BUS_DMASYNC_POSTWRITE);
+ cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_mq_cqe);
+ num_cqes++;
+ }
+
+ if (num_cqes)
+ oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
+
+ return 0;
+}
+
+
+static void
+setup_max_queues_want(POCE_SOFTC sc)
+{
+ int max_rss = 0;
+
+ /* Check if it is FLEX machine. Is so dont use RSS */
+ if ((sc->function_mode & FNM_FLEX10_MODE) ||
+ (sc->function_mode & FNM_UMC_MODE) ||
+ (sc->function_mode & FNM_VNIC_MODE) ||
+ (!sc->rss_enable) ||
+ (sc->flags & OCE_FLAGS_BE2)) {
+ sc->nrqs = 1;
+ sc->nwqs = 1;
+ sc->rss_enable = 0;
+ } else {
+ /* For multiq, our deisgn is to have TX rings equal to
+ RSS rings. So that we can pair up one RSS ring and TX
+ to a single intr, which improves CPU cache efficiency.
+ */
+ if (IS_BE(sc) && (!sc->be3_native))
+ max_rss = OCE_LEGACY_MODE_RSS;
+ else
+ max_rss = OCE_MAX_RSS;
+
+ sc->nrqs = MIN(OCE_NCPUS, max_rss) + 1; /* 1 for def RX */
+ sc->nwqs = MIN(OCE_NCPUS, max_rss);
+ }
+
+}
+
+
+static void
+update_queues_got(POCE_SOFTC sc)
+{
+ if (sc->rss_enable) {
+ sc->nrqs = sc->intr_count + 1;
+ sc->nwqs = sc->intr_count;
+ } else {
+ sc->nrqs = 1;
+ sc->nwqs = 1;
+ }
+}
+
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/oce/oce_if.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/oce/oce_if.h Fri Mar 02 17:36:33 2012 +0200
@@ -0,0 +1,1078 @@
+/*-
+ * Copyright (C) 2012 Emulex
+ * 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.
+ *
+ * 3. Neither the name of the Emulex Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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.
+ *
+ * Contact Information:
+ * freebsd-drivers at emulex.com
+ *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
+ */
+
+/* $FreeBSD: head/sys/dev/oce/oce_if.h 231879 2012-02-17 13:55:17Z luigi $ */
+
+#include <sys/param.h>
+#include <sys/endian.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/mbuf.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/sockopt.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sysctl.h>
+#include <sys/random.h>
+#include <sys/firmware.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <net/bpf.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/if_media.h>
+#include <net/if_vlan_var.h>
+#include <net/if_dl.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet6/in6_var.h>
+#include <netinet6/ip6_mroute.h>
+
+#include <netinet/udp.h>
+#include <netinet/tcp.h>
+#include <netinet/sctp.h>
+#include <netinet/tcp_lro.h>
+
+#include <machine/bus.h>
+
+#include "oce_hw.h"
+
+/* OCE device driver module component revision informaiton */
+#define COMPONENT_REVISION "4.2.127.0"
+
+
+/* OCE devices supported by this driver */
+#define PCI_VENDOR_EMULEX 0x10df /* Emulex */
+#define PCI_VENDOR_SERVERENGINES 0x19a2 /* ServerEngines (BE) */
+#define PCI_PRODUCT_BE2 0x0700 /* BE2 network adapter */
+#define PCI_PRODUCT_BE3 0x0710 /* BE3 network adapter */
+#define PCI_PRODUCT_XE201 0xe220 /* XE201 network adapter */
+#define PCI_PRODUCT_XE201_VF 0xe228 /* XE201 with VF in Lancer */
+
+#define IS_BE(sc) (((sc->flags & OCE_FLAGS_BE3) | \
+ (sc->flags & OCE_FLAGS_BE2))? 1:0)
+#define IS_XE201(sc) ((sc->flags & OCE_FLAGS_XE201) ? 1:0)
+#define HAS_A0_CHIP(sc) ((sc->flags & OCE_FLAGS_HAS_A0_CHIP) ? 1:0)
+
+
+/* proportion Service Level Interface queues */
+#define OCE_MAX_UNITS 2
+#define OCE_MAX_PPORT OCE_MAX_UNITS
+#define OCE_MAX_VPORT OCE_MAX_UNITS
+
+extern int mp_ncpus; /* system's total active cpu cores */
+#define OCE_NCPUS mp_ncpus
+
+/* This should be powers of 2. Like 2,4,8 & 16 */
+#define OCE_MAX_RSS 4 /* TODO: 8*/
+#define OCE_LEGACY_MODE_RSS 4 /* For BE3 Legacy mode*/
+
+#define OCE_MIN_RQ 1
+#define OCE_MIN_WQ 1
+
+#define OCE_MAX_RQ OCE_MAX_RSS + 1 /* one default queue */
+#define OCE_MAX_WQ 8
+
+#define OCE_MAX_EQ 32
+#define OCE_MAX_CQ OCE_MAX_RQ + OCE_MAX_WQ + 1 /* one MCC queue */
+#define OCE_MAX_CQ_EQ 8 /* Max CQ that can attached to an EQ */
+
+#define OCE_DEFAULT_WQ_EQD 16
+#define OCE_MAX_PACKET_Q 16
+#define OCE_RQ_BUF_SIZE 2048
+#define OCE_LSO_MAX_SIZE (64 * 1024)
+#define LONG_TIMEOUT 30
+#define OCE_MAX_JUMBO_FRAME_SIZE 16360
+#define OCE_MAX_MTU (OCE_MAX_JUMBO_FRAME_SIZE - \
+ ETHER_VLAN_ENCAP_LEN - \
+ ETHER_HDR_LEN)
+
+#define OCE_MAX_TX_ELEMENTS 29
+#define OCE_MAX_TX_DESC 1024
+#define OCE_MAX_TX_SIZE 65535
+#define OCE_MAX_RX_SIZE 4096
+#define OCE_MAX_RQ_POSTS 255
+#define OCE_DEFAULT_PROMISCUOUS 0
+
+
+#define RSS_ENABLE_IPV4 0x1
+#define RSS_ENABLE_TCP_IPV4 0x2
+#define RSS_ENABLE_IPV6 0x4
+#define RSS_ENABLE_TCP_IPV6 0x8
+
+
+/* flow control definitions */
+#define OCE_FC_NONE 0x00000000
+#define OCE_FC_TX 0x00000001
+#define OCE_FC_RX 0x00000002
+#define OCE_DEFAULT_FLOW_CONTROL (OCE_FC_TX | OCE_FC_RX)
+
+
+/* Interface capabilities to give device when creating interface */
+#define OCE_CAPAB_FLAGS (MBX_RX_IFACE_FLAGS_BROADCAST | \
+ MBX_RX_IFACE_FLAGS_UNTAGGED | \
+ MBX_RX_IFACE_FLAGS_PROMISCUOUS | \
+ MBX_RX_IFACE_FLAGS_MCAST_PROMISCUOUS | \
+ MBX_RX_IFACE_FLAGS_RSS | \
+ MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR)
+
+/* Interface capabilities to enable by default (others set dynamically) */
+#define OCE_CAPAB_ENABLE (MBX_RX_IFACE_FLAGS_BROADCAST | \
+ MBX_RX_IFACE_FLAGS_UNTAGGED | \
+ MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR)
+
+#define OCE_IF_HWASSIST (CSUM_IP | CSUM_TCP | CSUM_UDP)
+#define OCE_IF_CAPABILITIES (IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \
+ IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | \
+ IFCAP_JUMBO_MTU | IFCAP_VLAN_MTU)
+#define OCE_IF_HWASSIST_NONE 0
+#define OCE_IF_CAPABILITIES_NONE 0
+
+
+#define ETH_ADDR_LEN 6
+#define MAX_VLANFILTER_SIZE 64
+#define MAX_VLANS 4096
+
+#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
+#define BSWAP_8(x) ((x) & 0xff)
+#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
+#define BSWAP_32(x) ((BSWAP_16(x) << 16) | \
+ BSWAP_16((x) >> 16))
+#define BSWAP_64(x) ((BSWAP_32(x) << 32) | \
+ BSWAP_32((x) >> 32))
+
+#define for_all_wq_queues(sc, wq, i) \
+ for (i = 0, wq = sc->wq[0]; i < sc->nwqs; i++, wq = sc->wq[i])
+#define for_all_rq_queues(sc, rq, i) \
+ for (i = 0, rq = sc->rq[0]; i < sc->nrqs; i++, rq = sc->rq[i])
+#define for_all_evnt_queues(sc, eq, i) \
+ for (i = 0, eq = sc->eq[0]; i < sc->neqs; i++, eq = sc->eq[i])
+#define for_all_cq_queues(sc, cq, i) \
+ for (i = 0, cq = sc->cq[0]; i < sc->ncqs; i++, cq = sc->cq[i])
+
+
+/* Flash specific */
+#define IOCTL_COOKIE "SERVERENGINES CORP"
+#define MAX_FLASH_COMP 32
+
+#define IMG_ISCSI 160
+#define IMG_REDBOOT 224
+#define IMG_BIOS 34
+#define IMG_PXEBIOS 32
+#define IMG_FCOEBIOS 33
+#define IMG_ISCSI_BAK 176
+#define IMG_FCOE 162
+#define IMG_FCOE_BAK 178
+#define IMG_NCSI 16
+#define IMG_PHY 192
+#define FLASHROM_OPER_FLASH 1
+#define FLASHROM_OPER_SAVE 2
+#define FLASHROM_OPER_REPORT 4
+#define FLASHROM_OPER_FLASH_PHY 9
+#define FLASHROM_OPER_SAVE_PHY 10
+#define TN_8022 13
+
+enum {
+ PHY_TYPE_CX4_10GB = 0,
+ PHY_TYPE_XFP_10GB,
+ PHY_TYPE_SFP_1GB,
+ PHY_TYPE_SFP_PLUS_10GB,
+ PHY_TYPE_KR_10GB,
+ PHY_TYPE_KX4_10GB,
+ PHY_TYPE_BASET_10GB,
+ PHY_TYPE_BASET_1GB,
+ PHY_TYPE_BASEX_1GB,
+ PHY_TYPE_SGMII,
+ PHY_TYPE_DISABLED = 255
+};
+
+/**
+ * @brief Define and hold all necessary info for a single interrupt
+ */
+#define OCE_MAX_MSI 32 /* Message Signaled Interrupts */
+#define OCE_MAX_MSIX 2048 /* PCI Express MSI Interrrupts */
+
+typedef struct oce_intr_info {
+ void *tag; /* cookie returned by bus_setup_intr */
+ struct resource *intr_res; /* PCI resource container */
+ int irq_rr; /* resource id for the interrupt */
+ struct oce_softc *sc; /* pointer to the parent soft c */
+ struct oce_eq *eq; /* pointer to the connected EQ */
+ struct taskqueue *tq; /* Associated task queue */
+ struct task task; /* task queue task */
+ char task_name[32]; /* task name */
+ int vector; /* interrupt vector number */
+} OCE_INTR_INFO, *POCE_INTR_INFO;
+
+
+/* Ring related */
+#define GET_Q_NEXT(_START, _STEP, _END) \
+ (((_START) + (_STEP)) < (_END) ? ((_START) + (_STEP)) \
+ : (((_START) + (_STEP)) - (_END)))
+
+#define DBUF_PA(obj) ((obj)->addr)
+#define DBUF_VA(obj) ((obj)->ptr)
+#define DBUF_TAG(obj) ((obj)->tag)
+#define DBUF_MAP(obj) ((obj)->map)
+#define DBUF_SYNC(obj, flags) \
+ (void) bus_dmamap_sync(DBUF_TAG(obj), DBUF_MAP(obj), (flags))
+
+#define RING_NUM_PENDING(ring) ring->num_used
+#define RING_FULL(ring) (ring->num_used == ring->num_items)
+#define RING_EMPTY(ring) (ring->num_used == 0)
+#define RING_NUM_FREE(ring) \
+ (uint32_t)(ring->num_items - ring->num_used)
+#define RING_GET(ring, n) \
+ ring->cidx = GET_Q_NEXT(ring->cidx, n, ring->num_items)
+#define RING_PUT(ring, n) \
+ ring->pidx = GET_Q_NEXT(ring->pidx, n, ring->num_items)
+
+#define RING_GET_CONSUMER_ITEM_VA(ring, type) \
+ (void*)((type *)DBUF_VA(&ring->dma) + ring->cidx)
+#define RING_GET_CONSUMER_ITEM_PA(ring, type) \
+ (uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->cidx)
+#define RING_GET_PRODUCER_ITEM_VA(ring, type) \
+ (void *)(((type *)DBUF_VA(&ring->dma)) + ring->pidx)
+#define RING_GET_PRODUCER_ITEM_PA(ring, type) \
+ (uint64_t)(((type *)DBUF_PA(ring->dbuf)) + ring->pidx)
+
+#define OCE_DMAPTR(o, c) ((c *)(o)->ptr)
+
+struct oce_packet_desc {
+ struct mbuf *mbuf;
+ bus_dmamap_t map;
+ int nsegs;
+ uint32_t wqe_idx;
+};
+
+typedef struct oce_dma_mem {
+ bus_dma_tag_t tag;
+ bus_dmamap_t map;
+ void *ptr;
+ bus_addr_t paddr;
+} OCE_DMA_MEM, *POCE_DMA_MEM;
+
+typedef struct oce_ring_buffer_s {
+ uint16_t cidx; /* Get ptr */
+ uint16_t pidx; /* Put Ptr */
+ size_t item_size;
+ size_t num_items;
+ uint32_t num_used;
+ OCE_DMA_MEM dma;
+} oce_ring_buffer_t;
+
+/* Stats */
+#define OCE_UNICAST_PACKET 0
+#define OCE_MULTICAST_PACKET 1
+#define OCE_BROADCAST_PACKET 2
+#define OCE_RSVD_PACKET 3
+
+struct oce_rx_stats {
+ /* Total Receive Stats*/
+ uint64_t t_rx_pkts;
+ uint64_t t_rx_bytes;
+ uint32_t t_rx_frags;
+ uint32_t t_rx_mcast_pkts;
+ uint32_t t_rx_ucast_pkts;
+ uint32_t t_rxcp_errs;
+};
+struct oce_tx_stats {
+ /*Total Transmit Stats */
+ uint64_t t_tx_pkts;
+ uint64_t t_tx_bytes;
+ uint32_t t_tx_reqs;
+ uint32_t t_tx_stops;
+ uint32_t t_tx_wrbs;
+ uint32_t t_tx_compl;
+ uint32_t t_ipv6_ext_hdr_tx_drop;
+};
+
+struct oce_be_stats {
+ uint8_t be_on_die_temperature;
+ uint32_t be_tx_events;
+ uint32_t eth_red_drops;
+ uint32_t rx_drops_no_pbuf;
+ uint32_t rx_drops_no_txpb;
+ uint32_t rx_drops_no_erx_descr;
+ uint32_t rx_drops_no_tpre_descr;
+ uint32_t rx_drops_too_many_frags;
+ uint32_t rx_drops_invalid_ring;
+ uint32_t forwarded_packets;
+ uint32_t rx_drops_mtu;
+ uint32_t rx_crc_errors;
+ uint32_t rx_alignment_symbol_errors;
+ uint32_t rx_pause_frames;
+ uint32_t rx_priority_pause_frames;
+ uint32_t rx_control_frames;
+ uint32_t rx_in_range_errors;
+ uint32_t rx_out_range_errors;
+ uint32_t rx_frame_too_long;
+ uint32_t rx_address_match_errors;
+ uint32_t rx_dropped_too_small;
+ uint32_t rx_dropped_too_short;
+ uint32_t rx_dropped_header_too_small;
+ uint32_t rx_dropped_tcp_length;
+ uint32_t rx_dropped_runt;
+ uint32_t rx_ip_checksum_errs;
+ uint32_t rx_tcp_checksum_errs;
+ uint32_t rx_udp_checksum_errs;
+ uint32_t rx_switched_unicast_packets;
+ uint32_t rx_switched_multicast_packets;
+ uint32_t rx_switched_broadcast_packets;
+ uint32_t tx_pauseframes;
+ uint32_t tx_priority_pauseframes;
+ uint32_t tx_controlframes;
+ uint32_t rxpp_fifo_overflow_drop;
+ uint32_t rx_input_fifo_overflow_drop;
+ uint32_t pmem_fifo_overflow_drop;
+ uint32_t jabber_events;
+};
+
+struct oce_xe201_stats {
+ uint64_t tx_pkts;
+ uint64_t tx_unicast_pkts;
+ uint64_t tx_multicast_pkts;
+ uint64_t tx_broadcast_pkts;
+ uint64_t tx_bytes;
+ uint64_t tx_unicast_bytes;
+ uint64_t tx_multicast_bytes;
+ uint64_t tx_broadcast_bytes;
+ uint64_t tx_discards;
+ uint64_t tx_errors;
+ uint64_t tx_pause_frames;
+ uint64_t tx_pause_on_frames;
+ uint64_t tx_pause_off_frames;
+ uint64_t tx_internal_mac_errors;
+ uint64_t tx_control_frames;
+ uint64_t tx_pkts_64_bytes;
+ uint64_t tx_pkts_65_to_127_bytes;
+ uint64_t tx_pkts_128_to_255_bytes;
+ uint64_t tx_pkts_256_to_511_bytes;
+ uint64_t tx_pkts_512_to_1023_bytes;
+ uint64_t tx_pkts_1024_to_1518_bytes;
+ uint64_t tx_pkts_1519_to_2047_bytes;
+ uint64_t tx_pkts_2048_to_4095_bytes;
+ uint64_t tx_pkts_4096_to_8191_bytes;
+ uint64_t tx_pkts_8192_to_9216_bytes;
+ uint64_t tx_lso_pkts;
+ uint64_t rx_pkts;
+ uint64_t rx_unicast_pkts;
+ uint64_t rx_multicast_pkts;
+ uint64_t rx_broadcast_pkts;
+ uint64_t rx_bytes;
+ uint64_t rx_unicast_bytes;
+ uint64_t rx_multicast_bytes;
+ uint64_t rx_broadcast_bytes;
+ uint32_t rx_unknown_protos;
+ uint64_t rx_discards;
+ uint64_t rx_errors;
+ uint64_t rx_crc_errors;
+ uint64_t rx_alignment_errors;
+ uint64_t rx_symbol_errors;
+ uint64_t rx_pause_frames;
+ uint64_t rx_pause_on_frames;
+ uint64_t rx_pause_off_frames;
+ uint64_t rx_frames_too_long;
+ uint64_t rx_internal_mac_errors;
+ uint32_t rx_undersize_pkts;
+ uint32_t rx_oversize_pkts;
+ uint32_t rx_fragment_pkts;
+ uint32_t rx_jabbers;
+ uint64_t rx_control_frames;
+ uint64_t rx_control_frames_unknown_opcode;
+ uint32_t rx_in_range_errors;
+ uint32_t rx_out_of_range_errors;
+ uint32_t rx_address_match_errors;
+ uint32_t rx_vlan_mismatch_errors;
+ uint32_t rx_dropped_too_small;
+ uint32_t rx_dropped_too_short;
+ uint32_t rx_dropped_header_too_small;
+ uint32_t rx_dropped_invalid_tcp_length;
+ uint32_t rx_dropped_runt;
+ uint32_t rx_ip_checksum_errors;
+ uint32_t rx_tcp_checksum_errors;
+ uint32_t rx_udp_checksum_errors;
+ uint32_t rx_non_rss_pkts;
+ uint64_t rx_ipv4_pkts;
+ uint64_t rx_ipv6_pkts;
+ uint64_t rx_ipv4_bytes;
+ uint64_t rx_ipv6_bytes;
+ uint64_t rx_nic_pkts;
+ uint64_t rx_tcp_pkts;
+ uint64_t rx_iscsi_pkts;
+ uint64_t rx_management_pkts;
+ uint64_t rx_switched_unicast_pkts;
+ uint64_t rx_switched_multicast_pkts;
+ uint64_t rx_switched_broadcast_pkts;
+ uint64_t num_forwards;
+ uint32_t rx_fifo_overflow;
+ uint32_t rx_input_fifo_overflow;
+ uint64_t rx_drops_too_many_frags;
+ uint32_t rx_drops_invalid_queue;
+ uint64_t rx_drops_mtu;
+ uint64_t rx_pkts_64_bytes;
+ uint64_t rx_pkts_65_to_127_bytes;
+ uint64_t rx_pkts_128_to_255_bytes;
+ uint64_t rx_pkts_256_to_511_bytes;
+ uint64_t rx_pkts_512_to_1023_bytes;
+ uint64_t rx_pkts_1024_to_1518_bytes;
+ uint64_t rx_pkts_1519_to_2047_bytes;
+ uint64_t rx_pkts_2048_to_4095_bytes;
+ uint64_t rx_pkts_4096_to_8191_bytes;
+ uint64_t rx_pkts_8192_to_9216_bytes;
+};
+
+struct oce_drv_stats {
+ struct oce_rx_stats rx;
+ struct oce_tx_stats tx;
+ union {
+ struct oce_be_stats be;
+ struct oce_xe201_stats xe201;
+ } u0;
+};
+
+
+
+#define MAX_LOCK_DESC_LEN 32
+struct oce_lock {
+ struct mtx mutex;
+ char name[MAX_LOCK_DESC_LEN+1];
+};
+#define OCE_LOCK struct oce_lock
+
+#define LOCK_CREATE(lock, desc) { \
+ strncpy((lock)->name, (desc), MAX_LOCK_DESC_LEN); \
+ (lock)->name[MAX_LOCK_DESC_LEN] = '\0'; \
+ mtx_init(&(lock)->mutex, (lock)->name, MTX_NETWORK_LOCK, MTX_DEF); \
+}
+#define LOCK_DESTROY(lock) \
+ if (mtx_initialized(&(lock)->mutex))\
+ mtx_destroy(&(lock)->mutex)
+#define TRY_LOCK(lock) mtx_trylock(&(lock)->mutex)
+#define LOCK(lock) mtx_lock(&(lock)->mutex)
+#define LOCKED(lock) mtx_owned(&(lock)->mutex)
+#define UNLOCK(lock) mtx_unlock(&(lock)->mutex)
+
+#define DEFAULT_MQ_MBOX_TIMEOUT (5 * 1000 * 1000)
+#define MBX_READY_TIMEOUT (1 * 1000 * 1000)
+#define DEFAULT_DRAIN_TIME 200
+#define MBX_TIMEOUT_SEC 5
+#define STAT_TIMEOUT 2000000
+
+/* size of the packet descriptor array in a transmit queue */
+#define OCE_TX_RING_SIZE 2048
+#define OCE_RX_RING_SIZE 1024
+#define OCE_WQ_PACKET_ARRAY_SIZE (OCE_TX_RING_SIZE/2)
+#define OCE_RQ_PACKET_ARRAY_SIZE (OCE_RX_RING_SIZE)
+
+struct oce_dev;
+
+enum eq_len {
+ EQ_LEN_256 = 256,
+ EQ_LEN_512 = 512,
+ EQ_LEN_1024 = 1024,
+ EQ_LEN_2048 = 2048,
+ EQ_LEN_4096 = 4096
+};
+
+enum eqe_size {
+ EQE_SIZE_4 = 4,
+ EQE_SIZE_16 = 16
+};
+
+enum qtype {
+ QTYPE_EQ,
+ QTYPE_MQ,
+ QTYPE_WQ,
+ QTYPE_RQ,
+ QTYPE_CQ,
+ QTYPE_RSS
+};
+
+typedef enum qstate_e {
+ QDELETED = 0x0,
+ QCREATED = 0x1
+} qstate_t;
+
+struct eq_config {
+ enum eq_len q_len;
+ enum eqe_size item_size;
+ uint32_t q_vector_num;
+ uint8_t min_eqd;
+ uint8_t max_eqd;
+ uint8_t cur_eqd;
+ uint8_t pad;
+};
+
+struct oce_eq {
+ uint32_t eq_id;
+ void *parent;
+ void *cb_context;
+ oce_ring_buffer_t *ring;
+ uint32_t ref_count;
+ qstate_t qstate;
+ struct oce_cq *cq[OCE_MAX_CQ_EQ];
+ int cq_valid;
+ struct eq_config eq_cfg;
+ int vector;
+};
+
+enum cq_len {
+ CQ_LEN_256 = 256,
+ CQ_LEN_512 = 512,
+ CQ_LEN_1024 = 1024
+};
+
+struct cq_config {
+ enum cq_len q_len;
+ uint32_t item_size;
+ boolean_t is_eventable;
+ boolean_t sol_eventable;
+ boolean_t nodelay;
+ uint16_t dma_coalescing;
+};
+
+typedef uint16_t(*cq_handler_t) (void *arg1);
+
+struct oce_cq {
+ uint32_t cq_id;
+ void *parent;
+ struct oce_eq *eq;
+ cq_handler_t cq_handler;
+ void *cb_arg;
+ oce_ring_buffer_t *ring;
+ qstate_t qstate;
+ struct cq_config cq_cfg;
+ uint32_t ref_count;
+};
+
+
+struct mq_config {
+ uint32_t eqd;
+ uint8_t q_len;
+ uint8_t pad[3];
+};
+
+
+struct oce_mq {
+ void *parent;
+ oce_ring_buffer_t *ring;
+ uint32_t mq_id;
+ struct oce_cq *cq;
+ struct oce_cq *async_cq;
+ uint32_t mq_free;
+ qstate_t qstate;
+ struct mq_config cfg;
+};
+
+struct oce_mbx_ctx {
+ struct oce_mbx *mbx;
+ void (*cb) (void *ctx);
+ void *cb_ctx;
+};
+
+struct wq_config {
+ uint8_t wq_type;
+ uint16_t buf_size;
+ uint8_t pad[1];
+ uint32_t q_len;
+ uint16_t pd_id;
+ uint16_t pci_fn_num;
+ uint32_t eqd; /* interrupt delay */
+ uint32_t nbufs;
+ uint32_t nhdl;
+};
+
+struct oce_tx_queue_stats {
+ uint64_t tx_pkts;
+ uint64_t tx_bytes;
+ uint32_t tx_reqs;
+ uint32_t tx_stops; /* number of times TX Q was stopped */
+ uint32_t tx_wrbs;
+ uint32_t tx_compl;
+ uint32_t tx_rate;
+ uint32_t ipv6_ext_hdr_tx_drop;
+};
+
+struct oce_wq {
+ OCE_LOCK tx_lock;
+ void *parent;
+ oce_ring_buffer_t *ring;
+ struct oce_cq *cq;
+ bus_dma_tag_t tag;
+ struct oce_packet_desc pckts[OCE_WQ_PACKET_ARRAY_SIZE];
+ uint32_t packets_in;
+ uint32_t packets_out;
+ uint32_t wqm_used;
+ boolean_t resched;
+ uint32_t wq_free;
+ uint32_t tx_deferd;
+ uint32_t pkt_drops;
+ qstate_t qstate;
+ uint16_t wq_id;
+ struct wq_config cfg;
+ int queue_index;
+ struct oce_tx_queue_stats tx_stats;
+ struct buf_ring *br;
+ struct task txtask;
+};
+
+struct rq_config {
+ uint32_t q_len;
+ uint32_t frag_size;
+ uint32_t mtu;
+ uint32_t if_id;
+ uint32_t is_rss_queue;
+ uint32_t eqd;
+ uint32_t nbufs;
+};
+
+struct oce_rx_queue_stats {
+ uint32_t rx_post_fail;
+ uint32_t rx_ucast_pkts;
+ uint32_t rx_compl;
+ uint64_t rx_bytes;
+ uint64_t rx_bytes_prev;
+ uint64_t rx_pkts;
+ uint32_t rx_rate;
+ uint32_t rx_mcast_pkts;
+ uint32_t rxcp_err;
+ uint32_t rx_frags;
+ uint32_t prev_rx_frags;
+ uint32_t rx_fps;
+};
+
+
+struct oce_rq {
+ struct rq_config cfg;
+ uint32_t rq_id;
+ int queue_index;
+ uint32_t rss_cpuid;
+ void *parent;
+ oce_ring_buffer_t *ring;
+ struct oce_cq *cq;
+ void *pad1;
+ bus_dma_tag_t tag;
+ struct oce_packet_desc pckts[OCE_RQ_PACKET_ARRAY_SIZE];
+ uint32_t packets_in;
+ uint32_t packets_out;
+ uint32_t pending;
+#ifdef notdef
+ struct mbuf *head;
+ struct mbuf *tail;
+ int fragsleft;
+#endif
+ qstate_t qstate;
+ OCE_LOCK rx_lock;
+ struct oce_rx_queue_stats rx_stats;
+ struct lro_ctrl lro;
+ int lro_pkts_queued;
+
+};
+
+struct link_status {
+ uint8_t physical_port;
+ uint8_t mac_duplex;
+ uint8_t mac_speed;
+ uint8_t mac_fault;
+ uint8_t mgmt_mac_duplex;
+ uint8_t mgmt_mac_speed;
+ uint16_t qos_link_speed;
+ uint32_t logical_link_status;
+};
+
+
+
+#define OCE_FLAGS_PCIX 0x00000001
+#define OCE_FLAGS_PCIE 0x00000002
+#define OCE_FLAGS_MSI_CAPABLE 0x00000004
+#define OCE_FLAGS_MSIX_CAPABLE 0x00000008
+#define OCE_FLAGS_USING_MSI 0x00000010
+#define OCE_FLAGS_USING_MSIX 0x00000020
+#define OCE_FLAGS_FUNCRESET_RQD 0x00000040
+#define OCE_FLAGS_VIRTUAL_PORT 0x00000080
+#define OCE_FLAGS_MBOX_ENDIAN_RQD 0x00000100
+#define OCE_FLAGS_BE3 0x00000200
+#define OCE_FLAGS_XE201 0x00000400
+#define OCE_FLAGS_BE2 0x00000800
+
+#define OCE_DEV_BE2_CFG_BAR 1
+#define OCE_DEV_CFG_BAR 0
+#define OCE_PCI_CSR_BAR 2
+#define OCE_PCI_DB_BAR 4
+
+typedef struct oce_softc {
+ device_t dev;
+ OCE_LOCK dev_lock;
+
+ uint32_t flags;
+
+ uint32_t pcie_link_speed;
+ uint32_t pcie_link_width;
+
+ uint8_t fn; /* PCI function number */
+
+ struct resource *devcfg_res;
+ bus_space_tag_t devcfg_btag;
+ bus_space_handle_t devcfg_bhandle;
+ void *devcfg_vhandle;
+
+ struct resource *csr_res;
+ bus_space_tag_t csr_btag;
+ bus_space_handle_t csr_bhandle;
+ void *csr_vhandle;
+
+ struct resource *db_res;
+ bus_space_tag_t db_btag;
+ bus_space_handle_t db_bhandle;
+ void *db_vhandle;
+
+ OCE_INTR_INFO intrs[OCE_MAX_EQ];
+ int intr_count;
+
+ struct ifnet *ifp;
+
+ struct ifmedia media;
+ uint8_t link_status;
+ uint8_t link_speed;
+ uint8_t duplex;
+ uint32_t qos_link_speed;
+ uint32_t speed;
+
+ char fw_version[32];
+ struct mac_address_format macaddr;
+
+ OCE_DMA_MEM bsmbx;
+ OCE_LOCK bmbx_lock;
+
+ uint32_t config_number;
+ uint32_t asic_revision;
+ uint32_t port_id;
+ uint32_t function_mode;
+ uint32_t function_caps;
+ uint32_t max_tx_rings;
+ uint32_t max_rx_rings;
+
+ struct oce_wq *wq[OCE_MAX_WQ]; /* TX work queues */
+ struct oce_rq *rq[OCE_MAX_RQ]; /* RX work queues */
+ struct oce_cq *cq[OCE_MAX_CQ]; /* Completion queues */
+ struct oce_eq *eq[OCE_MAX_EQ]; /* Event queues */
+ struct oce_mq *mq; /* Mailbox queue */
+
+ uint32_t neqs;
+ uint32_t ncqs;
+ uint32_t nrqs;
+ uint32_t nwqs;
+
+ uint32_t tx_ring_size;
+ uint32_t rx_ring_size;
+ uint32_t rq_frag_size;
+ uint32_t rss_enable;
+
+ uint32_t if_id; /* interface ID */
+ uint32_t nifs; /* number of adapter interfaces, 0 or 1 */
+ uint32_t pmac_id; /* PMAC id */
+
+ uint32_t if_cap_flags;
+
+ uint32_t flow_control;
+ uint32_t promisc;
+ /*Vlan Filtering related */
+ eventhandler_tag vlan_attach;
+ eventhandler_tag vlan_detach;
+ uint16_t vlans_added;
+ uint8_t vlan_tag[MAX_VLANS];
+ /*stats */
+ OCE_DMA_MEM stats_mem;
+ struct oce_drv_stats oce_stats_info;
+ struct callout timer;
+ int8_t be3_native;
+ uint32_t pvid;
+
+} OCE_SOFTC, *POCE_SOFTC;
+
+
+
+/**************************************************
+ * BUS memory read/write macros
+ * BE3: accesses three BAR spaces (CFG, CSR, DB)
+ * Lancer: accesses one BAR space (CFG)
+ **************************************************/
+#define OCE_READ_REG32(sc, space, o) \
+ ((IS_BE(sc)) ? (bus_space_read_4((sc)->space##_btag, \
+ (sc)->space##_bhandle,o)) \
+ : (bus_space_read_4((sc)->devcfg_btag, \
+ (sc)->devcfg_bhandle,o)))
+#define OCE_READ_REG16(sc, space, o) \
+ ((IS_BE(sc)) ? (bus_space_read_2((sc)->space##_btag, \
+ (sc)->space##_bhandle,o)) \
+ : (bus_space_read_2((sc)->devcfg_btag, \
+ (sc)->devcfg_bhandle,o)))
+#define OCE_READ_REG8(sc, space, o) \
+ ((IS_BE(sc)) ? (bus_space_read_1((sc)->space##_btag, \
+ (sc)->space##_bhandle,o)) \
+ : (bus_space_read_1((sc)->devcfg_btag, \
+ (sc)->devcfg_bhandle,o)))
+
+#define OCE_WRITE_REG32(sc, space, o, v) \
+ ((IS_BE(sc)) ? (bus_space_write_4((sc)->space##_btag, \
+ (sc)->space##_bhandle,o,v)) \
+ : (bus_space_write_4((sc)->devcfg_btag, \
+ (sc)->devcfg_bhandle,o,v)))
+#define OCE_WRITE_REG16(sc, space, o, v) \
+ ((IS_BE(sc)) ? (bus_space_write_2((sc)->space##_btag, \
+ (sc)->space##_bhandle,o,v)) \
+ : (bus_space_write_2((sc)->devcfg_btag, \
+ (sc)->devcfg_bhandle,o,v)))
+#define OCE_WRITE_REG8(sc, space, o, v) \
+ ((IS_BE(sc)) ? (bus_space_write_1((sc)->space##_btag, \
+ (sc)->space##_bhandle,o,v)) \
+ : (bus_space_write_1((sc)->devcfg_btag, \
+ (sc)->devcfg_bhandle,o,v)))
+
+
+/***********************************************************
+ * DMA memory functions
+ ***********************************************************/
+#define oce_dma_sync(d, f) bus_dmamap_sync((d)->tag, (d)->map, f)
+int oce_dma_alloc(POCE_SOFTC sc, bus_size_t size, POCE_DMA_MEM dma, int flags);
+void oce_dma_free(POCE_SOFTC sc, POCE_DMA_MEM dma);
+void oce_dma_map_addr(void *arg, bus_dma_segment_t * segs, int nseg, int error);
+void oce_destroy_ring_buffer(POCE_SOFTC sc, oce_ring_buffer_t *ring);
+oce_ring_buffer_t *oce_create_ring_buffer(POCE_SOFTC sc,
+ uint32_t q_len, uint32_t num_entries);
+/************************************************************
+ * oce_hw_xxx functions
+ ************************************************************/
+int oce_clear_rx_buf(struct oce_rq *rq);
+int oce_hw_pci_alloc(POCE_SOFTC sc);
+int oce_hw_init(POCE_SOFTC sc);
+int oce_hw_start(POCE_SOFTC sc);
+int oce_create_nw_interface(POCE_SOFTC sc);
+int oce_pci_soft_reset(POCE_SOFTC sc);
+int oce_hw_update_multicast(POCE_SOFTC sc);
+void oce_delete_nw_interface(POCE_SOFTC sc);
+void oce_hw_shutdown(POCE_SOFTC sc);
+void oce_hw_intr_enable(POCE_SOFTC sc);
+void oce_hw_intr_disable(POCE_SOFTC sc);
+void oce_hw_pci_free(POCE_SOFTC sc);
+
+/***********************************************************
+ * oce_queue_xxx functions
+ ***********************************************************/
+int oce_queue_init_all(POCE_SOFTC sc);
+int oce_start_rq(struct oce_rq *rq);
+int oce_start_wq(struct oce_wq *wq);
+int oce_start_mq(struct oce_mq *mq);
+int oce_start_rx(POCE_SOFTC sc);
+void oce_arm_eq(POCE_SOFTC sc,
+ int16_t qid, int npopped, uint32_t rearm, uint32_t clearint);
+void oce_queue_release_all(POCE_SOFTC sc);
+void oce_arm_cq(POCE_SOFTC sc, int16_t qid, int npopped, uint32_t rearm);
+void oce_drain_eq(struct oce_eq *eq);
+void oce_drain_mq_cq(void *arg);
+void oce_drain_rq_cq(struct oce_rq *rq);
+void oce_drain_wq_cq(struct oce_wq *wq);
+
+uint32_t oce_page_list(oce_ring_buffer_t *ring, struct phys_addr *pa_list);
+
+/***********************************************************
+ * cleanup functions
+ ***********************************************************/
+void oce_stop_rx(POCE_SOFTC sc);
+void oce_intr_free(POCE_SOFTC sc);
+void oce_free_posted_rxbuf(struct oce_rq *rq);
+#if defined(INET6) || defined(INET)
+void oce_free_lro(POCE_SOFTC sc);
+#endif
+
+
+/************************************************************
+ * Mailbox functions
+ ************************************************************/
+int oce_fw_clean(POCE_SOFTC sc);
+int oce_reset_fun(POCE_SOFTC sc);
+int oce_mbox_init(POCE_SOFTC sc);
+int oce_mbox_dispatch(POCE_SOFTC sc, uint32_t tmo_sec);
+int oce_get_fw_version(POCE_SOFTC sc);
+int oce_first_mcc_cmd(POCE_SOFTC sc);
+
+int oce_read_mac_addr(POCE_SOFTC sc, uint32_t if_id, uint8_t perm,
+ uint8_t type, struct mac_address_format *mac);
+int oce_get_fw_config(POCE_SOFTC sc);
+int oce_if_create(POCE_SOFTC sc, uint32_t cap_flags, uint32_t en_flags,
+ uint16_t vlan_tag, uint8_t *mac_addr, uint32_t *if_id);
+int oce_if_del(POCE_SOFTC sc, uint32_t if_id);
+int oce_config_vlan(POCE_SOFTC sc, uint32_t if_id,
+ struct normal_vlan *vtag_arr, uint8_t vtag_cnt,
+ uint32_t untagged, uint32_t enable_promisc);
+int oce_set_flow_control(POCE_SOFTC sc, uint32_t flow_control);
+int oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss);
+int oce_rxf_set_promiscuous(POCE_SOFTC sc, uint32_t enable);
+int oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl);
+int oce_get_link_status(POCE_SOFTC sc, struct link_status *link);
+int oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem);
+int oce_mbox_get_nic_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem);
+int oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
+ uint32_t reset_stats);
+int oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
+ uint32_t req_size, uint32_t reset_stats);
+int oce_update_multicast(POCE_SOFTC sc, POCE_DMA_MEM pdma_mem);
+int oce_pass_through_mbox(POCE_SOFTC sc, POCE_DMA_MEM dma_mem, uint32_t req_size);
+int oce_mbox_macaddr_del(POCE_SOFTC sc, uint32_t if_id, uint32_t pmac_id);
+int oce_mbox_macaddr_add(POCE_SOFTC sc, uint8_t *mac_addr,
+ uint32_t if_id, uint32_t *pmac_id);
+int oce_mbox_cmd_test_loopback(POCE_SOFTC sc, uint32_t port_num,
+ uint32_t loopback_type, uint32_t pkt_size, uint32_t num_pkts,
+ uint64_t pattern);
+
+int oce_mbox_cmd_set_loopback(POCE_SOFTC sc, uint8_t port_num,
+ uint8_t loopback_type, uint8_t enable);
+
+int oce_mbox_check_native_mode(POCE_SOFTC sc);
+int oce_mbox_post(POCE_SOFTC sc,
+ struct oce_mbx *mbx, struct oce_mbx_ctx *mbxctx);
+int oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode,
+ POCE_DMA_MEM pdma_mem, uint32_t num_bytes);
+int oce_mbox_lancer_write_flashrom(POCE_SOFTC sc, uint32_t data_size,
+ uint32_t data_offset,POCE_DMA_MEM pdma_mem,
+ uint32_t *written_data, uint32_t *additional_status);
+
+int oce_mbox_get_flashrom_crc(POCE_SOFTC sc, uint8_t *flash_crc,
+ uint32_t offset, uint32_t optype);
+int oce_mbox_get_phy_info(POCE_SOFTC sc, struct oce_phy_info *phy_info);
+int oce_mbox_create_rq(struct oce_rq *rq);
+int oce_mbox_create_wq(struct oce_wq *wq);
+int oce_mbox_create_eq(struct oce_eq *eq);
+int oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce,
+ uint32_t is_eventable);
+void mbx_common_req_hdr_init(struct mbx_hdr *hdr,
+ uint8_t dom,
+ uint8_t port,
+ uint8_t subsys,
+ uint8_t opcode,
+ uint32_t timeout, uint32_t pyld_len,
+ uint8_t version);
+
+
+uint16_t oce_mq_handler(void *arg);
+
+/************************************************************
+ * Transmit functions
+ ************************************************************/
+uint16_t oce_wq_handler(void *arg);
+void oce_start(struct ifnet *ifp);
+void oce_tx_task(void *arg, int npending);
+
+/************************************************************
+ * Receive functions
+ ************************************************************/
+int oce_alloc_rx_bufs(struct oce_rq *rq, int count);
+uint16_t oce_rq_handler(void *arg);
+
+
+/* Sysctl functions */
+void oce_add_sysctls(POCE_SOFTC sc);
+void oce_refresh_queue_stats(POCE_SOFTC sc);
+int oce_refresh_nic_stats(POCE_SOFTC sc);
+int oce_stats_init(POCE_SOFTC sc);
+void oce_stats_free(POCE_SOFTC sc);
+
+/* Capabilities */
+#define OCE_MODCAP_RSS 1
+#define OCE_MAX_RSP_HANDLED 64
+extern uint32_t oce_max_rsp_handled; /* max responses */
+
+#define OCE_MAC_LOOPBACK 0x0
+#define OCE_PHY_LOOPBACK 0x1
+#define OCE_ONE_PORT_EXT_LOOPBACK 0x2
+#define OCE_NO_LOOPBACK 0xff
+
+#define atomic_inc_32(x) atomic_add_32(x, 1)
+#define atomic_dec_32(x) atomic_subtract_32(x, 1)
+
+#define LE_64(x) htole64(x)
+#define LE_32(x) htole32(x)
+#define LE_16(x) htole16(x)
+#define DW_SWAP(x, l)
+#define IS_ALIGNED(x,a) ((x % a) == 0)
+#define ADDR_HI(x) ((uint32_t)((uint64_t)(x) >> 32))
+#define ADDR_LO(x) ((uint32_t)((uint64_t)(x) & 0xffffffff));
+
+#define IF_LRO_ENABLED(sc) (((sc)->ifp->if_capenable & IFCAP_LRO) ? 1:0)
+#define IF_LSO_ENABLED(sc) (((sc)->ifp->if_capenable & IFCAP_TSO4) ? 1:0)
+#define IF_CSUM_ENABLED(sc) (((sc)->ifp->if_capenable & IFCAP_HWCSUM) ? 1:0)
+
+#define OCE_LOG2(x) (oce_highbit(x))
+static inline uint32_t oce_highbit(uint32_t x)
+{
+ int i;
+ int c;
+ int b;
+
+ c = 0;
+ b = 0;
+
+ for (i = 0; i < 32; i++) {
+ if ((1 << i) & x) {
+ c++;
+ b = i;
+ }
+ }
+
+ if (c == 1)
+ return b;
+
+ return 0;
+}
+
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/oce/oce_mbox.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/oce/oce_mbox.c Fri Mar 02 17:36:33 2012 +0200
@@ -0,0 +1,1739 @@
+/*-
+ * Copyright (C) 2012 Emulex
+ * 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.
+ *
+ * 3. Neither the name of the Emulex Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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.
+ *
+ * Contact Information:
+ * freebsd-drivers at emulex.com
+ *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
+ */
+
+
+/* $FreeBSD: head/sys/dev/oce/oce_mbox.c 231879 2012-02-17 13:55:17Z luigi $ */
+
+#include "oce_if.h"
+
+
+/**
+ * @brief Reset (firmware) common function
+ * @param sc software handle to the device
+ * @returns 0 on success, ETIMEDOUT on failure
+ */
+int
+oce_reset_fun(POCE_SOFTC sc)
+{
+ struct oce_mbx *mbx;
+ struct oce_bmbx *mb;
+ struct ioctl_common_function_reset *fwcmd;
+ int rc = 0;
+
+ if (sc->flags & OCE_FLAGS_FUNCRESET_RQD) {
+ mb = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
+ mbx = &mb->mbx;
+ bzero(mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct ioctl_common_function_reset *)&mbx->payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_FUNCTION_RESET,
+ 10, /* MBX_TIMEOUT_SEC */
+ sizeof(struct
+ ioctl_common_function_reset),
+ OCE_MBX_VER_V0);
+
+ mbx->u0.s.embedded = 1;
+ mbx->payload_length =
+ sizeof(struct ioctl_common_function_reset);
+
+ rc = oce_mbox_dispatch(sc, 2);
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief This funtions tells firmware we are
+ * done with commands.
+ * @param sc software handle to the device
+ * @returns 0 on success, ETIMEDOUT on failure
+ */
+int
+oce_fw_clean(POCE_SOFTC sc)
+{
+ struct oce_bmbx *mbx;
+ uint8_t *ptr;
+ int ret = 0;
+
+ mbx = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
+ ptr = (uint8_t *) &mbx->mbx;
+
+ /* Endian Signature */
+ *ptr++ = 0xff;
+ *ptr++ = 0xaa;
+ *ptr++ = 0xbb;
+ *ptr++ = 0xff;
+ *ptr++ = 0xff;
+ *ptr++ = 0xcc;
+ *ptr++ = 0xdd;
+ *ptr = 0xff;
+
+ ret = oce_mbox_dispatch(sc, 2);
+
+ return ret;
+}
+
+
+/**
+ * @brief Mailbox wait
+ * @param sc software handle to the device
+ * @param tmo_sec timeout in seconds
+ */
+static int
+oce_mbox_wait(POCE_SOFTC sc, uint32_t tmo_sec)
+{
+ tmo_sec *= 10000;
+ pd_mpu_mbox_db_t mbox_db;
+
+ for (;;) {
+ if (tmo_sec != 0) {
+ if (--tmo_sec == 0)
+ break;
+ }
+
+ mbox_db.dw0 = OCE_READ_REG32(sc, db, PD_MPU_MBOX_DB);
+
+ if (mbox_db.bits.ready)
+ return 0;
+
+ DELAY(100);
+ }
+
+ device_printf(sc->dev, "Mailbox timed out\n");
+
+ return ETIMEDOUT;
+}
+
+
+/**
+ * @brief Mailbox dispatch
+ * @param sc software handle to the device
+ * @param tmo_sec timeout in seconds
+ */
+int
+oce_mbox_dispatch(POCE_SOFTC sc, uint32_t tmo_sec)
+{
+ pd_mpu_mbox_db_t mbox_db;
+ uint32_t pa;
+ int rc;
+
+ oce_dma_sync(&sc->bsmbx, BUS_DMASYNC_PREWRITE);
+ pa = (uint32_t) ((uint64_t) sc->bsmbx.paddr >> 34);
+ bzero(&mbox_db, sizeof(pd_mpu_mbox_db_t));
+ mbox_db.bits.ready = 0;
+ mbox_db.bits.hi = 1;
+ mbox_db.bits.address = pa;
+
+ rc = oce_mbox_wait(sc, tmo_sec);
+ if (rc == 0) {
+ OCE_WRITE_REG32(sc, db, PD_MPU_MBOX_DB, mbox_db.dw0);
+
+ pa = (uint32_t) ((uint64_t) sc->bsmbx.paddr >> 4) & 0x3fffffff;
+ mbox_db.bits.ready = 0;
+ mbox_db.bits.hi = 0;
+ mbox_db.bits.address = pa;
+
+ rc = oce_mbox_wait(sc, tmo_sec);
+
+ if (rc == 0) {
+ OCE_WRITE_REG32(sc, db, PD_MPU_MBOX_DB, mbox_db.dw0);
+
+ rc = oce_mbox_wait(sc, tmo_sec);
+
+ oce_dma_sync(&sc->bsmbx, BUS_DMASYNC_POSTWRITE);
+ }
+ }
+
+ return rc;
+}
+
+
+
+/**
+ * @brief Mailbox common request header initialization
+ * @param hdr mailbox header
+ * @param dom domain
+ * @param port port
+ * @param subsys subsystem
+ * @param opcode opcode
+ * @param timeout timeout
+ * @param pyld_len payload length
+ */
+void
+mbx_common_req_hdr_init(struct mbx_hdr *hdr,
+ uint8_t dom, uint8_t port,
+ uint8_t subsys, uint8_t opcode,
+ uint32_t timeout, uint32_t pyld_len,
+ uint8_t version)
+{
+ hdr->u0.req.opcode = opcode;
+ hdr->u0.req.subsystem = subsys;
+ hdr->u0.req.port_number = port;
+ hdr->u0.req.domain = dom;
+
+ hdr->u0.req.timeout = timeout;
+ hdr->u0.req.request_length = pyld_len - sizeof(struct mbx_hdr);
+ hdr->u0.req.version = version;
+}
+
+
+
+/**
+ * @brief Function to initialize the hw with host endian information
+ * @param sc software handle to the device
+ * @returns 0 on success, ETIMEDOUT on failure
+ */
+int
+oce_mbox_init(POCE_SOFTC sc)
+{
+ struct oce_bmbx *mbx;
+ uint8_t *ptr;
+ int ret = 0;
+
+ if (sc->flags & OCE_FLAGS_MBOX_ENDIAN_RQD) {
+ mbx = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
+ ptr = (uint8_t *) &mbx->mbx;
+
+ /* Endian Signature */
+ *ptr++ = 0xff;
+ *ptr++ = 0x12;
+ *ptr++ = 0x34;
+ *ptr++ = 0xff;
+ *ptr++ = 0xff;
+ *ptr++ = 0x56;
+ *ptr++ = 0x78;
+ *ptr = 0xff;
+
+ ret = oce_mbox_dispatch(sc, 0);
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Function to get the firmware version
+ * @param sc software handle to the device
+ * @returns 0 on success, EIO on failure
+ */
+int
+oce_get_fw_version(POCE_SOFTC sc)
+{
+ struct oce_mbx mbx;
+ struct mbx_get_common_fw_version *fwcmd;
+ int ret = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_get_common_fw_version *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_GET_FW_VERSION,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_get_common_fw_version),
+ OCE_MBX_VER_V0);
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_get_common_fw_version);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ ret = oce_mbox_post(sc, &mbx, NULL);
+ if (ret)
+ return ret;
+
+ bcopy(fwcmd->params.rsp.fw_ver_str, sc->fw_version, 32);
+
+ return 0;
+}
+
+
+/**
+ * @brief Firmware will send gracious notifications during
+ * attach only after sending first mcc commnad. We
+ * use MCC queue only for getting async and mailbox
+ * for sending cmds. So to get gracious notifications
+ * atleast send one dummy command on mcc.
+ */
+int
+oce_first_mcc_cmd(POCE_SOFTC sc)
+{
+ struct oce_mbx *mbx;
+ struct oce_mq *mq = sc->mq;
+ struct mbx_get_common_fw_version *fwcmd;
+ uint32_t reg_value;
+
+ mbx = RING_GET_PRODUCER_ITEM_VA(mq->ring, struct oce_mbx);
+ bzero(mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_get_common_fw_version *)&mbx->payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_GET_FW_VERSION,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_get_common_fw_version),
+ OCE_MBX_VER_V0);
+ mbx->u0.s.embedded = 1;
+ mbx->payload_length = sizeof(struct mbx_get_common_fw_version);
+ bus_dmamap_sync(mq->ring->dma.tag, mq->ring->dma.map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ RING_PUT(mq->ring, 1);
+ reg_value = (1 << 16) | mq->mq_id;
+ OCE_WRITE_REG32(sc, db, PD_MQ_DB, reg_value);
+
+ return 0;
+}
+
+/**
+ * @brief Function to post a MBX to the mbox
+ * @param sc software handle to the device
+ * @param mbx pointer to the MBX to send
+ * @param mbxctx pointer to the mbx context structure
+ * @returns 0 on success, error on failure
+ */
+int
+oce_mbox_post(POCE_SOFTC sc, struct oce_mbx *mbx, struct oce_mbx_ctx *mbxctx)
+{
+ struct oce_mbx *mb_mbx = NULL;
+ struct oce_mq_cqe *mb_cqe = NULL;
+ struct oce_bmbx *mb = NULL;
+ int rc = 0;
+ uint32_t tmo = 0;
+ uint32_t cstatus = 0;
+ uint32_t xstatus = 0;
+
+ LOCK(&sc->bmbx_lock);
+
+ mb = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
+ mb_mbx = &mb->mbx;
+
+ /* get the tmo */
+ tmo = mbx->tag[0];
+ mbx->tag[0] = 0;
+
+ /* copy mbx into mbox */
+ bcopy(mbx, mb_mbx, sizeof(struct oce_mbx));
+
+ /* now dispatch */
+ rc = oce_mbox_dispatch(sc, tmo);
+ if (rc == 0) {
+ /*
+ * the command completed successfully. Now get the
+ * completion queue entry
+ */
+ mb_cqe = &mb->cqe;
+ DW_SWAP(u32ptr(&mb_cqe->u0.dw[0]), sizeof(struct oce_mq_cqe));
+
+ /* copy mbox mbx back */
+ bcopy(mb_mbx, mbx, sizeof(struct oce_mbx));
+
+ /* pick up the mailbox status */
+ cstatus = mb_cqe->u0.s.completion_status;
+ xstatus = mb_cqe->u0.s.extended_status;
+
+ /*
+ * store the mbx context in the cqe tag section so that
+ * the upper layer handling the cqe can associate the mbx
+ * with the response
+ */
+ if (cstatus == 0 && mbxctx) {
+ /* save context */
+ mbxctx->mbx = mb_mbx;
+ bcopy(&mbxctx, mb_cqe->u0.s.mq_tag,
+ sizeof(struct oce_mbx_ctx *));
+ }
+ }
+
+ UNLOCK(&sc->bmbx_lock);
+
+ return rc;
+}
+
+/**
+ * @brief Function to read the mac address associated with an interface
+ * @param sc software handle to the device
+ * @param if_id interface id to read the address from
+ * @param perm set to 1 if reading the factory mac address.
+ * In this case if_id is ignored
+ * @param type type of the mac address, whether network or storage
+ * @param[out] mac [OUTPUT] pointer to a buffer containing the
+ * mac address when the command succeeds.
+ * @returns 0 on success, EIO on failure
+ */
+int
+oce_read_mac_addr(POCE_SOFTC sc, uint32_t if_id,
+ uint8_t perm, uint8_t type, struct mac_address_format *mac)
+{
+ struct oce_mbx mbx;
+ struct mbx_query_common_iface_mac *fwcmd;
+ int ret = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_query_common_iface_mac *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_QUERY_IFACE_MAC,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_query_common_iface_mac),
+ OCE_MBX_VER_V0);
+
+ fwcmd->params.req.permanent = perm;
+ if (!perm)
+ fwcmd->params.req.if_id = (uint16_t) if_id;
+ else
+ fwcmd->params.req.if_id = 0;
+
+ fwcmd->params.req.type = type;
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_query_common_iface_mac);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ ret = oce_mbox_post(sc, &mbx, NULL);
+ if (ret)
+ return ret;
+
+ /* copy the mac addres in the output parameter */
+ mac->size_of_struct = fwcmd->params.rsp.mac.size_of_struct;
+ bcopy(&fwcmd->params.rsp.mac.mac_addr[0], &mac->mac_addr[0],
+ mac->size_of_struct);
+
+ return 0;
+}
+
+/**
+ * @brief Function to query the fw attributes from the hw
+ * @param sc software handle to the device
+ * @returns 0 on success, EIO on failure
+ */
+int
+oce_get_fw_config(POCE_SOFTC sc)
+{
+ struct oce_mbx mbx;
+ struct mbx_common_query_fw_config *fwcmd;
+ int ret = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_common_query_fw_config *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_common_query_fw_config),
+ OCE_MBX_VER_V0);
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_common_query_fw_config);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ ret = oce_mbox_post(sc, &mbx, NULL);
+ if (ret)
+ return ret;
+
+ DW_SWAP(u32ptr(fwcmd), sizeof(struct mbx_common_query_fw_config));
+
+ sc->config_number = fwcmd->params.rsp.config_number;
+ sc->asic_revision = fwcmd->params.rsp.asic_revision;
+ sc->port_id = fwcmd->params.rsp.port_id;
+ sc->function_mode = fwcmd->params.rsp.function_mode;
+ sc->function_caps = fwcmd->params.rsp.function_caps;
+
+ if (fwcmd->params.rsp.ulp[0].ulp_mode & ULP_NIC_MODE) {
+ sc->max_tx_rings = fwcmd->params.rsp.ulp[0].nic_wq_tot;
+ sc->max_rx_rings = fwcmd->params.rsp.ulp[0].lro_rqid_tot;
+ } else {
+ sc->max_tx_rings = fwcmd->params.rsp.ulp[1].nic_wq_tot;
+ sc->max_rx_rings = fwcmd->params.rsp.ulp[1].lro_rqid_tot;
+ }
+
+ return 0;
+
+}
+
+/**
+ *
+ * @brief function to create a device interface
+ * @param sc software handle to the device
+ * @param cap_flags capability flags
+ * @param en_flags enable capability flags
+ * @param vlan_tag optional vlan tag to associate with the if
+ * @param mac_addr pointer to a buffer containing the mac address
+ * @param[out] if_id [OUTPUT] pointer to an integer to hold the ID of the
+ interface created
+ * @returns 0 on success, EIO on failure
+ */
+int
+oce_if_create(POCE_SOFTC sc,
+ uint32_t cap_flags,
+ uint32_t en_flags,
+ uint16_t vlan_tag,
+ uint8_t *mac_addr,
+ uint32_t *if_id)
+{
+ struct oce_mbx mbx;
+ struct mbx_create_common_iface *fwcmd;
+ int rc = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_create_common_iface *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_CREATE_IFACE,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_create_common_iface),
+ OCE_MBX_VER_V0);
+ DW_SWAP(u32ptr(&fwcmd->hdr), sizeof(struct mbx_hdr));
+
+ fwcmd->params.req.version = 0;
+ fwcmd->params.req.cap_flags = LE_32(cap_flags);
+ fwcmd->params.req.enable_flags = LE_32(en_flags);
+ if (mac_addr != NULL) {
+ bcopy(mac_addr, &fwcmd->params.req.mac_addr[0], 6);
+ fwcmd->params.req.vlan_tag.u0.normal.vtag = LE_16(vlan_tag);
+ fwcmd->params.req.mac_invalid = 0;
+ } else {
+ fwcmd->params.req.mac_invalid = 1;
+ }
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_create_common_iface);
+ DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ if (rc)
+ return rc;
+
+ *if_id = LE_32(fwcmd->params.rsp.if_id);
+
+ if (mac_addr != NULL)
+ sc->pmac_id = LE_32(fwcmd->params.rsp.pmac_id);
+
+ return 0;
+}
+
+/**
+ * @brief Function to delete an interface
+ * @param sc software handle to the device
+ * @param if_id ID of the interface to delete
+ * @returns 0 on success, EIO on failure
+ */
+int
+oce_if_del(POCE_SOFTC sc, uint32_t if_id)
+{
+ struct oce_mbx mbx;
+ struct mbx_destroy_common_iface *fwcmd;
+ int rc = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_destroy_common_iface *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_DESTROY_IFACE,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_destroy_common_iface),
+ OCE_MBX_VER_V0);
+
+ fwcmd->params.req.if_id = if_id;
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_destroy_common_iface);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ return rc;
+}
+
+/**
+ * @brief Function to send the mbx command to configure vlan
+ * @param sc software handle to the device
+ * @param if_id interface identifier index
+ * @param vtag_arr array of vlan tags
+ * @param vtag_cnt number of elements in array
+ * @param untagged boolean TRUE/FLASE
+ * @param enable_promisc flag to enable/disable VLAN promiscuous mode
+ * @returns 0 on success, EIO on failure
+ */
+int
+oce_config_vlan(POCE_SOFTC sc,
+ uint32_t if_id,
+ struct normal_vlan *vtag_arr,
+ uint8_t vtag_cnt, uint32_t untagged, uint32_t enable_promisc)
+{
+ struct oce_mbx mbx;
+ struct mbx_common_config_vlan *fwcmd;
+ int rc;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+ fwcmd = (struct mbx_common_config_vlan *)&mbx.payload;
+
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_CONFIG_IFACE_VLAN,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_common_config_vlan),
+ OCE_MBX_VER_V0);
+
+ fwcmd->params.req.if_id = (uint8_t) if_id;
+ fwcmd->params.req.promisc = (uint8_t) enable_promisc;
+ fwcmd->params.req.untagged = (uint8_t) untagged;
+ fwcmd->params.req.num_vlans = vtag_cnt;
+
+ if (!enable_promisc) {
+ bcopy(vtag_arr, fwcmd->params.req.tags.normal_vlans,
+ vtag_cnt * sizeof(struct normal_vlan));
+ }
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_common_config_vlan);
+ DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + mbx.payload_length));
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+
+ return rc;
+
+}
+
+/**
+ * @brief Function to set flow control capability in the hardware
+ * @param sc software handle to the device
+ * @param flow_control flow control flags to set
+ * @returns 0 on success, EIO on failure
+ */
+int
+oce_set_flow_control(POCE_SOFTC sc, uint32_t flow_control)
+{
+ struct oce_mbx mbx;
+ struct mbx_common_get_set_flow_control *fwcmd =
+ (struct mbx_common_get_set_flow_control *)&mbx.payload;
+ int rc;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_SET_FLOW_CONTROL,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_common_get_set_flow_control),
+ OCE_MBX_VER_V0);
+
+ if (flow_control & OCE_FC_TX)
+ fwcmd->tx_flow_control = 1;
+
+ if (flow_control & OCE_FC_RX)
+ fwcmd->rx_flow_control = 1;
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_common_get_set_flow_control);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+
+ return rc;
+}
+
+/**
+ * @brief Initialize the RSS CPU indirection table
+ *
+ * The table is used to choose the queue to place the incomming packets.
+ * Incomming packets are hashed. The lowest bits in the hash result
+ * are used as the index into the CPU indirection table.
+ * Each entry in the table contains the RSS CPU-ID returned by the NIC
+ * create. Based on the CPU ID, the receive completion is routed to
+ * the corresponding RSS CQs. (Non-RSS packets are always completed
+ * on the default (0) CQ).
+ *
+ * @param sc software handle to the device
+ * @param *fwcmd pointer to the rss mbox command
+ * @returns none
+ */
+static int
+oce_rss_itbl_init(POCE_SOFTC sc, struct mbx_config_nic_rss *fwcmd)
+{
+ int i = 0, j = 0, rc = 0;
+ uint8_t *tbl = fwcmd->params.req.cputable;
+
+
+ for (j = 0; j < sc->nrqs; j++) {
+ if (sc->rq[j]->cfg.is_rss_queue) {
+ tbl[i] = sc->rq[j]->rss_cpuid;
+ i = i + 1;
+ }
+ }
+ if (i == 0) {
+ device_printf(sc->dev, "error: Invalid number of RSS RQ's\n");
+ rc = ENXIO;
+
+ }
+
+ /* fill log2 value indicating the size of the CPU table */
+ if (rc == 0)
+ fwcmd->params.req.cpu_tbl_sz_log2 = LE_16(OCE_LOG2(i));
+
+ return rc;
+}
+
+/**
+ * @brief Function to set flow control capability in the hardware
+ * @param sc software handle to the device
+ * @param if_id interface id to read the address from
+ * @param enable_rss 0=disable, RSS_ENABLE_xxx flags otherwise
+ * @returns 0 on success, EIO on failure
+ */
+int
+oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss)
+{
+ int rc;
+ struct oce_mbx mbx;
+ struct mbx_config_nic_rss *fwcmd =
+ (struct mbx_config_nic_rss *)&mbx.payload;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_NIC,
+ NIC_CONFIG_RSS,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_config_nic_rss),
+ OCE_MBX_VER_V0);
+ if (enable_rss)
+ fwcmd->params.req.enable_rss = (RSS_ENABLE_IPV4 |
+ RSS_ENABLE_TCP_IPV4 |
+ RSS_ENABLE_IPV6 |
+ RSS_ENABLE_TCP_IPV6);
+ fwcmd->params.req.flush = OCE_FLUSH;
+ fwcmd->params.req.if_id = LE_32(if_id);
+
+ srandom(arc4random()); /* random entropy seed */
+ read_random(fwcmd->params.req.hash, sizeof(fwcmd->params.req.hash));
+
+ rc = oce_rss_itbl_init(sc, fwcmd);
+ if (rc == 0) {
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_config_nic_rss);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+
+ }
+
+ return rc;
+}
+
+/**
+ * @brief RXF function to enable/disable device promiscuous mode
+ * @param sc software handle to the device
+ * @param enable enable/disable flag
+ * @returns 0 on success, EIO on failure
+ * @note
+ * The NIC_CONFIG_PROMISCUOUS command deprecated for Lancer.
+ * This function uses the COMMON_SET_IFACE_RX_FILTER command instead.
+ */
+int
+oce_rxf_set_promiscuous(POCE_SOFTC sc, uint32_t enable)
+{
+ struct mbx_set_common_iface_rx_filter *fwcmd;
+ int sz = sizeof(struct mbx_set_common_iface_rx_filter);
+ iface_rx_filter_ctx_t *req;
+ OCE_DMA_MEM sgl;
+ int rc;
+
+ /* allocate mbx payload's dma scatter/gather memory */
+ rc = oce_dma_alloc(sc, sz, &sgl, 0);
+ if (rc)
+ return rc;
+
+ fwcmd = OCE_DMAPTR(&sgl, struct mbx_set_common_iface_rx_filter);
+
+ req = &fwcmd->params.req;
+ req->iface_flags_mask = MBX_RX_IFACE_FLAGS_PROMISCUOUS |
+ MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
+ if (enable) {
+ req->iface_flags = MBX_RX_IFACE_FLAGS_PROMISCUOUS |
+ MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
+ }
+ req->if_id = sc->if_id;
+
+ rc = oce_set_common_iface_rx_filter(sc, &sgl);
+ oce_dma_free(sc, &sgl);
+
+ return rc;
+}
+
+
+/**
+ * @brief Function modify and select rx filter options
+ * @param sc software handle to the device
+ * @param sgl scatter/gather request/response
+ * @returns 0 on success, error code on failure
+ */
+int
+oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl)
+{
+ struct oce_mbx mbx;
+ int mbx_sz = sizeof(struct mbx_set_common_iface_rx_filter);
+ struct mbx_set_common_iface_rx_filter *fwcmd;
+ int rc;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+ fwcmd = OCE_DMAPTR(sgl, struct mbx_set_common_iface_rx_filter);
+
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_SET_IFACE_RX_FILTER,
+ MBX_TIMEOUT_SEC,
+ mbx_sz,
+ OCE_MBX_VER_V0);
+
+ oce_dma_sync(sgl, BUS_DMASYNC_PREWRITE);
+ mbx.u0.s.embedded = 0;
+ mbx.u0.s.sge_count = 1;
+ mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(sgl->paddr);
+ mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(sgl->paddr);
+ mbx.payload.u0.u1.sgl[0].length = mbx_sz;
+ mbx.payload_length = mbx_sz;
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ return rc;
+}
+
+/**
+ * @brief Function to query the link status from the hardware
+ * @param sc software handle to the device
+ * @param[out] link pointer to the structure returning link attributes
+ * @returns 0 on success, EIO on failure
+ */
+int
+oce_get_link_status(POCE_SOFTC sc, struct link_status *link)
+{
+ struct oce_mbx mbx;
+ struct mbx_query_common_link_config *fwcmd;
+ int rc = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_query_common_link_config *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_QUERY_LINK_CONFIG,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_query_common_link_config),
+ OCE_MBX_VER_V0);
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_query_common_link_config);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+
+ if (rc) {
+ device_printf(sc->dev, "Could not get link speed: %d\n", rc);
+ } else {
+ /* interpret response */
+ bcopy(&fwcmd->params.rsp, link, sizeof(struct link_status));
+ link->logical_link_status = LE_32(link->logical_link_status);
+ link->qos_link_speed = LE_16(link->qos_link_speed);
+ }
+
+ return rc;
+}
+
+
+
+int
+oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem)
+{
+ struct oce_mbx mbx;
+ struct mbx_get_nic_stats_v0 *fwcmd;
+ int rc = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_nic_stats_v0);
+ bzero(fwcmd, sizeof(struct mbx_get_nic_stats_v0));
+
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_NIC,
+ NIC_GET_STATS,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_get_nic_stats_v0),
+ OCE_MBX_VER_V0);
+
+ mbx.u0.s.embedded = 0;
+ mbx.u0.s.sge_count = 1;
+
+ oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE);
+
+ mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr);
+ mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr);
+ mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_nic_stats_v0);
+
+ mbx.payload_length = sizeof(struct mbx_get_nic_stats_v0);
+
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+
+ oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
+
+ if (rc) {
+ device_printf(sc->dev,
+ "Could not get nic statistics: %d\n", rc);
+ }
+
+ return rc;
+}
+
+
+
+/**
+ * @brief Function to get NIC statistics
+ * @param sc software handle to the device
+ * @param *stats pointer to where to store statistics
+ * @param reset_stats resets statistics of set
+ * @returns 0 on success, EIO on failure
+ * @note command depricated in Lancer
+ */
+int
+oce_mbox_get_nic_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem)
+{
+ struct oce_mbx mbx;
+ struct mbx_get_nic_stats *fwcmd;
+ int rc = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+ fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_nic_stats);
+ bzero(fwcmd, sizeof(struct mbx_get_nic_stats));
+
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_NIC,
+ NIC_GET_STATS,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_get_nic_stats),
+ OCE_MBX_VER_V1);
+
+
+ mbx.u0.s.embedded = 0; /* stats too large for embedded mbx rsp */
+ mbx.u0.s.sge_count = 1; /* using scatter gather instead */
+
+ oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE);
+ mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr);
+ mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr);
+ mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_nic_stats);
+
+ mbx.payload_length = sizeof(struct mbx_get_nic_stats);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
+ if (rc) {
+ device_printf(sc->dev,
+ "Could not get nic statistics: %d\n", rc);
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Function to get pport (physical port) statistics
+ * @param sc software handle to the device
+ * @param *stats pointer to where to store statistics
+ * @param reset_stats resets statistics of set
+ * @returns 0 on success, EIO on failure
+ */
+int
+oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
+ uint32_t reset_stats)
+{
+ struct oce_mbx mbx;
+ struct mbx_get_pport_stats *fwcmd;
+ int rc = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+ fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_pport_stats);
+ bzero(fwcmd, sizeof(struct mbx_get_pport_stats));
+
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_NIC,
+ NIC_GET_PPORT_STATS,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_get_pport_stats),
+ OCE_MBX_VER_V0);
+
+ fwcmd->params.req.reset_stats = reset_stats;
+ fwcmd->params.req.port_number = sc->if_id;
+
+ mbx.u0.s.embedded = 0; /* stats too large for embedded mbx rsp */
+ mbx.u0.s.sge_count = 1; /* using scatter gather instead */
+
+ oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE);
+ mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr);
+ mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr);
+ mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_pport_stats);
+
+ mbx.payload_length = sizeof(struct mbx_get_pport_stats);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
+
+ if (rc != 0) {
+ device_printf(sc->dev,
+ "Could not get physical port statistics: %d\n", rc);
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief Function to get vport (virtual port) statistics
+ * @param sc software handle to the device
+ * @param *stats pointer to where to store statistics
+ * @param reset_stats resets statistics of set
+ * @returns 0 on success, EIO on failure
+ */
+int
+oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
+ uint32_t req_size, uint32_t reset_stats)
+{
+ struct oce_mbx mbx;
+ struct mbx_get_vport_stats *fwcmd;
+ int rc = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_vport_stats);
+ bzero(fwcmd, sizeof(struct mbx_get_vport_stats));
+
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_NIC,
+ NIC_GET_VPORT_STATS,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_get_vport_stats),
+ OCE_MBX_VER_V0);
+
+ fwcmd->params.req.reset_stats = reset_stats;
+ fwcmd->params.req.vport_number = sc->if_id;
+
+ mbx.u0.s.embedded = 0; /* stats too large for embedded mbx rsp */
+ mbx.u0.s.sge_count = 1; /* using scatter gather instead */
+
+ oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE);
+ mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr);
+ mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr);
+ mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_vport_stats);
+
+ mbx.payload_length = sizeof(struct mbx_get_vport_stats);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
+
+ if (rc != 0) {
+ device_printf(sc->dev,
+ "Could not get physical port statistics: %d\n", rc);
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief Function to update the muticast filter with
+ * values in dma_mem
+ * @param sc software handle to the device
+ * @param dma_mem pointer to dma memory region
+ * @returns 0 on success, EIO on failure
+ */
+int
+oce_update_multicast(POCE_SOFTC sc, POCE_DMA_MEM pdma_mem)
+{
+ struct oce_mbx mbx;
+ struct oce_mq_sge *sgl;
+ struct mbx_set_common_iface_multicast *req = NULL;
+ int rc = 0;
+
+ req = OCE_DMAPTR(pdma_mem, struct mbx_set_common_iface_multicast);
+ mbx_common_req_hdr_init(&req->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_SET_IFACE_MULTICAST,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_set_common_iface_multicast),
+ OCE_MBX_VER_V0);
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ mbx.u0.s.embedded = 0; /*Non embeded*/
+ mbx.payload_length = sizeof(struct mbx_set_common_iface_multicast);
+ mbx.u0.s.sge_count = 1;
+ sgl = &mbx.payload.u0.u1.sgl[0];
+ sgl->pa_hi = htole32(upper_32_bits(pdma_mem->paddr));
+ sgl->pa_lo = htole32((pdma_mem->paddr) & 0xFFFFFFFF);
+ sgl->length = htole32(mbx.payload_length);
+
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+
+ return rc;
+}
+
+
+/**
+ * @brief Function to send passthrough Ioctls
+ * @param sc software handle to the device
+ * @param dma_mem pointer to dma memory region
+ * @param req_size size of dma_mem
+ * @returns 0 on success, EIO on failure
+ */
+int
+oce_pass_through_mbox(POCE_SOFTC sc, POCE_DMA_MEM dma_mem, uint32_t req_size)
+{
+ struct oce_mbx mbx;
+ struct oce_mq_sge *sgl;
+ int rc = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ mbx.u0.s.embedded = 0; /*Non embeded*/
+ mbx.payload_length = req_size;
+ mbx.u0.s.sge_count = 1;
+ sgl = &mbx.payload.u0.u1.sgl[0];
+ sgl->pa_hi = htole32(upper_32_bits(dma_mem->paddr));
+ sgl->pa_lo = htole32((dma_mem->paddr) & 0xFFFFFFFF);
+ sgl->length = htole32(req_size);
+
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ return rc;
+}
+
+
+int
+oce_mbox_macaddr_add(POCE_SOFTC sc, uint8_t *mac_addr,
+ uint32_t if_id, uint32_t *pmac_id)
+{
+ struct oce_mbx mbx;
+ struct mbx_add_common_iface_mac *fwcmd;
+ int rc = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_add_common_iface_mac *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_ADD_IFACE_MAC,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_add_common_iface_mac),
+ OCE_MBX_VER_V0);
+
+ fwcmd->params.req.if_id = (uint16_t) if_id;
+ bcopy(mac_addr, fwcmd->params.req.mac_address, 6);
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_add_common_iface_mac);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ if (rc)
+ return rc;
+
+ *pmac_id = fwcmd->params.rsp.pmac_id;
+
+ return rc;
+}
+
+
+int
+oce_mbox_macaddr_del(POCE_SOFTC sc, uint32_t if_id, uint32_t pmac_id)
+{
+ struct oce_mbx mbx;
+ struct mbx_del_common_iface_mac *fwcmd;
+ int rc = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_del_common_iface_mac *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_DEL_IFACE_MAC,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_del_common_iface_mac),
+ OCE_MBX_VER_V0);
+
+ fwcmd->params.req.if_id = (uint16_t)if_id;
+ fwcmd->params.req.pmac_id = pmac_id;
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_del_common_iface_mac);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ return rc;
+}
+
+
+
+int
+oce_mbox_check_native_mode(POCE_SOFTC sc)
+{
+ struct oce_mbx mbx;
+ struct mbx_common_set_function_cap *fwcmd;
+ int rc = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_common_set_function_cap *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_SET_FUNCTIONAL_CAPS,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_common_set_function_cap),
+ OCE_MBX_VER_V0);
+
+ fwcmd->params.req.valid_capability_flags = CAP_SW_TIMESTAMPS |
+ CAP_BE3_NATIVE_ERX_API;
+
+ fwcmd->params.req.capability_flags = CAP_BE3_NATIVE_ERX_API;
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_common_set_function_cap);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ //if (rc != 0) This can fail in legacy mode. So skip
+ // FN_LEAVE(rc);
+
+ sc->be3_native = fwcmd->params.rsp.capability_flags
+ & CAP_BE3_NATIVE_ERX_API;
+
+ return 0;
+}
+
+
+
+int
+oce_mbox_cmd_set_loopback(POCE_SOFTC sc, uint8_t port_num,
+ uint8_t loopback_type, uint8_t enable)
+{
+ struct oce_mbx mbx;
+ struct mbx_lowlevel_set_loopback_mode *fwcmd;
+ int rc = 0;
+
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_lowlevel_set_loopback_mode *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_LOWLEVEL,
+ OPCODE_LOWLEVEL_SET_LOOPBACK_MODE,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_lowlevel_set_loopback_mode),
+ OCE_MBX_VER_V0);
+
+ fwcmd->params.req.src_port = port_num;
+ fwcmd->params.req.dest_port = port_num;
+ fwcmd->params.req.loopback_type = loopback_type;
+ fwcmd->params.req.loopback_state = enable;
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_lowlevel_set_loopback_mode);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+
+ return rc;
+
+}
+
+int
+oce_mbox_cmd_test_loopback(POCE_SOFTC sc, uint32_t port_num,
+ uint32_t loopback_type, uint32_t pkt_size, uint32_t num_pkts,
+ uint64_t pattern)
+{
+
+ struct oce_mbx mbx;
+ struct mbx_lowlevel_test_loopback_mode *fwcmd;
+ int rc = 0;
+
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_lowlevel_test_loopback_mode *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_LOWLEVEL,
+ OPCODE_LOWLEVEL_TEST_LOOPBACK,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_lowlevel_test_loopback_mode),
+ OCE_MBX_VER_V0);
+
+ fwcmd->params.req.pattern = pattern;
+ fwcmd->params.req.src_port = port_num;
+ fwcmd->params.req.dest_port = port_num;
+ fwcmd->params.req.pkt_size = pkt_size;
+ fwcmd->params.req.num_pkts = num_pkts;
+ fwcmd->params.req.loopback_type = loopback_type;
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_lowlevel_test_loopback_mode);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ if (rc)
+ return rc;
+
+ return(fwcmd->params.rsp.status);
+}
+
+int
+oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode,
+ POCE_DMA_MEM pdma_mem, uint32_t num_bytes)
+{
+
+ struct oce_mbx mbx;
+ struct oce_mq_sge *sgl = NULL;
+ struct mbx_common_read_write_flashrom *fwcmd = NULL;
+ int rc = 0, payload_len = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+ fwcmd = OCE_DMAPTR(pdma_mem, struct mbx_common_read_write_flashrom);
+ payload_len = sizeof(struct mbx_common_read_write_flashrom) + 32*1024;
+
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_WRITE_FLASHROM,
+ LONG_TIMEOUT,
+ payload_len,
+ OCE_MBX_VER_V0);
+
+ fwcmd->flash_op_type = optype;
+ fwcmd->flash_op_code = opcode;
+ fwcmd->data_buffer_size = num_bytes;
+
+ mbx.u0.s.embedded = 0; /*Non embeded*/
+ mbx.payload_length = payload_len;
+ mbx.u0.s.sge_count = 1;
+
+ sgl = &mbx.payload.u0.u1.sgl[0];
+ sgl->pa_hi = upper_32_bits(pdma_mem->paddr);
+ sgl->pa_lo = pdma_mem->paddr & 0xFFFFFFFF;
+ sgl->length = payload_len;
+
+ /* post the command */
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ if (rc) {
+ device_printf(sc->dev, "Write FlashROM mbox post failed\n");
+ } else {
+ rc = fwcmd->hdr.u0.rsp.status;
+ }
+
+ return rc;
+
+}
+
+int
+oce_mbox_get_flashrom_crc(POCE_SOFTC sc, uint8_t *flash_crc,
+ uint32_t offset, uint32_t optype)
+{
+
+ int rc = 0, payload_len = 0;
+ struct oce_mbx mbx;
+ struct mbx_common_read_write_flashrom *fwcmd;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_common_read_write_flashrom *)&mbx.payload;
+
+ /* Firmware requires extra 4 bytes with this ioctl. Since there
+ is enough room in the mbx payload it should be good enough
+ Reference: Bug 14853
+ */
+ payload_len = sizeof(struct mbx_common_read_write_flashrom) + 4;
+
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_READ_FLASHROM,
+ MBX_TIMEOUT_SEC,
+ payload_len,
+ OCE_MBX_VER_V0);
+
+ fwcmd->flash_op_type = optype;
+ fwcmd->flash_op_code = FLASHROM_OPER_REPORT;
+ fwcmd->data_offset = offset;
+ fwcmd->data_buffer_size = 0x4;
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = payload_len;
+
+ /* post the command */
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ if (rc) {
+ device_printf(sc->dev, "Read FlashROM CRC mbox post failed\n");
+ } else {
+ bcopy(fwcmd->data_buffer, flash_crc, 4);
+ rc = fwcmd->hdr.u0.rsp.status;
+ }
+ return rc;
+}
+
+int
+oce_mbox_get_phy_info(POCE_SOFTC sc, struct oce_phy_info *phy_info)
+{
+
+ struct oce_mbx mbx;
+ struct mbx_common_phy_info *fwcmd;
+ int rc = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_common_phy_info *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_GET_PHY_CONFIG,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_common_phy_info),
+ OCE_MBX_VER_V0);
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_common_phy_info);
+
+ /* now post the command */
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ if (rc) {
+ device_printf(sc->dev, "Read PHY info mbox post failed\n");
+ } else {
+ rc = fwcmd->hdr.u0.rsp.status;
+ phy_info->phy_type = fwcmd->params.rsp.phy_info.phy_type;
+ phy_info->interface_type =
+ fwcmd->params.rsp.phy_info.interface_type;
+ phy_info->auto_speeds_supported =
+ fwcmd->params.rsp.phy_info.auto_speeds_supported;
+ phy_info->fixed_speeds_supported =
+ fwcmd->params.rsp.phy_info.fixed_speeds_supported;
+ phy_info->misc_params =fwcmd->params.rsp.phy_info.misc_params;
+
+ }
+ return rc;
+
+}
+
+
+int
+oce_mbox_lancer_write_flashrom(POCE_SOFTC sc, uint32_t data_size,
+ uint32_t data_offset, POCE_DMA_MEM pdma_mem,
+ uint32_t *written_data, uint32_t *additional_status)
+{
+
+ struct oce_mbx mbx;
+ struct mbx_lancer_common_write_object *fwcmd = NULL;
+ int rc = 0, payload_len = 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+ payload_len = sizeof(struct mbx_lancer_common_write_object);
+
+ mbx.u0.s.embedded = 1;/* Embedded */
+ mbx.payload_length = payload_len;
+ fwcmd = (struct mbx_lancer_common_write_object *)&mbx.payload;
+
+ /* initialize the ioctl header */
+ mbx_common_req_hdr_init(&fwcmd->params.req.hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_WRITE_OBJECT,
+ LONG_TIMEOUT,
+ payload_len,
+ OCE_MBX_VER_V0);
+
+ fwcmd->params.req.write_length = data_size;
+ if (data_size == 0)
+ fwcmd->params.req.eof = 1;
+ else
+ fwcmd->params.req.eof = 0;
+
+ strcpy(fwcmd->params.req.object_name, "/prg");
+ fwcmd->params.req.descriptor_count = 1;
+ fwcmd->params.req.write_offset = data_offset;
+ fwcmd->params.req.buffer_length = data_size;
+ fwcmd->params.req.address_lower = pdma_mem->paddr & 0xFFFFFFFF;
+ fwcmd->params.req.address_upper = upper_32_bits(pdma_mem->paddr);
+
+ /* post the command */
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ if (rc) {
+ device_printf(sc->dev,
+ "Write Lancer FlashROM mbox post failed\n");
+ } else {
+ *written_data = fwcmd->params.rsp.actual_write_length;
+ *additional_status = fwcmd->params.rsp.additional_status;
+ rc = fwcmd->params.rsp.status;
+ }
+ return rc;
+
+}
+
+
+
+int
+oce_mbox_create_rq(struct oce_rq *rq)
+{
+
+ struct oce_mbx mbx;
+ struct mbx_create_nic_rq *fwcmd;
+ POCE_SOFTC sc = rq->parent;
+ int rc, num_pages = 0;
+
+ if (rq->qstate == QCREATED)
+ return 0;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_create_nic_rq *)&mbx.payload;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_NIC,
+ NIC_CREATE_RQ, MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_create_nic_rq),
+ OCE_MBX_VER_V0);
+
+ /* oce_page_list will also prepare pages */
+ num_pages = oce_page_list(rq->ring, &fwcmd->params.req.pages[0]);
+
+ if (IS_XE201(sc)) {
+ fwcmd->params.req.frag_size = rq->cfg.frag_size/2048;
+ fwcmd->params.req.page_size = 1;
+ fwcmd->hdr.u0.req.version = OCE_MBX_VER_V1;
+ } else
+ fwcmd->params.req.frag_size = OCE_LOG2(rq->cfg.frag_size);
+ fwcmd->params.req.num_pages = num_pages;
+ fwcmd->params.req.cq_id = rq->cq->cq_id;
+ fwcmd->params.req.if_id = sc->if_id;
+ fwcmd->params.req.max_frame_size = rq->cfg.mtu;
+ fwcmd->params.req.is_rss_queue = rq->cfg.is_rss_queue;
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_create_nic_rq);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ if (rc)
+ goto error;
+
+ rq->rq_id = fwcmd->params.rsp.rq_id;
+ rq->rss_cpuid = fwcmd->params.rsp.rss_cpuid;
+
+ return 0;
+error:
+ device_printf(sc->dev, "Mbox Create RQ failed\n");
+ return rc;
+
+}
+
+
+
+int
+oce_mbox_create_wq(struct oce_wq *wq)
+{
+ struct oce_mbx mbx;
+ struct mbx_create_nic_wq *fwcmd;
+ POCE_SOFTC sc = wq->parent;
+ int rc = 0, version, num_pages;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_create_nic_wq *)&mbx.payload;
+ if (IS_XE201(sc)) {
+ version = OCE_MBX_VER_V1;
+ fwcmd->params.req.if_id = sc->if_id;
+ } else
+ version = OCE_MBX_VER_V0;
+
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_NIC,
+ NIC_CREATE_WQ, MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_create_nic_wq),
+ version);
+
+ num_pages = oce_page_list(wq->ring, &fwcmd->params.req.pages[0]);
+
+ fwcmd->params.req.nic_wq_type = wq->cfg.wq_type;
+ fwcmd->params.req.num_pages = num_pages;
+ fwcmd->params.req.wq_size = OCE_LOG2(wq->cfg.q_len) + 1;
+ fwcmd->params.req.cq_id = wq->cq->cq_id;
+ fwcmd->params.req.ulp_num = 1;
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_create_nic_wq);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ if (rc)
+ goto error;
+
+ wq->wq_id = LE_16(fwcmd->params.rsp.wq_id);
+
+ return 0;
+error:
+ device_printf(sc->dev, "Mbox Create WQ failed\n");
+ return rc;
+
+}
+
+
+
+int
+oce_mbox_create_eq(struct oce_eq *eq)
+{
+ struct oce_mbx mbx;
+ struct mbx_create_common_eq *fwcmd;
+ POCE_SOFTC sc = eq->parent;
+ int rc = 0;
+ uint32_t num_pages;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_create_common_eq *)&mbx.payload;
+
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_CREATE_EQ, MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_create_common_eq),
+ OCE_MBX_VER_V0);
+
+ num_pages = oce_page_list(eq->ring, &fwcmd->params.req.pages[0]);
+ fwcmd->params.req.ctx.num_pages = num_pages;
+ fwcmd->params.req.ctx.valid = 1;
+ fwcmd->params.req.ctx.size = (eq->eq_cfg.item_size == 4) ? 0 : 1;
+ fwcmd->params.req.ctx.count = OCE_LOG2(eq->eq_cfg.q_len / 256);
+ fwcmd->params.req.ctx.armed = 0;
+ fwcmd->params.req.ctx.delay_mult = eq->eq_cfg.cur_eqd;
+
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_create_common_eq);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ if (rc)
+ goto error;
+
+ eq->eq_id = LE_16(fwcmd->params.rsp.eq_id);
+
+ return 0;
+error:
+ device_printf(sc->dev, "Mbox Create EQ failed\n");
+ return rc;
+}
+
+
+
+int
+oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce, uint32_t is_eventable)
+{
+ struct oce_mbx mbx;
+ struct mbx_create_common_cq *fwcmd;
+ POCE_SOFTC sc = cq->parent;
+ uint8_t version;
+ oce_cq_ctx_t *ctx;
+ uint32_t num_pages, page_size;
+ int rc = 0;
+
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_create_common_cq *)&mbx.payload;
+
+ if (IS_XE201(sc))
+ version = OCE_MBX_VER_V2;
+ else
+ version = OCE_MBX_VER_V0;
+
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_CREATE_CQ,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_create_common_cq),
+ version);
+
+ ctx = &fwcmd->params.req.cq_ctx;
+
+ num_pages = oce_page_list(cq->ring, &fwcmd->params.req.pages[0]);
+ page_size = 1; /* 1 for 4K */
+
+ if (version == OCE_MBX_VER_V2) {
+ ctx->v2.num_pages = LE_16(num_pages);
+ ctx->v2.page_size = page_size;
+ ctx->v2.eventable = is_eventable;
+ ctx->v2.valid = 1;
+ ctx->v2.count = OCE_LOG2(cq->cq_cfg.q_len / 256);
+ ctx->v2.nodelay = cq->cq_cfg.nodelay;
+ ctx->v2.coalesce_wm = ncoalesce;
+ ctx->v2.armed = 0;
+ ctx->v2.eq_id = cq->eq->eq_id;
+ if (ctx->v2.count == 3) {
+ if (cq->cq_cfg.q_len > (4*1024)-1)
+ ctx->v2.cqe_count = (4*1024)-1;
+ else
+ ctx->v2.cqe_count = cq->cq_cfg.q_len;
+ }
+ } else {
+ ctx->v0.num_pages = LE_16(num_pages);
+ ctx->v0.eventable = is_eventable;
+ ctx->v0.valid = 1;
+ ctx->v0.count = OCE_LOG2(cq->cq_cfg.q_len / 256);
+ ctx->v0.nodelay = cq->cq_cfg.nodelay;
+ ctx->v0.coalesce_wm = ncoalesce;
+ ctx->v0.armed = 0;
+ ctx->v0.eq_id = cq->eq->eq_id;
+ }
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_create_common_cq);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ if (rc)
+ goto error;
+
+ cq->cq_id = LE_16(fwcmd->params.rsp.cq_id);
+
+ return 0;
+error:
+ device_printf(sc->dev, "Mbox Create CQ failed\n");
+ return rc;
+
+}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/oce/oce_queue.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/oce/oce_queue.c Fri Mar 02 17:36:33 2012 +0200
@@ -0,0 +1,1212 @@
+/*-
+ * Copyright (C) 2012 Emulex
+ * 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.
+ *
+ * 3. Neither the name of the Emulex Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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.
+ *
+ * Contact Information:
+ * freebsd-drivers at emulex.com
+ *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
+ */
+
+/* $FreeBSD: head/sys/dev/oce/oce_queue.c 231879 2012-02-17 13:55:17Z luigi $ */
+
+#include "oce_if.h"
+
+/*****************************************************
+ * local queue functions
+ *****************************************************/
+
+static struct oce_wq *oce_wq_init(POCE_SOFTC sc,
+ uint32_t q_len, uint32_t wq_type);
+static int oce_wq_create(struct oce_wq *wq, struct oce_eq *eq);
+static void oce_wq_free(struct oce_wq *wq);
+static void oce_wq_del(struct oce_wq *wq);
+static struct oce_rq *oce_rq_init(POCE_SOFTC sc,
+ uint32_t q_len,
+ uint32_t frag_size,
+ uint32_t mtu, uint32_t rss);
+static int oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq);
+static void oce_rq_free(struct oce_rq *rq);
+static void oce_rq_del(struct oce_rq *rq);
+static struct oce_eq *oce_eq_create(POCE_SOFTC sc,
+ uint32_t q_len,
+ uint32_t item_size,
+ uint32_t eq_delay,
+ uint32_t vector);
+static void oce_eq_del(struct oce_eq *eq);
+static struct oce_mq *oce_mq_create(POCE_SOFTC sc,
+ struct oce_eq *eq, uint32_t q_len);
+static void oce_mq_free(struct oce_mq *mq);
+static int oce_destroy_q(POCE_SOFTC sc, struct oce_mbx
+ *mbx, size_t req_size, enum qtype qtype);
+struct oce_cq *oce_cq_create(POCE_SOFTC sc,
+ struct oce_eq *eq,
+ uint32_t q_len,
+ uint32_t item_size,
+ uint32_t sol_event,
+ uint32_t is_eventable,
+ uint32_t nodelay, uint32_t ncoalesce);
+static void oce_cq_del(POCE_SOFTC sc, struct oce_cq *cq);
+
+
+
+/**
+ * @brief Create and initialize all the queues on the board
+ * @param sc software handle to the device
+ * @returns 0 if successful, or error
+ **/
+int
+oce_queue_init_all(POCE_SOFTC sc)
+{
+ int rc = 0, i, vector;
+ struct oce_wq *wq;
+ struct oce_rq *rq;
+
+ /* alloc TX/RX queues */
+ for_all_wq_queues(sc, wq, i) {
+ sc->wq[i] = oce_wq_init(sc, sc->tx_ring_size,
+ NIC_WQ_TYPE_STANDARD);
+ if (!sc->wq[i])
+ goto error;
+
+ }
+
+ for_all_rq_queues(sc, rq, i) {
+ sc->rq[i] = oce_rq_init(sc, sc->rx_ring_size, sc->rq_frag_size,
+ OCE_MAX_JUMBO_FRAME_SIZE,
+ (i == 0) ? 0 : sc->rss_enable);
+ if (!sc->rq[i])
+ goto error;
+ }
+
+ /* Create network interface on card */
+ if (oce_create_nw_interface(sc))
+ goto error;
+
+ /* create all of the event queues */
+ for (vector = 0; vector < sc->intr_count; vector++) {
+ sc->eq[vector] = oce_eq_create(sc, EQ_LEN_1024, EQE_SIZE_4,
+ 0, vector);
+ if (!sc->eq[vector])
+ goto error;
+ }
+
+ /* create Tx, Rx and mcc queues */
+ for_all_wq_queues(sc, wq, i) {
+ rc = oce_wq_create(wq, sc->eq[i]);
+ if (rc)
+ goto error;
+ wq->queue_index = i;
+ TASK_INIT(&wq->txtask, 1, oce_tx_task, wq);
+ }
+
+ for_all_rq_queues(sc, rq, i) {
+ rc = oce_rq_create(rq, sc->if_id,
+ sc->eq[(i == 0) ? 0:(i-1)]);
+ if (rc)
+ goto error;
+ rq->queue_index = i;
+ }
+
+ sc->mq = oce_mq_create(sc, sc->eq[0], 64);
+ if (!sc->mq)
+ goto error;
+
+ return rc;
+
+error:
+ oce_queue_release_all(sc);
+ return 1;
+}
+
+
+
+/**
+ * @brief Releases all mailbox queues created
+ * @param sc software handle to the device
+ */
+void
+oce_queue_release_all(POCE_SOFTC sc)
+{
+ int i = 0;
+ struct oce_wq *wq;
+ struct oce_rq *rq;
+ struct oce_eq *eq;
+
+ for_all_rq_queues(sc, rq, i) {
+ if (rq) {
+ oce_rq_del(sc->rq[i]);
+ oce_rq_free(sc->rq[i]);
+ }
+ }
+
+ for_all_wq_queues(sc, wq, i) {
+ if (wq) {
+ oce_wq_del(sc->wq[i]);
+ oce_wq_free(sc->wq[i]);
+ }
+ }
+
+ if (sc->mq)
+ oce_mq_free(sc->mq);
+
+ for_all_evnt_queues(sc, eq, i) {
+ if (eq)
+ oce_eq_del(sc->eq[i]);
+ }
+}
+
+
+
+/**
+ * @brief Function to create a WQ for NIC Tx
+ * @param sc software handle to the device
+ * @param qlen number of entries in the queue
+ * @param wq_type work queue type
+ * @returns the pointer to the WQ created or NULL on failure
+ */
+static struct
+oce_wq *oce_wq_init(POCE_SOFTC sc, uint32_t q_len, uint32_t wq_type)
+{
+ struct oce_wq *wq;
+ int rc = 0, i;
+
+ /* q_len must be min 256 and max 2k */
+ if (q_len < 256 || q_len > 2048) {
+ device_printf(sc->dev,
+ "Invalid q length. Must be "
+ "[256, 2000]: 0x%x\n", q_len);
+ return NULL;
+ }
+
+ /* allocate wq */
+ wq = malloc(sizeof(struct oce_wq), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (!wq)
+ return NULL;
+
+ /* Set the wq config */
+ wq->cfg.q_len = q_len;
+ wq->cfg.wq_type = (uint8_t) wq_type;
+ wq->cfg.eqd = OCE_DEFAULT_WQ_EQD;
+ wq->cfg.nbufs = 2 * wq->cfg.q_len;
+ wq->cfg.nhdl = 2 * wq->cfg.q_len;
+
+ wq->parent = (void *)sc;
+
+ rc = bus_dma_tag_create(bus_get_dma_tag(sc->dev),
+ 1, 0,
+ BUS_SPACE_MAXADDR,
+ BUS_SPACE_MAXADDR,
+ NULL, NULL,
+ OCE_MAX_TX_SIZE,
+ OCE_MAX_TX_ELEMENTS,
+ PAGE_SIZE, 0, NULL, NULL, &wq->tag);
+
+ if (rc)
+ goto free_wq;
+
+
+ for (i = 0; i < OCE_WQ_PACKET_ARRAY_SIZE; i++) {
+ rc = bus_dmamap_create(wq->tag, 0, &wq->pckts[i].map);
+ if (rc)
+ goto free_wq;
+ }
+
+ wq->ring = oce_create_ring_buffer(sc, q_len, NIC_WQE_SIZE);
+ if (!wq->ring)
+ goto free_wq;
+
+
+ LOCK_CREATE(&wq->tx_lock, "TX_lock");
+
+#if __FreeBSD_version >= 800000
+ /* Allocate buf ring for multiqueue*/
+ wq->br = buf_ring_alloc(4096, M_DEVBUF,
+ M_WAITOK, &wq->tx_lock.mutex);
+ if (!wq->br)
+ goto free_wq;
+#endif
+ return wq;
+
+
+free_wq:
+ device_printf(sc->dev, "Create WQ failed\n");
+ oce_wq_free(wq);
+ return NULL;
+}
+
+
+
+/**
+ * @brief Frees the work queue
+ * @param wq pointer to work queue to free
+ */
+static void
+oce_wq_free(struct oce_wq *wq)
+{
+ POCE_SOFTC sc = (POCE_SOFTC) wq->parent;
+ int i;
+
+ taskqueue_drain(taskqueue_swi, &wq->txtask);
+
+ if (wq->ring != NULL) {
+ oce_destroy_ring_buffer(sc, wq->ring);
+ wq->ring = NULL;
+ }
+
+ for (i = 0; i < OCE_WQ_PACKET_ARRAY_SIZE; i++) {
+ if (wq->pckts[i].map != NULL) {
+ bus_dmamap_unload(wq->tag, wq->pckts[i].map);
+ bus_dmamap_destroy(wq->tag, wq->pckts[i].map);
+ wq->pckts[i].map = NULL;
+ }
+ }
+
+ if (wq->tag != NULL)
+ bus_dma_tag_destroy(wq->tag);
+ if (wq->br != NULL)
+ buf_ring_free(wq->br, M_DEVBUF);
+
+ LOCK_DESTROY(&wq->tx_lock);
+ free(wq, M_DEVBUF);
+}
+
+
+
+/**
+ * @brief Create a work queue
+ * @param wq pointer to work queue
+ * @param eq pointer to associated event queue
+ */
+static int
+oce_wq_create(struct oce_wq *wq, struct oce_eq *eq)
+{
+ POCE_SOFTC sc = wq->parent;
+ struct oce_cq *cq;
+ int rc = 0;
+
+ /* create the CQ */
+ cq = oce_cq_create(sc,
+ eq,
+ CQ_LEN_1024,
+ sizeof(struct oce_nic_tx_cqe), 0, 1, 0, 3);
+ if (!cq)
+ return ENXIO;
+
+
+ wq->cq = cq;
+
+ rc = oce_mbox_create_wq(wq);
+ if (rc)
+ goto error;
+
+ wq->qstate = QCREATED;
+ wq->wq_free = wq->cfg.q_len;
+ wq->ring->cidx = 0;
+ wq->ring->pidx = 0;
+
+ eq->cq[eq->cq_valid] = cq;
+ eq->cq_valid++;
+ cq->cb_arg = wq;
+ cq->cq_handler = oce_wq_handler;
+
+ return 0;
+
+error:
+ device_printf(sc->dev, "WQ create failed\n");
+ oce_wq_del(wq);
+ return rc;
+}
+
+
+
+
+/**
+ * @brief Delete a work queue
+ * @param wq pointer to work queue
+ */
+static void
+oce_wq_del(struct oce_wq *wq)
+{
+ struct oce_mbx mbx;
+ struct mbx_delete_nic_wq *fwcmd;
+ POCE_SOFTC sc = (POCE_SOFTC) wq->parent;
+
+ if (wq->qstate == QCREATED) {
+ bzero(&mbx, sizeof(struct oce_mbx));
+ /* now fill the command */
+ fwcmd = (struct mbx_delete_nic_wq *)&mbx.payload;
+ fwcmd->params.req.wq_id = wq->wq_id;
+ (void)oce_destroy_q(sc, &mbx,
+ sizeof(struct mbx_delete_nic_wq), QTYPE_WQ);
+ wq->qstate = QDELETED;
+ }
+
+ if (wq->cq != NULL) {
+ oce_cq_del(sc, wq->cq);
+ wq->cq = NULL;
+ }
+}
+
+
+
+/**
+ * @brief function to allocate receive queue resources
+ * @param sc software handle to the device
+ * @param q_len length of receive queue
+ * @param frag_size size of an receive queue fragment
+ * @param mtu maximum transmission unit
+ * @param rss is-rss-queue flag
+ * @returns the pointer to the RQ created or NULL on failure
+ */
+static struct
+oce_rq *oce_rq_init(POCE_SOFTC sc,
+ uint32_t q_len,
+ uint32_t frag_size,
+ uint32_t mtu, uint32_t rss)
+{
+ struct oce_rq *rq;
+ int rc = 0, i;
+
+ if (OCE_LOG2(frag_size) <= 0)
+ return NULL;
+
+ if ((q_len == 0) || (q_len > 1024))
+ return NULL;
+
+ /* allocate the rq */
+ rq = malloc(sizeof(struct oce_rq), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (!rq)
+ return NULL;
+
+
+ rq->cfg.q_len = q_len;
+ rq->cfg.frag_size = frag_size;
+ rq->cfg.mtu = mtu;
+ rq->cfg.eqd = 0;
+ rq->lro_pkts_queued = 0;
+ rq->cfg.is_rss_queue = rss;
+ rq->packets_in = 0;
+ rq->packets_out = 0;
+ rq->pending = 0;
+
+ rq->parent = (void *)sc;
+
+ rc = bus_dma_tag_create(bus_get_dma_tag(sc->dev),
+ 1, 0,
+ BUS_SPACE_MAXADDR,
+ BUS_SPACE_MAXADDR,
+ NULL, NULL,
+ OCE_MAX_RX_SIZE,
+ 1, PAGE_SIZE, 0, NULL, NULL, &rq->tag);
+
+ if (rc)
+ goto free_rq;
+
+ for (i = 0; i < OCE_RQ_PACKET_ARRAY_SIZE; i++) {
+ rc = bus_dmamap_create(rq->tag, 0, &rq->pckts[i].map);
+ if (rc)
+ goto free_rq;
+ }
+
+ /* create the ring buffer */
+ rq->ring = oce_create_ring_buffer(sc, q_len,
+ sizeof(struct oce_nic_rqe));
+ if (!rq->ring)
+ goto free_rq;
+
+ LOCK_CREATE(&rq->rx_lock, "RX_lock");
+
+ return rq;
+
+free_rq:
+ device_printf(sc->dev, "Create RQ failed\n");
+ oce_rq_free(rq);
+ return NULL;
+}
+
+
+
+
+/**
+ * @brief Free a receive queue
+ * @param rq pointer to receive queue
+ */
+static void
+oce_rq_free(struct oce_rq *rq)
+{
+ POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
+ int i = 0 ;
+
+ if (rq->ring != NULL) {
+ oce_destroy_ring_buffer(sc, rq->ring);
+ rq->ring = NULL;
+ }
+ for (i = 0; i < OCE_RQ_PACKET_ARRAY_SIZE; i++) {
+ if (rq->pckts[i].map != NULL) {
+ bus_dmamap_unload(rq->tag, rq->pckts[i].map);
+ bus_dmamap_destroy(rq->tag, rq->pckts[i].map);
+ rq->pckts[i].map = NULL;
+ }
+ if (rq->pckts[i].mbuf) {
+ m_free(rq->pckts[i].mbuf);
+ rq->pckts[i].mbuf = NULL;
+ }
+ }
+
+ if (rq->tag != NULL)
+ bus_dma_tag_destroy(rq->tag);
+
+ LOCK_DESTROY(&rq->rx_lock);
+ free(rq, M_DEVBUF);
+}
+
+
+
+
+/**
+ * @brief Create a receive queue
+ * @param rq receive queue
+ * @param if_id interface identifier index`
+ * @param eq pointer to event queue
+ */
+static int
+oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq)
+{
+ POCE_SOFTC sc = rq->parent;
+ struct oce_cq *cq;
+
+ cq = oce_cq_create(sc,
+ eq,
+ CQ_LEN_1024,
+ sizeof(struct oce_nic_rx_cqe), 0, 1, 0, 3);
+ if (!cq)
+ return ENXIO;
+
+ rq->cq = cq;
+ rq->cfg.if_id = if_id;
+
+ /* Dont create RQ here. Create in if_activate */
+ rq->qstate = 0;
+ rq->ring->cidx = 0;
+ rq->ring->pidx = 0;
+ eq->cq[eq->cq_valid] = cq;
+ eq->cq_valid++;
+ cq->cb_arg = rq;
+ cq->cq_handler = oce_rq_handler;
+
+ return 0;
+
+}
+
+
+
+
+/**
+ * @brief Delete a receive queue
+ * @param rq receive queue
+ */
+static void
+oce_rq_del(struct oce_rq *rq)
+{
+ POCE_SOFTC sc = (POCE_SOFTC) rq->parent;
+ struct oce_mbx mbx;
+ struct mbx_delete_nic_rq *fwcmd;
+
+ if (rq->qstate == QCREATED) {
+ bzero(&mbx, sizeof(mbx));
+
+ fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload;
+ fwcmd->params.req.rq_id = rq->rq_id;
+ (void)oce_destroy_q(sc, &mbx,
+ sizeof(struct mbx_delete_nic_rq), QTYPE_RQ);
+ rq->qstate = QDELETED;
+ }
+
+ if (rq->cq != NULL) {
+ oce_cq_del(sc, rq->cq);
+ rq->cq = NULL;
+ }
+}
+
+
+
+/**
+ * @brief function to create an event queue
+ * @param sc software handle to the device
+ * @param q_len length of event queue
+ * @param item_size size of an event queue item
+ * @param eq_delay event queue delay
+ * @retval eq success, pointer to event queue
+ * @retval NULL failure
+ */
+static struct
+oce_eq *oce_eq_create(POCE_SOFTC sc, uint32_t q_len,
+ uint32_t item_size,
+ uint32_t eq_delay,
+ uint32_t vector)
+{
+ struct oce_eq *eq;
+ int rc = 0;
+
+ /* allocate an eq */
+ eq = malloc(sizeof(struct oce_eq), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (eq == NULL)
+ return NULL;
+
+ eq->parent = (void *)sc;
+ eq->eq_id = 0xffff;
+ eq->ring = oce_create_ring_buffer(sc, q_len, item_size);
+ if (!eq->ring)
+ goto free_eq;
+
+ eq->eq_cfg.q_len = q_len;
+ eq->eq_cfg.item_size = item_size;
+ eq->eq_cfg.cur_eqd = (uint8_t) eq_delay;
+
+ rc = oce_mbox_create_eq(eq);
+ if (rc)
+ goto free_eq;
+
+ sc->intrs[sc->neqs++].eq = eq;
+
+ return eq;
+
+free_eq:
+ oce_eq_del(eq);
+ return NULL;
+}
+
+
+
+
+/**
+ * @brief Function to delete an event queue
+ * @param eq pointer to an event queue
+ */
+static void
+oce_eq_del(struct oce_eq *eq)
+{
+ struct oce_mbx mbx;
+ struct mbx_destroy_common_eq *fwcmd;
+ POCE_SOFTC sc = (POCE_SOFTC) eq->parent;
+
+ if (eq->eq_id != 0xffff) {
+ bzero(&mbx, sizeof(mbx));
+ fwcmd = (struct mbx_destroy_common_eq *)&mbx.payload;
+ fwcmd->params.req.id = eq->eq_id;
+ (void)oce_destroy_q(sc, &mbx,
+ sizeof(struct mbx_destroy_common_eq), QTYPE_EQ);
+ }
+
+ if (eq->ring != NULL) {
+ oce_destroy_ring_buffer(sc, eq->ring);
+ eq->ring = NULL;
+ }
+
+ free(eq, M_DEVBUF);
+
+}
+
+
+
+
+/**
+ * @brief Function to create an MQ
+ * @param sc software handle to the device
+ * @param eq the EQ to associate with the MQ for event notification
+ * @param q_len the number of entries to create in the MQ
+ * @returns pointer to the created MQ, failure otherwise
+ */
+static struct oce_mq *
+oce_mq_create(POCE_SOFTC sc, struct oce_eq *eq, uint32_t q_len)
+{
+ struct oce_mbx mbx;
+ struct mbx_create_common_mq_ex *fwcmd = NULL;
+ struct oce_mq *mq = NULL;
+ int rc = 0;
+ struct oce_cq *cq;
+ oce_mq_ext_ctx_t *ctx;
+ uint32_t num_pages;
+ uint32_t page_size;
+ uint32_t version;
+
+
+ cq = oce_cq_create(sc, eq, CQ_LEN_256,
+ sizeof(struct oce_mq_cqe), 1, 1, 0, 0);
+ if (!cq)
+ return NULL;
+
+ /* allocate the mq */
+ mq = malloc(sizeof(struct oce_mq), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (!mq) {
+ oce_cq_del(sc, cq);
+ goto error;
+ }
+
+ mq->parent = sc;
+
+ mq->ring = oce_create_ring_buffer(sc, q_len, sizeof(struct oce_mbx));
+ if (!mq->ring)
+ goto error;
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+
+ fwcmd = (struct mbx_create_common_mq_ex *)&mbx.payload;
+ version = OCE_MBX_VER_V0;
+ mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
+ MBX_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_CREATE_MQ_EXT,
+ MBX_TIMEOUT_SEC,
+ sizeof(struct mbx_create_common_mq_ex),
+ version);
+
+ num_pages = oce_page_list(mq->ring, &fwcmd->params.req.pages[0]);
+ page_size = mq->ring->num_items * mq->ring->item_size;
+
+ ctx = &fwcmd->params.req.context;
+ ctx->v0.num_pages = num_pages;
+ ctx->v0.cq_id = cq->cq_id;
+ ctx->v0.ring_size = OCE_LOG2(q_len) + 1;
+ ctx->v0.valid = 1;
+ /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
+ ctx->v0.async_evt_bitmap = 0xffffffff;
+
+ mbx.u0.s.embedded = 1;
+ mbx.payload_length = sizeof(struct mbx_create_common_mq_ex);
+ DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, &mbx, NULL);
+ if (rc)
+ goto error;
+
+ mq->mq_id = LE_16(fwcmd->params.rsp.mq_id);
+ mq->cq = cq;
+ eq->cq[eq->cq_valid] = cq;
+ eq->cq_valid++;
+ mq->cq->eq = eq;
+ mq->cfg.q_len = (uint8_t) q_len;
+ mq->cfg.eqd = 0;
+ mq->qstate = QCREATED;
+
+ mq->cq->cb_arg = mq;
+ mq->cq->cq_handler = oce_mq_handler;
+
+ return mq;
+
+error:
+ device_printf(sc->dev, "MQ create failed\n");
+ oce_mq_free(mq);
+ mq = NULL;
+ return mq;
+}
+
+
+
+
+
+/**
+ * @brief Function to free a mailbox queue
+ * @param mq pointer to a mailbox queue
+ */
+static void
+oce_mq_free(struct oce_mq *mq)
+{
+ POCE_SOFTC sc = (POCE_SOFTC) mq->parent;
+ struct oce_mbx mbx;
+ struct mbx_destroy_common_mq *fwcmd;
+
+ if (!mq)
+ return;
+
+ if (mq->ring != NULL) {
+ oce_destroy_ring_buffer(sc, mq->ring);
+ mq->ring = NULL;
+ if (mq->qstate == QCREATED) {
+ bzero(&mbx, sizeof (struct oce_mbx));
+ fwcmd = (struct mbx_destroy_common_mq *)&mbx.payload;
+ fwcmd->params.req.id = mq->mq_id;
+ (void) oce_destroy_q(sc, &mbx,
+ sizeof (struct mbx_destroy_common_mq),
+ QTYPE_MQ);
+ }
+ mq->qstate = QDELETED;
+ }
+
+ if (mq->cq != NULL) {
+ oce_cq_del(sc, mq->cq);
+ mq->cq = NULL;
+ }
+
+ free(mq, M_DEVBUF);
+ mq = NULL;
+}
+
+
+
+/**
+ * @brief Function to delete a EQ, CQ, MQ, WQ or RQ
+ * @param sc sofware handle to the device
+ * @param mbx mailbox command to send to the fw to delete the queue
+ * (mbx contains the queue information to delete)
+ * @param req_size the size of the mbx payload dependent on the qtype
+ * @param qtype the type of queue i.e. EQ, CQ, MQ, WQ or RQ
+ * @returns 0 on success, failure otherwise
+ */
+static int
+oce_destroy_q(POCE_SOFTC sc, struct oce_mbx *mbx, size_t req_size,
+ enum qtype qtype)
+{
+ struct mbx_hdr *hdr = (struct mbx_hdr *)&mbx->payload;
+ int opcode;
+ int subsys;
+ int rc = 0;
+
+ switch (qtype) {
+ case QTYPE_EQ:
+ opcode = OPCODE_COMMON_DESTROY_EQ;
+ subsys = MBX_SUBSYSTEM_COMMON;
+ break;
+ case QTYPE_CQ:
+ opcode = OPCODE_COMMON_DESTROY_CQ;
+ subsys = MBX_SUBSYSTEM_COMMON;
+ break;
+ case QTYPE_MQ:
+ opcode = OPCODE_COMMON_DESTROY_MQ;
+ subsys = MBX_SUBSYSTEM_COMMON;
+ break;
+ case QTYPE_WQ:
+ opcode = NIC_DELETE_WQ;
+ subsys = MBX_SUBSYSTEM_NIC;
+ break;
+ case QTYPE_RQ:
+ opcode = NIC_DELETE_RQ;
+ subsys = MBX_SUBSYSTEM_NIC;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ mbx_common_req_hdr_init(hdr, 0, 0, subsys,
+ opcode, MBX_TIMEOUT_SEC, req_size,
+ OCE_MBX_VER_V0);
+
+ mbx->u0.s.embedded = 1;
+ mbx->payload_length = (uint32_t) req_size;
+ DW_SWAP(u32ptr(mbx), mbx->payload_length + OCE_BMBX_RHDR_SZ);
+
+ rc = oce_mbox_post(sc, mbx, NULL);
+
+ if (rc != 0)
+ device_printf(sc->dev, "Failed to del q\n");
+
+ return rc;
+}
+
+
+
+/**
+ * @brief Function to create a completion queue
+ * @param sc software handle to the device
+ * @param eq optional eq to be associated with to the cq
+ * @param q_len length of completion queue
+ * @param item_size size of completion queue items
+ * @param sol_event command context event
+ * @param is_eventable event table
+ * @param nodelay no delay flag
+ * @param ncoalesce no coalescence flag
+ * @returns pointer to the cq created, NULL on failure
+ */
+struct oce_cq *
+oce_cq_create(POCE_SOFTC sc, struct oce_eq *eq,
+ uint32_t q_len,
+ uint32_t item_size,
+ uint32_t sol_event,
+ uint32_t is_eventable,
+ uint32_t nodelay, uint32_t ncoalesce)
+{
+ struct oce_cq *cq = NULL;
+ int rc = 0;
+
+ cq = malloc(sizeof(struct oce_cq), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (!cq)
+ return NULL;
+
+ cq->ring = oce_create_ring_buffer(sc, q_len, item_size);
+ if (!cq->ring)
+ goto error;
+
+ cq->parent = sc;
+ cq->eq = eq;
+ cq->cq_cfg.q_len = q_len;
+ cq->cq_cfg.item_size = item_size;
+ cq->cq_cfg.nodelay = (uint8_t) nodelay;
+
+ rc = oce_mbox_cq_create(cq, ncoalesce, is_eventable);
+ if (rc)
+ goto error;
+
+ sc->cq[sc->ncqs++] = cq;
+
+ return cq;
+
+error:
+ device_printf(sc->dev, "CQ create failed\n");
+ oce_cq_del(sc, cq);
+ return NULL;
+}
+
+
+
+/**
+ * @brief Deletes the completion queue
+ * @param sc software handle to the device
+ * @param cq pointer to a completion queue
+ */
+static void
+oce_cq_del(POCE_SOFTC sc, struct oce_cq *cq)
+{
+ struct oce_mbx mbx;
+ struct mbx_destroy_common_cq *fwcmd;
+
+ if (cq->ring != NULL) {
+
+ bzero(&mbx, sizeof(struct oce_mbx));
+ /* now fill the command */
+ fwcmd = (struct mbx_destroy_common_cq *)&mbx.payload;
+ fwcmd->params.req.id = cq->cq_id;
+ (void)oce_destroy_q(sc, &mbx,
+ sizeof(struct mbx_destroy_common_cq), QTYPE_CQ);
+ /*NOW destroy the ring */
+ oce_destroy_ring_buffer(sc, cq->ring);
+ cq->ring = NULL;
+ }
+
+ free(cq, M_DEVBUF);
+ cq = NULL;
+}
+
+
+
+/**
+ * @brief Start a receive queue
+ * @param rq pointer to a receive queue
+ */
+int
+oce_start_rq(struct oce_rq *rq)
+{
+ int rc;
+
+ rc = oce_alloc_rx_bufs(rq, rq->cfg.q_len);
+
+ if (rc == 0)
+ oce_arm_cq(rq->parent, rq->cq->cq_id, 0, TRUE);
+ return rc;
+}
+
+
+
+/**
+ * @brief Start a work queue
+ * @param wq pointer to a work queue
+ */
+int
+oce_start_wq(struct oce_wq *wq)
+{
+ oce_arm_cq(wq->parent, wq->cq->cq_id, 0, TRUE);
+ return 0;
+}
+
+
+
+/**
+ * @brief Start a mailbox queue
+ * @param mq pointer to a mailbox queue
+ */
+int
+oce_start_mq(struct oce_mq *mq)
+{
+ oce_arm_cq(mq->parent, mq->cq->cq_id, 0, TRUE);
+ return 0;
+}
+
+
+
+/**
+ * @brief Function to arm an EQ so that it can generate events
+ * @param sc software handle to the device
+ * @param qid id of the EQ returned by the fw at the time of creation
+ * @param npopped number of EQEs to arm
+ * @param rearm rearm bit enable/disable
+ * @param clearint bit to clear the interrupt condition because of which
+ * EQEs are generated
+ */
+void
+oce_arm_eq(POCE_SOFTC sc,
+ int16_t qid, int npopped, uint32_t rearm, uint32_t clearint)
+{
+ eq_db_t eq_db = { 0 };
+
+ eq_db.bits.rearm = rearm;
+ eq_db.bits.event = 1;
+ eq_db.bits.num_popped = npopped;
+ eq_db.bits.clrint = clearint;
+ eq_db.bits.qid = qid;
+ OCE_WRITE_REG32(sc, db, PD_EQ_DB, eq_db.dw0);
+
+}
+
+
+
+
+/**
+ * @brief Function to arm a CQ with CQEs
+ * @param sc software handle to the device
+ * @param qid id of the CQ returned by the fw at the time of creation
+ * @param npopped number of CQEs to arm
+ * @param rearm rearm bit enable/disable
+ */
+void oce_arm_cq(POCE_SOFTC sc, int16_t qid, int npopped, uint32_t rearm)
+{
+ cq_db_t cq_db = { 0 };
+
+ cq_db.bits.rearm = rearm;
+ cq_db.bits.num_popped = npopped;
+ cq_db.bits.event = 0;
+ cq_db.bits.qid = qid;
+ OCE_WRITE_REG32(sc, db, PD_CQ_DB, cq_db.dw0);
+
+}
+
+
+
+
+/*
+ * @brief function to cleanup the eqs used during stop
+ * @param eq pointer to event queue structure
+ * @returns the number of EQs processed
+ */
+void
+oce_drain_eq(struct oce_eq *eq)
+{
+
+ struct oce_eqe *eqe;
+ uint16_t num_eqe = 0;
+ POCE_SOFTC sc = eq->parent;
+
+ do {
+ eqe = RING_GET_CONSUMER_ITEM_VA(eq->ring, struct oce_eqe);
+ if (eqe->evnt == 0)
+ break;
+ eqe->evnt = 0;
+ bus_dmamap_sync(eq->ring->dma.tag, eq->ring->dma.map,
+ BUS_DMASYNC_POSTWRITE);
+ num_eqe++;
+ RING_GET(eq->ring, 1);
+
+ } while (TRUE);
+
+ oce_arm_eq(sc, eq->eq_id, num_eqe, FALSE, TRUE);
+
+}
+
+
+
+void
+oce_drain_wq_cq(struct oce_wq *wq)
+{
+ POCE_SOFTC sc = wq->parent;
+ struct oce_cq *cq = wq->cq;
+ struct oce_nic_tx_cqe *cqe;
+ int num_cqes = 0;
+
+ bus_dmamap_sync(cq->ring->dma.tag, cq->ring->dma.map,
+ BUS_DMASYNC_POSTWRITE);
+
+ do {
+ cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe);
+ if (cqe->u0.dw[3] == 0)
+ break;
+ cqe->u0.dw[3] = 0;
+ bus_dmamap_sync(cq->ring->dma.tag, cq->ring->dma.map,
+ BUS_DMASYNC_POSTWRITE);
+ RING_GET(cq->ring, 1);
+ num_cqes++;
+
+ } while (TRUE);
+
+ oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE);
+
+}
+
+
+/*
+ * @brief function to drain a MCQ and process its CQEs
+ * @param dev software handle to the device
+ * @param cq pointer to the cq to drain
+ * @returns the number of CQEs processed
+ */
+void
+oce_drain_mq_cq(void *arg)
+{
+ /* TODO: additional code. */
+ return;
+}
+
+
+
+/**
+ * @brief function to process a Recieve queue
+ * @param arg pointer to the RQ to charge
+ * @return number of cqes processed
+ */
+void
+oce_drain_rq_cq(struct oce_rq *rq)
+{
+ struct oce_nic_rx_cqe *cqe;
+ uint16_t num_cqe = 0;
+ struct oce_cq *cq;
+ POCE_SOFTC sc;
+
+ sc = rq->parent;
+ cq = rq->cq;
+ cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe);
+ /* dequeue till you reach an invalid cqe */
+ while (RQ_CQE_VALID(cqe)) {
+ RQ_CQE_INVALIDATE(cqe);
+ RING_GET(cq->ring, 1);
+ cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring,
+ struct oce_nic_rx_cqe);
+ num_cqe++;
+ }
+ oce_arm_cq(sc, cq->cq_id, num_cqe, FALSE);
+
+ return;
+}
+
+
+void
+oce_free_posted_rxbuf(struct oce_rq *rq)
+{
+ struct oce_packet_desc *pd;
+
+ while (rq->pending) {
+
+ pd = &rq->pckts[rq->packets_out];
+ bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(rq->tag, pd->map);
+ if (pd->mbuf != NULL) {
+ m_freem(pd->mbuf);
+ pd->mbuf = NULL;
+ }
+
+ if ((rq->packets_out + 1) == OCE_RQ_PACKET_ARRAY_SIZE)
+ rq->packets_out = 0;
+ else
+ rq->packets_out++;
+
+ rq->pending--;
+ }
+
+}
+
+void
+oce_stop_rx(POCE_SOFTC sc)
+{
+ struct oce_mbx mbx;
+ struct mbx_delete_nic_rq *fwcmd;
+ struct oce_rq *rq;
+ int i = 0;
+
+ for_all_rq_queues(sc, rq, i) {
+ if (rq->qstate == QCREATED) {
+ /* Delete rxq in firmware */
+
+ bzero(&mbx, sizeof(mbx));
+ fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload;
+ fwcmd->params.req.rq_id = rq->rq_id;
+
+ (void)oce_destroy_q(sc, &mbx,
+ sizeof(struct mbx_delete_nic_rq), QTYPE_RQ);
+
+ rq->qstate = QDELETED;
+
+ DELAY(1);
+
+ /* Free posted RX buffers that are not used */
+ oce_free_posted_rxbuf(rq);
+
+ }
+ }
+}
+
+
+
+int
+oce_start_rx(POCE_SOFTC sc)
+{
+ struct oce_rq *rq;
+ int rc = 0, i;
+
+ for_all_rq_queues(sc, rq, i) {
+ if (rq->qstate == QCREATED)
+ continue;
+ rc = oce_mbox_create_rq(rq);
+ if (rc)
+ goto error;
+ /* reset queue pointers */
+ rq->qstate = QCREATED;
+ rq->pending = 0;
+ rq->ring->cidx = 0;
+ rq->ring->pidx = 0;
+ rq->packets_in = 0;
+ rq->packets_out = 0;
+ }
+
+ DELAY(1);
+
+ /* RSS config */
+ if (sc->rss_enable) {
+ rc = oce_config_nic_rss(sc, (uint8_t) sc->if_id, RSS_ENABLE);
+ if (rc)
+ goto error;
+
+ }
+
+ return rc;
+error:
+ device_printf(sc->dev, "Start RX failed\n");
+ return rc;
+
+}
+
+
+
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/oce/oce_sysctl.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/oce/oce_sysctl.c Fri Mar 02 17:36:33 2012 +0200
@@ -0,0 +1,1305 @@
+/*-
+ * Copyright (C) 2012 Emulex
+ * 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.
+ *
+ * 3. Neither the name of the Emulex Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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.
+ *
+ * Contact Information:
+ * freebsd-drivers at emulex.com
+ *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
+ */
+
+/* $FreeBSD: head/sys/dev/oce/oce_sysctl.c 231879 2012-02-17 13:55:17Z luigi $ */
+
+#include "oce_if.h"
+
+static void copy_stats_to_sc_xe201(POCE_SOFTC sc);
+static void copy_stats_to_sc_be3(POCE_SOFTC sc);
+static void copy_stats_to_sc_be2(POCE_SOFTC sc);
+static int oce_sysctl_loopback(SYSCTL_HANDLER_ARGS);
+static int oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw);
+static int oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS);
+static int oce_be3_flashdata(POCE_SOFTC sc, const struct firmware
+ *fw, int num_imgs);
+static int oce_lancer_fwupgrade(POCE_SOFTC sc, const struct firmware *fw);
+static boolean_t oce_phy_flashing_required(POCE_SOFTC sc);
+static boolean_t oce_img_flashing_required(POCE_SOFTC sc, const char *p,
+ int img_optype, uint32_t img_offset,
+ uint32_t img_size, uint32_t hdrs_size);
+static void oce_add_stats_sysctls_be3(POCE_SOFTC sc,
+ struct sysctl_ctx_list *ctx,
+ struct sysctl_oid *stats_node);
+static void oce_add_stats_sysctls_xe201(POCE_SOFTC sc,
+ struct sysctl_ctx_list *ctx,
+ struct sysctl_oid *stats_node);
+
+extern char component_revision[32];
+
+
+void
+oce_add_sysctls(POCE_SOFTC sc)
+{
+
+ struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
+ struct sysctl_oid *tree = device_get_sysctl_tree(sc->dev);
+ struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
+ struct sysctl_oid *stats_node;
+
+ SYSCTL_ADD_STRING(ctx, child,
+ OID_AUTO, "component_revision",
+ CTLTYPE_INT | CTLFLAG_RD,
+ &component_revision,
+ sizeof(component_revision),
+ "EMULEX One-Connect device driver revision");
+
+ SYSCTL_ADD_STRING(ctx, child,
+ OID_AUTO, "firmware_version",
+ CTLTYPE_INT | CTLFLAG_RD,
+ &sc->fw_version,
+ sizeof(sc->fw_version),
+ "EMULEX One-Connect Firmware Version");
+
+ SYSCTL_ADD_INT(ctx, child,
+ OID_AUTO, "max_rsp_handled",
+ CTLTYPE_INT | CTLFLAG_RW,
+ &oce_max_rsp_handled,
+ sizeof(oce_max_rsp_handled),
+ "Maximum receive frames handled per interupt");
+
+ if (sc->function_mode & FNM_FLEX10_MODE)
+ SYSCTL_ADD_UINT(ctx, child,
+ OID_AUTO, "speed",
+ CTLFLAG_RD,
+ &sc->qos_link_speed,
+ 0,"QOS Speed");
+ else
+ SYSCTL_ADD_UINT(ctx, child,
+ OID_AUTO, "speed",
+ CTLFLAG_RD,
+ &sc->speed,
+ 0,"Link Speed");
+
+ if (sc->function_mode & FNM_UMC_MODE)
+ SYSCTL_ADD_UINT(ctx, child,
+ OID_AUTO, "pvid",
+ CTLFLAG_RD,
+ &sc->pvid,
+ 0,"PVID");
+
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "loop_back",
+ CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0,
+ oce_sysctl_loopback, "I", "Loop Back Tests");
+
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "fw_upgrade",
+ CTLTYPE_STRING | CTLFLAG_RW, (void *)sc, 0,
+ oce_sys_fwupgrade, "A", "Firmware ufi file");
+
+ stats_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats",
+ CTLFLAG_RD, NULL, "Ethernet Statistics");
+
+ if (IS_BE(sc))
+ oce_add_stats_sysctls_be3(sc, ctx, stats_node);
+ else
+ oce_add_stats_sysctls_xe201(sc, ctx, stats_node);
+
+
+}
+
+
+
+static uint32_t
+oce_loopback_test(struct oce_softc *sc, uint8_t loopback_type)
+{
+ uint32_t status = 0;
+
+ oce_mbox_cmd_set_loopback(sc, sc->if_id, loopback_type, 1);
+ status = oce_mbox_cmd_test_loopback(sc, sc->if_id, loopback_type,
+ 1500, 2, 0xabc);
+ oce_mbox_cmd_set_loopback(sc, sc->if_id, OCE_NO_LOOPBACK, 1);
+
+ return status;
+}
+
+
+static int
+oce_sysctl_loopback(SYSCTL_HANDLER_ARGS)
+{
+ int value = 0;
+ uint32_t status;
+ struct oce_softc *sc = (struct oce_softc *)arg1;
+
+ status = sysctl_handle_int(oidp, &value, 0, req);
+ if (status || !req->newptr)
+ return status;
+
+ if (value != 1) {
+ device_printf(sc->dev,
+ "Not a Valid value. Set to loop_back=1 to run tests\n");
+ return 0;
+ }
+
+ if ((status = oce_loopback_test(sc, OCE_MAC_LOOPBACK))) {
+ device_printf(sc->dev,
+ "MAC Loopback Test = Failed (Error status = %d)\n",
+ status);
+ } else
+ device_printf(sc->dev, "MAC Loopback Test = Success\n");
+
+ if ((status = oce_loopback_test(sc, OCE_PHY_LOOPBACK))) {
+ device_printf(sc->dev,
+ "PHY Loopback Test = Failed (Error status = %d)\n",
+ status);
+ } else
+ device_printf(sc->dev, "PHY Loopback Test = Success\n");
+
+ if ((status = oce_loopback_test(sc, OCE_ONE_PORT_EXT_LOOPBACK))) {
+ device_printf(sc->dev,
+ "EXT Loopback Test = Failed (Error status = %d)\n",
+ status);
+ } else
+ device_printf(sc->dev, "EXT Loopback Test = Success\n");
+
+ return 0;
+}
+
+
+static int
+oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS)
+{
+ char ufiname[256] = {0};
+ uint32_t status = 1;
+ struct oce_softc *sc = (struct oce_softc *)arg1;
+ const struct firmware *fw;
+
+ status = sysctl_handle_string(oidp, ufiname, sizeof(ufiname), req);
+ if (status || !req->newptr)
+ return status;
+
+ fw = firmware_get(ufiname);
+ if (fw == NULL) {
+ device_printf(sc->dev, "Unable to get Firmware. "
+ "Make sure %s is copied to /boot/modules\n", ufiname);
+ return ENOENT;
+ }
+
+ if (IS_BE(sc)) {
+ if ((sc->flags & OCE_FLAGS_BE2)) {
+ device_printf(sc->dev,
+ "Flashing not supported for BE2 yet.\n");
+ status = 1;
+ goto done;
+ }
+ status = oce_be3_fwupgrade(sc, fw);
+ } else
+ status = oce_lancer_fwupgrade(sc, fw);
+done:
+ if (status) {
+ device_printf(sc->dev, "Firmware Upgrade failed\n");
+ } else {
+ device_printf(sc->dev, "Firmware Flashed successfully\n");
+ }
+
+ /* Release Firmware*/
+ firmware_put(fw, FIRMWARE_UNLOAD);
+
+ return status;
+}
+
+
+static int
+oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
+{
+ int rc = 0, num_imgs = 0, i = 0;
+ const struct flash_file_hdr *fhdr;
+ const struct image_hdr *img_ptr;
+
+ fhdr = (const struct flash_file_hdr *)fw->data;
+ if (fhdr->build[0] != '3') {
+ device_printf(sc->dev, "Invalid BE3 firmware image\n");
+ return EINVAL;
+ }
+ /* Display flash version */
+ device_printf(sc->dev, "Flashing Firmware %s\n", &fhdr->build[2]);
+
+ num_imgs = fhdr->num_imgs;
+ for (i = 0; i < num_imgs; i++) {
+ img_ptr = (const struct image_hdr *)((const char *)fw->data +
+ sizeof(struct flash_file_hdr) +
+ (i * sizeof(struct image_hdr)));
+ if (img_ptr->imageid == 1) {
+ rc = oce_be3_flashdata(sc, fw, num_imgs);
+ break;
+ }
+ }
+
+ return rc;
+}
+
+
+static int
+oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int num_imgs)
+{
+ char cookie[2][16] = {"*** SE FLAS", "H DIRECTORY *** "};
+ const char *p = (const char *)fw->data;
+ const struct flash_sec_info *fsec = NULL;
+ struct mbx_common_read_write_flashrom *req;
+ int rc = 0, i, img_type, bin_offset = 0;
+ boolean_t skip_image;
+ uint32_t optype = 0, size = 0, start = 0, num_bytes = 0;
+ uint32_t opcode = 0;
+ OCE_DMA_MEM dma_mem;
+
+ /* Validate Cookie */
+ bin_offset = (sizeof(struct flash_file_hdr) +
+ (num_imgs * sizeof(struct image_hdr)));
+ p += bin_offset;
+ while (p < ((const char *)fw->data + fw->datasize)) {
+ fsec = (const struct flash_sec_info *)p;
+ if (!memcmp(cookie, fsec->cookie, sizeof(cookie)))
+ break;
+ fsec = NULL;
+ p += 32;
+ }
+
+ if (!fsec) {
+ device_printf(sc->dev,
+ "Invalid Cookie. Firmware image corrupted ?\n");
+ return EINVAL;
+ }
+
+ rc = oce_dma_alloc(sc, sizeof(struct mbx_common_read_write_flashrom)
+ + 32*1024, &dma_mem, 0);
+ if (rc) {
+ device_printf(sc->dev,
+ "Memory allocation failure while flashing\n");
+ return ENOMEM;
+ }
+ req = OCE_DMAPTR(&dma_mem, struct mbx_common_read_write_flashrom);
+
+ for (i = 0; i < MAX_FLASH_COMP; i++) {
+
+ img_type = fsec->fsec_entry[i].type;
+ skip_image = FALSE;
+ switch (img_type) {
+ case IMG_ISCSI:
+ optype = 0;
+ size = 2097152;
+ start = 2097152;
+ break;
+ case IMG_REDBOOT:
+ optype = 1;
+ size = 1048576;
+ start = 262144;
+ if (!oce_img_flashing_required(sc, fw->data,
+ optype, start, size, bin_offset))
+ skip_image = TRUE;
+ break;
+ case IMG_BIOS:
+ optype = 2;
+ size = 524288;
+ start = 12582912;
+ break;
+ case IMG_PXEBIOS:
+ optype = 3;
+ size = 524288;
+ start = 13107200;
+ break;
+ case IMG_FCOEBIOS:
+ optype = 8;
+ size = 524288;
+ start = 13631488;
+ break;
+ case IMG_ISCSI_BAK:
+ optype = 9;
+ size = 2097152;
+ start = 4194304;
+ break;
+ case IMG_FCOE:
+ optype = 10;
+ size = 2097152;
+ start = 6291456;
+ break;
+ case IMG_FCOE_BAK:
+ optype = 11;
+ size = 2097152;
+ start = 8388608;
+ break;
+ case IMG_NCSI:
+ optype = 13;
+ size = 262144;
+ start = 15990784;
+ break;
+ case IMG_PHY:
+ optype = 99;
+ size = 262144;
+ start = 1310720;
+ if (!oce_phy_flashing_required(sc))
+ skip_image = TRUE;
+ break;
+ default:
+ skip_image = TRUE;
+ break;
+ }
+ if (skip_image)
+ continue;
+
+ p = fw->data;
+ p = p + bin_offset + start;
+ if ((p + size) > ((const char *)fw->data + fw->datasize)) {
+ rc = 1;
+ goto ret;
+ }
+
+ while (size) {
+
+ if (size > 32*1024)
+ num_bytes = 32*1024;
+ else
+ num_bytes = size;
+ size -= num_bytes;
+
+ if (!size)
+ opcode = FLASHROM_OPER_FLASH;
+ else
+ opcode = FLASHROM_OPER_SAVE;
+
+ memcpy(req->data_buffer, p, num_bytes);
+ p += num_bytes;
+
+ rc = oce_mbox_write_flashrom(sc, optype, opcode,
+ &dma_mem, num_bytes);
+ if (rc) {
+ device_printf(sc->dev,
+ "cmd to write to flash rom failed.\n");
+ rc = EIO;
+ goto ret;
+ }
+ /* Leave the CPU for others for some time */
+ pause("yield", 10);
+
+ }
+ }
+ret:
+ oce_dma_free(sc, &dma_mem);
+ return rc;
+
+}
+
+
+static boolean_t
+oce_phy_flashing_required(POCE_SOFTC sc)
+{
+ int status = 0;
+ struct oce_phy_info phy_info;
+
+ status = oce_mbox_get_phy_info(sc, &phy_info);
+ if (status)
+ return FALSE;
+
+ if ((phy_info.phy_type == TN_8022) &&
+ (phy_info.interface_type == PHY_TYPE_BASET_10GB)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static boolean_t
+oce_img_flashing_required(POCE_SOFTC sc, const char *p,
+ int img_optype, uint32_t img_offset,
+ uint32_t img_size, uint32_t hdrs_size)
+{
+ uint32_t crc_offset;
+ uint8_t flashed_crc[4];
+ int status;
+
+ crc_offset = hdrs_size + img_offset + img_size - 4;
+
+ p += crc_offset;
+
+ status = oce_mbox_get_flashrom_crc(sc, flashed_crc,
+ (img_size - 4), img_optype);
+ if (status)
+ return TRUE; /* Some thing worng. ReFlash */
+
+ /*update redboot only if crc does not match*/
+ if (bcmp(flashed_crc, p, 4))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+static int
+oce_lancer_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
+{
+
+ int rc = 0;
+ OCE_DMA_MEM dma_mem;
+ const uint8_t *data = NULL;
+ uint8_t *dest_image_ptr = NULL;
+ size_t size = 0;
+ uint32_t data_written = 0, chunk_size = 0;
+ uint32_t offset = 0, add_status = 0;
+
+ if (!IS_ALIGNED(fw->datasize, sizeof(uint32_t))) {
+ device_printf(sc->dev,
+ "Lancer FW image is not 4 byte aligned.");
+ return EINVAL;
+ }
+
+ rc = oce_dma_alloc(sc, 32*1024, &dma_mem, 0);
+ if (rc) {
+ device_printf(sc->dev,
+ "Memory allocation failure while flashing Lancer\n");
+ return ENOMEM;
+ }
+
+ size = fw->datasize;
+ data = fw->data;
+ dest_image_ptr = OCE_DMAPTR(&dma_mem, uint8_t);
+
+ while (size) {
+ chunk_size = MIN(size, (32*1024));
+
+ bcopy(data, dest_image_ptr, chunk_size);
+
+ rc = oce_mbox_lancer_write_flashrom(sc, chunk_size, offset,
+ &dma_mem, &data_written, &add_status);
+
+ if (rc)
+ break;
+
+ size -= data_written;
+ data += data_written;
+ offset += data_written;
+ pause("yield", 10);
+
+ }
+
+ if (!rc)
+ /* Commit the firmware*/
+ rc = oce_mbox_lancer_write_flashrom(sc, 0, offset, &dma_mem,
+ &data_written, &add_status);
+ if (rc) {
+ device_printf(sc->dev, "Lancer firmware load error. "
+ "Addstatus = 0x%x, status = %d \n", add_status, rc);
+ rc = EIO;
+ }
+ oce_dma_free(sc, &dma_mem);
+ return rc;
+
+}
+
+
+static void
+oce_add_stats_sysctls_be3(POCE_SOFTC sc,
+ struct sysctl_ctx_list *ctx,
+ struct sysctl_oid *stats_node)
+{
+ struct sysctl_oid *rx_stats_node, *tx_stats_node;
+ struct sysctl_oid_list *rx_stat_list, *tx_stat_list;
+ struct sysctl_oid_list *queue_stats_list;
+ struct sysctl_oid *queue_stats_node;
+ struct oce_drv_stats *stats;
+ char prefix[32];
+ int i;
+
+ stats = &sc->oce_stats_info;
+
+ rx_stats_node = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(stats_node),
+ OID_AUTO,"rx", CTLFLAG_RD,
+ NULL, "RX Ethernet Statistics");
+ rx_stat_list = SYSCTL_CHILDREN(rx_stats_node);
+
+
+ SYSCTL_ADD_QUAD(ctx, rx_stat_list, OID_AUTO, "total_pkts",
+ CTLFLAG_RD, &stats->rx.t_rx_pkts,
+ "Total Received Packets");
+ SYSCTL_ADD_QUAD(ctx, rx_stat_list, OID_AUTO, "total_bytes",
+ CTLFLAG_RD, &stats->rx.t_rx_bytes,
+ "Total Received Bytes");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_frags",
+ CTLFLAG_RD, &stats->rx.t_rx_frags, 0,
+ "Total Received Fragements");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_mcast_pkts",
+ CTLFLAG_RD, &stats->rx.t_rx_mcast_pkts, 0,
+ "Total Received Multicast Packets");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_ucast_pkts",
+ CTLFLAG_RD, &stats->rx.t_rx_ucast_pkts, 0,
+ "Total Received Unicast Packets");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_rxcp_errs",
+ CTLFLAG_RD, &stats->rx.t_rxcp_errs, 0,
+ "Total Receive completion errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "pause_frames",
+ CTLFLAG_RD, &stats->u0.be.rx_pause_frames, 0,
+ "Pause Frames");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "priority_pause_frames",
+ CTLFLAG_RD, &stats->u0.be.rx_priority_pause_frames, 0,
+ "Priority Pause Frames");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "control_frames",
+ CTLFLAG_RD, &stats->u0.be.rx_control_frames, 0,
+ "Control Frames");
+
+ for (i = 0; i < sc->nrqs; i++) {
+ sprintf(prefix, "queue%d",i);
+ queue_stats_node = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(rx_stats_node),
+ OID_AUTO, prefix, CTLFLAG_RD,
+ NULL, "Queue name");
+ queue_stats_list = SYSCTL_CHILDREN(queue_stats_node);
+
+ SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "rx_pkts",
+ CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_pkts,
+ "Receive Packets");
+ SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "rx_bytes",
+ CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_bytes,
+ "Recived Bytes");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "rx_frags",
+ CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_frags, 0,
+ "Received Fragments");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO,
+ "rx_mcast_pkts", CTLFLAG_RD,
+ &sc->rq[i]->rx_stats.rx_mcast_pkts, 0,
+ "Received Multicast Packets");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO,
+ "rx_ucast_pkts", CTLFLAG_RD,
+ &sc->rq[i]->rx_stats.rx_ucast_pkts, 0,
+ "Received Unicast Packets");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "rxcp_err",
+ CTLFLAG_RD, &sc->rq[i]->rx_stats.rxcp_err, 0,
+ "Received Completion Errors");
+
+ }
+
+ rx_stats_node = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(rx_stats_node),
+ OID_AUTO, "err", CTLFLAG_RD,
+ NULL, "Receive Error Stats");
+ rx_stat_list = SYSCTL_CHILDREN(rx_stats_node);
+
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "crc_errs",
+ CTLFLAG_RD, &stats->u0.be.rx_crc_errors, 0,
+ "CRC Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "pbuf_errors",
+ CTLFLAG_RD, &stats->u0.be.rx_drops_no_pbuf, 0,
+ "Drops due to pbuf full");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "erx_errors",
+ CTLFLAG_RD, &stats->u0.be.rx_drops_no_erx_descr, 0,
+ "ERX Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "alignment_errors",
+ CTLFLAG_RD, &stats->u0.be.rx_drops_too_many_frags, 0,
+ "RX Alignmnet Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "in_range_errors",
+ CTLFLAG_RD, &stats->u0.be.rx_in_range_errors, 0,
+ "In Range Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "out_range_errors",
+ CTLFLAG_RD, &stats->u0.be.rx_out_range_errors, 0,
+ "Out Range Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "frame_too_long",
+ CTLFLAG_RD, &stats->u0.be.rx_frame_too_long, 0,
+ "Frame Too Long");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "address_match_errors",
+ CTLFLAG_RD, &stats->u0.be.rx_address_match_errors, 0,
+ "Address Match Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_too_small",
+ CTLFLAG_RD, &stats->u0.be.rx_dropped_too_small, 0,
+ "Dropped Too Small");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_too_short",
+ CTLFLAG_RD, &stats->u0.be.rx_dropped_too_short, 0,
+ "Dropped Too Short");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO,
+ "dropped_header_too_small", CTLFLAG_RD,
+ &stats->u0.be.rx_dropped_header_too_small, 0,
+ "Dropped Header Too Small");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_tcp_length",
+ CTLFLAG_RD, &stats->u0.be.rx_dropped_tcp_length, 0,
+ "Dropped TCP Length");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_runt",
+ CTLFLAG_RD, &stats->u0.be.rx_dropped_runt, 0,
+ "Dropped runt");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "ip_checksum_errs",
+ CTLFLAG_RD, &stats->u0.be.rx_ip_checksum_errs, 0,
+ "IP Checksum Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "tcp_checksum_errs",
+ CTLFLAG_RD, &stats->u0.be.rx_tcp_checksum_errs, 0,
+ "TCP Checksum Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "udp_checksum_errs",
+ CTLFLAG_RD, &stats->u0.be.rx_udp_checksum_errs, 0,
+ "UDP Checksum Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "fifo_overflow_drop",
+ CTLFLAG_RD, &stats->u0.be.rxpp_fifo_overflow_drop, 0,
+ "FIFO Overflow Drop");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO,
+ "input_fifo_overflow_drop", CTLFLAG_RD,
+ &stats->u0.be.rx_input_fifo_overflow_drop, 0,
+ "Input FIFO Overflow Drop");
+
+ tx_stats_node = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(stats_node), OID_AUTO,
+ "tx",CTLFLAG_RD, NULL,
+ "TX Ethernet Statistics");
+ tx_stat_list = SYSCTL_CHILDREN(tx_stats_node);
+
+ SYSCTL_ADD_QUAD(ctx, tx_stat_list, OID_AUTO, "total_tx_pkts",
+ CTLFLAG_RD, &stats->tx.t_tx_pkts,
+ "Total Transmit Packets");
+ SYSCTL_ADD_QUAD(ctx, tx_stat_list, OID_AUTO, "total_tx_bytes",
+ CTLFLAG_RD, &stats->tx.t_tx_bytes,
+ "Total Transmit Bytes");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_reqs",
+ CTLFLAG_RD, &stats->tx.t_tx_reqs, 0,
+ "Total Transmit Requests");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_stops",
+ CTLFLAG_RD, &stats->tx.t_tx_stops, 0,
+ "Total Transmit Stops");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_wrbs",
+ CTLFLAG_RD, &stats->tx.t_tx_wrbs, 0,
+ "Total Transmit WRB's");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_compl",
+ CTLFLAG_RD, &stats->tx.t_tx_compl, 0,
+ "Total Transmit Completions");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO,
+ "total_ipv6_ext_hdr_tx_drop", CTLFLAG_RD,
+ &stats->tx.t_ipv6_ext_hdr_tx_drop, 0,
+ "Total Transmit IPV6 Drops");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "pauseframes",
+ CTLFLAG_RD, &stats->u0.be.tx_pauseframes, 0,
+ "Pause Frames");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "priority_pauseframes",
+ CTLFLAG_RD, &stats->u0.be.tx_priority_pauseframes, 0,
+ "Priority Pauseframes");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "controlframes",
+ CTLFLAG_RD, &stats->u0.be.tx_controlframes, 0,
+ "Tx Control Frames");
+
+ for (i = 0; i < sc->nwqs; i++) {
+ sprintf(prefix, "queue%d",i);
+ queue_stats_node = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(tx_stats_node),
+ OID_AUTO, prefix, CTLFLAG_RD,
+ NULL, "Queue name");
+ queue_stats_list = SYSCTL_CHILDREN(queue_stats_node);
+
+ SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "tx_pkts",
+ CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_pkts,
+ "Transmit Packets");
+ SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "tx_bytes",
+ CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_bytes,
+ "Transmit Bytes");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_reqs",
+ CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_reqs, 0,
+ "Transmit Requests");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_stops",
+ CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_stops, 0,
+ "Transmit Stops");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_wrbs",
+ CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_wrbs, 0,
+ "Transmit WRB's");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_compl",
+ CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_compl, 0,
+ "Transmit Completions");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO,
+ "ipv6_ext_hdr_tx_drop",CTLFLAG_RD,
+ &sc->wq[i]->tx_stats.ipv6_ext_hdr_tx_drop, 0,
+ "Transmit IPV6 Ext Header Drop");
+
+ }
+ return;
+}
+
+
+static void
+oce_add_stats_sysctls_xe201(POCE_SOFTC sc,
+ struct sysctl_ctx_list *ctx,
+ struct sysctl_oid *stats_node)
+{
+ struct sysctl_oid *rx_stats_node, *tx_stats_node;
+ struct sysctl_oid_list *rx_stat_list, *tx_stat_list;
+ struct sysctl_oid_list *queue_stats_list;
+ struct sysctl_oid *queue_stats_node;
+ struct oce_drv_stats *stats;
+ char prefix[32];
+ int i;
+
+ stats = &sc->oce_stats_info;
+
+ rx_stats_node = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(stats_node),
+ OID_AUTO, "rx", CTLFLAG_RD,
+ NULL, "RX Ethernet Statistics");
+ rx_stat_list = SYSCTL_CHILDREN(rx_stats_node);
+
+
+ SYSCTL_ADD_QUAD(ctx, rx_stat_list, OID_AUTO, "total_pkts",
+ CTLFLAG_RD, &stats->rx.t_rx_pkts,
+ "Total Received Packets");
+ SYSCTL_ADD_QUAD(ctx, rx_stat_list, OID_AUTO, "total_bytes",
+ CTLFLAG_RD, &stats->rx.t_rx_bytes,
+ "Total Received Bytes");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_frags",
+ CTLFLAG_RD, &stats->rx.t_rx_frags, 0,
+ "Total Received Fragements");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_mcast_pkts",
+ CTLFLAG_RD, &stats->rx.t_rx_mcast_pkts, 0,
+ "Total Received Multicast Packets");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_ucast_pkts",
+ CTLFLAG_RD, &stats->rx.t_rx_ucast_pkts, 0,
+ "Total Received Unicast Packets");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "total_rxcp_errs",
+ CTLFLAG_RD, &stats->rx.t_rxcp_errs, 0,
+ "Total Receive completion errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "pause_frames",
+ CTLFLAG_RD, &stats->u0.xe201.rx_pause_frames, 0,
+ "Pause Frames");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "control_frames",
+ CTLFLAG_RD, &stats->u0.xe201.rx_control_frames, 0,
+ "Control Frames");
+
+ for (i = 0; i < sc->nrqs; i++) {
+ sprintf(prefix, "queue%d",i);
+ queue_stats_node = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(rx_stats_node),
+ OID_AUTO, prefix, CTLFLAG_RD,
+ NULL, "Queue name");
+ queue_stats_list = SYSCTL_CHILDREN(queue_stats_node);
+
+ SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "rx_pkts",
+ CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_pkts,
+ "Receive Packets");
+ SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "rx_bytes",
+ CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_bytes,
+ "Recived Bytes");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "rx_frags",
+ CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_frags, 0,
+ "Received Fragments");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO,
+ "rx_mcast_pkts", CTLFLAG_RD,
+ &sc->rq[i]->rx_stats.rx_mcast_pkts, 0,
+ "Received Multicast Packets");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO,
+ "rx_ucast_pkts",CTLFLAG_RD,
+ &sc->rq[i]->rx_stats.rx_ucast_pkts, 0,
+ "Received Unicast Packets");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "rxcp_err",
+ CTLFLAG_RD, &sc->rq[i]->rx_stats.rxcp_err, 0,
+ "Received Completion Errors");
+
+ }
+
+ rx_stats_node = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(rx_stats_node),
+ OID_AUTO, "err", CTLFLAG_RD,
+ NULL, "Receive Error Stats");
+ rx_stat_list = SYSCTL_CHILDREN(rx_stats_node);
+
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "crc_errs",
+ CTLFLAG_RD, &stats->u0.xe201.rx_crc_errors, 0,
+ "CRC Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "alignment_errors",
+ CTLFLAG_RD, &stats->u0.xe201.rx_alignment_errors, 0,
+ "RX Alignmnet Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "in_range_errors",
+ CTLFLAG_RD, &stats->u0.xe201.rx_in_range_errors, 0,
+ "In Range Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "out_range_errors",
+ CTLFLAG_RD, &stats->u0.xe201.rx_out_of_range_errors, 0,
+ "Out Range Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "frame_too_long",
+ CTLFLAG_RD, &stats->u0.xe201.rx_frames_too_long, 0,
+ "Frame Too Long");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "address_match_errors",
+ CTLFLAG_RD, &stats->u0.xe201.rx_address_match_errors, 0,
+ "Address Match Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_too_small",
+ CTLFLAG_RD, &stats->u0.xe201.rx_dropped_too_small, 0,
+ "Dropped Too Small");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_too_short",
+ CTLFLAG_RD, &stats->u0.xe201.rx_dropped_too_short, 0,
+ "Dropped Too Short");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO,
+ "dropped_header_too_small", CTLFLAG_RD,
+ &stats->u0.xe201.rx_dropped_header_too_small, 0,
+ "Dropped Header Too Small");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO,
+ "dropped_tcp_length", CTLFLAG_RD,
+ &stats->u0.xe201.rx_dropped_invalid_tcp_length, 0,
+ "Dropped TCP Length");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "dropped_runt",
+ CTLFLAG_RD, &stats->u0.xe201.rx_dropped_runt, 0,
+ "Dropped runt");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "ip_checksum_errs",
+ CTLFLAG_RD, &stats->u0.xe201.rx_ip_checksum_errors, 0,
+ "IP Checksum Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "tcp_checksum_errs",
+ CTLFLAG_RD, &stats->u0.xe201.rx_tcp_checksum_errors, 0,
+ "TCP Checksum Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "udp_checksum_errs",
+ CTLFLAG_RD, &stats->u0.xe201.rx_udp_checksum_errors, 0,
+ "UDP Checksum Errors");
+ SYSCTL_ADD_UINT(ctx, rx_stat_list, OID_AUTO, "input_fifo_overflow_drop",
+ CTLFLAG_RD, &stats->u0.xe201.rx_fifo_overflow, 0,
+ "Input FIFO Overflow Drop");
+
+ tx_stats_node = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(stats_node),
+ OID_AUTO, "tx", CTLFLAG_RD,
+ NULL, "TX Ethernet Statistics");
+ tx_stat_list = SYSCTL_CHILDREN(tx_stats_node);
+
+ SYSCTL_ADD_QUAD(ctx, tx_stat_list, OID_AUTO, "total_tx_pkts",
+ CTLFLAG_RD, &stats->tx.t_tx_pkts,
+ "Total Transmit Packets");
+ SYSCTL_ADD_QUAD(ctx, tx_stat_list, OID_AUTO, "total_tx_bytes",
+ CTLFLAG_RD, &stats->tx.t_tx_bytes,
+ "Total Transmit Bytes");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_reqs",
+ CTLFLAG_RD, &stats->tx.t_tx_reqs, 0,
+ "Total Transmit Requests");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_stops",
+ CTLFLAG_RD, &stats->tx.t_tx_stops, 0,
+ "Total Transmit Stops");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_wrbs",
+ CTLFLAG_RD, &stats->tx.t_tx_wrbs, 0,
+ "Total Transmit WRB's");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "total_tx_compl",
+ CTLFLAG_RD, &stats->tx.t_tx_compl, 0,
+ "Total Transmit Completions");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO,
+ "total_ipv6_ext_hdr_tx_drop",
+ CTLFLAG_RD, &stats->tx.t_ipv6_ext_hdr_tx_drop, 0,
+ "Total Transmit IPV6 Drops");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "pauseframes",
+ CTLFLAG_RD, &stats->u0.xe201.tx_pause_frames, 0,
+ "Pause Frames");
+ SYSCTL_ADD_UINT(ctx, tx_stat_list, OID_AUTO, "controlframes",
+ CTLFLAG_RD, &stats->u0.xe201.tx_control_frames, 0,
+ "Tx Control Frames");
+
+ for (i = 0; i < sc->nwqs; i++) {
+ sprintf(prefix, "queue%d",i);
+ queue_stats_node = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(tx_stats_node),
+ OID_AUTO, prefix, CTLFLAG_RD,
+ NULL, "Queue name");
+ queue_stats_list = SYSCTL_CHILDREN(queue_stats_node);
+
+ SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "tx_pkts",
+ CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_pkts,
+ "Transmit Packets");
+ SYSCTL_ADD_QUAD(ctx, queue_stats_list, OID_AUTO, "tx_bytes",
+ CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_bytes,
+ "Transmit Bytes");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_reqs",
+ CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_reqs, 0,
+ "Transmit Requests");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_stops",
+ CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_stops, 0,
+ "Transmit Stops");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_wrbs",
+ CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_wrbs, 0,
+ "Transmit WRB's");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "tx_compl",
+ CTLFLAG_RD, &sc->wq[i]->tx_stats.tx_compl, 0,
+ "Transmit Completions");
+ SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO,
+ "ipv6_ext_hdr_tx_drop", CTLFLAG_RD,
+ &sc->wq[i]->tx_stats.ipv6_ext_hdr_tx_drop, 0,
+ "Transmit IPV6 Ext Header Drop");
+
+ }
+ return;
+}
+
+
+void
+oce_refresh_queue_stats(POCE_SOFTC sc)
+{
+ struct oce_drv_stats *adapter_stats;
+ int i;
+
+ adapter_stats = &sc->oce_stats_info;
+
+ /* Caluculate total TX and TXstats from all queues */
+
+ bzero(&adapter_stats->rx, sizeof(struct oce_rx_stats));
+ for (i = 0; i < sc->nrqs; i++) {
+
+ adapter_stats->rx.t_rx_pkts += sc->rq[i]->rx_stats.rx_pkts;
+ adapter_stats->rx.t_rx_bytes += sc->rq[i]->rx_stats.rx_bytes;
+ adapter_stats->rx.t_rx_frags += sc->rq[i]->rx_stats.rx_frags;
+ adapter_stats->rx.t_rx_mcast_pkts +=
+ sc->rq[i]->rx_stats.rx_mcast_pkts;
+ adapter_stats->rx.t_rx_ucast_pkts +=
+ sc->rq[i]->rx_stats.rx_ucast_pkts;
+ adapter_stats->rx.t_rxcp_errs += sc-> rq[i]->rx_stats.rxcp_err;
+ }
+
+ bzero(&adapter_stats->tx, sizeof(struct oce_tx_stats));
+ for (i = 0; i < sc->nwqs; i++) {
+ adapter_stats->tx.t_tx_reqs += sc->wq[i]->tx_stats.tx_reqs;
+ adapter_stats->tx.t_tx_stops += sc->wq[i]->tx_stats.tx_stops;
+ adapter_stats->tx.t_tx_wrbs += sc->wq[i]->tx_stats.tx_wrbs;
+ adapter_stats->tx.t_tx_compl += sc->wq[i]->tx_stats.tx_compl;
+ adapter_stats->tx.t_tx_bytes += sc->wq[i]->tx_stats.tx_bytes;
+ adapter_stats->tx.t_tx_pkts += sc->wq[i]->tx_stats.tx_pkts;
+ adapter_stats->tx.t_ipv6_ext_hdr_tx_drop +=
+ sc->wq[i]->tx_stats.ipv6_ext_hdr_tx_drop;
+ }
+
+}
+
+
+
+static void
+copy_stats_to_sc_xe201(POCE_SOFTC sc)
+{
+ struct oce_xe201_stats *adapter_stats;
+ struct mbx_get_pport_stats *nic_mbx;
+ struct pport_stats *port_stats;
+
+ nic_mbx = OCE_DMAPTR(&sc->stats_mem, struct mbx_get_pport_stats);
+ port_stats = &nic_mbx->params.rsp.pps;
+ adapter_stats = &sc->oce_stats_info.u0.xe201;
+
+ adapter_stats->tx_pkts = port_stats->tx_pkts;
+ adapter_stats->tx_unicast_pkts = port_stats->tx_unicast_pkts;
+ adapter_stats->tx_multicast_pkts = port_stats->tx_multicast_pkts;
+ adapter_stats->tx_broadcast_pkts = port_stats->tx_broadcast_pkts;
+ adapter_stats->tx_bytes = port_stats->tx_bytes;
+ adapter_stats->tx_unicast_bytes = port_stats->tx_unicast_bytes;
+ adapter_stats->tx_multicast_bytes = port_stats->tx_multicast_bytes;
+ adapter_stats->tx_broadcast_bytes = port_stats->tx_broadcast_bytes;
+ adapter_stats->tx_discards = port_stats->tx_discards;
+ adapter_stats->tx_errors = port_stats->tx_errors;
+ adapter_stats->tx_pause_frames = port_stats->tx_pause_frames;
+ adapter_stats->tx_pause_on_frames = port_stats->tx_pause_on_frames;
+ adapter_stats->tx_pause_off_frames = port_stats->tx_pause_off_frames;
+ adapter_stats->tx_internal_mac_errors =
+ port_stats->tx_internal_mac_errors;
+ adapter_stats->tx_control_frames = port_stats->tx_control_frames;
+ adapter_stats->tx_pkts_64_bytes = port_stats->tx_pkts_64_bytes;
+ adapter_stats->tx_pkts_65_to_127_bytes =
+ port_stats->tx_pkts_65_to_127_bytes;
+ adapter_stats->tx_pkts_128_to_255_bytes =
+ port_stats->tx_pkts_128_to_255_bytes;
+ adapter_stats->tx_pkts_256_to_511_bytes =
+ port_stats->tx_pkts_256_to_511_bytes;
+ adapter_stats->tx_pkts_512_to_1023_bytes =
+ port_stats->tx_pkts_512_to_1023_bytes;
+ adapter_stats->tx_pkts_1024_to_1518_bytes =
+ port_stats->tx_pkts_1024_to_1518_bytes;
+ adapter_stats->tx_pkts_1519_to_2047_bytes =
+ port_stats->tx_pkts_1519_to_2047_bytes;
+ adapter_stats->tx_pkts_2048_to_4095_bytes =
+ port_stats->tx_pkts_2048_to_4095_bytes;
+ adapter_stats->tx_pkts_4096_to_8191_bytes =
+ port_stats->tx_pkts_4096_to_8191_bytes;
+ adapter_stats->tx_pkts_8192_to_9216_bytes =
+ port_stats->tx_pkts_8192_to_9216_bytes;
+ adapter_stats->tx_lso_pkts = port_stats->tx_lso_pkts;
+ adapter_stats->rx_pkts = port_stats->rx_pkts;
+ adapter_stats->rx_unicast_pkts = port_stats->rx_unicast_pkts;
+ adapter_stats->rx_multicast_pkts = port_stats->rx_multicast_pkts;
+ adapter_stats->rx_broadcast_pkts = port_stats->rx_broadcast_pkts;
+ adapter_stats->rx_bytes = port_stats->rx_bytes;
+ adapter_stats->rx_unicast_bytes = port_stats->rx_unicast_bytes;
+ adapter_stats->rx_multicast_bytes = port_stats->rx_multicast_bytes;
+ adapter_stats->rx_broadcast_bytes = port_stats->rx_broadcast_bytes;
+ adapter_stats->rx_unknown_protos = port_stats->rx_unknown_protos;
+ adapter_stats->rx_discards = port_stats->rx_discards;
+ adapter_stats->rx_errors = port_stats->rx_errors;
+ adapter_stats->rx_crc_errors = port_stats->rx_crc_errors;
+ adapter_stats->rx_alignment_errors = port_stats->rx_alignment_errors;
+ adapter_stats->rx_symbol_errors = port_stats->rx_symbol_errors;
+ adapter_stats->rx_pause_frames = port_stats->rx_pause_frames;
+ adapter_stats->rx_pause_on_frames = port_stats->rx_pause_on_frames;
+ adapter_stats->rx_pause_off_frames = port_stats->rx_pause_off_frames;
+ adapter_stats->rx_frames_too_long = port_stats->rx_frames_too_long;
+ adapter_stats->rx_internal_mac_errors =
+ port_stats->rx_internal_mac_errors;
+ adapter_stats->rx_undersize_pkts = port_stats->rx_undersize_pkts;
+ adapter_stats->rx_oversize_pkts = port_stats->rx_oversize_pkts;
+ adapter_stats->rx_fragment_pkts = port_stats->rx_fragment_pkts;
+ adapter_stats->rx_jabbers = port_stats->rx_jabbers;
+ adapter_stats->rx_control_frames = port_stats->rx_control_frames;
+ adapter_stats->rx_control_frames_unknown_opcode =
+ port_stats->rx_control_frames_unknown_opcode;
+ adapter_stats->rx_in_range_errors = port_stats->rx_in_range_errors;
+ adapter_stats->rx_out_of_range_errors =
+ port_stats->rx_out_of_range_errors;
+ adapter_stats->rx_address_match_errors =
+ port_stats->rx_address_match_errors;
+ adapter_stats->rx_vlan_mismatch_errors =
+ port_stats->rx_vlan_mismatch_errors;
+ adapter_stats->rx_dropped_too_small = port_stats->rx_dropped_too_small;
+ adapter_stats->rx_dropped_too_short = port_stats->rx_dropped_too_short;
+ adapter_stats->rx_dropped_header_too_small =
+ port_stats->rx_dropped_header_too_small;
+ adapter_stats->rx_dropped_invalid_tcp_length =
+ port_stats->rx_dropped_invalid_tcp_length;
+ adapter_stats->rx_dropped_runt = port_stats->rx_dropped_runt;
+ adapter_stats->rx_ip_checksum_errors =
+ port_stats->rx_ip_checksum_errors;
+ adapter_stats->rx_tcp_checksum_errors =
+ port_stats->rx_tcp_checksum_errors;
+ adapter_stats->rx_udp_checksum_errors =
+ port_stats->rx_udp_checksum_errors;
+ adapter_stats->rx_non_rss_pkts = port_stats->rx_non_rss_pkts;
+ adapter_stats->rx_ipv4_pkts = port_stats->rx_ipv4_pkts;
+ adapter_stats->rx_ipv6_pkts = port_stats->rx_ipv6_pkts;
+ adapter_stats->rx_ipv4_bytes = port_stats->rx_ipv4_bytes;
+ adapter_stats->rx_ipv6_bytes = port_stats->rx_ipv6_bytes;
+ adapter_stats->rx_nic_pkts = port_stats->rx_nic_pkts;
+ adapter_stats->rx_tcp_pkts = port_stats->rx_tcp_pkts;
+ adapter_stats->rx_iscsi_pkts = port_stats->rx_iscsi_pkts;
+ adapter_stats->rx_management_pkts = port_stats->rx_management_pkts;
+ adapter_stats->rx_switched_unicast_pkts =
+ port_stats->rx_switched_unicast_pkts;
+ adapter_stats->rx_switched_multicast_pkts =
+ port_stats->rx_switched_multicast_pkts;
+ adapter_stats->rx_switched_broadcast_pkts =
+ port_stats->rx_switched_broadcast_pkts;
+ adapter_stats->num_forwards = port_stats->num_forwards;
+ adapter_stats->rx_fifo_overflow = port_stats->rx_fifo_overflow;
+ adapter_stats->rx_input_fifo_overflow =
+ port_stats->rx_input_fifo_overflow;
+ adapter_stats->rx_drops_too_many_frags =
+ port_stats->rx_drops_too_many_frags;
+ adapter_stats->rx_drops_invalid_queue =
+ port_stats->rx_drops_invalid_queue;
+ adapter_stats->rx_drops_mtu = port_stats->rx_drops_mtu;
+ adapter_stats->rx_pkts_64_bytes = port_stats->rx_pkts_64_bytes;
+ adapter_stats->rx_pkts_65_to_127_bytes =
+ port_stats->rx_pkts_65_to_127_bytes;
+ adapter_stats->rx_pkts_128_to_255_bytes =
+ port_stats->rx_pkts_128_to_255_bytes;
+ adapter_stats->rx_pkts_256_to_511_bytes =
+ port_stats->rx_pkts_256_to_511_bytes;
+ adapter_stats->rx_pkts_512_to_1023_bytes =
+ port_stats->rx_pkts_512_to_1023_bytes;
+ adapter_stats->rx_pkts_1024_to_1518_bytes =
+ port_stats->rx_pkts_1024_to_1518_bytes;
+ adapter_stats->rx_pkts_1519_to_2047_bytes =
+ port_stats->rx_pkts_1519_to_2047_bytes;
+ adapter_stats->rx_pkts_2048_to_4095_bytes =
+ port_stats->rx_pkts_2048_to_4095_bytes;
+ adapter_stats->rx_pkts_4096_to_8191_bytes =
+ port_stats->rx_pkts_4096_to_8191_bytes;
+ adapter_stats->rx_pkts_8192_to_9216_bytes =
+ port_stats->rx_pkts_8192_to_9216_bytes;
+}
+
+
+
+static void
+copy_stats_to_sc_be2(POCE_SOFTC sc)
+{
+ struct oce_be_stats *adapter_stats;
+ struct oce_pmem_stats *pmem;
+ struct oce_rxf_stats_v0 *rxf_stats;
+ struct oce_port_rxf_stats_v0 *port_stats;
+ struct mbx_get_nic_stats_v0 *nic_mbx;
+ uint32_t port = sc->port_id;
+
+ nic_mbx = OCE_DMAPTR(&sc->stats_mem, struct mbx_get_nic_stats_v0);
+ pmem = &nic_mbx->params.rsp.stats.pmem;
+ rxf_stats = &nic_mbx->params.rsp.stats.rxf;
+ port_stats = &nic_mbx->params.rsp.stats.rxf.port[port];
+
+ adapter_stats = &sc->oce_stats_info.u0.be;
+
+
+ /* Update stats */
+ adapter_stats->rx_pause_frames = port_stats->rx_pause_frames;
+ adapter_stats->rx_crc_errors = port_stats->rx_crc_errors;
+ adapter_stats->rx_control_frames = port_stats->rx_control_frames;
+ adapter_stats->rx_in_range_errors = port_stats->rx_in_range_errors;
+ adapter_stats->rx_frame_too_long = port_stats->rx_frame_too_long;
+ adapter_stats->rx_dropped_runt = port_stats->rx_dropped_runt;
+ adapter_stats->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
+ adapter_stats->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
+ adapter_stats->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
+ adapter_stats->rxpp_fifo_overflow_drop =
+ port_stats->rxpp_fifo_overflow_drop;
+ adapter_stats->rx_dropped_tcp_length =
+ port_stats->rx_dropped_tcp_length;
+ adapter_stats->rx_dropped_too_small = port_stats->rx_dropped_too_small;
+ adapter_stats->rx_dropped_too_short = port_stats->rx_dropped_too_short;
+ adapter_stats->rx_out_range_errors = port_stats->rx_out_range_errors;
+ adapter_stats->rx_dropped_header_too_small =
+ port_stats->rx_dropped_header_too_small;
+ adapter_stats->rx_input_fifo_overflow_drop =
+ port_stats->rx_input_fifo_overflow_drop;
+ adapter_stats->rx_address_match_errors =
+ port_stats->rx_address_match_errors;
+ adapter_stats->rx_alignment_symbol_errors =
+ port_stats->rx_alignment_symbol_errors;
+ adapter_stats->tx_pauseframes = port_stats->tx_pauseframes;
+ adapter_stats->tx_controlframes = port_stats->tx_controlframes;
+
+ if (sc->if_id)
+ adapter_stats->jabber_events = rxf_stats->port1_jabber_events;
+ else
+ adapter_stats->jabber_events = rxf_stats->port0_jabber_events;
+
+ adapter_stats->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
+ adapter_stats->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
+ adapter_stats->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
+ adapter_stats->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
+ adapter_stats->forwarded_packets = rxf_stats->forwarded_packets;
+ adapter_stats->rx_drops_mtu = rxf_stats->rx_drops_mtu;
+ adapter_stats->rx_drops_no_tpre_descr =
+ rxf_stats->rx_drops_no_tpre_descr;
+ adapter_stats->rx_drops_too_many_frags =
+ rxf_stats->rx_drops_too_many_frags;
+ adapter_stats->eth_red_drops = pmem->eth_red_drops;
+}
+
+
+static void
+copy_stats_to_sc_be3(POCE_SOFTC sc)
+{
+ struct oce_be_stats *adapter_stats;
+ struct oce_pmem_stats *pmem;
+ struct oce_rxf_stats_v1 *rxf_stats;
+ struct oce_port_rxf_stats_v1 *port_stats;
+ struct mbx_get_nic_stats *nic_mbx;
+ uint32_t port = sc->port_id;
+
+ nic_mbx = OCE_DMAPTR(&sc->stats_mem, struct mbx_get_nic_stats);
+ pmem = &nic_mbx->params.rsp.stats.pmem;
+ rxf_stats = &nic_mbx->params.rsp.stats.rxf;
+ port_stats = &nic_mbx->params.rsp.stats.rxf.port[port];
+
+ adapter_stats = &sc->oce_stats_info.u0.be;
+
+ /* Update stats */
+ adapter_stats->pmem_fifo_overflow_drop =
+ port_stats->pmem_fifo_overflow_drop;
+ adapter_stats->rx_priority_pause_frames =
+ port_stats->rx_priority_pause_frames;
+ adapter_stats->rx_pause_frames = port_stats->rx_pause_frames;
+ adapter_stats->rx_crc_errors = port_stats->rx_crc_errors;
+ adapter_stats->rx_control_frames = port_stats->rx_control_frames;
+ adapter_stats->rx_in_range_errors = port_stats->rx_in_range_errors;
+ adapter_stats->rx_frame_too_long = port_stats->rx_frame_too_long;
+ adapter_stats->rx_dropped_runt = port_stats->rx_dropped_runt;
+ adapter_stats->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
+ adapter_stats->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
+ adapter_stats->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
+ adapter_stats->rx_dropped_tcp_length =
+ port_stats->rx_dropped_tcp_length;
+ adapter_stats->rx_dropped_too_small = port_stats->rx_dropped_too_small;
+ adapter_stats->rx_dropped_too_short = port_stats->rx_dropped_too_short;
+ adapter_stats->rx_out_range_errors = port_stats->rx_out_range_errors;
+ adapter_stats->rx_dropped_header_too_small =
+ port_stats->rx_dropped_header_too_small;
+ adapter_stats->rx_input_fifo_overflow_drop =
+ port_stats->rx_input_fifo_overflow_drop;
+ adapter_stats->rx_address_match_errors =
+ port_stats->rx_address_match_errors;
+ adapter_stats->rx_alignment_symbol_errors =
+ port_stats->rx_alignment_symbol_errors;
+ adapter_stats->rxpp_fifo_overflow_drop =
+ port_stats->rxpp_fifo_overflow_drop;
+ adapter_stats->tx_pauseframes = port_stats->tx_pauseframes;
+ adapter_stats->tx_controlframes = port_stats->tx_controlframes;
+ adapter_stats->jabber_events = port_stats->jabber_events;
+
+ adapter_stats->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
+ adapter_stats->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
+ adapter_stats->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
+ adapter_stats->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
+ adapter_stats->forwarded_packets = rxf_stats->forwarded_packets;
+ adapter_stats->rx_drops_mtu = rxf_stats->rx_drops_mtu;
+ adapter_stats->rx_drops_no_tpre_descr =
+ rxf_stats->rx_drops_no_tpre_descr;
+ adapter_stats->rx_drops_too_many_frags =
+ rxf_stats->rx_drops_too_many_frags;
+
+ adapter_stats->eth_red_drops = pmem->eth_red_drops;
+}
+
+
+int
+oce_stats_init(POCE_SOFTC sc)
+{
+ int rc = 0, sz;
+
+ if (IS_BE(sc)) {
+ if (sc->flags & OCE_FLAGS_BE2)
+ sz = sizeof(struct mbx_get_nic_stats_v0);
+ else
+ sz = sizeof(struct mbx_get_nic_stats);
+ } else
+ sz = sizeof(struct mbx_get_pport_stats);
+
+ rc = oce_dma_alloc(sc, sz, &sc->stats_mem, 0);
+
+ return rc;
+}
+
+
+void
+oce_stats_free(POCE_SOFTC sc)
+{
+
+ oce_dma_free(sc, &sc->stats_mem);
+
+}
+
+
+int
+oce_refresh_nic_stats(POCE_SOFTC sc)
+{
+ int rc = 0, reset = 0;
+
+ if (IS_BE(sc)) {
+ if (sc->flags & OCE_FLAGS_BE2) {
+ rc = oce_mbox_get_nic_stats_v0(sc, &sc->stats_mem);
+ if (!rc)
+ copy_stats_to_sc_be2(sc);
+ } else {
+ rc = oce_mbox_get_nic_stats(sc, &sc->stats_mem);
+ if (!rc)
+ copy_stats_to_sc_be3(sc);
+ }
+
+ } else {
+ rc = oce_mbox_get_pport_stats(sc, &sc->stats_mem, reset);
+ if (!rc)
+ copy_stats_to_sc_xe201(sc);
+ }
+
+ return rc;
+}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/oce/oce_util.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/oce/oce_util.c Fri Mar 02 17:36:33 2012 +0200
@@ -0,0 +1,268 @@
+/*-
+ * Copyright (C) 2012 Emulex
+ * 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.
+ *
+ * 3. Neither the name of the Emulex Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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.
+ *
+ * Contact Information:
+ * freebsd-drivers at emulex.com
+ *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
+ */
+
+/* $FreeBSD: head/sys/dev/oce/oce_util.c 231879 2012-02-17 13:55:17Z luigi $ */
+
+#include "oce_if.h"
+
+static void oce_dma_map_ring(void *arg,
+ bus_dma_segment_t *segs,
+ int nseg,
+ int error);
+
+/**
+ * @brief Allocate DMA memory
+ * @param sc software handle to the device
+ * @param size bus size
+ * @param dma dma memory area
+ * @param flags creation flags
+ * @returns 0 on success, error otherwize
+ */
+int
+oce_dma_alloc(POCE_SOFTC sc, bus_size_t size, POCE_DMA_MEM dma, int flags)
+{
+ int rc;
+
+
+ memset(dma, 0, sizeof(OCE_DMA_MEM));
+
+ rc = bus_dma_tag_create(bus_get_dma_tag(sc->dev),
+ 8, 0,
+ BUS_SPACE_MAXADDR,
+ BUS_SPACE_MAXADDR,
+ NULL, NULL,
+ size, 1, size, 0, NULL, NULL, &dma->tag);
+
+ if (rc == 0) {
+ rc = bus_dmamem_alloc(dma->tag,
+ &dma->ptr,
+ BUS_DMA_NOWAIT | BUS_DMA_COHERENT,
+ &dma->map);
+ }
+
+ dma->paddr = 0;
+ if (rc == 0) {
+ rc = bus_dmamap_load(dma->tag,
+ dma->map,
+ dma->ptr,
+ size,
+ oce_dma_map_addr,
+ &dma->paddr, flags | BUS_DMA_NOWAIT);
+ if (dma->paddr == 0)
+ rc = ENXIO;
+ }
+
+ if (rc != 0)
+ oce_dma_free(sc, dma);
+
+ return rc;
+}
+
+/**
+ * @brief Free DMA memory
+ * @param sc software handle to the device
+ * @param dma dma area to free
+ */
+void
+oce_dma_free(POCE_SOFTC sc, POCE_DMA_MEM dma)
+{
+ if (dma->tag == NULL)
+ return;
+
+ if (dma->map != NULL) {
+ bus_dmamap_sync(dma->tag, dma->map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(dma->tag, dma->map);
+ }
+
+ if (dma->ptr != NULL) {
+ bus_dmamem_free(dma->tag, dma->ptr, dma->map);
+ dma->map = NULL;
+ dma->ptr = NULL;
+ }
+
+ bus_dma_tag_destroy(dma->tag);
+ dma->tag = NULL;
+
+ return;
+}
+
+
+
+/**
+ * @brief Map DMA memory segment addresses
+ * @param arg physical address pointer
+ * @param segs dma memory segments
+ * @param nseg number of dma memory segments
+ * @param error if error, zeroes the physical address
+ */
+void
+oce_dma_map_addr(void *arg, bus_dma_segment_t * segs, int nseg, int error)
+{
+ bus_addr_t *paddr = arg;
+
+ if (error)
+ *paddr = 0;
+ else
+ *paddr = segs->ds_addr;
+}
+
+
+
+/**
+ * @brief Destroy a ring buffer
+ * @param sc software handle to the device
+ * @param ring ring buffer
+ */
+
+void
+oce_destroy_ring_buffer(POCE_SOFTC sc, oce_ring_buffer_t *ring)
+{
+ oce_dma_free(sc, &ring->dma);
+ free(ring, M_DEVBUF);
+}
+
+
+
+oce_ring_buffer_t *
+oce_create_ring_buffer(POCE_SOFTC sc,
+ uint32_t q_len, uint32_t item_size)
+{
+ uint32_t size = q_len * item_size;
+ int rc;
+ oce_ring_buffer_t *ring;
+
+
+ ring = malloc(sizeof(oce_ring_buffer_t), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (ring == NULL)
+ return NULL;
+
+ ring->item_size = item_size;
+ ring->num_items = q_len;
+
+ rc = bus_dma_tag_create(bus_get_dma_tag(sc->dev),
+ 4096, 0,
+ BUS_SPACE_MAXADDR,
+ BUS_SPACE_MAXADDR,
+ NULL, NULL,
+ size, 8, 4096, 0, NULL, NULL, &ring->dma.tag);
+ if (rc)
+ goto fail;
+
+
+ rc = bus_dmamem_alloc(ring->dma.tag,
+ &ring->dma.ptr,
+ BUS_DMA_NOWAIT | BUS_DMA_COHERENT,
+ &ring->dma.map);
+ if (rc)
+ goto fail;
+
+ bzero(ring->dma.ptr, size);
+ bus_dmamap_sync(ring->dma.tag, ring->dma.map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ ring->dma.paddr = 0;
+
+ return ring;
+
+fail:
+ oce_dma_free(sc, &ring->dma);
+ free(ring, M_DEVBUF);
+ ring = NULL;
+ return NULL;
+}
+
+
+
+struct _oce_dmamap_paddr_table {
+ uint32_t max_entries;
+ uint32_t num_entries;
+ struct phys_addr *paddrs;
+};
+
+
+
+/**
+ * @brief Map ring buffer
+ * @param arg dma map phyical address table pointer
+ * @param segs dma memory segments
+ * @param nseg number of dma memory segments
+ * @param error maps only if error is 0
+ */
+static void
+oce_dma_map_ring(void *arg, bus_dma_segment_t * segs, int nseg, int error)
+{
+ int i;
+ struct _oce_dmamap_paddr_table *dpt =
+ (struct _oce_dmamap_paddr_table *)arg;
+
+ if (error == 0) {
+ if (nseg <= dpt->max_entries) {
+ for (i = 0; i < nseg; i++) {
+ dpt->paddrs[i].lo = ADDR_LO(segs[i].ds_addr);
+ dpt->paddrs[i].hi = ADDR_HI(segs[i].ds_addr);
+ }
+ dpt->num_entries = nseg;
+ }
+ }
+}
+
+
+
+/**
+ * @brief Load bus dma map for a ring buffer
+ * @param ring ring buffer pointer
+ * @param pa_list physical address list
+ * @returns number entries
+ */
+uint32_t
+oce_page_list(oce_ring_buffer_t *ring, struct phys_addr *pa_list)
+{
+ struct _oce_dmamap_paddr_table dpt;
+
+ dpt.max_entries = 8;
+ dpt.num_entries = 0;
+ dpt.paddrs = pa_list;
+
+ bus_dmamap_load(ring->dma.tag,
+ ring->dma.map,
+ ring->dma.ptr,
+ ring->item_size * ring->num_items,
+ oce_dma_map_ring, &dpt, BUS_DMA_NOWAIT);
+
+ return dpt.num_entries;
+}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/pci/pci.c
--- a/head/sys/dev/pci/pci.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/pci/pci.c Fri Mar 02 17:36:33 2012 +0200
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/pci/pci.c 230340 2012-01-19 21:38:19Z jhb $");
+__FBSDID("$FreeBSD: head/sys/dev/pci/pci.c 232360 2012-03-01 20:20:55Z jhb $");
#include "opt_bus.h"
@@ -73,7 +73,6 @@
#define PCIR_IS_BIOS(cfg, reg) \
(((cfg)->hdrtype == PCIM_HDRTYPE_NORMAL && reg == PCIR_BIOS) || \
((cfg)->hdrtype == PCIM_HDRTYPE_BRIDGE && reg == PCIR_BIOS_1))
-
static pci_addr_t pci_mapbase(uint64_t mapreg);
static const char *pci_maptype(uint64_t mapreg);
@@ -171,7 +170,7 @@
DEVMETHOD(pci_msi_count, pci_msi_count_method),
DEVMETHOD(pci_msix_count, pci_msix_count_method),
- { 0, 0 }
+ DEVMETHOD_END
};
DEFINE_CLASS_0(pci, pci_driver, pci_methods, 0);
@@ -183,7 +182,6 @@
static char *pci_vendordata;
static size_t pci_vendordata_size;
-
struct pci_quirk {
uint32_t devid; /* Vendor/device of the card */
int type;
@@ -194,7 +192,7 @@
int arg2;
};
-struct pci_quirk pci_quirks[] = {
+static const struct pci_quirk const pci_quirks[] = {
/* The Intel 82371AB and 82443MX has a map register at offset 0x90. */
{ 0x71138086, PCI_QUIRK_MAP_REG, 0x90, 0 },
{ 0x719b8086, PCI_QUIRK_MAP_REG, 0x90, 0 },
@@ -227,6 +225,12 @@
{ 0x74501022, PCI_QUIRK_DISABLE_MSI, 0, 0 },
/*
+ * MSI-X doesn't work with at least LSI SAS1068E passed through by
+ * VMware.
+ */
+ { 0x079015ad, PCI_QUIRK_DISABLE_MSI, 0, 0 },
+
+ /*
* Some virtualization environments emulate an older chipset
* but support MSI just fine. QEMU uses the Intel 82440.
*/
@@ -724,7 +728,6 @@
}
}
-
#if defined(__i386__) || defined(__amd64__) || defined(__powerpc__)
/*
* Enable the MSI mapping window for all HyperTransport
@@ -875,10 +878,9 @@
remain |= byte2 << 8;
if (remain > (0x7f*4 - vrs.off)) {
state = -1;
- printf(
- "pci%d:%d:%d:%d: invalid VPD data, remain %#x\n",
- cfg->domain, cfg->bus, cfg->slot,
- cfg->func, remain);
+ pci_printf(cfg,
+ "invalid VPD data, remain %#x\n",
+ remain);
}
name = byte & 0x7f;
} else {
@@ -950,10 +952,8 @@
* if this happens, we can't trust the rest
* of the VPD.
*/
- printf(
- "pci%d:%d:%d:%d: bad keyword length: %d\n",
- cfg->domain, cfg->bus, cfg->slot,
- cfg->func, dflen);
+ pci_printf(cfg, "bad keyword length: %d\n",
+ dflen);
cksumvalid = 0;
state = -1;
break;
@@ -986,10 +986,8 @@
cksumvalid = 1;
else {
if (bootverbose)
- printf(
- "pci%d:%d:%d:%d: bad VPD cksum, remain %hhu\n",
- cfg->domain, cfg->bus,
- cfg->slot, cfg->func,
+ pci_printf(cfg,
+ "bad VPD cksum, remain %hhu\n",
vrs.cksum);
cksumvalid = 0;
state = -1;
@@ -1067,9 +1065,7 @@
break;
default:
- printf("pci%d:%d:%d:%d: invalid state: %d\n",
- cfg->domain, cfg->bus, cfg->slot, cfg->func,
- state);
+ pci_printf(cfg, "invalid state: %d\n", state);
state = -1;
break;
}
@@ -1086,8 +1082,7 @@
}
if (state < -1) {
/* I/O error, clean up */
- printf("pci%d:%d:%d:%d: failed to read VPD data.\n",
- cfg->domain, cfg->bus, cfg->slot, cfg->func);
+ pci_printf(cfg, "failed to read VPD data.\n");
if (cfg->vpd.vpd_ident != NULL) {
free(cfg->vpd.vpd_ident, M_DEVBUF);
cfg->vpd.vpd_ident = NULL;
@@ -1873,7 +1868,7 @@
int
pci_msi_device_blacklisted(device_t dev)
{
- struct pci_quirk *q;
+ const struct pci_quirk *q;
if (!pci_honor_msi_blacklist)
return (0);
@@ -1893,7 +1888,7 @@
static int
pci_msi_vm_chipset(device_t dev)
{
- struct pci_quirk *q;
+ const struct pci_quirk *q;
for (q = &pci_quirks[0]; q->devid; q++) {
if (q->devid == pci_get_devid(dev) &&
@@ -3023,7 +3018,7 @@
struct pci_devinfo *dinfo = device_get_ivars(dev);
pcicfgregs *cfg = &dinfo->cfg;
struct resource_list *rl = &dinfo->resources;
- struct pci_quirk *q;
+ const struct pci_quirk *q;
int i;
/* ATA devices needs special map treatment */
@@ -3864,7 +3859,6 @@
}
}
-
#include "opt_ddb.h"
#ifdef DDB
#include <ddb/ddb.h>
@@ -4021,7 +4015,6 @@
return (res);
}
-
struct resource *
pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
@@ -4433,3 +4426,22 @@
if (pci_get_powerstate(dev) != PCI_POWERSTATE_D3)
pci_set_powerstate(dev, PCI_POWERSTATE_D3);
}
+
+/* Wrapper APIs suitable for device driver use. */
+void
+pci_save_state(device_t dev)
+{
+ struct pci_devinfo *dinfo;
+
+ dinfo = device_get_ivars(dev);
+ pci_cfg_save(dev, dinfo, 0);
+}
+
+void
+pci_restore_state(device_t dev)
+{
+ struct pci_devinfo *dinfo;
+
+ dinfo = device_get_ivars(dev);
+ pci_cfg_restore(dev, dinfo);
+}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/pci/pcivar.h
--- a/head/sys/dev/pci/pcivar.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/pci/pcivar.h Fri Mar 02 17:36:33 2012 +0200
@@ -23,7 +23,7 @@
* (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: head/sys/dev/pci/pcivar.h 223885 2011-07-09 14:30:13Z kib $
+ * $FreeBSD: head/sys/dev/pci/pcivar.h 232360 2012-03-01 20:20:55Z jhb $
*
*/
@@ -467,6 +467,8 @@
void pci_ht_map_msi(device_t dev, uint64_t addr);
int pci_get_max_read_req(device_t dev);
+void pci_restore_state(device_t dev);
+void pci_save_state(device_t dev);
int pci_set_max_read_req(device_t dev, int size);
#endif /* _SYS_BUS_H_ */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/pcn/if_pcn.c
--- a/head/sys/dev/pcn/if_pcn.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/pcn/if_pcn.c Fri Mar 02 17:36:33 2012 +0200
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/pcn/if_pcn.c 227843 2011-11-22 21:28:20Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/pcn/if_pcn.c 232204 2012-02-27 08:57:02Z kevlo $");
/*
* AMD Am79c972 fast ethernet PCI NIC driver. Datasheets are available
@@ -966,7 +966,7 @@
mii_tick(mii);
/* link just died */
- if (sc->pcn_link & !(mii->mii_media_status & IFM_ACTIVE))
+ if (sc->pcn_link && !(mii->mii_media_status & IFM_ACTIVE))
sc->pcn_link = 0;
/* link just came up, restart */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/ral/if_ral_pci.c
--- a/head/sys/dev/ral/if_ral_pci.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/ral/if_ral_pci.c Fri Mar 02 17:36:33 2012 +0200
@@ -74,6 +74,10 @@
{ 0x1814, 0x0301, "Ralink Technology RT2561S" },
{ 0x1814, 0x0302, "Ralink Technology RT2561" },
{ 0x1814, 0x0401, "Ralink Technology RT2661" },
+ { 0x1814, 0x0601, "Ralink Technology RT2860 PCI" },
+ { 0x1814, 0x0681, "Ralink Technology RT2860 PCIe" },
+ { 0x1814, 0x0701, "Ralink Technology RT2870 PCI" },
+ { 0x1814, 0x0781, "Ralink Technology RT2870 PCIe" },
{ 0, 0, NULL }
};
@@ -101,7 +105,14 @@
rt2661_suspend,
rt2661_resume,
rt2661_intr
-};
+}/*, ral_rt2860_opns = {
+ rt2860_attach,
+ rt2860_detach,
+ rt2860_shutdown,
+ rt2860_suspend,
+ rt2860_resume,
+ rt2860_intr
+}*/;
struct ral_pci_softc {
union {
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/re/if_re.c
--- a/head/sys/dev/re/if_re.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/re/if_re.c Fri Mar 02 17:36:33 2012 +0200
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/re/if_re.c 230336 2012-01-19 20:13:16Z yongari $");
+__FBSDID("$FreeBSD: head/sys/dev/re/if_re.c 232246 2012-02-28 05:23:29Z yongari $");
/*
* RealTek 8139C+/8169/8169S/8110S/8168/8111/8101E PCI NIC driver
@@ -1433,11 +1433,16 @@
sc->rl_flags |= RL_FLAG_MACSLEEP;
/* FALLTHROUGH */
case RL_HWREV_8168CP:
- case RL_HWREV_8168D:
sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 | RL_FLAG_WOL_MANLINK;
break;
+ case RL_HWREV_8168D:
+ sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PHYWAKE_PM |
+ RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT |
+ RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 |
+ RL_FLAG_WOL_MANLINK;
+ break;
case RL_HWREV_8168DP:
sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_AUTOPAD |
@@ -1472,6 +1477,22 @@
break;
}
+ if (sc->rl_hwrev->rl_rev == RL_HWREV_8139CPLUS) {
+ sc->rl_cfg0 = RL_8139_CFG0;
+ sc->rl_cfg1 = RL_8139_CFG1;
+ sc->rl_cfg2 = 0;
+ sc->rl_cfg3 = RL_8139_CFG3;
+ sc->rl_cfg4 = RL_8139_CFG4;
+ sc->rl_cfg5 = RL_8139_CFG5;
+ } else {
+ sc->rl_cfg0 = RL_CFG0;
+ sc->rl_cfg1 = RL_CFG1;
+ sc->rl_cfg2 = RL_CFG2;
+ sc->rl_cfg3 = RL_CFG3;
+ sc->rl_cfg4 = RL_CFG4;
+ sc->rl_cfg5 = RL_CFG5;
+ }
+
/* Reset the adapter. */
RL_LOCK(sc);
re_reset(sc);
@@ -1479,12 +1500,12 @@
/* Enable PME. */
CSR_WRITE_1(sc, RL_EECMD, RL_EE_MODE);
- cfg = CSR_READ_1(sc, RL_CFG1);
+ cfg = CSR_READ_1(sc, sc->rl_cfg1);
cfg |= RL_CFG1_PME;
- CSR_WRITE_1(sc, RL_CFG1, cfg);
- cfg = CSR_READ_1(sc, RL_CFG5);
+ CSR_WRITE_1(sc, sc->rl_cfg1, cfg);
+ cfg = CSR_READ_1(sc, sc->rl_cfg5);
cfg &= RL_CFG5_PME_STS;
- CSR_WRITE_1(sc, RL_CFG5, cfg);
+ CSR_WRITE_1(sc, sc->rl_cfg5, cfg);
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
if ((sc->rl_flags & RL_FLAG_PAR) != 0) {
@@ -1556,19 +1577,6 @@
re_gmii_writereg(dev, 1, 0x0e, 0);
}
-#define RE_PHYAD_INTERNAL 0
-
- /* Do MII setup. */
- phy = RE_PHYAD_INTERNAL;
- if (sc->rl_type == RL_8169)
- phy = 1;
- error = mii_attach(dev, &sc->rl_miibus, ifp, re_ifmedia_upd,
- re_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, MIIF_DOPAUSE);
- if (error != 0) {
- device_printf(dev, "attaching PHYs failed\n");
- goto fail;
- }
-
ifp->if_softc = sc;
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
@@ -1593,6 +1601,19 @@
TASK_INIT(&sc->rl_inttask, 0, re_int_task, sc);
+#define RE_PHYAD_INTERNAL 0
+
+ /* Do MII setup. */
+ phy = RE_PHYAD_INTERNAL;
+ if (sc->rl_type == RL_8169)
+ phy = 1;
+ error = mii_attach(dev, &sc->rl_miibus, ifp, re_ifmedia_upd,
+ re_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, MIIF_DOPAUSE);
+ if (error != 0) {
+ device_printf(dev, "attaching PHYs failed\n");
+ goto fail;
+ }
+
/*
* Call MI attach routine.
*/
@@ -2090,6 +2111,7 @@
ifp = sc->rl_ifp;
#ifdef DEV_NETMAP
if (ifp->if_capenable & IFCAP_NETMAP) {
+ NA(ifp)->rx_rings->nr_kflags |= NKR_PENDINTR;
selwakeuppri(&NA(ifp)->rx_rings->si, PI_NET);
return 0;
}
@@ -2946,32 +2968,32 @@
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_WRITECFG);
if (jumbo != 0) {
- CSR_WRITE_1(sc, RL_CFG3, CSR_READ_1(sc, RL_CFG3) |
+ CSR_WRITE_1(sc, sc->rl_cfg3, CSR_READ_1(sc, sc->rl_cfg3) |
RL_CFG3_JUMBO_EN0);
switch (sc->rl_hwrev->rl_rev) {
case RL_HWREV_8168DP:
break;
case RL_HWREV_8168E:
- CSR_WRITE_1(sc, RL_CFG4, CSR_READ_1(sc, RL_CFG4) |
- 0x01);
+ CSR_WRITE_1(sc, sc->rl_cfg4,
+ CSR_READ_1(sc, sc->rl_cfg4) | 0x01);
break;
default:
- CSR_WRITE_1(sc, RL_CFG4, CSR_READ_1(sc, RL_CFG4) |
- RL_CFG4_JUMBO_EN1);
+ CSR_WRITE_1(sc, sc->rl_cfg4,
+ CSR_READ_1(sc, sc->rl_cfg4) | RL_CFG4_JUMBO_EN1);
}
} else {
- CSR_WRITE_1(sc, RL_CFG3, CSR_READ_1(sc, RL_CFG3) &
+ CSR_WRITE_1(sc, sc->rl_cfg3, CSR_READ_1(sc, sc->rl_cfg3) &
~RL_CFG3_JUMBO_EN0);
switch (sc->rl_hwrev->rl_rev) {
case RL_HWREV_8168DP:
break;
case RL_HWREV_8168E:
- CSR_WRITE_1(sc, RL_CFG4, CSR_READ_1(sc, RL_CFG4) &
- ~0x01);
+ CSR_WRITE_1(sc, sc->rl_cfg4,
+ CSR_READ_1(sc, sc->rl_cfg4) & ~0x01);
break;
default:
- CSR_WRITE_1(sc, RL_CFG4, CSR_READ_1(sc, RL_CFG4) &
- ~RL_CFG4_JUMBO_EN1);
+ CSR_WRITE_1(sc, sc->rl_cfg4,
+ CSR_READ_1(sc, sc->rl_cfg4) & ~RL_CFG4_JUMBO_EN1);
}
}
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
@@ -3084,7 +3106,7 @@
if (sc->rl_hwrev->rl_rev == RL_HWREV_8169_8110SC ||
sc->rl_hwrev->rl_rev == RL_HWREV_8169_8110SCE) {
reg = 0x000fff00;
- if ((CSR_READ_1(sc, RL_CFG2) & RL_CFG2_PCI66MHZ) != 0)
+ if ((CSR_READ_1(sc, sc->rl_cfg2) & RL_CFG2_PCI66MHZ) != 0)
reg |= 0x000000ff;
if (sc->rl_hwrev->rl_rev == RL_HWREV_8169_8110SCE)
reg |= 0x00f00000;
@@ -3249,7 +3271,8 @@
if (sc->rl_testmode)
return;
- CSR_WRITE_1(sc, RL_CFG1, CSR_READ_1(sc, RL_CFG1) | RL_CFG1_DRVLOAD);
+ CSR_WRITE_1(sc, sc->rl_cfg1, CSR_READ_1(sc, sc->rl_cfg1) |
+ RL_CFG1_DRVLOAD);
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
@@ -3782,19 +3805,19 @@
CSR_WRITE_1(sc, RL_EECMD, RL_EE_MODE);
/* Enable PME. */
- v = CSR_READ_1(sc, RL_CFG1);
+ v = CSR_READ_1(sc, sc->rl_cfg1);
v &= ~RL_CFG1_PME;
if ((ifp->if_capenable & IFCAP_WOL) != 0)
v |= RL_CFG1_PME;
- CSR_WRITE_1(sc, RL_CFG1, v);
-
- v = CSR_READ_1(sc, RL_CFG3);
+ CSR_WRITE_1(sc, sc->rl_cfg1, v);
+
+ v = CSR_READ_1(sc, sc->rl_cfg3);
v &= ~(RL_CFG3_WOL_LINK | RL_CFG3_WOL_MAGIC);
if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0)
v |= RL_CFG3_WOL_MAGIC;
- CSR_WRITE_1(sc, RL_CFG3, v);
-
- v = CSR_READ_1(sc, RL_CFG5);
+ CSR_WRITE_1(sc, sc->rl_cfg3, v);
+
+ v = CSR_READ_1(sc, sc->rl_cfg5);
v &= ~(RL_CFG5_WOL_BCAST | RL_CFG5_WOL_MCAST | RL_CFG5_WOL_UCAST |
RL_CFG5_WOL_LANWAKE);
if ((ifp->if_capenable & IFCAP_WOL_UCAST) != 0)
@@ -3803,7 +3826,7 @@
v |= RL_CFG5_WOL_MCAST | RL_CFG5_WOL_BCAST;
if ((ifp->if_capenable & IFCAP_WOL) != 0)
v |= RL_CFG5_WOL_LANWAKE;
- CSR_WRITE_1(sc, RL_CFG5, v);
+ CSR_WRITE_1(sc, sc->rl_cfg5, v);
/* Config register write done. */
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
@@ -3839,17 +3862,17 @@
/* Enable config register write. */
CSR_WRITE_1(sc, RL_EECMD, RL_EE_MODE);
- v = CSR_READ_1(sc, RL_CFG3);
+ v = CSR_READ_1(sc, sc->rl_cfg3);
v &= ~(RL_CFG3_WOL_LINK | RL_CFG3_WOL_MAGIC);
- CSR_WRITE_1(sc, RL_CFG3, v);
+ CSR_WRITE_1(sc, sc->rl_cfg3, v);
/* Config register write done. */
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
- v = CSR_READ_1(sc, RL_CFG5);
+ v = CSR_READ_1(sc, sc->rl_cfg5);
v &= ~(RL_CFG5_WOL_BCAST | RL_CFG5_WOL_MCAST | RL_CFG5_WOL_UCAST);
v &= ~RL_CFG5_WOL_LANWAKE;
- CSR_WRITE_1(sc, RL_CFG5, v);
+ CSR_WRITE_1(sc, sc->rl_cfg5, v);
}
static void
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/rt2860/rt2860.c
--- a/head/sys/dev/rt2860/rt2860.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/rt2860/rt2860.c Fri Mar 02 17:36:33 2012 +0200
@@ -4656,7 +4656,7 @@
/* align end on a 4-bytes boundary */
- dmalen = (len + 3) & ~ 3;
+ dmalen = (len + 3) 0& ~ 3;
memset((caddr_t) txwi + len, 0, dmalen - len);
@@ -6702,8 +6702,7 @@
struct rt2860_rxdesc *desc;
int i;
- for (i = 0; i < RT2860_SOFTC_RX_RING_DATA_COUNT; i++)
- {
+ for (i = 0; i < RT2860_SOFTC_RX_RING_DATA_COUNT; i++) {
desc = &ring->desc[i];
desc->sdl0 &= ~htole16(RT2860_RXDESC_SDL0_DDONE);
@@ -6724,8 +6723,7 @@
struct rt2860_softc_rx_data *data;
int i;
- if (ring->desc != NULL)
- {
+ if (ring->desc != NULL) {
bus_dmamap_sync(ring->desc_dma_tag, ring->desc_dma_map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(ring->desc_dma_tag, ring->desc_dma_map);
@@ -6736,12 +6734,10 @@
if (ring->desc_dma_tag != NULL)
bus_dma_tag_destroy(ring->desc_dma_tag);
- for (i = 0; i < RT2860_SOFTC_RX_RING_DATA_COUNT; i++)
- {
+ for (i = 0; i < RT2860_SOFTC_RX_RING_DATA_COUNT; i++) {
data = &ring->data[i];
- if (data->m != NULL)
- {
+ if (data->m != NULL) {
bus_dmamap_sync(ring->data_dma_tag, data->dma_map,
BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(ring->data_dma_tag, data->dma_map);
@@ -6766,39 +6762,31 @@
struct rt2860_softc_tx_ring *ring, int qid)
{
struct rt2860_softc_tx_data *data;
- int error, i;
-
+ int error, i, size;
+
+ size = RT2860_SOFTC_TX_RING_DESC_COUNT * sizeof(struct rt2860_txdesc);
mtx_init(&ring->lock, device_get_nameunit(sc->dev), NULL, MTX_DEF);
- error = bus_dma_tag_create(bus_get_dma_tag(sc->dev), PAGE_SIZE, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- RT2860_SOFTC_TX_RING_DESC_COUNT * sizeof(struct rt2860_txdesc), 1,
- RT2860_SOFTC_TX_RING_DESC_COUNT * sizeof(struct rt2860_txdesc),
- 0, NULL, NULL, &ring->desc_dma_tag);
- if (error != 0)
- {
- printf("%s: could not create Tx desc DMA tag\n",
- device_get_nameunit(sc->dev));
+ error = bus_dma_tag_create(bus_get_dma_tag(sc->dev), PAGE_SIZE, 0,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ size, 1, size, 0, NULL, NULL, &ring->desc_dma_tag);
+ if (error != 0) {
+ device_printf(sc->dev, "could not create Tx desc DMA tag\n");
goto fail;
}
error = bus_dmamem_alloc(ring->desc_dma_tag, (void **) &ring->desc,
BUS_DMA_NOWAIT | BUS_DMA_ZERO, &ring->desc_dma_map);
- if (error != 0)
- {
- printf("%s: could not allocate Tx desc DMA memory\n",
- device_get_nameunit(sc->dev));
+ if (error != 0) {
+ device_printf(sc->dev,
+ "could not allocate Tx desc DMA memory\n");
goto fail;
}
error = bus_dmamap_load(ring->desc_dma_tag, ring->desc_dma_map,
- ring->desc,
- RT2860_SOFTC_TX_RING_DESC_COUNT * sizeof(struct rt2860_txdesc),
- rt2860_dma_map_addr, &ring->desc_phys_addr, 0);
- if (error != 0)
- {
- printf("%s: could not load Tx desc DMA map\n",
- device_get_nameunit(sc->dev));
+ ring->desc, size, rt2860_dma_map_addr, &ring->desc_phys_addr, 0);
+ if (error != 0) {
+ device_printf(sc->dev, "could not load Tx desc DMA map\n");
goto fail;
}
@@ -6806,58 +6794,46 @@
ring->desc_cur = 0;
ring->desc_next = 0;
- error = bus_dma_tag_create(bus_get_dma_tag(sc->dev), PAGE_SIZE, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- RT2860_SOFTC_TX_RING_DATA_COUNT * RT2860_TX_DATA_SEG0_SIZE, 1,
- RT2860_SOFTC_TX_RING_DATA_COUNT * RT2860_TX_DATA_SEG0_SIZE,
- 0, NULL, NULL, &ring->seg0_dma_tag);
- if (error != 0)
- {
- printf("%s: could not create Tx seg0 DMA tag\n",
- device_get_nameunit(sc->dev));
+ size = RT2860_SOFTC_TX_RING_DATA_COUNT * RT2860_TX_DATA_SEG0_SIZE;
+ error = bus_dma_tag_create(bus_get_dma_tag(sc->dev), PAGE_SIZE, 0,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ size, 1, size, 0, NULL, NULL, &ring->seg0_dma_tag);
+ if (error != 0) {
+ device_printf(sc->dev, "could not create Tx seg0 DMA tag\n");
goto fail;
}
error = bus_dmamem_alloc(ring->seg0_dma_tag, (void **) &ring->seg0,
BUS_DMA_NOWAIT | BUS_DMA_ZERO, &ring->seg0_dma_map);
- if (error != 0)
- {
- printf("%s: could not allocate Tx seg0 DMA memory\n",
- device_get_nameunit(sc->dev));
+ if (error != 0) {
+ device_printf(sc->dev, "could not allocate Tx seg0 DMA memory\n");
goto fail;
}
error = bus_dmamap_load(ring->seg0_dma_tag, ring->seg0_dma_map,
- ring->seg0,
- RT2860_SOFTC_TX_RING_DATA_COUNT * RT2860_TX_DATA_SEG0_SIZE,
- rt2860_dma_map_addr, &ring->seg0_phys_addr, 0);
- if (error != 0)
- {
- printf("%s: could not load Tx seg0 DMA map\n",
- device_get_nameunit(sc->dev));
+ ring->seg0, size, rt2860_dma_map_addr, &ring->seg0_phys_addr, 0);
+ if (error != 0) {
+ device_printf(sc->dev, "could not load Tx seg0 DMA map\n");
goto fail;
}
- error = bus_dma_tag_create(bus_get_dma_tag(sc->dev), PAGE_SIZE, 0,
+
+ error = bus_dma_tag_create(bus_get_dma_tag(sc->dev), PAGE_SIZE, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- MJUMPAGESIZE, RT2860_SOFTC_MAX_SCATTER, MJUMPAGESIZE, 0, NULL, NULL,
- &ring->data_dma_tag);
- if (error != 0)
- {
- printf("%s: could not create Tx data DMA tag\n",
- device_get_nameunit(sc->dev));
+ MJUMPAGESIZE, RT2860_SOFTC_MAX_SCATTER, MJUMPAGESIZE, 0,
+ NULL, NULL, &ring->data_dma_tag);
+ if (error != 0) {
+ device_printf(sc->dev, "could not create Tx data DMA tag\n");
goto fail;
}
- for (i = 0; i < RT2860_SOFTC_TX_RING_DATA_COUNT; i++)
- {
+ for (i = 0; i < RT2860_SOFTC_TX_RING_DATA_COUNT; i++){
data = &ring->data[i];
- error = bus_dmamap_create(ring->data_dma_tag, 0, &data->dma_map);
- if (error != 0)
- {
- printf("%s: could not create Tx data DMA map\n",
- device_get_nameunit(sc->dev));
+ error = bus_dmamap_create(ring->data_dma_tag, 0,
+ &data->dma_map);
+ if (error != 0) {
+ device_printf(sc->dev, "could not create Tx data DMA map\n");
goto fail;
}
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sdhci/sdhci.c
--- a/head/sys/dev/sdhci/sdhci.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/sdhci/sdhci.c Fri Mar 02 17:36:33 2012 +0200
@@ -24,7 +24,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/sdhci/sdhci.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/dev/sdhci/sdhci.c 231266 2012-02-09 10:20:41Z glebius $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -74,6 +74,8 @@
#define SDHCI_QUIRK_INCR_TIMEOUT_CONTROL (1<<7)
/* Controller has broken read timings */
#define SDHCI_QUIRK_BROKEN_TIMINGS (1<<8)
+/* Controller needs lowered frequency */
+#define SDHCI_QUIRK_LOWER_FREQUENCY (1<<9)
static const struct sdhci_device {
uint32_t model;
@@ -85,6 +87,8 @@
SDHCI_QUIRK_FORCE_DMA },
{ 0xe8221180, 0xffff, "RICOH SD",
SDHCI_QUIRK_FORCE_DMA },
+ { 0xe8231180, 0xffff, "RICOH R5CE823 SD",
+ SDHCI_QUIRK_LOWER_FREQUENCY },
{ 0x8034104c, 0xffff, "TI XX21/XX11 SD",
SDHCI_QUIRK_FORCE_DMA },
{ 0x05501524, 0xffff, "ENE CB712 SD",
@@ -350,6 +354,24 @@
}
static void
+sdhci_lower_frequency(device_t dev)
+{
+
+ /* Enable SD2.0 mode. */
+ pci_write_config(dev, SDHC_PCI_MODE_KEY, 0xfc, 1);
+ pci_write_config(dev, SDHC_PCI_MODE, SDHC_PCI_MODE_SD20, 1);
+ pci_write_config(dev, SDHC_PCI_MODE_KEY, 0x00, 1);
+
+ /*
+ * Some SD/MMC cards don't work with the default base
+ * clock frequency of 200MHz. Lower it to 50Hz.
+ */
+ pci_write_config(dev, SDHC_PCI_BASE_FREQ_KEY, 0x01, 1);
+ pci_write_config(dev, SDHC_PCI_BASE_FREQ, 50, 1);
+ pci_write_config(dev, SDHC_PCI_BASE_FREQ_KEY, 0x00, 1);
+}
+
+static void
sdhci_set_clock(struct sdhci_slot *slot, uint32_t clock)
{
uint32_t res;
@@ -631,6 +653,9 @@
break;
}
}
+ /* Some controllers need to be bumped into the right mode. */
+ if (sc->quirks & SDHCI_QUIRK_LOWER_FREQUENCY)
+ sdhci_lower_frequency(dev);
/* Read slots info from PCI registers. */
slots = pci_read_config(dev, PCI_SLOT_INFO, 1);
bar = PCI_SLOT_INFO_FIRST_BAR(slots);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sdhci/sdhci.h
--- a/head/sys/dev/sdhci/sdhci.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/sdhci/sdhci.h Fri Mar 02 17:36:33 2012 +0200
@@ -22,7 +22,7 @@
* (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$
+ * $FreeBSD: head/sys/dev/sdhci/sdhci.h 231266 2012-02-09 10:20:41Z glebius $
*/
/*
@@ -38,6 +38,15 @@
#define PCI_SLOT_INFO_FIRST_BAR(x) ((x) & 7)
/*
+ * RICOH specific PCI registers
+ */
+#define SDHC_PCI_MODE_KEY 0xf9
+#define SDHC_PCI_MODE 0x150
+#define SDHC_PCI_MODE_SD20 0x10
+#define SDHC_PCI_BASE_FREQ_KEY 0xfc
+#define SDHC_PCI_BASE_FREQ 0xe1
+
+/*
* Controller registers
*/
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sf/if_sf.c
--- a/head/sys/dev/sf/if_sf.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/sf/if_sf.c Fri Mar 02 17:36:33 2012 +0200
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/sf/if_sf.c 227843 2011-11-22 21:28:20Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/sf/if_sf.c 232040 2012-02-23 08:22:44Z yongari $");
/*
* Adaptec AIC-6915 "Starfire" PCI fast ethernet driver for FreeBSD.
@@ -96,7 +96,6 @@
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
-#include <sys/taskqueue.h>
#include <net/bpf.h>
#include <net/if.h>
@@ -172,6 +171,7 @@
static void sf_stop(struct sf_softc *);
static void sf_watchdog(struct sf_softc *);
static int sf_ifmedia_upd(struct ifnet *);
+static int sf_ifmedia_upd_locked(struct ifnet *);
static void sf_ifmedia_sts(struct ifnet *, struct ifmediareq *);
static void sf_reset(struct sf_softc *);
static int sf_dma_alloc(struct sf_softc *);
@@ -191,7 +191,6 @@
static int sf_miibus_readreg(device_t, int, int);
static int sf_miibus_writereg(device_t, int, int, int);
static void sf_miibus_statchg(device_t);
-static void sf_link_task(void *, int);
#ifdef DEVICE_POLLING
static int sf_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
#endif
@@ -393,36 +392,30 @@
sf_miibus_statchg(device_t dev)
{
struct sf_softc *sc;
-
- sc = device_get_softc(dev);
- taskqueue_enqueue(taskqueue_swi, &sc->sf_link_task);
-}
-
-static void
-sf_link_task(void *arg, int pending)
-{
- struct sf_softc *sc;
struct mii_data *mii;
struct ifnet *ifp;
uint32_t val;
- sc = (struct sf_softc *)arg;
-
- SF_LOCK(sc);
-
+ sc = device_get_softc(dev);
mii = device_get_softc(sc->sf_miibus);
ifp = sc->sf_ifp;
if (mii == NULL || ifp == NULL ||
- (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- SF_UNLOCK(sc);
+ (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
return;
+
+ sc->sf_link = 0;
+ if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+ (IFM_ACTIVE | IFM_AVALID)) {
+ switch (IFM_SUBTYPE(mii->mii_media_active)) {
+ case IFM_10_T:
+ case IFM_100_TX:
+ case IFM_100_FX:
+ sc->sf_link = 1;
+ break;
+ }
}
-
- if (mii->mii_media_status & IFM_ACTIVE) {
- if (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)
- sc->sf_link = 1;
- } else
- sc->sf_link = 0;
+ if (sc->sf_link == 0)
+ return;
val = csr_read_4(sc, SF_MACCFG_1);
val &= ~SF_MACCFG1_FULLDUPLEX;
@@ -453,8 +446,6 @@
else
val &= ~SF_TIMER_TIMES_TEN;
csr_write_4(sc, SF_TIMER_CTL, val);
-
- SF_UNLOCK(sc);
}
static void
@@ -523,20 +514,27 @@
sf_ifmedia_upd(struct ifnet *ifp)
{
struct sf_softc *sc;
- struct mii_data *mii;
- struct mii_softc *miisc;
int error;
sc = ifp->if_softc;
SF_LOCK(sc);
+ error = sf_ifmedia_upd_locked(ifp);
+ SF_UNLOCK(sc);
+ return (error);
+}
+static int
+sf_ifmedia_upd_locked(struct ifnet *ifp)
+{
+ struct sf_softc *sc;
+ struct mii_data *mii;
+ struct mii_softc *miisc;
+
+ sc = ifp->if_softc;
mii = device_get_softc(sc->sf_miibus);
LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
PHY_RESET(miisc);
- error = mii_mediachg(mii);
- SF_UNLOCK(sc);
-
- return (error);
+ return (mii_mediachg(mii));
}
/*
@@ -550,8 +548,12 @@
sc = ifp->if_softc;
SF_LOCK(sc);
+ if ((ifp->if_flags & IFF_UP) == 0) {
+ SF_UNLOCK(sc);
+ return;
+ }
+
mii = device_get_softc(sc->sf_miibus);
-
mii_pollstat(mii);
ifmr->ifm_active = mii->mii_media_active;
ifmr->ifm_status = mii->mii_media_status;
@@ -592,7 +594,8 @@
case SIOCADDMULTI:
case SIOCDELMULTI:
SF_LOCK(sc);
- sf_rxfilter(sc);
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+ sf_rxfilter(sc);
SF_UNLOCK(sc);
break;
case SIOCGIFMEDIA:
@@ -744,7 +747,6 @@
mtx_init(&sc->sf_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF);
callout_init_mtx(&sc->sf_co, &sc->sf_mtx, 0);
- TASK_INIT(&sc->sf_link_task, 0, sf_link_task, sc);
/*
* Map control/status registers.
@@ -946,7 +948,6 @@
sf_stop(sc);
SF_UNLOCK(sc);
callout_drain(&sc->sf_co);
- taskqueue_drain(taskqueue_swi, &sc->sf_link_task);
if (ifp != NULL)
ether_ifdetach(ifp);
}
@@ -1548,7 +1549,9 @@
*/
eidx = 0;
prog = 0;
- for (cons = sc->sf_cdata.sf_rxc_cons; ; SF_INC(cons, SF_RX_CLIST_CNT)) {
+ for (cons = sc->sf_cdata.sf_rxc_cons;
+ (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0;
+ SF_INC(cons, SF_RX_CLIST_CNT)) {
cur_cmp = &sc->sf_rdata.sf_rx_cring[cons];
status = le32toh(cur_cmp->sf_rx_status1);
if (status == 0)
@@ -1851,6 +1854,7 @@
struct sf_softc *sc;
struct ifnet *ifp;
uint32_t status;
+ int cnt;
sc = (struct sf_softc *)arg;
SF_LOCK(sc);
@@ -1869,13 +1873,13 @@
if ((ifp->if_capenable & IFCAP_POLLING) != 0)
goto done_locked;
#endif
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- goto done_locked;
/* Disable interrupts. */
csr_write_4(sc, SF_IMR, 0x00000000);
- for (; (status & SF_INTRS) != 0;) {
+ for (cnt = 32; (status & SF_INTRS) != 0;) {
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ break;
if ((status & SF_ISR_RXDQ1_DMADONE) != 0)
sf_rxeof(sc);
@@ -1910,15 +1914,19 @@
#endif
}
}
+ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ sf_start_locked(ifp);
+ if (--cnt <= 0)
+ break;
/* Reading the ISR register clears all interrrupts. */
status = csr_read_4(sc, SF_ISR);
}
- /* Re-enable interrupts. */
- csr_write_4(sc, SF_IMR, SF_INTRS);
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+ /* Re-enable interrupts. */
+ csr_write_4(sc, SF_IMR, SF_INTRS);
+ }
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- sf_start_locked(ifp);
done_locked:
SF_UNLOCK(sc);
}
@@ -2010,6 +2018,7 @@
if (sf_init_rx_ring(sc) == ENOBUFS) {
device_printf(sc->sf_dev,
"initialization failed: no memory for rx buffers\n");
+ sf_stop(sc);
return;
}
@@ -2135,12 +2144,12 @@
else
SF_CLRBIT(sc, SF_GEN_ETH_CTL, SF_ETHCTL_RXGFP_ENB);
- sc->sf_link = 0;
- mii_mediachg(mii);
-
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ sc->sf_link = 0;
+ sf_ifmedia_upd_locked(ifp);
+
callout_reset(&sc->sf_co, hz, sf_tick, sc);
}
@@ -2329,6 +2338,9 @@
/* Disable Tx/Rx egine. */
csr_write_4(sc, SF_GEN_ETH_CTL, 0);
+ /* Give hardware chance to drain active DMA cycles. */
+ DELAY(1000);
+
csr_write_4(sc, SF_CQ_CONSIDX, 0);
csr_write_4(sc, SF_CQ_PRODIDX, 0);
csr_write_4(sc, SF_RXDQ_ADDR_Q1, 0);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sf/if_sfreg.h
--- a/head/sys/dev/sf/if_sfreg.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/sf/if_sfreg.h Fri Mar 02 17:36:33 2012 +0200
@@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/sf/if_sfreg.h 232203 2012-02-27 08:55:32Z kevlo $
*/
/*
@@ -352,7 +352,7 @@
#define SF_INTRS \
(SF_IMR_RXDQ2_NOBUFS|SF_IMR_RXDQ1_DMADONE|SF_IMR_RXDQ2_DMADONE| \
- SF_IMR_TX_DMADONE|SF_IMR_RXDQ1_NOBUFS|SF_IMR_RXDQ2_DMADONE| \
+ SF_IMR_TX_DMADONE|SF_IMR_RXDQ1_NOBUFS| \
SF_IMR_NORMALINTR|SF_IMR_ABNORMALINTR|SF_IMR_TXCQ_NOBUFS| \
SF_IMR_RXCQ1_NOBUFS|SF_IMR_RXCQ2_NOBUFS|SF_IMR_STATSOFLOW| \
SF_IMR_TX_LOFIFO|SF_IMR_DMAERR|SF_IMR_RXGFP_NORESP| \
@@ -1083,7 +1083,6 @@
int sf_if_flags;
struct callout sf_co;
int sf_watchdog_timer;
- struct task sf_link_task;
int sf_link;
int sf_suspended;
int sf_detach;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/siba/siba_cc.c
--- a/head/sys/dev/siba/siba_cc.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/siba/siba_cc.c Fri Mar 02 17:36:33 2012 +0200
@@ -121,6 +121,7 @@
u_int32_t idhi;
u_int32_t corerev;
int uarts = 0;
+ int i;
sc->devid = SIBA_DEVID_CHIPCOMMON;
/*
@@ -256,7 +257,8 @@
}
bus_generic_probe(dev);
- siba_cc_add_child(dev, 1, "uart", 0);
+ for(i = 0; i < uarts; i++) /* add all uarts found on CC */
+ siba_cc_add_child(dev, i+1, "uart", i);
siba_cc_add_child(dev, 10, "cfi", 0);
siba_cc_add_child(dev, 100, "gpio", 0);
@@ -531,7 +533,27 @@
return;
}
+static int
+siba_cc_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+// struct siba_dev_softc *sd;
+// struct siba_softc *siba;
+// sd = device_get_ivars(child);
+// siba = (struct siba_softc *)sd->sd_bus;
+ switch (which) {
+ case SIBA_CC_IVAR_XTALFREQ:
+ /* BCM5354 CC uart uses 25Mhz clock.
+ * Slightly shift it to make uart divisor happy
+ */
+ *result = 25804800;
+ break;
+ default:
+ return (ENOENT);
+ }
+
+ return (0);
+}
static device_method_t siba_cc_methods[] = {
/* Device interface */
@@ -546,6 +568,7 @@
DEVMETHOD(bus_get_resource_list, siba_cc_get_reslist),
DEVMETHOD(bus_add_child, siba_cc_add_child),
DEVMETHOD(bus_print_child, siba_cc_print_child),
+ DEVMETHOD(bus_read_ivar, siba_cc_read_ivar),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/siba/siba_cc.h
--- a/head/sys/dev/siba/siba_cc.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/siba/siba_cc.h Fri Mar 02 17:36:33 2012 +0200
@@ -157,4 +157,8 @@
bus_space_write_4((sc)->sc_bt, (sc)->sc_bh, \
(reg), (val))
+enum siba_cc_device_ivars {
+ SIBA_CC_IVAR_XTALFREQ
+};
+
#endif /* _SIBA_CC_H_ */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/siba/siba_cc_uart.c
--- a/head/sys/dev/siba/siba_cc_uart.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/siba/siba_cc_uart.c Fri Mar 02 17:36:33 2012 +0200
@@ -43,9 +43,10 @@
#include "uart_if.h"
-#define DEFAULT_RCLK 1843200
+// #define DEFAULT_RCLK 1843200
+#define DEFAULT_RCLK 25804800 /* BCM5354 CC */
-static void l_putc( int c )
+static void l_putc( int c , bus_space_handle_t bsh )
{
char chr;
int limit = 2000;
@@ -58,7 +59,7 @@
if ( !(limit % 10) ) limit--;
}
- (*((volatile unsigned char *)0xb8000300)) = c;
+ (*((volatile unsigned char *)bsh)) = c;
*((volatile unsigned int *) 0xb8000000);
@@ -70,7 +71,7 @@
}
}
-static int l_getc( void )
+static int l_getc( bus_space_handle_t bsh )
{
char chr;
int limit = 2000;
@@ -82,7 +83,7 @@
if ( !(limit % 10) ) limit--;
}
- chr = (*((volatile unsigned char *)0xb8000300));
+ chr = (*((volatile unsigned char *)bsh));
if (chr == '~')
breakpoint();
@@ -353,7 +354,7 @@
while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0 && --limit)
DELAY(4);
// uart_setreg(bas, REG_DATA, c);
- l_putc(c);
+ l_putc(c, bas->bsh);
uart_barrier(bas);
limit = 250000;
@@ -372,7 +373,7 @@
ns8250_getc(struct uart_bas *bas, struct mtx *hwmtx)
{
int c;
- return (l_getc());
+ return (l_getc(bas->bsh) );
uart_lock(hwmtx);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/siba/siba_core.c
--- a/head/sys/dev/siba/siba_core.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/siba/siba_core.c Fri Mar 02 17:36:33 2012 +0200
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/siba/siba_core.c 227849 2011-11-22 21:56:55Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/siba/siba_core.c 232250 2012-02-28 13:19:34Z gavin $");
/*
* the Sonics Silicon Backplane driver.
@@ -1173,7 +1173,7 @@
if (((pmu & SIBA_CC_PMUCTL_XF) >> 2) == e->xf)
return;
- DPRINTF(siba, SIBA_DEBUG_PLL, "change PLL value to %u.%03u mhz\n",
+ DPRINTF(siba, SIBA_DEBUG_PLL, "change PLL value to %u.%03u MHz\n",
(xtalfreq / 1000), (xtalfreq % 1000));
KASSERT(siba->siba_chipid == 0x4328 || siba->siba_chipid == 0x5354,
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sound/pci/cs461x_dsp.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/sound/pci/cs461x_dsp.h Fri Mar 02 17:36:33 2012 +0200
@@ -0,0 +1,3497 @@
+/* $FreeBSD: head/sys/dev/sound/pci/cs461x_dsp.h 230897 2012-02-01 21:38:01Z pfg $ */
+/*-
+ * Copyright (C) 1996-2008, 4Front Technologies
+ * 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 AUTHOR 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 AUTHOR 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, WHETHERIN 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.
+ *
+ */
+/*
+ * This file is based on cs461x_dsp.h from the Open Sound System.
+ * Purpose: Firmware for cs461x/cs461x cards.
+ */
+
+#ifndef _DEV_SOUND_PCI_CS461X_DSP_H
+#define _DEV_SOUND_PCI_CS461X_DSP_H
+
+struct cs461x_firmware_struct cs461x_firmware = {
+ {{0x00000000, 0x00003000}, {0x00010000, 0x00003800},
+ {0x00020000, 0x00007000}},
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000163, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00200040, 0x00008010, 0x00000000,
+ 0x00000000, 0x80000001, 0x00000001, 0x00060000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00900080, 0x00000173, 0x00000000,
+ 0x00000000, 0x00000010, 0x00800000, 0x00900000,
+ 0xf2c0000f, 0x00000200, 0x00000000, 0x00010600,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000163, 0x330300c2,
+ 0x06000000, 0x00000000, 0x80008000, 0x80008000,
+ 0x3fc0000f, 0x00000301, 0x00010400, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00b00000, 0x00d0806d, 0x330480c3,
+ 0x04800000, 0x00000001, 0x00800001, 0x0000ffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x066a0130, 0x06350070, 0x0000929d, 0x929d929d,
+ 0x00000000, 0x0000735a, 0x00000600, 0x00000000,
+ 0x929d735a, 0x00000000, 0x00010000, 0x735a735a,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x000000f0, 0x0000804f, 0x000000c3,
+ 0x05000000, 0x00a00010, 0x00000000, 0x80008000,
+ 0x00000000, 0x00000000, 0x00000700, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000080, 0x00a00000, 0x0000809a, 0x000000c2,
+ 0x07400000, 0x00000000, 0x80008000, 0xffffffff,
+ 0x00c80028, 0x00005555, 0x00000000, 0x000107a0,
+ 0x00c80028, 0x000000c2, 0x06800000, 0x00000000,
+ 0x06e00080, 0x00300000, 0x000080bb, 0x000000c9,
+ 0x07a00000, 0x04000000, 0x80008000, 0xffffffff,
+ 0x00c80028, 0x00005555, 0x00000000, 0x00000780,
+ 0x00c80028, 0x000000c5, 0xff800000, 0x00000000,
+ 0x00640080, 0x00c00000, 0x00008197, 0x000000c9,
+ 0x07800000, 0x04000000, 0x80008000, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000805e, 0x000000c1,
+ 0x00000000, 0x00800000, 0x80008000, 0x80008000,
+ 0x00020000, 0x0000ffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x07c00000, 0x00900000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000018e, 0x000000c2,
+ 0x07c00000, 0x00000000, 0x80008000, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00e00100, 0x00000173, 0x00000000,
+ 0x00000000, 0x00400010, 0x00800000, 0x00e00000,
+ 0x00000000, 0x00000000, 0x08400000, 0x00900000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x01100000, 0x0000018e, 0x000000c2,
+ 0x08400000, 0x00000000, 0x80008000, 0xffffffff,
+ 0x007fff80, 0x00280058, 0x01300000, 0x00000000,
+ 0x00000000, 0x2aab0000, 0x00000000, 0x00000000,
+ 0x00000000, 0x01200000, 0x0000026c, 0x000000c2,
+ 0x08c00000, 0x18000000, 0x80008000, 0x80008000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000805e, 0x000000c1,
+ 0x00000000, 0x01000000, 0x80008000, 0x80008000,
+ 0x00000000, 0x00000110, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000082, 0x09000000, 0x00000000,
+ 0x00000000, 0x00000600, 0x013d0233, 0x20ff0040,
+ 0x00000000, 0x0000804c, 0x000101d8, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x929d0600, 0x929d929d, 0x929d929d, 0x929d0000,
+ 0x929d929d, 0x929d929d, 0x929d929d, 0x929d929d,
+ 0x929d929d, 0x00100635, 0x060b013f, 0x00000004,
+ 0x00000001, 0x007a0002, 0x00000000, 0x066e0610,
+ 0x0105929d, 0x929d929d, 0x929d929d, 0x929d929d,
+ 0x929d929d, 0xa431ac75, 0x0001735a, 0xa431ac75,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0x735a0051,
+ 0x00000000, 0x929d929d, 0x929d929d, 0x929d929d,
+ 0x929d929d, 0x929d929d, 0x929d929d, 0x929d929d,
+ 0x929d929d, 0x929d929d, 0x00000000, 0x06400136,
+ 0x0000270f, 0x00010000, 0x007a0000, 0x00000000,
+ 0x068e0645, 0x0105929d, 0x929d929d, 0x929d929d,
+ 0x929d929d, 0x929d929d, 0xa431ac75, 0x0001735a,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0x735a0100, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00010004,
+ 0x00040730, 0x00001002, 0x000f619e, 0x00001003,
+ 0x00001705, 0x00001400, 0x000a411e, 0x00001003,
+ 0x00040730, 0x00001002, 0x000f619e, 0x00001003,
+ 0x00009705, 0x00001400, 0x000a411e, 0x00001003,
+ 0x00040730, 0x00001002, 0x000f619e, 0x00001003,
+ 0x00011705, 0x00001400, 0x000a411e, 0x00001003,
+ 0x00040730, 0x00001002, 0x000f619e, 0x00001003,
+ 0x00019705, 0x00001400, 0x000a411e, 0x00001003,
+ 0x00040730, 0x00001002, 0x000f619e, 0x00001003,
+ 0x00021705, 0x00001400, 0x000a411e, 0x00001003,
+ 0x00040730, 0x00001002, 0x000f619e, 0x00001003,
+ 0x00029705, 0x00001400, 0x000a411e, 0x00001003,
+ 0x00040730, 0x00001002, 0x000f619e, 0x00001003,
+ 0x00031705, 0x00001400, 0x000a411e, 0x00001003,
+ 0x00040730, 0x00001002, 0x000f619e, 0x00001003,
+ 0x00039705, 0x00001400, 0x000a411e, 0x00001003,
+ 0x000fe19e, 0x00001003, 0x0009c730, 0x00001003,
+ 0x0008e19c, 0x00001003, 0x000083c1, 0x00093040,
+ 0x00098730, 0x00001002, 0x000ee19e, 0x00001003,
+ 0x00009705, 0x00001400, 0x000a211e, 0x00001003,
+ 0x00098730, 0x00001002, 0x000ee19e, 0x00001003,
+ 0x00011705, 0x00001400, 0x000a211e, 0x00001003,
+ 0x00098730, 0x00001002, 0x000ee19e, 0x00001003,
+ 0x00019705, 0x00001400, 0x000a211e, 0x00001003,
+ 0x00098730, 0x00001002, 0x000ee19e, 0x00001003,
+ 0x00021705, 0x00001400, 0x000a211e, 0x00001003,
+ 0x00098730, 0x00001002, 0x000ee19e, 0x00001003,
+ 0x00029705, 0x00001400, 0x000a211e, 0x00001003,
+ 0x00098730, 0x00001002, 0x000ee19e, 0x00001003,
+ 0x00031705, 0x00001400, 0x000a211e, 0x00001003,
+ 0x00098730, 0x00001002, 0x000ee19e, 0x00001003,
+ 0x00039705, 0x00001400, 0x000a211e, 0x00001003,
+ 0x0000a730, 0x00001008, 0x000e2730, 0x00001002,
+ 0x0000a731, 0x00001002, 0x0000a731, 0x00001002,
+ 0x0000a731, 0x00001002, 0x0000a731, 0x00001002,
+ 0x0000a731, 0x00001002, 0x0000a731, 0x00001002,
+ 0x00000000, 0x00000000, 0x000f619c, 0x00001003,
+ 0x0007f801, 0x000c0000, 0x00000037, 0x00001000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x000c0000, 0x00000000, 0x00000000,
+ 0x0000373c, 0x00001000, 0x00000000, 0x00000000,
+ 0x000ee19c, 0x00001003, 0x0007f801, 0x000c0000,
+ 0x00000037, 0x00001000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000273c, 0x00001000,
+ 0x00000033, 0x00001000, 0x000e679e, 0x00001003,
+ 0x00007705, 0x00001400, 0x000ac71e, 0x00001003,
+ 0x00087fc1, 0x000c3be0, 0x0007f801, 0x000c0000,
+ 0x00000037, 0x00001000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000a730, 0x00001003,
+ 0x00000033, 0x00001000, 0x0007f801, 0x000c0000,
+ 0x00000037, 0x00001000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x000c0000,
+ 0x00000032, 0x00001000, 0x0000273d, 0x00001000,
+ 0x0004a730, 0x00001003, 0x00000f41, 0x00097140,
+ 0x0000a841, 0x0009b240, 0x0000a0c1, 0x0009f040,
+ 0x0001c641, 0x00093540, 0x0001cec1, 0x0009b5c0,
+ 0x00000000, 0x00000000, 0x0001bf05, 0x0003fc40,
+ 0x00002725, 0x000aa400, 0x00013705, 0x00093a00,
+ 0x0000002e, 0x0009d6c0, 0x00038630, 0x00001004,
+ 0x0004ef0a, 0x000eb785, 0x0003fc8a, 0x00000000,
+ 0x00000000, 0x000c70e0, 0x0007d182, 0x0002c640,
+ 0x00000630, 0x00001004, 0x000799b8, 0x0002c6c0,
+ 0x00031705, 0x00092240, 0x00039f05, 0x000932c0,
+ 0x0003520a, 0x00000000, 0x00040731, 0x0000100b,
+ 0x00010705, 0x000b20c0, 0x00000000, 0x000eba44,
+ 0x00032108, 0x000c60c4, 0x00065208, 0x000c2917,
+ 0x000406b0, 0x00001007, 0x00012f05, 0x00036880,
+ 0x0002818e, 0x000c0000, 0x0004410a, 0x00000000,
+ 0x00040630, 0x00001007, 0x00029705, 0x000c0000,
+ 0x00000000, 0x00000000, 0x00003fc1, 0x0003fc40,
+ 0x000037c1, 0x00091b40, 0x00003fc1, 0x000911c0,
+ 0x000037c1, 0x000957c0, 0x00003fc1, 0x000951c0,
+ 0x000037c1, 0x00000000, 0x00003fc1, 0x000991c0,
+ 0x000037c1, 0x00000000, 0x00003fc1, 0x0009d1c0,
+ 0x000037c1, 0x00000000, 0x0001ccc1, 0x000915c0,
+ 0x0001c441, 0x0009d800, 0x0009cdc1, 0x00091240,
+ 0x0001c541, 0x00091d00, 0x0009cfc1, 0x00095240,
+ 0x0001c741, 0x00095c80, 0x000e8ca9, 0x00099240,
+ 0x000e85ad, 0x00095640, 0x00069ca9, 0x00099d80,
+ 0x000e952d, 0x00099640, 0x000eaca9, 0x0009d6c0,
+ 0x000ea5ad, 0x00091a40, 0x0006bca9, 0x0009de80,
+ 0x000eb52d, 0x00095a40, 0x000ecca9, 0x00099ac0,
+ 0x000ec5ad, 0x0009da40, 0x000edca9, 0x0009d300,
+ 0x000a6e0a, 0x00001000, 0x000ed52d, 0x00091e40,
+ 0x000eeca9, 0x00095ec0, 0x000ee5ad, 0x00099e40,
+ 0x0006fca9, 0x00002500, 0x000fb208, 0x000c59a0,
+ 0x000ef52d, 0x0009de40, 0x00068ca9, 0x000912c1,
+ 0x000683ad, 0x00095241, 0x00020f05, 0x000991c1,
+ 0x00000000, 0x00000000, 0x00086f88, 0x00001000,
+ 0x0009cf81, 0x000b5340, 0x0009c701, 0x000b92c0,
+ 0x0009de81, 0x000bd300, 0x0009d601, 0x000b1700,
+ 0x0001fd81, 0x000b9d80, 0x0009f501, 0x000b57c0,
+ 0x000a0f81, 0x000bd740, 0x00020701, 0x000b5c80,
+ 0x000a1681, 0x000b97c0, 0x00021601, 0x00002500,
+ 0x000a0701, 0x000b9b40, 0x000a0f81, 0x000b1bc0,
+ 0x00021681, 0x00002d00, 0x00020f81, 0x000bd800,
+ 0x000a0701, 0x000b5bc0, 0x00021601, 0x00003500,
+ 0x000a0f81, 0x000b5f40, 0x000a0701, 0x000bdbc0,
+ 0x00021681, 0x00003d00, 0x00020f81, 0x000b1d00,
+ 0x000a0701, 0x000b1fc0, 0x00021601, 0x00020500,
+ 0x00020f81, 0x000b1341, 0x000a0701, 0x000b9fc0,
+ 0x00021681, 0x00020d00, 0x00020f81, 0x000bde80,
+ 0x000a0701, 0x000bdfc0, 0x00021601, 0x00021500,
+ 0x00020f81, 0x000b9341, 0x00020701, 0x000b53c1,
+ 0x00021681, 0x00021d00, 0x000a0f81, 0x000d0380,
+ 0x0000b601, 0x000b15c0, 0x00007b01, 0x00000000,
+ 0x00007b81, 0x000bd1c0, 0x00007b01, 0x00000000,
+ 0x00007b81, 0x000b91c0, 0x00007b01, 0x000b57c0,
+ 0x00007b81, 0x000b51c0, 0x00007b01, 0x000b1b40,
+ 0x00007b81, 0x000b11c0, 0x00087b01, 0x000c3dc0,
+ 0x0007e488, 0x000d7e45, 0x00000000, 0x000d7a44,
+ 0x0007e48a, 0x00000000, 0x00011f05, 0x00084080,
+ 0x00000000, 0x00000000, 0x00001705, 0x000b3540,
+ 0x00008a01, 0x000bf040, 0x00007081, 0x000bb5c0,
+ 0x00055488, 0x00000000, 0x0000d482, 0x0003fc40,
+ 0x0003fc88, 0x00000000, 0x0001e401, 0x000b3a00,
+ 0x0001ec81, 0x000bd6c0, 0x0004ef08, 0x000eb784,
+ 0x000c86b0, 0x00001007, 0x00008281, 0x000bb240,
+ 0x0000b801, 0x000b7140, 0x00007888, 0x00000000,
+ 0x0000073c, 0x00001000, 0x0007f188, 0x000c0000,
+ 0x00000000, 0x00000000, 0x00055288, 0x000c555c,
+ 0x0005528a, 0x000c0000, 0x0009fa88, 0x000c5d00,
+ 0x0000fa88, 0x00000000, 0x00000032, 0x00001000,
+ 0x0000073d, 0x00001000, 0x0007f188, 0x000c0000,
+ 0x00000000, 0x00000000, 0x0008c01c, 0x00001003,
+ 0x00002705, 0x00001008, 0x0008b201, 0x000c1392,
+ 0x0000ba01, 0x00000000, 0x00008731, 0x00001400,
+ 0x0004c108, 0x000fe0c4, 0x00057488, 0x00000000,
+ 0x000a6388, 0x00001001, 0x0008b334, 0x000bc141,
+ 0x0003020e, 0x00000000, 0x000886b0, 0x00001008,
+ 0x00003625, 0x000c5dfa, 0x000a638a, 0x00001001,
+ 0x0008020e, 0x00001002, 0x0008a6b0, 0x00001008,
+ 0x0007f301, 0x00000000, 0x00000000, 0x00000000,
+ 0x00002725, 0x000a8c40, 0x000000ae, 0x00000000,
+ 0x000d8630, 0x00001008, 0x00000000, 0x000c74e0,
+ 0x0007d182, 0x0002d640, 0x000a8630, 0x00001008,
+ 0x000799b8, 0x0002d6c0, 0x0000748a, 0x000c3ec5,
+ 0x0007420a, 0x000c0000, 0x00062208, 0x000c4117,
+ 0x00070630, 0x00001009, 0x00000000, 0x000c0000,
+ 0x0001022e, 0x00000000, 0x0003a630, 0x00001009,
+ 0x00000000, 0x000c0000, 0x00000036, 0x00001000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0002a730, 0x00001008, 0x0007f801, 0x000c0000,
+ 0x00000037, 0x00001000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0002a730, 0x00001008,
+ 0x00000033, 0x00001000, 0x0002a705, 0x00001008,
+ 0x00007a01, 0x000c0000, 0x000e6288, 0x000d550a,
+ 0x0006428a, 0x00000000, 0x00060730, 0x0000100a,
+ 0x00000000, 0x000c0000, 0x00000000, 0x00000000,
+ 0x0007aab0, 0x00034880, 0x00078fb0, 0x0000100b,
+ 0x00057488, 0x00000000, 0x00033b94, 0x00081140,
+ 0x000183ae, 0x00000000, 0x000786b0, 0x0000100b,
+ 0x00022f05, 0x000c3545, 0x0000eb8a, 0x00000000,
+ 0x00042731, 0x00001003, 0x0007aab0, 0x00034880,
+ 0x00048fb0, 0x0000100a, 0x00057488, 0x00000000,
+ 0x00033b94, 0x00081140, 0x000183ae, 0x00000000,
+ 0x000806b0, 0x0000100b, 0x00022f05, 0x00000000,
+ 0x00007401, 0x00091140, 0x00048f05, 0x000951c0,
+ 0x00042731, 0x00001003, 0x0000473d, 0x00001000,
+ 0x000f19b0, 0x000bbc47, 0x00080000, 0x000bffc7,
+ 0x000fe19e, 0x00001003, 0x00000000, 0x00000000,
+ 0x0008e19c, 0x00001003, 0x000083c1, 0x00093040,
+ 0x00000f41, 0x00097140, 0x0000a841, 0x0009b240,
+ 0x0000a0c1, 0x0009f040, 0x0001c641, 0x00093540,
+ 0x0001cec1, 0x0009b5c0, 0x00000000, 0x000fdc44,
+ 0x00055208, 0x00000000, 0x00010705, 0x000a2880,
+ 0x0000a23a, 0x00093a00, 0x0003fc8a, 0x000df6c5,
+ 0x0004ef0a, 0x000c0000, 0x00012f05, 0x00036880,
+ 0x00065308, 0x000c2997, 0x000d86b0, 0x0000100a,
+ 0x0004410a, 0x000d40c7, 0x00000000, 0x00000000,
+ 0x00080730, 0x00001004, 0x00056f0a, 0x000ea105,
+ 0x00000000, 0x00000000, 0x0000473d, 0x00001000,
+ 0x000f19b0, 0x000bbc47, 0x00080000, 0x000bffc7,
+ 0x0000273d, 0x00001000, 0x00000000, 0x000eba44,
+ 0x00048f05, 0x0000f440, 0x00007401, 0x0000f7c0,
+ 0x00000734, 0x00001000, 0x00010705, 0x000a6880,
+ 0x00006a88, 0x000c75c4, 0x00000000, 0x000e5084,
+ 0x00000000, 0x000eba44, 0x00087401, 0x000e4782,
+ 0x00000734, 0x00001000, 0x00010705, 0x000a6880,
+ 0x00006a88, 0x000c75c4, 0x0007c108, 0x000c0000,
+ 0x0007e721, 0x000bed40, 0x00005f25, 0x000badc0,
+ 0x0003ba97, 0x000beb80, 0x00065590, 0x000b2e00,
+ 0x00033217, 0x00003ec0, 0x00065590, 0x000b8e40,
+ 0x0003ed80, 0x000491c0, 0x00073fb0, 0x00074c80,
+ 0x000283a0, 0x0000100c, 0x000ee388, 0x00042970,
+ 0x00008301, 0x00021ef2, 0x000b8f14, 0x0000000f,
+ 0x000c4d8d, 0x0000001b, 0x000d6dc2, 0x000e06c6,
+ 0x000032ac, 0x000c3916, 0x0004edc2, 0x00074c80,
+ 0x00078898, 0x00001000, 0x00038894, 0x00000032,
+ 0x000c4d8d, 0x00092e1b, 0x000d6dc2, 0x000e06c6,
+ 0x0004edc2, 0x000c1956, 0x0000722c, 0x00034a00,
+ 0x00041705, 0x0009ed40, 0x00058730, 0x00001400,
+ 0x000d7488, 0x000c3a00, 0x00048f05, 0x00000000,
+ 0x0007bfb0, 0x000bc240, 0x00000c2e, 0x000c6084,
+ 0x000e8630, 0x0000100c, 0x00006408, 0x000efb84,
+ 0x00016008, 0x00000000, 0x0001c088, 0x000c0000,
+ 0x000fc908, 0x000e3392, 0x0005f488, 0x000efb84,
+ 0x0001d402, 0x000b2e00, 0x0003d418, 0x00001000,
+ 0x0008d574, 0x000c4293, 0x00065625, 0x000ea30e,
+ 0x00096c01, 0x000c6f92, 0x0001a58a, 0x000c6085,
+ 0x00002f43, 0x00000000, 0x000103a0, 0x0000100d,
+ 0x0005e608, 0x000c0000, 0x00000000, 0x00000000,
+ 0x000ca108, 0x000dcca1, 0x00003bac, 0x000c3205,
+ 0x00073843, 0x00000000, 0x00040730, 0x0000100d,
+ 0x0001600a, 0x000c0000, 0x00057488, 0x00000000,
+ 0x00000000, 0x000e5084, 0x00000000, 0x000eba44,
+ 0x00087401, 0x000e4782, 0x00000734, 0x00001000,
+ 0x00010705, 0x000a6880, 0x00006a88, 0x000c75c4,
+ 0x0006a108, 0x000cf2c4, 0x0004f4c0, 0x00000000,
+ 0x000fa418, 0x0000101f, 0x0005d402, 0x0001c500,
+ 0x000e8630, 0x0000100d, 0x00004418, 0x00001380,
+ 0x000e243d, 0x000d394a, 0x00049705, 0x00000000,
+ 0x0007d530, 0x000b4240, 0x000d80f2, 0x0000100d,
+ 0x00009134, 0x000ca20a, 0x00004c90, 0x00001000,
+ 0x0005d705, 0x00000000, 0x00004f25, 0x00098240,
+ 0x00004725, 0x00000000, 0x0000e48a, 0x00000000,
+ 0x00027295, 0x0009c2c0, 0x0003df25, 0x00000000,
+ 0x000e0030, 0x0000100e, 0x0005f718, 0x000ac600,
+ 0x0007cf30, 0x000c2a01, 0x0007a630, 0x0000100e,
+ 0x000484a0, 0x0000100e, 0x00029314, 0x000bcb80,
+ 0x0003cf25, 0x000b0e00, 0x0004f5c0, 0x00000000,
+ 0x00049118, 0x000d888a, 0x0007dd02, 0x000c6efa,
+ 0x00000000, 0x00000000, 0x0004f5c0, 0x00069c80,
+ 0x0000d402, 0x00000000, 0x000e0630, 0x0000100e,
+ 0x00079130, 0x00000000, 0x00049118, 0x00090e00,
+ 0x0006c10a, 0x00000000, 0x00000000, 0x000c0000,
+ 0x0007cf30, 0x00030580, 0x00005725, 0x00000000,
+ 0x000d04a0, 0x0000100e, 0x00029314, 0x000b4780,
+ 0x0003cf25, 0x000b8600, 0x00000000, 0x00000000,
+ 0x00000000, 0x000c0000, 0x00000000, 0x00042c80,
+ 0x0001dec1, 0x000e488c, 0x00031114, 0x00000000,
+ 0x0004f5c2, 0x00000000, 0x0003640a, 0x00000000,
+ 0x00000000, 0x000e5084, 0x00000000, 0x000eb844,
+ 0x00007001, 0x00000000, 0x00000734, 0x00001000,
+ 0x00010705, 0x000a6880, 0x00006a88, 0x000c75c4,
+ 0x00036488, 0x00000000, 0x0000c403, 0x00001000,
+ 0x000fa6b1, 0x00001010, 0x00014403, 0x00001000,
+ 0x0006a6b1, 0x00001011, 0x0006a108, 0x000cf2c4,
+ 0x0004f4c0, 0x000d5384, 0x0007e48a, 0x00000000,
+ 0x00067718, 0x00001000, 0x0007a418, 0x00001000,
+ 0x0007221a, 0x00000000, 0x0005d402, 0x00014500,
+ 0x000d8630, 0x0000100f, 0x00004418, 0x00001780,
+ 0x000e243d, 0x000d394a, 0x00049705, 0x00000000,
+ 0x0007d530, 0x000b4240, 0x000cc0f2, 0x0000100f,
+ 0x00014414, 0x00000000, 0x00004c90, 0x00001000,
+ 0x0005d705, 0x00000000, 0x00004f25, 0x00098240,
+ 0x00004725, 0x00000000, 0x0000e48a, 0x00000000,
+ 0x00027295, 0x0009c2c0, 0x0007df25, 0x00000000,
+ 0x000cc030, 0x00001010, 0x0005f718, 0x000fe798,
+ 0x00029314, 0x000bcb80, 0x00000930, 0x000b0e00,
+ 0x0004f5c0, 0x000de204, 0x000a84a0, 0x00001010,
+ 0x0007cf25, 0x000e3560, 0x00049118, 0x00000000,
+ 0x00049118, 0x000d888a, 0x0007dd02, 0x000c6efa,
+ 0x0000c434, 0x00030040, 0x000fda82, 0x000c2312,
+ 0x000fdc0e, 0x00001001, 0x00083402, 0x000c2b92,
+ 0x000906b0, 0x00001010, 0x00075a82, 0x00000000,
+ 0x0000d625, 0x000b0940, 0x0000840e, 0x00001002,
+ 0x0000aabc, 0x000c511e, 0x00098730, 0x00001010,
+ 0x0000aaf4, 0x000e910a, 0x0004628a, 0x00000000,
+ 0x00006aca, 0x00000000, 0x00000930, 0x00000000,
+ 0x0004f5c0, 0x00069c80, 0x00046ac0, 0x00000000,
+ 0x0003c40a, 0x000fc898, 0x00049118, 0x00090e00,
+ 0x0006c10a, 0x00000000, 0x00000000, 0x000e5084,
+ 0x00000000, 0x000eb844, 0x00007001, 0x00000000,
+ 0x00000734, 0x00001000, 0x00010705, 0x000a6880,
+ 0x00006a88, 0x000c75c4, 0x00048f05, 0x00001402,
+ 0x00051705, 0x00001402, 0x00046dc0, 0x000feac1,
+ 0x0005a6b0, 0x00001011, 0x00085f25, 0x000c2b92,
+ 0x000475c2, 0x00000000, 0x00005f05, 0x00001400,
+ 0x00046dc2, 0x00000000, 0x00000f05, 0x00001402,
+ 0x0003a508, 0x00000000, 0x00005f05, 0x00001400,
+ 0x00046dc2, 0x00000000, 0x00004438, 0x000d9205,
+ 0x0000273d, 0x00001000, 0x00048f05, 0x00001402,
+ 0x00085f25, 0x000c2b92, 0x00046dc2, 0x000c621c,
+ 0x0003240a, 0x000c0000, 0x00046dc0, 0x00000000,
+ 0x0000273d, 0x00001000, 0x00066488, 0x00000000,
+ 0x0000c403, 0x00001000, 0x0009a6b1, 0x00001012,
+ 0x00014403, 0x00001000, 0x0003a6b1, 0x00001013,
+ 0x0006a108, 0x00000000, 0x00023c18, 0x00001000,
+ 0x0004f4c0, 0x000c3245, 0x0000a418, 0x00001000,
+ 0x0003a20a, 0x00000000, 0x00004418, 0x00001380,
+ 0x000e243d, 0x000d394a, 0x000c9705, 0x000def92,
+ 0x0006c030, 0x00001012, 0x0005f718, 0x000fe798,
+ 0x000504a0, 0x00001012, 0x00029314, 0x000b4780,
+ 0x0003cf25, 0x000b8600, 0x00005725, 0x00000000,
+ 0x00000000, 0x000c05d7, 0x00000000, 0x00042c80,
+ 0x0001dec1, 0x000e488c, 0x000b1114, 0x000c2f12,
+ 0x0004f5c2, 0x00000000, 0x0004a918, 0x00098600,
+ 0x0006c28a, 0x00000000, 0x00000000, 0x000e5084,
+ 0x00000000, 0x000eb844, 0x00007001, 0x00000000,
+ 0x00000734, 0x00001000, 0x00010705, 0x000a6880,
+ 0x00006a88, 0x000c75c4, 0x00069705, 0x00001402,
+ 0x00038f05, 0x00001400, 0x000475c0, 0x000feac1,
+ 0x000fa6b0, 0x00001012, 0x00046dc0, 0x00000000,
+ 0x00085518, 0x0000100f, 0x00045534, 0x000f9285,
+ 0x00068f05, 0x00001402, 0x00046588, 0x000feedd,
+ 0x00046dc2, 0x00000000, 0x00070f05, 0x00001402,
+ 0x0005e588, 0x000e36e1, 0x00000000, 0x000c5084,
+ 0x00002f25, 0x000f2a84, 0x00005518, 0x000017fc,
+ 0x0006550a, 0x00000000, 0x0000551a, 0x00001002,
+ 0x0003450a, 0x000f6145, 0x0000473d, 0x00001000,
+ 0x00004438, 0x000f1205, 0x00005f25, 0x00000000,
+ 0x00068f05, 0x00001402, 0x00005725, 0x000e36e1,
+ 0x0000c438, 0x000f1205, 0x0000273d, 0x00001000,
+ 0x0002a880, 0x000b4e40, 0x00042214, 0x000e5548,
+ 0x000542bf, 0x00000000, 0x00000000, 0x000481c0,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000030,
+ 0x0000072d, 0x000fbf8a, 0x00077f94, 0x000ea7df,
+ 0x0002ac95, 0x000d3145, 0x00002731, 0x00001400,
+ 0x00006288, 0x000c71c4, 0x00014108, 0x000e6044,
+ 0x00035408, 0x00000000, 0x00025418, 0x000a0ec0,
+ 0x0001443d, 0x000ca21e, 0x00046595, 0x000d730c,
+ 0x0006538e, 0x00000000, 0x0000c630, 0x00001014,
+ 0x000e7b0e, 0x000df782, 0x0001c6b0, 0x00001014,
+ 0x00036f05, 0x000c0000, 0x00043695, 0x000d598c,
+ 0x0005331a, 0x000f2185, 0x00000000, 0x00000000,
+ 0x000007ae, 0x000bdb00, 0x00040630, 0x00001400,
+ 0x0005e708, 0x000c0000, 0x0007ef30, 0x000b1c00,
+ 0x000806a0, 0x00001014, 0x00066408, 0x000c0000,
+ 0x00000000, 0x00000000, 0x00021843, 0x00000000,
+ 0x00000cac, 0x00062c00, 0x00001dac, 0x00063400,
+ 0x00002cac, 0x0006cc80, 0x000db943, 0x000e5ca1,
+ 0x00000000, 0x00000000, 0x0006680a, 0x000f3205,
+ 0x00042730, 0x00001400, 0x00014108, 0x000f2204,
+ 0x00025418, 0x000a2ec0, 0x00015dbd, 0x00038100,
+ 0x00015dbc, 0x00000000, 0x0005e415, 0x00034880,
+ 0x0001258a, 0x000d730c, 0x0006538e, 0x000baa40,
+ 0x00008630, 0x00001015, 0x00067b0e, 0x000ac380,
+ 0x0003ef05, 0x00000000, 0x0000f734, 0x0001c300,
+ 0x000586b0, 0x00001400, 0x000b6f05, 0x000c3a00,
+ 0x00048f05, 0x00000000, 0x0005b695, 0x0008c380,
+ 0x0002058e, 0x00000000, 0x000500b0, 0x00001400,
+ 0x0002b318, 0x000e998d, 0x0006430a, 0x00000000,
+ 0x00000000, 0x000ef384, 0x00004725, 0x000c0000,
+ 0x00000000, 0x000f3204, 0x00004f25, 0x000c0000,
+ 0x00080000, 0x000e5ca1, 0x000cb943, 0x000e5ca1,
+ 0x0004b943, 0x00000000, 0x00040730, 0x00001400,
+ 0x000cb943, 0x000e5ca1, 0x0004b943, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000}
+};
+
+#endif /* !_DEV_SOUND_PCI_CS461X_DSP_H */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sound/pci/csa.c
--- a/head/sys/dev/sound/pci/csa.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/sound/pci/csa.c Fri Mar 02 17:36:33 2012 +0200
@@ -50,9 +50,9 @@
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
-#include <gnu/dev/sound/pci/csaimg.h>
+#include <dev/sound/pci/cs461x_dsp.h>
-SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/csa.c 230602 2012-01-26 21:43:11Z pfg $");
+SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/csa.c 230897 2012-02-01 21:38:01Z pfg $");
/* This is the pci device id. */
#define CS4610_PCI_ID 0x60011013
@@ -95,6 +95,7 @@
static driver_intr_t csa_intr;
static int csa_initialize(sc_p scp);
static int csa_downloadimage(csa_res *resp);
+static int csa_transferimage(csa_res *resp, u_int32_t *src, u_long dest, u_long len);
static devclass_t csa_devclass;
@@ -860,26 +861,46 @@
static int
csa_downloadimage(csa_res *resp)
{
- int i;
- u_int32_t tmp, src, dst, count;
+ int ret;
+ u_long ul, offset;
- for (i = 0; i < CLEAR__COUNT; i++) {
- dst = ClrStat[i].BA1__DestByteOffset;
- count = ClrStat[i].BA1__SourceSize;
- for (tmp = 0; tmp < count; tmp += 4)
- csa_writemem(resp, dst + tmp, 0x00000000);
+ for (ul = 0, offset = 0 ; ul < INKY_MEMORY_COUNT ; ul++) {
+ /*
+ * DMA this block from host memory to the appropriate
+ * memory on the CSDevice.
+ */
+ ret = csa_transferimage(resp,
+ cs461x_firmware.BA1Array + offset,
+ cs461x_firmware.MemoryStat[ul].ulDestAddr,
+ cs461x_firmware.MemoryStat[ul].ulSourceSize);
+ if (ret)
+ return (ret);
+ offset += cs461x_firmware.MemoryStat[ul].ulSourceSize >> 2;
}
+ return (0);
+}
- for (i = 0; i < FILL__COUNT; i++) {
- src = 0;
- dst = FillStat[i].Offset;
- count = FillStat[i].Size;
- for (tmp = 0; tmp < count; tmp += 4) {
- csa_writemem(resp, dst + tmp, FillStat[i].pFill[src]);
- src++;
- }
- }
+static int
+csa_transferimage(csa_res *resp, u_int32_t *src, u_long dest, u_long len)
+{
+ u_long ul;
+
+ /*
+ * We do not allow DMAs from host memory to host memory (although the DMA
+ * can do it) and we do not allow DMAs which are not a multiple of 4 bytes
+ * in size (because that DMA can not do that). Return an error if either
+ * of these conditions exist.
+ */
+ if ((len & 0x3) != 0)
+ return (EINVAL);
+ /* Check the destination address that it is a multiple of 4 */
+ if ((dest & 0x3) != 0)
+ return (EINVAL);
+
+ /* Write the buffer out. */
+ for (ul = 0 ; ul < len ; ul += 4)
+ csa_writemem(resp, dest + ul, src[ul >> 2]);
return (0);
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sound/pci/csareg.h
--- a/head/sys/dev/sound/pci/csareg.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/sound/pci/csareg.h Fri Mar 02 17:36:33 2012 +0200
@@ -27,7 +27,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/dev/sound/pci/csareg.h 230602 2012-01-26 21:43:11Z pfg $
+ * $FreeBSD: head/sys/dev/sound/pci/csareg.h 230897 2012-02-01 21:38:01Z pfg $
*/
#ifndef _CSA_REG_H
@@ -1949,4 +1949,25 @@
#define CS_AC97_POWER_CONTROL_MIXVON_ON 0x0004
#define CS_AC97_POWER_CONTROL_MIXVOFF_ON 0x0008
+/*
+ * this is 3*1024 for parameter, 3.5*1024 for sample and 2*3.5*1024
+ * for code since each instruction is 40 bits and takes two dwords
+ */
+
+/* The following struct holds the initialization array. */
+#define INKY_BA1_DWORD_SIZE (13*1024+512)
+/* this is parameter, sample, and code */
+#define INKY_MEMORY_COUNT 3
+
+struct cs461x_firmware_struct
+{
+ struct
+ {
+ u_int32_t ulDestAddr, ulSourceSize;
+ } MemoryStat[INKY_MEMORY_COUNT];
+
+ u_int32_t BA1Array[INKY_BA1_DWORD_SIZE];
+};
+
+
#endif /* _CSA_REG_H */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sound/pci/hda/hdacc.c
--- a/head/sys/dev/sound/pci/hda/hdacc.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/sound/pci/hda/hdacc.c Fri Mar 02 17:36:33 2012 +0200
@@ -41,7 +41,7 @@
#include <dev/sound/pci/hda/hda_reg.h>
#include <dev/sound/pci/hda/hdac.h>
-SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hda/hdacc.c 230574 2012-01-26 10:30:50Z mav $");
+SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hda/hdacc.c 231024 2012-02-05 16:41:06Z mav $");
struct hdacc_fg {
device_t dev;
@@ -612,7 +612,7 @@
struct hdacc_softc *codec = device_get_softc(dev);
device_t child;
- if ((child = codec->streams[dir][stream]) != NULL);
+ if ((child = codec->streams[dir][stream]) != NULL)
HDAC_STREAM_INTR(child, dir, stream);
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sound/pci/hdspe-pcm.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/sound/pci/hdspe-pcm.c Fri Mar 02 17:36:33 2012 +0200
@@ -0,0 +1,709 @@
+/*-
+ * Copyright (c) 2012 Ruslan Bukin <br at bsdpad.com>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * RME HDSPe driver for FreeBSD (pcm-part).
+ * Supported cards: AIO, RayDAT.
+ */
+
+#include <dev/sound/pcm/sound.h>
+#include <dev/sound/pci/hdspe.h>
+#include <dev/sound/chip.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <mixer_if.h>
+
+SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hdspe-pcm.c 232337 2012-03-01 13:10:18Z mav $");
+
+struct hdspe_latency {
+ uint32_t n;
+ uint32_t period;
+ float ms;
+};
+
+static struct hdspe_latency latency_map[] = {
+ { 7, 32, 0.7 },
+ { 0, 64, 1.5 },
+ { 1, 128, 3 },
+ { 2, 256, 6 },
+ { 3, 512, 12 },
+ { 4, 1024, 23 },
+ { 5, 2048, 46 },
+ { 6, 4096, 93 },
+
+ { 0, 0, 0 },
+};
+
+struct hdspe_rate {
+ uint32_t speed;
+ uint32_t reg;
+};
+
+static struct hdspe_rate rate_map[] = {
+ { 32000, (HDSPE_FREQ_32000) },
+ { 44100, (HDSPE_FREQ_44100) },
+ { 48000, (HDSPE_FREQ_48000) },
+ { 64000, (HDSPE_FREQ_32000 | HDSPE_FREQ_DOUBLE) },
+ { 88200, (HDSPE_FREQ_44100 | HDSPE_FREQ_DOUBLE) },
+ { 96000, (HDSPE_FREQ_48000 | HDSPE_FREQ_DOUBLE) },
+ { 128000, (HDSPE_FREQ_32000 | HDSPE_FREQ_QUAD) },
+ { 176400, (HDSPE_FREQ_44100 | HDSPE_FREQ_QUAD) },
+ { 192000, (HDSPE_FREQ_48000 | HDSPE_FREQ_QUAD) },
+
+ { 0, 0 },
+};
+
+
+static int
+hdspe_hw_mixer(struct sc_chinfo *ch, unsigned int dst,
+ unsigned int src, unsigned short data)
+{
+ struct sc_pcminfo *scp = ch->parent;
+ struct sc_info *sc = scp->sc;
+ int offs = 0;
+
+ if (ch->dir == PCMDIR_PLAY)
+ offs = 64;
+
+ hdspe_write_4(sc, HDSPE_MIXER_BASE +
+ ((offs + src + 128 * dst) * sizeof(uint32_t)),
+ data & 0xFFFF);
+
+ return 0;
+};
+
+static int
+hdspechan_setgain(struct sc_chinfo *ch)
+{
+
+ hdspe_hw_mixer(ch, ch->lslot, ch->lslot,
+ ch->lvol * HDSPE_MAX_GAIN / 100);
+ hdspe_hw_mixer(ch, ch->rslot, ch->rslot,
+ ch->rvol * HDSPE_MAX_GAIN / 100);
+
+ return 0;
+}
+
+static int
+hdspemixer_init(struct snd_mixer *m)
+{
+ struct sc_pcminfo *scp = mix_getdevinfo(m);
+ struct sc_info *sc = scp->sc;
+ int mask;
+
+ if (sc == NULL)
+ return -1;
+
+ mask = SOUND_MASK_PCM;
+
+ if (scp->hc->play)
+ mask |= SOUND_MASK_VOLUME;
+
+ if (scp->hc->rec)
+ mask |= SOUND_MASK_RECLEV;
+
+ snd_mtxlock(sc->lock);
+ pcm_setflags(scp->dev, pcm_getflags(scp->dev) | SD_F_SOFTPCMVOL);
+ mix_setdevs(m, mask);
+ snd_mtxunlock(sc->lock);
+
+ return 0;
+}
+
+static int
+hdspemixer_set(struct snd_mixer *m, unsigned dev,
+ unsigned left, unsigned right)
+{
+ struct sc_pcminfo *scp = mix_getdevinfo(m);
+ struct sc_chinfo *ch;
+ int i;
+
+#if 0
+ device_printf(scp->dev, "hdspemixer_set() %d %d\n",
+ left,right);
+#endif
+
+ for (i = 0; i < scp->chnum; i++) {
+ ch = &scp->chan[i];
+ if ((dev == SOUND_MIXER_VOLUME && ch->dir == PCMDIR_PLAY) ||
+ (dev == SOUND_MIXER_RECLEV && ch->dir == PCMDIR_REC)) {
+ ch->lvol = left;
+ ch->rvol = right;
+ if (ch->run)
+ hdspechan_setgain(ch);
+ }
+ }
+
+ return 0;
+}
+
+static kobj_method_t hdspemixer_methods[] = {
+ KOBJMETHOD(mixer_init, hdspemixer_init),
+ KOBJMETHOD(mixer_set, hdspemixer_set),
+ KOBJMETHOD_END
+};
+MIXER_DECLARE(hdspemixer);
+
+static void
+hdspechan_enable(struct sc_chinfo *ch, int value)
+{
+ struct sc_pcminfo *scp = ch->parent;
+ struct sc_info *sc = scp->sc;
+ int reg;
+
+ if (ch->dir == PCMDIR_PLAY)
+ reg = HDSPE_OUT_ENABLE_BASE;
+ else
+ reg = HDSPE_IN_ENABLE_BASE;
+
+ ch->run = value;
+
+ hdspe_write_1(sc, reg + (4 * ch->lslot), value);
+ hdspe_write_1(sc, reg + (4 * ch->rslot), value);
+}
+
+static int
+hdspe_running(struct sc_info *sc)
+{
+ struct sc_pcminfo *scp;
+ struct sc_chinfo *ch;
+ int i, j, devcount, err;
+ device_t *devlist;
+
+ if ((err = device_get_children(sc->dev, &devlist, &devcount)) != 0)
+ goto bad;
+
+ for (i = 0; i < devcount; i++) {
+ scp = device_get_ivars(devlist[i]);
+ for (j = 0; j < scp->chnum; j++) {
+ ch = &scp->chan[j];
+ if (ch->run)
+ goto bad;
+ }
+ }
+
+ return 0;
+bad:
+
+#if 0
+ device_printf(sc->dev,"hdspe is running\n");
+#endif
+
+ return 1;
+}
+
+static void
+hdspe_start_audio(struct sc_info *sc)
+{
+
+ sc->ctrl_register |= (HDSPE_AUDIO_INT_ENABLE | HDSPE_ENABLE);
+ hdspe_write_4(sc, HDSPE_CONTROL_REG, sc->ctrl_register);
+}
+
+static void
+hdspe_stop_audio(struct sc_info *sc)
+{
+
+ if (hdspe_running(sc) == 1)
+ return;
+
+ sc->ctrl_register &= ~(HDSPE_AUDIO_INT_ENABLE | HDSPE_ENABLE);
+ hdspe_write_4(sc, HDSPE_CONTROL_REG, sc->ctrl_register);
+}
+
+/* Multiplex / demultiplex: 2.0 <-> 2 x 1.0. */
+static void
+buffer_copy(struct sc_chinfo *ch)
+{
+ struct sc_pcminfo *scp = ch->parent;
+ struct sc_info *sc = scp->sc;
+ int length,src,dst;
+ int ssize, dsize;
+ int i;
+
+ length = sndbuf_getready(ch->buffer) /
+ (4 /* Bytes per sample. */ * 2 /* channels */);
+
+ if (ch->dir == PCMDIR_PLAY) {
+ src = sndbuf_getreadyptr(ch->buffer);
+ } else {
+ src = sndbuf_getfreeptr(ch->buffer);
+ }
+
+ src /= 4; /* Bytes per sample. */
+ dst = src / 2; /* Destination buffer twice smaller. */
+
+ ssize = ch->size / 4;
+ dsize = ch->size / 8;
+
+ /*
+ * Use two fragment buffer to avoid sound clipping.
+ */
+
+ for (i = 0; i < sc->period * 2 /* fragments */; i++) {
+ if (ch->dir == PCMDIR_PLAY) {
+ sc->pbuf[dst + HDSPE_CHANBUF_SAMPLES * ch->lslot] =
+ ch->data[src];
+ sc->pbuf[dst + HDSPE_CHANBUF_SAMPLES * ch->rslot] =
+ ch->data[src + 1];
+
+ } else {
+ ch->data[src] =
+ sc->rbuf[dst + HDSPE_CHANBUF_SAMPLES * ch->lslot];
+ ch->data[src+1] =
+ sc->rbuf[dst + HDSPE_CHANBUF_SAMPLES * ch->rslot];
+ }
+
+ dst+=1;
+ dst %= dsize;
+ src+=2;
+ src %= ssize;
+ }
+}
+
+static int
+clean(struct sc_chinfo *ch){
+ struct sc_pcminfo *scp = ch->parent;
+ struct sc_info *sc = scp->sc;
+ uint32_t *buf = sc->rbuf;
+
+ if (ch->dir == PCMDIR_PLAY) {
+ buf = sc->pbuf;
+ }
+
+ bzero(buf + HDSPE_CHANBUF_SAMPLES * ch->lslot, HDSPE_CHANBUF_SIZE);
+ bzero(buf + HDSPE_CHANBUF_SAMPLES * ch->rslot, HDSPE_CHANBUF_SIZE);
+
+ return 0;
+}
+
+
+/* Channel interface. */
+static void *
+hdspechan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
+ struct pcm_channel *c, int dir)
+{
+ struct sc_pcminfo *scp = devinfo;
+ struct sc_info *sc = scp->sc;
+ struct sc_chinfo *ch;
+ int num;
+
+ snd_mtxlock(sc->lock);
+ num = scp->chnum;
+
+ ch = &scp->chan[num];
+ ch->lslot = scp->hc->left;
+ ch->rslot = scp->hc->right;
+ ch->run = 0;
+ ch->lvol = 0;
+ ch->rvol = 0;
+
+ ch->size = HDSPE_CHANBUF_SIZE * 2 /* slots */;
+ ch->data = malloc(ch->size, M_HDSPE, M_NOWAIT);
+
+ ch->buffer = b;
+ ch->channel = c;
+ ch->parent = scp;
+
+ ch->dir = dir;
+
+ snd_mtxunlock(sc->lock);
+
+ if (sndbuf_setup(ch->buffer, ch->data, ch->size) != 0) {
+ device_printf(scp->dev, "Can't setup sndbuf.\n");
+ return NULL;
+ }
+
+ return ch;
+}
+
+static int
+hdspechan_trigger(kobj_t obj, void *data, int go)
+{
+ struct sc_chinfo *ch = data;
+ struct sc_pcminfo *scp = ch->parent;
+ struct sc_info *sc = scp->sc;
+
+ snd_mtxlock(sc->lock);
+ switch (go) {
+ case PCMTRIG_START:
+#if 0
+ device_printf(scp->dev, "hdspechan_trigger(): start\n");
+#endif
+ hdspechan_enable(ch, 1);
+ hdspechan_setgain(ch);
+ hdspe_start_audio(sc);
+ break;
+
+ case PCMTRIG_STOP:
+ case PCMTRIG_ABORT:
+#if 0
+ device_printf(scp->dev, "hdspechan_trigger(): stop or abort\n");
+#endif
+ clean(ch);
+ hdspechan_enable(ch, 0);
+ hdspe_stop_audio(sc);
+ break;
+
+ case PCMTRIG_EMLDMAWR:
+ case PCMTRIG_EMLDMARD:
+ if(ch->run)
+ buffer_copy(ch);
+ break;
+ }
+
+ snd_mtxunlock(sc->lock);
+
+ return 0;
+}
+
+static uint32_t
+hdspechan_getptr(kobj_t obj, void *data)
+{
+ struct sc_chinfo *ch = data;
+ struct sc_pcminfo *scp = ch->parent;
+ struct sc_info *sc = scp->sc;
+ uint32_t ret, pos;
+
+ snd_mtxlock(sc->lock);
+ ret = hdspe_read_2(sc, HDSPE_STATUS_REG);
+ snd_mtxunlock(sc->lock);
+
+ pos = ret & HDSPE_BUF_POSITION_MASK;
+ pos *= 2; /* Hardbuf twice bigger. */
+
+ return pos;
+}
+
+static int
+hdspechan_free(kobj_t obj, void *data)
+{
+ struct sc_chinfo *ch = data;
+ struct sc_pcminfo *scp = ch->parent;
+ struct sc_info *sc = scp->sc;
+
+#if 0
+ device_printf(scp->dev, "hdspechan_free()\n");
+#endif
+ snd_mtxlock(sc->lock);
+ if (ch->data != NULL) {
+ free(ch->data, M_HDSPE);
+ ch->data = NULL;
+ }
+ snd_mtxunlock(sc->lock);
+
+ return 0;
+}
+
+static int
+hdspechan_setformat(kobj_t obj, void *data, uint32_t format)
+{
+ struct sc_chinfo *ch = data;
+
+#if 0
+ struct sc_pcminfo *scp = ch->parent;
+ device_printf(scp->dev, "hdspechan_setformat(%d)\n", format);
+#endif
+
+ ch->format = format;
+
+ return 0;
+}
+
+static uint32_t
+hdspechan_setspeed(kobj_t obj, void *data, uint32_t speed)
+{
+ struct sc_chinfo *ch = data;
+ struct sc_pcminfo *scp = ch->parent;
+ struct sc_info *sc = scp->sc;
+ struct hdspe_rate *hr = NULL;
+ long long period;
+ int threshold;
+ int i;
+
+#if 0
+ device_printf(scp->dev, "hdspechan_setspeed(%d)\n", speed);
+#endif
+
+ if (hdspe_running(sc) == 1)
+ goto end;
+
+ /* First look for equal frequency. */
+ for (i = 0; rate_map[i].speed != 0; i++) {
+ if (rate_map[i].speed == speed)
+ hr = &rate_map[i];
+ }
+
+ /* If no match, just find nearest. */
+ if (hr == NULL) {
+ for (i = 0; rate_map[i].speed != 0; i++) {
+ hr = &rate_map[i];
+ threshold = hr->speed + ((rate_map[i + 1].speed != 0) ?
+ ((rate_map[i + 1].speed - hr->speed) >> 1) : 0);
+ if (speed < threshold)
+ break;
+ }
+ }
+
+ switch (sc->type) {
+ case RAYDAT:
+ case AIO:
+ period = HDSPE_FREQ_AIO;
+ break;
+ default:
+ /* Unsupported card. */
+ goto end;
+ }
+
+ /* Write frequency on the device. */
+ sc->ctrl_register &= ~HDSPE_FREQ_MASK;
+ sc->ctrl_register |= hr->reg;
+ hdspe_write_4(sc, HDSPE_CONTROL_REG, sc->ctrl_register);
+
+ speed = hr->speed;
+ if (speed > 96000)
+ speed /= 4;
+ else if (speed > 48000)
+ speed /= 2;
+
+ /* Set DDS value. */
+ period /= speed;
+ hdspe_write_4(sc, HDSPE_FREQ_REG, period);
+
+ sc->speed = hr->speed;
+end:
+ return sc->speed;
+}
+
+static uint32_t
+hdspechan_setblocksize(kobj_t obj, void *data, uint32_t blocksize)
+{
+ struct sc_chinfo *ch = data;
+ struct sc_pcminfo *scp = ch->parent;
+ struct sc_info *sc = scp->sc;
+ struct hdspe_latency *hl = NULL;
+ int threshold;
+ int i;
+
+#if 0
+ device_printf(scp->dev, "hdspechan_setblocksize(%d)\n", blocksize);
+#endif
+
+ if (hdspe_running(sc) == 1)
+ goto end;
+
+ if (blocksize > HDSPE_LAT_BYTES_MAX)
+ blocksize = HDSPE_LAT_BYTES_MAX;
+ else if (blocksize < HDSPE_LAT_BYTES_MIN)
+ blocksize = HDSPE_LAT_BYTES_MIN;
+
+ blocksize /= 4 /* samples */;
+
+ /* First look for equal latency. */
+ for (i = 0; latency_map[i].period != 0; i++) {
+ if (latency_map[i].period == blocksize) {
+ hl = &latency_map[i];
+ }
+ }
+
+ /* If no match, just find nearest. */
+ if (hl == NULL) {
+ for (i = 0; latency_map[i].period != 0; i++) {
+ hl = &latency_map[i];
+ threshold = hl->period + ((latency_map[i + 1].period != 0) ?
+ ((latency_map[i + 1].period - hl->period) >> 1) : 0);
+ if (blocksize < threshold)
+ break;
+ }
+ }
+
+ snd_mtxlock(sc->lock);
+ sc->ctrl_register &= ~HDSPE_LAT_MASK;
+ sc->ctrl_register |= hdspe_encode_latency(hl->n);
+ hdspe_write_4(sc, HDSPE_CONTROL_REG, sc->ctrl_register);
+ sc->period = hl->period;
+ snd_mtxunlock(sc->lock);
+
+#if 0
+ device_printf(scp->dev, "New period=%d\n", sc->period);
+#endif
+
+ sndbuf_resize(ch->buffer, (HDSPE_CHANBUF_SIZE * 2) / (sc->period * 4),
+ (sc->period * 4));
+end:
+ return sndbuf_getblksz(ch->buffer);
+}
+
+static uint32_t hdspe_rfmt[] = {
+ SND_FORMAT(AFMT_S32_LE, 2, 0),
+ 0
+};
+
+static struct pcmchan_caps hdspe_rcaps = {32000, 192000, hdspe_rfmt, 0};
+
+static uint32_t hdspe_pfmt[] = {
+ SND_FORMAT(AFMT_S32_LE, 2, 0),
+ 0
+};
+
+static struct pcmchan_caps hdspe_pcaps = {32000, 192000, hdspe_pfmt, 0};
+
+static struct pcmchan_caps *
+hdspechan_getcaps(kobj_t obj, void *data)
+{
+ struct sc_chinfo *ch = data;
+
+#if 0
+ struct sc_pcminfo *scl = ch->parent;
+ device_printf(scp->dev, "hdspechan_getcaps()\n");
+#endif
+
+ return (ch->dir == PCMDIR_PLAY) ?
+ &hdspe_pcaps : &hdspe_rcaps;
+}
+
+static kobj_method_t hdspechan_methods[] = {
+ KOBJMETHOD(channel_init, hdspechan_init),
+ KOBJMETHOD(channel_free, hdspechan_free),
+ KOBJMETHOD(channel_setformat, hdspechan_setformat),
+ KOBJMETHOD(channel_setspeed, hdspechan_setspeed),
+ KOBJMETHOD(channel_setblocksize, hdspechan_setblocksize),
+ KOBJMETHOD(channel_trigger, hdspechan_trigger),
+ KOBJMETHOD(channel_getptr, hdspechan_getptr),
+ KOBJMETHOD(channel_getcaps, hdspechan_getcaps),
+ KOBJMETHOD_END
+};
+CHANNEL_DECLARE(hdspechan);
+
+
+static int
+hdspe_pcm_probe(device_t dev)
+{
+
+#if 0
+ device_printf(dev,"hdspe_pcm_probe()\n");
+#endif
+
+ return 0;
+}
+
+static uint32_t
+hdspe_pcm_intr(struct sc_pcminfo *scp) {
+ struct sc_chinfo *ch;
+ struct sc_info *sc = scp->sc;
+ int i;
+
+ for (i = 0; i < scp->chnum; i++) {
+ ch = &scp->chan[i];
+ snd_mtxunlock(sc->lock);
+ chn_intr(ch->channel);
+ snd_mtxlock(sc->lock);
+ }
+
+ return 0;
+}
+
+static int
+hdspe_pcm_attach(device_t dev)
+{
+ struct sc_pcminfo *scp;
+ char status[SND_STATUSLEN];
+ char desc[64];
+ int i, err;
+
+ scp = device_get_ivars(dev);
+ scp->ih = &hdspe_pcm_intr;
+
+ bzero(desc, sizeof(desc));
+ snprintf(desc, sizeof(desc), "HDSPe AIO [%s]", scp->hc->descr);
+ device_set_desc_copy(dev, desc);
+
+ /*
+ * We don't register interrupt handler with snd_setup_intr
+ * in pcm device. Mark pcm device as MPSAFE manually.
+ */
+ pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
+
+ err = pcm_register(dev, scp, scp->hc->play, scp->hc->rec);
+ if (err) {
+ device_printf(dev, "Can't register pcm.\n");
+ return ENXIO;
+ }
+
+ scp->chnum = 0;
+ for (i = 0; i < scp->hc->play; i++) {
+ pcm_addchan(dev, PCMDIR_PLAY, &hdspechan_class, scp);
+ scp->chnum++;
+ }
+
+ for (i = 0; i < scp->hc->rec; i++) {
+ pcm_addchan(dev, PCMDIR_REC, &hdspechan_class, scp);
+ scp->chnum++;
+ }
+
+ snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld %s",
+ rman_get_start(scp->sc->cs),
+ rman_get_start(scp->sc->irq),
+ PCM_KLDSTRING(snd_hdspe));
+ pcm_setstatus(dev, status);
+
+ mixer_init(dev, &hdspemixer_class, scp);
+
+ return 0;
+}
+
+static int
+hdspe_pcm_detach(device_t dev)
+{
+ int err;
+
+ err = pcm_unregister(dev);
+ if (err) {
+ device_printf(dev, "Can't unregister device.\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static device_method_t hdspe_pcm_methods[] = {
+ DEVMETHOD(device_probe, hdspe_pcm_probe),
+ DEVMETHOD(device_attach, hdspe_pcm_attach),
+ DEVMETHOD(device_detach, hdspe_pcm_detach),
+ { 0, 0 }
+};
+
+static driver_t hdspe_pcm_driver = {
+ "pcm",
+ hdspe_pcm_methods,
+ PCM_SOFTC_SIZE,
+};
+
+DRIVER_MODULE(snd_hdspe_pcm, hdspe, hdspe_pcm_driver, pcm_devclass, 0, 0);
+MODULE_DEPEND(snd_hdspe, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
+MODULE_VERSION(snd_hdspe, 1);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sound/pci/hdspe.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/sound/pci/hdspe.c Fri Mar 02 17:36:33 2012 +0200
@@ -0,0 +1,410 @@
+/*-
+ * Copyright (c) 2012 Ruslan Bukin <br at bsdpad.com>
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+ * RME HDSPe driver for FreeBSD.
+ * Supported cards: AIO, RayDAT.
+ */
+
+#include <dev/sound/pcm/sound.h>
+#include <dev/sound/pci/hdspe.h>
+#include <dev/sound/chip.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <mixer_if.h>
+
+SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hdspe.c 232337 2012-03-01 13:10:18Z mav $");
+
+static struct hdspe_channel chan_map_aio[] = {
+ { 0, 1, "line", 1, 1 },
+ { 6, 7, "phone", 1, 0 },
+ { 8, 9, "aes", 1, 1 },
+ { 10, 11, "s/pdif", 1, 1 },
+ { 12, 16, "adat", 1, 1 },
+
+ /* Single or double speed. */
+ { 14, 18, "adat", 1, 1 },
+
+ /* Single speed only. */
+ { 13, 15, "adat", 1, 1 },
+ { 17, 19, "adat", 1, 1 },
+
+ { 0, 0, NULL, 0, 0 },
+};
+
+static struct hdspe_channel chan_map_rd[] = {
+ { 0, 1, "aes", 1, 1 },
+ { 2, 3, "s/pdif", 1, 1 },
+ { 4, 5, "adat", 1, 1 },
+ { 6, 7, "adat", 1, 1 },
+ { 8, 9, "adat", 1, 1 },
+ { 10, 11, "adat", 1, 1 },
+
+ /* Single or double speed. */
+ { 12, 13, "adat", 1, 1 },
+ { 14, 15, "adat", 1, 1 },
+ { 16, 17, "adat", 1, 1 },
+ { 18, 19, "adat", 1, 1 },
+
+ /* Single speed only. */
+ { 20, 21, "adat", 1, 1 },
+ { 22, 23, "adat", 1, 1 },
+ { 24, 25, "adat", 1, 1 },
+ { 26, 27, "adat", 1, 1 },
+ { 28, 29, "adat", 1, 1 },
+ { 30, 31, "adat", 1, 1 },
+ { 32, 33, "adat", 1, 1 },
+ { 34, 35, "adat", 1, 1 },
+
+ { 0, 0, NULL, 0, 0 },
+};
+
+static void
+hdspe_intr(void *p)
+{
+ struct sc_info *sc = (struct sc_info *)p;
+ struct sc_pcminfo *scp;
+ device_t *devlist;
+ int devcount, status;
+ int i, err;
+
+ snd_mtxlock(sc->lock);
+
+ status = hdspe_read_1(sc, HDSPE_STATUS_REG);
+ if (status & HDSPE_AUDIO_IRQ_PENDING) {
+ if ((err = device_get_children(sc->dev, &devlist, &devcount)) != 0)
+ return;
+
+ for (i = 0; i < devcount; i++) {
+ scp = device_get_ivars(devlist[i]);
+ if (scp->ih != NULL)
+ scp->ih(scp);
+ }
+
+ hdspe_write_1(sc, HDSPE_INTERRUPT_ACK, 0);
+ }
+
+ snd_mtxunlock(sc->lock);
+}
+
+static void
+hdspe_dmapsetmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+#if 0
+ struct sc_info *sc = (struct sc_info *)arg;
+ device_printf(sc->dev, "hdspe_dmapsetmap()\n");
+#endif
+}
+
+static int
+hdspe_alloc_resources(struct sc_info *sc)
+{
+
+ /* Allocate resource. */
+ sc->csid = PCIR_BAR(0);
+ sc->cs = bus_alloc_resource(sc->dev, SYS_RES_MEMORY,
+ &sc->csid, 0, ~0, 1, RF_ACTIVE);
+
+ if (!sc->cs) {
+ device_printf(sc->dev, "Unable to map SYS_RES_MEMORY.\n");
+ return (ENXIO);
+ }
+ sc->cst = rman_get_bustag(sc->cs);
+ sc->csh = rman_get_bushandle(sc->cs);
+
+
+ /* Allocate interrupt resource. */
+ sc->irqid = 0;
+ sc->irq = bus_alloc_resource(sc->dev, SYS_RES_IRQ, &sc->irqid,
+ 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
+
+ if (!sc->irq ||
+ bus_setup_intr(sc->dev, sc->irq, INTR_MPSAFE | INTR_TYPE_AV,
+ NULL, hdspe_intr, sc, &sc->ih)) {
+ device_printf(sc->dev, "Unable to alloc interrupt resource.\n");
+ return (ENXIO);
+ }
+
+ /* Allocate DMA resources. */
+ if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(sc->dev),
+ /*alignment*/4,
+ /*boundary*/0,
+ /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+ /*highaddr*/BUS_SPACE_MAXADDR,
+ /*filter*/NULL,
+ /*filterarg*/NULL,
+ /*maxsize*/2 * HDSPE_DMASEGSIZE,
+ /*nsegments*/2,
+ /*maxsegsz*/HDSPE_DMASEGSIZE,
+ /*flags*/0,
+ /*lockfunc*/busdma_lock_mutex,
+ /*lockarg*/&Giant,
+ /*dmatag*/&sc->dmat) != 0) {
+ device_printf(sc->dev, "Unable to create dma tag.\n");
+ return (ENXIO);
+ }
+
+ sc->bufsize = HDSPE_DMASEGSIZE;
+
+ /* pbuf (play buffer). */
+ if (bus_dmamem_alloc(sc->dmat, (void **)&sc->pbuf,
+ BUS_DMA_NOWAIT, &sc->pmap)) {
+ device_printf(sc->dev, "Can't alloc pbuf.\n");
+ return (ENXIO);
+ }
+
+ if (bus_dmamap_load(sc->dmat, sc->pmap, sc->pbuf, sc->bufsize,
+ hdspe_dmapsetmap, sc, 0)) {
+ device_printf(sc->dev, "Can't load pbuf.\n");
+ return (ENXIO);
+ }
+
+ /* rbuf (rec buffer). */
+ if (bus_dmamem_alloc(sc->dmat, (void **)&sc->rbuf,
+ BUS_DMA_NOWAIT, &sc->rmap)) {
+ device_printf(sc->dev, "Can't alloc rbuf.\n");
+ return (ENXIO);
+ }
+
+ if (bus_dmamap_load(sc->dmat, sc->rmap, sc->rbuf, sc->bufsize,
+ hdspe_dmapsetmap, sc, 0)) {
+ device_printf(sc->dev, "Can't load rbuf.\n");
+ return (ENXIO);
+ }
+
+ bzero(sc->pbuf, sc->bufsize);
+ bzero(sc->rbuf, sc->bufsize);
+
+ return (0);
+}
+
+static void
+hdspe_map_dmabuf(struct sc_info *sc)
+{
+ uint32_t paddr,raddr;
+ int i;
+
+ paddr = vtophys(sc->pbuf);
+ raddr = vtophys(sc->rbuf);
+
+ for (i = 0; i < HDSPE_MAX_SLOTS * 16; i++) {
+ hdspe_write_4(sc, HDSPE_PAGE_ADDR_BUF_OUT + 4 * i,
+ paddr + i * 4096);
+ hdspe_write_4(sc, HDSPE_PAGE_ADDR_BUF_IN + 4 * i,
+ raddr + i * 4096);
+ }
+}
+
+static int
+hdspe_probe(device_t dev)
+{
+ uint32_t rev;
+
+ if (pci_get_vendor(dev) == PCI_VENDOR_XILINX &&
+ pci_get_device(dev) == PCI_DEVICE_XILINX_HDSPE) {
+ rev = pci_get_revid(dev);
+ switch (rev) {
+ case PCI_REVISION_AIO:
+ device_set_desc(dev, "RME HDSPe AIO");
+ return 0;
+ case PCI_REVISION_RAYDAT:
+ device_set_desc(dev, "RME HDSPe RayDAT");
+ return 0;
+ }
+ }
+
+ return (ENXIO);
+}
+
+static int
+set_pci_config(device_t dev)
+{
+ uint32_t data;
+
+ pci_enable_busmaster(dev);
+
+ data = pci_get_revid(dev);
+ data |= PCIM_CMD_PORTEN;
+ pci_write_config(dev, PCIR_COMMAND, data, 2);
+
+ return 0;
+}
+
+static int
+hdspe_init(struct sc_info *sc)
+{
+ long long period;
+
+ /* Set defaults. */
+ sc->ctrl_register |= HDSPM_CLOCK_MODE_MASTER;
+
+ /* Set latency. */
+ sc->period = 32;
+ sc->ctrl_register = hdspe_encode_latency(7);
+
+ /* Set rate. */
+ sc->speed = HDSPE_SPEED_DEFAULT;
+ sc->ctrl_register &= ~HDSPE_FREQ_MASK;
+ sc->ctrl_register |= HDSPE_FREQ_MASK_DEFAULT;
+ hdspe_write_4(sc, HDSPE_CONTROL_REG, sc->ctrl_register);
+
+ switch (sc->type) {
+ case RAYDAT:
+ case AIO:
+ period = HDSPE_FREQ_AIO;
+ break;
+ default:
+ return (ENXIO);
+ }
+
+ /* Set DDS value. */
+ period /= sc->speed;
+ hdspe_write_4(sc, HDSPE_FREQ_REG, period);
+
+ /* Other settings. */
+ sc->settings_register = 0;
+ hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register);
+
+ return 0;
+}
+
+static int
+hdspe_attach(device_t dev)
+{
+ struct sc_info *sc;
+ struct sc_pcminfo *scp;
+ struct hdspe_channel *chan_map;
+ uint32_t rev;
+ int i, err;
+
+#if 0
+ device_printf(dev, "hdspe_attach()\n");
+#endif
+
+ set_pci_config(dev);
+
+ sc = device_get_softc(dev);
+ sc->lock = snd_mtxcreate(device_get_nameunit(dev),
+ "snd_hdspe softc");
+ sc->dev = dev;
+
+ rev = pci_get_revid(dev);
+ switch (rev) {
+ case PCI_REVISION_AIO:
+ sc->type = AIO;
+ chan_map = chan_map_aio;
+ break;
+ case PCI_REVISION_RAYDAT:
+ sc->type = RAYDAT;
+ chan_map = chan_map_rd;
+ break;
+ default:
+ return ENXIO;
+ }
+
+ /* Allocate resources. */
+ err = hdspe_alloc_resources(sc);
+ if (err) {
+ device_printf(dev, "Unable to allocate system resources.\n");
+ return ENXIO;
+ }
+
+ if (hdspe_init(sc) != 0)
+ return ENXIO;
+
+ for (i = 0; i < HDSPE_MAX_CHANS && chan_map[i].descr != NULL; i++) {
+ scp = malloc(sizeof(struct sc_pcminfo), M_DEVBUF, M_NOWAIT | M_ZERO);
+ scp->hc = &chan_map[i];
+ scp->sc = sc;
+ scp->dev = device_add_child(dev, "pcm", -1);
+ device_set_ivars(scp->dev, scp);
+ }
+
+ hdspe_map_dmabuf(sc);
+
+ return 0;
+}
+
+static void
+hdspe_dmafree(struct sc_info *sc)
+{
+
+ bus_dmamap_unload(sc->dmat, sc->rmap);
+ bus_dmamap_unload(sc->dmat, sc->pmap);
+ bus_dmamem_free(sc->dmat, sc->rbuf, sc->rmap);
+ bus_dmamem_free(sc->dmat, sc->pbuf, sc->pmap);
+ sc->rmap = sc->pmap = NULL;
+ sc->rbuf = sc->pbuf = NULL;
+}
+
+static int
+hdspe_detach(device_t dev)
+{
+ struct sc_info *sc;
+ int err;
+
+ sc = device_get_softc(dev);
+ if (sc == NULL) {
+ device_printf(dev,"Can't detach: softc is null.\n");
+ return 0;
+ }
+
+ err = device_delete_children(dev);
+ if (err)
+ return (err);
+
+ hdspe_dmafree(sc);
+
+ if (sc->ih)
+ bus_teardown_intr(dev, sc->irq, sc->ih);
+ if (sc->dmat)
+ bus_dma_tag_destroy(sc->dmat);
+ if (sc->irq)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ if (sc->cs)
+ bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->cs);
+ if (sc->lock)
+ snd_mtxfree(sc->lock);
+
+ return 0;
+}
+
+static device_method_t hdspe_methods[] = {
+ DEVMETHOD(device_probe, hdspe_probe),
+ DEVMETHOD(device_attach, hdspe_attach),
+ DEVMETHOD(device_detach, hdspe_detach),
+ { 0, 0 }
+};
+
+static driver_t hdspe_driver = {
+ "hdspe",
+ hdspe_methods,
+ PCM_SOFTC_SIZE,
+};
+
+DRIVER_MODULE(snd_hdspe, pci, hdspe_driver, pcm_devclass, 0, 0);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sound/pci/hdspe.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/sound/pci/hdspe.h Fri Mar 02 17:36:33 2012 +0200
@@ -0,0 +1,179 @@
+/*-
+ * Copyright (c) 2012 Ruslan Bukin <br at bsdpad.com>
+ * 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 AUTHOR 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 AUTHOR 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: head/sys/dev/sound/pci/hdspe.h 232337 2012-03-01 13:10:18Z mav $
+ */
+
+#define PCI_VENDOR_XILINX 0x10ee
+#define PCI_DEVICE_XILINX_HDSPE 0x3fc6 /* AIO, MADI, AES, RayDAT */
+#define PCI_CLASS_REVISION 0x08
+#define PCI_REVISION_AIO 212
+#define PCI_REVISION_RAYDAT 211
+
+#define AIO 0
+#define RAYDAT 1
+
+/* Hardware mixer */
+#define HDSPE_OUT_ENABLE_BASE 512
+#define HDSPE_IN_ENABLE_BASE 768
+#define HDSPE_MIXER_BASE 32768
+#define HDSPE_MAX_GAIN 32768
+
+/* Buffer */
+#define HDSPE_PAGE_ADDR_BUF_OUT 8192
+#define HDSPE_PAGE_ADDR_BUF_IN (HDSPE_PAGE_ADDR_BUF_OUT + 64 * 16 * 4)
+#define HDSPE_BUF_POSITION_MASK 0x000FFC0
+
+/* Frequency */
+#define HDSPE_FREQ_0 (1<<6)
+#define HDSPE_FREQ_1 (1<<7)
+#define HDSPE_FREQ_DOUBLE (1<<8)
+#define HDSPE_FREQ_QUAD (1<<31)
+
+#define HDSPE_FREQ_32000 HDSPE_FREQ_0
+#define HDSPE_FREQ_44100 HDSPE_FREQ_1
+#define HDSPE_FREQ_48000 (HDSPE_FREQ_0 | HDSPE_FREQ_1)
+#define HDSPE_FREQ_MASK (HDSPE_FREQ_0 | HDSPE_FREQ_1 | \
+ HDSPE_FREQ_DOUBLE | HDSPE_FREQ_QUAD)
+#define HDSPE_FREQ_MASK_DEFAULT HDSPE_FREQ_48000
+#define HDSPE_FREQ_REG 256
+#define HDSPE_FREQ_AIO 104857600000000ULL
+
+#define HDSPE_SPEED_DEFAULT 48000
+
+/* Latency */
+#define HDSPE_LAT_0 (1<<1)
+#define HDSPE_LAT_1 (1<<2)
+#define HDSPE_LAT_2 (1<<3)
+#define HDSPE_LAT_MASK (HDSPE_LAT_0 | HDSPE_LAT_1 | HDSPE_LAT_2)
+#define HDSPE_LAT_BYTES_MAX (4096 * 4)
+#define HDSPE_LAT_BYTES_MIN (32 * 4)
+#define hdspe_encode_latency(x) (((x)<<1) & HDSPE_LAT_MASK)
+
+/* Settings */
+#define HDSPE_SETTINGS_REG 0
+#define HDSPE_CONTROL_REG 64
+#define HDSPE_STATUS_REG 0
+#define HDSPE_ENABLE (1<<0)
+#define HDSPM_CLOCK_MODE_MASTER (1<<4)
+
+/* Interrupts */
+#define HDSPE_AUDIO_IRQ_PENDING (1<<0)
+#define HDSPE_AUDIO_INT_ENABLE (1<<5)
+#define HDSPE_INTERRUPT_ACK 96
+
+/* Channels */
+#define HDSPE_MAX_SLOTS 64 /* Mono channels */
+#define HDSPE_MAX_CHANS (HDSPE_MAX_SLOTS / 2) /* Stereo pairs */
+
+#define HDSPE_CHANBUF_SAMPLES (16 * 1024)
+#define HDSPE_CHANBUF_SIZE (4 * HDSPE_CHANBUF_SAMPLES)
+#define HDSPE_DMASEGSIZE (HDSPE_CHANBUF_SIZE * HDSPE_MAX_SLOTS)
+
+struct hdspe_channel {
+ uint32_t left;
+ uint32_t right;
+ char *descr;
+ uint32_t play;
+ uint32_t rec;
+};
+
+static MALLOC_DEFINE(M_HDSPE, "hdspe", "hdspe audio");
+
+/* Channel registers */
+struct sc_chinfo {
+ struct snd_dbuf *buffer;
+ struct pcm_channel *channel;
+ struct sc_pcminfo *parent;
+
+ /* Channel information */
+ uint32_t dir;
+ uint32_t format;
+ uint32_t lslot;
+ uint32_t rslot;
+ uint32_t lvol;
+ uint32_t rvol;
+
+ /* Buffer */
+ uint32_t *data;
+ uint32_t size;
+
+ /* Flags */
+ uint32_t run;
+};
+
+/* PCM device private data */
+struct sc_pcminfo {
+ device_t dev;
+ uint32_t (*ih) (struct sc_pcminfo *scp);
+ uint32_t chnum;
+ struct sc_chinfo chan[HDSPE_MAX_CHANS];
+ struct sc_info *sc;
+ struct hdspe_channel *hc;
+};
+
+/* HDSPe device private data */
+struct sc_info {
+ device_t dev;
+ struct mtx *lock;
+
+ uint32_t ctrl_register;
+ uint32_t settings_register;
+ uint32_t type;
+
+ /* Control/Status register */
+ struct resource *cs;
+ int csid;
+ bus_space_tag_t cst;
+ bus_space_handle_t csh;
+
+ struct resource *irq;
+ int irqid;
+ void *ih;
+ bus_dma_tag_t dmat;
+
+ /* Play/Record DMA buffers */
+ uint32_t *pbuf;
+ uint32_t *rbuf;
+ uint32_t bufsize;
+ bus_dmamap_t pmap;
+ bus_dmamap_t rmap;
+ uint32_t period;
+ uint32_t speed;
+};
+
+#define hdspe_read_1(sc, regno) \
+ bus_space_read_1((sc)->cst, (sc)->csh, (regno))
+#define hdspe_read_2(sc, regno) \
+ bus_space_read_2((sc)->cst, (sc)->csh, (regno))
+#define hdspe_read_4(sc, regno) \
+ bus_space_read_4((sc)->cst, (sc)->csh, (regno))
+
+#define hdspe_write_1(sc, regno, data) \
+ bus_space_write_1((sc)->cst, (sc)->csh, (regno), (data))
+#define hdspe_write_2(sc, regno, data) \
+ bus_space_write_2((sc)->cst, (sc)->csh, (regno), (data))
+#define hdspe_write_4(sc, regno, data) \
+ bus_space_write_4((sc)->cst, (sc)->csh, (regno), (data))
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sound/pcm/mixer.c
--- a/head/sys/dev/sound/pcm/mixer.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/sound/pcm/mixer.c Fri Mar 02 17:36:33 2012 +0200
@@ -35,7 +35,7 @@
#include "feeder_if.h"
#include "mixer_if.h"
-SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/mixer.c 227293 2011-11-07 06:44:47Z ed $");
+SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/mixer.c 231378 2012-02-10 12:35:57Z ed $");
static MALLOC_DEFINE(M_MIXER, "mixer", "mixer");
@@ -1463,7 +1463,7 @@
*
* XXX Described by Hannu at 4Front, but not found in
* soundcard.h.
- strlcpy(mi->devnode, d->mixer_dev->si_name,
+ strlcpy(mi->devnode, devtoname(d->mixer_dev),
sizeof(mi->devnode));
mi->legacy_device = i;
*/
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sound/pcm/sound.c
--- a/head/sys/dev/sound/pcm/sound.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/sound/pcm/sound.c Fri Mar 02 17:36:33 2012 +0200
@@ -42,7 +42,7 @@
#include "feeder_if.h"
-SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/sound.c 222826 2011-06-07 17:01:52Z mav $");
+SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/sound.c 231647 2012-02-14 09:19:30Z mav $");
devclass_t pcm_devclass;
@@ -1415,7 +1415,6 @@
pcmsg_unrhdr = new_unrhdr(1, INT_MAX, NULL);
break;
case MOD_UNLOAD:
- case MOD_SHUTDOWN:
ret = sndstat_acquire(curthread);
if (ret != 0)
break;
@@ -1424,6 +1423,8 @@
pcmsg_unrhdr = NULL;
}
break;
+ case MOD_SHUTDOWN:
+ break;
default:
ret = ENOTSUP;
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/sound/usb/uaudio.c
--- a/head/sys/dev/sound/usb/uaudio.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/sound/usb/uaudio.c Fri Mar 02 17:36:33 2012 +0200
@@ -1,5 +1,5 @@
/* $NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $ */
-/* $FreeBSD: head/sys/dev/sound/usb/uaudio.c 228485 2011-12-14 01:03:07Z hselasky $ */
+/* $FreeBSD: head/sys/dev/sound/usb/uaudio.c 232039 2012-02-23 07:56:19Z hselasky $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/sound/usb/uaudio.c 228485 2011-12-14 01:03:07Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/sound/usb/uaudio.c 232039 2012-02-23 07:56:19Z hselasky $");
/*
* USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf
@@ -626,21 +626,21 @@
sc->sc_mixer_count);
if (sc->sc_play_chan.valid) {
- device_printf(dev, "Play: %d Hz, %d ch, %s format\n",
+ device_printf(dev, "Play: %d Hz, %d ch, %s format.\n",
sc->sc_play_chan.sample_rate,
sc->sc_play_chan.p_asf1d->bNrChannels,
sc->sc_play_chan.p_fmt->description);
} else {
- device_printf(dev, "No playback!\n");
+ device_printf(dev, "No playback.\n");
}
if (sc->sc_rec_chan.valid) {
- device_printf(dev, "Record: %d Hz, %d ch, %s format\n",
+ device_printf(dev, "Record: %d Hz, %d ch, %s format.\n",
sc->sc_rec_chan.sample_rate,
sc->sc_rec_chan.p_asf1d->bNrChannels,
sc->sc_rec_chan.p_fmt->description);
} else {
- device_printf(dev, "No recording!\n");
+ device_printf(dev, "No recording.\n");
}
if (sc->sc_midi_chan.valid) {
@@ -648,9 +648,9 @@
if (umidi_probe(dev)) {
goto detach;
}
- device_printf(dev, "MIDI sequencer\n");
+ device_printf(dev, "MIDI sequencer.\n");
} else {
- device_printf(dev, "No midi sequencer\n");
+ device_printf(dev, "No midi sequencer.\n");
}
DPRINTF("doing child attach\n");
@@ -659,13 +659,21 @@
sc->sc_sndcard_func.func = SCF_PCM;
- child = device_add_child(dev, "pcm", -1);
-
- if (child == NULL) {
- DPRINTF("out of memory\n");
- goto detach;
+ /*
+ * Only attach a PCM device if we have a playback, recording
+ * or mixer device present:
+ */
+ if (sc->sc_play_chan.valid ||
+ sc->sc_rec_chan.valid ||
+ sc->sc_mix_info) {
+ child = device_add_child(dev, "pcm", -1);
+
+ if (child == NULL) {
+ DPRINTF("out of memory\n");
+ goto detach;
+ }
+ device_set_ivars(child, &sc->sc_sndcard_func);
}
- device_set_ivars(child, &sc->sc_sndcard_func);
if (bus_generic_attach(dev)) {
DPRINTF("child attach failed\n");
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/uart/uart_bus_siba.c
--- a/head/sys/dev/uart/uart_bus_siba.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/uart/uart_bus_siba.c Fri Mar 02 17:36:33 2012 +0200
@@ -49,6 +49,8 @@
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
+#include <dev/siba/siba_cc.h>
+
#include "uart_if.h"
static int uart_siba_cc_probe(device_t dev);
@@ -72,14 +74,27 @@
static int
uart_siba_cc_probe(device_t dev)
{
+ device_t parent;
struct uart_softc *sc;
+ uintptr_t rclk;
+ parent = device_get_parent(dev);
sc = device_get_softc(dev);
- sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
sc->sc_class = &uart_ns8250_class;
- bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
+
+ if (device_get_unit(dev) == 0) {
+ sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
+ bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
+ }
- return (uart_bus_probe(dev, 0, sc->sc_bas.rclk, 0, 0));
+ if (BUS_READ_IVAR(parent, dev, SIBA_CC_IVAR_XTALFREQ, &rclk))
+ rclk = 0;
+
+ sc->sc_bas.bsh=
+ MIPS_PHYS_TO_KSEG1(0x18000000+
+ device_get_unit(dev)?SIBA_CC_UART1:SIBA_CC_UART0);
+
+ return (uart_bus_probe(dev, 0, rclk, 0, 0));
}
DRIVER_MODULE(uart, siba_cc, uart_siba_cc_driver, uart_devclass, 0, 0);
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/uart/uart_cpu_siba.c
--- a/head/sys/dev/uart/uart_cpu_siba.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/uart/uart_cpu_siba.c Fri Mar 02 17:36:33 2012 +0200
@@ -82,7 +82,7 @@
* covers the most MIPS cores where 2 UARTs had their resources
* predefined.
*/
- for (i = 0; i < 1; i++) {
+ for (i = 0; i < 2; i++) {
if (resource_int_value("uart", i, "flags", &ivar))
continue;
if (devtype == UART_DEV_CONSOLE && !UART_FLAGS_CONSOLE(ivar))
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/uart/uart_dev_siba.c
--- a/head/sys/dev/uart/uart_dev_siba.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/uart/uart_dev_siba.c Fri Mar 02 17:36:33 2012 +0200
@@ -42,7 +42,8 @@
#include "uart_if.h"
-#define DEFAULT_RCLK 3686400
+//#define DEFAULT_RCLK 3686400
+#define DEFAULT_RCLK 25804800 /* BCM5354 CC */
#include <sys/types.h>
@@ -172,14 +173,14 @@
siba_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
int parity)
{
- unsigned int baud_base = 16200000 / 16;
+ unsigned int baud_base = DEFAULT_RCLK;
if (bas->rclk == 0)
bas->rclk = baud_base;
/* Set baud and 8N1 */
- unsigned int quot = (baud_base + 57600) / 115200;
+ unsigned int quot = baud_base / 16 / 115200;
uart_setreg(bas, UART_LCR, UART_LCR_DLAB);
uart_setreg(bas, UART_DLL, quot & 0xff);
uart_setreg(bas, UART_DLM, quot >> 8);
@@ -371,5 +372,5 @@
1,
.uc_ops = &uart_siba_ops,
.uc_range = 8,
- .uc_rclk = 3686400
+ .uc_rclk = DEFAULT_RCLK
};
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/usb/net/if_mos.c
--- a/head/sys/dev/usb/net/if_mos.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/usb/net/if_mos.c Fri Mar 02 17:36:33 2012 +0200
@@ -79,10 +79,10 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/net/if_mos.c 227843 2011-11-22 21:28:20Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/net/if_mos.c 232257 2012-02-28 15:45:42Z kevlo $");
/*
- * Moschip MCS7730/MCS7830 USB to Ethernet controller
+ * Moschip MCS7730/MCS7830/MCS7832 USB to Ethernet controller
* The datasheet is available at the following URL:
* http://www.moschip.com/data/products/MCS7830/Data%20Sheet_7830.pdf
*/
@@ -149,6 +149,7 @@
static const STRUCT_USB_HOST_ID mos_devs[] = {
{USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7730, MCS7730)},
{USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7830, MCS7830)},
+ {USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7832, MCS7832)},
{USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN030, MCS7830)},
};
@@ -715,6 +716,8 @@
MOS_DPRINTFN("model: MCS7730");
} else if (sc->mos_flags & MCS7830) {
MOS_DPRINTFN("model: MCS7830");
+ } else if (sc->mos_flags & MCS7832) {
+ MOS_DPRINTFN("model: MCS7832");
}
error = uether_ifattach(ue);
if (error) {
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/usb/net/if_mosreg.h
--- a/head/sys/dev/usb/net/if_mosreg.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/usb/net/if_mosreg.h Fri Mar 02 17:36:33 2012 +0200
@@ -1,4 +1,4 @@
-/* $FreeBSD$ */
+/* $FreeBSD: head/sys/dev/usb/net/if_mosreg.h 232257 2012-02-28 15:45:42Z kevlo $ */
/*-
* Copyright (c) 2010, 2011 Rick van der Zwet <info at rickvanderzwet.nl>
*
@@ -152,6 +152,7 @@
#define MCS7730 0x0001
#define MCS7830 0x0002
+#define MCS7832 0x0004
#define MOS_INC(x, y) (x) = (x + 1) % y
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/usb/serial/u3g.c
--- a/head/sys/dev/usb/serial/u3g.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/usb/serial/u3g.c Fri Mar 02 17:36:33 2012 +0200
@@ -16,7 +16,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $FreeBSD: head/sys/dev/usb/serial/u3g.c 230238 2012-01-16 22:26:25Z hselasky $
+ * $FreeBSD: head/sys/dev/usb/serial/u3g.c 231713 2012-02-14 21:36:55Z hselasky $
*/
/*
@@ -447,6 +447,7 @@
U3G_DEV(QUANTA, Q111, 0),
U3G_DEV(SIERRA, AC402, 0),
U3G_DEV(SIERRA, AC595U, 0),
+ U3G_DEV(SIERRA, AC313U, 0),
U3G_DEV(SIERRA, AC597E, 0),
U3G_DEV(SIERRA, AC875E, 0),
U3G_DEV(SIERRA, AC875U, 0),
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/usb/storage/umass.c
--- a/head/sys/dev/usb/storage/umass.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/usb/storage/umass.c Fri Mar 02 17:36:33 2012 +0200
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/storage/umass.c 227461 2011-11-12 08:16:45Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/storage/umass.c 232361 2012-03-01 20:25:17Z hselasky $");
/*-
* Copyright (c) 1999 MAEKAWA Masahide <bishop at rr.iij4u.or.jp>,
@@ -27,7 +27,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: head/sys/dev/usb/storage/umass.c 227461 2011-11-12 08:16:45Z hselasky $
+ * $FreeBSD: head/sys/dev/usb/storage/umass.c 232361 2012-03-01 20:25:17Z hselasky $
* $NetBSD: umass.c,v 1.28 2000/04/02 23:46:53 augustss Exp $
*/
@@ -137,14 +137,6 @@
#include <cam/cam_periph.h>
-#define UMASS_EXT_BUFFER
-#ifdef UMASS_EXT_BUFFER
-/* this enables loading of virtual buffers into DMA */
-#define UMASS_USB_FLAGS .ext_buffer=1,
-#else
-#define UMASS_USB_FLAGS
-#endif
-
#ifdef USB_DEBUG
#define DIF(m, x) \
do { \
@@ -542,7 +534,7 @@
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
.bufsize = UMASS_BULK_SIZE,
- .flags = {.proxy_buffer = 1,.short_xfer_ok = 1, UMASS_USB_FLAGS},
+ .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer=1,},
.callback = &umass_t_bbb_data_read_callback,
.timeout = 0, /* overwritten later */
},
@@ -561,7 +553,7 @@
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
.bufsize = UMASS_BULK_SIZE,
- .flags = {.proxy_buffer = 1,.short_xfer_ok = 1, UMASS_USB_FLAGS},
+ .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer=1,},
.callback = &umass_t_bbb_data_write_callback,
.timeout = 0, /* overwritten later */
},
@@ -634,7 +626,7 @@
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
.bufsize = UMASS_BULK_SIZE,
- .flags = {.proxy_buffer = 1,.short_xfer_ok = 1, UMASS_USB_FLAGS},
+ .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer=1,},
.callback = &umass_t_cbi_data_read_callback,
.timeout = 0, /* overwritten later */
},
@@ -653,7 +645,7 @@
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
.bufsize = UMASS_BULK_SIZE,
- .flags = {.proxy_buffer = 1,.short_xfer_ok = 1, UMASS_USB_FLAGS},
+ .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer=1,},
.callback = &umass_t_cbi_data_write_callback,
.timeout = 0, /* overwritten later */
},
@@ -1053,14 +1045,16 @@
usbd_transfer_unsetup(sc->sc_xfer, UMASS_T_MAX);
-#if (__FreeBSD_version >= 700037)
mtx_lock(&sc->sc_mtx);
-#endif
+
+ /* cancel any leftover CCB's */
+
+ umass_cancel_ccb(sc);
+
umass_cam_detach_sim(sc);
-#if (__FreeBSD_version >= 700037)
mtx_unlock(&sc->sc_mtx);
-#endif
+
mtx_destroy(&sc->sc_mtx);
return (0); /* success */
@@ -1201,7 +1195,6 @@
default: /* Error */
umass_tr_error(xfer, error);
return;
-
}
}
@@ -1240,7 +1233,6 @@
default: /* Error */
umass_tr_error(xfer, error);
return;
-
}
}
@@ -1326,7 +1318,6 @@
default: /* Error */
umass_tr_error(xfer, error);
return;
-
}
}
@@ -1335,19 +1326,12 @@
{
struct umass_softc *sc = usbd_xfer_softc(xfer);
uint32_t max_bulk = usbd_xfer_max_len(xfer);
-#ifndef UMASS_EXT_BUFFER
- struct usb_page_cache *pc;
-#endif
int actlen, sumlen;
usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
-#ifndef UMASS_EXT_BUFFER
- pc = usbd_xfer_get_frame(xfer, 0);
- usbd_copy_out(pc, 0, sc->sc_transfer.data_ptr, actlen);
-#endif
sc->sc_transfer.data_rem -= actlen;
sc->sc_transfer.data_ptr += actlen;
sc->sc_transfer.actlen += actlen;
@@ -1369,12 +1353,9 @@
}
usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout);
-#ifdef UMASS_EXT_BUFFER
usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr,
max_bulk);
-#else
- usbd_xfer_set_frame_len(xfer, 0, max_bulk);
-#endif
+
usbd_transfer_submit(xfer);
return;
@@ -1385,7 +1366,6 @@
umass_transfer_start(sc, UMASS_T_BBB_DATA_RD_CS);
}
return;
-
}
}
@@ -1401,9 +1381,6 @@
{
struct umass_softc *sc = usbd_xfer_softc(xfer);
uint32_t max_bulk = usbd_xfer_max_len(xfer);
-#ifndef UMASS_EXT_BUFFER
- struct usb_page_cache *pc;
-#endif
int actlen, sumlen;
usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
@@ -1431,14 +1408,8 @@
}
usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout);
-#ifdef UMASS_EXT_BUFFER
usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr,
max_bulk);
-#else
- pc = usbd_xfer_get_frame(xfer, 0);
- usbd_copy_in(pc, 0, sc->sc_transfer.data_ptr, max_bulk);
- usbd_xfer_set_frame_len(xfer, 0, max_bulk);
-#endif
usbd_transfer_submit(xfer);
return;
@@ -1450,7 +1421,6 @@
umass_transfer_start(sc, UMASS_T_BBB_DATA_WR_CS);
}
return;
-
}
}
@@ -1576,7 +1546,6 @@
umass_transfer_start(sc, UMASS_T_BBB_DATA_RD_CS);
}
return;
-
}
}
@@ -1607,8 +1576,7 @@
if (sc->sc_xfer[sc->sc_last_xfer_index]) {
usbd_transfer_start(sc->sc_xfer[sc->sc_last_xfer_index]);
} else {
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
+ umass_cancel_ccb(sc);
}
}
@@ -1728,7 +1696,6 @@
else
umass_transfer_start(sc, UMASS_T_CBI_RESET2);
break;
-
}
}
@@ -1783,7 +1750,6 @@
default: /* Error */
umass_tr_error(xfer, error);
break;
-
}
}
@@ -1873,19 +1839,12 @@
{
struct umass_softc *sc = usbd_xfer_softc(xfer);
uint32_t max_bulk = usbd_xfer_max_len(xfer);
-#ifndef UMASS_EXT_BUFFER
- struct usb_page_cache *pc;
-#endif
int actlen, sumlen;
usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
-#ifndef UMASS_EXT_BUFFER
- pc = usbd_xfer_get_frame(xfer, 0);
- usbd_copy_out(pc, 0, sc->sc_transfer.data_ptr, actlen);
-#endif
sc->sc_transfer.data_rem -= actlen;
sc->sc_transfer.data_ptr += actlen;
sc->sc_transfer.actlen += actlen;
@@ -1907,12 +1866,9 @@
}
usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout);
-#ifdef UMASS_EXT_BUFFER
usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr,
max_bulk);
-#else
- usbd_xfer_set_frame_len(xfer, 0, max_bulk);
-#endif
+
usbd_transfer_submit(xfer);
break;
@@ -1924,7 +1880,6 @@
umass_transfer_start(sc, UMASS_T_CBI_DATA_RD_CS);
}
break;
-
}
}
@@ -1940,9 +1895,6 @@
{
struct umass_softc *sc = usbd_xfer_softc(xfer);
uint32_t max_bulk = usbd_xfer_max_len(xfer);
-#ifndef UMASS_EXT_BUFFER
- struct usb_page_cache *pc;
-#endif
int actlen, sumlen;
usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
@@ -1970,14 +1922,8 @@
}
usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout);
-#ifdef UMASS_EXT_BUFFER
usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr,
max_bulk);
-#else
- pc = usbd_xfer_get_frame(xfer, 0);
- usbd_copy_in(pc, 0, sc->sc_transfer.data_ptr, max_bulk);
- usbd_xfer_set_frame_len(xfer, 0, max_bulk);
-#endif
usbd_transfer_submit(xfer);
break;
@@ -1990,7 +1936,6 @@
umass_transfer_start(sc, UMASS_T_CBI_DATA_WR_CS);
}
break;
-
}
}
@@ -2092,7 +2037,6 @@
usbd_errstr(error));
umass_tr_error(xfer, error);
break;
-
}
}
@@ -2121,9 +2065,7 @@
DEVNAME_SIM,
sc /* priv */ ,
sc->sc_unit /* unit number */ ,
-#if (__FreeBSD_version >= 700037)
&sc->sc_mtx /* mutex */ ,
-#endif
1 /* maximum device openings */ ,
0 /* maximum tagged device openings */ ,
devq);
@@ -2133,27 +2075,15 @@
return (ENOMEM);
}
-#if (__FreeBSD_version >= 700037)
mtx_lock(&sc->sc_mtx);
-#endif
-
-#if (__FreeBSD_version >= 700048)
- if (xpt_bus_register(sc->sc_sim, sc->sc_dev, sc->sc_unit) != CAM_SUCCESS) {
+
+ if (xpt_bus_register(sc->sc_sim, sc->sc_dev,
+ sc->sc_unit) != CAM_SUCCESS) {
mtx_unlock(&sc->sc_mtx);
return (ENOMEM);
}
-#else
- if (xpt_bus_register(sc->sc_sim, sc->sc_unit) != CAM_SUCCESS) {
-#if (__FreeBSD_version >= 700037)
- mtx_unlock(&sc->sc_mtx);
-#endif
- return (ENOMEM);
- }
-#endif
-
-#if (__FreeBSD_version >= 700037)
mtx_unlock(&sc->sc_mtx);
-#endif
+
return (0);
}
@@ -2204,11 +2134,6 @@
xpt_done(ccb);
return;
}
- if (sc) {
-#if (__FreeBSD_version < 700037)
- mtx_lock(&sc->sc_mtx);
-#endif
- }
/*
* Verify, depending on the operation to perform, that we either got
* a valid sc, because an existing target was referenced, or
@@ -2411,12 +2336,11 @@
strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
cpi->unit_number = cam_sim_unit(sim);
cpi->bus_id = sc->sc_unit;
-#if (__FreeBSD_version >= 700025)
cpi->protocol = PROTO_SCSI;
cpi->protocol_version = SCSI_REV_2;
cpi->transport = XPORT_USB;
cpi->transport_version = 0;
-#endif
+
if (sc == NULL) {
cpi->base_transfer_speed = 0;
cpi->max_lun = 0;
@@ -2468,16 +2392,12 @@
cam_sim_path(sc->sc_sim), ccb->ccb_h.target_id,
ccb->ccb_h.target_lun);
-#if (__FreeBSD_version >= 700025)
cts->protocol = PROTO_SCSI;
cts->protocol_version = SCSI_REV_2;
cts->transport = XPORT_USB;
cts->transport_version = 0;
cts->xport_specific.valid = 0;
-#else
- cts->valid = 0;
- cts->flags = 0; /* no disconnection, tagging */
-#endif
+
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
@@ -2520,11 +2440,6 @@
}
done:
-#if (__FreeBSD_version < 700037)
- if (sc) {
- mtx_unlock(&sc->sc_mtx);
- }
-#endif
return;
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/usb/usb_dev.c
--- a/head/sys/dev/usb/usb_dev.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/usb/usb_dev.c Fri Mar 02 17:36:33 2012 +0200
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/usb/usb_dev.c 227461 2011-11-12 08:16:45Z hselasky $ */
+/* $FreeBSD: head/sys/dev/usb/usb_dev.c 231378 2012-02-10 12:35:57Z ed $ */
/*-
* Copyright (c) 2006-2008 Hans Petter Selasky. All rights reserved.
*
@@ -842,7 +842,7 @@
struct usb_cdev_privdata *cpd;
int err, ep;
- DPRINTFN(2, "%s fflags=0x%08x\n", dev->si_name, fflags);
+ DPRINTFN(2, "%s fflags=0x%08x\n", devtoname(dev), fflags);
KASSERT(fflags & (FREAD|FWRITE), ("invalid open flags"));
if (((fflags & FREAD) && !(pd->mode & FREAD)) ||
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/usb/usbdevs
--- a/head/sys/dev/usb/usbdevs Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/usb/usbdevs Fri Mar 02 17:36:33 2012 +0200
@@ -1,4 +1,4 @@
-$FreeBSD: head/sys/dev/usb/usbdevs 230333 2012-01-19 18:03:52Z hselasky $
+$FreeBSD: head/sys/dev/usb/usbdevs 232257 2012-02-28 15:45:42Z kevlo $
/* $NetBSD: usbdevs,v 1.392 2004/12/29 08:38:44 imp Exp $ */
/*-
@@ -2309,6 +2309,7 @@
product MOSCHIP MCS7730 0x7730 MCS7730 Ethernet
product MOSCHIP MCS7820 0x7820 MCS7820 Serial Port Adapter
product MOSCHIP MCS7830 0x7830 MCS7830 Ethernet
+product MOSCHIP MCS7832 0x7832 MCS7832 Ethernet
product MOSCHIP MCS7840 0x7840 MCS7840 Serial Port Adapter
/* Motorola products */
@@ -3008,6 +3009,7 @@
product SIERRA E6893 0x6893 E6893
product SIERRA MC8700 0x68A3 MC8700
product SIERRA AIRCARD875 0x6820 Aircard 875 HSDPA
+product SIERRA AC313U 0x68aa Sierra Wireless AirCard 313U
product SIERRA TRUINSTALL 0x0fff Aircard Tru Installer
/* Sigmatel products */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/vge/if_vge.c
--- a/head/sys/dev/vge/if_vge.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/vge/if_vge.c Fri Mar 02 17:36:33 2012 +0200
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/vge/if_vge.c 227843 2011-11-22 21:28:20Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/vge/if_vge.c 231510 2012-02-11 08:12:52Z kevlo $");
/*
* VIA Networking Technologies VT612x PCI gigabit ethernet NIC driver.
@@ -2022,11 +2022,9 @@
vge_init_locked(struct vge_softc *sc)
{
struct ifnet *ifp = sc->vge_ifp;
- struct mii_data *mii;
int error, i;
VGE_LOCK_ASSERT(sc);
- mii = device_get_softc(sc->vge_miibus);
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
return;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/wi/if_wi.c
--- a/head/sys/dev/wi/if_wi.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/wi/if_wi.c Fri Mar 02 17:36:33 2012 +0200
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/wi/if_wi.c 230562 2012-01-26 05:11:37Z adrian $");
+__FBSDID("$FreeBSD: head/sys/dev/wi/if_wi.c 232147 2012-02-25 08:01:29Z adrian $");
#include "opt_wlan.h"
@@ -1511,6 +1511,10 @@
case WI_INFO_LINK_STAT:
wi_read_bap(sc, fid, sizeof(ltbuf), &stat, sizeof(stat));
DPRINTF(("wi_info_intr: LINK_STAT 0x%x\n", le16toh(stat)));
+
+ if (vap == NULL)
+ goto finish;
+
switch (le16toh(stat)) {
case WI_INFO_LINK_STAT_CONNECTED:
if (vap->iv_state == IEEE80211_S_RUN &&
@@ -1566,6 +1570,7 @@
le16toh(ltbuf[1]), le16toh(ltbuf[0])));
break;
}
+finish:
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
}
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/wtap/if_wtap.c
--- a/head/sys/dev/wtap/if_wtap.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/wtap/if_wtap.c Fri Mar 02 17:36:33 2012 +0200
@@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
- * $FreeBSD: head/sys/dev/wtap/if_wtap.c 229970 2012-01-11 17:41:14Z adrian $
+ * $FreeBSD: head/sys/dev/wtap/if_wtap.c 231378 2012-02-10 12:35:57Z ed $
*/
#include "if_wtapvar.h"
#include <sys/uio.h> /* uio struct */
@@ -84,7 +84,7 @@
uint8_t buf[1024];
int buf_len;
- uprintf("write device %s \"echo.\"\n", dev->si_name);
+ uprintf("write device %s \"echo.\"\n", devtoname(dev));
buf_len = MIN(uio->uio_iov->iov_len, 1024);
err = copyin(uio->uio_iov->iov_base, buf, buf_len);
@@ -101,7 +101,7 @@
TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
printf("ifp->if_xname = %s\n", ifp->if_xname);
- if(strcmp(dev->si_name, ifp->if_xname) == 0){
+ if(strcmp(devtoname(dev), ifp->if_xname) == 0){
printf("found match, correspoding wtap = %s\n",
ifp->if_xname);
sc = (struct wtap_softc *)ifp->if_softc;
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/wtap/if_wtap_module.c
--- a/head/sys/dev/wtap/if_wtap_module.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/wtap/if_wtap_module.c Fri Mar 02 17:36:33 2012 +0200
@@ -26,7 +26,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
- * $FreeBSD: head/sys/dev/wtap/if_wtap_module.c 229970 2012-01-11 17:41:14Z adrian $
+ * $FreeBSD: head/sys/dev/wtap/if_wtap_module.c 231828 2012-02-16 16:48:12Z adrian $
*/
#include <sys/param.h>
#include <sys/module.h>
@@ -184,3 +184,4 @@
};
DECLARE_MODULE(wtap, wtap_conf, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
+MODULE_DEPEND(wtap, wlan, 1, 1, 1); /* 802.11 media layer */
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/xen/blkback/blkback.c
--- a/head/sys/dev/xen/blkback/blkback.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/xen/blkback/blkback.c Fri Mar 02 17:36:33 2012 +0200
@@ -31,7 +31,7 @@
* Ken Merry (Spectra Logic Corporation)
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/xen/blkback/blkback.c 230587 2012-01-26 16:35:09Z ken $");
+__FBSDID("$FreeBSD: head/sys/dev/xen/blkback/blkback.c 231883 2012-02-17 22:33:46Z gibbs $");
/**
* \file blkback.c
@@ -40,6 +40,8 @@
* a FreeBSD domain to other domains.
*/
+#include "opt_kdtrace.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -63,6 +65,7 @@
#include <sys/mount.h>
#include <sys/sysctl.h>
#include <sys/bitstring.h>
+#include <sys/sdt.h>
#include <geom/geom.h>
@@ -124,7 +127,7 @@
static MALLOC_DEFINE(M_XENBLOCKBACK, "xbbd", "Xen Block Back Driver Data");
#ifdef XBB_DEBUG
-#define DPRINTF(fmt, args...) \
+#define DPRINTF(fmt, args...) \
printf("xbb(%s:%d): " fmt, __FUNCTION__, __LINE__, ##args)
#else
#define DPRINTF(fmt, args...) do {} while(0)
@@ -134,7 +137,7 @@
* The maximum mapped region size per request we will allow in a negotiated
* block-front/back communication channel.
*/
-#define XBB_MAX_REQUEST_SIZE \
+#define XBB_MAX_REQUEST_SIZE \
MIN(MAXPHYS, BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE)
/**
@@ -142,9 +145,9 @@
* segment blocks) per request we will allow in a negotiated block-front/back
* communication channel.
*/
-#define XBB_MAX_SEGMENTS_PER_REQUEST \
- (MIN(UIO_MAXIOV, \
- MIN(BLKIF_MAX_SEGMENTS_PER_REQUEST, \
+#define XBB_MAX_SEGMENTS_PER_REQUEST \
+ (MIN(UIO_MAXIOV, \
+ MIN(BLKIF_MAX_SEGMENTS_PER_REQUEST, \
(XBB_MAX_REQUEST_SIZE / PAGE_SIZE) + 1)))
/**
@@ -980,9 +983,10 @@
static uint8_t *
xbb_get_kva(struct xbb_softc *xbb, int nr_pages)
{
- intptr_t first_clear, num_clear;
+ intptr_t first_clear;
+ intptr_t num_clear;
uint8_t *free_kva;
- int i;
+ int i;
KASSERT(nr_pages != 0, ("xbb_get_kva of zero length"));
@@ -1681,19 +1685,19 @@
req_ring_idx++;
switch (xbb->abi) {
case BLKIF_PROTOCOL_NATIVE:
- sg = BLKRING_GET_SG_REQUEST(&xbb->rings.native,
- req_ring_idx);
+ sg = BLKRING_GET_SEG_BLOCK(&xbb->rings.native,
+ req_ring_idx);
break;
case BLKIF_PROTOCOL_X86_32:
{
- sg = BLKRING_GET_SG_REQUEST(&xbb->rings.x86_32,
- req_ring_idx);
+ sg = BLKRING_GET_SEG_BLOCK(&xbb->rings.x86_32,
+ req_ring_idx);
break;
}
case BLKIF_PROTOCOL_X86_64:
{
- sg = BLKRING_GET_SG_REQUEST(&xbb->rings.x86_64,
- req_ring_idx);
+ sg = BLKRING_GET_SEG_BLOCK(&xbb->rings.x86_64,
+ req_ring_idx);
break;
}
default:
@@ -1817,8 +1821,8 @@
struct xbb_xen_reqlist *reqlist;
- xbb = (struct xbb_softc *)context;
- rings = &xbb->rings;
+ xbb = (struct xbb_softc *)context;
+ rings = &xbb->rings;
/*
* Work gather and dispatch loop. Note that we have a bias here
@@ -2032,6 +2036,13 @@
taskqueue_enqueue(xbb->io_taskqueue, &xbb->io_task);
}
+SDT_PROVIDER_DEFINE(xbb);
+SDT_PROBE_DEFINE1(xbb, kernel, xbb_dispatch_dev, flush, flush, "int");
+SDT_PROBE_DEFINE3(xbb, kernel, xbb_dispatch_dev, read, read, "int", "uint64_t",
+ "uint64_t");
+SDT_PROBE_DEFINE3(xbb, kernel, xbb_dispatch_dev, write, write, "int",
+ "uint64_t", "uint64_t");
+
/*----------------------------- Backend Handlers -----------------------------*/
/**
* Backend handler for character device access.
@@ -2087,6 +2098,9 @@
nreq->pendcnt = 1;
+ SDT_PROBE1(xbb, kernel, xbb_dispatch_dev, flush,
+ device_get_unit(xbb->dev));
+
(*dev_data->csw->d_strategy)(bio);
return (0);
@@ -2181,6 +2195,17 @@
bios[bio_idx]->bio_bcount);
}
#endif
+ if (operation == BIO_READ) {
+ SDT_PROBE3(xbb, kernel, xbb_dispatch_dev, read,
+ device_get_unit(xbb->dev),
+ bios[bio_idx]->bio_offset,
+ bios[bio_idx]->bio_length);
+ } else if (operation == BIO_WRITE) {
+ SDT_PROBE3(xbb, kernel, xbb_dispatch_dev, write,
+ device_get_unit(xbb->dev),
+ bios[bio_idx]->bio_offset,
+ bios[bio_idx]->bio_length);
+ }
(*dev_data->csw->d_strategy)(bios[bio_idx]);
}
@@ -2193,6 +2218,12 @@
return (error);
}
+SDT_PROBE_DEFINE1(xbb, kernel, xbb_dispatch_file, flush, flush, "int");
+SDT_PROBE_DEFINE3(xbb, kernel, xbb_dispatch_file, read, read, "int", "uint64_t",
+ "uint64_t");
+SDT_PROBE_DEFINE3(xbb, kernel, xbb_dispatch_file, write, write, "int",
+ "uint64_t", "uint64_t");
+
/**
* Backend handler for file access.
*
@@ -2237,6 +2268,9 @@
case BIO_FLUSH: {
struct mount *mountpoint;
+ SDT_PROBE1(xbb, kernel, xbb_dispatch_file, flush,
+ device_get_unit(xbb->dev));
+
vfs_is_locked = VFS_LOCK_GIANT(xbb->vn->v_mount);
(void) vn_start_write(xbb->vn, &mountpoint, V_WAIT);
@@ -2336,6 +2370,10 @@
switch (operation) {
case BIO_READ:
+ SDT_PROBE3(xbb, kernel, xbb_dispatch_file, read,
+ device_get_unit(xbb->dev), xuio.uio_offset,
+ xuio.uio_resid);
+
vn_lock(xbb->vn, LK_EXCLUSIVE | LK_RETRY);
/*
@@ -2366,6 +2404,10 @@
case BIO_WRITE: {
struct mount *mountpoint;
+ SDT_PROBE3(xbb, kernel, xbb_dispatch_file, write,
+ device_get_unit(xbb->dev), xuio.uio_offset,
+ xuio.uio_resid);
+
(void)vn_start_write(xbb->vn, &mountpoint, V_WAIT);
vn_lock(xbb->vn, LK_EXCLUSIVE | LK_RETRY);
@@ -3028,6 +3070,8 @@
const char *otherend_path;
int error;
u_int ring_idx;
+ u_int ring_page_order;
+ size_t ring_size;
otherend_path = xenbus_get_otherend_path(xbb->dev);
@@ -3035,23 +3079,19 @@
* Protocol defaults valid even if all negotiation fails.
*/
xbb->ring_config.ring_pages = 1;
- xbb->max_requests = BLKIF_MAX_RING_REQUESTS(PAGE_SIZE);
xbb->max_request_segments = BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK;
xbb->max_request_size = xbb->max_request_segments * PAGE_SIZE;
/*
* Mandatory data (used in all versions of the protocol) first.
*/
- error = xs_gather(XST_NIL, otherend_path,
- "ring-ref", "%" PRIu32,
- &xbb->ring_config.ring_ref[0],
- "event-channel", "%" PRIu32,
- &xbb->ring_config.evtchn,
- NULL);
+ error = xs_scanf(XST_NIL, otherend_path,
+ "event-channel", NULL, "%" PRIu32,
+ &xbb->ring_config.evtchn);
if (error != 0) {
xenbus_dev_fatal(xbb->dev, error,
- "Unable to retrieve ring information from "
- "frontend %s. Unable to connect.",
+ "Unable to retrieve event-channel information "
+ "from frontend %s. Unable to connect.",
xenbus_get_otherend_path(xbb->dev));
return (error);
}
@@ -3065,10 +3105,20 @@
* we must use independant calls in order to guarantee
* we don't miss information in a sparsly populated front-end
* tree.
+ *
+ * \note xs_scanf() does not update variables for unmatched
+ * fields.
*/
+ ring_page_order = 0;
(void)xs_scanf(XST_NIL, otherend_path,
- "ring-pages", NULL, "%u",
+ "ring-page-order", NULL, "%u",
+ &ring_page_order);
+ xbb->ring_config.ring_pages = 1 << ring_page_order;
+ (void)xs_scanf(XST_NIL, otherend_path,
+ "num-ring-pages", NULL, "%u",
&xbb->ring_config.ring_pages);
+ ring_size = PAGE_SIZE * xbb->ring_config.ring_pages;
+ xbb->max_requests = BLKIF_MAX_RING_REQUESTS(ring_size);
(void)xs_scanf(XST_NIL, otherend_path,
"max-requests", NULL, "%u",
@@ -3084,7 +3134,7 @@
if (xbb->ring_config.ring_pages > XBB_MAX_RING_PAGES) {
xenbus_dev_fatal(xbb->dev, EINVAL,
- "Front-end specificed ring-pages of %u "
+ "Front-end specified ring-pages of %u "
"exceeds backend limit of %zu. "
"Unable to connect.",
xbb->ring_config.ring_pages,
@@ -3092,7 +3142,7 @@
return (EINVAL);
} else if (xbb->max_requests > XBB_MAX_REQUESTS) {
xenbus_dev_fatal(xbb->dev, EINVAL,
- "Front-end specificed max_requests of %u "
+ "Front-end specified max_requests of %u "
"exceeds backend limit of %u. "
"Unable to connect.",
xbb->max_requests,
@@ -3100,7 +3150,7 @@
return (EINVAL);
} else if (xbb->max_request_segments > XBB_MAX_SEGMENTS_PER_REQUEST) {
xenbus_dev_fatal(xbb->dev, EINVAL,
- "Front-end specificed max_requests_segments "
+ "Front-end specified max_requests_segments "
"of %u exceeds backend limit of %u. "
"Unable to connect.",
xbb->max_request_segments,
@@ -3108,7 +3158,7 @@
return (EINVAL);
} else if (xbb->max_request_size > XBB_MAX_REQUEST_SIZE) {
xenbus_dev_fatal(xbb->dev, EINVAL,
- "Front-end specificed max_request_size "
+ "Front-end specified max_request_size "
"of %u exceeds backend limit of %u. "
"Unable to connect.",
xbb->max_request_size,
@@ -3116,22 +3166,39 @@
return (EINVAL);
}
- /* If using a multi-page ring, pull in the remaining references. */
- for (ring_idx = 1; ring_idx < xbb->ring_config.ring_pages; ring_idx++) {
- char ring_ref_name[]= "ring_refXX";
-
- snprintf(ring_ref_name, sizeof(ring_ref_name),
- "ring-ref%u", ring_idx);
- error = xs_scanf(XST_NIL, otherend_path,
- ring_ref_name, NULL, "%" PRIu32,
- &xbb->ring_config.ring_ref[ring_idx]);
+ if (xbb->ring_config.ring_pages == 1) {
+ error = xs_gather(XST_NIL, otherend_path,
+ "ring-ref", "%" PRIu32,
+ &xbb->ring_config.ring_ref[0],
+ NULL);
if (error != 0) {
xenbus_dev_fatal(xbb->dev, error,
- "Failed to retriev grant reference "
- "for page %u of shared ring. Unable "
- "to connect.", ring_idx);
+ "Unable to retrieve ring information "
+ "from frontend %s. Unable to "
+ "connect.",
+ xenbus_get_otherend_path(xbb->dev));
return (error);
}
+ } else {
+ /* Multi-page ring format. */
+ for (ring_idx = 0; ring_idx < xbb->ring_config.ring_pages;
+ ring_idx++) {
+ char ring_ref_name[]= "ring_refXX";
+
+ snprintf(ring_ref_name, sizeof(ring_ref_name),
+ "ring-ref%u", ring_idx);
+ error = xs_scanf(XST_NIL, otherend_path,
+ ring_ref_name, NULL, "%" PRIu32,
+ &xbb->ring_config.ring_ref[ring_idx]);
+ if (error != 0) {
+ xenbus_dev_fatal(xbb->dev, error,
+ "Failed to retriev grant "
+ "reference for page %u of "
+ "shared ring. Unable "
+ "to connect.", ring_idx);
+ return (error);
+ }
+ }
}
error = xs_gather(XST_NIL, otherend_path,
@@ -3197,8 +3264,8 @@
static int
xbb_alloc_request_lists(struct xbb_softc *xbb)
{
- int i;
struct xbb_xen_reqlist *reqlist;
+ int i;
/*
* If no requests can be merged, we need 1 request list per
@@ -3318,7 +3385,7 @@
static void
xbb_connect(struct xbb_softc *xbb)
{
- int error;
+ int error;
if (xenbus_get_state(xbb->dev) == XenbusStateConnected)
return;
@@ -3399,7 +3466,8 @@
static int
xbb_shutdown(struct xbb_softc *xbb)
{
- int error;
+ XenbusState frontState;
+ int error;
DPRINTF("\n");
@@ -3413,6 +3481,20 @@
if ((xbb->flags & XBBF_IN_SHUTDOWN) != 0)
return (EAGAIN);
+ xbb->flags |= XBBF_IN_SHUTDOWN;
+ mtx_unlock(&xbb->lock);
+
+ if (xenbus_get_state(xbb->dev) < XenbusStateClosing)
+ xenbus_set_state(xbb->dev, XenbusStateClosing);
+
+ frontState = xenbus_get_otherend_state(xbb->dev);
+ mtx_lock(&xbb->lock);
+ xbb->flags &= ~XBBF_IN_SHUTDOWN;
+
+ /* The front can submit I/O until entering the closed state. */
+ if (frontState < XenbusStateClosed)
+ return (EAGAIN);
+
DPRINTF("\n");
/* Indicate shutdown is in progress. */
@@ -3434,19 +3516,6 @@
DPRINTF("\n");
- /*
- * Before unlocking mutex, set this flag to prevent other threads from
- * getting into this function
- */
- xbb->flags |= XBBF_IN_SHUTDOWN;
- mtx_unlock(&xbb->lock);
-
- if (xenbus_get_state(xbb->dev) < XenbusStateClosing)
- xenbus_set_state(xbb->dev, XenbusStateClosing);
-
- mtx_lock(&xbb->lock);
- xbb->flags &= ~XBBF_IN_SHUTDOWN;
-
/* Indicate to xbb_detach() that is it safe to proceed. */
wakeup(xbb);
@@ -3573,6 +3642,16 @@
"max_request_segments", CTLFLAG_RD,
&xbb->max_request_segments, 0,
"maximum number of pages per requests (negotiated)");
+
+ SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
+ "max_request_size", CTLFLAG_RD,
+ &xbb->max_request_size, 0,
+ "maximum size in bytes of a request (negotiated)");
+
+ SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
+ "ring_pages", CTLFLAG_RD,
+ &xbb->ring_config.ring_pages, 0,
+ "communication channel pages (negotiated)");
}
/**
@@ -3587,6 +3666,7 @@
{
struct xbb_softc *xbb;
int error;
+ u_int max_ring_page_order;
DPRINTF("Attaching to %s\n", xenbus_get_node(dev));
@@ -3621,6 +3701,10 @@
return (error);
}
+ /*
+ * Amazon EC2 client compatility. They refer to max-ring-pages
+ * instead of to max-ring-page-order.
+ */
error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
"max-ring-pages", "%zu", XBB_MAX_RING_PAGES);
if (error) {
@@ -3629,6 +3713,15 @@
return (error);
}
+ max_ring_page_order = flsl(XBB_MAX_RING_PAGES) - 1;
+ error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
+ "max-ring-page-order", "%u", max_ring_page_order);
+ if (error) {
+ xbb_attach_failed(xbb, error, "writing %s/max-ring-page-order",
+ xenbus_get_node(xbb->dev));
+ return (error);
+ }
+
error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
"max-requests", "%u", XBB_MAX_REQUESTS);
if (error) {
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/xen/blkfront/blkfront.c
--- a/head/sys/dev/xen/blkfront/blkfront.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/xen/blkfront/blkfront.c Fri Mar 02 17:36:33 2012 +0200
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/xen/blkfront/blkfront.c 227293 2011-11-07 06:44:47Z ed $");
+__FBSDID("$FreeBSD: head/sys/dev/xen/blkfront/blkfront.c 231839 2012-02-16 21:58:47Z gibbs $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -41,6 +41,7 @@
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/module.h>
+#include <sys/sysctl.h>
#include <machine/bus.h>
#include <sys/rman.h>
@@ -139,7 +140,7 @@
* with blkfront as the emulated drives, easing transition slightly.
*/
static void
-blkfront_vdevice_to_unit(int vdevice, int *unit, const char **name)
+blkfront_vdevice_to_unit(uint32_t vdevice, int *unit, const char **name)
{
static struct vdev_info {
int major;
@@ -186,6 +187,7 @@
if (vdevice & (1 << 28)) {
*unit = (vdevice & ((1 << 28) - 1)) >> 8;
*name = "xbd";
+ return;
}
for (i = 0; info[i].major; i++) {
@@ -407,6 +409,40 @@
return (ENXIO);
}
+static void
+xb_setup_sysctl(struct xb_softc *xb)
+{
+ struct sysctl_ctx_list *sysctl_ctx = NULL;
+ struct sysctl_oid *sysctl_tree = NULL;
+
+ sysctl_ctx = device_get_sysctl_ctx(xb->xb_dev);
+ if (sysctl_ctx == NULL)
+ return;
+
+ sysctl_tree = device_get_sysctl_tree(xb->xb_dev);
+ if (sysctl_tree == NULL)
+ return;
+
+ SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
+ "max_requests", CTLFLAG_RD, &xb->max_requests, -1,
+ "maximum outstanding requests (negotiated)");
+
+ SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
+ "max_request_segments", CTLFLAG_RD,
+ &xb->max_request_segments, 0,
+ "maximum number of pages per requests (negotiated)");
+
+ SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
+ "max_request_size", CTLFLAG_RD,
+ &xb->max_request_size, 0,
+ "maximum size in bytes of a request (negotiated)");
+
+ SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
+ "ring_pages", CTLFLAG_RD,
+ &xb->ring_pages, 0,
+ "communication channel pages (negotiated)");
+}
+
/*
* Setup supplies the backend dir, virtual device. We place an event
* channel and shared frame entries. We watch backend to wait if it's
@@ -417,14 +453,14 @@
{
struct xb_softc *sc;
const char *name;
+ uint32_t vdevice;
int error;
- int vdevice;
int i;
int unit;
/* FIXME: Use dynamic device id if this is not set. */
error = xs_scanf(XST_NIL, xenbus_get_node(dev),
- "virtual-device", NULL, "%i", &vdevice);
+ "virtual-device", NULL, "%" PRIu32, &vdevice);
if (error) {
xenbus_dev_fatal(dev, error, "reading virtual-device");
device_printf(dev, "Couldn't determine virtual device.\n");
@@ -449,6 +485,8 @@
sc->vdevice = vdevice;
sc->connected = BLKIF_STATE_DISCONNECTED;
+ xb_setup_sysctl(sc);
+
/* Wait for backend device to publish its protocol capabilities. */
xenbus_set_state(dev, XenbusStateInitialising);
@@ -501,6 +539,7 @@
{
const char *otherend_path;
const char *node_path;
+ uint32_t max_ring_page_order;
int error;
int i;
@@ -513,10 +552,10 @@
* Protocol defaults valid even if negotiation for a
* setting fails.
*/
+ max_ring_page_order = 0;
sc->ring_pages = 1;
- sc->max_requests = BLKIF_MAX_RING_REQUESTS(PAGE_SIZE);
sc->max_request_segments = BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK;
- sc->max_request_size = (sc->max_request_segments - 1) * PAGE_SIZE;
+ sc->max_request_size = XBF_SEGS_TO_SIZE(sc->max_request_segments);
sc->max_request_blocks = BLKIF_SEGS_TO_BLOCKS(sc->max_request_segments);
/*
@@ -526,13 +565,25 @@
* we must use independant calls in order to guarantee
* we don't miss information in a sparsly populated back-end
* tree.
+ *
+ * \note xs_scanf() does not update variables for unmatched
+ * fields.
*/
otherend_path = xenbus_get_otherend_path(sc->xb_dev);
node_path = xenbus_get_node(sc->xb_dev);
+
+ /* Support both backend schemes for relaying ring page limits. */
+ (void)xs_scanf(XST_NIL, otherend_path,
+ "max-ring-page-order", NULL, "%" PRIu32,
+ &max_ring_page_order);
+ sc->ring_pages = 1 << max_ring_page_order;
(void)xs_scanf(XST_NIL, otherend_path,
"max-ring-pages", NULL, "%" PRIu32,
&sc->ring_pages);
+ if (sc->ring_pages < 1)
+ sc->ring_pages = 1;
+ sc->max_requests = BLKIF_MAX_RING_REQUESTS(sc->ring_pages * PAGE_SIZE);
(void)xs_scanf(XST_NIL, otherend_path,
"max-requests", NULL, "%" PRIu32,
&sc->max_requests);
@@ -552,6 +603,16 @@
sc->ring_pages = XBF_MAX_RING_PAGES;
}
+ if (powerof2(sc->ring_pages) == 0) {
+ uint32_t new_page_limit;
+
+ new_page_limit = 0x01 << (fls(sc->ring_pages) - 1);
+ device_printf(sc->xb_dev, "Back-end specified ring-pages of "
+ "%u is not a power of 2. Limited to %u.\n",
+ sc->ring_pages, new_page_limit);
+ sc->ring_pages = new_page_limit;
+ }
+
if (sc->max_requests > XBF_MAX_REQUESTS) {
device_printf(sc->xb_dev, "Back-end specified max_requests of "
"%u limited to front-end limit of %u.\n",
@@ -560,8 +621,8 @@
}
if (sc->max_request_segments > XBF_MAX_SEGMENTS_PER_REQUEST) {
- device_printf(sc->xb_dev, "Back-end specificed "
- "max_requests_segments of %u limited to "
+ device_printf(sc->xb_dev, "Back-end specified "
+ "max_request_segments of %u limited to "
"front-end limit of %u.\n",
sc->max_request_segments,
XBF_MAX_SEGMENTS_PER_REQUEST);
@@ -569,12 +630,23 @@
}
if (sc->max_request_size > XBF_MAX_REQUEST_SIZE) {
- device_printf(sc->xb_dev, "Back-end specificed "
+ device_printf(sc->xb_dev, "Back-end specified "
"max_request_size of %u limited to front-end "
"limit of %u.\n", sc->max_request_size,
XBF_MAX_REQUEST_SIZE);
sc->max_request_size = XBF_MAX_REQUEST_SIZE;
}
+
+ if (sc->max_request_size > XBF_SEGS_TO_SIZE(sc->max_request_segments)) {
+ device_printf(sc->xb_dev, "Back-end specified "
+ "max_request_size of %u limited to front-end "
+ "limit of %u. (Too few segments.)\n",
+ sc->max_request_size,
+ XBF_SEGS_TO_SIZE(sc->max_request_segments));
+ sc->max_request_size =
+ XBF_SEGS_TO_SIZE(sc->max_request_segments);
+ }
+
sc->max_request_blocks = BLKIF_SEGS_TO_BLOCKS(sc->max_request_segments);
/* Allocate datastructures based on negotiated values. */
@@ -625,11 +697,20 @@
if (setup_blkring(sc) != 0)
return;
+ /* Support both backend schemes for relaying ring page limits. */
error = xs_printf(XST_NIL, node_path,
- "ring-pages","%u", sc->ring_pages);
+ "num-ring-pages","%u", sc->ring_pages);
if (error) {
xenbus_dev_fatal(sc->xb_dev, error,
- "writing %s/ring-pages",
+ "writing %s/num-ring-pages",
+ node_path);
+ return;
+ }
+ error = xs_printf(XST_NIL, node_path,
+ "ring-page-order","%u", fls(sc->ring_pages) - 1);
+ if (error) {
+ xenbus_dev_fatal(sc->xb_dev, error,
+ "writing %s/ring-page-order",
node_path);
return;
}
@@ -711,24 +792,30 @@
return (error);
}
}
- error = xs_printf(XST_NIL, xenbus_get_node(sc->xb_dev),
- "ring-ref","%u", sc->ring_ref[0]);
- if (error) {
- xenbus_dev_fatal(sc->xb_dev, error, "writing %s/ring-ref",
- xenbus_get_node(sc->xb_dev));
- return (error);
- }
- for (i = 1; i < sc->ring_pages; i++) {
- char ring_ref_name[]= "ring_refXX";
+ if (sc->ring_pages == 1) {
+ error = xs_printf(XST_NIL, xenbus_get_node(sc->xb_dev),
+ "ring-ref", "%u", sc->ring_ref[0]);
+ if (error) {
+ xenbus_dev_fatal(sc->xb_dev, error,
+ "writing %s/ring-ref",
+ xenbus_get_node(sc->xb_dev));
+ return (error);
+ }
+ } else {
+ for (i = 0; i < sc->ring_pages; i++) {
+ char ring_ref_name[]= "ring_refXX";
- snprintf(ring_ref_name, sizeof(ring_ref_name), "ring-ref%u", i);
- error = xs_printf(XST_NIL, xenbus_get_node(sc->xb_dev),
- ring_ref_name, "%u", sc->ring_ref[i]);
- if (error) {
- xenbus_dev_fatal(sc->xb_dev, error, "writing %s/%s",
- xenbus_get_node(sc->xb_dev),
- ring_ref_name);
- return (error);
+ snprintf(ring_ref_name, sizeof(ring_ref_name),
+ "ring-ref%u", i);
+ error = xs_printf(XST_NIL, xenbus_get_node(sc->xb_dev),
+ ring_ref_name, "%u", sc->ring_ref[i]);
+ if (error) {
+ xenbus_dev_fatal(sc->xb_dev, error,
+ "writing %s/%s",
+ xenbus_get_node(sc->xb_dev),
+ ring_ref_name);
+ return (error);
+ }
}
}
@@ -795,7 +882,7 @@
unsigned int binfo;
int err, feature_barrier;
- if( (sc->connected == BLKIF_STATE_CONNECTED) ||
+ if( (sc->connected == BLKIF_STATE_CONNECTED) ||
(sc->connected == BLKIF_STATE_SUSPENDED) )
return;
@@ -923,15 +1010,13 @@
return (ENXIO);
sc->xb_flags &= ~XB_OPEN;
if (--(sc->users) == 0) {
- /* Check whether we have been instructed to close. We will
- have ignored this request initially, as the device was
- still mounted. */
- device_t dev = sc->xb_dev;
- XenbusState state =
- xenbus_read_driver_state(xenbus_get_otherend_path(dev));
-
- if (state == XenbusStateClosing)
- blkfront_closing(dev);
+ /*
+ * Check whether we have been instructed to close. We will
+ * have ignored this request initially, as the device was
+ * still mounted.
+ */
+ if (xenbus_get_otherend_state(sc->xb_dev) == XenbusStateClosing)
+ blkfront_closing(sc->xb_dev);
}
return (0);
}
@@ -1033,7 +1118,7 @@
struct xb_command *cm;
blkif_request_t *ring_req;
struct blkif_request_segment *sg;
- struct blkif_request_segment *last_block_sg;
+ struct blkif_request_segment *last_block_sg;
grant_ref_t *sg_ref;
vm_paddr_t buffer_ma;
uint64_t fsect, lsect;
@@ -1104,12 +1189,12 @@
nsegs--;
}
block_segs = MIN(nsegs, BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK);
- if (block_segs == 0)
- break;
+ if (block_segs == 0)
+ break;
- sg = BLKRING_GET_SG_REQUEST(&sc->ring, sc->ring.req_prod_pvt);
+ sg = BLKRING_GET_SEG_BLOCK(&sc->ring, sc->ring.req_prod_pvt);
sc->ring.req_prod_pvt++;
- last_block_sg = sg + block_segs;
+ last_block_sg = sg + block_segs;
}
if (cm->operation == BLKIF_OP_READ)
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/xen/blkfront/block.h
--- a/head/sys/dev/xen/blkfront/block.h Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/xen/blkfront/block.h Fri Mar 02 17:36:33 2012 +0200
@@ -26,7 +26,7 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
- * $FreeBSD: head/sys/dev/xen/blkfront/block.h 225705 2011-09-21 00:02:44Z gibbs $
+ * $FreeBSD: head/sys/dev/xen/blkfront/block.h 231839 2012-02-16 21:58:47Z gibbs $
*/
@@ -35,6 +35,32 @@
#include <xen/blkif.h>
/**
+ * Given a number of blkif segments, compute the maximum I/O size supported.
+ *
+ * \note This calculation assumes that all but the first and last segments
+ * of the I/O are fully utilized.
+ *
+ * \note We reserve a segement from the maximum supported by the transport to
+ * guarantee we can handle an unaligned transfer without the need to
+ * use a bounce buffer.
+ */
+#define XBF_SEGS_TO_SIZE(segs) \
+ (((segs) - 1) * PAGE_SIZE)
+
+/**
+ * Compute the maximum number of blkif segments requried to represent
+ * an I/O of the given size.
+ *
+ * \note This calculation assumes that all but the first and last segments
+ * of the I/O are fully utilized.
+ *
+ * \note We reserve a segement to guarantee we can handle an unaligned
+ * transfer without the need to use a bounce buffer.
+ */
+#define XBF_SIZE_TO_SEGS(size) \
+ ((size / PAGE_SIZE) + 1)
+
+/**
* The maximum number of outstanding requests blocks (request headers plus
* additional segment blocks) we will allow in a negotiated block-front/back
* communication channel.
@@ -44,22 +70,18 @@
/**
* The maximum mapped region size per request we will allow in a negotiated
* block-front/back communication channel.
- *
- * \note We reserve a segement from the maximum supported by the transport to
- * guarantee we can handle an unaligned transfer without the need to
- * use a bounce buffer..
*/
-#define XBF_MAX_REQUEST_SIZE \
- MIN(MAXPHYS, (BLKIF_MAX_SEGMENTS_PER_REQUEST - 1) * PAGE_SIZE)
+#define XBF_MAX_REQUEST_SIZE \
+ MIN(MAXPHYS, XBF_SEGS_TO_SIZE(BLKIF_MAX_SEGMENTS_PER_REQUEST))
/**
* The maximum number of segments (within a request header and accompanying
* segment blocks) per request we will allow in a negotiated block-front/back
* communication channel.
*/
-#define XBF_MAX_SEGMENTS_PER_REQUEST \
- (MIN(BLKIF_MAX_SEGMENTS_PER_REQUEST, \
- (XBF_MAX_REQUEST_SIZE / PAGE_SIZE) + 1))
+#define XBF_MAX_SEGMENTS_PER_REQUEST \
+ (MIN(BLKIF_MAX_SEGMENTS_PER_REQUEST, \
+ XBF_SIZE_TO_SEGS(XBF_MAX_REQUEST_SIZE)))
/**
* The maximum number of shared memory ring pages we will allow in a
diff -r dc3e1538e0ca -r e8744e5a2f8e head/sys/dev/xen/netback/netback.c
--- a/head/sys/dev/xen/netback/netback.c Fri Mar 02 17:27:16 2012 +0200
+++ b/head/sys/dev/xen/netback/netback.c Fri Mar 02 17:36:33 2012 +0200
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/xen/netback/netback.c 230587 2012-01-26 16:35:09Z ken $");
+__FBSDID("$FreeBSD: head/sys/dev/xen/netback/netback.c 230916 2012-02-02 17:54:35Z ken $");
/**
* \file netback.c
@@ -75,6 +75,8 @@
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
#include <machine/_inttypes.h>
#include <machine/xen/xen-os.h>
More information about the Zrouter-src-freebsd
mailing list